mirror of
https://codeberg.org/polyteknisk-radiogruppe/the_prg_server_configuration.git
synced 2026-06-13 18:28:55 +02:00
Update the home-manager new hash.
Added dynamic public IPv4 address updater to traefik.
This commit is contained in:
parent
6d11b57c61
commit
140935c120
2 changed files with 143 additions and 1 deletions
|
|
@ -6,7 +6,7 @@
|
|||
}: let
|
||||
home-manager = builtins.fetchTarball {
|
||||
url = "https://github.com/nix-community/home-manager/archive/release-25.11.tar.gz";
|
||||
sha256 = "1kqxy6r4ahnbazmpa4pncdp62najdikdaw8hvrv8nl6qxvbmf9fy";
|
||||
sha256 = "8C+y46xA9bxcchj9GeDPJaRUDApaA3sy2fhJr1bTbUw=";
|
||||
};
|
||||
cfg = config.services.forgejo;
|
||||
srv = cfg.settings.server;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,39 @@
|
|||
...
|
||||
}: let
|
||||
choose = paths: builtins.head (builtins.filter (p: builtins.pathExists p) paths);
|
||||
# Package the upstream cloudflare-ddns-updater from GitHub into the Nix store
|
||||
upstreamOwner = "K0p1-Git";
|
||||
upstreamRepo = "cloudflare-ddns-updater";
|
||||
upstreamRev = "e9906c3aa0b73c26e3473618ad7a69db853e669d";
|
||||
upstreamSrc = pkgs.fetchFromGitHub {
|
||||
owner = upstreamOwner;
|
||||
repo = upstreamRepo;
|
||||
rev = upstreamRev;
|
||||
sha256 = "0j1pv57hk9rhr1kxqqjxg71y0d2d1hi3b4yiq908x5kcv3abbina";
|
||||
};
|
||||
|
||||
cloudflare-ddns-pkg = pkgs.stdenv.mkDerivation {
|
||||
pname = "cloudflare-ddns-updater";
|
||||
version = upstreamRev;
|
||||
src = upstreamSrc;
|
||||
# no build required for a script-only repo
|
||||
buildPhase = '': '';
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin $out/lib/cloudflare-ddns
|
||||
cp -r $src/* $out/lib/cloudflare-ddns/ || true
|
||||
if [ -x "$out/lib/cloudflare-ddns/update.sh" ]; then
|
||||
cp "$out/lib/cloudflare-ddns/update.sh" $out/bin/cloudflare-ddns
|
||||
chmod +x $out/bin/cloudflare-ddns
|
||||
else
|
||||
# If upstream layout changes, keep the repo contents available under $out/lib
|
||||
true
|
||||
fi
|
||||
'';
|
||||
meta = with pkgs.lib; {
|
||||
description = "Cloudflare DDNS updater";
|
||||
license = licenses.mit;
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.local = {
|
||||
hostname = lib.mkOption {
|
||||
|
|
@ -562,6 +595,115 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
# PRG Cloudflare DDNS updater
|
||||
environment.etc."cloudflare-ddns/update.sh" = {
|
||||
text = let
|
||||
domain = "prg-radio.org";
|
||||
records = ["git" "grafana" "anubis" "wavelog" "partdb" "mail" "mailadmin" "@"];
|
||||
recordsStr = lib.concatStringsSep " " records;
|
||||
zoneId = "9fde8d0fa53502f2d1b7e0b1d3765d49";
|
||||
envFile = "/home/traefikprg/cloudflare/cloudflare.env";
|
||||
in ''
|
||||
#!/usr/bin/env bash
|
||||
set -euuo pipefail
|
||||
|
||||
# Load environment variables (must contain CLOUDFLARE_API_TOKEN)
|
||||
if [ -f "${envFile}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "${envFile}"
|
||||
fi
|
||||
|
||||
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
|
||||
echo "CLOUDFLARE_API_TOKEN is not set in ${envFile}, aborting" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
API_BASE="https://api.cloudflare.com/client/v4"
|
||||
|
||||
# get current public IPv4
|
||||
CURRENT_IP=$(curl -4 -sS https://ipv4.icanhazip.com | tr -d '\n') || true
|
||||
if [ -z "$CURRENT_IP" ]; then
|
||||
echo "Failed to detect public IPv4 address" >&2
|
||||
exit 3
|
||||
fi
|
||||
|
||||
jq=${pkgs.jq}/bin/jq
|
||||
|
||||
update_or_create() {
|
||||
local fqdn="$1"
|
||||
# Query existing A records for fqdn
|
||||
res=$(curl -sS -X GET "$API_BASE/zones/${zoneId}/dns_records?type=A&name=$fqdn" \
|
||||
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||
-H "Content-Type: application/json")
|
||||
|
||||
ok=$(echo "$res" | $jq -r '.success')
|
||||
if [ "$ok" != "true" ]; then
|
||||
echo "Cloudflare API query failed for $fqdn: $res" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
existing_ip=$(echo "$res" | $jq -r '.result[0].content // empty')
|
||||
record_id=$(echo "$res" | $jq -r '.result[0].id // empty')
|
||||
|
||||
if [ -n "$existing_ip" ] && [ "$existing_ip" = "$CURRENT_IP" ]; then
|
||||
echo "$fqdn is already set to $CURRENT_IP, skipping"
|
||||
return 0
|
||||
fi
|
||||
|
||||
payload=$(cat <<JSON
|
||||
{"type":"A","name":"$fqdn","content":"$CURRENT_IP","ttl":1,"proxied":false}
|
||||
JSON
|
||||
)
|
||||
|
||||
if [ -n "$record_id" ]; then
|
||||
echo "Updating $fqdn ($record_id) -> $CURRENT_IP"
|
||||
curl -sS -X PUT "$API_BASE/zones/${zoneId}/dns_records/$record_id" \
|
||||
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "$payload" | $jq -r '.'
|
||||
else
|
||||
echo "Creating record $fqdn -> $CURRENT_IP"
|
||||
curl -sS -X POST "$API_BASE/zones/${zoneId}/dns_records" \
|
||||
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "$payload" | $jq -r '.'
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Starting PRG Cloudflare DDNS updater: setting IP=$CURRENT_IP"
|
||||
for r in ${recordsStr}; do
|
||||
if [ "$r" = "@" ]; then
|
||||
fqdn="${domain}"
|
||||
else
|
||||
fqdn="$r.${domain}"
|
||||
fi
|
||||
update_or_create "$fqdn" || true
|
||||
done
|
||||
'';
|
||||
mode = "0755";
|
||||
group = "root";
|
||||
};
|
||||
|
||||
systemd.services."prg-cloudflare-ddns-updater" = {
|
||||
description = "PRG Cloudflare DDNS updater";
|
||||
wantedBy = ["multi-user.target"];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
EnvironmentFile = "/home/traefikprg/cloudflare/cloudflare.env";
|
||||
ExecStart = "${pkgs.bash}/bin/bash /etc/cloudflare-ddns/update.sh";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers."prg-cloudflare-ddns-updater" = {
|
||||
description = "Run PRG Cloudflare DDNS updater periodically";
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnBootSec = "1m";
|
||||
OnUnitActiveSec = "10m";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Enable Tailscale for remote access to Traefik dashboard and configuration
|
||||
services.tailscale.enable = true;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue