blob: bdb55e317c505a2162cf7b36ad6c7f09cf0a2dbf [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;
33 interfaces = [
34 "185.236.240.1"
35 "2a0d:eb00:2137::1"
36 "127.0.0.1"
37 ];
38 allowedAccess = [
39 "185.236.240.0/22"
40 "2a0d:eb00::0/29"
41 "127.0.0.0/8"
42 ];
43 extraConfig = ''
44 outgoing-interface: 185.236.240.1
45 outgoing-interface: 2a0d:eb00:2137::1
46 cache-max-negative-ttl: 30
47
48 # Disable DoH in Firefox
49 local-zone: "use-application-dns.net" static
50
51 # Rejestr Stron Hazardowych.
52 # Populated by the rsh-unbound daemon.
53 include: "/var/lib/unbound/rsh.conf"
Serge Bazanski767f0312021-12-08 14:07:39 +000054
55 remote-control:
56 control-enable: yes
57 control-interface: /var/run/unbound.ctl
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020058 '';
59 };
Serge Bazanski767f0312021-12-08 14:07:39 +000060 # Fix `systemctl reload unbound`.
61 systemd.services.unbound.reload = "${pkgs.unbound}/bin/unbound-control -c /var/lib/unbound/unbound.conf reload";
Serge Bazanski6abe4fa2020-10-03 00:18:34 +020062 hscloud.rsh = {
63 enable = true;
64 out = "/var/lib/unbound/rsh.conf";
65 };
66
Serge Bazanskia5b0c132021-10-07 18:47:51 +000067 networking.wireguard.interfaces = {
68 wg-camp = {
69 ips = [
70 "185.236.240.68/31"
71 "2a0d:eb00:2137:1::e/127"
72 ];
73 allowedIPsAsRoutes = false;
74 listenPort = 51820;
75 generatePrivateKeyFile = true;
76 privateKeyFile = "/root/camp-wg";
77 peers = [
78 {
79 publicKey = "TbXDHeHwT4/xQ1+l4HH9EzbYUUCU4Pk/r0nsGSw+qUc=";
80 allowedIPs = [
81 "185.236.240.69/32"
82 "185.236.241.0/24"
83 "2a0d:eb00:8007::/48"
84 "2a0d:eb00:2137:1::f/128"
85 ];
86 }
87 ];
88 };
89 };
90
91 hscloud.routing.static.v6.camp = {
92 table = "aggregate";
93 address = "2a0d:eb00:8007::";
94 prefixLength = 48;
95 via = "2a0d:eb00:2137:1::f";
96 };
97 hscloud.routing.static.v4.camp = {
98 table = "aggregate";
99 address = "185.236.241.0";
100 prefixLength = 24;
101 via = "185.236.240.69";
102 };
103
104
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200105 hscloud.renameInterfaces = {
106 # Link to Nitronet CPE.
107 e1-nnet.mac = "ac:1f:6b:1c:d7:ae";
108 # Link to HSWAW Customs.
109 e2-customs.mac = "ac:1f:6b:1c:d7:af";
110 # Link to management switch.
111 e3-mgmt.mac = "ac:1f:6b:1c:d7:b0";
112 # Link to oob1.
113 e4-oob.mac = "ac:1f:6b:1c:d7:b1";
114 e5.mac = "ac:1f:6b:1c:d7:b2";
115 e6.mac = "ac:1f:6b:1c:d7:b3";
116 # Link to dcsw01.hswaw.net
117 e7-dcsw.mac = "ac:1f:6b:1c:db:06";
118 e8.mac = "ac:1f:6b:1c:db:07";
119 };
120 networking.interfaces.e7-dcsw.mtu = 9000;
121
122 networking.vlans = {
123 "vl-globalmix" = { interface = "e1-nnet"; id = 466; };
124 "vl-polmix" = { interface = "e1-nnet"; id = 2486; };
125 "vl-openpeering" = { interface = "e1-nnet"; id = 992; };
126
127 "vl-dcsw-l3" = { interface = "e7-dcsw"; id = 4001; };
128 "vl-dist-l3" = { interface = "e7-dcsw"; id = 3006; };
129
130 # Extra vlans contained in //bgpwtf/machines/secrets/plain/edge01.waw.bgp.wtf-private.nix
131 };
132 networking.interfaces = {
133 lo = {
134 ipv4.addresses = [ { address = "185.236.240.1"; prefixLength = 32; } ];
135 ipv6.addresses = [ { address = "2a0d:eb00:2137::1"; prefixLength = 64; } ];
136 };
137 ## EPIX links via Nitronet.
138 "vl-globalmix" = {
139 ipv4.addresses = [ { address = "185.235.70.45"; prefixLength = 31; } ];
140 ipv6.addresses = [ { address = "2001:67c:778:fd40::b9eb:462d"; prefixLength = 127; } ];
141 };
142 "vl-polmix" = {
143 ipv4.addresses = [ { address = "94.246.185.175"; prefixLength = 31; } ];
144 ipv6.addresses = [ { address = "2001:67c:778:fa40::5ef6:b9af"; prefixLength = 127; } ];
145 };
146 "vl-openpeering" = {
147 ipv4.addresses = [ { address = "89.46.145.61"; prefixLength = 21; } ];
148 ipv6.addresses = [ { address = "2001:678:3ac::313"; prefixLength = 48; } ];
149 };
150
151 ## L3/mgmt links..
152 # To customs.hackerspace.pl.
153 "e2-customs" = {
154 ipv4.addresses = [ { address = "185.236.240.4"; prefixLength = 31; } ];
155 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::2"; prefixLength = 127; } ];
156 };
157 # To mgmt.
158 "e3-mgmt" = {
159 ipv4.addresses = [ { address = "10.10.10.1"; prefixLength = 24; } ];
160 };
161 # To obb1.
162 "e4-oob" = {
163 ipv4.addresses = [ { address = "185.236.240.74"; prefixLength = 29; } ];
164 };
165 # To dcsw01, L3 (BGP).
166 "vl-dcsw-l3" = {
167 mtu = 9000;
168 ipv4.addresses = [ { address = "185.236.240.6"; prefixLength = 31; } ];
169 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::6"; prefixLength = 127; } ];
170 };
171 # To dist02, L3 (BGP).
172 "vl-dist-l3" = {
173 ipv4.addresses = [ { address = "185.236.240.14"; prefixLength = 31; } ];
174 ipv6.addresses = [ { address = "2a0d:eb00:2137:1::a"; prefixLength = 127; } ];
175 };
Bartosz Stebelc7267982020-12-10 15:38:29 +0100176 # VM bridge
177 "br0" = {
178 ipv4.addresses = [ { address = "185.236.240.17"; prefixLength = 29; } ];
179 ipv6.addresses = [ { address = "2a0d:eb00:2137:3::1"; prefixLength = 64; } ];
180 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200181
182 # Extra interface configs contained in //bgpwtf/machines/secrets/plain/edge01.waw.bgp.wtf-private.nix
183 };
Bartosz Stebelc7267982020-12-10 15:38:29 +0100184 networking.bridges = {
185 "br0" = {
186 interfaces = [];
187 };
188 };
189 hscloud.anchorvm = {
190 bridge = "br0";
191 };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200192
193 hscloud.routing.enable = true;
194 hscloud.routing.routerID = "185.236.240.1";
195 hscloud.routing.asn = 204880;
196 # Use default master4/master6 tables so that `birdc show route` works.
197 hscloud.routing.tables.master.program = true;
198 hscloud.routing.tables.master.programSourceV4 = "185.236.240.1";
199 hscloud.routing.tables.master.programSourceV6 = "2a0d:eb00:2137::1";
200
201 hscloud.routing.extra = ''
202 function net_martian_v4() {
203 return net ~ [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+,
204 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} ];
205 }
206 function net_as204480_waw_v4() {
207 return net ~ [ 185.236.240.0/23+ ];
208 }
209 function net_martian_v6() {
210 return net ~ [ fc00::/7+, fec0::/10+, ::/128-, ::/0{0,15}, ::/0{49,128} ];
211 }
212 function net_as204480_waw_v6() {
213 return net ~ [ 2a0d:eb00::/32 ];
214 }
215
216 '';
217 hscloud.routing.originate = {
218 # WAW prefixes, exposed into internet BGP table.
Serge Bazanskia5b0c132021-10-07 18:47:51 +0000219 v4.waw = { table = "internet"; address = "185.236.240.0"; prefixLength = 23; };
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200220 v6.waw = { table = "internet"; address = "2a0d:eb00::"; prefixLength = 32; };
221
222 # Default gateway via us, exposed into aggregated table.
223 v4.default = { table = "aggregate"; address = "0.0.0.0"; prefixLength = 0; };
224 v6.default = { table = "aggregate"; address = "::"; prefixLength = 0; };
225 };
226 hscloud.routing.pipe = let
Serge Bazanskid9a63652020-10-16 19:07:41 +0200227 copySourcesToKernel = sources: table: extra: {
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200228 table = "master";
229 peerTable = table;
230 filterIn = ''
Serge Bazanskid9a63652020-10-16 19:07:41 +0200231 ${extra}
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200232 ${concatStringsSep "\n" (map (v: "if source = RTS_${v} then accept;") sources)}
233 reject;
234 '';
235 };
236 in {
Serge Bazanskid9a63652020-10-16 19:07:41 +0200237 v4."internet_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "internet" "";
Serge Bazanski81e7fba2021-09-08 23:29:52 +0200238 v4."aggregate_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "aggregate" ''
239 # Static v4 routes for customers.
240 if proto ~ "static_static_ipv4_customer_*" then accept;
241 '';
Serge Bazanskid9a63652020-10-16 19:07:41 +0200242 v6."internet_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "internet" "";
243 v6."aggregate_to_kernel" = copySourcesToKernel ["BGP" "OSPF"] "aggregate" ''
244 # Static v6 routes for customers.
245 if proto ~ "static_static_ipv6_customer_*" then accept;
246 '';
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200247 };
248
249 hscloud.routing.ospf.v6.main = {
250 area."0.0.0.0".interfaces = {
251 "e2-customs" = {
252 type = "bcast";
253 };
254 "e4-oob" = {
255 type = "bcast";
256 stub = true;
257 };
258 };
259 table = "aggregate";
260 filterIn = ''
261 # hswaw prefix from e2-customs
Serge Bazanskie9f2c9d2020-11-08 16:31:11 +0100262 if net ~ [ 2a0d:eb00:4242::/48+ ] then accept;
Serge Bazanski6abe4fa2020-10-03 00:18:34 +0200263 # e2-customs link
264 if net ~ [ 2a0d:eb00:2137:1::2/127+ ] then accept;
265 '';
266 };
267 hscloud.routing.ospf.v4.main = {
268 area."0.0.0.0".interfaces = {
269 "e4-oob" = {
270 type = "bcast";
271 stub = true;
272 };
273 };
274 table = "aggregate";
275 filterIn = ''
276 # e4-oob link
277 if net ~ [ 185.236.240.72/29+ ] then accept;
278 '';
279 };
280
281 hscloud.routing.bgpSessions.v4 = let
282 filterInUpstream = ''
283 if net_martian_v4() then reject;
284 if net_as204480_waw_v4() then reject;
285 accept;
286 '';
287 filterOutUpstream = ''
288 # Accept AS204880-announced prefixes.
289 if (net ~ [ 185.236.240.0/22+ ]) then accept;
290 reject;
291 '';
292 in {
293 "waw_globalmix" = {
294 description = "UPSTREAM EPIX.WAR GlobalMix";
295 table = "internet";
296 local = "185.235.70.45";
297 neighbors = [
298 { address = "185.235.70.44"; asn = 62081; }
299 ];
300 prepend = 2; pref = 100;
301 filterIn = filterInUpstream;
302 filterOut = filterOutUpstream;
303 };
304 "waw_polmix" = {
305 description = "UPSTREAM EPIX.WAR PolMix";
306 table = "internet";
307 local = "94.246.185.175";
308 neighbors = [
309 { address = "94.246.185.174"; asn = 201054; }
310 ];
311 prepend = 1; pref = 200;
312 filterIn = filterInUpstream;
313 filterOut = filterOutUpstream;
314 };
315 "waw_openpeering" = {
316 description = "IXP EPIX.WAR OpenPeering";
317 table = "internet";
318 local = "89.46.145.61";
319 neighbors = [
320 { address = "89.46.144.11"; asn = 48850; }
321 { address = "89.46.144.12"; asn = 48850; }
322 ];
323 prepend = 0; pref = 300;
324 filterIn = filterInUpstream;
325 filterOut = filterOutUpstream;
326 };
327 "waw_google" = {
328 description = "PEER Google AS15169 (EPIX)";
329 table = "internet";
330 local = "89.46.145.61";
331 neighbors = [
332 # TODO(q3k): secretify the password.
333 { address = "89.46.144.185"; asn = 15169; password = passwords."edge01.waw-bgp-google"; }
334 ];
335 prepend = 0; pref = 300;
336 filterIn = filterInUpstream;
337 filterOut = filterOutUpstream;
338 };
339 # hscloud spine switch (dcsw01.hswaw.net).
340 "waw_hscloud" = {
341 description = "AGGREGATE CUSTOMER hscloud/dcsw01";
342 table = "aggregate";
343 local = "185.236.240.6";
344 asn = 65000;
345 neighbors = [
346 { address = "185.236.240.7"; asn = 65001; }
347 ];
348 filterIn = ''
349 # wieloryb prefix
350 if net ~ [ 185.236.240.8/31+ ] then accept;
351 # dcsw01 l2 general purpose
352 if net ~ [ 185.236.240.24/29+ ] then accept;
353 # hscloud l2 general purpose
354 if net ~ [ 185.236.240.32/28+ ] then accept;
355 # k0 metallb pools
356 if net ~ [ 185.236.240.48/28+, 185.236.240.112/28+ ] then accept;
Serge Bazanski1c80bd72021-06-30 23:22:38 +0200357 # dcsw01.hswaw.net / dcr03sw48.hswaw.net
358 if net ~ [ 185.236.240.66/31 ] 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}