A bash script that creates a kill switch for WireGuard VPN on macOS using PF (Packet Filter). It ensures that your internet traffic only flows through the VPN, preventing any leaks if the VPN connection drops
- Blocks all traffic when VPN is disconnected
- Allows traffic only through WireGuard VPN interface
- Monitors VPN connection status
- Configurable through environment variables
- Automatic cleanup on script termination
- User-friendly status messages
- macOS operating system
- WireGuard installed
- Administrative privileges (sudo)
- Clone this repository or download the
killswitch.sh
script:
git clone https://github.com/Alexandrshy/wireguard-killswitch.git
cd wireguard-killswitch
- Make the script executable:
chmod +x killswitch.sh
Simply run the script:
./killswitch.sh
You can configure the script using environment variables:
VPN_INTERFACE
: WireGuard interface name (default: utun4)WIREGUARD_PORT
: WireGuard server port (default: 51820)PF_RULES_PATH
: Path to PF rules file (default: /etc/pf.anchors/wireguard_killswitch)
Example:
export VPN_INTERFACE=utun4
export WIREGUARD_PORT=51820
export PF_RULES_PATH=/etc/pf.anchors/wireguard_killswitch
To determine which interface your WireGuard VPN is using:
- First, check all available interfaces:
ifconfig | grep utun
-
Note the current interfaces, then connect to your WireGuard VPN
-
Run the same command again:
ifconfig | grep utun
- The new utun interface that appears is your WireGuard interface. Example output:
Before VPN connection:
utun0: flags=8031<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1490
utun1: flags=8031<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
After VPN connection:
utun0: flags=8031<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1490
utun1: flags=8031<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
utun3: flags=8031<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1690 <- This is your WireGuard interface
- Update the VPN_INTERFACE variable in the script or set it via environment variable:
export VPN_INTERFACE="utun3"
To make the kill switch start automatically after system reboot, follow these steps:
- Copy the script to a permanent location:
sudo cp killswitch.sh /usr/local/sbin/killswitch.sh
sudo chmod +x /usr/local/sbin/killswitch.sh
- Create a launch daemon configuration:
sudo mkdir -p /Library/LaunchDaemons
- Create the launch daemon file:
cat << 'EOF' | sudo tee /Library/LaunchDaemons/com.wireguard.killswitch.plist
<?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>Label</key>
<string>com.wireguard.killswitch</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/sbin/killswitch.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/killswitch.log</string>
<key>StandardErrorPath</key>
<string>/var/log/killswitch.error.log</string>
</dict>
</plist>
EOF
- Set correct permissions:
sudo chown root:wheel /Library/LaunchDaemons/com.wireguard.killswitch.plist
sudo chmod 644 /Library/LaunchDaemons/com.wireguard.killswitch.plist
- Load the launch daemon:
sudo launchctl load -w /Library/LaunchDaemons/com.wireguard.killswitch.plist
- Verify the launch daemon is running:
sudo launchctl list | grep com.wireguard.killswitch
- To stop the service:
launchctl unload /Library/LaunchDaemons/com.wireguard.killswitch.plist
- To disable autostart:
launchctl unload /Library/LaunchDaemons/com.wireguard.killswitch.plist
Check the log files for any issues:
tail -f /var/log/killswitch.log
tail -f /var/log/killswitch.error.log
-
Script doesn't start automatically
- Check permissions:
chmod +x /path/to/your/killswitch.sh
- Verify the path in the plist file
- Check log files for errors
- Check permissions:
-
Permission denied errors
- Ensure the script has proper ownership:
sudo chown root:wheel /path/to/your/killswitch.sh
- Make sure the script is executable:
chmod +x /path/to/your/killswitch.sh
- Ensure the script has proper ownership:
- The script requires root privileges to modify firewall rules
- All traffic is blocked if the VPN connection drops
- DNS queries are allowed to facilitate VPN connection
Contributions are welcome! Please feel free to submit a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details