Blocking traffic bypassing the VPN

Hacker

Professional
Messages
1,046
Reputation
9
Reaction score
733
Points
113
If you use OpenVPN (via thunnelblick or another client) on macOS, you probably know that there is no easy way to prevent using an unsecured network before connecting to a VPN in either the openvpn or thunnelblick settings. In this article, I will tell you about one of the possible solutions to this problem.

Since OpenVPN creates a separate network interface for traffic that must pass through it, we can simply block all traffic to other interfaces, except for one connection, which is used by itself for OpenVPN.

To do this, we will use the PF (Packet Filter) tool, which is built into macOS with OS X 10.7.

A packet filter is a command-line utility that doesn't have a user interface to configure it. So you should open your most liked terminal and then create two configuration files with the following contents.

/etc/pf.anchors/me.dolzhenko.pf.conf:
Code:
anchor "me.dolzhenko.pf"
load anchor "me.dolzhenko.pf" from "/etc/pf.anchors/me.dolzhenko.pf.rules"

/etc/pf.anchors/me.dolzhenko.pf.rules:
Code:
# Options
set block-policy drop
set fingerprints "/etc/pf.os"
set ruleset-optimization basic
set skip on lo0

# Normalization
# Scrub incoming packets
scrub in all no-df

# Filtering
# Antispoof
antispoof log quick for { lo0 en0 en2 }

# Block everything by default
block in log
block out log

# Block to/from illegal destinations or sources
block in log quick from no-route to any

# Pass packets that go through TUN interfaces
pass in quick on { utun0 utun1 } all
pass out quick on { utun0 utun1 } all

# Pass packets that go to/from VPN server
vpn = "0.0.0.0"

Note: do not forget to replace the line "VPN=0.0.0.0" with the IP of your VPN server.

To verify that the configuration file is correct, type the following command in the terminal:
Code:
$ sudo pfctl -n -v -f /etc/pf.anchors/me.dolzhenko.pf.conf

If everything is correct and there are no errors, you can apply packet filtering to the rules described in the configuration file. To do this, simply enter the following command:
Code:
$ sudo pfctl -e -v -f /etc/pf.anchors/me.dolzhenko.pf.conf

And check that all of them were applied using the command:
Code:
$ sudo pfctl -a me.dolzhenko.pf -s rules

Now all packets, except those that go through the VPN server, will be blocked. But everything is great, except for one point. After the next reboot, macOS resets the list of filter rules to the default state.

To avoid entering this command manually every time after a reboot, you can register it using the launchd service, which will execute it for you.

To do this, simply create a file with the following contents::

/Library/LaunchDaemons/me.dolzhenko.pf.plist:
Code:
<?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>me.dolzhenko.pf.plist</string>
 <key>Program</key>
 <string>/sbin/pfctl</string>
 <key>ProgramArguments</key>
 <array>
 <string>/sbin/pfctl</string>
 <string>-e</string>
 <string>-f</string>
 <string>/etc/pf.anchors/me.dolzhenko.pf.conf</string>
 </array>

Now you can try restarting your computer and make sure that all the necessary rules have been applied. But before doing this, make sure that all created files belong to the super - user account - root.
 
Top