Setup IP forwarding

Yes, forwarding rules for VPN <> Internet. Check out /etc/wireguard/wg0.conf:

PostUp = sysctl net.ipv4.conf.%i.forwarding=1 net.ipv4.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = sysctl net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').accept_ra=2
PostUp = sysctl net.ipv6.conf.%i.forwarding=1 net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostUp = ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.9.0.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE

ip r l 0/0 | mawk '{print $5;exit}' prints the interface name of the default route, hence should be eth0. As you can see, the sysctl-wise IP forwarding is enabled as well, althought only for the particular interfaces, not for all.

Don’t know if it can help but reading wireguard docs I’ve seen the Table option. Can this be used to set the table number and prevent routing tables changing number @trendy?

I rely completely on you guys :smiling_face_with_tear:

If you set this option, WireGuard does not setup its IP rules (for routing all outgoing requests through the VPN), but it needs to be done manually then. It only creates the routing table with the given name.

Oh understood.
Then I have to rely on you guys :grimacing:

I’ve made some progress though:

  • I’ve installed pihole and now setting the RPi4 as both DNS server and gateway on a device allow me to connect and reach all websites. Turning VPN on doesn’t allow me to connect anymore on this device.

  • I still have the Plex problem, on the device which uses the RPi4 as gateway I can’t load Plex at all, either with VPN on or off.

With the VPN switched on what is the output of
iptables-save -c; ip6tables-save -c; nft list ruleset; ip -4 addr; ip -4 ro list table all; ip -4 ru

Here you go :+1:

root@DietPi:~# iptables-save -c; ip6tables-save -c; nft list ruleset; ip -4 addr; ip -4 ro list table all; ip -4 ru
# Generated by iptables-save v1.8.9 (nf_tables) on Sat Nov  4 17:36:59 2023
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[75:21076] -A PREROUTING -p udp -m comment --comment "wg-quick(8) rule for wg0" -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
[22:2792] -A POSTROUTING -p udp -m mark --mark 0xca6d -m comment --comment "wg-quick(8) rule for wg0" -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
COMMIT
# Completed on Sat Nov  4 17:36:59 2023
# Generated by iptables-save v1.8.9 (nf_tables) on Sat Nov  4 17:36:59 2023
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
[0:0] -A PREROUTING -d 10.59.244.2/32 ! -i wg0 -m addrtype ! --src-type LOCAL -m comment --comment "wg-quick(8) rule for wg0" -j DROP
COMMIT
# Completed on Sat Nov  4 17:36:59 2023
# Generated by ip6tables-save v1.8.9 (nf_tables) on Sat Nov  4 17:36:59 2023
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[5:2340] -A PREROUTING -p udp -m comment --comment "wg-quick(8) rule for wg0" -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
[0:0] -A POSTROUTING -p udp -m mark --mark 0xca6d -m comment --comment "wg-quick(8) rule for wg0" -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
COMMIT
# Completed on Sat Nov  4 17:36:59 2023
-bash: nft: command not found
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 192.168.178.42/24 brd 192.168.178.255 scope global dynamic eth0
       valid_lft 863328sec preferred_lft 863328sec
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 10.59.244.2/24 scope global wg0
       valid_lft forever preferred_lft forever
192.168.178.0/24 dev eth0 table 51820 scope link
default dev wg0 table 51821 scope link
default via 192.168.178.1 dev eth0
10.59.244.0/24 dev wg0 proto kernel scope link src 10.59.244.2
192.168.178.0/24 dev eth0 proto kernel scope link src 192.168.178.42
local 10.59.244.2 dev wg0 table local proto kernel scope host src 10.59.244.2
broadcast 10.59.244.255 dev wg0 table local proto kernel scope link src 10.59.244.2
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 192.168.178.42 dev eth0 table local proto kernel scope host src 192.168.178.42
broadcast 192.168.178.255 dev eth0 table local proto kernel scope link src 192.168.178.42
0:      from all lookup local
32764:  from all lookup main suppress_prefixlength 0
32765:  not from all fwmark 0xca6d lookup 51821
32766:  from all lookup main
32767:  from all lookup default

I am out of ideas.
There are no rules in iptables for filtering nor in NAT for the masquerade.
Also there aren’t any nftables.
Wireguard scripts are adding a fwmark on an iprule for looking up to table 51821.
Did you change anything on the wg.conf? Paste it once again because I don’t understand how all this has happened.

Here’s the conf:

[Interface]
PrivateKey = ***
Address = 10.59.244.2/24
PreUp = ip route add 192.168.178.0/24 dev eth0 table 51820
PostDown = ip route del 192.168.178.0/24 dev eth0 table 51820
PostDown = iptables -D FORWARD -i eth0 -o eth0 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE

[Peer]
PublicKey = ***
PresharedKey = ***
Endpoint = publicip:port
AllowedIPs = 0.0.0.0/0, ::0/0

I currently have 2 problems left: DNS not working while VPN is up and Plex not working while VPN is up.

I’ve thought that maybe Plex isn’t working because DNS isn’t working while VPN up as basically I can’t reach most websites if not all.

Also I’ve set Plex to use the eth0 as preferred network interface. Don’t know if it’s related or can help.

Some observations:

  • I’ve 2 devices (TVs) that use the RPi4 as gateway and dns

  • On one, while vpn is either down or up, I can do everything. Plex works only while vpn is down.

  • On the other one, while vpn is down, I can do everything. While vpn is up I cannot reach any websites. Plex works only while vpn is down.

The second device has specific setting to enable/disable ipv6, tried disabling but nothing changed.
Can this maybe cause any problem? Maybe dns/pihole requires specific changes for ipv6? Enable packet forwarding for ipv6?

Maybe the root cause of the problems are the iptables changing number? Is it possible to clear custom tables and start over?

Once again please help me figuring this out as I bought the RPi4 basically specifically for this :sweat_smile:

EDIT: I’ve put a single PostUp and all commands inline separated by ;. Now on first device Plex works even while vpn is up!
The second device is still not working while vpn is up so I really think something ipv6 related.

EDIT2: On first device I cannot reach websites while vpn is up!
I really think something dns while vpn is up or ipv6 related and things should be fine then.

  1. The conf is quite empty, there are no iptables rules to allow forwarding when the tunnel comes up. The rules that @MichaIng mentioned earlier. What does iptables -L -t nat ; iptables -L -t filter return?

  2. Regarding IPv6, is your VPN providing IPv6 address too? What does ip -6 addr show?

  3. Regarding the port number change, what is the Endpoint port that is used?

  4. Regarding the DNS, what is the DNS used by the devices?

Sorry, do I need to add his rules? Btw here the command you asked:
VPN down:

root@DietPi:~# iptables -L -t nat ; iptables -L -t filter
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

VPN UP:

root@DietPi:~# iptables -L -t nat ; iptables -L -t filter
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

This command only returns lo and eth0 interfaces, VPN is up so I suppose no IPv6? Do I need to post and redact any information if needed?

Port? I meant the ip tables number.
The port used is 51820, just like the ip tables number… is this related?

Devices use the RPi4 as gateway and dns server. RPi4 is running piHole with Google DNS and CloudFlare DNS as upstream DNS resolvers (both IPv4 and IPv6).

As usual, thanks in advance! :wink:

Yes, this is completely empty and it is not weird that it is not working.

I suppose so too, but you can verify it with the VPN provider because you have the ::/0 in the allowed IPs.

I meant the port from the configuration. Is it 51820 or 51821?

One thing to test is if the DNS is responding when the VPN is up. From a lan host run a nslookup dietpi.com and see if you get an answer.
Also another thing to check is if you are trying to access the Plex by hostname or by IP.

I need to add all of this right?

PostUp = sysctl net.ipv4.conf.%i.forwarding=1 net.ipv4.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = sysctl net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').accept_ra=2
PostUp = sysctl net.ipv6.conf.%i.forwarding=1 net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.9.0.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostUp = ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.9.0.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE

The port is 51820. Default WireGuard’s port if I remember correctly.

I get an answer from 192.168.178.1 which is my router.

Where can I check this? On the devices I mentioned earlier I just run the Plex app.

yes, but change the prefix from 10.9.0.0/24 to 192.168.178.0/24

Then I don’t know how is the ip rule

deciding to lookup table 51821. Maybe it will be faster to change the commands then:

PreUp = ip route add 192.168.178.0/24 dev eth0 table 51821
PostDown = ip route del 192.168.178.0/24 dev eth0 table 51821

That’s not good, you are supposed to get an answer from the Pi.

And how did you configure on the plex app where is the plex server?

Here’s the new conf, now it doesn’t work at all:

[Interface]
PrivateKey = [REDACTED]
Address = 10.59.244.2/24
PreUp = ip route add 192.168.178.0/24 dev eth0 table 51820
PostUp = sysctl net.ipv4.conf.%i.forwarding=1 net.ipv4.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = sysctl net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').accept_ra=2
PostUp = sysctl net.ipv6.conf.%i.forwarding=1 net.ipv6.conf.$(ip r l 0/0 | mawk '{print $5;exit}').forwarding=1
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -s 192.168.178.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostUp = ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = ip route del 192.168.178.0/24 dev eth0 table 51820
PostDown = iptables -D FORWARD -i eth0 -o eth0 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -s 192.168.178.0/24 -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $(ip r l 0/0 | mawk '{print $5;exit}') -j MASQUERADE

[Peer]
PublicKey = [REDACTED]
PresharedKey = [REDACTED]
Endpoint = PUBLICIP:51820
AllowedIPs = 0.0.0.0/0, ::0/0

Tried this too. No luck. Is there a way to clean the iptables we made and start over?

Tried again and still getting from my router, I really suppose something wrong with dns/pihole on the RPi4 as on devices that use the RPi4 as dns server I can only reach google.com.
PiHole upstream dns servers are google and cloudflare…

If you mean the “friendly name” it’s device’s name so DietPi.
I’ve also set to use the preferred network interface to eth0 (192.168.178.42).

Let’s take a step back. It is getting too complicated like this.
Reboot the RPi to reset everything to defaults.
Don’t start the VPN.
Make sure the lan hosts are using the RPi as DHCP, gateway, and DNS server as you had it configured. That means that if you do nslookup/dig on some lan host, the Pihole must answer all the time. If you ran a traceroute, then the first hop is the RPi.
The Plex server should also work all the time.
Can you confirm these?

Done.

I must be stupid or something as my pc cannot seem to use the RPi4 as dns server, here’s the conf:


I cannot see it under PiHole’s devices.
My router is actually the DHCP server and I just set gateway and dns server on each device.

EDIT: Had to set both IPv4 and IPv6 dns server address to make my pc use the PiHole. Now nslookup dietpi.com returns an answer from PiHole.

I see you are running an AVM FritzBox. Usually there should be an option inside the Router to distribute PiHole as IPv6 DNS server automatically. But this would mean every device inside your network will get PiHole assigned as IPv6 DNS server

Another option is to create a custom configuration for PiHole / dnsmasq to distribute DNSv6 information via RA.

1 Like

Or if you are planning to use the Pihole as gateway only for a couple of lan hosts, maybe it would make sense to just turn off IPv6 for them, or use static settings.

But you can create groups inside Pihole and just create a group for devices which not should use Pihole.