Killswitch for proxy/vpn

This discussion on Qubes OS forums goes into details of creating a proxy-vm. I suppose it would be beneficial to add a killswitch on top of this to prevent IP leaks in case of a proxy failure, or before the tun0 interface is fully initialized. Here’s how:

After setting up the proxy-vm as described in the guide above, append the following to /rw/config/rc.local

# Killswitch
nft add table inet killswitch
nft add chain inet killswitch output '{ type filter hook output priority 0; policy drop; }'
nft add rule inet killswitch output oif lo accept
nft add rule inet killswitch output oifname "tun0" accept
nft add rule inet killswitch output oifname "vif*" accept
nft add rule inet killswitch output ip daddr <YOUR PROXY IP> tcp dport <YOUR PROXY PORT> accept
nft add chain inet killswitch input '{ type filter hook input priority 0; policy drop; }'
nft add rule inet killswitch input iif lo accept
nft add rule inet killswitch input iifname "tun0" accept
nft add rule inet killswitch input iifname "vif*" accept
nft add rule inet killswitch input ct state established,related accept
nft add chain inet killswitch forward '{ type filter hook forward priority 0; policy drop; }'
nft add rule inet killswitch forward iifname "vif*" oifname "tun0" accept
nft add rule inet killswitch forward iifname "tun0" oifname "vif*" accept
nft add rule inet killswitch forward ct state established,related accept

# Launch proxy
/usr/local/bin/sing-box run -c /etc/sing-box/config.json
  • Don’t forget to replace the placeholders with your proxy IP and port.
  • Use the rc.local script instead of directly editing /etc/nftables.conf or tampering with nftables.service, because it can easily lead to breakage of Qubes networking and is not sane.
  • The vif* interface corresponds to VMs that use the VM in question (vm-proxy) as their networking VM, so these requests should be routed to tun0.
  • tun0 here also uses oifname and iifname so that nftables works correctly even before the tun0 interface is initialized by sing-box.
  • If more proxies are added, just duplicate the line where the proxy IP and port are specified, with the new address.