WireGuard: Difference between revisions

Tie-ling (talk | contribs)
manually start and stop wg0
Tie-ling (talk | contribs)
restructure text
Line 15: Line 15:
traffic on a per user basis.  For example, you can route all torrenting traffic
traffic on a per user basis.  For example, you can route all torrenting traffic
through a wireguard tunnel, see below.
through a wireguard tunnel, see below.
systemd.network is recommended due to its powerful configuration interface.
wg-quick is suitable for common usage patterns.  networking.wireguard seems to
have issues with routing.  NetworkManager does not supoort Proxy server setup, and
is cubersome to use.
Skip to Generate Keys section if you are in a hurry.


= Use cases =
= Use cases =
Line 43: Line 50:
     text = "nameserver ::1";
     text = "nameserver ::1";
   };
   };
}
</syntaxhighlight>
=== Proxy DNS with dnsmasq ===
You can also use the proxy server as DNS server with
dnsmasq.
<syntaxhighlight lang="nix">
{
  networking.firewall = {
    allowedTCPPorts = [ 53 ];
    allowedUDPPorts = [ 53 ];
  };
  services = {
    dnsmasq = {
      enable = true;
      settings.interface = "wg0";
    };
  };
}
</syntaxhighlight>
For wg-quick peer, use the
following option
<syntaxhighlight lang="nix">
{
  networking.wg-quick.interfaces.wg0.dns =
  [ {internal v4 & v6 ip addr of server} ];
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 144: Line 121:
   };
   };
</syntaxHighlight>
</syntaxHighlight>
= networking.wireguard =
Note: does not automatically configure routes, see comments.
== Peer setup ==
<syntaxhighlight lang="nix">
{ config, ... }:
{
  age.secrets.wg-key-peer0 = {
    file = "./secrets/wg-key-peer0.age";
  };
  networking.firewall.allowedUDPPorts = [ 51820 ];
  networking.wireguard = {
    enable = true;
    interfaces = {
      # network interface name.
      # You can name the interface arbitrarily.
      wg0 = {
        # the IP address and subnet of this peer
        ips = [ "fd31:bf08:57cb::9/128" "192.168.26.9/32" ];
        # WireGuard Port
        # Must be accessible by peers
        listenPort = 51820;
        # Path to the private key file.
        #
        # Note: can also be included inline via the privateKey option,
        # but this makes the private key world-readable;
        # using privateKeyFile is recommended.
        privateKeyFile = config.age.secrets.wg-key-laptop.path;
        peers = [
          {
            name = "home nas";
            publicKey = "ejmbag/fcc9OLp8K62zfV0NCbp056DnA0qpNixLXwCo=";
            allowedIPs = [
              "fd31:bf08:57cb::8/128"
              "192.168.26.8/32"
            ];
            endpoint = "192.168.1.56: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;
          }
        ];
      };
    };
}
# it’s not imperative but it does not know how to do it :
# sudo ip route add 11.111.11.111 via 192.168.1.11 dev wlo1
# the ip adresse 11: external and 192: local.
</syntaxhighlight>
== Proxy server setup ==
Same as peer setup, skip the endpoint option, with the following
addition, Remember to update the internal IP addresses in the script:
<syntaxhighlight lang="nix">
{
  # enable NAT
  networking.nat = {
    enable = true;
    enableIPv6 = true;
    externalInterface = "ens6";
    internalInterfaces = [ "wg0" ];
  };
  networking.wireguard.interfaces.wg0 = {
      # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
      postSetup = ''
        ${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 eth0 -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 eth0 -j MASQUERADE
      '';
      # Undo the above
      postShutdown = ''
        ${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 eth0 -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 eth0 -j MASQUERADE
      '';
  };
}
</syntaxhighlight>
== Proxy client setup ==
Same as peer setup, specify proxy server ip or domain in the endpoint
option.  Use <code>[ "0.0.0.0/0" "::/0" ]</code> as allowed IPs.
= wg-quick =
== Peer setup ==
<syntaxhighlight lang="nix">
{
  networking.wg-quick.interfaces = {
    wg0 = {
      address = [
        "fd31:bf08:57cb::9/128"
        "192.168.26.9/32"
      ];
      # use dnscrypt, or proxy dns as described above
      dns = [ "127.0.0.1" ];
      privateKeyFile = config.age.secrets.wg-key-laptop.path;
      peers = [
        {
          # bt wg conf
          publicKey = "ejmbag/fcc9OLp8K62zfV0NCbp056DnA0qpNixLXwCo=";
          allowedIPs = [
            "fd31:bf08:57cb::8/128"
            "192.168.26.8/32"
          ];
          endpoint = "192.168.1.56:51820";
        }
      ];
    };
  };
}
</syntaxhighlight>
== Proxy server setup ==
Same as peer setup, skip the endpoint option, with the following
addition:
<syntaxhighlight lang="nix">
{
  # enable NAT
  networking.nat = {
    enable = true;
    enableIPv6 = true;
    externalInterface = "ens6";
    internalInterfaces = [ "wg0" ];
  };
  networking.wg-quick.interfaces = {
    wg0 = {
      # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
      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 eth0 -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 eth0 -j MASQUERADE
      '';
      # Undo the above
      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 eth0 -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 eth0 -j MASQUERADE
      '';
    };
  };
}
</syntaxhighlight>
== Proxy client setup ==
Same as peer setup, specify proxy server ip or domain in the endpoint
option.  Use <code>[ "0.0.0.0/0" "::/0" ]</code> as allowed IPs.
Optionally, configure proxy server as DNS server as described above.
== Manually start and stop wg-quick ==
The above steps will set up a <tt>wg-quick-wg0.service</tt> systemd unit.
You can start it by typing the following in your terminal:
<syntaxHighlight lang="sh">
sudo systemctl start wg-quick-wg0.service
</syntaxHighlight>
To stop the service:
<syntaxHighlight lang="sh">
sudo systemctl stop wg-quick-wg0.service
</syntaxHighlight>
== Reuse existing wg-quick config file ==
If you have WireGuard configuration files that you want to use as-is
(similarly how you would
[https://wiki.debian.org/WireGuard#Step_2_-_Configuration configure
WireGuard e.g. in Debian], without converting them to a declarative
NixOS configuration, you can also configure <code>wg-quick</code> to
use them. For example, if you have a configuration file
<code>/etc/nixos/wireguard/wg0.conf</code>, add the following line to
your <code>configuration.nix</code>:
<syntaxHighlight lang="nix">
networking.wg-quick.interfaces.wg0.configFile = "/etc/nixos/files/wireguard/wg0.conf";
</syntaxHighlight>
This will set up a <code>wg-quick-wg0.service</code> systemd unit.


= systemd.network =
= systemd.network =
Line 616: Line 386:
   ]
   ]
</syntaxhighlight>
</syntaxhighlight>
= wg-quick =
== Peer setup ==
<syntaxhighlight lang="nix">
{
  networking.wg-quick.interfaces = {
    wg0 = {
      address = [
        "fd31:bf08:57cb::9/128"
        "192.168.26.9/32"
      ];
      # use dnscrypt, or proxy dns as described above
      dns = [ "127.0.0.1" ];
      privateKeyFile = config.age.secrets.wg-key-laptop.path;
      peers = [
        {
          # bt wg conf
          publicKey = "ejmbag/fcc9OLp8K62zfV0NCbp056DnA0qpNixLXwCo=";
          allowedIPs = [
            "fd31:bf08:57cb::8/128"
            "192.168.26.8/32"
          ];
          endpoint = "192.168.1.56:51820";
        }
      ];
    };
  };
}
</syntaxhighlight>
== Proxy server setup ==
Same as peer setup, skip the endpoint option, with the following
addition:
<syntaxhighlight lang="nix">
{
  # enable NAT
  networking.nat = {
    enable = true;
    enableIPv6 = true;
    externalInterface = "ens6";
    internalInterfaces = [ "wg0" ];
  };
  networking.wg-quick.interfaces = {
    wg0 = {
      # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
      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 eth0 -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 eth0 -j MASQUERADE
      '';
      # Undo the above
      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 eth0 -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 eth0 -j MASQUERADE
      '';
    };
  };
}
</syntaxhighlight>
== Proxy client setup ==
Same as peer setup, specify proxy server ip or domain in the endpoint
option.  Use <code>[ "0.0.0.0/0" "::/0" ]</code> as allowed IPs.
Optionally, configure proxy server as DNS server as described above.
=== Proxy DNS with dnsmasq ===
You can also use the proxy server as DNS server with
dnsmasq.
<syntaxhighlight lang="nix">
{
  networking.firewall = {
    allowedTCPPorts = [ 53 ];
    allowedUDPPorts = [ 53 ];
  };
  services = {
    dnsmasq = {
      enable = true;
      settings.interface = "wg0";
    };
  };
}
</syntaxhighlight>
For wg-quick peer, use the
following option
<syntaxhighlight lang="nix">
{
  networking.wg-quick.interfaces.wg0.dns =
  [ {internal v4 & v6 ip addr of server} ];
}
</syntaxhighlight>
== Manually start and stop wg-quick ==
The above steps will set up a <tt>wg-quick-wg0.service</tt> systemd unit.
You can start it by typing the following in your terminal:
<syntaxHighlight lang="sh">
sudo systemctl start wg-quick-wg0.service
</syntaxHighlight>
To stop the service:
<syntaxHighlight lang="sh">
sudo systemctl stop wg-quick-wg0.service
</syntaxHighlight>
== Reuse existing wg-quick config file ==
If you have WireGuard configuration files that you want to use as-is
(similarly how you would
[https://wiki.debian.org/WireGuard#Step_2_-_Configuration configure
WireGuard e.g. in Debian], without converting them to a declarative
NixOS configuration, you can also configure <code>wg-quick</code> to
use them. For example, if you have a configuration file
<code>/etc/nixos/wireguard/wg0.conf</code>, add the following line to
your <code>configuration.nix</code>:
<syntaxHighlight lang="nix">
networking.wg-quick.interfaces.wg0.configFile = "/etc/nixos/files/wireguard/wg0.conf";
</syntaxHighlight>
This will set up a <code>wg-quick-wg0.service</code> systemd unit.
= networking.wireguard =
Note: does not automatically configure routes, see comments.
== Peer setup ==
<syntaxhighlight lang="nix">
{ config, ... }:
{
  age.secrets.wg-key-peer0 = {
    file = "./secrets/wg-key-peer0.age";
  };
  networking.firewall.allowedUDPPorts = [ 51820 ];
  networking.wireguard = {
    enable = true;
    interfaces = {
      # network interface name.
      # You can name the interface arbitrarily.
      wg0 = {
        # the IP address and subnet of this peer
        ips = [ "fd31:bf08:57cb::9/128" "192.168.26.9/32" ];
        # WireGuard Port
        # Must be accessible by peers
        listenPort = 51820;
        # Path to the private key file.
        #
        # Note: can also be included inline via the privateKey option,
        # but this makes the private key world-readable;
        # using privateKeyFile is recommended.
        privateKeyFile = config.age.secrets.wg-key-laptop.path;
        peers = [
          {
            name = "home nas";
            publicKey = "ejmbag/fcc9OLp8K62zfV0NCbp056DnA0qpNixLXwCo=";
            allowedIPs = [
              "fd31:bf08:57cb::8/128"
              "192.168.26.8/32"
            ];
            endpoint = "192.168.1.56: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;
          }
        ];
      };
    };
}
# it’s not imperative but it does not know how to do it :
# sudo ip route add 11.111.11.111 via 192.168.1.11 dev wlo1
# the ip adresse 11: external and 192: local.
</syntaxhighlight>
== Proxy server setup ==
Same as peer setup, skip the endpoint option, with the following
addition, Remember to update the internal IP addresses in the script:
<syntaxhighlight lang="nix">
{
  # enable NAT
  networking.nat = {
    enable = true;
    enableIPv6 = true;
    externalInterface = "ens6";
    internalInterfaces = [ "wg0" ];
  };
  networking.wireguard.interfaces.wg0 = {
      # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
      postSetup = ''
        ${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 eth0 -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 eth0 -j MASQUERADE
      '';
      # Undo the above
      postShutdown = ''
        ${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 eth0 -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 eth0 -j MASQUERADE
      '';
  };
}
</syntaxhighlight>
== Proxy client setup ==
Same as peer setup, specify proxy server ip or domain in the endpoint
option.  Use <code>[ "0.0.0.0/0" "::/0" ]</code> as allowed IPs.


= NetworkManager Proxy client setup =
= NetworkManager Proxy client setup =