infra.network
53 options
infra.network.dhcp
infra.network.dhcp.dnsServers
DNS servers advertised to clients (fleet DNS + public fallback).
Type: list of string
Default:
config.fleet.network.dns_servers
Example:
[
"192.0.2.100"
"1.1.1.1"
]
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.domain
Domain name advertised to clients. Must be non-null when infra.network.dhcp is enabled (asserted).
Type: null or string
Default:
config.fleet.network.dns_domain
Example:
"example.lan"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.enable
Whether to enable Kea DHCPv4 server.
Type: boolean
Default:
false
Example:
true
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.gateway
Default gateway advertised to clients.
Type: string
Default: none (required when its feature is enabled)
Example:
"192.0.2.1"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.interface
Network interface to listen on.
Type: string
Default:
"eth1"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.poolEnd
End of DHCP pool range.
Type: string
Default: none (required when its feature is enabled)
Example:
"192.0.2.99"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.poolStart
Start of DHCP pool range.
Type: string
Default: none (required when its feature is enabled)
Example:
"192.0.2.50"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.reservations
Static DHCP reservations (MAC → IP).
Type: list of (submodule)
Default:
[ ]
Example:
[ { hostname = "printer"; hw-address = "52:54:00:12:34:56"; ip-address = "192.0.2.240"; } ]
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.reservations.*.hostname
Hostname handed to the client in the lease (Kea hostname reservation field).
Type: string
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.reservations.*.hw-address
Client MAC address the reservation matches on (colon-separated hex, e.g. “52:54:00:12:34:56”).
Type: string
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.reservations.*.ip-address
Fixed IPv4 address assigned to the matching client. Must lie inside the served subnet.
Type: string
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.subnet
CIDR subnet for DHCP allocation.
Type: string
Default: none (required when its feature is enabled)
Example:
"192.0.2.0/24"
Declared by: nix/modules/infra/network/dhcp
infra.network.dhcp.validLifetime
DHCP lease valid lifetime in seconds.
Type: signed integer
Default:
43200
Declared by: nix/modules/infra/network/dhcp
infra.network.dns
infra.network.dns.domain
DNS zone to serve. Must be non-null when infra.network.dns is enabled (asserted).
Type: null or string
Default:
config.fleet.settings.domain.internal
Declared by: nix/modules/infra/network/dns
infra.network.dns.enable
Whether to enable CoreDNS internal DNS server.
Type: boolean
Default:
false
Example:
true
Declared by: nix/modules/infra/network/dns
infra.network.dns.extraZones
Additional internal DNS zones beyond domain. Outer attrset
key is the zone name; inner attrset is record-name → IP.
Record names can be multi-label (e.g., “platform.pve”,
“nodes.btc.pve”) to express hierarchy within the zone.
Empty IPs are skipped, same as records.
Type: attribute set of attribute set of string
Default:
{ }
Example:
{ "example.xen" = { pbs = "192.0.2.99"; "platform.pve" = "192.0.2.98"; }; }
Declared by: nix/modules/infra/network/dns
infra.network.dns.forwarders
Upstream DNS servers for non-local queries.
Type: list of string
Default:
config.fleet.settings.network.upstreamResolvers
Declared by: nix/modules/infra/network/dns
infra.network.dns.listenAddress
Address CoreDNS listens on.
Type: string
Default:
"0.0.0.0"
Declared by: nix/modules/infra/network/dns
infra.network.dns.port
Port CoreDNS listens on.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
53
Declared by: nix/modules/infra/network/dns
infra.network.dns.publicDomain
Public DNS zone for internal (split-horizon) resolution of public names. Only forced when publicRecords is non-empty (asserted non-null then).
Type: null or string
Default:
config.fleet.settings.domain.base
Declared by: nix/modules/infra/network/dns
infra.network.dns.publicRecords
Hostname → IP mapping for the public domain zone (internal resolution only).
Type: attribute set of string
Default:
{ }
Example:
{ vpn = "192.0.2.2"; }
Declared by: nix/modules/infra/network/dns
infra.network.dns.records
Hostname → IP mapping for A records in the internal zone.
Type: attribute set of string
Default:
{ }
Example:
{ app-db = "192.0.2.104"; grafana = "192.0.2.4"; }
Declared by: nix/modules/infra/network/dns
infra.network.tailnet
infra.network.tailnet.advertiseExitNode
Advertise this node as an exit node.
Type: boolean
Default:
false
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.advertiseRoutes
CIDR routes this node should advertise.
Type: list of string
Default:
[ ]
Example:
[
"192.0.2.0/24"
]
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.advertiseTags
Tailscale ACL tags this node should advertise. Each entry must
be of the form “tag:tailscale up — the drift-fix oneshot below re-runs up
when this list changes so rebuilds reliably re-tag the node.
Type: list of string
Default:
[ ]
Example:
[
"tag:env-dev"
"tag:role-postgres"
]
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.authKeyFile
Path to file containing Tailscale/Headscale preauth key.
Type: null or absolute path
Default:
null
Example:
config.sops.secrets."services/tailscale/preauth_key".path
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.enable
Whether to enable Tailscale client.
Type: boolean
Default:
false
Example:
true
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.extraUpFlags
Extra flags appended to tailscale up.
Type: list of string
Default:
[ ]
Example:
[
"--login-server=https://vpn.example.dev"
"--accept-dns=false"
]
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.fetchAuthKey
Fetch the tailnet preauth key over HTTPS at boot instead of carrying a SOPS copy on every host: a pre-autoconnect oneshot curls url, writes the body to outputPath (mode 0400), and authKeyFile defaults to that path. null disables fetching.
Type: null or (submodule)
Default:
null
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.fetchAuthKey.outputPath
Where the fetched key is persisted on disk (mode 0400).
Type: string
Default:
"/var/lib/tailscale-fetch/preauth.key"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.fetchAuthKey.url
HTTPS endpoint that returns the preauth key as raw text body.
Type: string
Default: none (required when its feature is enabled)
Example:
"https://headscale.example.lan/internal/preauth/fleet-bot"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.fleetNode
One-line fleet tailnet enrollment. When true this implies
enable and derives the following — all via mkDefault, so
any individual knob stays overridable per-host:
userspace = true— LXC containers have no /dev/net/tunfetchAuthKey.url— fleet.settings.tailnet.preauthKeyUrl (when set; else SOPS auth key)advertiseTags— this host’s ACL tags, from the fleet manifest via lib/headscale-policy.nixextraUpFlags— –login-server (from fleet.settings.tailnet.controlUrl), –hostname=, –accept-dns=false Turns the per-host tailnet rollout into a single line per host regardless of that host’s module structure.
Type: boolean
Default:
false
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.funnel.enable
Whether to enable Tailscale Funnel (public internet exposure).
Type: boolean
Default:
false
Example:
true
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.funnel.routes
Path-based routes to expose via Tailscale Funnel.
Type: attribute set of (submodule)
Default:
{ }
Example:
{
headplane = {
backendPort = 3100;
path = "/admin";
};
headscale = {
backendPort = 8080;
path = "/";
};
}
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.funnel.routes.<name>.backendAddress
Address the route proxies to (combined with backendPort). Default targets loopback on this host.
Type: string
Default:
"127.0.0.1"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.funnel.routes.<name>.backendPort
Local port to proxy to.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.funnel.routes.<name>.path
URL path to serve on the ts.net hostname.
Type: string
Default:
"/"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.outboundProxy
Local port for tailscaled’s outbound HTTP proxy
(--outbound-http-proxy-listen). Set this when a service on a
USERSPACE node needs to make outbound connections to tailnet peers.
In userspace mode tailscaled installs no kernel routes, so the host
cannot originate ordinary TCP to a tailnet IP at all — there is no
interface to send it out of. The node is reachable INBOUND (that is
what serveUI relies on) while every outbound connection fails, which
is a confusing asymmetry to debug: tailscale ping succeeds, because
it goes through the daemon rather than the kernel datapath, while
curl http://<tailnet-ip>/ has nowhere to send the packet.
With this set, point the client at http://localhost:
Type: null or 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
null
Example:
1055
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serve
Declarative Tailscale Serve raw-TCP forwarders — tailnet-only, never
funnelled to the public internet. Each entry exposes
tcp://<hostname>.<base-domain>:<servePort> over the tailnet and
forwards raw bytes to a local backend. In userspace mode (all fleet
LXCs) serve is the only way to accept inbound tailnet connections.
See ADR-036 (tailnet-only admin plane).
Type: attribute set of (submodule)
Default:
{ }
Example:
{ caddy = { servePort = 443; backendPort = 443; }; }
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serve.<name>.backendAddress
Local address to forward to.
Type: string
Default:
"127.0.0.1"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serve.<name>.backendPort
Local TCP port to forward raw bytes to.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serve.<name>.enable
Enable this Tailscale Serve forwarder.
Type: boolean
Default:
true
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serve.<name>.servePort
Tailnet-side TCP port exposed on this node’s MagicDNS name
(<hostname>.<base-domain>). This is a raw passthrough: TLS is
terminated by the backend (typically a local Caddy holding the
tailnet-suffix wildcard cert), NOT by tailscaled. headscale has
no tailscale cert/serve-HTTPS support (upstream #2527), so
--https/--tls-terminated-tcp are unusable here — this is
always a raw --tcp forwarder. See ADR-036.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
443
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI
Tailnet-only browser UIs. Each entry produces a Caddy vhost on this
host’s MagicDNS name with a browser-trusted per-host cert, fronted
by tailscale serve. Reachable only from tailnet members (no public
DNS record). The network is the gate — see ADR-036.
Type: attribute set of (submodule)
Default:
{ }
Example:
{ pgweb.backendPort = 8081; }
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.backendAddress
Local backend address.
Type: string
Default:
"127.0.0.1"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.backendPort
Local backend port the UI listens on.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default: none (required when its feature is enabled)
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.description
One-line, human-facing summary of what this UI is for.
Surfaced in the developer handbook by
nix run .#wiki-services. Keep it dev-facing (what you’d
use it for), not infra detail. Falls back to the matching
infra.services.<name>.description when left blank.
Type: string
Default:
""
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.enable
Expose this UI over the tailnet.
Type: boolean
Default:
true
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.path
URL path within the servePort vhost. “/” = the whole vhost
(at most one per (host, servePort)). “/foo” = a handle /foo*
block. Prefer distinct servePorts over paths unless the app
explicitly supports a base path.
Type: string
Default:
"/"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUI.<name>.servePort
Tailnet-side TCP port. Reached at
https://<hostname>.<serveUIDomain>[:servePort]. For a host
running more than one UI, give each a distinct port (e.g. 443
and 8443) so every UI sits at its own vhost root — avoids the
sub-path breakage common to SPAs. Entries sharing a port are
combined into one vhost and disambiguated by path.
Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)
Default:
443
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.serveUIDomain
MagicDNS base domain for serveUI hostnames (<hostname>.<this>). Must be non-null when serveUI entries exist (asserted).
Type: null or string
Default:
config.fleet.settings.domain.tailnetSuffix
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.tailnetName
Tailnet or Headscale namespace name.
Type: null or string
Default:
null
Example:
"fleet-bot"
Declared by: nix/modules/infra/network/tailnet
infra.network.tailnet.userspace
Run tailscaled in userspace networking mode
(--tun=userspace-networking). Required for LXC containers
that don’t have /dev/net/tun passed through. Strongly preferred
on LXC anyway: the Proxmox host runs its own kernel-mode
tailscaled on a separate (cloud) tailnet, and granting LXCs
TUN passthrough breaks that isolation.
In userspace mode tailscaled does not install kernel routes
for tailnet IPs, so applications must use tailscale’s built-in
proxies — tailscale ssh, tailscale serve, or the SOCKS5
proxy at 127.0.0.1:1055 — rather than direct routing.
Type: boolean
Default:
false
Declared by: nix/modules/infra/network/tailnet