/nixos-router

A simple module to make NixOS act as a router!

Primary LanguageNixGNU General Public License v3.0GPL-3.0

nixos-router

A simple module to make NixOS act as a router!

This uses:

  • nftables for firewalling & NAT,
  • dnsmasq as a DHCP server; it also forwards DNS to…
  • stubby for secure DNS over TLS & DNSSEC validation
  • hostapd for running a WLAN Access Point with WPA3 SAE-PK security

Usage

Simply include the module in your NixOS config flake:

# flake.nix
{
  inputs = {
    nixos-router.url = "github:42LoCo42/nixos-router";
    # no need to "follow" any inputs!
  };
}

And configure it like this:

# configuration.nix
{ self, ... }: {
  imports = [ self.inputs.nixos-router.nixosModules.default ];

  services.router = {
    enable = true;

    lanIF = "wlan0";
    wanIF = "eth0";

    wlan = {
      ssid = "My Network";
      passwordFile = "/var/lib/wlan-password.sae";
    };
  };
}

You need a SAE password file to use WLAN; to generate it do this:

# obtain required tools
nix shell nixpkgs#openssl github:42LoCo42/obscura#sae_pk_gen

# generate the EC keypair
openssl ecparam -name prime256v1 -genkey -noout -out wlan-password.der -outform der

# convert to SAE password file
# use the same SSID here!
sae_pk_gen wlan-password.der 3 "My Network" |
    sed 's|sae_password=||' >wlan-password.sae

The file wlan-password.der can now be deleted. Its contents are part of wlan-password.sae. Speaking of, check out that file to get the WLAN password!

You can also select a longer one from the list in the file (but you can’t pick your own due to how SAE-PK works). To change the password, just put it at the start of the line that’s not a comment!

YOUR-WLAN-PASS-WORD|pk=<very long string>

WLAN QR code

Tired of manually entering passwords? Run sudo qr to display a QR code that you can scan with your phone to automatically connect to the WLAN!

qr.png

All options

Main options (services.router)

  • enable (bool): Enable this module. Default: false
  • lanIF (string): Name of the LAN (internal) network interface. Required!
  • wanIF (string): Name of the WAN (external) network interface. Required!
  • lanIP (string): LAN IP of the router. Default: 10.0.0.1
  • lanSize (number, 0..32): Size of the LAN in CIDR notation (the part after the slash). Default: 24
  • lanAlloc (string): DHCP allocation range & duration. Must match lanIP and lanSize! Default: 10.0.0.2,10.0.0.254,12h
  • blockFakeLocals (bool): Whether to block incoming connections on the WAN that originate from local IP ranges. Disable this when testing in a VM! Default: true

WLAN options (services.router.wlan)

  • enable (bool): Enable the WLAN. Default: true
  • ssid (string): SSID of the WLAN. Required!
  • passwordFile (path): Path to the SAE password file. Required!
  • hide (bool): Ignore SSID broadcast requests to hide the WLAN. Default: false