nixpkgs-immich/nixos/tests/strongswan-swanctl.nix
2024-09-17 10:23:40 -06:00

149 lines
4.5 KiB
Nix

# This strongswan-swanctl test is based on:
# https://www.strongswan.org/testing/testresults/swanctl/rw-psk-ipv4/index.html
# https://github.com/strongswan/strongswan/tree/master/testing/tests/swanctl/rw-psk-ipv4
#
# The roadwarrior carol sets up a connection to gateway moon. The authentication
# is based on pre-shared keys and IPv4 addresses. Upon the successful
# establishment of the IPsec tunnels, the specified updown script automatically
# inserts iptables-based firewall rules that let pass the tunneled traffic. In
# order to test both tunnel and firewall, carol pings the client alice behind
# the gateway moon.
#
# alice moon carol
# eth1------vlan_0------eth1 eth2------vlan_1------eth1
# 192.168.0.1 192.168.0.3 192.168.1.3 192.168.1.2
#
# See the NixOS manual for how to run this test:
# https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively
import ./make-test-python.nix ({ pkgs, ...} :
let
allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT";
# Shared VPN settings:
vlan0 = "192.168.0.0/24";
carolIp = "192.168.1.2";
moonIp = "192.168.1.3";
version = 2;
secret = "0sFpZAZqEN6Ti9sqt4ZP5EWcqx";
esp_proposals = [ "aes128gcm128-x25519" ];
proposals = [ "aes128-sha256-x25519" ];
in {
name = "strongswan-swanctl";
meta.maintainers = with pkgs.lib.maintainers; [ basvandijk ];
nodes = {
alice = { ... } : {
virtualisation.vlans = [ 0 ];
networking = {
dhcpcd.enable = false;
defaultGateway = "192.168.0.3";
};
};
moon = { config, ...} :
let strongswan = config.services.strongswan-swanctl.package;
in {
virtualisation.vlans = [ 0 1 ];
networking = {
dhcpcd.enable = false;
firewall = {
allowedUDPPorts = [ 4500 500 ];
extraCommands = allowESP;
};
nat = {
enable = true;
internalIPs = [ vlan0 ];
internalInterfaces = [ "eth1" ];
externalIP = moonIp;
externalInterface = "eth2";
};
};
environment.systemPackages = [ strongswan ];
services.strongswan-swanctl = {
enable = true;
swanctl = {
connections = {
rw = {
local_addrs = [ moonIp ];
local.main = {
auth = "psk";
};
remote.main = {
auth = "psk";
};
children = {
net = {
local_ts = [ vlan0 ];
updown = "${strongswan}/libexec/ipsec/_updown iptables";
inherit esp_proposals;
};
};
inherit version;
inherit proposals;
};
};
secrets = {
ike.carol = {
id.main = carolIp;
inherit secret;
};
};
};
};
};
carol = { config, ...} :
let strongswan = config.services.strongswan-swanctl.package;
in {
virtualisation.vlans = [ 1 ];
networking = {
dhcpcd.enable = false;
firewall.extraCommands = allowESP;
};
environment.systemPackages = [ strongswan ];
services.strongswan-swanctl = {
enable = true;
swanctl = {
connections = {
home = {
local_addrs = [ carolIp ];
remote_addrs = [ moonIp ];
local.main = {
auth = "psk";
id = carolIp;
};
remote.main = {
auth = "psk";
id = moonIp;
};
children = {
home = {
remote_ts = [ vlan0 ];
start_action = "trap";
updown = "${strongswan}/libexec/ipsec/_updown iptables";
inherit esp_proposals;
};
};
inherit version;
inherit proposals;
};
};
secrets = {
ike.moon = {
id.main = moonIp;
inherit secret;
};
};
};
};
};
};
testScript = ''
start_all()
carol.wait_until_succeeds("ping -c 1 alice")
'';
})