3

I want to block all websites except one or two websites (white list) while working for 'productivity' purposes (when I am working only). I know how to block individual websites as shown here http://www.wikihow.com/Block-and-Unblock-Internet-Sites-(On-a-Mac) but I want to block all except one or two (i.e., create a white list).

Can it be done from Terminal? (like blocking apps as in the link)

I would prefer to do it without installing any productivity apps.

2 Answers 2

2

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.

  1. 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.

  2. 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"
    
  3. Parse and test your anchor file to make sure there are no errors:

    sudo pfctl -vnf /etc/pf.anchors/org.user.block.out
    
  4. Now enable the firewall:

    sudo pfctl -f /etc/pf.conf -e
    
  5. 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):

  1. Create a log file:

    sudo touch /etc/log/pf.log
    
  2. Modify syslog.conf by adding a line:

    local2.*                        /var/log/pf.log
    
  3. 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
    
  4. Create a launch daemon /Library/LaunchDaemons/org.user.pflog.plist with the content:

    <?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>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>org.user.pflog</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/pflog.sh</string>
        </array>
        <key>Disabled</key>             
        <false/>
        <key>RunAtLoad</key>
        <true/>
    </dict>
    </plist>
    
  5. Stop pfctl with sudo pfctl -d
  6. 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
    
  7. Load the logger plist:

    sudo launchctl load -w /Library/LaunchDaemons/org.user.pflog.plist
    
  8. Now re-enable the firewall:

    sudo pfctl -f /etc/pf.conf -e
    
  9. 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.

7
  • I have tried all this steps but can access all websites after following all steps. To start with, I did every as it is as you write, that is with wikipedia and stackoverflow and tested after applying the changes if other websites are opening or not.. but they are opening...
    – Umar
    Apr 2, 2016 at 8:48
  • I dont know, how to check it ?
    – Umar
    Apr 2, 2016 at 9:35
  • both the files (org.user.block.out and pf.conf) have an empty new line at the end
    – Umar
    Apr 2, 2016 at 9:45
  • Let us continue this discussion in chat.
    – Umar
    Apr 2, 2016 at 9:54
  • 1
    @Umar Hmm that doesn't work that easy with pf. pf is no "application firewall" like "alf". I think it's possible (this extra firewall already has an anchor in /private/etc/pf.anchors/com.apple) but I think it's complicated. Probably that's better asked in a new question because that's far beyond the scope of this one here.
    – klanomath
    Apr 2, 2016 at 14:46
0

Basically using the same strategy as the linked article you posted but in a slightly different way.

First Get the IP addresses of the sites you want to access

Easiest way is just to ping them from Terminal, ping www.google.com. Record the IP address. If that doesn't give you an IP address, try nslookup nslookup www.google.com. Record the IP address.

Turn your DNS off

Manually turn your DNS server settings to nothing. If you are using DHCP you may need to set a static IP address on your Mac to accomplish this, or do it on your router / DHCP server and renew your IP.

Allow the sites you want to access

Open you hosts file from Terminal, vi /etc/hosts and add the IP address and DNS names of the sites you wish to access

216.58.199.78    www.google.com
157.166.226.25   www.cnn.com

Add these to the end of the file.

When your done being productive

Turn you DNS settings back to normal. You may also want to comment out the lines in the hosts file with a #.

#216.58.199.78    www.google.com
#157.166.226.25   www.cnn.com
5
  • I have tried to implement this. But when I get static IP, all websites are blocked including the one I want to access. For eg., 216.58.199.78 www.google.com
    – Umar
    Mar 29, 2016 at 5:47
  • Can you post what you added to your host file?
    – tyelford
    Mar 29, 2016 at 8:57
  • in beginning, I just added white list to my already black list, but then i erased the black list and now i just type google to see if it works or not .. and this is how it looks 108.177.14.94 www.google.se
    – Umar
    Mar 29, 2016 at 9:18
  • after turning DNS off i still get nothing... i.e no web acess
    – Umar
    Apr 2, 2016 at 7:27
  • I think the issue is there bec as soon as I turn DNS off.. there is no web access what so ever
    – Umar
    Apr 2, 2016 at 8:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .