OpenVPN: Difference between revisions

From NixOS Wiki
imported>HLandau
mNo edit summary
imported>Gnidorah
fixes
Line 56: Line 56:
   port = 1194;
   port = 1194;
in {
in {
  boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
   networking.nat = {
   networking.nat = {
     enable = true;
     enable = true;
     externalInterface = <your-server-out-itf>;
     externalInterface = <your-server-out-if>;
     internalInterfaces  = [ vpn-dev ];
     internalInterfaces  = [ vpn-dev ];
   };
   };
Line 71: Line 70:
     secret ${client-key}
     secret ${client-key}
     port ${toString port}
     port ${toString port}
     cipher AES-256-CBC
     cipher AES-256-CBC
    auth-nocache
     comp-lzo
     comp-lzo
     keepalive 10 60
     keepalive 10 60
     ping-timer-rem
     ping-timer-rem
Line 82: Line 83:
   environment.etc."openvpn/smartphone-client.ovpn" = {
   environment.etc."openvpn/smartphone-client.ovpn" = {
     text = ''
     text = ''
      client
       dev tun
       dev tun
       remote "${domain}"
       remote "${domain}"
       ifconfig 10.8.0.1 10.8.0.2
       ifconfig 10.8.0.2 10.8.0.1
       port ${toString port}
       port ${toString port}
      redirect-gateway def1


       cipher AES-256-CBC
       cipher AES-256-CBC
      auth-nocache
       comp-lzo
       comp-lzo
       keepalive 10 60
       keepalive 10 60
Line 98: Line 101:


     '';
     '';
     mode = "700";
     mode = "600";
   };
   };
   system.activationScripts.openvpn-addkey = ''
   system.activationScripts.openvpn-addkey = ''

Revision as of 06:25, 21 February 2018

VPN Client

OpenVPN can be configured for automatic startup by enabling it in /etc/nixos/configuration.nix:

{
  ...
  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 ''; };
  };
  ...
}

You will need to create the referenced configuration files. The above example will start three VPN instances; more can be added.

Ensure you use absolute paths for any files such as certificates and keys referenced from the configuration files.

Mounting filesystems via a VPN

If you mount filesystems through the VPN, the filesystem will not be unmounted properly because the VPN connection will be shut down prior to unmounting the filesystem. However, newer systemd versions allow you to set mount options to unmount the mount before closing the VPN connection via the mount option x-systemd.requires=openvpn-vpnname.service.

Example mount configurations:

{
  ...
  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" ];
  };
  ...
}

If you want to run OpenVPN clients in NixOS declarative containers, you will need to set the enableTun container option.

VPN Server

Simple one-client VPN gateway server

The following is an example of a VPN server configuration which supports a single known client.

let
  # generate via openvpn --genkey --secret static.key
  client-key = "/root/openvpn-laptop.key";
  domain = "vpn.localhost.localdomain";
  vpn-dev = "tun0";
  port = 1194;
in {
  networking.nat = {
    enable = true;
    externalInterface = <your-server-out-if>;
    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
    auth-nocache

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

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

      cipher AES-256-CBC
      auth-nocache

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

    '';
    mode = "600";
  };
  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
  '';
}