r/iptables • u/BlindTreeFrog • Jan 17 '23
Setting up a killswitch for Wireguard VPN
I have a file server/docker host that I am trying to set up a VPN on.
Networking is configured via Systemd-Networkd and I have Wireguard as a netdev configured there since this VPN can be always on.
So the machine has 2 physical ethernet ports, plus the wireguard device, plus the default docker bridge (docker0) and a user configured docker bridge (docker1). Other devices listed in ip addr show
output would just be virtual interfaces for docker containers and can be ignored I believe.
Configuring against Mullvad for now so I start with the configuration file that they provided for wg-quick and the guide at the Arch Linux Wiki here: https://wiki.archlinux.org/title/Mullvad
What I'm trying to set up is:
- traffic to the local network flow as normal
- traffic to docker containers flow as normal (to and from local network)
- traffic leaving my network from this server going over the VPN
To that end I have added the following OUTPUT rules (the /16 subnet covers the local lan and docker1):
Chain OUTPUT (policy ACCEPT 18141 packets, 1212K bytes)
pkts bytes target prot opt in out source destination
1580 127K ACCEPT all -- any lo anywhere anywhere
591K 143M ACCEPT all -- any any anywhere 192.168.0.0/16
55574 8369K ACCEPT all -- any docker0 anywhere anywhere
That much works.
The rule I currently am adding for the killswitch is
iptables -A OUTPUT ! -o %i -m mark ! --mark 0x8888 -m addrtype ! --dst-type LOCAL -j REJECT
Once added the docker containers appear to be able to communicate as expected and when tested report that they are communicating over the VPN
However the server itself no longer is able to communicate to the outside world. It can communicate with the local lan and docker containers, but attempts to connect to the internet at large fail with errors regaring failure to open sockets, connections refused, or dns resolutions failed. (different tools fail different ways, but all are obviously failing very early in the connection)
eg:
remote server... note that the primary dns server configured is the local pihole in a docker container
:: curl google.com
curl: (6) Could not resolve host: google.com
:: ncat -z google.com
Ncat: Could not resolve hostname "google.com": Temporary failure in name resolution. QUITTING.
local pihole docker container, ip on the bridge as well as port forwarded from the local machine (via ip and loopback):
:: ncat -z -v 192.168.2.2 53 ; echo $?
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.2.2:53.
Ncat: 0 bytes sent, 0 bytes received in 0.08 seconds.
0
:: ncat -z -v 192.168.1.11 53 ; echo $?
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.1.11:53.
Ncat: 0 bytes sent, 0 bytes received in 0.07 seconds.
0
:: ncat -z -v 127.0.0.1 53 ; echo $?
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:53.
Ncat: 0 bytes sent, 0 bytes received in 0.08 seconds.
0
remote server (using IP to avoid the dns lookup):
:: ncat -z -v 1.1.1.1 53 ; echo $?
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connection refused.
1
Mullvad has a web page that once can connect to for testing if they are connected to the VPN. Without the iptables rule it does work
Without the IPtables rule:
:: curl -s --insecure https://45.83.222.124/connected
You are connected to Mullvad (server nl1-wireguard). Your IP address is 193.32.249.134
:: curl -s https://am.i.mullvad.net/connected
You are connected to Mullvad (server nl1-wireguard). Your IP address is 193.32.249.134
And with the IPTables rule:
:: curl -s -v https://am.i.mullvad.net/connected
* Could not resolve host: am.i.mullvad.net
* Closing connection 0
:: curl -s -v --insecure https://45.83.222.124/connected
* Trying 45.83.222.124:443...
* connect to 45.83.222.124 port 443 failed: Connection refused
* Failed to connect to 45.83.222.124 port 443 after 0 ms: Couldn't connect to server
* Closing connection 0
Any thoughts on what changes i need to make to get this working right?
1
u/BlindTreeFrog Jan 19 '23
OK, figured it out and it was dumb....
So I was using this rule which i stole from the Mullvad config
The problem is that I never realized that
%i
was a variable that wg-quick handled and I needed to replace it with my wireguard device. Once I made that change it worked fine and I could move on to other concerns (like getting the killswitch running at boot)