1# This strongswan-swanctl test is based on:
2# https://www.strongswan.org/testing/testresults/swanctl/rw-psk-ipv4/index.html
3# https://github.com/strongswan/strongswan/tree/master/testing/tests/swanctl/rw-psk-ipv4
4#
5# The roadwarrior carol sets up a connection to gateway moon. The authentication
6# is based on pre-shared keys and IPv4 addresses. Upon the successful
7# establishment of the IPsec tunnels, the specified updown script automatically
8# inserts iptables-based firewall rules that let pass the tunneled traffic. In
9# order to test both tunnel and firewall, carol pings the client alice behind
10# the gateway moon.
11#
12# alice moon carol
13# eth1------vlan_0------eth1 eth2------vlan_1------eth1
14# 192.168.0.1 192.168.0.3 192.168.1.3 192.168.1.2
15#
16# See the NixOS manual for how to run this test:
17# https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively
18
19import ./make-test.nix ({ pkgs, ...} :
20
21let
22 allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT";
23
24 # Shared VPN settings:
25 vlan0 = "192.168.0.0/24";
26 carolIp = "192.168.1.2";
27 moonIp = "192.168.1.3";
28 version = 2;
29 secret = "0sFpZAZqEN6Ti9sqt4ZP5EWcqx";
30 esp_proposals = [ "aes128gcm128-x25519" ];
31 proposals = [ "aes128-sha256-x25519" ];
32in {
33 name = "strongswan-swanctl";
34 meta.maintainers = with pkgs.stdenv.lib.maintainers; [ basvandijk ];
35 nodes = {
36
37 alice = { ... } : {
38 virtualisation.vlans = [ 0 ];
39 networking = {
40 dhcpcd.enable = false;
41 defaultGateway = "192.168.0.3";
42 };
43 };
44
45 moon = { config, ...} :
46 let strongswan = config.services.strongswan-swanctl.package;
47 in {
48 virtualisation.vlans = [ 0 1 ];
49 networking = {
50 dhcpcd.enable = false;
51 firewall = {
52 allowedUDPPorts = [ 4500 500 ];
53 extraCommands = allowESP;
54 };
55 nat = {
56 enable = true;
57 internalIPs = [ vlan0 ];
58 internalInterfaces = [ "eth1" ];
59 externalIP = moonIp;
60 externalInterface = "eth2";
61 };
62 };
63 environment.systemPackages = [ strongswan ];
64 services.strongswan-swanctl = {
65 enable = true;
66 swanctl = {
67 connections = {
68 "rw" = {
69 local_addrs = [ moonIp ];
70 local."main" = {
71 auth = "psk";
72 };
73 remote."main" = {
74 auth = "psk";
75 };
76 children = {
77 "net" = {
78 local_ts = [ vlan0 ];
79 updown = "${strongswan}/libexec/ipsec/_updown iptables";
80 inherit esp_proposals;
81 };
82 };
83 inherit version;
84 inherit proposals;
85 };
86 };
87 secrets = {
88 ike."carol" = {
89 id."main" = carolIp;
90 inherit secret;
91 };
92 };
93 };
94 };
95 };
96
97 carol = { config, ...} :
98 let strongswan = config.services.strongswan-swanctl.package;
99 in {
100 virtualisation.vlans = [ 1 ];
101 networking = {
102 dhcpcd.enable = false;
103 firewall.extraCommands = allowESP;
104 };
105 environment.systemPackages = [ strongswan ];
106 services.strongswan-swanctl = {
107 enable = true;
108 swanctl = {
109 connections = {
110 "home" = {
111 local_addrs = [ carolIp ];
112 remote_addrs = [ moonIp ];
113 local."main" = {
114 auth = "psk";
115 id = carolIp;
116 };
117 remote."main" = {
118 auth = "psk";
119 id = moonIp;
120 };
121 children = {
122 "home" = {
123 remote_ts = [ vlan0 ];
124 start_action = "trap";
125 updown = "${strongswan}/libexec/ipsec/_updown iptables";
126 inherit esp_proposals;
127 };
128 };
129 inherit version;
130 inherit proposals;
131 };
132 };
133 secrets = {
134 ike."moon" = {
135 id."main" = moonIp;
136 inherit secret;
137 };
138 };
139 };
140 };
141 };
142
143 };
144 testScript = ''
145 startAll();
146 $carol->waitUntilSucceeds("ping -c 1 alice");
147 '';
148})