#!/usr/bin/env bash # Read-only. Usage: sudo bash check-automatic-renewal.sh apache example.com set -euo pipefail [[ $# == 2 && ( $1 == apache || $1 == nginx ) ]] || { echo 'Usage: bash check-automatic-renewal.sh apache|nginx example.com' >&2;exit 2; } python3 - "$1" "$2" <<'PY' import ipaddress,json,os,pathlib,re,socket,subprocess,sys server,host=sys.argv[1:] if len(host)>253 or not re.fullmatch(r'(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z][A-Za-z0-9-]{1,62}',host):raise SystemExit('Use one DNS hostname without a wildcard,scheme,port or path') values={} for line in pathlib.Path('/etc/os-release').read_text().splitlines(): if '=' in line: k,v=line.split('=',1);values[k]=v.strip('"') platform=values.get('ID')=='ubuntu' and values.get('VERSION_ID')=='24.04' def run(args): try: p=subprocess.run(args,capture_output=True,text=True,timeout=10);return p.returncode,p.stdout+p.stderr except (FileNotFoundError,subprocess.TimeoutExpired):return 1,'' code,version=run(['apache2ctl','-v'] if server=='apache' else ['nginx','-v']) supported=code==0 and ('Apache/2.4.' in version if server=='apache' else 'nginx/1.24.' in version) try:addresses=sorted({x[4][0] for x in socket.getaddrinfo(host,None)}) except socket.gaierror:addresses=[] _,ports=run(['ss','-ltn']);http80=any(re.search(r':80\s',line) for line in ports.splitlines()) try:systemd=pathlib.Path('/proc/1/comm').read_text().strip()=='systemd' except OSError:systemd=False public_dns=bool(addresses) and all(ipaddress.ip_address(x).is_global for x in addresses) client_code,client=run(['certbot','--version']) print(json.dumps({'Mode':'Read-only','Server':server,'Hostname':host,'Administrator':os.geteuid()==0,'TestedOperatingSystem':platform,'TestedServerVersion':supported,'Version':version.strip(),'Systemd':systemd,'Http80Listener':http80,'DnsAddresses':addresses,'PublicDnsConfigured':public_dns,'NativeClientInstalled':client_code==0,'NativeClientVersion':client.strip(),'PrerequisitesReady':os.geteuid()==0 and platform and supported and systemd and http80 and public_dns,'ExternalValidationStillRequired':True,'Scope':'Ubuntu24.04 Apache2.4/Nginx1.24 HTTP-01 prerequisites only. Does not prove external firewall/proxy reachability or renewal installation.','Unsupported':'Wildcard DNS APIs,managed hosting,containers,other versions and unusual proxies require review.','ChangedSettings':False,'UploadedData':False},indent=2)) PY