# 在OpenWrt路由上自动监控博客能否访问与IP优选脚本教程

杨公子 2026-08-21 13:09 1

博客自动监控与IP优选脚本教程


一、背景介绍


在维护个人博客时,我们经常会遇到以下问题:



  • Cloudflare IP被限制访问

  • 服务器IP被屏蔽

  • CDN节点故障导致访问缓慢或无法访问

  • 网络线路波动影响用户体验


为了解决这些问题,我编写了一个自动化监控和IP优选脚本,当博客无法访问时自动执行IP优选操作,确保博客始终可访问。

此教程配合saas来实现,其中RECORD_NAME为回源域名


二、脚本功能


2.1 核心功能



  1. 自动监控:每5分钟检测博客是否可访问

  2. 智能IP优选:检测到异常时自动执行IP优选脚本

  3. Cloudflare管理:自动检查和修正CNAME记录

  4. 多重策略:执行2次IP优选后自动切换备用CNAME

  5. 详细日志:记录所有操作和诊断信息


2.2 工作流程


博客监控 → 检测到异常 → 第1次执行IP优选 → 等待5分钟

再次检测 → 仍然异常 → 第2次执行IP优选 → 等待5分钟

再次检测 → 仍然异常 → 切换CNAME记录 → 等待DNS生效

再次检测 → 恢复正常或记录错误

三、环境准备


3.1 系统要求



  • OpenWrt / Linux 系统

  • 安装 curl、nslookup、nc 等工具

  • Cloudflare API访问权限


3.2 获取Cloudflare API信息




  1. 登录Cloudflare控制台




  2. 获取API Key



    • 点击右上角头像 → "我的个人资料"

    • 选择"API令牌" → "创建令牌"

    • 选择"编辑区域DNS"模板

    • 生成令牌并保存




  3. 获取Zone ID



    • 在域名概览页面右侧找到"区域ID"

    • 复制保存




3.3 准备IP优选脚本


创建 /root/cu.sh 作为IP优选脚本:


#!/bin/bash
# Cloudflare优选IP脚本
# 功能:自动测试并选择最优的Cloudflare IP

# 示例代码框架
echo "开始IP优选..."
# 这里填写您的IP优选逻辑
# 例如:从IP池中选择最优IP并更新DNS

四、脚本详解


4.1 完整脚本代码


#!/bin/sh

# ==================== 配置区 ====================
URL="https://yourblog.com" # 监控的网站(请替换为您的博客地址)
TIMEOUT=30 # 超时时间(秒)
MAX_RETRY=2 # 重试次数
YX_SCRIPT="/root/cu.sh" # IP优选脚本路径
LOG_FILE="/var/log/blog_monitor.log" # 日志文件
LOCK_FILE="/tmp/blog_monitor.lock" # 锁文件
RETRY_COUNT_FILE="/tmp/cu_retry_count.txt" # IP优选次数计数文件

# Cloudflare API配置
CF_API_KEY="your_cloudflare_api_key" # 请替换为您的Cloudflare API Key
CF_EMAIL="[email protected]" # 请替换为您的Cloudflare邮箱
ZONE_ID="your_zone_id" # 请替换为您的Zone ID
RECORD_NAME="cname.example.com" # 要管理的DNS记录(请替换为您的CNAME记录)
EXPECTED_TARGET="target1.example.com" # 期望的CNAME值(请替换为您的首选目标)
FALLBACK_TARGET="target2.example.com" # 备用CNAME值(请替换为您的备选目标)
# ==================== 配置结束 ====================

# 日志函数
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}

# 重置IP优选次数计数
reset_retry_count() {
echo "0" > "$RETRY_COUNT_FILE"
log "已重置IP优选次数计数"
}

# 获取当前IP优选次数
get_retry_count() {
if [ -f "$RETRY_COUNT_FILE" ]; then
cat "$RETRY_COUNT_FILE"
else
echo "0"
fi
}

# 增加IP优选次数
increment_retry_count() {
local current=$(get_retry_count)
local new=$((current + 1))
echo "$new" > "$RETRY_COUNT_FILE"
echo "$new"
}

# 获取当前CNAME记录值
get_current_cname() {
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME&type=CNAME" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_API_KEY" \
-H "Content-Type: application/json" | grep -o '"content":"[^"]*"' | head -1 | cut -d'"' -f4
}

# 获取记录ID
get_record_id() {
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME&type=CNAME" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_API_KEY" \
-H "Content-Type: application/json" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4
}

# 修改Cloudflare CNAME记录
update_cloudflare_cname() {
local target_value="$1"
log "开始修改Cloudflare CNAME记录: $RECORD_NAME -> $target_value"

RECORD_ID=$(get_record_id)

if [ -z "$RECORD_ID" ]; then
log "错误: 无法获取 $RECORD_NAME 的记录ID"
return 1
fi

log "获取到记录ID: $RECORD_ID"

UPDATE_RESULT=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"type\":\"CNAME\",\"name\":\"$RECORD_NAME\",\"content\":\"$target_value\",\"ttl\":120,\"proxied\":false}")

if echo "$UPDATE_RESULT" | grep -q '"success":true'; then
log "Cloudflare CNAME记录更新成功: $RECORD_NAME -> $target_value"
return 0
else
log "Cloudflare CNAME记录更新失败: $UPDATE_RESULT"
return 1
fi
}

# 检查并修正CNAME记录
ensure_correct_cname() {
log "检查 $RECORD_NAME 的CNAME记录..."
CURRENT_CNAME=$(get_current_cname)

if [ -z "$CURRENT_CNAME" ]; then
log "警告: 无法获取当前CNAME记录,尝试创建新的记录"
CREATE_RESULT=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"type\":\"CNAME\",\"name\":\"$RECORD_NAME\",\"content\":\"$EXPECTED_TARGET\",\"ttl\":120,\"proxied\":false}")

if echo "$CREATE_RESULT" | grep -q '"success":true'; then
log "成功创建CNAME记录: $RECORD_NAME -> $EXPECTED_TARGET"
return 0
else
log "创建CNAME记录失败: $CREATE_RESULT"
return 1
fi
elif [ "$CURRENT_CNAME" != "$EXPECTED_TARGET" ]; then
log "当前CNAME值: $CURRENT_CNAME (不符合预期)"
log "将更新为: $EXPECTED_TARGET"
update_cloudflare_cname "$EXPECTED_TARGET"
return $?
else
log "CNAME记录正确: $RECORD_NAME -> $EXPECTED_TARGET ✓"
return 0
fi
}

# 获取当前CNAME解析结果
get_current_resolve() {
nslookup "$RECORD_NAME" 2>/dev/null | grep -A1 "Name:" | tail -n1 | awk '{print $2}'
}

# 网站访问检查
check_access() {
for i in $(seq 1 $MAX_RETRY); do
RESPONSE=$(curl -sLk -w "\n%{http_code}" --connect-timeout $TIMEOUT "$URL" 2>&1)
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | head -n -1)

if echo "$BODY" | grep -q "Cloudflare\|Error 1034\|Edge IP Restricted"; then
log "检测到Cloudflare错误: Edge IP Restricted"
return 2
fi

if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 400 ]; then
return 0
elif [ "$HTTP_CODE" = "403" ] && echo "$BODY" | grep -q "Cloudflare"; then
log "Cloudflare阻止访问 (HTTP 403)"
return 3
fi

log "第${i}次检测失败,HTTP状态码: $HTTP_CODE"
sleep 3
done
return 1
}

# 执行IP优选脚本
run_optimize_script() {
# 先确保CNAME正确
ensure_correct_cname

if [ -x "$YX_SCRIPT" ]; then
log "执行IP优选脚本: $YX_SCRIPT"
"$YX_SCRIPT" >> "$LOG_FILE" 2>&1
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
log "IP优选脚本执行成功"
return 0
else
log "IP优选脚本执行失败,退出码: $EXIT_CODE"
return 1
fi
else
log "错误: IP优选脚本 $YX_SCRIPT 不存在或不可执行"
return 1
fi
}

# 网络诊断
diagnose_network() {
log "========== 开始网络诊断 =========="

CURRENT_IP=$(get_current_resolve)
log "当前 $RECORD_NAME 解析到: $CURRENT_IP"

SITE_IP=$(nslookup ${URL#https://} 2>/dev/null | grep -A1 "Name:" | tail -n1 | awk '{print $2}')
log "${URL#https://} 解析到: $SITE_IP"

CURRENT_CNAME=$(get_current_cname)
log "Cloudflare中 $RECORD_NAME 的CNAME值: $CURRENT_CNAME"

if [ -n "$CURRENT_IP" ]; then
PING_RESULT=$(ping -c 3 -W 2 "$CURRENT_IP" 2>&1)
if echo "$PING_RESULT" | grep -q "0% packet loss"; then
log "Ping $CURRENT_IP 成功"
else
log "Ping $CURRENT_IP 失败"
fi
fi

if [ -n "$CURRENT_IP" ]; then
PORT_CHECK=$(nc -zv -w 3 "$CURRENT_IP" 443 2>&1)
if echo "$PORT_CHECK" | grep -q "succeeded\|Connected"; then
log "端口443连接成功"
else
log "端口443连接失败"
fi
fi

log "========== 网络诊断结束 =========="
}

# ==================== 主程序 ====================

# 检查锁文件
if [ -f "$LOCK_FILE" ] && [ $(find "$LOCK_FILE" -mmin -5 2>/dev/null) ]; then
log "IP优选脚本已在执行中(5分钟内),跳过本次检测"
exit 0
fi

# 执行检测
check_access
RETURN_CODE=$?

case $RETURN_CODE in
0)
log "博客可正常访问 ✓"
reset_retry_count
;;
2|3)
touch "$LOCK_FILE"
RETRY_COUNT=$(increment_retry_count)
log "检测到Cloudflare错误 (当前已执行第${RETRY_COUNT}次IP优选)"

if [ "$RETRY_COUNT" -ge 2 ]; then
log "【重要】已执行IP优选两次,网站仍无法访问"
diagnose_network

log "确保CNAME记录为 $EXPECTED_TARGET"
ensure_correct_cname

sleep 10
log "检查CNAME修正后网站是否恢复..."
check_access
if [ $? -eq 0 ]; then
log "修正CNAME后网站恢复访问 ✓"
reset_retry_count
else
log "修正CNAME后网站仍无法访问,尝试备用方案: $FALLBACK_TARGET"
update_cloudflare_cname "$FALLBACK_TARGET"
reset_retry_count
sleep 30

NEW_IP=$(get_current_resolve)
log "DNS更新后,$RECORD_NAME 解析到: $NEW_IP"

check_access
if [ $? -eq 0 ]; then
log "切换到备用CNAME后网站恢复访问 ✓"
else
log "所有IP优选方案均失败,请手动检查配置"
diagnose_network
fi
fi
else
log "第一次执行IP优选,先确保CNAME正确"
ensure_correct_cname
run_optimize_script
fi
rm -f "$LOCK_FILE"
;;
*)
touch "$LOCK_FILE"
RETRY_COUNT=$(increment_retry_count)
log "博客无法访问 (当前已执行第${RETRY_COUNT}次IP优选)"

if [ "$RETRY_COUNT" -ge 2 ]; then
diagnose_network
ensure_correct_cname
sleep 10
check_access
if [ $? -eq 0 ]; then
log "修正CNAME后网站恢复访问 ✓"
reset_retry_count
else
log "修正CNAME后网站仍无法访问,尝试备用方案: $FALLBACK_TARGET"
update_cloudflare_cname "$FALLBACK_TARGET"
reset_retry_count
sleep 30
check_access
if [ $? -eq 0 ]; then
log "切换到备用CNAME后网站恢复访问 ✓"
else
log "所有IP优选方案均失败,请手动检查"
diagnose_network
fi
fi
else
ensure_correct_cname
run_optimize_script
fi
rm -f "$LOCK_FILE"
;;
esac

4.2 配置说明






























































配置项 说明 示例
URL 监控的网站地址 https://yourblog.com
TIMEOUT 请求超时时间 30秒
MAX_RETRY 检测失败重试次数 2次
YX_SCRIPT IP优选脚本路径 /root/cu.sh
CF_API_KEY Cloudflare API密钥 从Cloudflare获取
CF_EMAIL Cloudflare账户邮箱 [email protected]
ZONE_ID 域名区域ID 从Cloudflare获取
RECORD_NAME 要管理的DNS记录 cname.example.com
EXPECTED_TARGET 期望的CNAME值 target1.example.com
FALLBACK_TARGET 备用CNAME值 target2.example.com

五、部署步骤


5.1 上传脚本


# 创建监控脚本
vi /root/blog_monitor.sh

# 粘贴脚本内容并保存
# 修改配置参数(URL、API密钥、域名等)

# 赋予执行权限
chmod +x /root/blog_monitor.sh

# 创建IP优选脚本(示例)
vi /root/cu.sh
chmod +x /root/cu.sh

5.2 测试运行


# 手动执行测试
/root/blog_monitor.sh

# 查看日志
tail -f /var/log/blog_monitor.log

5.3 设置定时任务


使用crontab设置每5分钟执行一次:


# 编辑crontab
crontab -e

# 添加以下行
*/5 * * * * /root/blog_monitor.sh

# 查看定时任务
crontab -l

5.4 OpenWrt特定设置


如果使用OpenWrt,可以使用其内置的定时任务:


# 编辑OpenWrt定时任务
vi /etc/crontabs/root

# 添加
*/5 * * * * /root/blog_monitor.sh

# 重启cron服务
/etc/init.d/cron restart

六、监控与维护


6.1 查看日志


# 实时查看日志
tail -f /var/log/blog_monitor.log

# 查看最近100行
tail -100 /var/log/blog_monitor.log

# 搜索IP优选相关记录
grep "IP优选" /var/log/blog_monitor.log

# 搜索错误
grep "错误" /var/log/blog_monitor.log

6.2 手动干预


# 查看当前IP优选次数
cat /tmp/cu_retry_count.txt

# 手动重置计数
echo "0" > /tmp/cu_retry_count.txt

# 手动触发检测
/root/blog_monitor.sh

# 手动执行IP优选
/root/cu.sh

6.3 常见问题处理


问题1:脚本无法执行


# 检查权限
ls -l /root/blog_monitor.sh

# 添加执行权限
chmod +x /root/blog_monitor.sh

问题2:Cloudflare API认证失败


# 测试API连接
curl -X GET "https://api.cloudflare.com/client/v4/zones" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: your_api_key" \
-H "Content-Type: application/json"

问题3:IP优选脚本执行失败


# 检查IP优选脚本是否存在
ls -l /root/cu.sh

# 手动测试IP优选脚本
/root/cu.sh

# 查看IP优选脚本错误输出
/root/cu.sh 2>&1

问题4:DNS解析延迟


# 刷新DNS缓存
/etc/init.d/dnsmasq restart

# 或使用OpenWrt命令
/etc/init.d/dnsmasq reload

# 验证DNS解析
nslookup cname.example.com

七、IP优选脚本示例


7.1 基础IP优选脚本


#!/bin/bash
# /root/cu.sh - 基础IP优选脚本

# Cloudflare优选IP列表(示例IP,请替换为实际IP池)
IPS=(
"104.16.0.0"
"104.17.0.0"
"104.18.0.0"
"104.19.0.0"
"104.20.0.0"
)

# 测试延迟
test_latency() {
local ip=$1
local latency=$(ping -c 3 -W 2 "$ip" 2>/dev/null | grep "avg" | awk -F'/' '{print $5}')
echo "$latency"
}

# 选择最优IP
best_ip=""
best_latency=9999

for ip in "${IPS[@]}"; do
latency=$(test_latency "$ip")
if [ -n "$latency" ] && [ $(echo "$latency < $best_latency" | bc) -eq 1 ]; then
best_latency=$latency
best_ip=$ip
fi
done

if [ -n "$best_ip" ]; then
echo "优选IP: $best_ip, 延迟: ${best_latency}ms"
# 更新DNS记录(请根据实际情况修改)
# curl -X PUT "https://api.cloudflare.com/..." -d "{\"content\":\"$best_ip\"}"
else
echo "未找到可用IP"
exit 1
fi

7.2 高级IP优选脚本


#!/bin/bash
# /root/cu.sh - 高级IP优选脚本

# 从多个来源获取IP池
get_ip_pool() {
# 从配置文件或网络获取
curl -s "https://api.example.com/cf-ips" | jq -r '.ips[]' 2>/dev/null || echo "104.16.0.0 104.17.0.0"
}

# 测试响应时间
test_response() {
local ip=$1
curl -s -o /dev/null -w "%{time_total}" --connect-timeout 3 "http://$ip" 2>/dev/null
}

# 多维度评分
score_ip() {
local ip=$1
local latency=$(test_response "$ip")
local loss=$(ping -c 10 -W 2 "$ip" 2>/dev/null | grep -o "[0-9]\+% packet loss" | grep -o "[0-9]\+")
loss=${loss:-100}

# 评分逻辑:延迟低、丢包少的IP得分高
if [ -n "$latency" ]; then
score=$(echo "scale=2; 100 - $latency*10 - $loss/10" | bc 2>/dev/null || echo "0")
echo "$score"
else
echo "0"
fi
}

# 主逻辑
echo "开始IP优选..."
# 具体实现...

八、性能优化建议


8.1 监控频率优化


根据实际情况调整监控频率:



  • 稳定期:每10分钟检测一次

  • 不稳定期:每3分钟检测一次


# 在crontab中设置不同频率
*/10 * * * * /root/blog_monitor.sh # 稳定期
*/3 * * * * /root/blog_monitor.sh # 不稳定期

8.2 IP池优化



  • 定期更新IP池数据

  • 使用CDN服务商提供的官方IP列表

  • 加入地域性IP分组


8.3 日志管理


# 添加日志轮转
cat > /etc/logrotate.d/blog_monitor << EOF
/var/log/blog_monitor.log {
weekly
rotate 4
compress
missingok
notifempty
}
EOF


九、注意事项



  1. API密钥安全:不要将包含API密钥的脚本提交到公开仓库

  2. 频率控制:IP优选频率不要太频繁,避免被误认为攻击

  3. 备份配置:定期备份Cloudflare DNS配置

  4. 测试环境:先在测试环境验证脚本功能

  5. 监控告警:建议配置告警通知,及时了解异常情况

  6. IP池更新:定期更新IP优选池,保证有效性


十、总结


通过这个自动化监控和IP优选脚本,我们可以:



  • 实时监控博客可用性

  • 自动执行IP优选操作

  • 智能管理DNS记录

  • 详细记录所有操作


这套方案大大减少了手动运维的工作量,让博客更加稳定可靠。IP优选策略能够有效应对网络波动和IP限制问题,确保访客始终能够访问到最优的节点。


十一、参考资源



  • Cloudflare API文档

  • OpenWrt crontab文档

  • Shell脚本编程指南

  • Cloudflare优选IP工具




更新日期:2026年8月21日

脚本版本:v2.0

适用环境:OpenWrt/Linux

标签:#博客监控 #IP优选 #Cloudflare #自动化运维

最新回复 (0)
    没有回复
* 帖子来源NodeSeek
返回