# -*- coding: utf-8 -*- r'''给服务器配上公共 DNS,让它能解析自己的域名。 == 问题 == Lightsail 默认用内网解析器 172.26.0.2: Current DNS Server: 172.26.0.2 dig @172.26.0.2 yk.xxmxxs.top -> 空 dig @1.1.1.1 yk.xxmxxs.top -> 104.21.54.45 ✅ dig @8.8.8.8 yk.xxmxxs.top -> 104.21.54.45 ✅ 用户刚加完 DNS 记录,公共解析器已经更新,但 Amazon 那个内网解析器 **还缓存着"这个域名不存在"**(负缓存,通常几分钟到一小时)。 后果不只是"监测误报"——任何在服务器上解析该域名的东西都会失败。 所以配上公共 DNS,既有 IPv4 也有 IPv6,并且让内网那个当后备 (内网解析器对 AWS 自家服务更快,留着有用)。 == 怎么配(Debian 13 + systemd-resolved)== /etc/systemd/resolved.conf.d/ 下放一个 drop-in: [Resolve] DNS=1.1.1.1 8.8.8.8 2606:4700:4700::1111 2606:4700:4700::1001 FallbackDNS=172.26.0.2 Domains=~. `Domains=~.` 表示"所有域名都用上面这些",把内网那个降为后备。 改完 `systemctl restart systemd-resolved` 生效。 == 为什么不直接改 /etc/resolv.conf == 它是指向 systemd-resolved stub(127.0.0.53)的软链接, 手改会被覆盖。要改就改 resolved 的配置。 ''' from __future__ import annotations import sys import tempfile from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT / "_build")) from lssh import run, upload # noqa: E402 DOMAIN = "yk.xxmxxs.top" CONF = '''# ykxmz:给这台服务器配上公共 DNS。 # # 起因:Lightsail 默认用内网解析器 172.26.0.2,而用户刚加的 # yk.xxmxxs.top 记录它**还缓存着"不存在"**(负缓存), # 导致服务器自己解析不了这个域名 —— 监测单元因此一直误报网站挂了。 # # 公共解析器(1.1.1.1 / 8.8.8.8)已经能正确解析,所以配上来。 # 内网解析器降为后备:它对 AWS 自家服务(比如实例元数据、 # S3 内网端点)响应更快,留着有用。 [Resolve] DNS=1.1.1.1 8.8.8.8 2606:4700:4700::1111 2606:4700:4700::1001 FallbackDNS=172.26.0.2 # 所有域名都用上面这些(内网那个只在全部失败时才用) Domains=~. # 顺便开一下 DNSSEC 校验 DNSSEC=allow-downgrade DNSOverTLS=no Cache=yes ''' def main() -> int: print("=" * 62) print(" 给服务器配公共 DNS") print("=" * 62) print() print(" ── 1. 写 drop-in 配置 ──") run("sudo mkdir -p /etc/systemd/resolved.conf.d", timeout=120, quiet=True) tmp = Path(tempfile.gettempdir()) / "ykxmz-dns.conf" tmp.write_text(CONF, encoding="utf-8", newline="\n") upload(str(tmp), "/tmp/ykxmz-dns.conf") out = run("sudo mv /tmp/ykxmz-dns.conf /etc/systemd/resolved.conf.d/ykxmz.conf " "&& echo ' 已装'", timeout=120, quiet=True) for ln in out[1].strip().splitlines(): print(" " + ln) print() print(" ── 2. 重启 systemd-resolved ──") out = run("sudo systemctl restart systemd-resolved; sleep 3; " "systemctl is-active systemd-resolved; " "echo ' --- 现在用的 DNS ---'; " "resolvectl status 2>/dev/null | grep -E 'DNS Servers|Fallback|Current DNS' " "| head -6", timeout=180, quiet=True) for ln in out[1].strip().splitlines(): print(" " + ln) print() print(" ── 3. 刷新缓存 + 验证解析 ──") out = run("sudo resolvectl flush-caches 2>/dev/null; " "echo ' getent:'; getent hosts %s | sed 's/^/ /'; " "echo ' dig 默认:'; dig +short +time=5 %s | sed 's/^/ /'; " "echo ' python:'; python3 -c \"import socket;" "print(' ', [a[4][0] for a in socket.getaddrinfo('%s',443)])\"" % (DOMAIN, DOMAIN, DOMAIN), timeout=180, quiet=True) for ln in out[1].strip().splitlines(): print(" " + ln) print() print(" ── 4. curl 域名(监测单元就是这么查的)──") out = run( "printf ' %-30s %s\\n' 'https 域名' " "\"$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 " "https://%s/v1/health)\"; " "printf ' %-30s %s\\n' 'http 域名(会 301)' " "\"$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 " "http://%s/v1/health)\"; " "printf ' %-30s %s\\n' 'https 域名 -L(跟跳转)' " "\"$(curl -sL -o /dev/null -w '%{http_code}' --max-time 15 " "https://%s/v1/health)\"; " "printf ' %-30s %s\\n' '中转本机' " "\"$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 " "http://127.0.0.1:13245/v1/health)\"" % (DOMAIN, DOMAIN, DOMAIN), timeout=180, quiet=True) for ln in out[1].strip().splitlines(): print(ln) print() print(" ── 5. 重跑监测 ──") run("printf 'fails=0\\nlast_rescue=0\\n' > " "/opt/ykxmz-relay/monitor_state.txt", timeout=60, quiet=True) run("bash /opt/ykxmz-relay/monitor.sh", timeout=180, quiet=True) out = run("cat /opt/ykxmz-relay/monitor_state.txt", timeout=60, quiet=True) for ln in out[1].strip().splitlines(): print(" " + ln) return 0 if __name__ == "__main__": sys.exit(main())