检查是否公网IP
检查 wan ip,如果不是公网ip,则重新拨号,确保公网ip可用
背景
在某处的宽带网络中,wan ip 有时不是公网ip,而是内网ip(100开头的号段),导致无法通过公网/DDNS访问。
因此,需要检查 wan ip,如果不是公网ip,则重新拨号。按照经验,一般拨号3-5次就大概率能获取到公网ip。
脚本实现
ssh 登录 openwrt 路由器,添加以下脚本:
vi /usr/bin/check_wan_ip.sh
内容为:
#!/bin/sh
# 日志文件路径
LOGFILE="/var/log/check_wan_ip.log"
# 日志大小上限(字节,10MB)
MAXSIZE=$((10 * 1024 * 1024))
# 检查日志文件大小,超过则轮转
if [ -f "$LOGFILE" ]; then
SIZE=$(stat -c%s "$LOGFILE")
if [ "$SIZE" -ge "$MAXSIZE" ]; then
mv "$LOGFILE" "$LOGFILE.1"
echo "$(date '+%F %T') Log rotated, old log moved to $LOGFILE.1" > "$LOGFILE"
fi
fi
# 开机宽限期(秒)
BOOT_GRACE=120
# 获取当前 WAN 接口的 IPv4 地址
IP=$(ifstatus wan | grep '"address"' | head -n1 | awk -F'"' '{print $4}')
# 定义日志函数(写入文件)
log() {
echo "$(date '+%F %T') $1" >> "$LOGFILE"
}
# 定义重拨函数
redial() {
log "Redialing wan..."
ifdown wan && sleep 5 && ifup wan
}
# 如果没取到 IP,检查启动时间
if [ -z "$IP" ]; then
UPTIME=$(cut -d. -f1 /proc/uptime)
if [ "$UPTIME" -lt "$BOOT_GRACE" ]; then
log "No IP yet, but system just booted ($UPTIME s), skipping check."
exit 0
else
log "No IP found on wan after $UPTIME s, redialing..."
redial
exit 0
fi
fi
# 判断是否为私网/CGNAT
is_private_ip() {
case $1 in
10.*) return 0 ;; # 10.0.0.0/8
192.168.*) return 0 ;; # 192.168.0.0/16
172.1[6-9].*|172.2[0-9].*|172.3[0-1].*) return 0 ;; # 172.16.0.0/12
100.6[4-9].*|100.7[0-9].*|100.8[0-9].*|100.9[0-5].*) return 0 ;; # 100.64.0.0/10
esac
return 1
}
if is_private_ip "$IP"; then
log "Got private/CGNAT IP ($IP) on wan"
redial
else
log "Got public IP ($IP) on wan, OK."
fi
增加执行权限:
chmod +x /usr/bin/check_wan_ip.sh
定期检查
设置每分钟检查一次:
crontab -e
添加以下内容:
*/1 * * * * /usr/bin/check_wan_ip.sh
保存并退出。确保 cron 服务已启用并运行:
/etc/init.d/cron enable
/etc/init.d/cron start
检查日志内容:
tail -f /var/log/check_wan_ip.log
如果获取到的是公网ip,会看到类似如下的内容:
2025-10-31 21:12:00 Got public IP (116.21.255.172) on wan, OK.
2025-10-31 21:13:00 Got public IP (116.21.255.172) on wan, OK.
2025-10-31 21:14:00 Got public IP (116.21.255.172) on wan, OK.
如果获取到的是私网ip,则会多次尝试拨号,直到获取到公网ip:
2025-10-31 21:27:00 Got private/CGNAT IP (100.95.147.166) on wan
2025-10-31 21:27:00 Redialing wan...
2025-10-31 21:28:00 Got private/CGNAT IP (100.95.155.241) on wan
2025-10-31 21:28:00 Redialing wan...
2025-10-31 21:29:00 Got private/CGNAT IP (100.95.143.37) on wan
2025-10-31 21:29:00 Redialing wan...
2025-10-31 21:30:00 Got private/CGNAT IP (100.95.143.37) on wan
2025-10-31 21:30:00 Redialing wan...
2025-10-31 21:31:00 Got public IP (49.84.144.173) on wan, OK.
2025-10-31 21:32:00 Got public IP (49.84.144.173) on wan, OK.