{ config, lib, pkgs, ... }: let wan-dev = "bond0.10"; lan-dev = "bond0"; # config.orbekk.nycmesh.listenPort wireguardPorts = [ config.orbekk.mullvad.listenPort config.orbekk.vpn.listenPort ]; mullvadMark = 30; heMark = 200; # nycmeshMark = 32; aliases = import ../data/aliases.nix; in { orbekk.mullvad.enable = true; orbekk.nycmesh.enable = false; services.tftpd.enable = true; services.openntpd.enable = true; environment.systemPackages = with pkgs; [ iptables ]; networking.useDHCP = false; networking.networkmanager.enable = lib.mkForce false; networking.nameservers = [ "1.1.1.1" "1.0.0.1" "2606:4700:4700::1111" "2606:4700:4700::1001" ]; networking.vlans = builtins.listToAttrs (map (id: { name = "${lan-dev}.${toString id}"; value = { inherit id; interface = lan-dev; }; }) [ 10 30 32 100 255 ]); networking.bonds.bond0 = { interfaces = [ "eno1" "eno2" ]; driverOptions = { miimon = "1000"; mode = "balance-rr"; }; }; systemd.services.update-dynamic-dns = { description = "Update dynamic dns records"; path = with pkgs; [ bash dnsutils nettools gawk iproute curl ]; startLimitIntervalSec = 5; script = toString ../tools/update-dns.sh; }; networking.firewall = { enable = lib.mkForce false; allowedTCPPorts = lib.mkForce [ ]; allowedUDPPorts = lib.mkForce [ ]; allowPing = true; logRefusedConnections = false; checkReversePath = false; }; services.ddclient = { enable = true; configFile = "/opt/secret/he-ddclient.conf"; }; # FIXME: Workaround for ddclient.conf not being available to ddclient. systemd.services.ddclient.serviceConfig.DynamicUser = lib.mkForce false; services.ferm = { enable = true; config = '' @def $DEV_UNTRUSTED_LAN = (${lan-dev}.30 ${lan-dev}.32); @def $DEV_LAN = (${lan-dev}.100 vpn); @def $DEV_ADMIN = (${lan-dev}.255); @def $DEV_WAN = (${wan-dev} he0 mullvad); @def $NET_LAN = (172.20.0.0/16); @def $NET_HE = (2001:470:8e2e::/48); # Forward dns queries to dnsmasq on LAN interfaces. domain (ip ip6) table nat chain PREROUTING { interface ($DEV_LAN $DEV_UNTRUSTED_LAN) daddr $NET_LAN proto (tcp udp) dport 53 REDIRECT to-ports 2053; } domain (ip ip6) table filter { chain INPUT { policy DROP; mod state state INVALID DROP; mod state state (ESTABLISHED RELATED) ACCEPT; interface lo ACCEPT; proto icmp ACCEPT; proto (udp udp) dport dhcpv6-client ACCEPT; proto 41 ACCEPT; # IPv6 sit tunnel interface ($DEV_WAN $DEV_LAN $DEV_UNTRUSTED_LAN) @subchain "wan_services" { # Valheim proto udp dport (3400 3401 3402) ACCEPT; proto (tcp udp) dport 2053 ACCEPT; proto (tcp udp) dport (bootpc bootps) ACCEPT; proto tcp dport ssh ACCEPT; proto (tcp udp) dport domain ACCEPT; proto tcp dport (http https) ACCEPT; proto udp dport (${ lib.concatStringsSep " " (map toString wireguardPorts) }) ACCEPT; } interface ($DEV_LAN $DEV_UNTRUSTED_LAN) { proto (tcp udp) dport 1080 ACCEPT; # socks proxy } interface ($DEV_LAN $DEV_ADMIN) @subchain "lan_services" { proto (tcp udp) dport 5000 ACCEPT; # random debugging proto (tcp udp) dport postgresql ACCEPT; # internal network only! proto (tcp udp) dport (ssh domain bootpc bootps ntp) ACCEPT; # prometheus temp rule proto tcp dport 11112 ACCEPT; proto (tcp udp) dport tftp ACCEPT; # RTMP streaming proto (tcp udp) dport 1935 ACCEPT; # Chromecast # proto udp dport 32768:61000 ACCEPT; # proto udp dport (5353 1900) ACCEPT; # proto tcp dport (8008 8009) ACCEPT; # Samba proto tcp dport (139 445) ACCEPT; proto udp dport (137 138) ACCEPT; # Project Zomboid proto udp dport (16261 16262) ACCEPT; # interface $DEV_LAN jump logdrop; } } chain OUTPUT policy ACCEPT; chain FORWARD { policy DROP; mod state state INVALID DROP; mod state state (ESTABLISHED RELATED) ACCEPT; interface $DEV_UNTRUSTED_LAN outerface $DEV_WAN ACCEPT; interface $DEV_LAN ACCEPT; # jump logdrop; } } domain ip6 table filter chain INPUT { proto ipv6-icmp ACCEPT; } domain (ip ip6) table filter chain logdrop { LOG log-level warning log-prefix "dropped "; DROP; } domain (ip ip6) table filter chain INPUT { interface $DEV_WAN DROP; # jump logdrop; } domain ip table nat { chain POSTROUTING { saddr $NET_LAN outerface $DEV_WAN MASQUERADE; } } domain (ip ip6) table mangle { chain PREROUTING { interface ${lan-dev}.30 MARK set-mark ${toString mullvadMark}; # Route HE traffic via tunnel. # saddr $NET_HE MARK set-mark ${toString heMark}; # saddr 2001:470:1f06:1194::2/64 MARK set-mark ${toString heMark}; } } ''; }; services = { openssh.enable = lib.mkDefault true; openssh.passwordAuthentication = false; }; boot.kernel.sysctl = { "net.ipv4.conf.all.forwarding" = true; "net.ipv4.conf.default.forwarding" = true; "net.ipv6.conf.all.forwarding" = true; "net.ipv6.conf.default.forwarding" = true; }; #services.hostapd = { # enable = true; # # driver = "iwlwifi"; # ssid = "2c"; # wpaPassphrase = "mintchip"; # interface = "${lan-dev}"; # hwMode = "g"; # channel = 11; # extraConfig = '' # country_code=US # wpa_key_mgmt=WPA-PSK # rsn_pairwise=CCMP # ''; #}; networking.dhcpcd = { # Wait for v4 and v6 addresses. # wait = "both"; extraConfig = '' noipv6rs nohook resolv.conf interface ${wan-dev} dhcp # ipv6rs # iaid 0 # ia_pd 0//56 ${lan-dev}.100/2/64 ''; runHook = '' # if [[ $reason =~ BOUND6|REBIND6 ]]; then # ip=${pkgs.iproute}/bin/ip # $ip addr add dev $interface "''${new_dhcp6_ia_pd1_prefix1}/64" || true # if [[ $new_dhcp6_ia_pd1_prefix1 != $old_dhcp6_ia_pd1_prefix1 ]]; then # $ip addr delete dev $interface "''${old_dhcp6_ia_pd1_prefix1}/64" # fi # fi systemctl restart update-dynamic-dns.service ''; }; systemd.services.dhcpcd = { after = [ "network-addresses-${wan-dev}.service" ]; preStart = lib.mkAfter '' ${pkgs.iproute}/bin/ip link set dev ${wan-dev} address ${ config.networking.interfaces.${wan-dev}.macAddress }; ''; }; services.dnsmasq = { enable = true; servers = [ "1.1.1.1" "8.8.8.8" "8.8.4.4" ]; resolveLocalQueries = false; extraConfig = '' port=2053 no-resolv no-hosts address=/localhost/::1 address=/localhost/127.0.0.1 enable-ra dhcp-authoritative # Null AAAA response on these domains server=/netflix.com/# address=/netflix.com/:: server=/netflix.net/# address=/netflix.net/:: server=/nflxext.com/# address=/nflxext.com/:: server=/nflximg.net/# address=/nflximg.net/:: server=/nflxvideo.net/# address=/nflxvideo.net/:: server=/nflxso.net/# address=/nflxso.net/:: dhcp-range=vlan30,172.20.30.50,172.20.30.254,5m dhcp-option=net:vlan30,option:router,172.20.30.1 dhcp-option=net:vlan30,option:dns-server,193.138.218.74 dhcp-option=net:vlan30,option:domain-search,nyc.orbekk.com dhcp-range=vlan100,172.20.100.50,172.20.100.254,5m dhcp-host=vlan100,d8:3b:bf:59:22:de,172.20.100.10 dhcp-range=vlan100,::100,::500,constructor:bond0.100,ra-only dhcp-option=net:vlan100,option:router,172.20.100.1 dhcp-option=net:vlan100,option:dns-server,172.20.100.1 dhcp-option=net:vlan100,option:domain-search,nyc.orbekk.com dhcp-range=vlan32,172.20.32.50,172.20.32.254,5m dhcp-range=vlan32,::100,::500,constructor:bond0.32,ra-only dhcp-option=net:vlan32,option:router,172.20.32.1 dhcp-option=net:vlan32,option:dns-server,172.20.32.1 dhcp-option=net:vlan32,option:domain-search,nyc.orbekk.com ''; }; networking.sits.he0 = { dev = wan-dev; remote = "209.51.161.14"; }; networking.iproute2.enable = true; # ${toString nycmeshMark} nycmesh networking.iproute2.rttablesExtraConfig = '' ${toString mullvadMark} mullvad ${toString heMark} he ''; systemd.services.network-route-setup = { description = "HE tunnel route setup"; requires = [ "network-online.target" ]; after = [ "network.target" "network-online.target" ]; wantedBy = [ "multi-user.target" ]; path = [ pkgs.iproute ]; script = '' #ip -6 rule add from 2001:470:8e2e::/48 lookup he prio 0 || true #ip -6 route replace default dev he0 src 2001:470:8e2e:20::d table he ip -6 route flush cache ip -6 rule add fwmark ${toString heMark} table he || true ''; }; networking.wireguard.interfaces.mullvad.postSetup = '' ip rule add fwmark ${toString mullvadMark} table mullvad ip route replace default dev mullvad table mullvad ip route flush cache ''; # networking.wireguard.interfaces.nycmesh.postSetup = '' # ip rule add fwmark ${toString nycmeshMark} table nycmesh # ip route replace default via 10.70.73.1 onlink dev nycmesh table nycmesh # ip route flush cache # ''; # boot.kernel.sysctl."net.ipv6.conf.${wan-dev}.disable_ipv6" = true; networking.interfaces.${wan-dev} = { macAddress = "3c:97:0e:19:7e:5c"; useDHCP = true; }; networking.interfaces.he0.ipv6 = { addresses = [ { address = "2001:470:1f06:1194::2"; prefixLength = 64; } { address = "2001:470:8e2e:20::d"; prefixLength = 64; } ]; routes = [ { address = "::"; prefixLength = 0; } { address = "::"; prefixLength = 0; options = { table = "he"; }; } ]; }; networking.interfaces."${lan-dev}".useDHCP = false; networking.interfaces."${lan-dev}.255" = { ipv4.addresses = [{ address = "10.10.255.3"; prefixLength = 24; }]; ipv6.addresses = [{ address = "2001:470:8e2e:ffff::3"; prefixLength = 64; }]; useDHCP = false; }; networking.interfaces."${lan-dev}.100" = { ipv4.addresses = [{ address = "172.20.100.1"; prefixLength = 24; }]; ipv6.addresses = [{ address = "2001:470:8e2e:100::1"; prefixLength = 64; }]; useDHCP = false; }; networking.interfaces."${lan-dev}.30" = { ipv4.addresses = [{ address = "172.20.30.1"; prefixLength = 24; }]; useDHCP = false; }; networking.interfaces."${lan-dev}.32" = { ipv4.addresses = [{ address = "172.20.32.1"; prefixLength = 23; }]; ipv6.addresses = [{ address = "2001:470:8e2e:32::1"; prefixLength = 64; }]; useDHCP = false; }; }