From 49a8b1663d116deab1a26c45b8b971ee2770665b Mon Sep 17 00:00:00 2001 From: Bob Gendler Date: Tue, 28 Nov 2023 10:39:21 -0500 Subject: [PATCH] refactor[includes] Updated enablePF-mscp.sh Updated script based on slack discussion --- includes/enablePF-mscp.sh | 180 +++++++++++++++++++++++++++++++------- 1 file changed, 149 insertions(+), 31 deletions(-) diff --git a/includes/enablePF-mscp.sh b/includes/enablePF-mscp.sh index f47035c9..6c527a3c 100644 --- a/includes/enablePF-mscp.sh +++ b/includes/enablePF-mscp.sh @@ -1,8 +1,31 @@ #!/bin/bash +# Title : enablePF-mscp.sh +# Description : This script will configure the packet filter `pf` with the settings recommended by the macOS Security Compliance Project (MSCP) +# Author : Dan Brodjieski +# Date : 2023-10-05 +# Version : 1.0 +# Usage : enablePF-mscp.sh [--uninstall] +# Notes : Script must be run with privileges +# : Configuring `pf` with a content filter installed may have unexpected results +# Changelog : 2023-10-05 - Added --uninstall parameter, refactored script for better functionality + +#### verify running as root +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root or with sudo, exiting..." + exit 1 +fi + +#### Setup environment +launchd_pfctl_plist="/Library/LaunchDaemons/mscp.pfctl.plist" +legacy_launchd_plist="/Library/LaunchDaemons/macsec.pfctl.plist" + +mdm_managed=$(/usr/bin/osascript -l JavaScript -e "$.NSUserDefaults.alloc.initWithSuiteName('com.apple.security.firewall').objectIsForcedForKey('EnableFirewall')") + +#### Functions #### #enabling macos application firewall enable_macos_application_firewall () { - + echo "The macOS application firewall is not managed by a profile, enabling from CLI" /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on /usr/libexec/ApplicationFirewall/socketfilterfw --setloggingopt detail /usr/libexec/ApplicationFirewall/socketfilterfw --setallowsigned on @@ -10,11 +33,10 @@ enable_macos_application_firewall () { } -#enabling pf firewall with macsec rules -enable_pf_firewall_with_macsec_rules () { - macsec_pfctl_plist="/Library/LaunchDaemons/macsec.pfctl.plist" - - if [[ -e "$macsec_pfctl_plist" ]]; then +#enabling pf firewall with mscp rules +enable_pf_firewall_with_mscp_rules () { + echo "Creating LaunchDeamon to load the MSCP rules" + if [[ -e "$launchd_pfctl_plist" ]]; then echo "LaunchDaemon already exists, flushing and reloading rules..." pfctl -e 2> /dev/null pfctl -f /etc/pf.conf 2> /dev/null @@ -22,55 +44,59 @@ enable_pf_firewall_with_macsec_rules () { fi # copy system provided launchd for custom ruleset - cp "/System/Library/LaunchDaemons/com.apple.pfctl.plist" "$macsec_pfctl_plist" + cp "/System/Library/LaunchDaemons/com.apple.pfctl.plist" "$launchd_pfctl_plist" #allow pf to be enabled when the job is loaded - /usr/libexec/PlistBuddy -c "Add :ProgramArguments:1 string -e" $macsec_pfctl_plist + /usr/libexec/PlistBuddy -c "Add :ProgramArguments:1 string -e" $launchd_pfctl_plist #use new label to not conflict with System's pfctl - /usr/libexec/PlistBuddy -c "Set :Label macsec.pfctl" $macsec_pfctl_plist + /usr/libexec/PlistBuddy -c "Set :Label mscp.pfctl" $launchd_pfctl_plist # enable the firewall pfctl -e 2> /dev/null #make pf run at system startup - launchctl enable system/macsec.pfctl - launchctl bootstrap system $macsec_pfctl_plist + launchctl enable system/mscp.pfctl + launchctl bootstrap system $launchd_pfctl_plist pfctl -f /etc/pf.conf 2> /dev/null #flush the pf ruleset (reload the rules) } -# append the macsec anchors to pf.conf -configure_pf_config_add_macsec_anchors () { - - # check to see if macsec anchors exists - anchors_exist=$(grep -c '^anchor "macsec_pf_anchors"' /etc/pf.conf) +# append the mscp anchors to pf.conf +configure_pf_config_add_mscp_anchors () { + echo "Adding the MSCP anchors to /etc/pf.conf" + # check to see if mscp anchors exists + anchors_exist=$(grep -c '^anchor "mscp_pf_anchors"' /etc/pf.conf) if [[ $anchors_exist == "0" ]];then - echo 'anchor "macsec_pf_anchors"' >> /etc/pf.conf - echo 'load anchor "macsec_pf_anchors" from "/etc/pf.anchors/macsec_pf_anchors"' >> /etc/pf.conf + echo 'anchor "mscp_pf_anchors"' >> /etc/pf.conf + echo 'load anchor "mscp_pf_anchors" from "/etc/pf.anchors/mscp_pf_anchors"' >> /etc/pf.conf else - echo "macsec anchors exist, continuing..." + echo "mscp anchors exist, continuing..." fi } -# Create /etc/pf.anchors/macsec_pf_anchors -create_macsec_pf_anchors () { -if [[ -e /etc/pf.anchors/macsec_pf_anchors ]]; then - echo "macsec Anchor file exists, deleting and recreating..." - rm -f /etc/pf.anchors/macsec_pf_anchors +# Create /etc/pf.anchors/mscp_pf_anchors +create_mscp_pf_anchors () { + echo "Creating the MSCP anchor configuration file" +if [[ -e /etc/pf.anchors/mscp_pf_anchors ]]; then + echo "mscp Anchor file exists, deleting and recreating..." + rm -f /etc/pf.anchors/mscp_pf_anchors fi -cat > /etc/pf.anchors/macsec_pf_anchors <<'ENDCONFIG' +cat > /etc/pf.anchors/mscp_pf_anchors <<'ENDCONFIG' -anchor macsec_pf_anchors +anchor mscp_pf_anchors #default deny all in, allow all out and keep state block in all pass out all keep state +#pass in all packets from localhost +pass in from 127.0.0.1 + ## Allow DHCP pass in inet proto udp from port 67 to port 68 pass in inet6 proto udp from port 547 to port 546 @@ -147,9 +173,101 @@ block log proto tcp to any port 540 ENDCONFIG } -#### +# function to remove legacy setup if exists +remove_macsec_setup() { + echo "References to macsec appear to exist, removing..." -enable_macos_application_firewall -create_macsec_pf_anchors -configure_pf_config_add_macsec_anchors -enable_pf_firewall_with_macsec_rules + launchctl disable system/macsec.pfctl + launchctl bootout system $legacy_launchd_plist + rm -rf $legacy_launchd_plist + + # check to see if macsec anchors exists + anchors_exist=$(grep -c '^anchor "macsec_pf_anchors"' /etc/pf.conf) + + if [[ ! $anchors_exist == "0" ]];then + sed -i "" '/macsec/d' /etc/pf.conf + else + echo "macsec anchors do not exist, continuing..." + fi + + rm -f /etc/pf.anchors/macsec_pf_anchors +} + +uninstall_mscp_pf(){ + echo "Removing MSCP configuration files from pf" + if [[ -e "$launchd_pfctl_plist" ]]; then + echo "LaunchDaemon exists, unloading and removing" + #remove mscp pf components from launchd + launchctl disable system/mscp.pfctl + launchctl bootout system $launchd_pfctl_plist + rm -rf $launchd_pfctl_plist + fi + + # check to see if mscp anchors exists + anchors_exist=$(grep -c '^anchor "mscp_pf_anchors"' /etc/pf.conf) + + if [[ ! $anchors_exist == "0" ]];then + sed -i "" '/mscp/d' /etc/pf.conf + else + echo "mscp anchors do not exist, continuing..." + fi + + rm -f /etc/pf.anchors/mscp_pf_anchors + + # flush rules and reload pf + echo "Flushing rules and reloading pf" + pfctl -f /etc/pf.conf 2> /dev/null #flush the pf ruleset (reload the rules) + +} + +#### Main Script #### + +POSITIONAL_ARGS=() + +while [[ $# -gt 0 ]]; do + case $1 in + -u|--uninstall) + UNINSTALL="true" + shift # past argument + shift # past value + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + *) + POSITIONAL_ARGS+=("$1") # save positional arg + shift # past argument + ;; + esac +done + +set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters + +if [[ $UNINSTALL == "true" ]]; then + if [[ -e "$legacy_launchd_plist" ]]; then + remove_macsec_setup + fi + uninstall_mscp_pf + exit 0 +fi + +# check to see if a profile has enabled the firewall. If it hasn't, then CLI can be used to enable +if [[ "$mdm_managed" == "false" ]];then + enable_macos_application_firewall +fi + +# clean up any legacy configurations +if [[ -e "$legacy_launchd_plist" ]]; then + echo "References to macsec appear to exist, removing..." + remove_macsec_setup +fi + +# create mscp anchors file +create_mscp_pf_anchors + +# add the anchors to the /etc/pf.conf file +configure_pf_config_add_mscp_anchors + +# create specific launch daemon for mscp configuration +enable_pf_firewall_with_mscp_rules