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