My Nix Configuration
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

[hosts.prefect] redo dn42 configuration with dn42.nix

dish b9ff3036 89c0dc3e

+623 -653
+3
.nvim.lua
··· 22 22 flake_parts_perSystem = { 23 23 expr = "(builtins.getFlake (builtins.toString ./.)).currentSystem.options", 24 24 }, 25 + my_modules = { 26 + exper = "(pkgs.lib.evalModules { modules = (builtins.getFlake (builtins.toString ./.)).nixosModules; }).options" 27 + } 25 28 }, 26 29 }, 27 30 },
+81 -4
flake.lock
··· 25 25 "type": "github" 26 26 } 27 27 }, 28 + "bird": { 29 + "inputs": { 30 + "flake-utils": "flake-utils", 31 + "nixpkgs": [ 32 + "dn42", 33 + "nixpkgs" 34 + ] 35 + }, 36 + "locked": { 37 + "lastModified": 1757884119, 38 + "narHash": "sha256-RF0Em7PjDRaQ5cBFgc3fL22qgDVbv2HoVW1TDRaaSNo=", 39 + "owner": "NuschtOS", 40 + "repo": "bird.nix", 41 + "rev": "f8d18c2c8eebd477987001a9c0af50a9ca7909e5", 42 + "type": "github" 43 + }, 44 + "original": { 45 + "owner": "NuschtOS", 46 + "repo": "bird.nix", 47 + "type": "github" 48 + } 49 + }, 28 50 "buildbot-nix": { 29 51 "inputs": { 30 52 "flake-parts": [ ··· 247 269 "original": { 248 270 "owner": "Daniel-42-z", 249 271 "repo": "dms-wallpaper-shuffler", 272 + "type": "github" 273 + } 274 + }, 275 + "dn42": { 276 + "inputs": { 277 + "bird": "bird", 278 + "nixpkgs": [ 279 + "nixpkgs" 280 + ] 281 + }, 282 + "locked": { 283 + "lastModified": 1759332252, 284 + "narHash": "sha256-zMPiXQmun2EIefsFlfkvcL6V2TcP0ASCjNbdaTQei68=", 285 + "owner": "NuschtOS", 286 + "repo": "dn42.nix", 287 + "rev": "4f786e87300f5f0361e4b6f3577e323b091d128b", 288 + "type": "github" 289 + }, 290 + "original": { 291 + "owner": "NuschtOS", 292 + "repo": "dn42.nix", 250 293 "type": "github" 251 294 } 252 295 }, ··· 332 375 }, 333 376 "flake-utils_2": { 334 377 "inputs": { 335 - "systems": "systems_4" 378 + "systems": "systems_3" 379 + }, 380 + "locked": { 381 + "lastModified": 1731533236, 382 + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 383 + "owner": "numtide", 384 + "repo": "flake-utils", 385 + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 386 + "type": "github" 387 + }, 388 + "original": { 389 + "owner": "numtide", 390 + "repo": "flake-utils", 391 + "type": "github" 392 + } 393 + }, 394 + "flake-utils_3": { 395 + "inputs": { 396 + "systems": "systems_5" 336 397 }, 337 398 "locked": { 338 399 "lastModified": 1694529238, ··· 353 414 "nixpkgs": [ 354 415 "nixpkgs" 355 416 ], 356 - "systems": "systems_3" 417 + "systems": "systems_4" 357 418 }, 358 419 "locked": { 359 420 "lastModified": 1760925941, ··· 371 432 }, 372 433 "gomod2nix": { 373 434 "inputs": { 374 - "flake-utils": "flake-utils_2", 435 + "flake-utils": "flake-utils_3", 375 436 "nixpkgs": [ 376 437 "tangled", 377 438 "nixpkgs" ··· 676 737 "dms-plugins": "dms-plugins", 677 738 "dms-power-usage": "dms-power-usage", 678 739 "dms-wp-shuffler": "dms-wp-shuffler", 740 + "dn42": "dn42", 679 741 "easy-hosts": "easy-hosts", 680 742 "flake-compat": "flake-compat", 681 743 "flake-parts": "flake-parts", 682 - "flake-utils": "flake-utils", 744 + "flake-utils": "flake-utils_2", 683 745 "golink": "golink", 684 746 "hardware": "hardware", 685 747 "home-manager": "home-manager", ··· 751 813 } 752 814 }, 753 815 "systems_4": { 816 + "locked": { 817 + "lastModified": 1681028828, 818 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 819 + "owner": "nix-systems", 820 + "repo": "default", 821 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 822 + "type": "github" 823 + }, 824 + "original": { 825 + "owner": "nix-systems", 826 + "repo": "default", 827 + "type": "github" 828 + } 829 + }, 830 + "systems_5": { 754 831 "locked": { 755 832 "lastModified": 1681028828, 756 833 "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+4
flake.nix
··· 50 50 ctp = { 51 51 url = "github:catppuccin/nix"; 52 52 }; 53 + dn42 = { 54 + url = "github:NuschtOS/dn42.nix"; 55 + inputs.nixpkgs.follows = "nixpkgs"; 56 + }; 53 57 dms = { 54 58 url = "github:AvengeMedia/DankMaterialShell"; 55 59 inputs.nixpkgs.follows = "nixpkgs";
+4
hosts/default.nix
··· 40 40 "server" 41 41 "vps" 42 42 ]; 43 + modules = [ 44 + inputs.self.nixosModules.dn42Wireguard 45 + inputs.dn42.nixosModules.default 46 + ]; 43 47 }; 44 48 thought = { 45 49 deployable = true;
-109
hosts/prefect/dn42/bgp.nix
··· 1 - _: { 2 - sessions = [ 3 - # Chrismoos 4 - { 5 - multi = true; 6 - multihop = false; 7 - gracefulRestart = true; 8 - name = "chrismoos"; 9 - neigh = "fe80::1588%wg42_chris"; 10 - as = "4242421588"; 11 - link = "1"; 12 - } 13 - # Kioubit 14 - { 15 - multi = true; 16 - multihop = false; 17 - gracefulRestart = true; 18 - name = "kioubit"; 19 - neigh = "fe80::ade0%wg42_kioubit"; 20 - as = "4242423914"; 21 - link = "3"; 22 - } 23 - # IEDON 24 - { 25 - multi = true; 26 - multihop = false; 27 - gracefulRestart = true; 28 - name = "ideon"; 29 - neigh = "fe80::2189:e8%wg42_iedon"; 30 - as = "4242422189"; 31 - link = "5"; 32 - } 33 - # SUNNET 34 - { 35 - multi = true; 36 - multihop = false; 37 - gracefulRestart = true; 38 - name = "sunnet"; 39 - neigh = "fe80::3088:193%wg42_sunnet"; 40 - as = "4242423088"; 41 - link = "3"; 42 - } 43 - # C4TG1RL5 44 - { 45 - multi = true; 46 - multihop = false; 47 - gracefulRestart = true; 48 - name = "c4tg1rl5"; 49 - neigh = "fe80::4242%wg42_catgirls"; 50 - as = "4242421411"; 51 - link = "6"; 52 - } 53 - # Potat0 54 - { 55 - multi = true; 56 - multihop = false; 57 - gracefulRestart = true; 58 - name = "potato"; 59 - neigh = "fe80::1816%wg42_potato"; 60 - as = "4242421816"; 61 - link = "2"; 62 - } 63 - # Uffsalot-v6 64 - { 65 - multi = false; 66 - v4 = false; 67 - v6 = true; 68 - multihop = false; 69 - gracefulRestart = true; 70 - name = "uffsalot_v6"; 71 - neigh = "fe80::780%wg42_uffsalot"; 72 - as = "4242420780"; 73 - link = "5"; 74 - } 75 - # Uffsalot-v6 76 - { 77 - multi = false; 78 - v4 = true; 79 - v6 = false; 80 - multihop = false; 81 - gracefulRestart = true; 82 - name = "uffsalot_v4"; 83 - neigh = "172.20.191.129"; 84 - as = "4242420780"; 85 - link = "5"; 86 - } 87 - # Bandura 88 - { 89 - multi = true; 90 - multihop = false; 91 - gracefulRestart = true; 92 - name = "bandura"; 93 - neigh = "fe80::2926%wg42_bandura"; 94 - as = "4242422923"; 95 - link = "4"; 96 - } 97 - # Bluemedia 98 - { 99 - multi = true; 100 - multihop = false; 101 - gracefulRestart = true; 102 - name = "bluemedia"; 103 - neigh = "fe80::42:3343:20:1%wg42_bluemedia"; 104 - as = "4242423343"; 105 - link = "5"; 106 - } 107 - ]; 108 - extraConfig = ""; 109 - }
-315
hosts/prefect/dn42/bird.conf
··· 1 - log stderr all; 2 - debug protocols all; 3 - timeformat protocol iso long; 4 - ################################################ 5 - # Variable header # 6 - ################################################ 7 - 8 - define OWNAS = 4242422459; 9 - define OWNIP = 172.20.43.96; 10 - define OWNIPv6 = fd21:1500:66b0::1; 11 - define OWNNET = 172.20.43.96/27; 12 - define OWNNETv6 = fd21:1500:66b0::/48; 13 - define OWNNETSET = [172.20.43.96/29+]; 14 - define OWNNETSETv6 = [fd21:1500:66b0::/48+]; 15 - define DN42_REGION = 42; 16 - 17 - ################################################ 18 - # Header end # 19 - ################################################ 20 - 21 - router id OWNIP; 22 - 23 - protocol device { 24 - scan time 10; 25 - } 26 - 27 - /* 28 - * Utility functions 29 - */ 30 - 31 - function is_self_net() { 32 - return net ~ OWNNETSET; 33 - } 34 - 35 - function is_self_net_v6() { 36 - return net ~ OWNNETSETv6; 37 - } 38 - 39 - function is_valid_network() { 40 - return net ~ [ 41 - 172.20.0.0/14{21,29}, # dn42 42 - 172.20.0.0/24{28,32}, # dn42 Anycast 43 - 172.21.0.0/24{28,32}, # dn42 Anycast 44 - 172.22.0.0/24{28,32}, # dn42 Anycast 45 - 172.23.0.0/24{28,32}, # dn42 Anycast 46 - 172.31.0.0/16+, # ChaosVPN 47 - 10.100.0.0/14+, # ChaosVPN 48 - 10.127.0.0/16{16,32}, # neonetwork 49 - 10.0.0.0/8{15,24} # Freifunk.net 50 - ]; 51 - } 52 - 53 - roa4 table dn42_roa; 54 - roa6 table dn42_roa_v6; 55 - 56 - protocol static { 57 - roa4 { table dn42_roa; }; 58 - include "/etc/bird/roa_dn42.conf"; 59 - }; 60 - 61 - protocol static { 62 - roa6 { table dn42_roa_v6; }; 63 - include "/etc/bird/roa_dn42_v6.conf"; 64 - }; 65 - 66 - function is_valid_network_v6() { 67 - return net ~ [ 68 - fd00::/8{44,64} # ULA address space as per RFC 4193 69 - ]; 70 - } 71 - 72 - protocol kernel { 73 - scan time 20; 74 - 75 - ipv6 { 76 - import none; 77 - export filter { 78 - if source = RTS_STATIC then reject; 79 - krt_prefsrc = OWNIPv6; 80 - accept; 81 - }; 82 - }; 83 - }; 84 - 85 - protocol kernel { 86 - scan time 20; 87 - ipv4 { 88 - import none; 89 - export filter { 90 - if source = RTS_STATIC then reject; 91 - krt_prefsrc = OWNIP; 92 - accept; 93 - }; 94 - }; 95 - } 96 - 97 - protocol static { 98 - route OWNNET reject; 99 - 100 - ipv4 { 101 - import all; 102 - export none; 103 - }; 104 - } 105 - 106 - protocol static { 107 - route OWNNETv6 reject; 108 - 109 - ipv6 { 110 - import all; 111 - export none; 112 - }; 113 - } 114 - 115 - template bgp dnpeers { 116 - local as OWNAS; 117 - path metric 1; 118 - } 119 - 120 - protocol ospf v3 { 121 - ipv4 { 122 - export filter { 123 - if source = RTS_STATIC || source = RTS_BGP then reject; 124 - accept; 125 - }; 126 - }; 127 - 128 - area 0 { 129 - interface "lo" { 130 - stub; 131 - }; 132 - 133 - interface "ospf_*"{ 134 - type pointopoint; 135 - }; 136 - }; 137 - } 138 - 139 - protocol ospf v3 { 140 - ipv6 { 141 - export filter { 142 - if source = RTS_STATIC || source = RTS_BGP then reject; 143 - accept; 144 - }; 145 - }; 146 - 147 - area 0 { 148 - interface "lo" { 149 - stub; 150 - }; 151 - 152 - interface "ospf_*" { 153 - type pointopoint; 154 - }; 155 - 156 - }; 157 - } 158 - 159 - 160 - function update_latency(int link_latency) { 161 - bgp_community.add((64511, link_latency)); 162 - if (64511, 9) ~ bgp_community then { bgp_community.delete([(64511, 1..8)]); return 9; } 163 - else if (64511, 8) ~ bgp_community then { bgp_community.delete([(64511, 1..7)]); return 8; } 164 - else if (64511, 7) ~ bgp_community then { bgp_community.delete([(64511, 1..6)]); return 7; } 165 - else if (64511, 6) ~ bgp_community then { bgp_community.delete([(64511, 1..5)]); return 6; } 166 - else if (64511, 5) ~ bgp_community then { bgp_community.delete([(64511, 1..4)]); return 5; } 167 - else if (64511, 4) ~ bgp_community then { bgp_community.delete([(64511, 1..3)]); return 4; } 168 - else if (64511, 3) ~ bgp_community then { bgp_community.delete([(64511, 1..2)]); return 3; } 169 - else if (64511, 2) ~ bgp_community then { bgp_community.delete([(64511, 1..1)]); return 2; } 170 - else return 1; 171 - } 172 - 173 - function update_bandwidth(int link_bandwidth) { 174 - bgp_community.add((64511, link_bandwidth)); 175 - if (64511, 21) ~ bgp_community then { bgp_community.delete([(64511, 22..29)]); return 21; } 176 - else if (64511, 22) ~ bgp_community then { bgp_community.delete([(64511, 23..29)]); return 22; } 177 - else if (64511, 23) ~ bgp_community then { bgp_community.delete([(64511, 24..29)]); return 23; } 178 - else if (64511, 24) ~ bgp_community then { bgp_community.delete([(64511, 25..29)]); return 24; } 179 - else if (64511, 25) ~ bgp_community then { bgp_community.delete([(64511, 26..29)]); return 25; } 180 - else if (64511, 26) ~ bgp_community then { bgp_community.delete([(64511, 27..29)]); return 26; } 181 - else if (64511, 27) ~ bgp_community then { bgp_community.delete([(64511, 28..29)]); return 27; } 182 - else if (64511, 28) ~ bgp_community then { bgp_community.delete([(64511, 29..29)]); return 28; } 183 - else return 29; 184 - } 185 - 186 - function update_crypto(int link_crypto) { 187 - bgp_community.add((64511, link_crypto)); 188 - if (64511, 31) ~ bgp_community then { bgp_community.delete([(64511, 32..34)]); return 31; } 189 - else if (64511, 32) ~ bgp_community then { bgp_community.delete([(64511, 33..34)]); return 32; } 190 - else if (64511, 33) ~ bgp_community then { bgp_community.delete([(64511, 34..34)]); return 33; } 191 - else return 34; 192 - } 193 - 194 - function get_region() { 195 - if (64511, 41) ~ bgp_community then { return 41; } 196 - else if (64511, 42) ~ bgp_community then { return 42; } 197 - else if (64511, 43) ~ bgp_community then { return 43; } 198 - else if (64511, 44) ~ bgp_community then { return 44; } 199 - else if (64511, 45) ~ bgp_community then { return 45; } 200 - else if (64511, 46) ~ bgp_community then { return 46; } 201 - else if (64511, 47) ~ bgp_community then { return 47; } 202 - else if (64511, 48) ~ bgp_community then { return 48; } 203 - else if (64511, 49) ~ bgp_community then { return 49; } 204 - else if (64511, 50) ~ bgp_community then { return 50; } 205 - else if (64511, 51) ~ bgp_community then { return 51; } 206 - else if (64511, 52) ~ bgp_community then { return 52; } 207 - else if (64511, 53) ~ bgp_community then { return 53; } 208 - else return DN42_REGION; 209 - } 210 - 211 - 212 - function calculate_local_pref(int dn42_latency) 213 - int pref; 214 - { 215 - pref = 100; 216 - if (is_self_net() || is_self_net_v6()) then { 217 - pref = 2000; 218 - } 219 - else if (bgp_path.len = 1) then { 220 - pref = 1000; 221 - } 222 - else if (DN42_REGION = get_region()) then { 223 - pref= 500; 224 - } 225 - else { 226 - if (DN42_REGION > get_region()) then { 227 - pref = 500 - ((DN42_REGION - get_region()) * 10); 228 - } 229 - else { 230 - pref = 500 - ((get_region() - DN42_REGION) * 10); 231 - } 232 - } 233 - pref = pref - 10*dn42_latency - 10* bgp_path.len; 234 - if pref > 2000 then { 235 - pref = 10; 236 - } 237 - return pref; 238 - } 239 - 240 - function update_flags(int link_latency; int link_bandwidth; int link_crypto) 241 - int dn42_latency; 242 - int dn42_bandwidth; 243 - int dn42_crypto; 244 - { 245 - dn42_latency = update_latency(link_latency); 246 - dn42_bandwidth = update_bandwidth(link_bandwidth) - 20; 247 - dn42_crypto = update_crypto(link_crypto) - 30; 248 - if dn42_bandwidth > 5 then dn42_bandwidth = 5; 249 - bgp_local_pref = calculate_local_pref(dn42_latency); 250 - return true; 251 - } 252 - 253 - 254 - function dn42_import_filter(int link_latency; int link_bandwidth; int link_crypto) { 255 - if (is_valid_network() && !is_self_net()) || (is_valid_network_v6() && !is_self_net_v6()) then { 256 - if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then { 257 - print "[dn42] Import : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto; 258 - reject; 259 - } 260 - update_flags(link_latency, link_bandwidth, link_crypto); 261 - if (65535, 666) ~ bgp_community then dest = RTD_BLACKHOLE; 262 - accept; 263 - } 264 - print "[dn42] Import : Invalid Network for ", net, " ASN ", bgp_path.last, " on ", proto; 265 - reject; 266 - } 267 - 268 - function dn42_export_filter(int link_latency; int link_bandwith; int link_crypto) { 269 - if is_valid_network() || is_valid_network_v6() then { 270 - # if roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID && roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID then { 271 - # print "[dn42] Export : ROA check failed for ", net, " ASN ", bgp_path.last, " on ", proto; 272 - # reject; 273 - # } 274 - if source = RTS_STATIC then bgp_community.add((64511, DN42_REGION)); 275 - update_flags(link_latency, link_bandwith, link_crypto); 276 - accept; 277 - } 278 - reject; 279 - } 280 - 281 - protocol bgp route_collector from dnpeers { 282 - neighbor fd42:4242:2601:ac12::1 as 4242422602; 283 - multihop; 284 - ipv4 { 285 - # export all available paths to the collector 286 - add paths tx; 287 - 288 - # import/export filters 289 - import none; 290 - export filter { 291 - # export all valid routes 292 - if ( is_valid_network() && source ~ [ RTS_STATIC, RTS_BGP ] ) 293 - then { 294 - accept; 295 - } 296 - reject; 297 - }; 298 - }; 299 - 300 - ipv6 { 301 - # export all available paths to the collector 302 - add paths tx; 303 - 304 - # import/export filters 305 - import none; 306 - export filter { 307 - # export all valid routes 308 - if ( is_valid_network_v6() && source ~ [ RTS_STATIC, RTS_BGP ] ) 309 - then { 310 - accept; 311 - } 312 - reject; 313 - }; 314 - }; 315 - }
+53 -20
hosts/prefect/dn42/default.nix
··· 1 - { pkgs, ... }: 1 + { pkgs, config, ... }: 2 + let 3 + cfg42 = config.networking.dn42; 4 + in 2 5 { 3 6 imports = [ 4 - ./services.nix 5 - ./wireguard.nix 7 + ./peers 6 8 ]; 7 - networking.interfaces.lo = { 8 - ipv4.addresses = [ 9 - { 10 - address = "172.20.43.96"; 11 - prefixLength = 32; 12 - } 13 - ]; 14 - ipv6.addresses = [ 15 - { 16 - address = "fd21:1500:66b0::1"; 17 - prefixLength = 128; 18 - } 19 - { 20 - address = "fe80::1"; 21 - prefixLength = 128; 22 - } 23 - ]; 9 + networking = { 10 + interfaces.lo = { 11 + ipv4.addresses = [ 12 + { 13 + address = "172.20.43.96"; 14 + prefixLength = 32; 15 + } 16 + ]; 17 + ipv6.addresses = [ 18 + { 19 + address = "fd21:1500:66b0::1"; 20 + prefixLength = 128; 21 + } 22 + { 23 + address = "fe80::1"; 24 + prefixLength = 128; 25 + } 26 + ]; 27 + }; 24 28 }; 29 + 25 30 environment.systemPackages = with pkgs; [ 26 31 dnsutils 27 32 mtr 28 33 tcpdump 29 34 wireguard-tools 30 35 ]; 36 + networking.dn42 = { 37 + enable = true; 38 + # ASN corresponding to DN42 PYRONET 39 + as = 4242422459; 40 + # Communities config 41 + # https://dn42.dev/howto/BGP-communities 42 + geo = 42; 43 + country = 1840; 44 + routerId = cfg42.addr.v4; 45 + # Primary IP Addresses 46 + addr = { 47 + v4 = "172.20.43.96"; 48 + v6 = "fd21:1500:66b0::1"; 49 + }; 50 + # Owned IP Ranges 51 + nets = { 52 + v4 = [ "172.20.43.96/27" ]; 53 + v6 = [ "fd21:1500:66b0::/48" ]; 54 + }; 55 + 56 + # Enable StayRTR 57 + # https://github.com/bgp/stayrtr 58 + stayrtr.enable = true; 59 + wg.tunnelDefaults = { 60 + privateKeyFile = "/run/agenix/dn42-privkey"; 61 + localAddrs.v4 = cfg42.addr.v4; 62 + }; 63 + }; 31 64 }
+25
hosts/prefect/dn42/peers/bandura.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.bandura = { 5 + as = 4242422923; 6 + addr.v6 = "fe80::2926"; 7 + interface = "wg42_bandura"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::11"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."55ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.bandura = { 18 + listenPort = 44923; 19 + peerPubKey = "xPW1/cWYDkk/IAss1GbdwVMW7fzKtyHA+qrfCriOB2k="; 20 + peerEndpoint = "aurora.mk16.de:52459"; 21 + peerAddrs.v6 = "fe80::2926"; 22 + localAddrs.v6 = "fe80::11"; 23 + }; 24 + }; 25 + }
+26
hosts/prefect/dn42/peers/catgirls.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.catgirls = { 5 + as = 4242421411; 6 + addr.v6 = "fe80::2189:124"; 7 + interface = "wg42_catgirls"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::111"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."148ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.catgirls = { 18 + enable = false; 19 + listenPort = 43411; 20 + peerPubKey = ""; 21 + peerEndpoint = ""; 22 + peerAddrs.v6 = "fe80::111"; 23 + localAddrs.v6 = "fe80::7"; 24 + }; 25 + }; 26 + }
+26
hosts/prefect/dn42/peers/chrismoos.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.chrismoos = { 5 + as = 4242421588; 6 + addr.v6 = "fe80::1588"; 7 + interface = "wg42_chrismoos"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::100"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."2.7ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.chrismoos = { 18 + listenPort = 43588; 19 + peerPubKey = "itmJ4Z8V1aNN368P6kMzuQM+GdzWbBKZjJiXrgSeGlw="; 20 + peerEndpoint = "us-qas01.dn42.tech9.io:58768"; 21 + peerAddrs.v4 = "172.20.16.143"; 22 + peerAddrs.v6 = "fe80::1588"; 23 + localAddrs.v6 = "fe80::100"; 24 + }; 25 + }; 26 + }
+21
hosts/prefect/dn42/peers/default.nix
··· 1 + _: 2 + let 3 + dn42Types = import ../types.nix; 4 + in 5 + { 6 + # Port numbers are 42000 + `last 4 digits of ASN` 7 + imports = [ 8 + # keep-sorted start 9 + (import ./bandura.nix { inherit dn42Types; }) 10 + # (import ./catgirls.nix { inherit dn42Types; }) 11 + (import ./chrismoos.nix { inherit dn42Types; }) 12 + (import ./iedon.nix { inherit dn42Types; }) 13 + (import ./kioubit.nix { inherit dn42Types; }) 14 + (import ./lare.nix { inherit dn42Types; }) 15 + (import ./potato.nix { inherit dn42Types; }) 16 + (import ./routedbits.nix { inherit dn42Types; }) 17 + (import ./sunnet.nix { inherit dn42Types; }) 18 + (import ./uffsalot.nix { inherit dn42Types; }) 19 + # keep-sorted end 20 + ]; 21 + }
+26
hosts/prefect/dn42/peers/iedon.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.iedon = { 5 + as = 4242422189; 6 + addr.v6 = "fe80::2189:124"; 7 + interface = "wg42_iedon"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::6"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."20ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.iedon = { 18 + listenPort = 44198; 19 + peerPubKey = "2Wmv10a9eVSni9nfZ7YPsyl3ZC5z7vHq0sTZGgk5WGo="; 20 + peerEndpoint = "us-nyc.dn42.iedon.net:48883"; 21 + peerAddrs.v4 = "172.23.91.124"; 22 + peerAddrs.v6 = "fe80::2189:124"; 23 + localAddrs.v6 = "fe80::6"; 24 + }; 25 + }; 26 + }
+27
hosts/prefect/dn42/peers/kioubit.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.kioubit = { 5 + as = 4242423914; 6 + addr.v6 = "fe80::ade0"; 7 + interface = "wg42_kioubit"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::ade1"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."7.3ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.kioubit = { 18 + listenPort = 45914; 19 + peerPubKey = "6Cylr9h1xFduAO+5nyXhFI1XJ0+Sw9jCpCDvcqErF1s="; 20 + peerEndpoint = "us2.g-load.eu:22459"; 21 + peerAddrs.v4 = "172.20.53.98"; 22 + peerAddrs.v6 = "fe80::ade0"; 23 + localAddrs.v4 = "192.168.220.70"; 24 + localAddrs.v6 = "fe80::ade1"; 25 + }; 26 + }; 27 + }
+25
hosts/prefect/dn42/peers/lare.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.lare = { 5 + as = 4242423035; 6 + addr.v6 = "fe80::3035:137"; 7 + interface = "wg42_lare"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::112"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."20ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.lare = { 18 + listenPort = 45035; 19 + peerPubKey = "AREskFoxP2cd6DXoJ7druDsiWKX+8TwrkQqfi4JxRRw="; 20 + peerEndpoint = "use2.dn42.lare.cc:22459"; 21 + peerAddrs.v6 = "fe80::3035:137"; 22 + localAddrs.v6 = "fe80::112"; 23 + }; 24 + }; 25 + }
+26
hosts/prefect/dn42/peers/potato.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.potato = { 5 + as = 4242421816; 6 + addr.v6 = "fe80::1816"; 7 + interface = "wg42_potato"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::111"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."148ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.potato = { 18 + enable = false; 19 + listenPort = 43816; 20 + peerPubKey = "LUwqKS6QrCPv510Pwt1eAIiHACYDsbMjrkrbGTJfviU="; 21 + peerEndpoint = "las.node.potat0.cc:22459"; 22 + peerAddrs.v6 = "fe80::1816"; 23 + localAddrs.v6 = "fe80::9"; 24 + }; 25 + }; 26 + }
+26
hosts/prefect/dn42/peers/routedbits.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.routedbits = { 5 + as = 4242420207; 6 + addr.v6 = "fe80::207"; 7 + interface = "wg42_routedbits"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::5"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."2.7ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.routedbits = { 18 + listenPort = 42207; 19 + peerPubKey = "/RLM4EcF8b7FKKcxnvHIYyDoES59HXIBqhKEWt4yRy0="; 20 + peerEndpoint = "router.iad1.routedbits.com:52459"; 21 + peerAddrs.v4 = "172.20.19.73"; 22 + peerAddrs.v6 = "fe80::207"; 23 + localAddrs.v6 = "fe80::5"; 24 + }; 25 + }; 26 + }
+26
hosts/prefect/dn42/peers/sunnet.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.sunnet = { 5 + as = 4242423088; 6 + addr.v6 = "fe80::3088:193"; 7 + interface = "wg42_sunnet"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::abcd"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."148ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.sunnet = { 18 + listenPort = 45088; 19 + peerPubKey = "QSAeFPotqFpF6fFe3CMrMjrpS5AL54AxWY2w1+Ot2Bo="; 20 + peerEndpoint = "lax1-us.dn42.6700.cc:22459"; 21 + peerAddrs.v4 = "172.21.100.193"; 22 + peerAddrs.v6 = "fe80::3088:193"; 23 + localAddrs.v6 = "fe80::abcd"; 24 + }; 25 + }; 26 + }
+26
hosts/prefect/dn42/peers/uffsalot.nix
··· 1 + { dn42Types, ... }: 2 + { 3 + config.networking.dn42 = { 4 + peers.uffsalot = { 5 + as = 4242420780; 6 + addr.v6 = "fe80::780"; 7 + interface = "wg42_uffsalot"; 8 + extendedNextHop = true; 9 + # My side 10 + srcAddr.v6 = "fe80::10"; 11 + # Communities 12 + crypto = dn42Types.crypto.safePFS; 13 + latency = dn42Types.latency."148ms"; 14 + bandwidth = dn42Types.bandwidth."1000mb"; 15 + transit = true; 16 + }; 17 + wg.tunnels.uffsalot = { 18 + listenPort = 42780; 19 + peerPubKey = "7V65FxvD9AQetyUr0qSiu+ik8samB4Atrw2ekvC0xQM="; 20 + peerEndpoint = "dn42-de-fra4.brand-web.net:42459"; 21 + peerAddrs.v4 = "172.20.191.129"; 22 + peerAddrs.v6 = "fe80::780"; 23 + localAddrs.v6 = "fe80::10"; 24 + }; 25 + }; 26 + }
-69
hosts/prefect/dn42/services.nix
··· 1 - { pkgs, lib, ... }: 2 - let 3 - script = pkgs.writeShellScriptBin "update-roa" '' 4 - mkdir -p /etc/bird/ 5 - ${pkgs.curl}/bin/curl -sfSLR {-o,-z}/etc/bird/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf 6 - ${pkgs.curl}/bin/curl -sfSLR {-o,-z}/etc/bird/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf 7 - ${pkgs.bird2}/bin/birdc c 8 - ${pkgs.bird2}/bin/birdc reload in all 9 - ''; 10 - bgp = import ./bgp.nix { }; 11 - in 12 - { 13 - systemd = { 14 - timers.dn42-roa = { 15 - description = "Trigger a ROA table update"; 16 - 17 - timerConfig = { 18 - OnBootSec = "5m"; 19 - OnUnitInactiveSec = "1h"; 20 - Unit = "dn42-roa.service"; 21 - }; 22 - 23 - wantedBy = [ "timers.target" ]; 24 - before = [ "bird.service" ]; 25 - }; 26 - services = { 27 - dn42-roa = { 28 - after = [ "network.target" ]; 29 - description = "DN42 ROA Updated"; 30 - unitConfig = { 31 - Type = "one-shot"; 32 - }; 33 - serviceConfig = { 34 - ExecStart = "${script}/bin/update-roa"; 35 - }; 36 - }; 37 - }; 38 - }; 39 - 40 - services = { 41 - bird = { 42 - enable = true; 43 - package = pkgs.bird2; 44 - checkConfig = false; 45 - config = 46 - builtins.readFile ./bird.conf 47 - + lib.concatStrings ( 48 - builtins.map ( 49 - x: 50 - "\n protocol bgp ${x.name} from dnpeers {\n ${if x.multihop then "multihop;" else ""}\n ${ 51 - if x.gracefulRestart then "graceful restart on;" else "" 52 - }\n neighbor ${x.neigh} as ${x.as};\n ${ 53 - if x.multi || x.v4 then 54 - "\n ipv4 {\n extended next hop on;\n import where dn42_import_filter(${x.link},25,34);\n export where dn42_export_filter(${x.link},25,34);\n import keep filtered;\n };\n " 55 - else 56 - "" 57 - }\n ${ 58 - if x.multi || x.v6 then 59 - "\n ipv6 {\n extended next hop on;\n import where dn42_import_filter(${x.link},25,34);\n export where dn42_export_filter(${x.link},25,34);\n import keep filtered;\n };\n " 60 - else 61 - "" 62 - }\n }\n " 63 - ) bgp.sessions 64 - ) 65 - + bgp.extraConfig; 66 - }; 67 - }; 68 - users.users.thehedgehog.extraGroups = [ "bird2" ]; 69 - }
-75
hosts/prefect/dn42/tunnels.nix
··· 1 - { tunnel, ... }: 2 - let 3 - # _defaultPubKey = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg="; 4 - defaultPrivKeyFile = "/run/agenix/dn42-privkey"; 5 - defaultLocalIPv4 = "172.20.43.96"; 6 - in 7 - { 8 - wg42_chris = 9 - # Ports 485-486 available 10 - 11 - tunnel 487 defaultPrivKeyFile "itmJ4Z8V1aNN368P6kMzuQM+GdzWbBKZjJiXrgSeGlw=" defaultLocalIPv4 "fe80::100" 12 - "us-qas01.dn42.tech9.io:52322" 13 - "wg42_chris" 14 - "172.20.16.143" 15 - "fe80::1588"; 16 - 17 - wg42_kioubit = 18 - tunnel 488 defaultPrivKeyFile "6Cylr9h1xFduAO+5nyXhFI1XJ0+Sw9jCpCDvcqErF1s=" defaultLocalIPv4 "fe80::3" 19 - "us2.g-load.eu:22459" 20 - "wg42_kioubit" 21 - "172.20.53.98" 22 - "fe80::ade0"; 23 - 24 - # Ports 489-490 available 25 - 26 - wg42_iedon = 27 - tunnel 491 defaultPrivKeyFile "Sz0UhewjDk2yRKI0QL9rB+5daWpXFVlbbz9cLfVVLn4=" defaultLocalIPv4 "fe80::6" 28 - "us-sjc.dn42.kuu.moe:35470" 29 - "wg42_iedon" 30 - "172.23.91.117" 31 - "fe80::2189:e8"; 32 - 33 - wg42_sunnet = 34 - tunnel 492 defaultPrivKeyFile "QSAeFPotqFpF6fFe3CMrMjrpS5AL54AxWY2w1+Ot2Bo=" defaultLocalIPv4 "fe80::abcd" 35 - "v6.lax1-us.dn42.6700.cc:22459" 36 - "wg42_sunnet" 37 - "172.21.100.193" 38 - "fe80::3088:193"; 39 - 40 - wg42_catgirls = 41 - tunnel 493 defaultPrivKeyFile "jo8eAfY8LeA4FAEJ4laYYMNkMd4z3oO/zN5DN0Mo+RQ=" defaultLocalIPv4 "fe80::7" "karx.xyz:22459" 42 - "wg42_catgirls" 43 - "" 44 - "fe80::4242"; 45 - 46 - # Port 494 Available 47 - 48 - wg42_potato = 49 - tunnel 495 defaultPrivKeyFile "LUwqKS6QrCPv510Pwt1eAIiHACYDsbMjrkrbGTJfviU=" defaultLocalIPv4 "fe80::9" 50 - "las.node.potat0.cc:22459" 51 - "wg42_potato" 52 - "" 53 - "fe80::1816"; 54 - 55 - wg42_uffsalot = 56 - tunnel 496 defaultPrivKeyFile "7V65FxvD9AQetyUr0qSiu+ik8samB4Atrw2ekvC0xQM=" defaultLocalIPv4 "fe80::10" 57 - "dn42-de-fra4.brand-web.net:42459" 58 - "wg42_uffsalot" 59 - "172.20.191.129" 60 - "fe80::780"; 61 - 62 - wg42_bandura = 63 - tunnel 497 defaultPrivKeyFile "xPW1/cWYDkk/IAss1GbdwVMW7fzKtyHA+qrfCriOB2k=" defaultLocalIPv4 "fe80::11" 64 - "aurora.mk16.de:52459" 65 - "wg42_bandura" 66 - "" 67 - "fe80::2926"; 68 - 69 - wg42_bluemedia = 70 - tunnel 498 defaultPrivKeyFile "7HNg2+uMI2WfntN+WlMnlTDG6xra/Dusee82cuXWMBY=" defaultLocalIPv4 "fe80::12" 71 - "de-fra01.dn42.bluemedia.dev:22459" 72 - "wg42_bluemedia" 73 - "172.22.167.82" 74 - "fe80::42:3343:20:1"; 75 - }
+63
hosts/prefect/dn42/types.nix
··· 1 + # DN42 Community Standard BGP Communities 2 + # See main lists here: https://dn42.dev/howto/BGP-communities 3 + { 4 + latency = { 5 + "2.7ms" = 1; 6 + "7.3ms" = 2; 7 + "20ms" = 3; 8 + "55ms" = 4; 9 + "148ms" = 5; 10 + "403ms" = 6; 11 + "1097ms" = 7; 12 + "2981ms" = 8; 13 + "gt2981" = 9; 14 + }; 15 + bandwidth = { 16 + "0.1mb" = 21; 17 + "1mb" = 22; 18 + "10mb" = 23; 19 + "100mb" = 24; 20 + "1000mb" = 25; 21 + }; 22 + crypto = { 23 + unencrypted = 31; 24 + unsafeVPN = 32; 25 + safeNoPFS = 33; 26 + safePFS = 34; 27 + }; 28 + region = { 29 + europe = 41; 30 + northAmericaEast = 42; 31 + northAmericaCentral = 43; 32 + northAmericaWest = 44; 33 + centralAmerica = 45; 34 + southAmericaEast = 46; 35 + southAmericaWest = 47; 36 + africaNorth = 48; 37 + africaSouth = 49; 38 + asiaSouth = 50; 39 + asiaSouthEast = 51; 40 + asiaEast = 52; 41 + pacificOceania = 53; 42 + antarctica = 54; 43 + asiaNorth = 55; 44 + asiaWest = 56; 45 + centralAsia = 57; 46 + }; 47 + country = { 48 + canada = 1124; 49 + china = 1156; 50 + taiwan = 1158; 51 + france = 1250; 52 + germany = 1276; 53 + hongKong = 1344; 54 + japan = 1392; 55 + netherlands = 1528; 56 + norway = 1578; 57 + russianFederation = 1643; 58 + singapore = 1702; 59 + switzerland = 1756; 60 + unitedKingdom = 1826; 61 + unitedStatesOfAmerica = 1840; 62 + }; 63 + }
-43
hosts/prefect/dn42/wireguard.nix
··· 1 - { pkgs, lib, ... }: 2 - let 3 - defaultLocalIPv4 = "172.20.43.96/32"; 4 - defaultLocalIPv6 = "fe80::1/64"; 5 - privKeyFile = "/run/agenix/dn42-privkey"; 6 - # _defaultPubKey = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg="; 7 - in 8 - { 9 - environment.systemPackages = [ pkgs.wireguard-tools ]; 10 - 11 - networking.wireguard.interfaces = import ./tunnels.nix rec { 12 - customTunnel = listenPort: privKeyFile: peerPubKey: endpoint: name: peerIPv4: peerIPv6: localIPv4: localIPv6: isOspf: { 13 - inherit listenPort; 14 - privateKeyFile = privKeyFile; 15 - allowedIPsAsRoutes = false; 16 - peers = [ 17 - { 18 - inherit endpoint; 19 - publicKey = peerPubKey; 20 - allowedIPs = [ 21 - "0.0.0.0/0" 22 - "::/0" 23 - ]; 24 - dynamicEndpointRefreshSeconds = 5; 25 - persistentKeepalive = 15; 26 - } 27 - ]; 28 - postSetup = '' 29 - ${if peerIPv4 != "" then "${pkgs.iproute2}/bin/ip addr add ${localIPv4} peer ${peerIPv4} dev ${name}" else ""} 30 - ${if peerIPv6 != "" then "${pkgs.iproute2}/bin/ip -6 addr add ${localIPv6} peer ${peerIPv6} dev ${name}" else ""} 31 - '' 32 - + lib.optionalString isOspf "${pkgs.iproute2}/bin/ip -6 addr add ${defaultLocalIPv6} dev ${name}"; 33 - }; 34 - # deadnix: skip 35 - tunnel = 36 - listenPort: _privKey: peerPubKey: localIPv4: localIPv6: endpoint: name: peerIPv4: peerIPv6: 37 - customTunnel listenPort privKeyFile peerPubKey endpoint name peerIPv4 peerIPv6 localIPv4 localIPv6 false; 38 - # deadnix: skip 39 - ospf = 40 - listenPort: _privKey: peerPubKey: endpoint: name: peerIPv4: peerIPv6: ULAIPv6: 41 - customTunnel listenPort privKeyFile peerPubKey endpoint name peerIPv4 peerIPv6 defaultLocalIPv4 ULAIPv6 true; 42 - }; 43 - }
+2 -17
hosts/prefect/firewall.nix
··· 28 28 ]; 29 29 allowedUDPPortRanges = [ 30 30 { 31 - from = 480; 32 - to = 510; 31 + from = 42000; 32 + to = 52000; 33 33 } 34 34 ]; 35 35 trustedInterfaces = [ 36 - "tailscale0" 37 36 "wg0" 38 - 39 - # DN42 Interfaces 40 - "wg42_bandura" 41 - "wg42_bluemedia" 42 - "wg42_catgirls" 43 - "wg42_chris" 44 - "wg42_iedon" 45 - "wg42_kioubit" 46 - "wg42_liki" 47 - "wg42_lutoma" 48 - "wg42_potato" 49 - "wg42_sunnet" 50 - "wg42_uffsalot" 51 - "wg42_usman" 52 37 ]; 53 38 extraForwardRules = '' 54 39 meta iifname "wg42_*" meta oifname "wg42_*" accept
-1
hosts/prefect/services/tailscale.nix
··· 6 6 networking.firewall = { 7 7 trustedInterfaces = [ "tailscale0" ]; 8 8 allowedUDPPorts = [ config.services.tailscale.port ]; 9 - checkReversePath = "loose"; 10 9 }; 11 10 }
+2
nixosModules/default.nix
··· 5 5 defaultUsers = import ./default-users; 6 6 profiles = import ./profiles; 7 7 8 + dn42Wireguard = import ./dn42Wireguard; 9 + 8 10 # Programs 9 11 chromium = import ./programs/chromium; 10 12 firefox = import ./programs/firefox;
+127
nixosModules/dn42Wireguard/default.nix
··· 1 + { 2 + config, 3 + lib, 4 + pkgs, 5 + ... 6 + }: 7 + let 8 + inherit (lib) types; 9 + cfg = config.networking.dn42.wg; 10 + 11 + tunnelDef = { 12 + options = { 13 + enable = lib.mkOption { 14 + description = "Whether to enable this wireguard tunnel"; 15 + type = types.bool; 16 + default = true; 17 + example = false; 18 + }; 19 + listenPort = lib.mkOption { 20 + description = "The port this tunnel listens on"; 21 + type = types.port; 22 + example = 42000; 23 + }; 24 + privateKeyFile = lib.mkOption { 25 + description = "Path to the tunnel's private key"; 26 + type = types.nullOr types.path; 27 + example = "/path/to/private/key"; 28 + default = null; 29 + }; 30 + peerPubKey = lib.mkOption { 31 + description = "Public key of the peer you're connecting to"; 32 + type = types.str; 33 + example = "e6kp9sca4XIzncKa9GEQwyOnMjje299Xg9ZdgXWMwHg="; 34 + }; 35 + peerEndpoint = lib.mkOption { 36 + description = "The endpoint of the peer you're connecting to"; 37 + type = types.str; 38 + example = "example.com:42000"; 39 + }; 40 + peerAddrs = { 41 + v4 = lib.mkOption { 42 + description = "The peer IPv4 address to connect to in the tunnel"; 43 + type = types.nullOr types.str; 44 + example = "192.168.1.1"; 45 + default = null; 46 + }; 47 + v6 = lib.mkOption { 48 + description = "The peer IPv6 address to connect to in the tunnel"; 49 + type = types.nullOr types.str; 50 + example = "fe80::42"; 51 + default = null; 52 + }; 53 + }; 54 + localAddrs = { 55 + v4 = lib.mkOption { 56 + description = "The local IPv4 address to listen on in the tunnel"; 57 + type = types.nullOr types.str; 58 + example = "192.168.1.1"; 59 + default = null; 60 + }; 61 + v6 = lib.mkOption { 62 + description = "The local IPv6 address to listen on in the tunnel"; 63 + type = types.nullOr types.str; 64 + example = "fe80::42"; 65 + default = null; 66 + }; 67 + }; 68 + }; 69 + }; 70 + in 71 + { 72 + options.networking.dn42.wg = { 73 + tunnelDefaults = lib.mkOption { 74 + description = "The default settings to apply to all tunnels"; 75 + type = types.submodule tunnelDef; 76 + }; 77 + tunnels = lib.mkOption { 78 + description = "DN42 WireGuard tunnels configuration"; 79 + type = types.attrsOf (types.submodule tunnelDef); 80 + }; 81 + }; 82 + config.networking = { 83 + wireguard.interfaces = lib.mapAttrs' ( 84 + name: value: 85 + let 86 + # Merge defaults with tunnel config, right side has priority 87 + # so tunnel config overrides defaults 88 + fc = cfg.tunnelDefaults // (lib.filterAttrs (_: v: v != null) value); 89 + in 90 + (lib.nameValuePair "wg42_${name}" { 91 + inherit (fc) listenPort privateKeyFile; 92 + allowedIPsAsRoutes = false; 93 + peers = [ 94 + { 95 + endpoint = fc.peerEndpoint; 96 + publicKey = fc.peerPubKey; 97 + allowedIPs = [ 98 + "0.0.0.0/0" 99 + "::/0" 100 + ]; 101 + dynamicEndpointRefreshSeconds = 5; 102 + persistentKeepalive = 15; 103 + } 104 + ]; 105 + postSetup = '' 106 + ${lib.optionalString ( 107 + fc.peerAddrs.v4 != null && fc.localAddrs.v4 != null 108 + ) "${pkgs.iproute2}/bin/ip addr add ${fc.localAddrs.v4} peer ${fc.peerAddrs.v4} dev wg42_${name}"} 109 + ${lib.optionalString ( 110 + fc.peerAddrs.v6 != null && fc.localAddrs.v6 != null 111 + ) "${pkgs.iproute2}/bin/ip addr add ${fc.localAddrs.v6} peer ${fc.peerAddrs.v6} dev wg42_${name}"} 112 + ''; 113 + }) 114 + ) (lib.filterAttrs (_: v: v.enable == true) cfg.tunnels); 115 + firewall = { 116 + trustedInterfaces = lib.mapAttrsToList (name: _: "wg42_" + name) ( 117 + lib.filterAttrs (_: v: v.enable == true) cfg.tunnels 118 + ); 119 + checkReversePath = false; 120 + extraInputRules = '' 121 + ip saddr 172.20.0.0/14 accept 122 + ip6 saddr fd00::/8 accept 123 + ip6 saddr fe80::/64 accept 124 + ''; 125 + }; 126 + }; 127 + }
+4
optnix.toml
··· 1 + [scopes.flake-parts] 2 + description = "flake-parts config" 3 + options-list-cmd = "nix eval --json .#debug.options-doc" 4 + evaluator = "nix eval .#debug.config.{{ .Option }}"