Archived
Check NixOS configurations / eval-hosts (pull_request) Successful in 10m31s
- variables.nix: switch to rec {}, extract giteaDomain/giteaRepoPath,
extraAdminSshKeys, haLanNfsFqdn, tailscaleResolverIp, ports.dhcp,
ports.dns; ipaServer now derives from homeDomain ref; section headers
- modules: use new vars throughout (pxe-boot, ts-dns-forwarder,
cluster-config, configuration.nix, mount-pxe-images) — eval unchanged
- docs: delete ephemeral planning docs (AUDIT_REPORT, ha-network-audit,
network-cutover); add docs/ha.md; drop migration reference table from
ip-addressing.md; remove stale server example from beszel.md
- CLAUDE.md/README.md/AGENTS.md: fix build types (tailscale-router,
ha-server, drop server); document scripts/ha/, scripts/ipa/, and
all previously undocumented top-level and lib scripts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
2.5 KiB
Nix
54 lines
2.5 KiB
Nix
{ vars, ... }:
|
|
|
|
{
|
|
# Run dnsmasq on the LAN interface as a forwarding-only resolver for
|
|
# *.ts.net (Tailscale MagicDNS names). FreeIPA's bind-dyndb-ldap
|
|
# cannot reach vars.tailscaleResolverIp directly because the DC is not a
|
|
# Tailscale node. This host IS a Tailscale node and can reach it via
|
|
# tailscale0, so it acts as an intermediary: FreeIPA has a conditional
|
|
# forward zone for ts.net pointing here (vars.tailscaleRouterIp), and this
|
|
# dnsmasq instance forwards those queries onward to Tailscale's resolver.
|
|
#
|
|
# Configure FreeIPA once after deploying this host:
|
|
# kinit admin
|
|
# ipa dnsforwardzone-add ${vars.tailnetDomain} \
|
|
# --forwarder=${vars.tailscaleRouterIp} \
|
|
# --forward-policy=only
|
|
# Note: IPA refuses to shadow ts.net (a real public TLD); use the
|
|
# tailnet-specific subdomain (vars.tailnetDomain) instead.
|
|
services.dnsmasq = {
|
|
enable = true;
|
|
# NixOS's dnsmasq module defaults resolveLocalQueries to true, which adds
|
|
# 127.0.0.1 to networking.nameservers and makes dnsmasq bind to
|
|
# listen-address=127.0.0.1. This instance is not the host's local
|
|
# resolver — it only serves IPA's conditional forwarder for tailnet names.
|
|
# The host uses domainControllerIp directly (networking.nameservers in
|
|
# host.nix). Without this, all host DNS goes through dnsmasq, which has
|
|
# no upstream for general queries (no-resolv=true), breaking resolution.
|
|
resolveLocalQueries = false;
|
|
settings = {
|
|
# Listen only on the LAN interface — not tailscale0 or loopback.
|
|
# bind-interfaces prevents dnsmasq from binding to 0.0.0.0 and then
|
|
# filtering by interface later; combined with `interface` this ensures
|
|
# it genuinely listens only on eth0.
|
|
bind-interfaces = true;
|
|
interface = [ vars.lxcLanInterface ];
|
|
|
|
# Forward-only: no local /etc/hosts or /etc/resolv.conf reading, no
|
|
# negative caching of NXDOMAIN for names this instance doesn't serve.
|
|
# All ts.net queries come from FreeIPA's conditional forwarder and must
|
|
# be answered by Tailscale's resolver.
|
|
no-hosts = true;
|
|
no-resolv = true;
|
|
|
|
# Forward *.tailnetDomain to Tailscale's internal resolver, scoped to
|
|
# the tailnet-specific subdomain rather than all of ts.net (FreeIPA
|
|
# refuses to shadow ts.net, a real public TLD).
|
|
server = [ "/${vars.tailnetDomain}/${vars.tailscaleResolverIp}" ];
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedUDPPorts = [ vars.ports.dns ];
|
|
networking.firewall.allowedTCPPorts = [ vars.ports.dns ];
|
|
}
|