nixos/{wg-quick,wireguard}: add AmneziaWG support (#341663)
This commit is contained in:
commit
0589bd307d
@ -11,6 +11,15 @@ let
|
|||||||
interfaceOpts = { ... }: {
|
interfaceOpts = { ... }: {
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
|
type = mkOption {
|
||||||
|
example = "amneziawg";
|
||||||
|
default = "wireguard";
|
||||||
|
type = types.enum ["wireguard" "amneziawg"];
|
||||||
|
description = ''
|
||||||
|
The type of the interface. Currently only "wireguard" and "amneziawg" are supported.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
configFile = mkOption {
|
configFile = mkOption {
|
||||||
example = "/secret/wg0.conf";
|
example = "/secret/wg0.conf";
|
||||||
default = null;
|
default = null;
|
||||||
@ -151,6 +160,22 @@ let
|
|||||||
description = "Peers linked to the interface.";
|
description = "Peers linked to the interface.";
|
||||||
type = with types; listOf (submodule peerOpts);
|
type = with types; listOf (submodule peerOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ str int ]);
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
Jc = 5;
|
||||||
|
Jmin = 10;
|
||||||
|
Jmax = 42;
|
||||||
|
S1 = 60;
|
||||||
|
S2 = 90;
|
||||||
|
H4 = 12345;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Extra options to append to the interface section. Can be used to define AmneziaWG-specific options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -230,7 +255,7 @@ let
|
|||||||
|
|
||||||
writeScriptFile = name: text: ((pkgs.writeShellScriptBin name text) + "/bin/${name}");
|
writeScriptFile = name: text: ((pkgs.writeShellScriptBin name text) + "/bin/${name}");
|
||||||
|
|
||||||
generatePrivateKeyScript = privateKeyFile: ''
|
generatePrivateKeyScript = privateKeyFile: wgBin: ''
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# If the parent dir does not already exist, create it.
|
# If the parent dir does not already exist, create it.
|
||||||
@ -239,7 +264,7 @@ let
|
|||||||
|
|
||||||
if [ ! -f "${privateKeyFile}" ]; then
|
if [ ! -f "${privateKeyFile}" ]; then
|
||||||
# Write private key file with atomically-correct permissions.
|
# Write private key file with atomically-correct permissions.
|
||||||
(set -e; umask 077; wg genkey > "${privateKeyFile}")
|
(set -e; umask 077; ${wgBin} genkey > "${privateKeyFile}")
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@ -247,11 +272,19 @@ let
|
|||||||
assert assertMsg (values.configFile != null || ((values.privateKey != null) != (values.privateKeyFile != null))) "Only one of privateKey, configFile or privateKeyFile may be set";
|
assert assertMsg (values.configFile != null || ((values.privateKey != null) != (values.privateKeyFile != null))) "Only one of privateKey, configFile or privateKeyFile may be set";
|
||||||
assert assertMsg (values.generatePrivateKeyFile == false || values.privateKeyFile != null) "generatePrivateKeyFile requires privateKeyFile to be set";
|
assert assertMsg (values.generatePrivateKeyFile == false || values.privateKeyFile != null) "generatePrivateKeyFile requires privateKeyFile to be set";
|
||||||
let
|
let
|
||||||
generateKeyScriptFile = if values.generatePrivateKeyFile then writeScriptFile "generatePrivateKey.sh" (generatePrivateKeyScript values.privateKeyFile) else null;
|
wgBin = {
|
||||||
|
wireguard = "wg";
|
||||||
|
amneziawg = "awg";
|
||||||
|
}.${values.type};
|
||||||
|
generateKeyScriptFile =
|
||||||
|
if values.generatePrivateKeyFile then
|
||||||
|
writeScriptFile "generatePrivateKey.sh" (generatePrivateKeyScript values.privateKeyFile wgBin)
|
||||||
|
else
|
||||||
|
null;
|
||||||
preUpFile = if values.preUp != "" then writeScriptFile "preUp.sh" values.preUp else null;
|
preUpFile = if values.preUp != "" then writeScriptFile "preUp.sh" values.preUp else null;
|
||||||
postUp =
|
postUp =
|
||||||
optional (values.privateKeyFile != null) "wg set ${name} private-key <(cat ${values.privateKeyFile})" ++
|
optional (values.privateKeyFile != null) "${wgBin} set ${name} private-key <(cat ${values.privateKeyFile})" ++
|
||||||
(concatMap (peer: optional (peer.presharedKeyFile != null) "wg set ${name} peer ${peer.publicKey} preshared-key <(cat ${peer.presharedKeyFile})") values.peers) ++
|
(concatMap (peer: optional (peer.presharedKeyFile != null) "${wgBin} set ${name} peer ${peer.publicKey} preshared-key <(cat ${peer.presharedKeyFile})") values.peers) ++
|
||||||
optional (values.postUp != "") values.postUp;
|
optional (values.postUp != "") values.postUp;
|
||||||
postUpFile = if postUp != [] then writeScriptFile "postUp.sh" (concatMapStringsSep "\n" (line: line) postUp) else null;
|
postUpFile = if postUp != [] then writeScriptFile "postUp.sh" (concatMapStringsSep "\n" (line: line) postUp) else null;
|
||||||
preDownFile = if values.preDown != "" then writeScriptFile "preDown.sh" values.preDown else null;
|
preDownFile = if values.preDown != "" then writeScriptFile "preDown.sh" values.preDown else null;
|
||||||
@ -279,6 +312,7 @@ let
|
|||||||
optionalString (postUpFile != null) "PostUp = ${postUpFile}\n" +
|
optionalString (postUpFile != null) "PostUp = ${postUpFile}\n" +
|
||||||
optionalString (preDownFile != null) "PreDown = ${preDownFile}\n" +
|
optionalString (preDownFile != null) "PreDown = ${preDownFile}\n" +
|
||||||
optionalString (postDownFile != null) "PostDown = ${postDownFile}\n" +
|
optionalString (postDownFile != null) "PostDown = ${postDownFile}\n" +
|
||||||
|
concatLines (mapAttrsToList (n: v: "${n} = ${toString v}") values.extraOptions) +
|
||||||
concatMapStringsSep "\n" (peer:
|
concatMapStringsSep "\n" (peer:
|
||||||
assert assertMsg (!((peer.presharedKeyFile != null) && (peer.presharedKey != null))) "Only one of presharedKey or presharedKeyFile may be set";
|
assert assertMsg (!((peer.presharedKeyFile != null) && (peer.presharedKey != null))) "Only one of presharedKey or presharedKeyFile may be set";
|
||||||
"[Peer]\n" +
|
"[Peer]\n" +
|
||||||
@ -304,7 +338,10 @@ let
|
|||||||
wantedBy = optional values.autostart "multi-user.target";
|
wantedBy = optional values.autostart "multi-user.target";
|
||||||
environment.DEVICE = name;
|
environment.DEVICE = name;
|
||||||
path = [
|
path = [
|
||||||
pkgs.wireguard-tools
|
{
|
||||||
|
wireguard = pkgs.wireguard-tools;
|
||||||
|
amneziawg = pkgs.amneziawg-tools;
|
||||||
|
}.${values.type}
|
||||||
config.networking.firewall.package # iptables or nftables
|
config.networking.firewall.package # iptables or nftables
|
||||||
config.networking.resolvconf.package # openresolv or systemd
|
config.networking.resolvconf.package # openresolv or systemd
|
||||||
];
|
];
|
||||||
@ -315,11 +352,11 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
${optionalString (!config.boot.isContainer) "${pkgs.kmod}/bin/modprobe wireguard"}
|
${optionalString (!config.boot.isContainer) "${pkgs.kmod}/bin/modprobe ${values.type}"}
|
||||||
${optionalString (values.configFile != null) ''
|
${optionalString (values.configFile != null) ''
|
||||||
cp ${values.configFile} ${configPath}
|
cp ${values.configFile} ${configPath}
|
||||||
''}
|
''}
|
||||||
wg-quick up ${configPath}
|
${wgBin}-quick up ${configPath}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
@ -328,7 +365,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
preStop = ''
|
preStop = ''
|
||||||
wg-quick down ${configPath}
|
${wgBin}-quick down ${configPath}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
@ -360,8 +397,12 @@ in {
|
|||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf (cfg.interfaces != {}) {
|
config = mkIf (cfg.interfaces != {}) {
|
||||||
boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
|
boot.extraModulePackages =
|
||||||
environment.systemPackages = [ pkgs.wireguard-tools ];
|
optional (any (x: x.type == "wireguard") (attrValues cfg.interfaces) && (versionOlder kernel.kernel.version "5.6")) kernel.wireguard
|
||||||
|
++ optional (any (x: x.type == "amneziawg") (attrValues cfg.interfaces)) kernel.amneziawg;
|
||||||
|
environment.systemPackages =
|
||||||
|
optional (any (x: x.type == "wireguard") (attrValues cfg.interfaces)) pkgs.wireguard-tools
|
||||||
|
++ optional (any (x: x.type == "amneziawg") (attrValues cfg.interfaces)) pkgs.amneziawg-tools;
|
||||||
systemd.services = mapAttrs' generateUnit cfg.interfaces;
|
systemd.services = mapAttrs' generateUnit cfg.interfaces;
|
||||||
|
|
||||||
# Prevent networkd from clearing the rules set by wg-quick when restarted (e.g. when waking up from suspend).
|
# Prevent networkd from clearing the rules set by wg-quick when restarted (e.g. when waking up from suspend).
|
||||||
|
|||||||
@ -189,6 +189,10 @@ in
|
|||||||
assertion = interface.interfaceNamespace == null;
|
assertion = interface.interfaceNamespace == null;
|
||||||
message = "networking.wireguard.interfaces.${name}.interfaceNamespace cannot be used with networkd.";
|
message = "networking.wireguard.interfaces.${name}.interfaceNamespace cannot be used with networkd.";
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
assertion = interface.type == "wireguard";
|
||||||
|
message = "networking.wireguard.interfaces.${name}.type value must be \"wireguard\" when used with networkd.";
|
||||||
|
}
|
||||||
]
|
]
|
||||||
++ flip concatMap interface.ips (ip: [
|
++ flip concatMap interface.ips (ip: [
|
||||||
# IP assertions
|
# IP assertions
|
||||||
|
|||||||
@ -15,6 +15,15 @@ let
|
|||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
|
type = mkOption {
|
||||||
|
example = "amneziawg";
|
||||||
|
default = "wireguard";
|
||||||
|
type = types.enum ["wireguard" "amneziawg"];
|
||||||
|
description = ''
|
||||||
|
The type of the interface. Currently only "wireguard" and "amneziawg" are supported.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
ips = mkOption {
|
ips = mkOption {
|
||||||
example = [ "192.168.2.1/24" ];
|
example = [ "192.168.2.1/24" ];
|
||||||
default = [];
|
default = [];
|
||||||
@ -206,6 +215,22 @@ let
|
|||||||
:::
|
:::
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ str int ]);
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
Jc = 5;
|
||||||
|
Jmin = 10;
|
||||||
|
Jmax = 42;
|
||||||
|
S1 = 60;
|
||||||
|
S2 = 90;
|
||||||
|
H4 = 12345;
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Extra options to append to the interface section. Can be used to define AmneziaWG-specific options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -346,6 +371,16 @@ let
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wgBins = {
|
||||||
|
wireguard = "wg";
|
||||||
|
amneziawg = "awg";
|
||||||
|
};
|
||||||
|
|
||||||
|
wgPackages = {
|
||||||
|
wireguard = pkgs.wireguard-tools;
|
||||||
|
amneziawg = pkgs.amneziawg-tools;
|
||||||
|
};
|
||||||
|
|
||||||
generateKeyServiceUnit = name: values:
|
generateKeyServiceUnit = name: values:
|
||||||
assert values.generatePrivateKeyFile;
|
assert values.generatePrivateKeyFile;
|
||||||
nameValuePair "wireguard-${name}-key"
|
nameValuePair "wireguard-${name}-key"
|
||||||
@ -354,7 +389,7 @@ let
|
|||||||
wantedBy = [ "wireguard-${name}.service" ];
|
wantedBy = [ "wireguard-${name}.service" ];
|
||||||
requiredBy = [ "wireguard-${name}.service" ];
|
requiredBy = [ "wireguard-${name}.service" ];
|
||||||
before = [ "wireguard-${name}.service" ];
|
before = [ "wireguard-${name}.service" ];
|
||||||
path = with pkgs; [ wireguard-tools ];
|
path = [ wgPackages.${values.type} ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
@ -370,7 +405,7 @@ let
|
|||||||
|
|
||||||
if [ ! -f "${values.privateKeyFile}" ]; then
|
if [ ! -f "${values.privateKeyFile}" ]; then
|
||||||
# Write private key file with atomically-correct permissions.
|
# Write private key file with atomically-correct permissions.
|
||||||
(set -e; umask 077; wg genkey > "${values.privateKeyFile}")
|
(set -e; umask 077; ${wgBins.${values.type}} genkey > "${values.privateKeyFile}")
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@ -395,7 +430,7 @@ let
|
|||||||
src = interfaceCfg.socketNamespace;
|
src = interfaceCfg.socketNamespace;
|
||||||
dst = interfaceCfg.interfaceNamespace;
|
dst = interfaceCfg.interfaceNamespace;
|
||||||
ip = nsWrap "ip" src dst;
|
ip = nsWrap "ip" src dst;
|
||||||
wg = nsWrap "wg" src dst;
|
wg = nsWrap wgBins.${interfaceCfg.type} src dst;
|
||||||
dynamicEndpointRefreshSeconds = dynamicRefreshSeconds interfaceCfg peer;
|
dynamicEndpointRefreshSeconds = dynamicRefreshSeconds interfaceCfg peer;
|
||||||
dynamicRefreshEnabled = dynamicEndpointRefreshSeconds != 0;
|
dynamicRefreshEnabled = dynamicEndpointRefreshSeconds != 0;
|
||||||
# We generate a different name (a `-refresh` suffix) when `dynamicEndpointRefreshSeconds`
|
# We generate a different name (a `-refresh` suffix) when `dynamicEndpointRefreshSeconds`
|
||||||
@ -412,7 +447,7 @@ let
|
|||||||
wantedBy = [ "wireguard-${interfaceName}.service" ];
|
wantedBy = [ "wireguard-${interfaceName}.service" ];
|
||||||
environment.DEVICE = interfaceName;
|
environment.DEVICE = interfaceName;
|
||||||
environment.WG_ENDPOINT_RESOLUTION_RETRIES = "infinity";
|
environment.WG_ENDPOINT_RESOLUTION_RETRIES = "infinity";
|
||||||
path = with pkgs; [ iproute2 wireguard-tools ];
|
path = with pkgs; [ iproute2 wgPackages.${interfaceCfg.type} ];
|
||||||
|
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
if !dynamicRefreshEnabled
|
if !dynamicRefreshEnabled
|
||||||
@ -501,7 +536,7 @@ let
|
|||||||
dst = values.interfaceNamespace;
|
dst = values.interfaceNamespace;
|
||||||
ipPreMove = nsWrap "ip" src null;
|
ipPreMove = nsWrap "ip" src null;
|
||||||
ipPostMove = nsWrap "ip" src dst;
|
ipPostMove = nsWrap "ip" src dst;
|
||||||
wg = nsWrap "wg" src dst;
|
wg = nsWrap wgBins.${values.type} src dst;
|
||||||
ns = if dst == "init" then "1" else dst;
|
ns = if dst == "init" then "1" else dst;
|
||||||
|
|
||||||
in
|
in
|
||||||
@ -512,7 +547,7 @@ let
|
|||||||
wants = [ "network.target" ];
|
wants = [ "network.target" ];
|
||||||
before = [ "network.target" ];
|
before = [ "network.target" ];
|
||||||
environment.DEVICE = name;
|
environment.DEVICE = name;
|
||||||
path = with pkgs; [ kmod iproute2 wireguard-tools ];
|
path = with pkgs; [ kmod iproute2 wgPackages.${values.type} ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
@ -520,10 +555,10 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
script = concatStringsSep "\n" (
|
script = concatStringsSep "\n" (
|
||||||
optional (!config.boot.isContainer) "modprobe wireguard || true"
|
optional (!config.boot.isContainer) "modprobe ${values.type} || true"
|
||||||
++ [
|
++ [
|
||||||
values.preSetup
|
values.preSetup
|
||||||
''${ipPreMove} link add dev "${name}" type wireguard''
|
''${ipPreMove} link add dev "${name}" type ${values.type}''
|
||||||
]
|
]
|
||||||
++ optional (values.interfaceNamespace != null && values.interfaceNamespace != values.socketNamespace) ''${ipPreMove} link set "${name}" netns "${ns}"''
|
++ optional (values.interfaceNamespace != null && values.interfaceNamespace != values.socketNamespace) ''${ipPreMove} link set "${name}" netns "${ns}"''
|
||||||
++ optional (values.mtu != null) ''${ipPostMove} link set "${name}" mtu ${toString values.mtu}''
|
++ optional (values.mtu != null) ''${ipPostMove} link set "${name}" mtu ${toString values.mtu}''
|
||||||
@ -535,6 +570,7 @@ let
|
|||||||
[ ''${wg} set "${name}" private-key "${privKey}"'' ]
|
[ ''${wg} set "${name}" private-key "${privKey}"'' ]
|
||||||
++ optional (values.listenPort != null) ''listen-port "${toString values.listenPort}"''
|
++ optional (values.listenPort != null) ''listen-port "${toString values.listenPort}"''
|
||||||
++ optional (values.fwMark != null) ''fwmark "${values.fwMark}"''
|
++ optional (values.fwMark != null) ''fwmark "${values.fwMark}"''
|
||||||
|
++ mapAttrsToList (k: v: ''${toLower k} "${toString v}"'') values.extraOptions
|
||||||
))
|
))
|
||||||
''${ipPostMove} link set up dev "${name}"''
|
''${ipPostMove} link set up dev "${name}"''
|
||||||
values.postSetup
|
values.postSetup
|
||||||
@ -554,6 +590,9 @@ let
|
|||||||
ns = last nsList;
|
ns = last nsList;
|
||||||
in
|
in
|
||||||
if (length nsList > 0 && ns != "init") then ''ip netns exec "${ns}" "${cmd}"'' else cmd;
|
if (length nsList > 0 && ns != "init") then ''ip netns exec "${ns}" "${cmd}"'' else cmd;
|
||||||
|
|
||||||
|
usingWg = any (x: x.type == "wireguard") (attrValues cfg.interfaces);
|
||||||
|
usingAwg = any (x: x.type == "amneziawg") (attrValues cfg.interfaces);
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -628,9 +667,11 @@ in
|
|||||||
message = "networking.wireguard.interfaces.${interfaceName} peer «${peer.publicKey}» has both presharedKey and presharedKeyFile set, but only one can be used.";
|
message = "networking.wireguard.interfaces.${interfaceName} peer «${peer.publicKey}» has both presharedKey and presharedKeyFile set, but only one can be used.";
|
||||||
}) all_peers;
|
}) all_peers;
|
||||||
|
|
||||||
boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
|
boot.extraModulePackages =
|
||||||
boot.kernelModules = [ "wireguard" ];
|
optional (usingWg && (versionOlder kernel.kernel.version "5.6")) kernel.wireguard
|
||||||
environment.systemPackages = [ pkgs.wireguard-tools ];
|
++ optional usingAwg kernel.amneziawg;
|
||||||
|
boot.kernelModules = optional usingWg "wireguard" ++ optional usingAwg "amneziawg";
|
||||||
|
environment.systemPackages = optional usingWg pkgs.wireguard-tools ++ optional usingAwg pkgs.amneziawg-tools;
|
||||||
|
|
||||||
systemd.services = mkIf (!cfg.useNetworkd) (
|
systemd.services = mkIf (!cfg.useNetworkd) (
|
||||||
(mapAttrs' generateInterfaceUnit cfg.interfaces)
|
(mapAttrs' generateInterfaceUnit cfg.interfaces)
|
||||||
|
|||||||
125
nixos/tests/wireguard/amneziawg-quick.nix
Normal file
125
nixos/tests/wireguard/amneziawg-quick.nix
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import ../make-test-python.nix (
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
kernelPackages ? null,
|
||||||
|
nftables ? false,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
wg-snakeoil-keys = import ./snakeoil-keys.nix;
|
||||||
|
peer = import ./make-peer.nix { inherit lib; };
|
||||||
|
commonConfig = {
|
||||||
|
boot.kernelPackages = lib.mkIf (kernelPackages != null) kernelPackages;
|
||||||
|
networking.nftables.enable = nftables;
|
||||||
|
# Make sure iptables doesn't work with nftables enabled
|
||||||
|
boot.blacklistedKernelModules = lib.mkIf nftables [ "nft_compat" ];
|
||||||
|
};
|
||||||
|
extraOptions = {
|
||||||
|
Jc = 5;
|
||||||
|
Jmin = 10;
|
||||||
|
Jmax = 42;
|
||||||
|
S1 = 60;
|
||||||
|
S2 = 90;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
name = "amneziawg-quick";
|
||||||
|
meta = with pkgs.lib.maintainers; {
|
||||||
|
maintainers = [
|
||||||
|
averyanalex
|
||||||
|
azahi
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
peer0 = peer {
|
||||||
|
ip4 = "192.168.0.1";
|
||||||
|
ip6 = "fd00::1";
|
||||||
|
extraConfig = lib.mkMerge [
|
||||||
|
commonConfig
|
||||||
|
{
|
||||||
|
networking.firewall.allowedUDPPorts = [ 23542 ];
|
||||||
|
networking.wg-quick.interfaces.wg0 = {
|
||||||
|
type = "amneziawg";
|
||||||
|
|
||||||
|
address = [
|
||||||
|
"10.23.42.1/32"
|
||||||
|
"fc00::1/128"
|
||||||
|
];
|
||||||
|
listenPort = 23542;
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer0) privateKey;
|
||||||
|
|
||||||
|
peers = lib.singleton {
|
||||||
|
allowedIPs = [
|
||||||
|
"10.23.42.2/32"
|
||||||
|
"fc00::2/128"
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer1) publicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
dns = [
|
||||||
|
"10.23.42.2"
|
||||||
|
"fc00::2"
|
||||||
|
"wg0"
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit extraOptions;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
peer1 = peer {
|
||||||
|
ip4 = "192.168.0.2";
|
||||||
|
ip6 = "fd00::2";
|
||||||
|
extraConfig = lib.mkMerge [
|
||||||
|
commonConfig
|
||||||
|
{
|
||||||
|
networking.useNetworkd = true;
|
||||||
|
networking.wg-quick.interfaces.wg0 = {
|
||||||
|
type = "amneziawg";
|
||||||
|
|
||||||
|
address = [
|
||||||
|
"10.23.42.2/32"
|
||||||
|
"fc00::2/128"
|
||||||
|
];
|
||||||
|
inherit (wg-snakeoil-keys.peer1) privateKey;
|
||||||
|
|
||||||
|
peers = lib.singleton {
|
||||||
|
allowedIPs = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
endpoint = "192.168.0.1:23542";
|
||||||
|
persistentKeepalive = 25;
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer0) publicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
dns = [
|
||||||
|
"10.23.42.1"
|
||||||
|
"fc00::1"
|
||||||
|
"wg0"
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit extraOptions;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
peer0.wait_for_unit("wg-quick-wg0.service")
|
||||||
|
peer1.wait_for_unit("wg-quick-wg0.service")
|
||||||
|
|
||||||
|
peer1.succeed("ping -c5 fc00::1")
|
||||||
|
peer1.succeed("ping -c5 10.23.42.1")
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
)
|
||||||
111
nixos/tests/wireguard/amneziawg.nix
Normal file
111
nixos/tests/wireguard/amneziawg.nix
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import ../make-test-python.nix (
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
kernelPackages ? null,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
wg-snakeoil-keys = import ./snakeoil-keys.nix;
|
||||||
|
peer = (import ./make-peer.nix) { inherit lib; };
|
||||||
|
extraOptions = {
|
||||||
|
Jc = 5;
|
||||||
|
Jmin = 10;
|
||||||
|
Jmax = 42;
|
||||||
|
S1 = 60;
|
||||||
|
S2 = 90;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
name = "amneziawg";
|
||||||
|
meta = with pkgs.lib.maintainers; {
|
||||||
|
maintainers = [
|
||||||
|
averyanalex
|
||||||
|
azahi
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
peer0 = peer {
|
||||||
|
ip4 = "192.168.0.1";
|
||||||
|
ip6 = "fd00::1";
|
||||||
|
extraConfig = {
|
||||||
|
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
|
||||||
|
networking.firewall.allowedUDPPorts = [ 23542 ];
|
||||||
|
networking.wireguard.interfaces.wg0 = {
|
||||||
|
type = "amneziawg";
|
||||||
|
ips = [
|
||||||
|
"10.23.42.1/32"
|
||||||
|
"fc00::1/128"
|
||||||
|
];
|
||||||
|
listenPort = 23542;
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer0) privateKey;
|
||||||
|
|
||||||
|
peers = lib.singleton {
|
||||||
|
allowedIPs = [
|
||||||
|
"10.23.42.2/32"
|
||||||
|
"fc00::2/128"
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer1) publicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
inherit extraOptions;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
peer1 = peer {
|
||||||
|
ip4 = "192.168.0.2";
|
||||||
|
ip6 = "fd00::2";
|
||||||
|
extraConfig = {
|
||||||
|
boot = lib.mkIf (kernelPackages != null) { inherit kernelPackages; };
|
||||||
|
networking.wireguard.interfaces.wg0 = {
|
||||||
|
type = "amneziawg";
|
||||||
|
ips = [
|
||||||
|
"10.23.42.2/32"
|
||||||
|
"fc00::2/128"
|
||||||
|
];
|
||||||
|
listenPort = 23542;
|
||||||
|
allowedIPsAsRoutes = false;
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer1) privateKey;
|
||||||
|
|
||||||
|
peers = lib.singleton {
|
||||||
|
allowedIPs = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
endpoint = "192.168.0.1:23542";
|
||||||
|
persistentKeepalive = 25;
|
||||||
|
|
||||||
|
inherit (wg-snakeoil-keys.peer0) publicKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
postSetup =
|
||||||
|
let
|
||||||
|
inherit (pkgs) iproute2;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
${iproute2}/bin/ip route replace 10.23.42.1/32 dev wg0
|
||||||
|
${iproute2}/bin/ip route replace fc00::1/128 dev wg0
|
||||||
|
'';
|
||||||
|
|
||||||
|
inherit extraOptions;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
peer0.wait_for_unit("wireguard-wg0.service")
|
||||||
|
peer1.wait_for_unit("wireguard-wg0.service")
|
||||||
|
|
||||||
|
peer1.succeed("ping -c5 fc00::1")
|
||||||
|
peer1.succeed("ping -c5 10.23.42.1")
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
)
|
||||||
@ -10,10 +10,12 @@ with pkgs.lib;
|
|||||||
let
|
let
|
||||||
tests = let callTest = p: args: import p ({ inherit system pkgs; } // args); in {
|
tests = let callTest = p: args: import p ({ inherit system pkgs; } // args); in {
|
||||||
basic = callTest ./basic.nix;
|
basic = callTest ./basic.nix;
|
||||||
|
amneziawg = callTest ./amneziawg.nix;
|
||||||
namespaces = callTest ./namespaces.nix;
|
namespaces = callTest ./namespaces.nix;
|
||||||
networkd = callTest ./networkd.nix;
|
networkd = callTest ./networkd.nix;
|
||||||
wg-quick = callTest ./wg-quick.nix;
|
wg-quick = callTest ./wg-quick.nix;
|
||||||
wg-quick-nftables = args: callTest ./wg-quick.nix ({ nftables = true; } // args);
|
wg-quick-nftables = args: callTest ./wg-quick.nix ({ nftables = true; } // args);
|
||||||
|
amneziawg-quick = callTest ./amneziawg-quick.nix;
|
||||||
generated = callTest ./generated.nix;
|
generated = callTest ./generated.nix;
|
||||||
dynamic-refresh = callTest ./dynamic-refresh.nix;
|
dynamic-refresh = callTest ./dynamic-refresh.nix;
|
||||||
dynamic-refresh-networkd = args: callTest ./dynamic-refresh.nix ({ useNetworkd = true; } // args);
|
dynamic-refresh-networkd = args: callTest ./dynamic-refresh.nix ({ useNetworkd = true; } // args);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user