nixos-config/machines/fuuko/services/router.nix

254 lines
7.2 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Home network configuration
#
# +----------+ +------+
# | | | | ( clients )
# | | | +|-|-|-|-|+
# +---+----+ +-+-+-+ |5 4 3 2 1|
# |upstream| |fuuko| |TL-SG105 |
# +--------+ +-----+ +---------+
#
# It consists of fuuko as a router (this configuration),
# connected to a TP-LINK TL-SG105E “smart managed” (i.e., it can do VLANs) 5-port switch.
# The upstream comes from some plasic Huawei router/AP I dont control.
#
# fuuko has two physical network interfaces,
# because remote unlocking (which requires network in initrd) is hard with VLANs.
#
# Wireless is configured by providing the whole hostapd configuration file as a secret.
# Once nixpkgs PR 222536 is merged, I will migrate to using the NixOS module.
# Thanks to Intels wisdom, its not possible to use 5GHz in AP mode.
{ config, lib, pkgs, ... }:
let
domain = "home.sbruder.de";
in
{
sops.secrets.wg-mullvad-private-key = {
owner = config.users.users.systemd-network.name;
sopsFile = ../secrets.yaml;
};
sops.secrets.hostapd-config = {
sopsFile = ../secrets.yaml;
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
};
networking = {
# networkd handles this
useDHCP = false;
# networkd didnt work that well for this
nat = {
enable = true;
enableIPv6 = true;
externalInterface = "wg-mullvad";
internalInterfaces = [ "br-lan" ];
internalIPv6s = [ "fd00:80:1::/64" ];
};
};
systemd.network = {
enable = true;
netdevs = {
br-lan = {
netdevConfig = {
Name = "br-lan";
Kind = "bridge";
};
};
wg-mullvad = {
netdevConfig = {
Kind = "wireguard";
Name = "wg-mullvad";
};
wireguardConfig = {
PrivateKeyFile = config.sops.secrets.wg-mullvad-private-key.path;
FirewallMark = 51820;
};
wireguardPeers = lib.singleton {
wireguardPeerConfig = {
Endpoint = "193.32.127.70:51820";
PublicKey = "dV/aHhwG0fmp0XuvSvrdWjCtdyhPDDFiE/nuv/1xnRM=";
AllowedIPs = [ "0.0.0.0/0" "::0/0" ];
PersistentKeepalive = 25;
};
};
};
};
networks = {
wan = {
name = "enp8s0";
networkConfig = {
# Upstream provides no IPv6 :(
# If this is not set, it waits and fails systemd-networkd-wait-online
LinkLocalAddressing = "no";
IPv6AcceptRA = "no";
};
DHCP = "ipv4";
dhcpV4Config = {
UseDNS = "no";
};
};
lan = {
name = "enp9s0";
bridge = [ "br-lan" ];
};
br-lan = {
name = "br-lan";
domains = [ domain ];
address = [ "10.80.1.1/24" "fd00:80:1::1/64" ];
};
wg-mullvad = {
name = "wg-mullvad";
address = [ "10.66.208.88/32" "fc00:bbbb:bbbb:bb01::3:d057/128" ];
dns = [ "10.64.0.1" ];
routingPolicyRules = [
{
routingPolicyRuleConfig = {
FirewallMark = 51820;
InvertRule = "yes";
Table = 51820;
Priority = 10;
#SuppressPrefixLength = 0; # cant be used here (forwarding does not work with it)
};
}
# FIXME: those two shouldnt be necessary
# It should automatically detect those routes existing and prioritise them
{
routingPolicyRuleConfig = {
To = "10.80.0.0/24";
Priority = 9;
};
}
{
routingPolicyRuleConfig = {
To = "10.80.1.0/24";
Priority = 9;
};
}
];
routes = [
{
routeConfig = {
Gateway = "0.0.0.0"; # point-to-point connection
Table = 51820;
};
}
{
routeConfig = {
Gateway = "::";
};
}
];
};
};
};
services.resolved.enable = false;
services.dnsmasq = {
enable = true;
extraConfig = ''
bogus-priv # do not forward revese lookups of internal addresses
domain-needed # do not forward names without domain
interface=br-lan # only respond to queries from lan
no-hosts # do not resolve hosts from /etc/hosts
no-resolv # only use explicitly configured resolvers
cache-size=10000
domain=${domain}
# Allow resolving the router
interface-name=${config.networking.hostName}.${domain},br-lan
interface-name=${config.networking.hostName},br-lan
# DHCPv4
dhcp-range=10.80.1.20,10.80.1.150,12h
dhcp-option=option:router,10.80.1.1
# SLAAC (for addresses) / DHCPv6 (for DNS)
dhcp-range=fd00:80:1::,ra-stateless,ra-names
dhcp-option=option6:dns-server,fd00:80:1::1
# Despite its name, the switch does not have a smart configuration,
# that would allow me to tell it not to get DHCP from wan,
# but from lan instead.
# So it has to use static configuration.
host-record=switchviech,switchviech.${domain},10.80.1.19
'';
servers = [
"10.64.0.1" # mullvad DNS, should be fastest overall
#"9.9.9.9" # dns.quad9.net
#"2620:fe::fe"
];
};
systemd.services.dnsmasq.after = [ "systemd-networkd.service" ];
services.prometheus.exporters.dnsmasq = {
enable = true;
listenAddress = config.sbruder.wireguard.home.address;
leasesPath = "/var/lib/dnsmasq/dnsmasq.leases";
};
networking.firewall.allowedUDPPorts = [ 53 67 ];
networking.firewall.allowedTCPPorts = [ 53 ];
# Wireless
boot.kernelModules = [ "nl80211" ];
environment.systemPackages = with pkgs; [
iw
wirelesstools
];
# The service is mostly taken from nixpkgs pr 222536.
systemd.services.hostapd = {
path = with pkgs; [ hostapd ];
after = [ "sys-subsystem-net-devices-wlp7s0.device" ];
bindsTo = [ "sys-subsystem-net-devices-wlp7s0.device" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.hostapd}/bin/hostapd ${config.sops.secrets.hostapd-config.path}";
Restart = "always";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
RuntimeDirectory = "hostapd";
# Hardening
LockPersonality = true;
MemoryDenyWriteExecute = true;
DevicePolicy = "closed";
DeviceAllow = "/dev/rfkill rw";
NoNewPrivileges = true;
PrivateUsers = false; # hostapd requires true root access.
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProcSubset = "pid";
ProtectSystem = "strict";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_NETLINK"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"@chown"
];
UMask = "0077";
};
};
}