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-python.nix (
20 { pkgs, ... }:
21
22 let
23 allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT";
24
25 # Shared VPN settings:
26 vlan0 = "192.168.0.0/24";
27 carolIp = "192.168.1.2";
28 moonIp = "192.168.1.3";
29 version = 2;
30 secret = "0sFpZAZqEN6Ti9sqt4ZP5EWcqx";
31 esp_proposals = [ "aes128gcm128-x25519" ];
32 proposals = [ "aes128-sha256-x25519" ];
33 in
34 {
35 name = "strongswan-swanctl";
36 meta.maintainers = with pkgs.lib.maintainers; [ basvandijk ];
37 nodes = {
38
39 alice =
40 { ... }:
41 {
42 virtualisation.vlans = [ 0 ];
43 networking = {
44 dhcpcd.enable = false;
45 defaultGateway = "192.168.0.3";
46 };
47 };
48
49 moon =
50 { config, ... }:
51 let
52 strongswan = config.services.strongswan-swanctl.package;
53 in
54 {
55 virtualisation.vlans = [
56 0
57 1
58 ];
59 networking = {
60 dhcpcd.enable = false;
61 firewall = {
62 allowedUDPPorts = [
63 4500
64 500
65 ];
66 extraCommands = allowESP;
67 };
68 nat = {
69 enable = true;
70 internalIPs = [ vlan0 ];
71 internalInterfaces = [ "eth1" ];
72 externalIP = moonIp;
73 externalInterface = "eth2";
74 };
75 };
76 environment.systemPackages = [ strongswan ];
77 services.strongswan-swanctl = {
78 enable = true;
79 swanctl = {
80 connections = {
81 rw = {
82 local_addrs = [ moonIp ];
83 local.main = {
84 auth = "psk";
85 };
86 remote.main = {
87 auth = "psk";
88 };
89 children = {
90 net = {
91 local_ts = [ vlan0 ];
92 updown = "${strongswan}/libexec/ipsec/_updown iptables";
93 inherit esp_proposals;
94 };
95 };
96 inherit version;
97 inherit proposals;
98 };
99 };
100 secrets = {
101 ike.carol = {
102 id.main = carolIp;
103 inherit secret;
104 };
105 };
106 };
107 };
108 };
109
110 carol =
111 { config, ... }:
112 let
113 strongswan = config.services.strongswan-swanctl.package;
114 in
115 {
116 virtualisation.vlans = [ 1 ];
117 networking = {
118 dhcpcd.enable = false;
119 firewall.extraCommands = allowESP;
120 };
121 environment.systemPackages = [ strongswan ];
122 services.strongswan-swanctl = {
123 enable = true;
124 swanctl = {
125 connections = {
126 home = {
127 local_addrs = [ carolIp ];
128 remote_addrs = [ moonIp ];
129 local.main = {
130 auth = "psk";
131 id = carolIp;
132 };
133 remote.main = {
134 auth = "psk";
135 id = moonIp;
136 };
137 children = {
138 home = {
139 remote_ts = [ vlan0 ];
140 start_action = "trap";
141 updown = "${strongswan}/libexec/ipsec/_updown iptables";
142 inherit esp_proposals;
143 };
144 };
145 inherit version;
146 inherit proposals;
147 };
148 };
149 secrets = {
150 ike.moon = {
151 id.main = moonIp;
152 inherit secret;
153 };
154 };
155 };
156 };
157 };
158
159 };
160 testScript = ''
161 start_all()
162 carol.wait_until_succeeds("ping -c 1 alice")
163 '';
164 }
165)