1# implements https://github.com/scionproto/scion/blob/27983125bccac6b84d1f96f406853aab0e460405/doc/tutorials/deploy.rst
2{ pkgs, ... }:
3let
4 trust-root-configuration-keys = pkgs.runCommand "generate-trc-keys.sh" {
5 buildInputs = [
6 pkgs.scion
7 ];
8 } (builtins.readFile ./bootstrap.sh);
9
10 imports = hostId: [
11 {
12 services.scion = {
13 enable = true;
14 bypassBootstrapWarning = true;
15 };
16 networking = {
17 useNetworkd = true;
18 useDHCP = false;
19 };
20 systemd.network.networks."01-eth1" = {
21 name = "eth1";
22 networkConfig.Address = "192.168.1.${toString hostId}/24";
23 };
24 environment.etc = {
25 "scion/topology.json".source = ./topology + "${toString hostId}.json";
26 "scion/crypto/as".source = trust-root-configuration-keys + "/AS${toString hostId}";
27 "scion/certs/ISD42-B1-S1.trc".source = trust-root-configuration-keys + "/ISD42-B1-S1.trc";
28 "scion/keys/master0.key".text = "U${toString hostId}v4k23ZXjGDwDofg/Eevw==";
29 "scion/keys/master1.key".text = "dBMko${toString hostId}qMS8DfrN/zP2OUdA==";
30 };
31 environment.systemPackages = [
32 pkgs.scion
33 ];
34 }
35 ];
36in
37{
38 name = "scion-test";
39 nodes = {
40 scion01 = {
41 imports = (imports 1);
42 };
43 scion02 = {
44 imports = (imports 2);
45 };
46 scion03 = {
47 imports = (imports 3);
48 };
49 scion04 = {
50 imports = (imports 4);
51 networking.interfaces."lo".ipv4.addresses = [
52 {
53 address = "172.16.1.1";
54 prefixLength = 32;
55 }
56 ];
57 services.scion.scion-ip-gateway = {
58 enable = true;
59 config = {
60 tunnel = {
61 src_ipv4 = "172.16.1.1";
62 };
63 };
64 trafficConfig = {
65 ASes = {
66 "42-ffaa:1:5" = {
67 Nets = [
68 "172.16.100.0/24"
69 ];
70 };
71 };
72 ConfigVersion = 9001;
73 };
74 };
75 };
76 scion05 = {
77 imports = (imports 5);
78 networking.interfaces."lo".ipv4.addresses = [
79 {
80 address = "172.16.100.1";
81 prefixLength = 32;
82 }
83 ];
84 services.scion.scion-ip-gateway = {
85 enable = true;
86 config = {
87 tunnel = {
88 src_ipv4 = "172.16.100.1";
89 };
90 };
91 trafficConfig = {
92 ASes = {
93 "42-ffaa:1:4" = {
94 Nets = [
95 "172.16.1.0/24"
96 ];
97 };
98 };
99 ConfigVersion = 9001;
100 };
101 };
102 };
103 };
104 testScript =
105 let
106 pingAll = pkgs.writeShellScript "ping-all-scion.sh" ''
107 addresses="42-ffaa:1:1 42-ffaa:1:2 42-ffaa:1:3 42-ffaa:1:4 42-ffaa:1:5"
108 timeout=100
109 wait_for_all() {
110 ret=0
111 for as in "$@"
112 do
113 scion showpaths $as --no-probe > /dev/null
114 ret=$?
115 if [ "$ret" -ne "0" ]; then
116 break
117 fi
118 done
119 return $ret
120 }
121 ping_all() {
122 ret=0
123 for as in "$@"
124 do
125 scion ping "$as,127.0.0.1" -c 3
126 ret=$?
127 if [ "$ret" -ne "0" ]; then
128 break
129 fi
130 done
131 return $ret
132 }
133 for i in $(seq 0 $timeout); do
134 sleep 1
135 wait_for_all $addresses || continue
136 ping_all $addresses && exit 0
137 done
138 exit 1
139 '';
140 in
141 ''
142 # List of AS instances
143 machines = [scion01, scion02, scion03, scion04, scion05]
144
145 # Functions to avoid many for loops
146 def start(allow_reboot=False):
147 for i in machines:
148 i.start(allow_reboot=allow_reboot)
149
150 def wait_for_unit(service_name):
151 for i in machines:
152 i.wait_for_unit(service_name)
153
154 def succeed(command):
155 for i in machines:
156 i.succeed(command)
157
158 def reboot():
159 for i in machines:
160 i.reboot()
161
162 def crash():
163 for i in machines:
164 i.crash()
165
166 # Start all machines, allowing reboot for later
167 start(allow_reboot=True)
168
169 # Wait for scion-control.service on all instances
170 wait_for_unit("scion-control.service")
171
172 # Ensure cert is valid against TRC
173 succeed("scion-pki certificate verify --trc /etc/scion/certs/*.trc /etc/scion/crypto/as/*.pem >&2")
174
175 # Execute pingAll command on all instances
176 succeed("${pingAll} >&2")
177
178 # Execute ICMP pings across scion-ip-gateway
179 scion04.succeed("ping -c 3 172.16.100.1 >&2")
180 scion05.succeed("ping -c 3 172.16.1.1 >&2")
181
182 # Restart all scion services and ping again to test robustness
183 succeed("systemctl restart scion-* >&2")
184 succeed("${pingAll} >&2")
185
186 # Reboot machines, wait for service, and ping again
187 reboot()
188 wait_for_unit("scion-control.service")
189 succeed("${pingAll} >&2")
190
191 # Crash, start, wait for service, and ping again
192 crash()
193 start()
194 wait_for_unit("scion-control.service")
195 succeed("pkill -9 scion-* >&2")
196 wait_for_unit("scion-control.service")
197 succeed("${pingAll} >&2")
198 '';
199}