This is another NixOS router framework working better for my usecase
- designed for environments with dynamic IP address configs
- uses DHCPv4 on WAN to get private or public IPv4
- uses DHCPv6 on WAN to get public IPv6 prefix via DHCP prefix delegation (DHCP-PD)
- allows easy exposing & forwarding of ports
- exposed port rules auto-adapt to changing IPv6 prefix
- port forwardings (i.e. DNAT) work on IPv4 & IPv6
- configuring them only requires MAC & static IPv4
- configures AdGuard Home as filtering DNS server for clients
- stays mostly compatible with common NixOS networking & firewall configs, e.g.:
.openFirewall&.allowedTCPPorts/.allowedUDPPortsoptions continue to work (opens port on all interfaces)
I also develop a NixOS test which tries to verify that these features work as expected, which will be published later in this flake.
Given all features, this module comes up with a few restrictions (; incomplete list):
- supports only one WAN & one LAN interface
- does not allow easy integration of a VPN network
- fully relies on systemd-networkd for DHCPv4/v6 client, DHCPv4 server & prefix-delegated router advertisements
It is not impossible or really, really hard to overcome these limitations but it may require changing this module in substantional ways.
(TODO link to yet uncommited stuff)
I was inspired to implement this by other, similar projects, which were sadly lacking some features highly important to me. However, as a form of credit & to provide further ressources to you:
- nixos-router by @chayleaf
- utilizes network namespaces (mine does not!)
- because of that, (at time of writing) it ditched systemd-networkd for now, which I wanted to use
- was not designed for a environment with dynamic IPs
- NixOS based router in 2023 by @ghostbuster91
- was a useful ressource in creating my module
Which has nothing to do in particular with this module, but which were discovered while implementing it.
- nftables sets do not support a the typical wildcard
*for non IP addresses (i.e. protocols, ports, etc.) BUT nftables supports "CIDR-like" syntax for all numeric values, e.g.meta mark == 0/2, hence0/0is kind of a wildcard for everything. - You can match ports for several OSI L4 protocols in a single set by leveraging the type concatenation
inet_proto&inet_service, which is matched bymeta l4proto . th dport(orth sport). This works for all protocols which declare their source & destination ports in the first or second 16 bits of the header (read manpage on howthworks). This is at least the case fordccp,sctp,tcp,udp&udplite. More funnily, you can technically useth sportto matchicmp&icmpv6types & codes together, through this requires some caution.