Creating whitelist of few websites from Terminal
To permanently block outgoing traffic to all domains except some you should create a new anchor file and add it to pf.conf and enable the included pf firewall.


Create an anchor file org.user.block.out in /private/etc/pf.anchors 

sudo touch /private/etc/pf.anchors/org.user.block.out


with the following content and a trailing empty line

#whitelist
mygoodhosts = "{ wikipedia.org, stackexchange.com, 197.10.15.234 }"
#ports to block/pass
myports = "{ 443, 80, 8080 }"

block drop out proto { tcp, udp } from any to any port $myports
pass out proto { tcp, udp } from any to $mygoodhosts port $myports


The additional IP address in mygoodhosts is just an example how to add additional items to the whitelist. The same goes for port 8080 in myports.

To allow complete access to stackexchange.com you have to add some more domains because some items (e.g. javascript) are loaded from third-party domains like ajax.googleapis.com.
Modify the file /private/etc/pf.conf but keep a trailing empty line

original file:

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"


to

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
anchor "org.user.block.out"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "org.user.block.out" from "/etc/pf.anchors/org.user.block.out"

Parse and test your anchor file to make sure there are no errors:

sudo pfctl -vnf /etc/pf.anchors/org.user.block.out

Now enable the firewall:

sudo pfctl -f /etc/pf.conf -e

To disable pf later (after you are done with productive work) simply enter:

sudo pfctl -d



The first two steps have only to be done once. If you want to add or remove a domain in the whitelist, stop the firewall, modify org.user.block.out, parse the anchor file and re-enable the firewall.



To enable logging you have to modify several files and add a launch daemon/shell script (all files created/modified probably need a trailing empty line):


Create a log file:

sudo touch /etc/log/pf.log

Modify syslog.conf by adding a line:

local2.*                        /var/log/pf.log

Add a shell script in /usr/local/bin/pflog.sh witht the content:

#!/bin/sh
# bodged solution to absence of pflogd, ref 'Book of PF' p136

ifconfig pflog0 create
/usr/sbin/tcpdump -lnettti pflog0 | /usr/bin/logger -t pf -p local2.info

Create a launch daemon /Library/LaunchDaemons/org.user.pflog.plist with the content:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
    &lt;key&gt;KeepAlive&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;Label&lt;/key&gt;
    &lt;string&gt;org.user.pflog&lt;/string&gt;
    &lt;key&gt;ProgramArguments&lt;/key&gt;
    &lt;array&gt;
        &lt;string&gt;/usr/local/bin/pflog.sh&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;Disabled&lt;/key&gt;             
    &lt;false/&gt;
    &lt;key&gt;RunAtLoad&lt;/key&gt;
    &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;

Stop pfctl with sudo pfctl -d
Modify the block drop line in /private/etc/pf.anchors/org.user.block.out to:

block drop out log (all) proto { tcp, udp } from any to any port $myports

Load the logger plist:

sudo launchctl load -w /Library/LaunchDaemons/org.user.pflog.plist

Now re-enable the firewall:

sudo pfctl -f /etc/pf.conf -e

Watch pf.log in Console.app!




After a system update or upgrade some of the original files above may have been replaced and you have to reapply all changes.