WireGuard: Difference between revisions

From NixOS Wiki
imported>HLandau
Created page with " === Generate Private / Public Key === Each peer needs to have at least one private and one public key. The keys can be generated on any machine that already has wireguard in..."
 
imported>HLandau
No edit summary
Line 1: Line 1:
=Setting up Wireguard=
==Generate keypair==


=== Generate Private / Public Key ===
Each peer needs to have a public-private keypair. The keys can be generated on any machine that already has Wireguard installed using the <tt>wg</tt> utility. If Wireguard isn't installed yet, it can be made available by adding <tt>wireguard</tt> to <tt>environment.systemPackages</tt> or by running <tt>nix-env -iA wireguard</tt>.
 
Each peer needs to have at least one private and one public key. The keys can be generated on any machine that already has wireguard installed using the wg utility. If wireguard isn't installed yet, it can be added as <code>wireguard</code> in the <code>environment.systemPackages</code> or installed using <code>nix-env -iA wireguard</code>.
 
The creation of the private/public key is rather simple. In the example below a folder <code>wireguard-keys</code> will be generated and the keys put in there.


Creating a keypair is simple:
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
mkdir ~/wireguard-keys
mkdir ~/wireguard-keys
Line 13: Line 12:
</syntaxHighlight>
</syntaxHighlight>


For different connections/roles you can of course generate more private/public keys and name them as you want or you can use the same pair for every connection - it's up to you.
You can create as many keypairs as you like for different connections or roles; it is also possible to reuse the same keypair for every connection.


=== Server Instance ===
==Server setup==
Enable Wireguard on the server via <tt>/etc/nixos/configuration.nix</tt>:
<syntaxHighlight lang="nix">
{
  ...
 
  # Ensure IP forwarding is enabled.
  boot.kernel.sysctl."net.ipv4.ip_forward" = 1;


<syntaxHighlight lang="nix">
  # Enable Wireguard
   networking.wireguard.interfaces = {
   networking.wireguard.interfaces = {
    # "wg0" is the network interface name. You can name the interface arbitrarily.
     wg0 = {
     wg0 = {
      # Determines the IP address and subnet of the server's end of the tunnel interface.
       ips = [ "10.100.0.1/24" ];
       ips = [ "10.100.0.1/24" ];
      # The port that Wireguard listens to. Must be accessible by the client.
       listenPort = 51820;
       listenPort = 51820;
       privateKey = "{server private key}";
 
       peers = [ {
      # Path to the private key file.
        publicKey = "{client public key}";
       #
        allowedIPs = [ "10.100.0.2/32" ];
      # 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 = "path to private key file";
 
       peers = [
        # List of allowed peers.
        {
          # Public key of the peer (not a file path).
          publicKey = "{client public key}";
          # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
          allowedIPs = [ "10.100.0.2/32" ];
        }
       ];
     };
     };
   };
   };
  ...
}
</syntaxHighlight>
</syntaxHighlight>


* wg0: This is the network interface name. You can also use something meaningful like <code>wg_home</code>
==Client setup==
* ips: This defines the server ip and subnet. In this case the server ip will be 10.100.0.1.
* listenPort: The port the server listens to; don't forget to portforward and allow it through the firewall
* privateKey: this is the private key of the server. Instead of <code>privateKey</code> also <code>privateKeyFile</code> could be used to point to the key file.
* peers: That's the list of peers. Wireguard must have each peer that can establish a connection to be listed.
* peers.publicKey: The public key of the peer/client.
* allowedIPs: The list of IPs that can be assigned to the client
 
=== Client Instance ===
 
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
{
  ...
   # Enable Wireguard
   # Enable Wireguard
   networking.wireguard.interfaces = {
   networking.wireguard.interfaces = {
    # "wg0" is the network interface name. You can name the interface arbitrarily.
     wg0 = {
     wg0 = {
      # Determines the IP address and subnet of the client's end of the tunnel interface.
       ips = [ "10.100.0.2/24" ];
       ips = [ "10.100.0.2/24" ];
       privateKey = "{client private key}";
 
       peers = [ {
      # Path to the private key file.
        publicKey = "{server public key}";
      #
        allowedIPs = [ "10.100.0.0/24" ];
       # Note: The private key can also be included inline via the privateKey option,
        endpoint = "{server ip}:51820";
      # but this makes the private key world-readable; thus, using privateKeyFile is
        persistentKeepalive = 25;
      # recommended.
       } ];
      privateKeyFile = "path to private key file";
 
       peers = [
        # For a client configuration, one peer entry for the server will suffice.
        {
          # Public key of the server (not a file path).
          publicKey = "{server public key}";
 
          # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
          # For a server peer this should be the whole subnet.
          allowedIPs = [ "10.100.0.0/24" ];
 
          # Set this to the server IP and port.
          endpoint = "{server ip}:51820";
 
          # Send keepalives every 25 seconds. Important to keep NAT tables alive.
          persistentKeepalive = 25;
        }
       ];
     };
     };
   };
   };
  ...
}
</syntaxHighlight>
</syntaxHighlight>


* wg0: This is the network interface name. You can also use something meaningful like <code>wg_home</code>
Multiple connections can be configured by configuring multiple interfaces under {{nixos:option|networking.wireguard.interfaces}}.
* ips: This defines the client ip
* privateKey: this is the private key of the client/peer. Instead of <code>privateKey</code> also <code>privateKeyFile</code>
* listenPort: The port the server listens to; don't forget to portforward and allow it through the firewall could be used to point to the key file.
* peers: That's the list of peers. Wireguard must have each peer that can establish a connection to be listed. A peer can be a server or another client. In the above exmample it's just a server entry.
* peers.publicKey: The public key of the peer/server.
* allowedIPs: The list of ips that will be routed through the vpn
* endpoint: The server's ip/hostname and port used for connection.
* persistentKeepalive: This is not necessary but it helps to keep the connection alive through NAT.
 
=== More info ===


* More information on the  [https://www.wireguard.com/ "Wireguard homepage"]
=See also=
* Current [https://nixos.org/nixos/options.html#wireguard "supported options"] in NixOS
* [https://www.wireguard.com/ Wireguard homepage]
* To use more than one wireguard connection, just add more wgX blocks to your configuration.nix
* [https://nixos.org/nixos/options.html#wireguard List of Wireguard options supported by NixOS]
* In order for different wg clients to talk to one another, you can enable ip forwarding on the server. All communications will then go through the wg server
* To enable direct peer-to-peer communications, add according peers you want to talk directly to as new peers, add each such peer's <code>publicKey</code> and <code>allowedIPs</code> to the peers section of the vpn.

Revision as of 22:00, 24 October 2017

Setting up Wireguard

Generate keypair

Each peer needs to have a public-private keypair. The keys can be generated on any machine that already has Wireguard installed using the wg utility. If Wireguard isn't installed yet, it can be made available by adding wireguard to environment.systemPackages or by running nix-env -iA wireguard.

Creating a keypair is simple:

mkdir ~/wireguard-keys
umask 077 ~/wireguard-keys
wg genkey > ~/wireguard-keys/private
wg pubkey < ~/wireguard-keys/private > ~/wireguard-keys/public

You can create as many keypairs as you like for different connections or roles; it is also possible to reuse the same keypair for every connection.

Server setup

Enable Wireguard on the server via /etc/nixos/configuration.nix:

{
  ...

  # Ensure IP forwarding is enabled.
  boot.kernel.sysctl."net.ipv4.ip_forward" = 1;

  networking.wireguard.interfaces = {
    # "wg0" is the network interface name. You can name the interface arbitrarily.
    wg0 = {
      # Determines the IP address and subnet of the server's end of the tunnel interface.
      ips = [ "10.100.0.1/24" ];

      # The port that Wireguard listens to. Must be accessible by the client.
      listenPort = 51820;

      # 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 = "path to private key file";

      peers = [
        # List of allowed peers.
        {
          # Public key of the peer (not a file path).
          publicKey = "{client public key}";
          # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
          allowedIPs = [ "10.100.0.2/32" ];
        }
      ];
    };
  };
  ...
}

Client setup

{
  ...
  # 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.100.0.2/24" ];

      # 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 = "path to private key file";

      peers = [
        # For a client configuration, one peer entry for the server will suffice.
        {
          # Public key of the server (not a file path).
          publicKey = "{server public key}";

          # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
          # For a server peer this should be the whole subnet.
          allowedIPs = [ "10.100.0.0/24" ];

          # Set this to the server IP and port.
          endpoint = "{server ip}:51820";

          # Send keepalives every 25 seconds. Important to keep NAT tables alive.
          persistentKeepalive = 25;
        }
      ];
    };
  };
  ...
}

Multiple connections can be configured by configuring multiple interfaces under networking.wireguard.interfaces.

See also