外网IP变更检测脚本

代码脚本 · 网络

检测服务器外网IP是否发生变化,IP变更时自动发送告警,支持调用DDNS接口更新域名解析,适用于动态IP家庭宽带/小运营商场景

详细内容

#!/bin/bash # ========================================== # 外网IP变更检测脚本 # 用途:检测外网IP变化,变更时告警并更新DDNS # 使用方法:加入crontab每5分钟执行一次 # ========================================== # ========== 配置 ========== IP_FILE="/tmp/current_public_ip.txt" LOG_FILE="/var/log/ip_change_monitor.log" ALERT_EMAIL="" WECOM_WEBHOOK="" # DDNS配置(支持阿里云DNS,留空则不更新) DDNS_ENABLE=false DDNS_PROVIDER="aliyun" # aliyun / cloudflare / dnspod DDNS_DOMAIN="" # 要更新的域名,如 home.example.com ALIYUN_ACCESS_KEY="" # 阿里云AccessKey ALIYUN_SECRET_KEY="" # 阿里云SecretKey # ========================== mkdir -p "$(dirname "$LOG_FILE")" log_msg() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } send_alert() { local title="$1" local content="$2" log_msg "【告警】$title: $content" if [ -n "$ALERT_EMAIL" ]; then echo -e "$content" | mail -s "【IP变更】$title" "$ALERT_EMAIL" 2>/dev/null fi if [ -n "$WECOM_WEBHOOK" ]; then curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{ "msgtype": "text", "text": {"content": "【IP变更告警】$title\n$content\n主机: $(hostname)"} }" >/dev/null 2>&1 fi } get_public_ip() { # 多个源依次尝试,提高可靠性 local ip="" local sources=( "https://api.ipify.org" "https://ifconfig.me" "https://icanhazip.com" "https://ipinfo.io/ip" "http://members.3322.org/dyndns/getip" ) for url in "${sources[@]}"; do ip=$(curl -s --connect-timeout 5 --max-time 10 "$url" 2>/dev/null | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | head -1) if [ -n "$ip" ]; then echo "$ip" return 0 fi done return 1 } update_aliyun_ddns() { local new_ip="$1" log_msg "正在更新阿里云DDNS: $DDNS_DOMAIN -> $new_ip" # 阿里云DNS API调用(简化版,实际使用需签名) # 这里提供一个基础框架,完整实现需要阿里云API签名 log_msg "阿里云DDNS更新需要完整API签名,请参考阿里云DNS API文档" # 实际生产环境建议使用 aliddns 工具或现成的DDNS客户端 } update_ddns() { local new_ip="$1" if [ "$DDNS_ENABLE" != true ]; then return fi case "$DDNS_PROVIDER" in aliyun) update_aliyun_ddns "$new_ip" ;; *) log_msg "暂不支持的DDNS服务商: $DDNS_PROVIDER" ;; esac } # 获取当前外网IP CURRENT_IP=$(get_public_ip) if [ -z "$CURRENT_IP" ]; then log_msg "❌ 无法获取外网IP,请检查网络连接" send_alert "无法获取外网IP" "所有IP查询源均失败,请检查服务器网络连接" exit 1 fi log_msg "当前外网IP: $CURRENT_IP" # 读取上次记录的IP if [ -f "$IP_FILE" ]; then OLD_IP=$(cat "$IP_FILE") else OLD_IP="" fi # 对比IP是否变化 if [ "$CURRENT_IP" = "$OLD_IP" ]; then log_msg "✅ 外网IP未变化" exit 0 fi # IP发生变化 if [ -z "$OLD_IP" ]; then log_msg "📝 首次记录外网IP: $CURRENT_IP" else log_msg "⚠️ 外网IP发生变化!" log_msg " 旧IP: $OLD_IP" log_msg " 新IP: $CURRENT_IP" send_alert "外网IP已变更" "外网IP发生变化!\n旧IP: $OLD_IP\n新IP: $CURRENT_IP\n变更时间: $(date '+%Y-%m-%d %H:%M:%S')\n\n如果使用了IP白名单或端口映射,请及时更新。" # 更新DDNS update_ddns "$CURRENT_IP" fi # 保存当前IP echo "$CURRENT_IP" > "$IP_FILE" log_msg "✅ 已保存新IP到 $IP_FILE"

适配环境

适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+

依赖环境:bash 4.0+

参数说明

[{"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}, {"name": "WECOM_WEBHOOK", "label": "\u4f01\u4e1a\u5fae\u4fe1Webhook(\u53ef\u9009)", "default": ""}, {"name": "DDNS_ENABLE", "label": "\u662f\u5426\u542f\u7528DDNS\u66f4\u65b0(true/false)", "default": "false"}, {"name": "DDNS_DOMAIN", "label": "DDNS\u57df\u540d(\u53ef\u9009)", "default": ""}]
外网IP动态IPDDNS变更检测告警

更多网络