OpenVPN: Difference between revisions
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..." |
imported from old wiki |
||
(8 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
== VPN Client== | |||
OpenVPN can be configured for automatic startup by enabling it in <tt>/etc/nixos/configuration.nix</tt>: | |||
<syntaxHighlight lang="nix"> | <syntaxHighlight lang="nix"> | ||
services.openvpn.servers = { | { | ||
... | |||
services.openvpn.servers = { | |||
officeVPN = { config = '' config /root/nixos/openvpn/officeVPN.conf ''; }; | officeVPN = { config = '' config /root/nixos/openvpn/officeVPN.conf ''; }; | ||
homeVPN = { config = '' config /root/nixos/openvpn/homeVPN.conf ''; }; | homeVPN = { config = '' config /root/nixos/openvpn/homeVPN.conf ''; }; | ||
serverVPN = { config = '' config /root/nixos/openvpn/serverVPN.conf ''; }; | serverVPN = { config = '' config /root/nixos/openvpn/serverVPN.conf ''; }; | ||
}; | }; | ||
... | |||
} | |||
</syntaxHighlight> | |||
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. | |||
Use <em>systemctl</em> to start/stop VPN service. Each generated service will have a prefix `openvpn-`: | |||
<syntaxHighlight> | |||
systemctl start openvpn-officeVPN.service | |||
</syntaxHighlight> | </syntaxHighlight> | ||
Should you have trouble with DNS resolution for services that should be available via the VPN, try adding the following to the config: | |||
<syntaxHighlight lang="nix"> | |||
{ | |||
... | |||
services.openvpn.servers = { | |||
officeVPN = { | |||
config = '' config /root/nixos/openvpn/officeVPN.conf ''; | |||
updateResolvConf = true; | |||
}; | |||
}; | |||
... | |||
} | |||
</syntaxHighlight> | |||
=== 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 <tt>x-systemd.requires=openvpn-<em>vpnname</em>.service</tt>. | |||
Example mount configurations: | |||
<syntaxHighlight lang="nix"> | <syntaxHighlight lang="nix"> | ||
fileSystems."/mnt/office" = { | { | ||
... | |||
fileSystems."/mnt/office" = { | |||
device = "//10.8.0.x/Share"; | device = "//10.8.0.x/Share"; | ||
fsType = "cifs"; | fsType = "cifs"; | ||
options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" "x-systemd.requires=openvpn-officeVPN.service" ]; | options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" | ||
}; | "x-systemd.requires=openvpn-officeVPN.service" ]; | ||
fileSystems."/mnt/home" = { | }; | ||
fileSystems."/mnt/home" = { | |||
device = "//10.9.0.x/Share"; | device = "//10.9.0.x/Share"; | ||
fsType = "cifs"; | fsType = "cifs"; | ||
options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" "x-systemd.requires=openvpn-homeVPN.service" ]; | options = [ "noauto" "user" "uid=1000" "gid=100" "username=xxx" "password=xxx" "iocharset=utf8" | ||
}; | "x-systemd.requires=openvpn-homeVPN.service" ]; | ||
}; | |||
... | |||
} | |||
</syntaxHighlight> | </syntaxHighlight> | ||
If you want to run OpenVPN clients in NixOS declarative containers, you will need to set the {{nixos:option|enableTun}} container option. | |||
If you | === Supporting legacy cipher providers === | ||
If you need to connect to servers with legacy ciphers (e.g. '''BF-CBC'''), one way is to override OpenVPN to use '''openssl_legacy''' package (which is [https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/development/libraries/openssl/3.0/legacy.cnf configured to enable legacy providers]), for example via an overlay: | |||
=== | <syntaxHighlight lang="nix"> | ||
final: prev: { | |||
openvpn = prev.openvpn.override { | |||
openssl = prev.openssl_legacy; | |||
}; | |||
} | |||
</syntaxHighlight> | |||
==== Simple one-client VPN | == VPN Server == | ||
=== Simple one-client VPN gateway server === | |||
The following is an example of a VPN server configuration which supports a single known client. | |||
<syntaxHighlight lang="nix"> | <syntaxHighlight lang="nix"> | ||
let | let | ||
# generate via openvpn --genkey --secret | # generate via openvpn --genkey --secret openvpn-laptop.key | ||
client-key = "/root/openvpn-laptop.key"; | client-key = "/root/openvpn-laptop.key"; | ||
domain = "vpn.localhost.localdomain"; | domain = "vpn.localhost.localdomain"; | ||
Line 50: | Line 87: | ||
port = 1194; | port = 1194; | ||
in { | in { | ||
# sudo systemctl start nat | |||
networking.nat = { | networking.nat = { | ||
enable = true; | enable = true; | ||
externalInterface = <your-server-out- | externalInterface = <your-server-out-if>; | ||
internalInterfaces = [ vpn-dev ]; | internalInterfaces = [ vpn-dev ]; | ||
}; | }; | ||
Line 65: | Line 102: | ||
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 76: | Line 115: | ||
environment.etc."openvpn/smartphone-client.ovpn" = { | environment.etc."openvpn/smartphone-client.ovpn" = { | ||
text = '' | text = '' | ||
dev tun | dev tun | ||
remote "${domain}" | remote "${domain}" | ||
ifconfig 10.8.0. | 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 92: | Line 133: | ||
''; | ''; | ||
mode = " | mode = "600"; | ||
}; | }; | ||
system.activationScripts.openvpn-addkey = '' | system.activationScripts.openvpn-addkey = '' | ||
Line 105: | Line 146: | ||
} | } | ||
</syntaxHighlight> | </syntaxHighlight> | ||
[[Category:Networking]] | |||
[[Category:Applications]] |
Latest revision as of 13:49, 7 June 2024
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.
Use systemctl to start/stop VPN service. Each generated service will have a prefix `openvpn-`:
systemctl start openvpn-officeVPN.service
Should you have trouble with DNS resolution for services that should be available via the VPN, try adding the following to the config:
{
...
services.openvpn.servers = {
officeVPN = {
config = '' config /root/nixos/openvpn/officeVPN.conf '';
updateResolvConf = true;
};
};
...
}
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.
Supporting legacy cipher providers
If you need to connect to servers with legacy ciphers (e.g. BF-CBC), one way is to override OpenVPN to use openssl_legacy package (which is configured to enable legacy providers), for example via an overlay:
final: prev: {
openvpn = prev.openvpn.override {
openssl = prev.openssl_legacy;
};
}
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 openvpn-laptop.key
client-key = "/root/openvpn-laptop.key";
domain = "vpn.localhost.localdomain";
vpn-dev = "tun0";
port = 1194;
in {
# sudo systemctl start nat
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
'';
}