EDIT: Now that this is solved, a working configuration can be found further down the thread.
Hello, I’m trying to set up WireGuard for the first time in NixOS. The desired outcome is a network namespace that has the WireGuard interface as its only interface, as described in the WireGuard docs.
There have been a couple prior posts here that I’ve referred to over the past few days as I’ve worked on this:
Here’s the relevant configuration:
{ config, pkgs, ... }:
systemd.services."netns@" = {
description = "%I network namespace";
before = [ "network.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.iproute}/bin/ip netns add %I";
ExecStop = "${pkgs.iproute}/bin/ip netns del %I";
};
};
systemd.services.wg = {
description = "wg network interface";
bindsTo = [ "netns@wg.service" ];
requires = [ "network-online.target" ];
after = [ "netns@wg.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
NetworkNamespacePath = "/var/run/netns/wg";
ExecStart = with pkgs; writers.writeBash "wg-up" ''
${iproute}/bin/ip link add wg0 type wireguard
${iproute}/bin/ip link set wg0 netns wg
${iproute}/bin/ip -n wg address add <ipv4 VPN addr/cidr> dev wg0
# ${iproute}/bin/ip -n wg -6 address add <ipv6 VPN addr/cidr> dev wg0
${wireguard}/bin/wg setconf wg0 /root/myVPNprovider.conf
${iproute}/bin/ip -n wg link set wg0 up
${iproute}/bin/ip -n wg route add default dev wg0
# ${iproute}/bin/ip -n wg -6 route add default dev wg0
'';
ExecStop = with pkgs; writers.writeBash "wg-down" ''
${iproute}/bin/ip -n wg route del default dev wg0
# ${iproute}/bin/ip -n wg -6 route del default dev wg0
${iproute}/bin/ip -n wg link del wg0
'';
};
};
The WireGuard config at /root/myVPNprovider.conf
looks like so:
[Interface]
PrivateKey = <my private key>
[Peer]
PublicKey = <VPN provider endpoint pubkey>
AllowedIPs = 0.0.0.0/0,::0/0
Endpoint = <VPN provider IPv4:port>
When I start wg.service
, the wg
namespace is created, wg0
interface exists inside it, and the default route is added. However, I have no connectivity at all inside the wg
namespace; no DNS, no ping, nothing.
Output from ip netns exec wg wg
shows that no handshake has been exchanged, and no traffic is received:
interface: wg0
public key: <my pubkey>
private key: (hidden)
listening port: 53739
peer: <VPN provider endpoint pubkey>
endpoint: <VPN provider IPv4:port>
allowed ips: 0.0.0.0/0, ::/0
transfer: 0 B received, 36.57 KiB sent
ip
info:
[me@pc:~]$ sudo ip -n wg link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/none
[me@pc:~]$ sudo ip -n wg addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet <ipv4 VPN addr/cidr> scope global wg0
valid_lft forever preferred_lft forever
[me@pc:~]$ sudo ip -n wg route
default dev wg0 scope link
I’ve spent many hours working on this, and I feel stuck.
Does anything look wrong? How would you troubleshoot this setup, and what can I try next?