OpenVPN

From NixOS Wiki
Revision as of 21:21, 24 October 2017 by imported>HLandau (Created page with " === VPN Client === Auto-starting openvpn on Nixos can easily be done by enabling it in the configuration nix. Just place the configs where you want them to have and set it up...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

VPN Client

Auto-starting openvpn on Nixos can easily be done by enabling it in the configuration nix. Just place the configs where you want them to have and set it up like below.

services.openvpn.servers = {
    officeVPN  = { config = '' config /root/nixos/openvpn/officeVPN.conf ''; };
    homeVPN    = { config = '' config /root/nixos/openvpn/homeVPN.conf ''; };
    serverVPN  = { config = '' config /root/nixos/openvpn/serverVPN.conf ''; };
};

This will start three vpn instances; more can be added. Also make sure that you use absolute path for certs and keys if you don't have integreated in the config files.

In case you want to mount filesystems through the vpn, then on shutdown there will be a 90 second timeout. However, newer systemd you can set mount options that will require systemd to first umount the mount before closing the vpn connection.

Just enhance the options with the following option "x-systemd.requires=openvpn-officeVPN.service".

This would then look like this:

fileSystems."/mnt/office" = {
    device = "//10.8.0.x/Share";
    fsType = "cifs";
    options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" "x-systemd.requires=openvpn-officeVPN.service" ];
};
fileSystems."/mnt/home" = {
    device = "//10.9.0.x/Share";
    fsType = "cifs";
    options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" "x-systemd.requires=openvpn-homeVPN.service" ];
};

So basically the value for the x-systemd.requires option is openvpn-{name}.service

If you want to run OpenVPN clients in nixos declarative containers, be sure to set enableTun option.

VPN Server

Simple one-client VPN Gateway server

One of the main use cases to run a VPN server is to provide a secure gateway to the internet for the connecting clients. This example builds a one-client VPN gateway in line with the OpenVPN Static Key Mini How-To. The Pro is that only a single static key is required.

let
  # generate via openvpn --genkey --secret static.key
  client-key = "/root/openvpn-laptop.key";
  domain = "vpn.localhost.localdomain";
  vpn-dev = "tun0";
  port = 1194;
in {
  boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
  networking.nat = {
    enable = true;
    externalInterface = <your-server-out-itf>;
    internalInterfaces  = [ vpn-dev ];
  };
  networking.firewall.trustedInterfaces = [ vpn-dev ];
  networking.firewall.allowedUDPPorts = [ port ];
  environment.systemPackages = [ pkgs.openvpn ]; # for key generation
  services.openvpn.servers.smartphone.config = ''
    dev ${vpn-dev}
    proto udp
    ifconfig 10.8.0.1 10.8.0.2
    secret ${client-key}
    port ${toString port}
    cipher AES-256-CBC
    comp-lzo

    keepalive 10 60
    ping-timer-rem
    persist-tun
    persist-key
  '';

  environment.etc."openvpn/smartphone-client.ovpn" = {
    text = ''
      client
      dev tun
      remote "${domain}"
      ifconfig 10.8.0.1 10.8.0.2
      port ${toString port}

      cipher AES-256-CBC
      comp-lzo
      keepalive 10 60
      resolv-retry infinite
      nobind
      persist-key
      persist-tun
      secret [inline]

    '';
    mode = "700";
  };
  system.activationScripts.openvpn-addkey = ''
    f="/etc/openvpn/smartphone-client.ovpn"
    if ! grep -q '<secret>' $f; then
      echo "appending secret key"
      echo "<secret>" >> $f
      cat ${client-key} >> $f
      echo "</secret>" >> $f
    fi
  '';
}