Wireguard Client with NetworkManager *almost* never connects to Server

Hello everyone! I have a Wireguard server on a NixOS system, which is known working (My Android phone can connect to it). I’d like to tunnel all traffic through it for security while using public wifi. Here’s the relevant server config:

{ pkgs, ... }:
let
  wg-interface = "wg0";
  wg-port = 53; # DNS Port to bypass Port Blockers
in
{
  networking = {
    nat.enable = true;
    nat.enableIPv6 = true;
    nat.externalInterface = "eno1";
    nat.internalInterfaces = [ wg-interface ];
  };
  networking.firewall.allowedUDPPorts = [ wg-port ];

  networking.wireguard.interfaces.${wg-interface} = {
    ips = [ "10.100.0.1/24" ];
    listenPort = wg-port;

    # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
    # For this to work you have to set the dnsserver IP of your router (or dnsserver of choice) in your clients
    postSetup = ''
      ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eno1 -j MASQUERADE
    '';

    # This undoes the above command
    postShutdown = ''
      ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o eno1 -j MASQUERADE
    '';

    privateKeyFile = "/var/lib/wireguard/private.key";
    peers = [
      # Phone
      {
        publicKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";
        allowedIPs = [ "10.100.0.2/32" ];
      }
      # other NixOS machine that almost never works
      {
        publicKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";
        allowedIPs = [ "10.100.0.3/32" ];
      }
    ];
  };
}

Note the Port it runs on. I haven’t tested another port and would like to keep it this way, but it sure is somewhat suspicious.

The client runs NetworkManager. Here’s its relevant config:

networking.networkmanager.enable = true;
networking.firewall.enable = true;
networking.wireguard.enable = true; # make sure the wireguard kernel module is present
networking.firewall.checkReversePath = false; # required for WG

I’ve configured NetworkManager using networkmanagerapplet. Here are the configuration values I used. Note that similar values (different key and allowed IP) work as expected on my phone:

  • interface name: wg
  • a Peer: public key of my server, Allowed IPs: 0.0.0.0/0, ::/0
  • IP addresses: 10.100.0.3/24
  • endpoint 24.134.30.64:53 (feel free to ping, this is my public server’s IP)
  • DNS servers: 1.1.1.1

Here’s the output of nmcli connection show wg: https://paste.rs/nUxVT

This is what shows up in dmesg when I enable the connection under NetworkManager. Note that I’ve enabled debug logging with echo "module wireguard +p" | /sys/kernel/debug/dynamic_debug/control:

[ 1720.615523] wireguard: wg: Interface created
[ 1720.648734] wireguard: wg: Peer 2 created
[ 1720.799100] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1725.877060] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1731.014501] wireguard: wg: Handshake for peer 2 (24.134.30.65:53) did not complete after 5 seconds, retrying (try 2)
[ 1731.014648] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1736.425001] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1741.510292] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1746.886137] wireguard: wg: Handshake for peer 2 (24.134.30.65:53) did not complete after 5 seconds, retrying (try 2)
[ 1746.886322] wireguard: wg: Sending handshake initiation to peer 2 (24.134.30.65:53)
[ 1749.651133] wireguard: wg: Peer 2 (24.134.30.65:53) destroyed
[ 1749.677156] wireguard: wg: Interface destroyed

(I disable the connection again at the end)

The strange thing is, sometimes, it does connect successfully (which I’m noticing by the fact that I have internet access) and then works as expected, tunnelling all traffic for a short while before it breaks again (I need to leave the laptop trying to connect for quite a while for that to happen, though).

Any help would be greatly appreciated. Thanks!

Your description makes it sound like a firewall is triggering on one end or another. I would think with the service provider for the host. Your phone works with this setup when it’s using the same network connection to test?

It may be the client firewall, but I doubt that, as I’ve seen packets going both ways between server and client using wireshark on the client.

I also tried both my phone and this laptop at home and at my Uni’s WLAN network. My phone works with both, my laptop with neither.

I also host the server myself at an office I have access too, I don’t think there should be any firewall there except the server’s NixOS firewall.

I doubt it, too, but try disabling that. I can’t think of anything else! It surely is happening because of the port you chose, but still, you should probably change it temporarily to verify that too.

That didn’t work, but I did find out what the Problem was: it apparently doesn’t like port 53. With some other arbitrary port number, it works perfectly. I’d prefer using port 53 though, as it bypasses port blockers. If anyone has an idea how I could get that working, that would be great.