{ config, pkgs, inputs, ... }: let domain = "per-aspera.space"; updateRoute53 = pkgs.writeShellScript "update-route53" '' #!/usr/bin/env bash set -euo pipefail HOSTED_ZONE_ID="Z09728753LLLNSYFXIBIM" # Get from Route 53 console DOMAIN=${domain} # Get current public IP CURRENT_IP=$(${pkgs.curl}/bin/curl -s https://ifconfig.me) # Validate IP format if ! echo "$CURRENT_IP" | grep -qE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'; then echo "[$(date)] ERROR: Invalid IP format: $CURRENT_IP" >&2 exit 1 fi # Get current DNS record DNS_IP=$(${pkgs.dig}/bin/dig +short "$DOMAIN" @8.8.8.8 | tail -n1) if [ "$CURRENT_IP" != "$DNS_IP" ]; then echo "[$(date)] IP changed: $DNS_IP -> $CURRENT_IP" ${pkgs.awscli2}/bin/aws route53 change-resource-record-sets \ --hosted-zone-id "$HOSTED_ZONE_ID" \ --change-batch "{ \"Changes\": [{ \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\": \"$DOMAIN\", \"Type\": \"A\", \"TTL\": 300, \"ResourceRecords\": [{\"Value\": \"$CURRENT_IP\"}] } }] }" echo "[$(date)] DNS updated successfully to $CURRENT_IP" else echo "[$(date)] IP unchanged: $CURRENT_IP" fi ''; in { networking.firewall.allowedTCPPorts = [ 80 443 ]; services.nginx = { enable = true; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; virtualHosts."${domain}" = { forceSSL = false; enableACME = false; root = "${inputs.thelenlucas.packages.${pkgs.system}.default}"; }; }; environment.systemPackages = [ pkgs.awscli2 ]; systemd.services.route53-ddns = { description = "Update Route 53 with current IP periodically"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; serviceConfig = { Type = "oneshot"; ExecStart = updateRoute53; }; }; systemd.timers.route53-ddns = { description = "Route 53 DDNS Update Timer"; wantedBy = [ "timers.target" ]; timerConfig = { OnBootSec = "1min"; OnUnitActiveSec = "5min"; Persistent = true; }; }; }