Packet Firewall version 14 package configuration

Packet Firewall version 14 package configuration

Table of Contents

This package is provided to all campus macOS devices as part of the JAMF on-boarding process.

Current Package Version: 14

CHANGES from Version 13:

14.0 - Opened access too Apple services, including Airplay, AirDrop, and continuity

CHANGES from Version 12:

13.0 - Removal of Ivanti ports from edu.utexas.shared.pf.macros file.

13.1 - Fix of pre-install.sh script of package.

13.2 - Added 146.6.161.0/25 subnet to UTNets list in the edu.utexas.shared.pf.macros file.

13.3 - Revision of campus_only_ports and anywhere_ports, their rules, and their descriptions in the appropriate files.

Package Contents


<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0">      <dict>           <key>Label</key>           <string>edu.utexas.shared.pf</string>           <key>ProgramArguments</key>           <array>                <string>/usr/local/bin/pf-control.sh</string>                <string>restart</string>           </array>           <key>RunAtLoad</key>           <true/>           <key>StandardErrorPath</key>           <string>/dev/null</string>           <key>StandardOutPath</key>           <string>/dev/null</string>      </dict> </plist>
# ===================================================== # edu.utexas.shared.pf.conf # Version: 13 # Revised: 03/17/2022 # # Packet Filter configuration file # # Credit # Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # ===================================================== # # edu.utexas.shared.pf anchor point # anchor "edu.utexas.shared.pf" load anchor "edu.utexas.shared.pf" from "/etc/pf.anchors/edu.utexas.shared.pf.rules"
# ===================================================== # edu.utexas.shared.pf.macros # Version: 13 # Revised: 04/26/2022 ## Macros for Packet Filter # # Credit # Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # ===================================================== protocol_types = "{ tcp, udp }" campus_only_ports = "{ 22, 88, 137:139, 389, 443, 445, 515, 548, 554, 631, 636, 2049, 2105, 3031, 3283:3284, 3689, 5350:5354, 5900, 5988:5989, 59000 }" # Above ports are for the following services in order: SSH, kerberos, wins/smb/netbios, ldap, https, netbios/smb, lpd (printing), afp, rtsp, ipp (printing), ldaps, nfs, kerberos, remote appleevents, ard, airplay, bonjour/mdns, vnc, cim-xml, cad/cti anywhere_ports = "{ }" # After further analysis, none of the ports listed below need to be forced opened since the client machine initiates an outbound connection for these services which is already allowed to return by another rule. They are left below for record purposes. #anywhere_ports = "{ 123, 319:320, 2195:2197, 3970:3972, 4242:4243, 4444:4455, 4500, 5223, 16384-16402, 17500 }" # Above ports are for the following services in order: ntp, ptp, apns, lanrev, crashplan, i2p, ipsec, apns, facetime, dropbox # Tables # UTnet Address Space-https://wikis.utexas.edu/pages/viewpage.action?pageId=50135084 table <UTNets> persist { \ 169.254.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, \ 128.83.17.230, 128.62.0.0/16, 128.83.0.0/16, \ 129.116.0.0/16, 146.6.0.0/16, 146.6.161.0/25, \ 198.213.192.0/18, 198.214.80.0/20, 198.214.250.0/23, \ 206.76.64.0/18, FE80::/10, 2607:F888::/32 } table <allow-mdns> persist { \ 10.0.0.0/8, 172.16/12, 192.168/16, \ 224.0.0.0/24, \ 239.0.0.0/8, \ fe80::/10, \ ff00::/13, ff08::/16, ff10::/13, ff18::/16, \ ff20::/13, ff28::/16, ff30::/13, ff38::/16, \ ff40::/13, ff48::/16, ff50::/13, ff58::/16, \ ff60::/13, ff68::/16, ff70::/13, ff78::/16 }
# ===================================================== # edu.utexas.shared.pf.rules # Version: 13 # Revised: 03/17/2022 # # Packet Filter defaults # # Credit # Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # ===================================================== # ===================================================== # Macros # ===================================================== include "/etc/pf.anchors/edu.utexas.shared.pf.macros" # ===================================================== # Filter rules # ===================================================== # Do not filter on the loopback interface set skip on {lo,vmnet} # Scrub incoming packets scrub in all no-df # Antispoof antispoof quick for en0 antispoof quick for (en1) antispoof quick for (en2) antispoof quick for (en3) # Block in by default. Previous versions used block drop. block return in log all # Allow outgoing traffic pass out all keep state # Allow DHCP pass in log inet proto udp from any port 67 to any port 68 # Allow ICMP from on campus pass in log proto icmp from <campus_only_ips> # Allow MDNS from on campus and special list pass in log proto { tcp, udp } from <UTNets> to port mdns pass in log proto { tcp, udp } from <allow-mdns> to port mdns pass in log proto { tcp, udp } from <UTNets> to port 554 pass in log proto { tcp, udp } from <allow-mdns> to port 554 # Allow ports and services listed in macros from anywhere # After further analysis, the purpose of this rule is already allowed by another rule. The rule is left below for record purposes # pass in log proto $protocol_types from any to any port $anywhere_ports flags S/SA # Restricts ports and services listed in macros to campus only IP address space pass in log proto $protocol_types from <UTNets> to any port $campus_only_ports flags S/SA # # Custom rules anchor # anchor "custom" load anchor "custom" from "/etc/pf.anchors/edu.utexas.shared.pf.custom"
#!/bin/bash # ============================================================================== # pf-control.sh for EPM-University of Texas at Austin # Version: 13 # Revised: 03/17/2022 # # Credit: # Packet Filter control script # Copyright 2012 Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== # ======================================== # Declare variables # ======================================== DEFAULT_RULES_FILE="/etc/pf.anchors/edu.utexas.shared.pf.rules" MACROS_FILE="/etc/pf.anchors/edu.utexas.shared.pf.macros" CUSTOM_RULES_FILE="/etc/pf.anchors/edu.utexas.shared.pf.custom" CONF_DIR_CUSTOM="/etc/pf.anchors/edu.utexas.shared.pf.d" PFCTL="/sbin/pfctl" ECHO="/bin/echo" STAT="/usr/bin/stat" PRINTF="/usr/bin/printf" SYSCTL="/usr/sbin/sysctl" SLEEP="/bin/sleep" OP_MODE="restart" # Added for v9. Detection of overwritten pf.conf PFCONF=$(cat /etc/pf.conf | grep "edu.utexas.shared.pf" | awk -F '"' 'FNR == 1 {print $2}') # ======================================== $SLEEP 20 # ======================================== # ======================================== function usage () { # ======================================== echo "" echo "$0 [-h|--help|h] [start|stop|restart]" echo "" echo "Where:" echo "-h|--help|h Print this message" echo "start Start the firewall (without flushing)" echo "stop Stop the firewall and flush rules" echo "restart Flush and re-read all rules and restart firewall" exit } # ======================================== function checkFilePerms () { # ======================================== FILESTATS=`$STAT -f "%Su:%Sg, %SHp%SMp%SLp" "$1"` if [[ $FILESTATS != "root:wheel, rw-r--r--" ]]; then return 1 else return 0 fi } # ======================================== function checkDirectoryPerms () { # ======================================== FILESTATS=`$STAT -f "%Su:%Sg, %SHp%SMp%SLp" "$1"` if [[ $FILESTATS != "root:wheel, rwxr-xr-x" ]]; then return 1 else return 0 fi } # ======================================== function verifyFiles () { # ======================================== $ECHO "" $ECHO "Verifying configuration security:" FORMAT="%-50s%-10s\n" INSECURE="Failed (Insecure, will not be loaded)" VERIFIED="OK" NOT_FOUND="Failed (No such file or directory)" OBJECT="" RESULT="" OBJECT=$CONF_DIR_CUSTOM if [[ -d "$CONF_DIR_CUSTOM" ]]; then if checkDirectoryPerms "$CONF_DIR_CUSTOM"; then RESULT=$VERIFIED fi else RESULT=$NOT_FOUND fi $PRINTF "$FORMAT" "$OBJECT" "$RESULT" OBJECT=$CUSTOM_RULES_FILE if [[ -f "$CUSTOM_RULES_FILE" ]]; then if checkFilePerms "$CUSTOM_RULES_FILE"; then RESULT=$VERIFIED else RESULT=$INSECURE fi else RESULT=$NOT_FOUND fi $PRINTF "$FORMAT" "$OBJECT" "$RESULT" if [[ -d $CONF_DIR_CUSTOM ]]; then shopt -s nullglob DID_FIND_CUSTOMRULE_FILES=0 CUSTOM_RULES=/etc/pf.anchors/edu.utexas.shared.custom.d/* for f in $CUSTOM_RULES do OBJECT=$f if checkFilePerms "$f"; then RESULT=$VERIFIED DID_FIND_CUSTOMRULE_FILES=1 else RESULT=$INSECURE fi $PRINTF "$FORMAT" "$OBJECT" "$RESULT" done shopt -u nullglob fi } # ======================================== function enablePfctl () { # ======================================== $ECHO "" $ECHO "Starting Packet Filter and reading default rules" $PFCTL -E > /dev/null 2>&1 $PFCTL -f /etc/edu.utexas.shared.pf.conf > /dev/null 2>&1 } # ======================================== function disablePfctl () { # ======================================== $ECHO "" $ECHO "Disabling Packet Filter" $PFCTL -d } # Added for v9 to ensure that pf.conf contains required anchors after upgrades or updates # ======================================== function fixPFConf () { # ======================================== $ECHO "" $ECHO "Checking and repairing Packet Filter Configuration" if [ -z "$PFCONF" ];then # ============================================ # Add PF anchors to /etc/pf.conf # ============================================ FILE='/etc/pf.conf' LINE1='anchor "edu.utexas.shared.pf"' LINE2='load anchor "edu.utexas.shared.pf" from "/etc/pf.anchors/edu.utexas.shared.pf.rules"' grep '\banchor "edu.utexas.shared.pf"\b' $FILE || echo $LINE1 >> $FILE grep '\bload anchor "edu.utexas.shared.pf" from "/etc/pf.anchors/edu.utexas.shared.pf.rules"\b' $FILE || echo $LINE2 >> $FILE fi } # ======================================== function loadCustomRules () { # ======================================== FILES_TO_LOAD=( "$MACROS_FILE" ) # Add custom rule file if [[ -f "$CUSTOM_RULES_FILE" ]]; then $ECHO "" $ECHO "Loading $CUSTOM_RULES_FILE:" if checkFilePerms "$CUSTOM_RULES_FILE"; then $ECHO "---> $CUSTOM_RULES_FILE" FILES_TO_LOAD=( "${FILES_TO_LOAD[@]}" "$CUSTOM_RULES_FILE" ) fi fi # Add each file in custom rule directory $ECHO "" $ECHO "Loading rule files in /etc/pf.anchors/edu.utexas.shared.pf.d/" shopt -s nullglob DID_FIND_CUSTOMRULE_FILES=0 CUSTOM_RULES=$CONF_DIR_CUSTOM/* for f in $CUSTOM_RULES do if checkFilePerms "$f"; then $ECHO "---> $f" FILES_TO_LOAD=( "${FILES_TO_LOAD[@]}" "$f" ) DID_FIND_CUSTOMRULE_FILES=1 fi done shopt -u nullglob [ $DID_FIND_CUSTOMRULE_FILES -eq 0 ] && $ECHO "---> Directory is empty" # Read all files that passed permissions check # and feed the results to pfctl cat ${FILES_TO_LOAD[@]} | $PFCTL -a "edu.utexas.shared.pf/custom" -f- > /dev/null 2>&1 } # ======================================== function showCurrentRules () { # ======================================== $ECHO "" $ECHO "Current rules:" $PFCTL -a '*' -sr } # ======================================== function configureKernelParameters () { # ======================================== $SYSCTL -w net.inet.ip.fw.enable=1 > /dev/null 2>&1 $SYSCTL -w net.inet.ip.fw.verbose=2 > /dev/null 2>&1 $SYSCTL -w net.inet6.ip6.fw.verbose=0 > /dev/null 2>&1 $SYSCTL -w net.inet.ip.fw.verbose_limit=0 > /dev/null 2>&1 $SYSCTL -w net.inet.ip.forwarding=0 > /dev/null 2>&1 } while test -n "$1"; do case $1 in -h|--help|h) usage ;; start) OP_MODE="start" shift ;; stop) OP_MODE="stop" shift ;; restart) OP_MODE="restart" shift ;; *) usage ;; esac done # Check for root if [[ $EUID -ne 0 ]]; then echo "This script must be run as root" 2>&1 exit 1 else verifyFiles if [[ $OP_MODE == "start" ]]; then configureKernelParameters # Added for v9 - fix for overwritten pf.conf fixPFConf enablePfctl loadCustomRules showCurrentRules elif [[ $OP_MODE == "stop" ]]; then disablePfctl elif [[ $OP_MODE == "restart" ]]; then configureKernelParameters disablePfctl # Added for v9 - fix for overwritten pf.conf fixPFConf enablePfctl loadCustomRules showCurrentRules else echo "Unknown operation mode..." usage exit 1 fi fi exit 0
#!/bin/bash # ============================================================================== # pf-restart.sh for EPM-University of Texas at Austin # Version: 13 # Revised: 03/17/2022 # # Restart pf firewall and display rules # # Credit: # Copyright 2012 Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== # Change to match the actual item (if needed): LAUNCHD_ITEM_NAME="edu.utexas.shared.pf" LAUNCHCTL="/bin/launchctl" PFCTL="/sbin/pfctl" PF_LAUNCHD_ITEM="/Library/LaunchDaemons/$LAUNCHD_ITEM_NAME.plist" # Check for root if [[ $EUID -ne 0 ]]; then echo "This script must be run as root" 2>&1 exit 1 else if [[ -f "$PF_LAUNCHD_ITEM" ]]; then # Unload the launchd item if already loaded $LAUNCHCTL list $LAUNCHD_ITEM_NAME if [[ $? -eq 0 ]]; then echo "" echo "# Unloading $PF_LAUNCHD_ITEM" $LAUNCHCTL unload "$PF_LAUNCHD_ITEM" fi # Load the launchd item echo "# Loading $PF_LAUNCHD_ITEM" $LAUNCHCTL load -w $PF_LAUNCHD_ITEM # Reset the counters # echo "# Flushing filter parameters" # $PFCTL -F all # echo "" # Show current rules sleep 1 echo "# Current active rules:" $PFCTL -a "*" -sr echo "" else echo "$PF_LAUNCHD_ITEM not found" 2>&1 exit 1 fi fi ## Turn off application firewall /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off

Package Scripts


#!/bin/bash # ============================================================================== # Preflight script for EPM-University of Texas at Austin # Version: 13 # Revised: 04/22/2022 # # Copyright 2012 Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== ITEM_NAME="edu.utexas.shared.pf" NOW=$(date +"%Y-%m-%d-%H%M%S") LAUNCHCTL="/bin/launchctl" PF_LAUNCH_DAEMON="$3/Library/LaunchDaemons/$ITEM_NAME.plist" BACKUP_DIR="$3/var/backups/$ITEM_NAME-$NOW" mkdir $BACKUP_DIR # ================================================= # Define the items to backup # ================================================= FILES_TO_BACKUP=( "$3/etc/edu.utexas.shared.pf.conf" "$3/etc/pf.anchors/edu.utexas.shared.pf.rules" "$3/etc/pf.anchors/edu.utexas.shared.pf.macros" "$3/etc/pf.anchors/edu.utexas.shared.pf.custom" "$3/etc/pf.conf" PF_LAUNCH_DAEMON ) DIRECTORIES_TO_BACKUP=( "$3/etc/pf.anchors/edu.utexas.shared.pf.d" ) # ================================================= # Backup # ================================================= for A_FILE in "${FILES_TO_BACKUP[@]}" do if [[ -f "$A_FILE" ]]; then echo "$SCRIPT_NAME: Backing up $A_FILE to $BACKUP_DIR/" cp "$A_FILE" "$BACKUP_DIR/" fi done for A_DIRECTORY in "${DIRECTORIES_TO_BACKUP[@]}" do if [[ -d "$A_DIRECTORY" ]]; then echo "$SCRIPT_NAME: Backing up $A_DIRECTORY to $BACKUP_DIR/$NOW-$A_DIRECTORY" cp -R "$A_DIRECTORY" "$BACKUP_DIR/" fi done # ================================================= # Unload the launchd item # ================================================= if [[ -f "$PF_LAUNCH_DAEMON" ]]; then $LAUNCHCTL list $ITEM_NAME if [[ $? -eq 0 ]]; then $LAUNCHCTL unload -w $PF_LAUNCH_DAEMON fi fi exit 0
#!/bin/bash # ============================================================================== # Postflight script for packet filter installer for EPM-University of Texas at Austin # Version: 13 # Revised: 03/17/2022 # # Credit: # Copyright 2012 Hannes Juutilainen <hjuutilainen@mac.com> # https://github.com/hjuutilainen/pf-conf # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== echo $SCRIPT_NAME: Starting # =========================================== # Create a rule template if it doesn't exist # =========================================== CUSTOM_RULE_FILE="$3/etc/pf.anchors/edu.utexas.shared.pf.custom" if [[ ! -f $CUSTOM_RULE_FILE ]]; then echo $SCRIPT_NAME: Creating example custom rules file $CUSTOM_RULE_FILE echo "# =====================================" >> $CUSTOM_RULE_FILE echo "# Custom rules for pf firewall" >> $CUSTOM_RULE_FILE echo "# Macros: /etc/pf.anchors/edu.utexas.shared.macros" echo "# =====================================" >> $CUSTOM_RULE_FILE echo "" >> $CUSTOM_RULE_FILE echo "# Example rule" >> $CUSTOM_RULE_FILE echo "# pass in proto tcp from IP-ADDRESS to port 22" >> $CUSTOM_RULE_FILE echo "" >> $CUSTOM_RULE_FILE fi # ============================================ # Create a directory for other custom files # ============================================ CUSTOM_RULE_DIR="$3/etc/pf.anchors/edu.utexas.shared.pf.d" if [[ ! -d "$CUSTOM_RULE_DIR" ]]; then mkdir "$CUSTOM_RULE_DIR" chown root:wheel "$CUSTOM_RULE_DIR" chmod 755 "$CUSTOM_RULE_DIR" fi # ============================================ # Add ACTS PF anchors to /etc/pf.conf for Cisco anchor overrule # ============================================ FILE='/etc/pf.conf' LINE1='anchor "edu.utexas.shared.pf"' LINE2='load anchor "edu.utexas.shared.pf" from "/etc/pf.anchors/edu.utexas.shared.pf.rules"' grep '\banchor "edu.utexas.shared.pf"\b' $FILE || echo $LINE1 >> $FILE grep '\bload anchor "edu.utexas.shared.pf" from "/etc/pf.anchors/edu.utexas.shared.pf.rules"\b' $FILE || echo $LINE2 >> $FILE # ============================================ # Start if installed on startup volume # ============================================ if [[ "$3" == "/" ]]; then echo $SCRIPT_NAME: Installed on startup volume echo $SCRIPT_NAME: Starting firewall if [[ -f "/usr/local/bin/pf-restart.sh" ]]; then /usr/local/bin/pf-restart.sh fi else echo $SCRIPT_NAME: Installed on non-startup volume echo $SCRIPT_NAME: Skipping firewall startup fi echo $SCRIPT_NAME: Done exit 0