134 lines
3.4 KiB
Nix
134 lines
3.4 KiB
Nix
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
{ lib, pkgs, ... }:
|
|
let
|
|
guests = {
|
|
forgejo-actions-runner = {
|
|
mac = "42:80:00:00:00:02";
|
|
v4 = "10.80.32.2";
|
|
v6 = "2a01:4f8:151:712d:1::2";
|
|
};
|
|
};
|
|
|
|
# port forwarding for IPv4
|
|
portForwards = {
|
|
tcp = { };
|
|
udp = { };
|
|
};
|
|
in
|
|
{
|
|
virtualisation.libvirtd = {
|
|
enable = true;
|
|
qemu.package = pkgs.qemu_kvm;
|
|
};
|
|
|
|
boot.kernel.sysctl = {
|
|
"net.ipv4.conf.all.forwarding" = true;
|
|
"net.ipv6.conf.all.forwarding" = true;
|
|
};
|
|
|
|
systemd.network = {
|
|
enable = true;
|
|
netdevs = {
|
|
br-virt = {
|
|
netdevConfig = {
|
|
Name = "br-virt";
|
|
Kind = "bridge";
|
|
};
|
|
};
|
|
};
|
|
networks = {
|
|
br-virt = {
|
|
name = "br-virt";
|
|
address = [ "10.80.32.1/24" "2a01:4f8:151:712d:1::1/80" ];
|
|
};
|
|
};
|
|
};
|
|
services.resolved.enable = false;
|
|
|
|
services.dnsmasq = {
|
|
enable = true;
|
|
|
|
settings = {
|
|
interface = [ "br-virt" ];
|
|
|
|
bind-interfaces = true; # do not bind to the wildcard interface
|
|
bogus-priv = true; # do not forward revese lookups of internal addresses
|
|
dhcp-fqdn = true; # only insert qualified names of DHCP clients into DNS
|
|
domain-needed = true; # do not forward names without domain
|
|
no-hosts = true; # do not resolve hosts from /etc/hosts
|
|
no-resolv = true; # only use explicitly configured resolvers
|
|
|
|
domain = [ "koyomi.sbruder.de" ];
|
|
|
|
enable-ra = true; # required to tell clients to use DHCPv6
|
|
|
|
# Force static configuration
|
|
dhcp-range = [
|
|
"10.80.32.0,static,255.255.255.0"
|
|
"2a01:4f8:151:712d:1::,static,80"
|
|
];
|
|
|
|
dhcp-host = lib.flatten (lib.mapAttrsToList
|
|
(name: { mac, v4, v6 }: [
|
|
"${mac},${v4},${name}"
|
|
"${mac},[${v6}],${name}"
|
|
])
|
|
guests);
|
|
|
|
# Hetzner recursive name servers
|
|
# https://docs.hetzner.com/dns-console/dns/general/recursive-name-servers/
|
|
server = [
|
|
"185.12.64.1"
|
|
"185.12.64.2"
|
|
"2a01:4ff:ff00::add:1"
|
|
"2a01:4ff:ff00::add:2"
|
|
];
|
|
};
|
|
};
|
|
|
|
networking.firewall = {
|
|
allowedTCPPorts = map lib.toInt (lib.attrNames portForwards.tcp);
|
|
allowedUDPPorts = map lib.toInt (lib.attrNames portForwards.udp);
|
|
|
|
interfaces.br-virt = {
|
|
allowedTCPPorts = [ 53 ]; # EDNS
|
|
allowedUDPPorts = [ 53 67 547 ]; # DNS / DHCP / DHCPv6
|
|
};
|
|
};
|
|
|
|
networking.nftables = {
|
|
enable = true;
|
|
ruleset = ''
|
|
# only IPv4
|
|
table ip hypervisor-nat {
|
|
chain postrouting {
|
|
type nat hook postrouting priority filter; policy accept
|
|
oifname eth0 masquerade
|
|
}
|
|
|
|
chain prerouting {
|
|
type nat hook prerouting priority dstnat; policy accept
|
|
${lib.concatStrings (lib.mapAttrsToList (port: guest: ''
|
|
iifname eth0 tcp dport ${port} dnat to ${guests.${guest}.v4}
|
|
'') portForwards.tcp)}
|
|
${lib.concatStrings (lib.mapAttrsToList (port: guest: ''
|
|
iifname eth0 udp dport ${port} dnat to ${guests.${guest}.v4}
|
|
'') portForwards.udp)}
|
|
}
|
|
}
|
|
|
|
table inet hypervisor-filter {
|
|
chain forward {
|
|
type filter hook forward priority filter; policy drop
|
|
|
|
iifname br-virt oifname eth0 counter accept
|
|
iifname eth0 oifname br-virt counter accept
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
}
|