FIREWALL ON / OFF depending on Network Condition

wmateo
Contributor

I am looking for a script or solution that turns OFF my user's laptops FW when they are in my network, and ON when they leave/unplug from it. I looked at "Network State" Policy that is cool when they are plugged in and check in, but what about when the user unplugs and takes laptop home? Any suggestions how I may go about this? if there is a script you can point me to, it would be helpful. Thanks

6 REPLIES 6

alexjdale
Valued Contributor III

We put some work into this, basically a launchdaemon that triggers on network changes (using a watch path), then runs a script that turns the FW off or on based on the network location. It ended up being too much of a PITA so we just keep the ALF on all the time, and it works fine.

Edit: I was able to get this to run as a cached policy with the script below in the "Execute Command" field, but it wasn't firing on all of my network changes (was switching around between our internal wifi, guest wifi, and wired) so there is some gap in my knowledge about how/when Casper triggers on network changes. It may be better to go with a launchdaemon.

res=`ping -c 1 casperhostname | grep "1 packets received"`; if [ "$res" ]; then defaults write /Library/Preferences/com.apple.alf globalstate -int 0; else defaults write /Library/Preferences/com.apple.alf globalstate -int 1; fi

wmateo
Contributor

@alexjdale Thanks. I think Launch Daemon is the way to go.... you have an example? I am new at scripting.

alexjdale
Valued Contributor III

There are two components: a plist file (the LaunchDaemon) and a script that it will execute. This launchdaemon uses a "watch path" to trigger, meaning whenever the file path is changed (in this case, when the file is modified/deleted/created, but it will work with folders and their contents as well) it executes the ProgramArguments.

The plist (naming convention is something like "com.companyname.autofirewall.plist") should be put into /Library/LaunchDaemons and look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
    <string>com.company.autofirewall</string>
  <key>ProgramArguments</key>
  <array>
    <string>/path/to/script</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>/var/run/resolv.conf</string>
  </array>
  <key>UserName</key>
  <string>root</string>
</dict>
</plist>

And the script could be something like:

#!/bin/bash
pingTest=`ping -c 1 casperhostname | grep "1 packets received"`
if [ "$pingTest" ]; then
    defaults write /Library/Preferences/com.apple.alf globalstate -int 0
else
    defaults write /Library/Preferences/com.apple.alf globalstate -int 1
fi

Permissions need to be set on each file (plist and script) or else it will not fire, to make sure users can't modify the script/plist since it runs as root and could be used to elevate permissions or execute arbitrary code. I go with owned by root, with no users or groups having write access.

Deploying is as simple as putting the two files in place, a pkg does the job. Rebooting after setup will load the daemon or you can manually load it with launchd in a postflight script. On startup, the OS will attempt to load any launchdaemons located in /Library/LaunchDaemons. Console will log any errors it runs into trying to load or execute the daemon/script.

One thing that may be an issue is that launchdaemons have a natural cooldown of I think 10 seconds (this can be changed in the plist), meaning it will not run more than once every 10 seconds, so it may be possible to miss a second network change if it happens too quickly after the previous one. The timing complications are what led me to just drop it and keep the ALF on all the time, it doesn't impact any of our workflows to have it on and users can always add exceptions if needed.

More info: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

wmateo
Contributor

Thanks Alex, This is a good starting point. @alexjdale

jdziat
Contributor

I'm surprised theres not an easy way to do this with network locations.

alexjdale
Valued Contributor III

I'd like to see Apple offer this natively as a Configuration Profile setting, I've requested it a few times. All they need to do is create a launchdaemon that monitors domain controller availability (same mechanism as the login screen when it says "network accounts are not available") and then toggle the ALF on or off based on that. That's how Windows does it with their GPO, pretty much.