#!/bin/bash # sync-nginx-local-ips.sh # 自动维护 nginx 本机公网 IP 直连规则(/etc/nginx/local_ip_rules.conf): # 出站公网 IP(ipify)+ iam.aeolianchi.me 的 A 记录 = 本机当前公网 IP 集合。 # 公网 IP 变更时重写规则文件并 reload nginx(仅变更时 reload)。 # 由 /etc/cron.d/sync-nginx-local-ips 每 5 分钟调用一次。 set -u PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin RULES=/etc/nginx/local_ip_rules.conf DOMAIN=iam.aeolianchi.me ips="" # 出站公网 IP out=$(curl -s --max-time 8 https://api.ipify.org 2>/dev/null | tr -dc '0-9.') # 域名 A 记录(入站公网 IP) dns=$(getent ahostsv4 "$DOMAIN" 2>/dev/null | awk 'NR==1{print $1}') for ip in "$out" "$dns"; do case "$ip" in ''|*[!0-9.]*) continue ;; esac case "|$ips|" in *"|$ip|"*) ;; *) ips="${ips}|${ip}" ;; esac done tmp="$RULES.tmp" { echo "# nginx 本机公网 IP 直连规则(自动生成,勿手改;由 sync-nginx-local-ips.sh 维护)" echo "# 公网 IP 变更后本文件会被重写并 reload nginx" IFS='|' for ip in $ips; do [ -n "$ip" ] && echo "if (\$host = \"$ip\") { rewrite ^(.*)\$ /__local\$1 last; }" done unset IFS } > "$tmp" if ! cmp -s "$RULES" "$tmp"; then mv "$tmp" "$RULES" if nginx -t >/dev/null 2>&1; then systemctl reload nginx logger -t sync-nginx-local-ips "nginx local-IP rules updated: [${ips#|}]" else logger -t sync-nginx-local-ips "nginx -t FAILED, rules NOT applied; keeping previous rules" rm -f "$tmp" fi else rm -f "$tmp" fi