99 lines
3.5 KiB
Nix
99 lines
3.5 KiB
Nix
{ config, pkgs, lib, inputs, ... }:
|
|
let
|
|
cfg = config.services.domeneshop-updater;
|
|
in
|
|
{
|
|
# auto domain update
|
|
|
|
# TODO: ensure dns64 does not interfere with this
|
|
|
|
options = with lib; {
|
|
services.domeneshop-updater.targets = mkOption {
|
|
type = with types; listOf str;
|
|
example = [ config.networking.fqdn ];
|
|
};
|
|
};
|
|
# don't run if local VM
|
|
config = lib.mkIf (cfg.targets != [] && !config.virtualisation.isVmVariant) {
|
|
|
|
users.users.domeneshop.isSystemUser = true;
|
|
users.users.domeneshop.group = "domeneshop";
|
|
users.groups.domeneshop = {};
|
|
|
|
sops.secrets."domeneshop/token".sopsFile = "${inputs.self}/secrets/dns.yaml";
|
|
sops.secrets."domeneshop/token".owner = "domeneshop";
|
|
sops.secrets."domeneshop/token".group = "domeneshop";
|
|
sops.secrets."domeneshop/secret".sopsFile = "${inputs.self}/secrets/dns.yaml";
|
|
sops.secrets."domeneshop/secret".owner = "domeneshop";
|
|
sops.secrets."domeneshop/secret".group = "domeneshop";
|
|
|
|
systemd.services.domeneshop-updater = {
|
|
description = "domene.shop dyndns domain updater";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "network-online.target" ];
|
|
wants = [ "network-online.target" ];
|
|
serviceConfig = let
|
|
prog = pkgs.writeShellApplication {
|
|
name = "domeneshop-dyndns-updater.sh";
|
|
runtimeInputs = with pkgs; [ curl iproute2 jq ];
|
|
text = ''
|
|
test -s /run/secrets/domeneshop/token || {
|
|
>&2 echo "ERROR: /run/secrets/domeneshop/token not found!"
|
|
exit 1
|
|
}
|
|
test -s /run/secrets/domeneshop/secret || {
|
|
>&2 echo "ERROR: /run/secrets/domeneshop/secret not found!"
|
|
exit 1
|
|
}
|
|
DOMENESHOP_TOKEN="$( cat /run/secrets/domeneshop/token)"
|
|
DOMENESHOP_SECRET="$(cat /run/secrets/domeneshop/secret)"
|
|
|
|
# get stable ipv6 addr, fallback to ipv4, fallback to curl default
|
|
IF=$(
|
|
ip -6 -json addr show scope global -temporary \
|
|
| jq '.[]| select(.ifname|contains("docker")|not) | .addr_info[].local | select(.==null|not)' -r \
|
|
| head -n1
|
|
)
|
|
if [[ -z "$IF" ]]; then
|
|
IF=$(
|
|
ip -4 -json addr show scope global -temporary \
|
|
| jq '.[]| select(.ifname|contains("docker")|not) | .addr_info[].local | select(.==null|not)' -r \
|
|
| head -n1
|
|
)
|
|
fi
|
|
if [[ -n "$IF" ]]; then
|
|
IF="--interface $IF"
|
|
else
|
|
IF=""
|
|
fi
|
|
|
|
# shellcheck disable=SC2086
|
|
echo + curl $IF api.domeneshop.no...
|
|
|
|
${lib.concatMapStringsSep "\n" (target: ''
|
|
# shellcheck disable=SC2086
|
|
curl $IF https://"$DOMENESHOP_TOKEN":"$DOMENESHOP_SECRET"@api.domeneshop.no/v0/dyndns/update?hostname="${target}"
|
|
'') cfg.targets}
|
|
'';
|
|
};
|
|
in {
|
|
User = "domeneshop";
|
|
Group = "domeneshop";
|
|
#DynamicUser = true; # maybe re-enable when sops-nix is in place?
|
|
ExecStart = "${prog}/bin/domeneshop-dyndns-updater.sh";
|
|
PrivateTmp = true;
|
|
};
|
|
};
|
|
systemd.timers.domeneshop-updater = let interval = "2h"; in {
|
|
description = "Update domene.shop every ${interval}";
|
|
wantedBy = [ "timers.target" ];
|
|
timerConfig = {
|
|
OnBootSec = "5m";
|
|
OnUnitInactiveSec = interval;
|
|
Unit = "domeneshop-updater.service";
|
|
};
|
|
};
|
|
|
|
};
|
|
}
|