fleet
fleet copied to clipboard
`alf` table returns no results on macOS 15 Sequoia
Problem
Application Firewall settings are no longer contained in a plist, so Firewall is reported as not activated in Sequoia devices (incorrectly).
Related to: https://github.com/osquery/osquery/issues/8395
From Apple docs: https://developer.apple.com/documentation/macos-release-notes/macos-15-release-notes#Deprecations Application Firewall settings are no longer contained in a property list. If your app or workflow relies on changing Application Firewall settings by modifying /Library/Preferences/com.apple.alf.plist, then you need to make changes to use the socketfilterfw command line tool instead. (124405935)
What have you tried?
No workarounds available at the moment via Fleet or osquery
Potential solutions
Another way to obtain the data could be to add a new fleetd table to allow this. The new fleetd table can execute the socketfilterfw command and return the data.
What is the expected workflow as a result of your proposal?
A new table (or other proposed solution) would allow me to pull the application firewall settings for my macOS 15 device.
QA notes
5.14.1 has been released to edge. Build fleetd with fleetctl package [...] --osqueryd-channel edge.
Following tests should be executed on macOS 14 and 15. The tables we want to test are:
alf: Should returnsglobal_state,stealth_enabled,logging_enabled, andversion(other columns will be empty for now). Test enabling/disabling each setting. PS: There's no way to enable firewall "logging" on macOS 15, so it will currently be always 0 (AFAICS macOS exposes the value of the setting but it's not configurable anymore).alf_exceptions: On macOS 14 this table returns file paths, in macOS 15 this table returns bundle identifiers instead. Exceptions on executables without bundle identifier are not included in the returned list for macOS 15.alf_explicit_auths: Returns no results on macOS 15 (you should only see a verbose log that saysI1008 09:47:54.161409 213143552 firewall.mm:239] alf_explicit_auths is currently not supported on macOS 15).
@zayhanlon @ddribeiro The socket filter binary does not work on managed / supervised devices (this is the breaking change at the root of all of this...)
Only configuration profiles can be used to change the firewall settings on managed devices. That does not mean that APIs to READ the firewall state are completely blocked, but, we or osquery needs a new way to get the data.
Allen:
Looks like Brock is all over this one already but to my knowledge, system_profiler SPFirewallDataType is the only place I can think of this info being available in a static, readable format. Otherwise you have to run /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate --getblockall --getallowsigned --getstealthmode to get the same details you would get from osquery.
@zayhanlon it is also in system_profiler SPManagedClientDataType
The firewall is now a system extension I think...
ALF:
Version: 5.0
Last Modified: 8/4/24, 6:31 AM
Bundle ID: com.apple.nke.applicationfirewall
Notarized: Unknown
Loaded: No
Obtained from: Not Signed
Location: /System/Library/Extensions/ALF.kext
Kext Version: 405
Loadable: No
Validity Errors:
Validation Failures:
Kext has a CFBundleExecutable property but the executable can't be found: ALF
Signature Validation Errors: Not Signed
Dependencies: Incomplete
Signed by: Not Signed
This is from System Profiler:
com.apple.security.firewall:
EnableLogging:
Value: 1
State: always
Source: com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)
AllowSigned:
Value: 1
State: always
Source: com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)
LoggingOption:
Value: detail
State: always
Source: com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)
EnableStealthMode:
Value: 0
State: always
Source: com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)
EnableFirewall:
Value: 1
State: always
Source: com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)
com.apple.security.firewall:
Description: Configures Firewall settings
Organization:
Name: Firewall
Identifier: [com.github.erikberglund.ProfileCreator.F302AA03-F873-4249-A1C3-7BD94B9B855F.com](http://com.github.erikberglund.profilecreator.f302aa03-f873-4249-a1c3-7bd94b9b855f.com/).apple.security.firewall.0E0E1617-E88D-45C6-9E9B-C56BFD80C730
UUID: 0E0E1617-E88D-45C6-9E9B-C56BFD80C730
Version: 1
Payload Data: {
AllowSigned = 1;
BlockAllIncoming = 0;
EnableFirewall = 1;
EnableStealthMode = 0;
@lucasmrod @zayhanlon @ddribeiro I think this is the closest to a simple source as we will get:
% system_profiler -json SPManagedClientDataType | jq '.[] | .[] | select(._name=="com.apple.security.firewall") | ._items[]'
{
"_name": "EnableLogging",
"data_keyValue": "1",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "AllowSigned",
"data_keyValue": "1",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "LoggingOption",
"data_keyValue": "detail",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "EnableStealthMode",
"data_keyValue": "0",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "EnableFirewall",
"data_keyValue": "1",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "BlockAllIncoming",
"data_keyValue": "0",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
{
"_name": "PayloadUUID",
"data_keyValue": "0E0E1617-E88D-45C6-9E9B-C56BFD80C730",
"data_source": "com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer), com.apple.security.firewall (Computer)",
"data_state": "always"
}
Also an option:
% system_profiler -json SPFirewallDataType
{
"SPFirewallDataType" : [
{
"_name" : "spfirewall_settings",
"spfirewall_globalstate" : "spfirewall_globalstate_limit_connections",
"spfirewall_loggingenabled" : "Yes",
"spfirewall_stealthenabled" : "No"
}
]
}
Since the data is available in system_profiler, I think we can use the approach we used for secureboot and do this in osquery core: https://github.com/osquery/osquery/issues/8395#issuecomment-2330198132
Nice!
I think we can use the approach we used for secureboot and do this in osquery core: https://github.com/osquery/osquery/issues/8395#issuecomment-2330198132
If I'm understanding this approach correctly, the plan is to fix the alf table so that it works on macOS 15 (and older versions of macOS). No new table or column.
@zwass is that right?
cc @nonpunctual @ddribeiro
Yes that's right. Use this different method to fix the existing table.
@zwass @noahtalerman THis is probably a good time to revisit... https://github.com/fleetdm/fleet/issues/19513
@zwass @noahtalerman @PezHub
From macOS Sequoia 15 RC Release Notes Sep 10 2024 1:05a:
Deprecations
Application Firewall settings are no longer contained in a property list. If your app or workflow relies on changing Application Firewall settings by modifying /Library/Preferences/com.apple.alf.plist, then you need to make changes to use the socketfilterfw command line tool instead. (124405935)
But... as mentioned above socketfilterfw DOES NOT WORK ON MANAGED MACS.
hey @sharon-fdm - we discussed this issue on the e-group call today and determined that we should take it on as a p1 on the engineering sprint due to several of our existing customers already moving to sequoia - this now becomes a workflow blocking issue and urgency has gone up. let me know if you have any questions and please feel free to chat with @zwass about his thoughts on addressing it.
@lukeheath fyi
@zayhanlon, understood. @lukeheath, I'll work with the team to see how we can take it with minimal impact.
Agreed, this now qualifies as P1.
@lukeheath @noahtalerman @sharon-fdm Not saying I know what the fastest solution is, but, since the data we need seems available in system_profiler & @zwass has already added code that makes including system profiler data types (i.e., SPFirewallDataType) easier, maybe that's all that's needed? or perhaps we can just add the list of system profiler data types & make a new system profiler table? Thanks!
% system_profiler -listdatatypes
Available Datatypes:
SPParallelATADataType
SPUniversalAccessDataType
SPSecureElementDataType
SPApplicationsDataType
SPAudioDataType
SPBluetoothDataType
SPCameraDataType
SPCardReaderDataType
SPiBridgeDataType
SPDeveloperToolsDataType
SPDiagnosticsDataType
SPDisabledSoftwareDataType
SPDiscBurningDataType
SPEthernetDataType
SPExtensionsDataType
SPFibreChannelDataType
SPFireWireDataType
SPFirewallDataType
SPFontsDataType
SPFrameworksDataType
SPDisplaysDataType
SPHardwareDataType
SPInstallHistoryDataType
SPInternationalDataType
SPLegacySoftwareDataType
SPNetworkLocationDataType
SPLogsDataType
SPManagedClientDataType
SPMemoryDataType
SPNVMeDataType
SPNetworkDataType
SPPCIDataType
SPParallelSCSIDataType
SPPowerDataType
SPPrefPaneDataType
SPPrintersSoftwareDataType
SPPrintersDataType
SPConfigurationProfileDataType
SPRawCameraDataType
SPSASDataType
SPSerialATADataType
SPSPIDataType
SPSmartCardsDataType
SPSoftwareDataType
SPStartupItemDataType
SPStorageDataType
SPSyncServicesDataType
SPThunderboltDataType
SPUSBDataType
SPNetworkVolumeDataType
SPWWANDataType
SPAirPortDataType
@lukeheath, @nonpunctual, @zayhanlon, I'd recommend that we do not stop the 4.57.0 release effort. Would it be ok if we start this P1 next week? (Aiming at a delayed 4.57.1)
@sharon-fdm i think thats ok. are we still doing patches? can we get a 4.57.1 out with this (or maybe itll require an osquery release - not sure)
@zayhanlon, we will need to decide whether we want to fix in osquery core (Long release time) or add something to Fleetd (quicker)
There are intentions to release osquery at the end of the month. It seems to me we should fix it there using the method discussed by Brock and I.
@zwass im in agreement. two of the customers that have asked for this for sure use vanilla osquery vs fleetd (@sharon-fdm fyi)
cc @lucasmrod
@sharon-fdm @zayhanlon It sounds like the decision is to wait for this to be fixed in osquery core. I'm going to downgrade to a P2 since we'll be in a holding pattern until the end of the month.
@lukeheath, agreed. P2 is more suitable here. We plan to do the dev work immediately after releasing 4.57.0 in hope that this will be part of OSQuery that is planned at end of September.
@nonpunctual Hi!
Am working on this and have the following questions (just in case you know).
From system profiler's SPFirewallDataType we can populate the following alf columns: global_state, stealth_enabled and logging_enabled.
Regarding logging_option, https://support.apple.com/en-jo/121011 mentions it's not available anymore, so this column will be empty for macOS 15+
Regarding the remaining columns in alf:
- What does
firewall_unloadmeans? (I cannot see that piece of information in macOS 15 and cannot find any docs). osquery docs just say "1 If firewall unloading enabled else 0" (Maybe it means if the firewall is allowed to be disabled via MDM or something?) - What
versionshould be in macOS 15 context? I can see the following underSPFirewallDataType:
_versionInfo : {
"com.apple.SystemProfiler.SPFirewallReporter" = 915;
}
- Seems
allow_signed_enabledis not available through system profiler'sSPFirewallDataTypebut is available through/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate --getblockall --getallowsigned --getstealthmode).
Maybe firewall_unload, allow_signed_enabled and logging_option are settings that are set on managed devices only? (So we could use SPManagedClientDataType to get them.)
Am all ears here :)
Hi @lucasmrod
Seems allow_signed_enabled is not available through system profiler's SPFirewallDataType but is available through /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate --getblockall --getallowsigned --getstealthmode).
If your Mac is unmanaged (no MDM) you can use the /usr/libexec/ApplicationFirewall/socketfilterfw binary.
If your mac is MANAGED, you can't, because when you try to call it (at least in Terminal) you get this:
There still could be some API / entitlement I suppose that could be called somehow, but, my thinking is there are no options to use anything having to do with /usr/libexec/ApplicationFirewall/socketfilterfw because all Macs we MDM enroll will be blocked from using it.
I don't have any relevant info about firewall version. We would probably need to ask someone at Apple if that has any meaning & I am sure it's a number kept track of by the firewall team & really isn't anything that has a control on it other than Apple Software Update.
I do believe that firewall_unload is related to making it mutable. I don't know if this is CHANGED in macOS 15. Another thing that's ringing a bell here is that you can set & unset stealth mode.
cc @allenhouchins @harrisonravazzolo @ddribeiro @dherder to see if they have any ideas.
From everything I've heard & read about this system_profiler options are what we want, but, what's tricky is to figure out which data type is best. Some of them are reporting what firewall settings have been via MDM vs. "what is the state of the firewall"? I can see arguments on both sides of that as to which thing is definitive. (see https://github.com/fleetdm/fleet/issues/21802#issuecomment-2329804922)
OK, I've opened a osquery PR with the settings that macOS does offer in SPFirewallDataType ; alf columns: global_state, stealth_enabled, logging_enabled, and version).
Maybe these columns are the most required from users/customers and the rest can be added later.
@zwass: Asking for early feedback for https://github.com/osquery/osquery/pull/8428.
@xpkoala Added QA notes.
Removing 4.58.0 milestone because this is an osquery core change.