sbc-deploys/modules/router/default.nix

445 lines
12 KiB
Nix
Raw Normal View History

2024-07-06 18:46:46 +00:00
{ hostName, wireguardPrivateKey }:
2024-07-02 05:52:32 +00:00
2024-07-06 18:46:46 +00:00
{ config, pkgs, ... }:
2024-07-01 19:11:08 +00:00
2024-07-02 05:52:32 +00:00
let
wan = "end0";
lan = "enp1s0";
bridge = "br-lan";
2024-07-02 22:38:29 +00:00
devices = "devices-vlan";
wifi = "wifi-vlan";
2024-07-06 18:46:46 +00:00
wg0 = "wg0";
2024-07-02 05:52:32 +00:00
in
2024-07-01 19:11:08 +00:00
{
2024-07-06 18:46:46 +00:00
sops.secrets.${wireguardPrivateKey} = {
format = "binary";
sopsFile = ../../secrets/${wireguardPrivateKey}.bin;
path = "/etc/wireguard-secret";
mode = "0400";
owner = "systemd-network";
group = "systemd-network";
restartUnits = [ "systemd-networkd.service" ];
};
2024-07-01 19:11:08 +00:00
boot.kernel = {
sysctl = {
"net.ipv6.conf.all.forwarding" = 1;
"net.ipv6.conf.${bridge}.accept_ra" = 2;
"net.ipv6.conf.${devices}.accept_ra" = 2;
"net.ipv6.conf.${wifi}.accept_ra" = 2;
2024-07-01 19:11:08 +00:00
"net.ipv4.conf.all.forwarding" = true;
"net.ipv4.conf.default.rp_filter" = 1;
2024-07-02 05:52:32 +00:00
"net.ipv4.conf.${wan}.rp_filter" = 1;
"net.ipv4.conf.${bridge}.rp_filter" = 0;
"net.ipv4.conf.${devices}.rp_filter" = 0;
"net.ipv4.conf.${wifi}.rp_filter" = 0;
2024-07-01 19:11:08 +00:00
};
};
2024-07-03 00:12:41 +00:00
environment.systemPackages = with pkgs; [
arp-scan
2024-07-06 18:46:46 +00:00
wireguard-tools
2024-07-03 00:12:41 +00:00
];
2024-07-01 19:11:08 +00:00
systemd.network = {
wait-online.anyInterface = true;
netdevs = {
"10-${devices}" = {
2024-07-02 22:38:29 +00:00
netdevConfig = {
Name = devices;
Kind = "vlan";
};
vlanConfig.Id = 30;
};
"10-${wifi}" = {
2024-07-02 22:38:29 +00:00
netdevConfig = {
Name = wifi;
Kind = "vlan";
};
vlanConfig.Id = 40;
};
2024-07-02 05:52:32 +00:00
"20-${bridge}" = {
netdevConfig = {
2024-07-01 19:11:08 +00:00
Kind = "bridge";
2024-07-02 05:52:32 +00:00
Name = bridge;
2024-07-01 19:11:08 +00:00
};
};
2024-07-06 18:46:46 +00:00
"30-${wg0}" = {
netdevConfig = {
Kind = "wireguard";
Name = wg0;
MTUBytes = "1300";
};
wireguardConfig = {
PrivateKeyFile = "/etc/wireguard-secret";
ListenPort = 51820;
};
wireguardPeers = [
{
PublicKey = "ppaJ0RAtdvFpdg0eJPkO0YnYnEMZhiwAlQJUHnC80EA=";
AllowedIPs = [ "192.168.5.10" "2001:db8:5::10" ];
}
];
};
2024-07-01 19:11:08 +00:00
};
networks = {
"06-${wan}" = {
2024-07-02 05:52:32 +00:00
matchConfig.Name = wan;
2024-07-01 19:11:08 +00:00
linkConfig.RequiredForOnline = "routable";
networkConfig = {
DHCP = true;
2024-07-02 05:52:32 +00:00
IPv6AcceptRA = true;
2024-07-01 19:11:08 +00:00
DNSOverTLS = true;
DNSSEC = true;
2024-07-05 13:22:39 +00:00
IPv6PrivacyExtensions = false;
2024-07-01 19:11:08 +00:00
IPForward = true;
LinkLocalAddressing = "ipv6";
2024-07-01 19:11:08 +00:00
};
};
2024-07-02 05:52:32 +00:00
"30-${lan}" = {
matchConfig.Name = lan;
2024-07-01 19:11:08 +00:00
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
2024-07-02 05:52:32 +00:00
Bridge = bridge;
2024-07-01 19:11:08 +00:00
ConfigureWithoutCarrier = true;
2024-07-03 00:12:41 +00:00
VLAN = [ devices wifi ];
2024-07-01 19:11:08 +00:00
};
};
2024-07-02 05:52:32 +00:00
"40-${bridge}" = {
matchConfig.Name = bridge;
2024-07-01 19:11:08 +00:00
bridgeConfig = { };
address = [
2024-07-02 05:52:32 +00:00
"192.168.20.1/24"
2024-07-04 17:33:29 +00:00
"2001:db8:20::1/64"
2024-07-01 19:11:08 +00:00
];
networkConfig = {
2024-07-04 20:20:34 +00:00
IPv6SendRA = true;
2024-07-01 19:11:08 +00:00
ConfigureWithoutCarrier = true;
};
2024-07-04 20:20:34 +00:00
ipv6Prefixes = [{
Prefix = "2001:db8:20::/64";
}];
ipv6SendRAConfig = {
EmitDNS = true;
DNS = "2001:db8:20::1";
};
2024-07-02 05:52:32 +00:00
linkConfig.RequiredForOnline = "no";
2024-07-01 19:11:08 +00:00
};
2024-07-02 22:38:29 +00:00
"50-${devices}" = {
matchConfig = {
Name = devices;
Type = "vlan";
};
address = [
"192.168.30.1/24"
2024-07-04 17:33:29 +00:00
"2001:db8:30::1/64"
2024-07-02 22:38:29 +00:00
];
2024-07-04 20:20:34 +00:00
networkConfig = {
IPv6SendRA = true;
};
ipv6Prefixes = [{
Prefix = "2001:db8:30::/64";
}];
ipv6SendRAConfig = {
EmitDNS = true;
DNS = "2001:db8:30::1";
};
2024-07-03 04:13:21 +00:00
linkConfig.RequiredForOnline = "routable";
2024-07-02 22:38:29 +00:00
};
"50-${wifi}" = {
matchConfig = {
Name = wifi;
Type = "vlan";
};
address = [
"192.168.40.1/24"
2024-07-04 17:33:29 +00:00
"2001:db8:40::1/64"
2024-07-02 22:38:29 +00:00
];
2024-07-04 20:20:34 +00:00
networkConfig = {
IPv6SendRA = true;
};
ipv6Prefixes = [{
Prefix = "2001:db8:40::/64";
}];
ipv6SendRAConfig = {
EmitDNS = true;
DNS = "2001:db8:40::1";
};
2024-07-03 04:13:21 +00:00
linkConfig.RequiredForOnline = "routable";
2024-07-02 22:38:29 +00:00
};
2024-07-06 18:46:46 +00:00
"60-${wg0}" = {
matchConfig.Name = wg0;
address = [ "192.168.5.1/24" "2001:db0:5::1/64" ];
networkConfig = { };
linkConfig.RequiredForOnline = "yes";
};
2024-07-01 19:11:08 +00:00
};
};
networking = {
2024-07-02 05:52:32 +00:00
inherit hostName;
2024-07-01 19:11:08 +00:00
useNetworkd = true;
useDHCP = false;
nat.enable = false;
firewall.enable = false;
nftables = {
enable = true;
2024-07-02 05:52:32 +00:00
checkRuleset = false;
2024-07-01 19:11:08 +00:00
ruleset = ''
define WAN=${wan}
define LAN=${lan}
define BRIDGE=${bridge}
define DEVICES=${devices}
define WIFI=${wifi}
2024-07-06 18:46:46 +00:00
define WG0=${wg0}
define HTTP_HOST=192.168.20.200
2024-07-05 00:28:45 +00:00
define HTTP_HOST_V6=2001:db8:20::200
define FORGEJO_HOST=192.168.20.201
2024-07-05 00:28:45 +00:00
define FORGEJO_HOST_V6=2001:db8:20::201
define FORGEJO_SSH_PORT=2222
2024-07-05 00:28:45 +00:00
define DRAWPILE_HOST=192.168.20.202
2024-07-05 00:28:45 +00:00
define DRAWPILE_HOST_V6=2001:db8:20::202
define DRAWPILE_TCP_PORT=27750
table inet filter {
set internal_access_tcp {
type inet_service; flags interval;
elements = { 22, 3128 }
}
set internal_access_udp {
type inet_service; flags interval;
elements = { 51820 }
}
set network_required_udp {
type inet_service; flags interval;
elements = { 53, 67, 68, 546, 547 }
}
set firewall_out_tcp_accepted {
type inet_service; flags interval;
elements = { 22, 53, 80, 443, 853 }
}
set firewall_out_udp_accepted {
type inet_service; flags interval;
elements = { 53, 123, 67, 68, 546, 547 }
}
chain global {
ct state { established, related } accept
ct state invalid drop
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain reject_politely {
reject with icmp type port-unreachable
}
chain bridge_in {
2024-07-05 00:28:45 +00:00
tcp dport { 80, 443 } ip daddr $HTTP_HOST ct state new accept comment "Allow HTTP/S to http host"
tcp dport { 80, 443 } ip6 daddr $HTTP_HOST_V6 ct state new accept comment "Allow HTTP/S to http host"
tcp dport $FORGEJO_SSH_PORT ip daddr $FORGEJO_HOST ct state new accept comment "Allow ssh to forgejo"
tcp dport $FORGEJO_SSH_PORT ip6 daddr $FORGEJO_HOST_V6 ct state new accept comment "Allow ssh to forgejo"
tcp dport $DRAWPILE_TCP_PORT ip daddr $DRAWPILE_HOST ct state new accept comment "Allow drawpile traffic to drawpile"
tcp dport $DRAWPILE_TCP_PORT ip6 daddr $DRAWPILE_HOST_V6 ct state new accept comment "Allow drawpile traffic to drawpile"
}
chain bridge_out {
accept
}
chain devices_in {}
chain devices_out {
udp dport 123 ct state new accept comment "Allow NTP from devices network"
tcp dport { 80, 443 } ct state new accept comment "Allow HTTP/S from devices network"
}
chain wifi_in {}
chain wifi_out {
accept
}
2024-07-06 18:46:46 +00:00
chain wg_in {}
chain wg_out {
accept
}
chain rate_limit {
flow table rate-limit-ftable { ip saddr limit rate 2/minute } accept comment "Allow rate limited"
}
chain forward {
type filter hook forward priority filter; policy drop;
jump global
oifname vmap {
$BRIDGE : jump bridge_in,
$DEVICES : jump devices_in,
2024-07-06 18:46:46 +00:00
$WIFI : jump wifi_in,
$WG0 : jump wg_in
}
oifname $WAN iifname vmap {
$BRIDGE : jump bridge_out,
$DEVICES : jump devices_out,
2024-07-06 18:46:46 +00:00
$WIFI : jump wifi_out,
$WG0 : jump wg_out
}
2024-07-04 04:09:14 +00:00
2024-07-06 18:46:46 +00:00
iifname $WG0 oifname $BRIDGE ct state new accept comment "Allow from wireguard to bridge"
iifname $BRIDGE oifname $WG0 ct state new accept comment "Allow from bridge to wireguard"
2024-07-04 04:09:14 +00:00
jump reject_politely
}
chain input {
type filter hook input priority 0; policy drop;
jump global
iifname lo accept
tcp dport @internal_access_tcp ct state new iifname vmap {
$BRIDGE : accept,
2024-07-06 18:46:46 +00:00
$WG0 : accept,
$DEVICES : jump reject_politely,
$WIFI : jump rate_limit,
$WAN : jump rate_limit
}
udp dport @internal_access_udp ct state new iifname vmap {
$BRIDGE : accept,
2024-07-06 18:46:46 +00:00
$WG0 : accept,
$DEVICES : jump reject_politely,
$WIFI : jump rate_limit,
$WAN : jump rate_limit
}
udp dport @network_required_udp ct state new accept comment "Allow internal network required stuff"
jump reject_politely
}
chain output {
type filter hook output priority 100; policy drop;
jump global
tcp dport @firewall_out_tcp_accepted ct state new accept
udp dport @firewall_out_udp_accepted ct state new accept
jump reject_politely
}
2024-07-02 05:52:32 +00:00
}
table ip nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
fib daddr type local tcp dport { 80, 443 } dnat to $HTTP_HOST
fib daddr type local tcp dport 22 dnat to $FORGEJO_HOST:$FORGEJO_SSH_PORT
fib daddr type local tcp dport $DRAWPILE_TCP_PORT dnat to $DRAWPILE_HOST
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname $WAN masquerade
2024-07-06 18:46:46 +00:00
iifname { $WAN, $BRIDGE, $DEVICES, $WIFI } oifname $BRIDGE masquerade
}
2024-07-01 19:11:08 +00:00
}
2024-07-04 17:33:29 +00:00
table ip6 nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
2024-07-05 00:28:45 +00:00
fib daddr type local tcp dport { 80, 443 } dnat to $HTTP_HOST_V6
fib daddr type local tcp dport 22 dnat to $FORGEJO_HOST_V6:$FORGEJO_SSH_PORT
fib daddr type local tcp dport $DRAWPILE_TCP_PORT dnat to $DRAWPILE_HOST_V6
2024-07-04 17:33:29 +00:00
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname $WAN masquerade
2024-07-06 18:46:46 +00:00
iifname { $WAN, $BRIDGE, $DEVICES, $WIFI } oifname $BRIDGE masquerade
2024-07-04 17:33:29 +00:00
}
}
2024-07-01 19:11:08 +00:00
'';
};
2024-07-02 05:52:32 +00:00
};
2024-07-01 19:11:08 +00:00
2024-07-02 05:52:32 +00:00
services.openssh.ports = [ 22 3128 ];
2024-07-01 19:11:08 +00:00
2024-07-02 05:52:32 +00:00
services.resolved.enable = false;
2024-07-01 19:11:08 +00:00
2024-07-02 05:52:32 +00:00
services.dnsmasq = {
enable = true;
settings = {
2024-07-04 18:46:51 +00:00
server = [
"9.9.9.9"
"9.9.9.10"
"2620:fe::fe"
"2620:fe::9"
];
2024-07-02 05:52:32 +00:00
domain-needed = true;
bogus-priv = true;
no-resolv = true;
2024-07-01 19:11:08 +00:00
# dhcpv6 stuff
2024-07-04 17:33:29 +00:00
enable-ra = true;
dhcp-authoritative = true;
strict-order = true;
2024-07-02 05:52:32 +00:00
cache-size = 1000;
2024-07-01 19:11:08 +00:00
2024-07-02 22:38:29 +00:00
dhcp-range = [
# format TAG,START,END,?MASK,?options,LEASE
"${bridge},192.168.20.50,192.168.20.90,24h"
2024-07-04 20:20:34 +00:00
"${bridge},::ffff,constructor:${bridge},ra-names,64,24h"
"${devices},192.168.30.10,192.168.30.240,24h"
2024-07-04 20:20:34 +00:00
"${devices},::10,constructor:${devices},ra-names,64,24h"
"${wifi},192.168.40.10,192.168.40.240,24h"
2024-07-04 20:20:34 +00:00
"${wifi},::10,constructor:${wifi},ra-names,64,24h"
2024-07-02 22:38:29 +00:00
];
2024-07-06 18:46:46 +00:00
interface = [ bridge devices wifi wg0 ];
2024-07-02 22:38:29 +00:00
dhcp-option = [
2024-07-03 00:12:41 +00:00
"${bridge},option:router,192.168.20.1"
"${bridge},option:dns-server,192.168.20.1"
2024-07-04 17:33:29 +00:00
"${bridge},option6:dns-server,2001:db8:20::1"
2024-07-02 22:38:29 +00:00
2024-07-03 00:12:41 +00:00
"${devices},option:router,192.168.30.1"
"${devices},option:dns-server,192.168.30.1"
2024-07-04 17:33:29 +00:00
"${devices},option6:dns-server,2001:db8:30::1"
2024-07-02 22:38:29 +00:00
2024-07-03 00:12:41 +00:00
"${wifi},option:router,192.168.40.1"
"${wifi},option:dns-server,192.168.40.1"
2024-07-04 17:33:29 +00:00
"${wifi},option6:dns-server,2001:db8:40::1"
2024-07-02 22:38:29 +00:00
];
2024-07-02 05:52:32 +00:00
local = "/lan/";
domain = "lan";
expand-hosts = true;
no-hosts = true;
address = [
"/router.lan/192.168.20.1"
2024-07-04 17:33:29 +00:00
"/router.lan/2001:db8:20::1"
];
2024-07-01 19:11:08 +00:00
};
};
2024-07-02 05:52:32 +00:00
services.irqbalance.enable = false;
2024-07-01 19:11:08 +00:00
}