How to setup wireguard VPN with firewalld?

I’m current trying to set up my Fedora 33 Workstation laptop as a wireguard VPN client to route all my internet traffic through my employers wireguard server. They have provided me with the following configuration file, which I placed into /etc/wireguard/wg0.conf:

[Interface]
PrivateKey = <hidden>
Address = 141.26.29.47/32, 2001:4c80:50:100::1D2F/128
DNS = 141.26.64.60
MTU = 1380
   
[Peer]
PublicKey = <hidden>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = wireguard.uni-koblenz.de:51820

However, after I start the VPN connection via

$ sudo wg-quick up wg0

I am no longer able to access anything on the Internet, e.g. pinging Google times out:

$ ping google.de
PING google.de(muc12s03-in-x03.1e100.net (2a00:1450:4016:802::2003)) 56 data bytes
# No further output

I have diagnosed the problem so far in that it is related to firewalld. If I stop it everything works as expected, i.e. internet is accessible and routed through my employer:

$ sudo systemctl stop firewalld

I do now know much about firewalld, but since it’s enabled by default on Fedora, I would like to keep it so. I have tried searching the web a bit for how to set it up, but have so far been unsuccessful. I have added a port for 51820/udp and turned on masquerading for both the FedoraWorkstation and the default zone:

$ firewall-cmd --list-all
FedoraWorkstation (active)
  target: default
  icmp-block-inversion: no
  interfaces: wlp0s20f3
  sources: 
  services: dhcpv6-client mdns samba-client ssh
  ports: 1025-65535/udp 1025-65535/tcp 51820/udp
  protocols: 
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

$ firewall-cmd --zone=public --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: dhcpv6-client mdns ssh
  ports: 51820/udp
  protocols: 
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Additionally, I think I have all required kernel parameters:

$ sysctl -a
# Manually truncated
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.wg0.forwarding = 1
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.wg0.forwarding = 1

Last, I don’t think this is a selinux problem. When I run setenforce 0 before doing wg-quick up wg0 I still see the exact same behavior.

In case this is relevant, here is some information on my system:

$ sudo wg
interface: wg0
  public key: (hidden)
  private key: (hidden)
  listening port: 34874 # port seems to be random for every new connection
  fwmark: 0xca6c # seems to at least change between this and 0xcc48

peer: (hidden)
  endpoint: [2001:4c80:50:52::61e]:51820
  allowed ips: 0.0.0.0/0, ::/0
  transfer: 0 B received, 148 B sent

$ uname -r
5.9.16-200.fc33.x86_64

Does anybody what I’m missing?

nmcli connection import type wireguard file /path/to/wg.conf

WireGuard in NetworkManager – Thomas Haller's Blog

Yes, I have also tried that. I see the exact same behavio, when I start the connection with

nmcli connection up wg0

or with

wg-quick up wg0

Try to use IPv4-only endpoint instead of the domain name.

I am not sure whether I understand what you mean. I just tried switchting the line in /etc/wireguard/wg0.conf from

Endpoint = wireguard.uni-koblenz.de:51820

to

Endpoint = 141.26.6.30:51820

but I still see the exact same behavior.

Just to reiterate: if I disable firewalld the VPN connection works without problems. So I don’t think the problem lies in the wireguard configuration. Rather I think that I somehow need to tell firewalld to not block wireguard.

I’m not following any specific guide, I tried googling lots of stuff. I also found the one you linked to, but unfortunately does not include much in regards to client config. I’m pretty sure I set up anything it mentions there.

Besides as this is my employers VPN server, the server is outside of my control in this case.

That’s weird, because WG client traffic is supposed to be outgoing.
Outgoing traffic should not be subjected to firewall restrictions by default.
I personally use a dual-stack WG tunnel with default firewall settings.

without specific error there isn’t much to do here, There must be a trace in the system logs to give you a clue/idea to find what is going on?.

  1. Open a terminal and execute journalctl -f
  2. Try to connect
  3. See if you find any value information

References

Regards.,

1 Like

Ok, I just tried to see whether I can produce some logs for this. Here is the output of journalctl -f while I performed the following:

ping google.com # worked
systemctl start wg-quick@wg0
ping google.com # did not work
systemctl stop firewalld
ping google.com # worked
systemctl start firewalld
ping google.com # did not work
systemctl stop wg-quick@wg0
ping google.com # worked

From looking through the logs, there doesn’t seem to be anything specific to the pings failing, and I wouldn’t have suspected there to be anything about that. Does anyone know, how I could debug this better? That is, make ping or something similar log where it is hanging?

To my eyes, here are the lines that could be relevant from the log:

Jan 13 16:43:18 razorback systemd-resolved[1960]: Using degraded feature set UDP instead of UDP+EDNS0 for DNS server 141.26.64.60.
Jan 13 16:43:33 razorback systemd-resolved[1960]: Using degraded feature set TCP instead of UDP for DNS server 141.26.64.60.
...
Jan 13 16:43:48 razorback firewalld[21610]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w10 -D FORWARD -i docker0 -o docker0 -j DROP' failed: iptables: Bad rule (does a matching rule exist in that chain?).

For the first two lines I tried googling for wireguard Using degraded feature set and found some GitHub issues. But trying stuff systemctl restart systemd-resolved and similar, did not change the behavior that I’m observing.

For the last line, this seems to be from me setting up Docker according to the article on Fedora Magazine. That is, a few days before I ran:

sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-masquerade

Not sure, if this could be related, but I can’t see why right now.

wireguard is embeded module in the kernel, and I found this:


This uses Linux kernel dyamic debug features

https://www.kernel.org/doc/html/latest/admin-guide/dynamic-debug-howto.html

This asumes that debugfs is mounted under /sys/kernel/debug

Enable WireGuard debug

echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control

Disable WireGuard debug

echo 'module wireguard -p' | sudo tee /sys/kernel/debug/dynamic_debug/control

View Logs

dmesg

or

sudo journalctl -f

Regards.,

Thanks for taking the time and helping, btw!

I ran the same commands again, this time with exact time info and using that dynamic debug freature for Wireguard you posted:

21:35:11 [root@razorback ~]$ ping google.de
PING google.de(fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003)) 56 data bytes
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=1 ttl=119 time=16.9 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=2 ttl=119 time=15.5 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=3 ttl=119 time=15.1 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=4 ttl=119 time=14.9 ms
^C
--- google.de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 14.864/15.577/16.860/0.769 ms
21:36:54 [root@razorback ~]$ systemctl start wg-quick@wg0
21:36:59 [root@razorback ~]$ ping google.de
PING google.de(fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003)) 56 data bytes
^C
--- google.de ping statistics ---
7 packets transmitted, 0 received, 100% packet loss, time 6158ms

21:37:08 [root@razorback ~]$ systemctl stop firewalld
21:37:14 [root@razorback ~]$ ping google.de
PING google.de(fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003)) 56 data bytes
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=1 ttl=114 time=17.4 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=2 ttl=114 time=16.3 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=3 ttl=114 time=18.9 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=4 ttl=114 time=16.5 ms
^C
--- google.de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 16.254/17.243/18.853/1.016 ms
21:37:20 [root@razorback ~]$ systemctl start firewalld
21:37:25 [root@razorback ~]$ ping google.de
PING google.de(fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003)) 56 data bytes
^C
--- google.de ping statistics ---
8 packets transmitted, 0 received, 100% packet loss, time 7184ms

21:37:35 [root@razorback ~]$ systemctl stop wg-quick@wg0
21:37:41 [root@razorback ~]$ ping google.de
PING google.de(fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003)) 56 data bytes
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=1 ttl=119 time=16.5 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=2 ttl=119 time=14.9 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=3 ttl=119 time=16.9 ms
64 bytes from fra16s07-in-x03.1e100.net (2a00:1450:4001:816::2003): icmp_seq=4 ttl=119 time=15.3 ms
^C
--- google.de ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 14.923/15.887/16.853/0.809 ms

dmesg did not yield much, here is what it added during that time:

[17094.088306] wireguard: wg0: Interface created
[17094.126723] wireguard: wg0: Peer 5 created
[17094.148554] wireguard: wg0: Sending keepalive packet to peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17094.148588] wireguard: wg0: Sending handshake initiation to peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17099.170118] wireguard: wg0: Sending handshake initiation to peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17104.175684] wireguard: wg0: Sending handshake initiation to peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17109.249264] wireguard: wg0: Sending handshake initiation to peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17109.264992] wireguard: wg0: Receiving handshake response from peer 5 ([2001:4c80:50:52::61e]:51820/0%0)
[17109.264997] wireguard: wg0: Keypair 4 created for peer 5
[17135.218769] wireguard: wg0: Keypair 4 destroyed for peer 5
[17135.266174] wireguard: wg0: Peer 5 ([2001:4c80:50:52::61e]:51820/0%0) destroyed
[17135.286307] wireguard: wg0: Interface destroyed

And here is the journalctl -f output.
This time the systemd-resolved[1960]: Using degraded feature set does not show up any more, so it seems to be unrelated.

Check before and after connecting the VPN:

ping -4qw3 fedoraproject.org; ping -6qw3 fedoraproject.org; \
ip route get 1; ip route get 1::; firewall-cmd --get-active-zones

Why do you think that you need forwarding?
Forwarding is required for transit traffic only.
Are you using this host as a gateway for other clients?

1 Like

So, it took me a while to figure this out, but I wanted to report my results here in case somebody runs into similar problems.

What caused this was the line Endpoint = wireguard.uni-koblenz.de:51820 in my wg0.conf. On my machine, that domain was resolved to a IPv6 address, and firewalld is blocking IPv6 Wireguard traffic to this for some reason.

In the end, I have settled for a workaround where I have a IPv4 address overwrite for that domain in my /etc/hosts. This is of course not 100% satisfactory, as I still don’t know why/how firewalld is blocking IPv6 Wireguard traffic, but I have already spent enough time on this. Maybe somebody else can debug this further :).

3 Likes

I have similar issues, that’s why I wanted to check your IPv4 and IPv6 connectivity separately.

To be honest, there are 2 issues:

  • WG completely hangs the IPv6 stack after several minutes/hours if I try to provide IPv6 over WG while there’s IPv6 connectivity over WAN, so stopping WG and reconnecting WAN or restarting NM doesn’t help, and it requires rebooting to resolve the issue.

  • WG randomly switches between IPv4 and IPv6 endpoint addresses even when the host has no IPv6 connectivity over WAN, so WG eventually hangs.

My current workaround is basically the same, that is to disable IPv6 connectivity over WAN and use only IPv4 address for the WG endpoint, and this way both IPv4 and IPv6 work fine inside the WG tunnel assuming that the server side provides dual stack connectivity.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.