diff options
| author | Joe Mou <dev@mou.fo> | 2023-09-28 00:53:11 -0400 |
|---|---|---|
| committer | Joe Mou <dev@mou.fo> | 2023-09-29 17:06:04 -0400 |
| commit | 8391bd18f4f7cd80095c5f27abdf034db0ff5f3f (patch) | |
| tree | 26e20ff374efa2d0f6eaba9590d2d5708037d1ef /hostnix/weebnix | |
| parent | 2cf7ccc1b157167add591d1e1b1e488cec618646 (diff) | |
Refactor system and dyndns modules
Diffstat (limited to 'hostnix/weebnix')
| -rw-r--r-- | hostnix/weebnix/configuration.nix | 155 | ||||
| -rw-r--r-- | hostnix/weebnix/dyndns.nix | 78 | ||||
| -rw-r--r-- | hostnix/weebnix/system.nix | 45 |
3 files changed, 127 insertions, 151 deletions
diff --git a/hostnix/weebnix/configuration.nix b/hostnix/weebnix/configuration.nix index 48186a2..72b0523 100644 --- a/hostnix/weebnix/configuration.nix +++ b/hostnix/weebnix/configuration.nix @@ -1,67 +1,16 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page -# and in the NixOS manual (accessible by running `nixos-help`). - -{ config, pkgs, lib, ... }: +{ config, pkgs, ... }: { imports = [ + ./dyndns.nix ./hardware-configuration.nix ./syncthing.nix + ./system.nix ]; nix.settings.experimental-features = [ "nix-command" "flakes" ]; nix.settings.trusted-users = [ "joe" ]; - boot.loader.systemd-boot.enable = true; - # Raspberry Pi has no NVRAM. - boot.loader.efi.canTouchEfiVariables = false; - - boot.kernelPackages = pkgs.linuxPackages_rpi4; - # https://github.com/NixOS/nixpkgs/issues/122130#issuecomment-1568815007 - # It's unclear if these are strictly necessary with the downstream kernel, - # but let's leave them in to keep working with mainline. - boot.initrd.availableKernelModules = [ "uas" "pcie-brcmstb" "reset-raspberrypi" ]; - - networking.hostName = "weebnix"; - networking.domain = "mou.fo"; - # TODO secrets management or switch to wired - networking.wireless = { - enable = true; - 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. - # i18n.defaultLocale = "en_US.UTF-8"; - # console = { - # font = "Lat2-Terminus16"; - # keyMap = "us"; - # useXkbConfig = true; # use xkbOptions in tty. - # }; - security.sudo.wheelNeedsPassword = false; users.users.joe = { @@ -70,113 +19,18 @@ openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHcqQDnH0LcUWFV+cd9aABfM55+72UAn1ZY5x5bHwPL4IEgT1nagbi1X3FwCJkh2rEcDsHl4FflcNfh+IyU2VyuQfRIXl7CKP040ovXmPVzgU8JiEDrrRebpZ7aHCKk+4Q6cJ8dzAI1sRogVyYrV0hLB4yeMnVexkIcsQMt5pXQ1zodlzHfW1W7OWQDbKjIyh4pv1KJ/IIjiBIt7l+OCqi7wZK4ubmxyMhmZx1xpRC5mz2/29Mpt+1VgCmxC7Hv1SG7yu+U0s4eJ3kbzFKNcZ/bCYqFxK48dT66qhS3qZFg09omumG8IbEUcx+WqM1V7WhiJYig9x5ovmMToQXTJ5uxLtcovnxO/53IgwV7INvmr8+NhD+LlkQfSjjUAW09bhVj9sKIW2bbrIxlOT8z6CQY9zGXNXi8u1oxPt3Q7d3rMxoWhWnr2l3Ok7OIkWooOK3e0NdhgIAxZKlYJAmIYaX391sGTyiuwUy96mg5JcYsLYMfkEg/Sv+2vQp8kkvB0E= joe@sparky" ]; - # packages = with pkgs; [ - # firefox - # tree - # ]; }; environment.systemPackages = with pkgs; [ libraspberrypi tmux - vim ]; - # Some programs need SUID wrappers, can be configured further or are - # started in user sessions. - # programs.mtr.enable = true; - # programs.gnupg.agent = { - # enable = true; - # enableSSHSupport = true; - # }; - - # Needs to be started manually, and the key added to nameservers. - # Based on https://nixos.org/manual/nixos/stable/index.html#module-security-acme-config-dns - systemd.services.sig0-keygen = { - unitConfig = { - ConditionPathExists = "!/var/lib/secrets/${config.networking.fqdn}.id"; - }; - serviceConfig = { - Type = "oneshot"; - }; - path = [ pkgs.bind ]; - scriptArgs = config.networking.fqdn; - script = '' - mkdir -p /var/lib/secrets - chmod 755 /var/lib/secrets - cd /var/lib/secrets - dnssec-keygen -a RSASHA512 -b 2048 -n HOST -T KEY $1. > $1.id - ''; - }; - - systemd.services.dyndns = { - requires = [ "network-online.target" ]; - after = [ "network-online.target" ]; - unitConfig = { - AssertPathExists = "/var/lib/secrets/${config.networking.fqdn}.id"; - # Defer errors for ~45min, throttle e-mails to ~hourly. - StartLimitIntervalSec = "1hr"; - StartLimitBurst = "45"; - }; - serviceConfig = { - Type = "oneshot"; - Restart = "on-failure"; - RestartSec = "1min"; - }; - path = [ pkgs.dnsutils pkgs.gawk pkgs.iproute2 ]; - scriptArgs = config.networking.fqdn; - script = '' - RR=''${1%%.*}.dynamic.''${1#*.} - - 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 - - # 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 $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 - . - ''; - }; - - systemd.timers.dyndns = { - wantedBy = [ "multi-user.target" ]; - timerConfig = { - OnStartupSec = "10"; - OnUnitActiveSec = "1min"; - }; - }; + programs.vim.defaultEditor = true; services.openssh.enable = true; - # Open ports in the firewall. - # networking.firewall.allowedTCPPorts = [ ... ]; - # networking.firewall.allowedUDPPorts = [ ... ]; - # Or disable the firewall altogether. - # networking.firewall.enable = false; - # Copy the NixOS configuration file and link it from the resulting system - # (/run/current-system/configuration.nix). This is useful in case you - # accidentally delete configuration.nix. - # system.copySystemConfiguration = true; # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions @@ -185,5 +39,4 @@ # Before changing this value read the documentation for this option # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). system.stateVersion = "23.05"; # Did you read the comment? - } diff --git a/hostnix/weebnix/dyndns.nix b/hostnix/weebnix/dyndns.nix new file mode 100644 index 0000000..a59c665 --- /dev/null +++ b/hostnix/weebnix/dyndns.nix @@ -0,0 +1,78 @@ +{ config, pkgs, ... }: + +{ + # Needs to be started manually, and the key added to nameservers. + # Based on https://nixos.org/manual/nixos/stable/index.html#module-security-acme-config-dns + systemd.services.sig0-keygen = { + unitConfig = { + ConditionPathExists = "!/var/lib/secrets/${config.networking.fqdn}.id"; + }; + serviceConfig = { + Type = "oneshot"; + }; + path = [ pkgs.bind ]; + scriptArgs = config.networking.fqdn; + script = '' + mkdir -p /var/lib/secrets + chmod 755 /var/lib/secrets + cd /var/lib/secrets + dnssec-keygen -a RSASHA512 -b 2048 -n HOST -T KEY $1. > $1.id + ''; + }; + + systemd.services.dyndns = { + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + unitConfig = { + AssertPathExists = "/var/lib/secrets/${config.networking.fqdn}.id"; + # Defer errors for ~45min, throttle e-mails to ~hourly. + StartLimitIntervalSec = "1hr"; + StartLimitBurst = "45"; + }; + serviceConfig = { + Type = "oneshot"; + Restart = "on-failure"; + RestartSec = "1min"; + }; + path = [ pkgs.dnsutils pkgs.gawk pkgs.iproute2 ]; + scriptArgs = config.networking.fqdn; + script = '' + RR=''${1%%.*}.dynamic.''${1#*.} + + 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 + + # 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 $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 + . + ''; + }; + + systemd.timers.dyndns = { + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnStartupSec = "10"; + OnUnitActiveSec = "1min"; + }; + }; +} diff --git a/hostnix/weebnix/system.nix b/hostnix/weebnix/system.nix new file mode 100644 index 0000000..94dca6d --- /dev/null +++ b/hostnix/weebnix/system.nix @@ -0,0 +1,45 @@ +{ pkgs, lib, ... }: + +{ + boot.loader.systemd-boot.enable = true; + # Raspberry Pi has no NVRAM. + boot.loader.efi.canTouchEfiVariables = false; + + boot.kernelPackages = pkgs.linuxPackages_rpi4; + # https://github.com/NixOS/nixpkgs/issues/122130#issuecomment-1568815007 + # It's unclear if these are strictly necessary with the downstream kernel, + # but let's leave them in to keep working with mainline. + boot.initrd.availableKernelModules = [ "uas" "pcie-brcmstb" "reset-raspberrypi" ]; + + networking.hostName = "weebnix"; + networking.domain = "mou.fo"; + # TODO secrets management or switch to wired + networking.wireless = { + enable = true; + networks."oldschool".psk = builtins.readFile /var/lib/secrets/oldschool.wpa-psk; + }; + + systemd.network.enable = true; + networking.dhcpcd.enable = false; + networking.tempAddresses = "disabled"; + + 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"; +} |
