From df4ae026e93951ca89efd24894920ebf4d92f409 Mon Sep 17 00:00:00 2001 From: Marsell Kukuljevic Date: Fri, 19 Dec 2025 15:58:18 +0100 Subject: [PATCH] Update domain expiry plugin to use RDAP too, not just whois. --- domains/domain_checks-0.2.0.mkp | Bin 4376 -> 0 bytes domains/domain_checks-0.3.0.mkp | Bin 0 -> 4972 bytes .../domains/libexec/agent_domains_expiry | 62 +++++++++++++++--- 3 files changed, 52 insertions(+), 10 deletions(-) delete mode 100755 domains/domain_checks-0.2.0.mkp create mode 100755 domains/domain_checks-0.3.0.mkp diff --git a/domains/domain_checks-0.2.0.mkp b/domains/domain_checks-0.2.0.mkp deleted file mode 100755 index 432f5c44d9d998145b453d09ca976f40e326022d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4376 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 DWq+H5 diff --git a/domains/domain_checks-0.3.0.mkp b/domains/domain_checks-0.3.0.mkp new file mode 100755 index 0000000000000000000000000000000000000000..da34c12080b84cdb6120107294483b10d2b992e4 GIT binary patch literal 4972 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 " 1>&2 @@ -14,15 +14,58 @@ domains="${@: 1:$#-2}" warn="${@: -1:1}" crit="${@: -2:1}" + +# Attempt lookup of domain name expiration using whois. +# +# Unfortunately, there's no actual format for whois entries, so this is a +# best-effort based on things seen in the wild. Note that ccTLDs usually do not +# publish expiry dates at all. +whois_domain() { + whois "$1" | grep 'Expir.*' | head -1 | grep -Eo '[0-9]{4}-[0-9]{2}-[0-9]{2}' +} + +# Attempt lookup of domain name expiration using RDAP. +# +# Unfortunately, RDAP tools are still relatively new and not available in many +# repos, so we do the lookup manually using curl. There's a two-step process: +# +# * look up (and cache) dns info from IANA. +# * using the info from IANA, query the TLD for the domain +# +# Also, as of 2025, RDAP is useful with gTLDs and about 1/3rd of ccTLDs. +rdap_domain() { + dns_file="$HOME/tmp/agent_domains_expiry.json" + domain="$1" + tld="${domain##*.}" # get TLD off end of $domain + + # Only attempt to fetch the file if it's older than 24h (or doesn't exist) + if [[ ! -f "$dns_file" ]] || [[ -n $(find "$dns_file" -mtime +0 2>/dev/null) ]]; then + # We do an conditional GET, using the file's timestamp + curl --silent \ + --time-cond "$dns_file" \ + --output "$dns_file" \ + "https://data.iana.org/rdap/dns.json" + fi + + registrar=$(jq -r '.services[] | select(.[0][] == "'"$tld"'") | .[1][0]' "$dns_file" 2> /dev/null) + + if [[ "$registrar" != "" ]]; then + curl -s "${registrar}domain/${domain}" | + jq -r '.events[] | select(.eventAction == "expiration") | .eventDate' 2> /dev/null | + grep -Eo '[0-9]{4}-[0-9]{2}-[0-9]{2}' + fi +} + + echo "<<>>" for domain in $domains; do - echo -n "{\"domain\": \"$domain\", \"state\": \"" + expires=$(rdap_domain "$domain" || true) + if [[ "$expires" == "" ]]; then + expires=$(whois_domain "$domain" || true) + fi - # Unfortunately, there's no actual format for whois entries, so this is a - # best-effort based on things seen in the wild. Note that ccTLDs usually - # do not publish expiry dates at all. - expires=$(whois "$domain" | grep 'Expir.*' | head -1 | grep -Eo '[0-9]{4}-[0-9]{2}-[0-9]{2}' || true) + echo -n "{\"domain\": \"$domain\", \"state\": \"" if [[ "$expires" == "" ]]; then echo -n "UNKNOWN" @@ -34,9 +77,8 @@ for domain in $domains; do echo -n "OK" fi - if [[ "$expires" == "" ]]; then - echo "\"}" - else - echo "\", \"expires\": \"$expires\"}" + if [[ "$expires" != "" ]]; then + echo -n "\", \"expires\": \"$expires" fi + echo "\"}" done