Wireguard Client & iptables

Thought it might be easier to create a new topic, instead of using an old guide: this one.

Basic information

DietPi version:

G_DIETPI_VERSION_CORE=8
G_DIETPI_VERSION_SUB=5
G_DIETPI_VERSION_RC=1
G_GITBRANCH=‘master’
G_GITOWNER=‘MichaIng’

Distro version:

bullseye 0

Kernel version:

Linux DietPi 5.15.32-v8+ #1538 SMP PREEMPT Thu Mar 31 19:40:39 BST 2022 aarch64 GNU/Linux

SBC model:

RPi 3 Model B (aarch64)

Power supply used: 5V 2A
SD card used: Samsung FIT 32GB

Additional Information

  • Software: Wireguard Client
  • Freshly installed DietPi and Wireguard client

Steps to reproduce

  1. New Dietpi installation. (Fresh, basic, OpenSSH, changed CPU setting and timezone)
  2. Installed WireGuard as a client
  3. Created a conf file on the Mullvad website: tunnel traffic: Only IPv4, No Killswitch, block all content
  4. Created /etc/wireguard/mullvad.conf
  5. Copied Mullvad conf file to mullvad.conf:

[Interface]
PrivateKey = PrKey
Address = 10.64.56.12/32
DNS = Local IP Pi-Hole
[Peer]
PublicKey = PuKEY
AllowedIPs = 0.0.0.0/0
Endpoint = 185.254.75.3:51820

  1. Started WireGuard (wg-quick up mulvad.conf )
  2. Checked VPN connection: OK (curl ifconfig.me && curl https://am.i.mullvad.net/connected)
  3. Added it to start up: systemctl enable wg-quick@mullvad
  4. Reboot: all OK
  5. Added a killswitch command to mullvad.conf (used it from here:mullvad)

[Interface]
PrivateKey = Key
Address = 10.64.56.12/32
DNS = IP adress Pi-Hole

PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show
%i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables
-I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype !
–dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i
fwmark) -m addrtype ! --dst-type LOCAL -j REJECT && ip6tables -D
OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype !
–dst-type LOCAL -j REJECT

[Peer]
PublicKey = KEY
AllowedIPs = 0.0.0.0/0
Endpoint = 185.254.75.3:51820

  1. Reboot: Pi unreabable

  2. ps Pi also unreachable after only adding this:

[Interface]
PrivateKey = KEY
Address = 10.64.56.12/32
DNS = IP adress Pi-Hole

PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show
%i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

[Peer]
PublicKey = KEY
AllowedIPs = 0.0.0.0/0
Endpoint = 185.254.75.3:51820

Expected behaviour

  • Pi makes a VPN connection
  • Still be able to connect to the Pi (SSH)
  • Killswitch when VPN is offline. (No connection out and Transmission-deamon killed)
  • No IPv6 leaking

Actual behaviour

  • Pi unreachable, but still showing up in network

Extra details

I have read on serveral sites about Wireguard & iptables (most are about setting up WG servers):

This is another step in learning more about iptables and network in generally.

If i only execute the first iptable line, after VPN is running (step 5):

iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

I get this message:
Unable to access interface: No such device
iptables v1.8.7 (nf_tables): mark: bad integer value for option “–mark”, or out of range.

yes because the code line is working inside wireguard config file only as you have a variable %i. This one you need to set manually if you go to execute the code line yourself. Usually it should be wg0.

1 Like

The rules block any outgoing packets that are not tunnelled, hence the Pi isn’t able to answer on any SSH request. You need to add an additional rule to explicitly permit all outgoing SSH packets, or those to your LAN at least.

The LOCAL doesn’t mean LAN here, but loopback/localhost destination only, AFAIK.

2 Likes

You need to add a rule to allow ssh and anything else you need to the dietpi.
iptables -I INPUT -i eth0 -p tcp -s 192.168.0.0/24 --dport 22 -j ACCEPT; iptables -I OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

1 Like

Do I need to add these lines to the mullvad.conf in PostUp?

Or do I add them as persistant iptables?

you can add it into PustUp part and to revert into PostDown.

BTW: there is no need to do screen prints. You could copy everything from SSH terminal directly :stuck_out_tongue_winking_eye:

Hehe, I don’t have the chance to add it into the confi file yet.
Just wanted to make sure I put it in the right place when I can add it.

I first added only Trendy’s rule and it was fine:

PostUp = iptables -I INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT && iptables -I OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -I INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT && iptables -I OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

But the Pi became unreachable after adding this:

PostUp = iptables -I INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT && iptables -I OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT && iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PostDown = iptables -I INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT && iptables -I OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

ps I changed the IP adress because this computer and the Pi use IP range 192.168.1.XXX

Do it like this:

PostUp = `iptables -I 1 INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j  ACCEPT && iptables -I 1 OUTPUT -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT && iptables -I 2 OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT`
PostDown = `iptables -D INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j  ACCEPT && iptables -D OUTPUT -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT  && iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT`

When I add these lines to the conf file, without rebooting, I get this message:

root@DietPi:/etc/wireguard# wg-quick up mullvad-de21.conf
[#] ip link add mullvad-de21 type wireguard
[#] wg setconf mullvad-de21 /dev/fd/63
[#] ip -4 address add 10.65.134.216/32 dev mullvad-de21
[#] ip link set mtu 1420 up dev mullvad-de21
[#] resolvconf -a tun.mullvad-de21 -m 0 -x
[#] wg set mullvad-de21 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev mullvad-de21 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n
[#] iptables -I 1 INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT && iptables -I 1 OUTPUT -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT && iptables -I 2 OUTPUT ! -o mullvad-de21 -m mark ! --mark $(wg show mullvad-de21 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
iptables v1.8.7 (nf_tables): Invalid rule number INPUT' Try iptables -h’ or ‘iptables --help’ for more information.
[#] resolvconf -d tun.mullvad-de21 -f
[#] iptables-restore -n
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip link delete dev mullvad-de21

I guess the INPUT rule #1 already exist and can’t be set again.

Can it be fixed by replacing rule #1 with #2 and rule #2 with #3?
Or do we need to change more stuff?

root@DietPi:/etc/wireguard# sudo iptables -S INPUT
-P INPUT ACCEPT

There aren’t any rules listed. Nothing is listed when I use the command “sudo iptables -S”

I placed the numbers behind INPUT / OUTPUT, that solved the issue.

2 Likes

When I kill wireguard, this happens and I cannot access the pi anymore:

root@DietPi:/etc/wireguard# wg-quick down mullvad-de21
[#] systemctl stop transmission-daemon
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip link delete dev mullvad-de21
[#] resolvconf -d tun.mullvad-de21 -f
[#] iptables-restore -n
[#] iptables -D INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j  ACCEPT && iptables -D OUTPUT -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT  && iptables -D OUTPUT ! -o mullvad-de21 -m mark ! --mark $(wg show mullvad-de21 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

I guess the PostDown needs some adjustments?

I think I have found the solution:

PostUp = iptables -I INPUT 1 -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j  ACCEPT && iptables -I OUTPUT 1 -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT && iptables -I OUTPUT 2 ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D INPUT -i eth0 -p tcp -s 192.168.1.0/24 --dport 22 -j  ACCEPT && iptables -D OUTPUT -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT  && iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT

Changed place numbers and PostDown to PreDown.

1 Like

New problem:

I am not able to access files from the NAS anymore. The drive is mounted. Is this because of the IP tables?

yes, because you allowed SSH only while VPN is connected.

1 Like

Is there a standard NFS port?