vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 1 | { config, pkgs, modulesPath, ... }: |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 2 | |
| 3 | let |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 4 | hw = builtins.fromJSON (builtins.readFile ./hw.json); |
| 5 | fw = import ./fw-7535.nix; |
| 6 | vuko-pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFhaCaC/CVYv6hphqmEdKaPrIn+Q946+myvL9SSnzFZk vuko@eagle"; |
| 7 | q3k-pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG599UildOrAq+LIOQjKqtGMwjgjIxozI1jtQQRKHtCP q3k@mimeomia"; |
| 8 | networks = { |
| 9 | uplink = { |
| 10 | description = "Hackerspace Internet Uplink"; |
| 11 | hw_addr = builtins.elemAt fw.hw_addresses 0; |
| 12 | ipv4 = "185.236.240.5"; |
| 13 | ipv6 = "2a0d:eb00:2137:1::3"; |
| 14 | }; |
| 15 | lan = { |
| 16 | description = "Hackerspace LAN"; |
| 17 | hw_addr = builtins.elemAt fw.hw_addresses 1; |
| 18 | ipv4 = "10.8.1.2"; |
| 19 | ipv6 = "2a0d:eb00:4242::1"; |
| 20 | }; |
| 21 | managment = { |
| 22 | description = "Management network (temporary routing)"; |
| 23 | hw_addr = builtins.elemAt fw.hw_addresses 2; |
| 24 | }; |
| 25 | lte = { |
| 26 | description = "temp LTE uplink"; |
| 27 | hw_addr = builtins.elemAt fw.hw_addresses 3; |
| 28 | }; |
| 29 | vpn = { |
| 30 | description = "Hackerspace members vpn"; |
| 31 | ipv4 = "10.9.1.1"; |
| 32 | }; |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 33 | bms = { |
| 34 | ipv4 = "10.11.1.1"; |
| 35 | }; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 36 | }; |
| 37 | hostname = "customs"; |
| 38 | openvpn-auth = import ./openvpn-auth { inherit pkgs; }; |
| 39 | secrets-path = "/etc/nixos/secrets/"; |
| 40 | update_authorized_keys = pkgs.writeShellScriptBin "update_authorized_keys" '' |
| 41 | ${pkgs.python3.withPackages (pp: [ pp.ldap3 ])}/bin/python ${./update_authorized_keys.py} ${hostname} ${secrets-path}/ldap-password.txt |
| 42 | ''; |
| 43 | |
| 44 | in { |
| 45 | imports = |
| 46 | [ |
| 47 | ./ulogd2/service.nix |
| 48 | #./hardware-configuration.nix |
vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 49 | (modulesPath + "/profiles/minimal.nix") |
| 50 | (modulesPath + "/profiles/all-hardware.nix") |
Piotr Dobrowolski | 6f6187c | 2021-10-16 23:22:22 +0200 | [diff] [blame] | 51 | ../../../bgpwtf/machines/modules/routing.nix |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 52 | ./checkinator-tracker.nix |
| 53 | ./checkinator-web.nix |
| 54 | ./mikrotik-exporter.nix |
| 55 | ./netboot.nix |
vuko | 2ea09a8 | 2023-12-03 20:06:27 +0100 | [diff] [blame] | 56 | ./doorman/service.nix |
Piotr Dobrowolski | 9c5d866 | 2022-05-08 02:17:41 +0200 | [diff] [blame] | 57 | ./beyondspace.nix |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 58 | ./laserproxy/service.nix |
| 59 | ]; |
| 60 | |
Piotr Dobrowolski | ab299d4 | 2023-10-16 19:10:23 +0200 | [diff] [blame] | 61 | # Prevent spurious rebuilds due to dbus override on minimal profile |
| 62 | environment.noXlibs = false; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 63 | |
| 64 | boot.loader.grub.enable = true; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 65 | boot.loader.grub.device = "nodev"; |
| 66 | boot.loader.grub.extraConfig = '' |
| 67 | serial --unit=0 --speed=115200 |
| 68 | terminal_input serial |
| 69 | terminal_output serial |
| 70 | ''; |
| 71 | boot.kernelParams = ["console=tty0" "console=ttyS0,115200"]; |
| 72 | |
| 73 | time.timeZone = "Europe/Warsaw"; |
| 74 | |
| 75 | fileSystems."/" = { |
| 76 | device = "/dev/disk/by-partuuid/${hw.rootUUID}"; |
| 77 | fsType = "ext4"; |
| 78 | }; |
| 79 | |
| 80 | services.postfix = let acme_dir = "/var/lib/acme"; in { |
| 81 | enable = true; |
| 82 | domain = "customs.hackerspace.pl"; |
| 83 | hostname = "customs.hackerspace.pl"; |
| 84 | destination = [ "localhost" ]; |
| 85 | sslCert = "${acme_dir}/customs.hackerspace.pl/full.pem"; |
| 86 | sslKey = "${acme_dir}/customs.hackerspace.pl/key.pem"; |
| 87 | enableSmtp = true; |
| 88 | enableSubmission = false; |
| 89 | #relayHost = "hackerspace.pl"; |
| 90 | extraConfig = '' |
| 91 | inet_interfaces = loopback-only |
| 92 | ''; |
| 93 | }; |
| 94 | |
| 95 | fileSystems."/mnt/secrets" = { |
| 96 | fsType = "tmpfs"; |
| 97 | options = [ "rw" "mode=755" "size=200M" "nosuid" "nodev" "relatime" "noexec" ]; |
| 98 | }; |
| 99 | |
| 100 | networking.hostName = hostname; |
| 101 | networking.domain = "hackerspace.pl"; |
| 102 | |
| 103 | networking.useDHCP = false; |
| 104 | networking.vlans = { |
| 105 | laser = { |
| 106 | id = 4001; |
| 107 | interface = "lan"; |
| 108 | }; |
| 109 | bms = { |
| 110 | id = 4002; |
| 111 | interface = "lan"; |
| 112 | }; |
| 113 | }; |
| 114 | |
| 115 | systemd.services.secrets = { |
| 116 | enable = true; |
| 117 | description = "Copy secrets and fix permissions"; |
| 118 | script = '' |
| 119 | ${pkgs.coreutils}/bin/install --owner=root --mode=700 --directory /mnt/secrets/nginx/ |
| 120 | ${pkgs.coreutils}/bin/install --owner=root --mode=400 -t /mnt/secrets/nginx/ \ |
| 121 | ${secrets-path}/nginx/at.hackerspace.pl.key \ |
| 122 | ${secrets-path}/nginx/at.hackerspace.pl.crt |
| 123 | ${pkgs.acl}/bin/setfacl -m "u:nginx:rx" /mnt/secrets/nginx |
| 124 | ${pkgs.acl}/bin/setfacl -m "u:nginx:r" /mnt/secrets/nginx/* |
| 125 | ''; |
| 126 | wantedBy = [ "nginx.service" ]; |
| 127 | partOf = [ "nginx.service" ]; |
| 128 | serviceConfig.Type = "oneshot"; |
| 129 | serviceConfig.RemainAfterExit = "true"; |
| 130 | serviceConfig.User = "root"; |
| 131 | }; |
| 132 | |
| 133 | services.prometheus.exporters.node = { |
| 134 | enable = true; |
| 135 | listenAddress = "[::1]"; |
| 136 | port = 9100; |
| 137 | enabledCollectors = [ "systemd" ]; |
| 138 | }; |
| 139 | |
| 140 | systemd.network.links = builtins.listToAttrs (map ( |
| 141 | name: { name = "10-link-${name}"; value = { |
| 142 | enable = true; |
| 143 | matchConfig = { |
| 144 | MACAddress = networks."${name}".hw_addr; |
| 145 | }; |
| 146 | linkConfig = { |
| 147 | Name = "${name}"; |
| 148 | }; |
| 149 | }; } |
| 150 | ) (builtins.filter (name: builtins.hasAttr "hw_addr" networks."${name}") (builtins.attrNames networks))); |
| 151 | |
| 152 | #networking.interfaces.vpn = { |
| 153 | # virtual = true; |
| 154 | # name = "vpn"; |
| 155 | # #ipv4.addresses = [ { address = 10.9.1.1; prefixlen = 16; } ]; |
| 156 | #}; |
| 157 | |
| 158 | boot.kernel.sysctl = { |
| 159 | "net.ipv4.ip_forward" = true; |
| 160 | "net.ipv6.conf.all.forwarding" = true; |
| 161 | }; |
| 162 | |
vuko | 2ea09a8 | 2023-12-03 20:06:27 +0100 | [diff] [blame] | 163 | hswaw.doorman-proxy = { |
| 164 | enable = true; |
| 165 | address = networks.bms.ipv4; |
| 166 | port = 8000; |
| 167 | password-file = "/root/secrets/ac-ldap-password.txt"; |
| 168 | }; |
| 169 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 170 | # using nftables so firewall has to be disabled |
| 171 | networking.firewall.enable = false; |
| 172 | networking.nftables.enable = true; |
| 173 | networking.nftables.ruleset = '' |
| 174 | table inet filter { |
| 175 | chain input { |
| 176 | type filter hook input priority 0; |
| 177 | |
| 178 | # accept any localhost traffic |
| 179 | iifname lo accept |
| 180 | |
| 181 | # accept traffic originated from us |
| 182 | ct state {established, related} accept |
| 183 | |
| 184 | # ICMP |
| 185 | ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, mld-listener-query, nd-router-solicit } accept |
| 186 | ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept |
| 187 | |
| 188 | # allow "ping" |
| 189 | ip6 nexthdr icmpv6 icmpv6 type echo-request accept |
| 190 | ip protocol icmp icmp type echo-request accept |
| 191 | |
| 192 | # allow OSPFv3 |
| 193 | ip6 nexthdr 89 accept |
| 194 | |
| 195 | tcp dport 22 accept |
| 196 | tcp dport 53 accept |
| 197 | udp dport 53 accept |
| 198 | tcp dport 80 accept |
| 199 | tcp dport 443 accept |
| 200 | udp dport tftp accept |
| 201 | |
| 202 | iifname managment udp dport tftp accept |
| 203 | iifname lan tcp dport 8080 accept |
| 204 | |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 205 | # mosquitto |
| 206 | iifname bms tcp dport 1883 accept |
Piotr Dobrowolski | 0f88591 | 2024-01-30 22:56:41 +0100 | [diff] [blame] | 207 | iifname bms tcp dport ${toString config.hswaw.doorman-proxy.port} accept |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 208 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 209 | # openvpn-members |
| 210 | udp dport 20001 accept |
| 211 | tcp dport 20001 accept |
| 212 | |
| 213 | # laserproxy |
| 214 | udp dport 40200 accept |
| 215 | udp dport 50200 accept |
| 216 | |
| 217 | counter drop |
| 218 | } |
| 219 | |
| 220 | # Allow all outgoing connections. |
| 221 | chain output { |
| 222 | type filter hook output priority 0; policy accept; |
| 223 | } |
| 224 | |
| 225 | chain forward { |
| 226 | type filter hook forward priority 0; policy drop; |
| 227 | ct state {established, related} jump accepted |
| 228 | oifname "loop" jump accepted |
| 229 | ip saddr 10.8.0.0/16 iifname "lan" jump accepted |
| 230 | ip saddr 10.9.0.0/16 iifname "vpn" jump accepted |
| 231 | ip6 saddr 2a0d:eb00:4242::0/64 iifname "lan" jump accepted |
| 232 | ip6 saddr 2a0d:eb00:4242:1::0/64 iifname "vpn" jump accepted |
| 233 | ip6 saddr 2a0d:eb00:4242:1::1/128 iifname "loop" jump accepted |
| 234 | } |
| 235 | |
| 236 | chain accepted { |
| 237 | # IMPORTANT |
| 238 | # Log all connections to the outside world from LAN interface, as we are |
| 239 | # required to do so |
| 240 | oifname != "uplink" accept |
| 241 | iifname "uplink" accept |
| 242 | ip daddr { 10.0.0.0/8, 225.225.225.225/32 } accept |
| 243 | ip6 daddr { 2a0d:eb00::/29, fe80::/8 } accept |
| 244 | log group 2 accept |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | table inet net { |
| 249 | chain postrouting { |
| 250 | type nat hook postrouting priority 100; |
| 251 | ip saddr 10.8.0.0/16 oifname uplink snat ${networks.uplink.ipv4} |
| 252 | ip saddr 10.9.0.0/16 oifname uplink snat ${networks.uplink.ipv4} |
| 253 | } |
| 254 | |
| 255 | chain prerouting { |
| 256 | type nat hook prerouting priority -100; |
| 257 | |
| 258 | # Access to staszkecoin from Internet |
| 259 | ip version 4 iifname "uplink" tcp dport 8333 dnat 10.8.1.49 |
| 260 | } |
| 261 | } |
| 262 | ''; |
| 263 | |
| 264 | systemd.services."loop-netdev" = let n = "loop"; in { |
| 265 | description = "Dummy interface: loop"; |
| 266 | wantedBy = [ "network-setup.service" "sys-subsystem-net-devices-${n}.device" ]; |
| 267 | partOf = [ "network-setup.service" ]; |
| 268 | after = [ "network-pre.target" ]; |
| 269 | before = [ "network-setup.service" ]; |
| 270 | serviceConfig.Type = "oneshot"; |
| 271 | serviceConfig.RemainAfterExit = true; |
| 272 | path = [ pkgs.iproute ]; |
| 273 | script = '' |
| 274 | # Remove Dead Interfaces |
| 275 | ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}" |
| 276 | ip link add "${n}" type dummy |
| 277 | ip link set "${n}" up |
| 278 | ''; |
| 279 | postStop = '' |
| 280 | ip link delete "${n}" |
| 281 | ''; |
| 282 | }; |
| 283 | |
| 284 | |
| 285 | networking.interfaces = { |
| 286 | uplink = { |
| 287 | ipv4.addresses = [ { address = networks.uplink.ipv4; prefixLength = 31; } ]; |
| 288 | ipv6.addresses = [ |
| 289 | { address = networks.uplink.ipv6; prefixLength = 112; } |
| 290 | ]; |
| 291 | }; |
| 292 | lan = { |
| 293 | ipv4.addresses = [ { address = networks.lan.ipv4; prefixLength = 16; } ]; |
| 294 | ipv6.addresses = [ { address = networks.lan.ipv6; prefixLength = 64; } ]; |
| 295 | }; |
| 296 | loop = { |
| 297 | ipv6.addresses = [ { address = "2a0d:eb00:4242:1::1"; prefixLength = 128; } ]; |
| 298 | }; |
| 299 | laser = { |
| 300 | ipv4.addresses = [ { address = "10.11.0.1"; prefixLength = 24; } ]; |
| 301 | }; |
| 302 | bms = { |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 303 | ipv4.addresses = [ { address = networks.bms.ipv4; prefixLength = 24; } ]; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 304 | }; |
| 305 | managment = { |
| 306 | ipv4.addresses = [ { address = "10.10.1.1"; prefixLength = 24; } ]; |
| 307 | }; |
| 308 | lte = { |
| 309 | ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ]; |
| 310 | }; |
| 311 | }; |
| 312 | |
| 313 | networking.defaultGateway = { |
| 314 | address = "185.236.240.4"; |
| 315 | interface = "uplink"; |
| 316 | }; |
| 317 | networking.defaultGateway6 = { |
| 318 | address = "2a0d:eb00:2137:1::1"; |
| 319 | interface = "uplink"; |
| 320 | }; |
| 321 | |
| 322 | |
| 323 | networking.nameservers = [ "1.0.0.1" "8.8.8.8" ]; |
| 324 | |
| 325 | services.openssh = { |
| 326 | enable = true; |
Piotr Dobrowolski | ab299d4 | 2023-10-16 19:10:23 +0200 | [diff] [blame] | 327 | settings = { |
| 328 | PasswordAuthentication = false; |
| 329 | LogLevel = "INFO"; |
| 330 | }; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 331 | }; |
| 332 | |
| 333 | users.users.root.openssh.authorizedKeys.keys = [ vuko-pubkey q3k-pubkey ]; |
| 334 | |
| 335 | services.dhcpd4 = { |
| 336 | enable = true; |
vuko | ee8f1d5 | 2022-12-31 01:04:42 +0100 | [diff] [blame] | 337 | configFile = "${./dhcpd.conf}"; |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 338 | interfaces = ["lan" "bms"]; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 339 | }; |
| 340 | |
vuko | c17bf90 | 2023-11-15 22:57:46 +0100 | [diff] [blame] | 341 | services.mosquitto.enable = true; |
| 342 | services.mosquitto.listeners = [ |
| 343 | { |
| 344 | address = networks.bms.ipv4; |
| 345 | port = 1883; |
| 346 | settings = { |
| 347 | allow_anonymous = true; |
| 348 | }; |
| 349 | acl = [ |
| 350 | "topic readwrite #" |
| 351 | ]; |
| 352 | } |
| 353 | ]; |
| 354 | |
vuko | ee8f1d5 | 2022-12-31 01:04:42 +0100 | [diff] [blame] | 355 | # Checkinator needs access to leases file. When DynamicUser is enable this |
| 356 | # file is hidden in /var/lib/private |
| 357 | systemd.services.dhcpd4.serviceConfig.DynamicUser= pkgs.lib.mkForce false; |
| 358 | users.users.dhcpd = { |
| 359 | group = "dhcpd"; |
| 360 | isSystemUser = true; |
| 361 | uid = 1005; |
| 362 | }; |
| 363 | users.groups."dhcpd" = {}; |
| 364 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 365 | hscloud.routing = { |
| 366 | enable = true; |
| 367 | # TODO(q3k): make this optional in upstream |
| 368 | extra = ""; |
| 369 | routerID = "185.236.240.5"; |
| 370 | tables.master.program = true; |
| 371 | pipe.v6.aggregate_to_kernel = { |
| 372 | table = "master"; |
| 373 | peerTable = "aggregate"; |
| 374 | filterIn = '' |
| 375 | if source = RTS_OSPF then accept; |
| 376 | if source = RTS_OSPF_EXT2 then accept; |
| 377 | reject; |
| 378 | ''; |
| 379 | }; |
| 380 | ospf.v6.upstream = { |
| 381 | table = "aggregate"; |
| 382 | area."0.0.0.0" = { |
| 383 | interfaces.uplink = { type = "bcast"; }; |
| 384 | interfaces.lan = { type = "bcast"; stub = true; }; |
| 385 | interfaces.loop = { type = "ptp"; stub = true; }; |
| 386 | }; |
| 387 | }; |
| 388 | }; |
| 389 | |
| 390 | services.radvd = { |
| 391 | enable = true; |
| 392 | config = '' |
| 393 | interface lan { |
| 394 | AdvSendAdvert on; |
| 395 | prefix 2a0d:eb00:4242::/64 { |
| 396 | }; |
| 397 | route 0::/0 { }; |
| 398 | }; |
| 399 | interface vpn { |
| 400 | AdvSendAdvert on; |
| 401 | prefix 2a0d:eb00:4242:1::/64 { |
| 402 | AdvRouterAddr on; |
| 403 | }; |
| 404 | route 0::/0 { }; |
| 405 | }; |
| 406 | ''; |
| 407 | }; |
| 408 | |
| 409 | services.logrotate = { |
| 410 | enable = true; |
vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 411 | settings = { |
| 412 | "/var/log/ulogd.pcap" = { |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 413 | frequency = "weekly"; |
vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 414 | postrotate = '' |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 415 | ${pkgs.killall}/bin/killall -HUP ulogd |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 416 | ''; |
vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 417 | rotate = 55; |
Ari Gerus | 2589ce6 | 2024-02-25 11:55:47 +0100 | [diff] [blame] | 418 | delaycompress = true; |
| 419 | compress = true; |
Ari Gerus | d63ed67 | 2024-02-20 21:06:16 +0100 | [diff] [blame] | 420 | compresscmd = "${pkgs.zstd}/bin/zstd"; |
| 421 | uncompresscmd = "${pkgs.zstd}/bin/unzstd"; |
| 422 | compressext = ".zst"; |
| 423 | compressoptions = "--rm"; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 424 | }; |
| 425 | }; |
| 426 | }; |
| 427 | |
| 428 | services.cron = let |
| 429 | log-neigh = pkgs.writeShellScript "log-neigh" '' |
| 430 | mkdir -p /var/log/arptables |
| 431 | chmod 700 /var/log/arptables |
| 432 | |
| 433 | # Larger than 10MB? rotate. |
| 434 | if [[ $(find /var/log/arptables/arptables.log -type f -size +10485760c 2>/dev/null) ]]; then |
| 435 | f=/var/log/arptables/$(date "+%s").log |
| 436 | cp /var/log/arptables/arptables.log $f |
| 437 | gzip -9 $f |
| 438 | rm /var/log/arptables/arptables.log |
| 439 | fi |
| 440 | |
| 441 | ip neigh >> /var/log/arptables/arptables.log |
| 442 | date --iso-8601=seconds >> /var/log/arptables/arptables.log |
| 443 | ''; |
| 444 | in { |
vuko | ca6dba9 | 2023-01-05 19:54:20 +0100 | [diff] [blame] | 445 | mailto = "both@hackerspace.pl"; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 446 | enable = true; |
| 447 | systemCronJobs = [ |
| 448 | "*/5 * * * * root ${log-neigh}" |
| 449 | "0 3 * * * root ${update_authorized_keys}/bin/update_authorized_keys" |
| 450 | ]; |
| 451 | }; |
| 452 | |
| 453 | services.knot = { |
| 454 | enable = true; |
| 455 | extraConfig = '' |
| 456 | server: |
| 457 | listen: ${networks.uplink.ipv4}@53 |
| 458 | listen: ${networks.uplink.ipv6}@53 |
| 459 | |
| 460 | zone: |
| 461 | - domain: waw.hackerspace.pl |
| 462 | storage: ${./zones} |
| 463 | file: waw.hackerspace.pl |
| 464 | - domain: i |
| 465 | storage: ${./zones} |
| 466 | file: i |
| 467 | - domain: api.ustream.tv |
| 468 | storage: ${./zones} |
| 469 | file: api.ustream.tv |
| 470 | - domain: api.eye.fi |
| 471 | storage: ${./zones} |
| 472 | file: api.eye.fi |
| 473 | log: |
| 474 | - target: syslog |
| 475 | any: info |
| 476 | ''; |
| 477 | }; |
| 478 | |
| 479 | services.nginx.enable = true; |
| 480 | services.nginx.mapHashBucketSize = 64; |
| 481 | services.nginx.appendHttpConfig = '' |
| 482 | server_names_hash_bucket_size 64; |
| 483 | ''; |
Piotr Dobrowolski | 9c5d866 | 2022-05-08 02:17:41 +0200 | [diff] [blame] | 484 | services.nginx.resolver.addresses = [ "127.0.0.1" ]; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 485 | |
vuko | 740a52d | 2022-12-27 20:45:00 +0100 | [diff] [blame] | 486 | security.acme.acceptTerms = true; |
| 487 | security.acme.defaults.email = "bofh@hackerspace.pl"; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 488 | |
| 489 | services.nginx.virtualHosts."customs.hackerspace.pl" = { |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 490 | enableACME = true; |
| 491 | |
| 492 | locations."/" = { |
| 493 | extraConfig = '' |
| 494 | return 302 https://isztar.mf.gov.pl; |
| 495 | ''; |
| 496 | }; |
| 497 | locations."/metrics/luftdaten" = { |
| 498 | proxyPass = "http://10.8.0.146"; |
| 499 | }; |
| 500 | locations."/metrics/spejsiot" = { |
vuko | 3262409 | 2022-12-22 23:09:06 +0100 | [diff] [blame] | 501 | proxyPass = "http://10.8.1.16/metrics"; |
| 502 | extraConfig = '' |
| 503 | proxy_set_header Host spejsiot.waw.hackerspace.pl; |
| 504 | ''; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 505 | }; |
| 506 | locations."/metrics/apm" = { |
| 507 | proxyPass = "http://10.8.1.40:5000/metrics"; |
| 508 | }; |
| 509 | locations."/metrics/vending" = { |
| 510 | proxyPass = "http://10.8.1.32:8000/"; |
| 511 | }; |
| 512 | locations."/metrics/sztancarka" = { |
| 513 | proxyPass = "http://10.8.0.96:8888/"; |
| 514 | }; |
| 515 | locations."/metrics/mikrotik" = { |
| 516 | proxyPass = "http://127.0.0.1:9436/metrics"; |
| 517 | extraConfig = '' |
| 518 | allow 209.250.231.127; |
| 519 | deny all; |
| 520 | ''; |
| 521 | }; |
| 522 | locations."/metrics/node" = { |
| 523 | proxyPass = "http://[::1]:9100/metrics"; |
| 524 | extraConfig = '' |
| 525 | allow 209.250.231.127; |
| 526 | deny all; |
| 527 | ''; |
| 528 | }; |
| 529 | locations."/stats/sztancarka-ppm" = { |
| 530 | proxyPass = "http://10.8.0.96:9090/api/v1/query?query=rate%28cut_count_total%5B15m%5D%29+*+60"; |
| 531 | }; |
| 532 | locations."/stats/sztancarka-last-24h" = { |
| 533 | proxyPass = "http://10.8.0.96:9090/api/v1/query?query=round(increase(cut_count_total[24h]))"; |
| 534 | }; |
| 535 | }; |
| 536 | |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 537 | services.unbound = let |
| 538 | local-zones = [ "waw.hackerspace.pl." "api.eye.fi." "api.ustream.tv." "i." ]; |
| 539 | in { |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 540 | enable = true; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 541 | |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 542 | #enableRootTrustAnchor = false; |
| 543 | |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 544 | settings = { |
| 545 | server = { |
| 546 | interface = [ |
| 547 | networks.lan.ipv4 |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 548 | networks.lan.ipv6 |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 549 | "127.0.0.1" |
| 550 | "::1" |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 551 | ]; |
| 552 | access-control = [ |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 553 | "::1/128 allow" |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 554 | "127.0.0.1/8 allow" |
| 555 | "10.0.0.0/8 allow" |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 556 | "${networks.lan.ipv6}/64 allow" |
| 557 | "${networks.lan.ipv4}/8 allow" |
| 558 | ]; |
| 559 | |
| 560 | # disable DNSSEC on locally resolved domains |
| 561 | domain-insecure = local-zones; |
| 562 | |
| 563 | # allow LAN adresses only for local domains |
| 564 | private-domain = local-zones; |
| 565 | private-address = [ |
| 566 | "10.0.0.0/8" |
| 567 | "${networks.lan.ipv6}/64" |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 568 | ]; |
| 569 | }; |
| 570 | |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 571 | # authoritative DNS servers |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 572 | stub-zone = map (name: { |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 573 | inherit name; |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 574 | stub-addr = networks.uplink.ipv4; |
vuko | 3125aa1 | 2022-12-31 02:52:24 +0100 | [diff] [blame] | 575 | }) local-zones; |
| 576 | |
| 577 | # recursive DNS servers |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 578 | forward-zone = { |
| 579 | name = "."; |
| 580 | forward-addr = "185.236.240.1"; |
| 581 | }; |
| 582 | }; |
| 583 | }; |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 584 | |
| 585 | # Public VPN access for Hackerspace members |
| 586 | services.openvpn.servers.members.config = '' |
| 587 | script-security 3 |
| 588 | auth-user-pass-verify ${openvpn-auth}/bin/openvpn-auth-member via-env |
| 589 | verify-client-cert none |
| 590 | username-as-common-name |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 591 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 592 | #user _openvpn |
| 593 | #group _openvpn |
| 594 | multihome |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 595 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 596 | port 20001 |
| 597 | proto udp |
| 598 | proto udp6 |
| 599 | dev vpn |
| 600 | dev-type tun |
| 601 | ca ${secrets-path}/openvpn-public/ca.crt |
| 602 | cert ${secrets-path}/openvpn-public/server.crt |
| 603 | key ${secrets-path}/openvpn-public/server.key |
| 604 | dh ${secrets-path}/openvpn-public/dh.pem |
| 605 | server 10.9.1.0 255.255.255.0 |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 606 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 607 | push "route 10.8.0.0 255.255.0.0" |
| 608 | push "route 10.9.0.0 255.255.0.0" |
| 609 | push "route 10.10.0.0 255.255.0.0" |
| 610 | push "route 10.11.0.0 255.255.0.0" |
| 611 | push "dhcp-option DNS ${networks.lan.ipv4}" |
| 612 | push "dhcp-option DOMAIN waw.hackerspace.pl" |
Piotr Dobrowolski | b6bc3e6 | 2021-10-16 21:56:59 +0200 | [diff] [blame] | 613 | |
Piotr Dobrowolski | a01905a | 2021-10-16 18:22:46 +0200 | [diff] [blame] | 614 | ifconfig-pool-persist /var/lib/openvpn-public/ipp.txt |
| 615 | #client-config-dir /var/lib/openvpn-public/ccd |
| 616 | client-to-client |
| 617 | keepalive 10 120 |
| 618 | comp-lzo |
| 619 | persist-key |
| 620 | persist-tun |
| 621 | ''; |
| 622 | |
| 623 | environment.systemPackages = with pkgs; [ |
| 624 | vim tcpdump htop nmon tmux git file procps parted dmidecode ack utillinux nmap mosh ncdu tree lz4 bind |
| 625 | rxvt_unicode.terminfo update_authorized_keys |
| 626 | ]; |
| 627 | programs.mtr.enable = true; |
| 628 | |
| 629 | environment.variables = { |
| 630 | EDITOR = "vim"; |
| 631 | }; |
| 632 | |
| 633 | system.stateVersion = "20.03"; |
| 634 | |
| 635 | boot.vesa = false; |
| 636 | boot.loader.grub.splashImage = null; |
| 637 | } |
| 638 | |