Make Wireguard work (DDNS)

I’m trying to set up wireguard. I’m unable to make it connect. The wiki page appears to be partially wrong. And I’m not particularly knowledgeable in the networking department.

I’ve tried both the “wireguard” and “wg-quick” methods of setting it up. The “wireguard” way seems to be known to actually be flawed in the wiki, because redirecting all traffic via 0.0.0.0/0 does not work.

Anyway, my setup is a private network behind DDNS, which may be an additional hurdle. So far, the output of wg show on clients indicates that they can resolve the domain name I use in place of an IP to some IPv6 address, though that address is not the same as I see using services like What is My IP Address (is that expected?).

Currently, I’m trying to make the wg-quick method from the wiki work. This is the config:

{
  pkgs,
  lib,
  config,
  ...
}: {
    # Not sure I want / need that but I copied from wiki just in case
    services.dnsmasq = {
      enable = true;
      extraConfig = ''
        interface=wg0
      '';
    };

    networking.nat = {
      enable = true;
      enableIPv6 = true;
      # This is a wifi stick for now. That's correct to use here, no?!
      externalInterface = "wlp0s29u1u1i2";
      internalInterfaces = ["wg0"];
    };

    networking.firewall = {
      allowedTCPPorts = [53];
      allowedUDPPorts = [53 51820];
    };

    networking.wg-quick.interfaces = {
      wg0 = {
        # Determines the IP/IPv6 address and subnet of the client's end of the tunnel interface
        address = ["10.0.0.1/24" "fdc9:281f:04d7:9ee9::1/64"]; # blind copy from wiki
        listenPort = 51820;
        privateKeyFile = "/my/private/key/file";

        postUp = ''
          ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT
          ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.0.0.1/24 -o wlp0s29u1u1i2 -j MASQUERADE
          ${pkgs.iptables}/bin/ip6tables -A FORWARD -i wg0 -j ACCEPT
          ${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o wlp0s29u1u1i2 -j MASQUERADE
        '';

        preDown = ''
          ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT
          ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.0.0.1/24 -o wlp0s29u1u1i2 -j MASQUERADE
          ${pkgs.iptables}/bin/ip6tables -D FORWARD -i wg0 -j ACCEPT
          ${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o wlp0s29u1u1i2 -j MASQUERADE
        '';

        peers = [
          {
            # Laptop
            publicKey = "hirf...akQ=";
            allowedIPs = ["10.0.0.4/32"];
          }
          {
            # Phone
            publicKey = "dL2...nA=";
            allowedIPs = ["10.100.0.2/32"];
          }
        ];
      };
    };
}

The corresponding “Laptop” client config is

{
  config,
  lib,
  ...
}: {
    networking.firewall = {
      allowedUDPPorts = [51820];
    };

    networking.wg-quick.interfaces = {
      wg0 = {
        address = ["10.100.0.4/24"];
        privateKeyFile = "/private/key/file";
        peers = [
          {
            publicKey = "2M...0=";
            allowedIPs = ["0.0.0.0/0" "::/0"];
            endpoint = "my-ddns-domain:51820";
            persistentKeepalive = 25;
          }
        ];
      };
    };
}

This does not establish a connection. In fact, it breaks internet access on the client completely. So I suspect the problem be on the server. The phone (using the wireguard android app) has the same problem.

Does somebody spot the problem in here?

Config looks ok at a glance, though you fell for the unofficial wiki, see WireGuard - NixOS Wiki.

What networking errors do you get? Personally I’d suggest setting this up without NAT first until you can nc through the tunnel between server and client, and only then figure out routing client messages to the outside.

Turns out it was an IP version issue. Wireguard, when given the opportunity, uses IPv6 and does not fall back to IPv4 if that doesn’t work. My old laptop (which I use as the server) doesn’t support IPv6. Hence, when given an explicit IPv4, it works, but does not through my DDNS name. Anyway, setting Wireguard up through my router turned out to be incredibly easy, so I’m doing that now

1 Like