I have wireguard setup using the Linuxserver.io containers. I’ve documented my “server” setup here: Wireguard – self hosted VPN – Roo's View
This works great. I’m able to connect from multiple devices. Some of them I can trivially ‘crawl back’ from the server side - to the remote device that is running wireguard (very handy).
The linuxserver.io docker image - puts the devices on a 10.13.13.0/24 network - so this means my ‘client’ gets say 10.13.13.3 as it’s “IP”. From the server - with the right ‘ip route’ magic - I can then actually reach that remote device that is maybe running SSHD on port 8022 by doing.
ssh -P 8022 user@10.13.13.3
and it works! Magic. Amazing.
So - I have some evidence that I have a working wireguard “server”, but I’m having trouble setting up a NixOS system to be a remote client that reaches back to that server and will let data flow.
I followed the first section in the documentation - specifically the client section. I did generate a new ‘peer’ configuration for my linuxserver.io wireguard server setup… so I had this as my configuration from the wireguard server side…
$cat peer_mynewclient.conf
[Interface]
Address = 10.13.13.9
PrivateKey = SECRET111XXX=
ListenPort = 51820
DNS = 192.168.1.8
[Peer]
PublicKey = SECRET222XXX=
PresharedKey = SECRET333XXX=
Endpoint = example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
With this information - I then was use it as a reference to setup my /etc/nixos/configuration.nix
file to have this.
networking.firewall = {
allowedUDPPorts = [ 51820 ]; # wireguard
};
# Enable WireGuard
networking.wireguard.interfaces = {
# "wg0" is the network interface name. You can name the interface arbitrarily.
wg0 = {
# Determines the IP address and subnet of the client's end of the tunnel interface.
ips = [ "10.13.13.9/32" ];
listenPort = 51820; # to match firewall allowedUDPPorts (without this wg uses random port numbers)
# Path to the private key file.
#
# Note: The private key can also be included inline via the privateKey option,
# but this makes the private key world-readable; thus, using privateKeyFile is
# recommended.
privateKeyFile = "/etc/nixos/secrets/privatekey.wg";
peers = [
# For a client configuration, one peer entry for the server will suffice.
{
# Public key of the server (not a file path).
publicKey = "SECRET222XXX=";
# Forward only particular subnets
allowedIPs = [ "192.168.1.0/22" ];
# Set this to the server IP and port.
endpoint = "example.com:51820"; # ToDo: route to endpoint not automatically configured https://wiki.archlinux.org/index.php/WireGuard#Loop_routing https://discourse.nixos.org/t/solved-minimal-firewall-setup-for-wireguard-client/7577
# Send keepalives every 25 seconds. Important to keep NAT tables alive.
persistentKeepalive = 25;
}
];
};
};
And yes, I put the SECRET111XXX=
into the file /etc/nixos/secrets/privatekey.wg
At this point - my NixOS machine appears to create a wireguard tunnel from it - to my existing server. On the server side I can query docker exec -it wireguard wg show
and see that it is connected.
On the NixOS client - it seems that it’s setup too
$ ifconfig -a wg0
wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420
inet 10.13.13.9 netmask 255.255.255.255 destination 10.13.13.9
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 586 bytes 86728 (84.6 KiB)
TX errors 0 dropped 31 overruns 0 carrier 0 collisions 0
but… I can’t seem to ping from the client to the server (network)
$ ping 192.168.1.99
PING 192.168.1.99 (192.168.1.99) 56(84) bytes of data.
^C
--- 192.168.1.99 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1007ms
On the client - I can see sudo ip route
showing me that indeed, I have a route defined
$ sudo ip route
192.168.1.0/22 dev wg0 scope link
I’ve also tried turning off the firewall entirely on the NixOS client
networking.firewall.enable = false;
Still no joy.
Additionally - but only a bonus - I can’t seem to crawl back from the server side.
$ ping 10.13.13.9
PING 10.13.13.9 (10.13.13.9) 56(84) bytes of data.
^C
--- 10.13.13.9 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1024ms
but this same ‘ping’ works for other clients that I have running and connected via wireguard.
This must be some sort of route/firewall issue on NixOS – but I’m just so confused.
I’ve reviewed the most relevant post - but it doesn’t seem to apply? Or I’m confused as to the ‘solution’.