diff --git a/hosts/servo/default.nix b/hosts/servo/default.nix index 71a0fbc2..7fd62a28 100644 --- a/hosts/servo/default.nix +++ b/hosts/servo/default.nix @@ -14,6 +14,7 @@ pkgs.freshrss ]; sane.impermanence.enable = true; + sane.services.dyn-dns.enable = true; # sane.services.duplicity.enable = true; # TODO: re-enable after HW upgrade boot.loader.efi.canTouchEfiVariables = false; diff --git a/modules/services/default.nix b/modules/services/default.nix index 490ed9b9..1ca1035c 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -2,6 +2,7 @@ { imports = [ ./duplicity.nix + ./dyn-dns.nix ./kiwix-serve.nix ./nixserve.nix ./trust-dns.nix diff --git a/modules/services/dyn-dns.nix b/modules/services/dyn-dns.nix new file mode 100644 index 00000000..07c51b60 --- /dev/null +++ b/modules/services/dyn-dns.nix @@ -0,0 +1,78 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.sane.services.dyn-dns; +in +{ + options = { + sane.services.dyn-dns = { + enable = mkOption { + default = false; + type = types.bool; + }; + + ipPath = mkOption { + default = "/var/lib/uninsane/wan.txt"; + type = types.str; + description = "where to store the latest WAN IPv4 address"; + }; + + ipCmd = mkOption { + default = "${pkgs.sane-scripts}/bin/sane-ip-check-router-wan"; + type = types.path; + description = "command to run to query the current WAN IP"; + }; + + interval = mkOption { + type = types.str; + default = "10min"; + description = "systemd time string for how frequently to re-check the IP"; + }; + + restartOnChange = mkOption { + type = types.listOf types.str; + default = []; + description = "list of systemd unit files to restart when the IP changes"; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.dyn-dns = { + description = "update this host's record of its WAN IP"; + after = [ "network.target" ]; + restartTriggers = [(builtins.toJSON cfg)]; + serviceConfig.Type = "oneshot"; + script = '' + mkdir -p $(dirname "${cfg.ipPath}") + ${cfg.ipCmd} > "${cfg.ipPath}" + ''; + }; + + systemd.timers.dyn-dns = { + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnStartupSec = cfg.interval; + OnUnitActiveSec = cfg.interval; + }; + }; + + systemd.paths.dyn-dns-watcher = { + before = [ "dyn-dns.service" ]; + wantedBy = [ "dyn-dns.service" ]; + pathConfig = { + Unit = "dyn-dns-reactor.service"; + PathChanged = [ cfg.ipPath ]; + }; + }; + + systemd.services.dyn-dns-reactor = { + description = "react to the system's WAN IP changing"; + serviceConfig.Type = "oneshot"; + script = if cfg.restartOnChange != [] then '' + ${pkgs.systemd}/bin/systemctl restart ${toString cfg.restartOnChange} + '' else "${pkgs.coreutils}/bin/true"; + }; + }; +}