From 70b3d92fb161faef0e1a1c423c5c0ff488c1eeb9 Mon Sep 17 00:00:00 2001 From: "Lennart J. Kurzweg (Nx2)" Date: Sun, 14 Jul 2024 02:14:19 +0200 Subject: [PATCH] update_namecheap in python --- sops-secrets.yaml | 6 ++- system-modules/nx2site.nix | 86 ++++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/sops-secrets.yaml b/sops-secrets.yaml index 8c55095..682d3c3 100644 --- a/sops-secrets.yaml +++ b/sops-secrets.yaml @@ -19,6 +19,8 @@ syncthing: key.pem: ENC[AES256_GCM,data:zFgSrZelmXgTAm0Zl0HSTp+M4tLOQzksdYnA1NZPeu4R+mxMylilEtHzMp9zE7urz5gadjUEiguDBkfTOIzFeSLeUlXBDBWJhXf5JPZ403HES11qlIFdW8BPkzVC3X0N0KyydLdfhM0MAhZdyrRxn1ATc0ppvyqTpeN1rxNYMHTezRH9WMmKC9VS506rCIZrfOtEsuBpsxP6tTjOQ9AxuWV1z6/DRjv55U2EojZ/viM6sjGSsuDAYZQJBA7VQcNsw4PZu49OfA0czo7FbE6Gh6+TJ9PdMOUuo2/syH4yPBC7vqMECIBN4MHzhyoOTqcyZHIV5iJsZqTIbTN+CP72pPPrhs/a5K0GkyT0PPHVem+dGhyAJWQglSAlcK8kXWDP,iv:pzQOoQvFqoC3nIuGLNx97cCE7qO+PHCVw9G4K1mX2nk=,tag:zXUch/o/B97TlgHhAYUveA==,type:str] weechat: passphrase: ENC[AES256_GCM,data:3NVhMouf3wwMJTZCvIjbi5fjHJHxe25Q+wRo,iv:W8cShdM3iUyEiRCPNupMin3gfF+cqGxslD18CAvUW4c=,tag:DXBATGEhHjhXqy+J9BNVwg==,type:str] +nx2site: + namecheap.pw: ENC[AES256_GCM,data:tN6ArfQu+YfVkPPN00raPZWmghDKVFmmGgwACVQQSHs=,iv:TlUl0L3+Ea9vt43lwDlM0SE1+CLvWJdryt1lFhQ+75I=,tag:pia2ORsm66AQUOE/ZiO8yA==,type:str] sops: kms: [] gcp_kms: [] @@ -61,8 +63,8 @@ sops: SHJLR3lvdlFiRmJuU25RUHFFTmpjamMKbzycdDvQBAuOiRROTZEQSnaXoPapz73L yVS9EUP25FSx/sGqRqaCefbeaybuM1aso6LDnlomv4Bib7zjugWKSw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-07-04T15:28:58Z" - mac: ENC[AES256_GCM,data:KTUyPeMc1OTQKJAMTGMnSWc44nkqRzvMk00o5LCiCVK9cq8Q5s3mtQave5ZsPyP8E5fJKp2wBikNJ6nbgrfLfHJhz0A5BdKkaELAQl3So7yDEl0oE3W4lS6Q5kIhpwBEabMzEU5E74FZ+9PcsUazb9MBU/Ngm3a+t6L5AIbiCE8=,iv:5p6eI2F5tqsfRE/0m8wP27HMsDky2cbV+D3syjq2aqU=,tag:8h+t7sKjX7uuo+IvilwAhg==,type:str] + lastmodified: "2024-07-13T23:01:06Z" + mac: ENC[AES256_GCM,data:K/ToZO4sX5l3lWpzB9AIfhQxag/eBF8B2vX9Yfa9ROWYxj+H2YfJQyA2GKCfkXv+h2H6wpKeHW2yiZAED5BKKjPkFG85u4yukWorlB1ozkzQTh7iRDGMVBs5Gj3Xe8GMYKMO/RzAmD6IYAC6kfrigqTIGNi+5p6I+WUf3E05CR0=,iv:bftIZe3R43V+MtpIygG6bHJdn1sFzAH3o1cpdESSvng=,tag:zMOwbk47LLMSfMCyEXAEkw==,type:str] pgp: - created_at: "2024-06-09T19:44:41Z" enc: |- diff --git a/system-modules/nx2site.nix b/system-modules/nx2site.nix index 5e6e416..ccf6a3f 100644 --- a/system-modules/nx2site.nix +++ b/system-modules/nx2site.nix @@ -1,6 +1,10 @@ -{ pkgs, lib, user, host, ... }: +{ config, pkgs, lib, user, host, ... }: lib.mkIf (host == "NxACE") { + sops.secrets = { + "nx2site/namecheap.pw" = { }; + }; + systemd = { timers."namecheap-dynamic-dns" = { wantedBy = [ "timers.target" ]; @@ -12,33 +16,63 @@ lib.mkIf (host == "NxACE") }; services."namecheap-dynamic-dns" = let - u = pkgs.writeScriptBin "update_namecheap" '' - my_ip=$(${pkgs.curl}/bin/curl -s https://ipinfo.io/ip) - dns_ip=$(${pkgs.dig}/bin/nslookup nx2.site | grep -E "Address: [0-9]" | cut -c 10-) - fdc="/home/nx2/nx2site/domain/count.txt" + u = let + domain = "nx2.site"; + passord-file-path = config.sops.secrets."nx2site/namecheap.pw".path; + log-file-path = "/var/log/update_namecheap.log"; + count-file-path = "/var/log/update_namecheap-count.txt"; + in + pkgs.writers.writePython3Bin "update_namecheap" { + libraries = with pkgs.python311Packages; [ + requests + ]; + flakeIgnore = [ "E501" "E305" "E701" "E704" "E302" "E114" "F841" ]; + } '' + import requests + import argparse + import socket + from datetime import datetime - force_update=false + def get_public_ip(): return requests.get('https://ipinfo.io/ip').text.strip() - while getopts "f" opt; do - case $opt in - f) - force_update=true - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - exit 1 - ;; - esac - done + def get_dns_ip(): return socket.gethostbyname_ex('${domain}')[2][0] - if [ "$force_update" == true ] || [ "$my_ip" != "$dns_ip" ]; then - count=$(<$fdc) - echo [ $count times ] $(date) from $dns_ip to $my_ip >> /home/nx2/nx2site/domain/updates.log - pw=$(cat /home/nx2/nx2site/domain/pw.txt) - ${pkgs.curl}/bin/curl -s "https://dynamicdns.park-your-domain.com/update?host=@&domain=nx2.site&password=$pw&ip=$my_ip" - ${pkgs.curl}/bin/curl -s "https://dynamicdns.park-your-domain.com/update?host=*&domain=nx2.site&password=$pw&ip=$my_ip" - echo 0 > $fdc - fi + def main(force_update): + my_ip = get_public_ip() + dns_ip = get_dns_ip() + + with open("${count-file-path}", "r") as f: + content = f.read() + if content == "": count = 0 + else: count = int(content) + count += 1 + with open("${count-file-path}", "w") as f: + f.write(str(count)) + + if not (force_update or my_ip != dns_ip): + print(f"Host IP and DNS response are both {my_ip} --> No Action") + exit(0) + else: + with open("${passord-file-path}", 'r') as pw_file: pw = pw_file.read().strip() + + # Perform DNS updates + resp_base = requests.get(f"https://dynamicdns.park-your-domain.com/update?host=@&domain=${domain}&password={pw}&ip={my_ip}") + resp_subd = requests.get(f"https://dynamicdns.park-your-domain.com/update?host=*&domain=${domain}&password={pw}&ip={my_ip}") + + # Reset the count file + with open("${count-file-path}", 'w') as f: f.write('0') + + now_str = datetime.now().strftime('%Y/%m/%d-%R') + log_entry = f"At {now_str} - from {dns_ip} to {my_ip} - {count} times - Response {resp_base.status_code}{' - (forced)' if force_update else ' '}\n" + print(log_entry, end="") + with open("${log-file-path}", 'a') as log_file: log_file.write(log_entry) + + if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--force', action='store_true', help='Force update') + args = parser.parse_args() + + main(args.force) ''; in { @@ -48,7 +82,7 @@ lib.mkIf (host == "NxACE") ''; serviceConfig = { Type = "oneshot"; - User = "nx2"; + # User = "nx2"; }; }; };