Disable all network traffic on a Mac VM

I needed to create a sandbox for a new user to look at some code. There are many API calls and hooks to the outside world I needed to protect from this person so created a VM and blocked all network traffic. I accomplished this using the packet filter ( PF ) built into macOS. I ran all commands in terminal as root to make life easier. It’s a VM so, YOLO.

Password: password
nano /etc/pf.conf

Add block all to the end of the config file for pf.

# Default PF configuration file.
# This file contains the main ruleset, which gets automatically loaded
# at startup.  PF will not be automatically enabled, however.  Instead,
# each component which utilizes PF is responsible for enabling and disabling
# PF via -E and -X as documented in pfctl(8).  That will ensure that PF
# is disabled only when the last enable reference is released.
# Care must be taken to ensure that the main ruleset does not get flushed,
# as the nested anchors rely on the anchor point defined here. In addition,
# to the anchors loaded by this file, some system services would dynamically
# insert anchors into the main ruleset. These anchors will be added only when
# the system service is used and would removed on termination of the service.
# See pf.conf(5) for syntax.
# com.apple anchor point
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

block all

You need to disable System Integrity Protection to set up pf to enable at boot. This can only be done from recovery mode.

Set the nvram to boot to recovery mode.

sudo nvram "recovery-boot-mode=unused"

reboot to recovery

sudo reboot recovery

Using terminal in recovery mode

csrutil disable

Your system should now be booted as normal and you can check if System Integrity Protection is disabled

csrutil status

You should expect it to say: System Integrity Protection status: disabled.

Now edit the plist to look like below. Specifically adding the <string>-e</string> which enables it on boot.

sudo nano /System/Library/LaunchDaemons/com.apple.pfctl.plist
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
&lt;plist version="1.0">

Now clean up after yourself and turn System Integrity Protection back on.

sudo nvram "recovery-boot-mode=unused"
sudo reboot recovery
csrutil enable