From 2cf7ccc1b157167add591d1e1b1e488cec618646 Mon Sep 17 00:00:00 2001 From: Joe Mou Date: Wed, 27 Sep 2023 21:54:19 -0400 Subject: IPv6 dynamic dns, systemd-networkd for RFC 7217 stable private addresses systemd-networkd is a bit opaque. In particular there doesn't seem to be a way to verify that the generated IPv6 addresses are stable private. An alternative may be to set net.ipv6.conf.default.addr_gen_mode = 2. systemd.network.wait-online.anyInterface does not seem to work properly; systemd-networkd-wait-online.service should be generated with --any flag but appears to be from upstream. --- hostnix/weebnix/configuration.nix | 52 +++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'hostnix') diff --git a/hostnix/weebnix/configuration.nix b/hostnix/weebnix/configuration.nix index f585f2a..48186a2 100644 --- a/hostnix/weebnix/configuration.nix +++ b/hostnix/weebnix/configuration.nix @@ -2,7 +2,7 @@ # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running `nixos-help`). -{ config, pkgs, ... }: +{ config, pkgs, lib, ... }: { imports = [ @@ -31,6 +31,27 @@ networks."oldschool".psk = builtins.readFile /var/lib/secrets/oldschool.wpa-psk; }; + networking.dhcpcd.enable = false; + networking.tempAddresses = "disabled"; + systemd.network.enable = true; + systemd.network.networks = let + default = { + networkConfig = { + DHCP = "yes"; + MulticastDNS = "yes"; + }; + ipv6AcceptRAConfig.Token = "prefixstable"; # RFC 7217 + }; + in { + "10-wlan" = lib.recursiveUpdate default { + matchConfig.Name = "wlan0"; + }; + "10-eth" = lib.recursiveUpdate default { + matchConfig.Name = "end0"; + linkConfig.RequiredForOnline = "no"; + }; + }; + time.timeZone = "America/New_York"; # Select internationalisation properties. @@ -102,23 +123,33 @@ Restart = "on-failure"; RestartSec = "1min"; }; - path = [ pkgs.dnsutils ]; + path = [ pkgs.dnsutils pkgs.gawk pkgs.iproute2 ]; scriptArgs = config.networking.fqdn; script = '' RR=''${1%%.*}.dynamic.''${1#*.} - IP=`dig +short @1.1.1.1 ch txt whoami.cloudflare | tr -d \"` - if [ -z "$IP" ]; then - echo "Missing IP: $IP" >&2 + IP4=`dig +short @1.1.1.1 ch txt whoami.cloudflare | tr -d \"` + if [ -z "$IP4" ]; then + echo "Missing IP: $IP4" >&2 exit 100 fi - OLDIP=`dig +short @popfresh.mou.fo $RR A 2> /dev/null` - [ "x$IP" = "x$OLDIP" ] && exit 0 # no update + # Follow some RFC 6724 default address guidance, excluding ULA. + # It might be more robust to bind a public source socket (RFC 5014). + IP6=`ip -6 address show scope global -deprecated | awk -F'[ /]+' '$2 == "inet6" && $3 !~ /^f[cd]/ { print $3; exit }'` + + OLDIP4=`dig +short @popfresh.mou.fo $RR A 2> /dev/null` + OLDIP6=`dig +short @popfresh.mou.fo $RR AAAA 2> /dev/null` + # [ "x$IP" = "x$OLDIP4" ] && exit 0 # no update + if [ "x$IP4" = "x$OLDIP4" -a "x$IP6" = "x$OLDIP6" ]; then + exit 0 + fi nsupdate -v -k /var/lib/secrets/`< /var/lib/secrets/$1.id`.private <<. update delete $RR. A - update add $RR. 300 A $IP + update add $RR. 300 A $IP4 + update delete $RR. AAAA + ''${IP6:+update add $RR. 300 AAAA $IP6} update delete $RR. TXT update add $RR. 300 TXT "v=spf1 include:_spf.mou.fo ~all" send @@ -134,11 +165,6 @@ }; }; - services.avahi = { - enable = true; - nssmdns = true; - }; - services.openssh.enable = true; # Open ports in the firewall. -- cgit v1.3.1