blob: c541bed5d4a3525d07fb3c1acca3a9ca869f0df2 [file] [log] [blame]
Serge Bazanski6abe4fa2020-10-03 00:18:34 +02001# Main configuration file for edge01.waw.bgp.wtf.
2# This includes everything needed to run the machine, except for hardware
3# configuration, which is defined in //bgpwtf/machines/
4# edge01.waw.bgp.wtf-hardware.nix.
5#
6# Any changes here can be tested in a local NixOS test by running the following:
7#
8# nix-build -A bgpwtf.machines.tests.edge01-waw
9#
10# To deploy changes, see //ops:machines.nix.
11
12{ config, pkgs, ... }:
13
14with builtins;
15
16let
17 passwords = import ./secrets/plain/passwords.nix;
18
19in rec {
20 networking.hostName = "edge01";
21 networking.domain = "waw.bgp.wtf";
22
23 imports = [
24 ./modules/router.nix
Bartosz Stebelc7267982020-12-10 15:38:29 +010025 ./modules/anchorvm.nix
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020026 # Private configuration data - notably, customer data.
27 ./secrets/plain/edge01.waw.bgp.wtf-private.nix
28 ];
29
30 # TODO(q3k): make this generic, move to modules/router.nix.
31 services.unbound = {
32 enable = true;
Serge Bazanskie1aa63c2022-06-12 12:27:56 +020033 settings = {
34 server = {
35 interface = [
36 "185.236.240.1"
37 "2a0d:eb00:2137::1"
38 "127.0.0.1"
39 ];
40 access-control = [
41 "185.236.240.0/22 allow"
42 "2a0d:eb00::0/29 allow"
43 "127.0.0.0/8 allow"
44 ];
45 outgoing-interface = [
46 "185.236.240.1"
47 "2a0d:eb00:2137::1"
48 ];
49 cache-max-negative-ttl = [ "30" ];
50 local-zone = [
51 # Disable DoH in Firefox
52 "\"use-application-dns.net\" static"
53 ];
54 };
55 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020056 };
Serge Bazanskie1aa63c2022-06-12 12:27:56 +020057 hscloud.rsh.enable = true;
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020058
Serge Bazanskia5b0c132021-10-07 18:47:51 +000059 networking.wireguard.interfaces = {
Serge Bazanski82fc1312021-12-08 14:09:51 +000060 wg-fmt = {
Serge Bazanskia5b0c132021-10-07 18:47:51 +000061 ips = [
62 "185.236.240.68/31"
63 "2a0d:eb00:2137:1::e/127"
64 ];
65 allowedIPsAsRoutes = false;
66 listenPort = 51820;
67 generatePrivateKeyFile = true;
Serge Bazanski82fc1312021-12-08 14:09:51 +000068 privateKeyFile = "/root/fmt-wg";
Serge Bazanskia5b0c132021-10-07 18:47:51 +000069 peers = [
70 {
Serge Bazanski82fc1312021-12-08 14:09:51 +000071 publicKey = "zxL/1Jr0LLwJwXDm8ZOWkuY3ZkHO3sC7TdSBh89CsWc=";
Serge Bazanskia5b0c132021-10-07 18:47:51 +000072 allowedIPs = [
Serge Bazanski82fc1312021-12-08 14:09:51 +000073 "0.0.0.0/0"
74 "::/0"
Serge Bazanskia5b0c132021-10-07 18:47:51 +000075 ];
Serge Bazanski82fc1312021-12-08 14:09:51 +000076 endpoint = "[2a00:6340:4000:10::10]:41521";
Serge Bazanskia5b0c132021-10-07 18:47:51 +000077 }
78 ];
79 };
80 };
81
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020082 hscloud.renameInterfaces = {
83 # Link to Nitronet CPE.
84 e1-nnet.mac = "ac:1f:6b:1c:d7:ae";
85 # Link to HSWAW Customs.
86 e2-customs.mac = "ac:1f:6b:1c:d7:af";
87 # Link to management switch.
88 e3-mgmt.mac = "ac:1f:6b:1c:d7:b0";
89 # Link to oob1.
90 e4-oob.mac = "ac:1f:6b:1c:d7:b1";
91 e5.mac = "ac:1f:6b:1c:d7:b2";
92 e6.mac = "ac:1f:6b:1c:d7:b3";
93 # Link to dcsw01.hswaw.net
94 e7-dcsw.mac = "ac:1f:6b:1c:db:06";
95 e8.mac = "ac:1f:6b:1c:db:07";
96 };
97 networking.interfaces.e7-dcsw.mtu = 9000;
98
99 networking.vlans = {
100 "vl-globalmix" = { interface = "e1-nnet"; id = 466; };
101 "vl-polmix" = { interface = "e1-nnet"; id = 2486; };
102 "vl-openpeering" = { interface = "e1-nnet"; id = 992; };
103
104 "vl-dcsw-l3" = { interface = "e7-dcsw"; id = 4001; };
105 "vl-dist-l3" = { interface = "e7-dcsw"; id = 3006; };
106
107 # Extra vlans contained in //bgpwtf/machines/secrets/plain/edge01.waw.bgp.wtf-private.nix
108 };
109 networking.interfaces = {
110 lo = {
111 ipv4.addresses = [ { address = "185.236.240.1"; prefixLength = 32; } ];
112 ipv6.addresses = [ { address = "2a0d:eb00:2137::1"; prefixLength = 64; } ];
113 };
114 ## EPIX links via Nitronet.
115 "vl-globalmix" = {
116 ipv4.addresses = [ { address = "185.235.70.45"; prefixLength = 31; } ];
117 ipv6.addresses = [ { address = "2001:67c:778:fd40::b9eb:462d"; prefixLength = 127; } ];
118 };
119 "vl-polmix" = {
120 ipv4.addresses = [ { address = "94.246.185.175"; prefixLength = 31; } ];
121 ipv6.addresses = [ { address = "2001:67c:778:fa40::5ef6:b9af"; prefixLength = 127; } ];
122 };
123 "vl-openpeering" = {
124 ipv4.addresses = [ { address = "89.46.145.61"; prefixLength = 21; } ];
125 ipv6.addresses = [ { address = "2001:678:3ac::313"; prefixLength = 48; } ];
126 };
127
128 ## L3/mgmt links..
129 # To customs.hackerspace.pl.
130 "e2-customs" = {
131 ipv4.addresses = [ { address = "185.236.240.4"; prefixLength = 31; } ];
132 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::2"; prefixLength = 127; } ];
133 };
134 # To mgmt.
135 "e3-mgmt" = {
136 ipv4.addresses = [ { address = "10.10.10.1"; prefixLength = 24; } ];
137 };
138 # To obb1.
139 "e4-oob" = {
140 ipv4.addresses = [ { address = "185.236.240.74"; prefixLength = 29; } ];
141 };
142 # To dcsw01, L3 (BGP).
143 "vl-dcsw-l3" = {
144 mtu = 9000;
145 ipv4.addresses = [ { address = "185.236.240.6"; prefixLength = 31; } ];
146 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::6"; prefixLength = 127; } ];
147 };
148 # To dist02, L3 (BGP).
149 "vl-dist-l3" = {
150 ipv4.addresses = [ { address = "185.236.240.14"; prefixLength = 31; } ];
151 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::a"; prefixLength = 127; } ];
152 };
Bartosz Stebelc7267982020-12-10 15:38:29 +0100153 # VM bridge
154 "br0" = {
155 ipv4.addresses = [ { address = "185.236.240.17"; prefixLength = 29; } ];
156 ipv6.addresses = [ { address = "2a0d:eb00:2137:3::1"; prefixLength = 64; } ];
157 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200158
159 # Extra interface configs contained in //bgpwtf/machines/secrets/plain/edge01.waw.bgp.wtf-private.nix
160 };
Bartosz Stebelc7267982020-12-10 15:38:29 +0100161 networking.bridges = {
162 "br0" = {
163 interfaces = [];
164 };
165 };
166 hscloud.anchorvm = {
167 bridge = "br0";
168 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200169
170 hscloud.routing.enable = true;
171 hscloud.routing.routerID = "185.236.240.1";
172 hscloud.routing.asn = 204880;
173 # Use default master4/master6 tables so that `birdc show route` works.
174 hscloud.routing.tables.master.program = true;
175 hscloud.routing.tables.master.programSourceV4 = "185.236.240.1";
176 hscloud.routing.tables.master.programSourceV6 = "2a0d:eb00:2137::1";
177
178 hscloud.routing.extra = ''
179 function net_martian_v4() {
180 return net ~ [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+,
181 127.0.0.0/8+, 224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ];
182 }
183 function net_as204480_waw_v4() {
184 return net ~ [ 185.236.240.0/23+ ];
185 }
186 function net_martian_v6() {
187 return net ~ [ fc00::/7+, fec0::/10+, ::/128-, ::/0{0,15}, ::/0{49,128} ];
188 }
189 function net_as204480_waw_v6() {
190 return net ~ [ 2a0d:eb00::/32 ];
191 }
192
193 '';
194 hscloud.routing.originate = {
195 # WAW prefixes, exposed into internet BGP table.
Serge Bazanskia5b0c132021-10-07 18:47:51 +0000196 v4.waw = { table = "internet"; address = "185.236.240.0"; prefixLength = 23; };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200197 v6.waw = { table = "internet"; address = "2a0d:eb00::"; prefixLength = 32; };
198
199 # Default gateway via us, exposed into aggregated table.
200 v4.default = { table = "aggregate"; address = "0.0.0.0"; prefixLength = 0; };
201 v6.default = { table = "aggregate"; address = "::"; prefixLength = 0; };
Serge Bazanski82fc1312021-12-08 14:09:51 +0000202
203 # Loopbacks for IGP table.
204 # Alternatively we could add 'lo' as a stub interface into IGP OSPF, but
205 # that would also add 127.0.0.1...
206 v4.loopbacks = { table = "igp"; address = "185.236.240.1"; prefixLength = 32; };
207 v6.loopbacks = { table = "igp"; address = "2a0d:eb00:2137::1"; prefixLength = 128; };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200208 };
209 hscloud.routing.pipe = let
Serge Bazanskid9a63652020-10-16 19:07:41 +0200210 copySourcesToKernel = sources: table: extra: {
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200211 table = "master";
212 peerTable = table;
213 filterIn = ''
Serge Bazanskid9a63652020-10-16 19:07:41 +0200214 ${extra}
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200215 ${concatStringsSep "\n" (map (v: "if source = RTS_${v} then accept;") sources)}
216 reject;
217 '';
218 };
219 in {
Serge Bazanskid9a63652020-10-16 19:07:41 +0200220 v4."internet_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "internet" "";
Serge Bazanski81e7fba2021-09-08 23:29:52 +0200221 v4."aggregate_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "aggregate" ''
222 # Static v4 routes for customers.
223 if proto ~ "static_static_ipv4_customer_*" then accept;
224 '';
Serge Bazanskid9a63652020-10-16 19:07:41 +0200225 v6."internet_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "internet" "";
226 v6."aggregate_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "aggregate" ''
227 # Static v6 routes for customers.
228 if proto ~ "static_static_ipv6_customer_*" then accept;
229 '';
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200230 };
231
232 hscloud.routing.ospf.v6.main = {
233 area."0.0.0.0".interfaces = {
234 "e2-customs" = {
235 type = "bcast";
236 };
237 "e4-oob" = {
238 type = "bcast";
239 stub = true;
240 };
241 };
242 table = "aggregate";
243 filterIn = ''
244 # hswaw prefix from e2-customs
Serge Bazanskie9f2c9d2020-11-08 16:31:11 +0100245 if net ~ [ 2a0d:eb00:4242::/48+ ] then accept;
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200246 # e2-customs link
247 if net ~ [ 2a0d:eb00:2137:1::2/127+ ] then accept;
248 '';
249 };
250 hscloud.routing.ospf.v4.main = {
251 area."0.0.0.0".interfaces = {
252 "e4-oob" = {
253 type = "bcast";
254 stub = true;
255 };
256 };
257 table = "aggregate";
258 filterIn = ''
259 # e4-oob link
260 if net ~ [ 185.236.240.72/29+ ] then accept;
261 '';
262 };
Serge Bazanski82fc1312021-12-08 14:09:51 +0000263 hscloud.routing.ospf.v6.igp = {
264 area."0.0.0.0".interfaces = {
265 "wg-fmt" = {
266 type = "ptmp";
267 neighbors = [
268 "2a0d:eb00:2137:1::f"
269 ];
270 };
271 };
272 table = "igp";
273 filterIn = ''
274 # fmt networks
275 if net ~ [ 2a0d:eb01::/48+ ] then accept;
276 '';
277 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200278
279 hscloud.routing.bgpSessions.v4 = let
280 filterInUpstream = ''
281 if net_martian_v4() then reject;
282 if net_as204480_waw_v4() then reject;
283 accept;
284 '';
285 filterOutUpstream = ''
286 # Accept AS204880-announced prefixes.
287 if (net ~ [ 185.236.240.0/22+ ]) then accept;
288 reject;
289 '';
290 in {
291 "waw_globalmix" = {
292 description = "UPSTREAM EPIX.WAR GlobalMix";
293 table = "internet";
294 local = "185.235.70.45";
295 neighbors = [
296 { address = "185.235.70.44"; asn = 62081; }
297 ];
298 prepend = 2; pref = 100;
299 filterIn = filterInUpstream;
300 filterOut = filterOutUpstream;
301 };
302 "waw_polmix" = {
303 description = "UPSTREAM EPIX.WAR PolMix";
304 table = "internet";
305 local = "94.246.185.175";
306 neighbors = [
307 { address = "94.246.185.174"; asn = 201054; }
308 ];
309 prepend = 1; pref = 200;
310 filterIn = filterInUpstream;
311 filterOut = filterOutUpstream;
312 };
313 "waw_openpeering" = {
314 description = "IXP EPIX.WAR OpenPeering";
315 table = "internet";
316 local = "89.46.145.61";
317 neighbors = [
318 { address = "89.46.144.11"; asn = 48850; }
319 { address = "89.46.144.12"; asn = 48850; }
320 ];
321 prepend = 0; pref = 300;
322 filterIn = filterInUpstream;
323 filterOut = filterOutUpstream;
324 };
325 "waw_google" = {
326 description = "PEER Google AS15169 (EPIX)";
327 table = "internet";
328 local = "89.46.145.61";
329 neighbors = [
330 # TODO(q3k): secretify the password.
331 { address = "89.46.144.185"; asn = 15169; password = passwords."edge01.waw-bgp-google"; }
332 ];
333 prepend = 0; pref = 300;
334 filterIn = filterInUpstream;
335 filterOut = filterOutUpstream;
336 };
337 # hscloud spine switch (dcsw01.hswaw.net).
338 "waw_hscloud" = {
339 description = "AGGREGATE CUSTOMER hscloud/dcsw01";
340 table = "aggregate";
341 local = "185.236.240.6";
342 asn = 65000;
343 neighbors = [
344 { address = "185.236.240.7"; asn = 65001; }
345 ];
346 filterIn = ''
347 # wieloryb prefix
348 if net ~ [ 185.236.240.8/31+ ] then accept;
349 # dcsw01 l2 general purpose
350 if net ~ [ 185.236.240.24/29+ ] then accept;
351 # hscloud l2 general purpose
352 if net ~ [ 185.236.240.32/28+ ] then accept;
353 # k0 metallb pools
354 if net ~ [ 185.236.240.48/28+, 185.236.240.112/28+ ] then accept;
Serge Bazanski0d22d0b2022-10-08 17:03:02 +0000355 # dcsw01.hswaw.net / dcr03sw48.hswaw.net
Serge Bazanski1c80bd72021-06-30 23:22:38 +0200356 if net ~ [ 185.236.240.66/31 ] then accept;
Serge Bazanski0d22d0b2022-10-08 17:03:02 +0000357 # dcr03 mgmt
358 if net ~ [ 10.10.32.0/24 ] then accept;
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200359 reject;
360 '';
361 };
362 # bgp.wtf internet customer router on W2A, floor 3 (dist02.bgp.wtf).
363 "waw_dist02" = {
364 description = "AGGREGATE CUSTOMER bgpwtf/dist02";
365 table = "aggregate";
366 local = "185.236.240.14";
367 asn = 65000;
368 neighbors = [
369 { address = "185.236.240.15"; asn = 65002; }
370 ];
371 filterIn = ''
372 # dist02 customer routed
373 if net ~ [ 185.236.240.80/28+ ] then accept;
374 reject;
375 '';
376 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200377 # backup LTE link to edge01.fra
378 "fra_edge01" = {
379 description = "IBGP edge01.fra";
380 table = "internet";
381 local = "185.236.240.74";
382 direct = true;
383 neighbors = [
384 { address = "185.236.240.75"; asn = 204880; }
385 ];
386 pref = 50;
387 filterIn = filterInUpstream;
388 filterOut = filterOutUpstream;
389 };
390 };
391 hscloud.routing.bgpSessions.v6 = let
392 filterInUpstream = ''
393 if net_martian_v6() then reject;
394 if net_as204480_waw_v6() then reject;
395 accept;
396 '';
397 filterOutUpstream = ''
398 # Accept AS204880-announced prefixes.
399 if (net ~ [ 2a0d:eb00::/29+ ]) then accept;
400 reject;
401 '';
402 in {
403 "waw_globalmix" = {
404 description = "UPSTREAM EPIX.WAR GlobalMix";
405 table = "internet";
406 local = "2001:67c:778:fd40::b9eb:462d";
407 neighbors = [
408 { address = "2001:67c:778:fd40::b9eb:462c"; asn = 62081; }
409 ];
410 prepend = 2; pref = 100;
411 filterIn = filterInUpstream;
412 filterOut = filterOutUpstream;
413 };
414 "waw_polmix" = {
415 description = "UPSTREAM EPIX.WAR PolMix";
416 table = "internet";
417 local = "2001:67c:778:fa40::5ef6:b9af";
418 neighbors = [
419 { address = "2001:67c:778:fa40::5ef6:b9ae"; asn = 201054; }
420 ];
421 prepend = 1; pref = 200;
422 filterIn = filterInUpstream;
423 filterOut = filterOutUpstream;
424 };
425 "waw_openpeering" = {
426 description = "IXP EPIX.WAR OpenPeering";
427 table = "internet";
428 local = "2001:678:3ac::313";
429 neighbors = [
430 { address = "2001:678:3ac::11"; asn = 48850; }
431 { address = "2001:678:3ac::12"; asn = 48850; }
432 ];
433 prepend = 0; pref = 300;
434 filterIn = filterInUpstream;
435 filterOut = filterOutUpstream;
436 };
437 "waw_google" = {
438 description = "PEER Google AS15169 (EPIX)";
439 table = "internet";
440 local = "2001:678:3ac::313";
441 neighbors = [
442 { address = "2001:678:3ac::185"; asn = 15169; password = passwords."edge01.waw-bgp-google"; }
443 ];
444 prepend = 0; pref = 300;
445 filterIn = filterInUpstream;
446 filterOut = filterOutUpstream;
447 };
448 # hscloud spine switch (dcsw01.hswaw.net).
449 "waw_hscloud" = {
450 description = "AGGREGATE CUSTOMER dcsw01.hswaw.net";
451 table = "aggregate";
452 local = "2a0d:eb00:2137:1::6";
453 asn = 65000;
454 neighbors = [
455 { address = "2a0d:eb00:2137:1::7"; asn = 65001; }
456 ];
457 filterIn = ''
458 # dcsw01 l2 general purpose
459 if net ~ [ 2a0d:eb00:2137::/48+ ] then accept;
Serge Bazanski400e03f2021-07-20 17:57:49 +0200460 # customer
461 if net ~ [ 2a0d:eb00:8004::/48+ ] then accept;
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200462 reject;
463 '';
464 };
465 # bgp.wtf internet customer router on W2A, floor 3 (dist02.bgp.wtf).
466 "waw_dist02" = {
467 description = "AGGREGATE CUSTOMER dist02.bgp.wtf";
468 table = "aggregate";
469 local = "2a0d:eb00:2137:1::a";
470 asn = 65000;
471 neighbors = [
472 { address = "2a0d:eb00:2137:1::b"; asn = 65002; }
473 ];
474 filterIn = ''
475 # dist02 customers.
476 if net ~ [ 2a0d:eb00:8002::/48 ] then accept;
477 reject;
478 '';
479 };
480 };
481}