summary refs log tree commit diff
path: root/nixos/tests/strongswan-swanctl.nix
blob: 0cf181ee62a56c224f06ea4d852d896820ec9566 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# 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")
  '';
})