目录
1. 脚本功能设计
1.1 核心脚本 <code>/usr/share/scripts/ddns.sh</code>
#!/bin/bash
# 日志功能增强版 - 赵峰伟 2025-12-18
LOG_FILE="/var/log/ddns_update.log"
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$TIMESTAMP] DDNS更新启动" >> $LOG_FILE
# 花生壳更新
oray_result=$(wget -q -O - 'http://账号:密码@ddns.oray.com:80/ph/update?hostname=域名')
echo "[$TIMESTAMP] 花生壳返回: $oray_result" >> $LOG_FILE
# 3322更新
dyndns_result=$(wget -q -O - 'http://账号:密码@members.3322.org/dyndns/update?hostname=域名')
echo "[$TIMESTAMP] 3322返回: $dyndns_result" >> $LOG_FILE
echo "[$TIMESTAMP] 更新完成" >> $LOG_FILE
1.2 脚本执行权限与测试
1. 赋予执行权限:
确保脚本具备执行权限,否则定时任务将无法运行。
chmod +x /usr/share/scripts/ddns.sh
2. 手动测试:
在命令行中手动执行脚本,并检查日志文件和DDNS解析记录是否已更新。
/usr/share/scripts/ddns.sh
tail -n 5 /var/log/ddns_update.log
预期日志输出:
[2025-12-18 10:00:00] DDNS更新启动
[2025-12-18 10:00:01] 花生壳返回: good 1.2.3.4
[2025-12-18 10:00:02] 3322返回: good 1.2.3.4
[2025-12-18 10:00:02] 更新完成
<code>good</code> 表示更新成功,<code>nochg</code> 表示IP未变化无需更新。
2. 系统集成配置
2.1 使用 Cron 定时任务
推荐使用系统级 Cron 定时器来周期性执行更新脚本,以确保动态IP变化时能及时响应。
1. 编辑 Cron 表:
以 root 用户身份编辑定时任务列表。
crontab -e
2. 添加定时任务:
建议每隔 5 分钟执行一次脚本,以实现强制更新和快速响应。
# M H D M W command
*/5 * * * * /usr/share/scripts/ddns.sh >/dev/null 2>&1
说明: <code>/dev/null 2>&1</code> 用于丢弃脚本的标准输出和标准错误,避免产生不必要的邮件通知。
2.2 任务验证
检查 Cron 服务是否正在运行,并确认任务是否已被加载。
# 查看当前用户的 crontab 列表
crontab -l
# 检查日志文件,确认定时任务已开始执行
tail -f /var/log/ddns_update.log
3. 安全加固方案
由于脚本中直接暴露了DDNS服务的用户名和密码,必须采取措施进行安全加固。
3.1 权限最小化
限制脚本文件和日志文件的访问权限,仅允许 root 用户读写。
# 限制脚本权限 (仅root可读写执行)
chown root:root /usr/share/scripts/ddns.sh
chmod 700 /usr/share/scripts/ddns.sh
# 限制日志权限 (仅root可读写)
chown root:root /var/log/ddns_update.log
chmod 600 /var/log/ddns_update.log
3.2 凭证分离(推荐)
将敏感的用户名和密码移动到只有 root 可访问的配置文件中,避免直接在脚本中硬编码。
1. 创建配置文件 <code>/etc/ddns_secrets.conf</code>:
ORAY_USER="账号"
ORAY_PASS="密码"
DYNDNS_USER="账号"
DYNDNS_PASS="密码"
2. 限制配置文件权限:
chmod 600 /etc/ddns_secrets.conf
3. 修改 <code>/usr/share/scripts/ddns.sh</code> 脚本:
通过 <code>source</code> 命令加载凭证。
#!/bin/bash
# ... (日志定义不变)
# 导入凭证
source /etc/ddns_secrets.conf
# 花生壳更新
oray_result=$(wget -q -O - "http://${ORAY_USER}:${ORAY_PASS}@ddns.oray.com:80/ph/update?hostname=taohuadongle.vicp.cc")
# ... (3322更新类似修改)
4. 故障排查指南
4.1 日志分析
所有故障信息都会记录在 <code>/var/log/ddns_update.log</code> 中。
| 状态码 | 含义 | 建议操作 |
|---|---|---|
| <code>badauth</code> | 认证失败 | 检查 <code>/etc/ddns_secrets.conf</code> 中的用户名和密码是否正确。 |
| <code>nohost</code> | 主机名不存在 | 检查 <code>hostname</code> 参数是否拼写错误或已过期。 |
| <code>911</code> (Oray) | 服务器错误 | 稍后重试,或联系服务商。 |
| <code>abuse</code> | 频繁更新 | 检查 Cron 任务频率,确保更新间隔不低于 5 分钟。 |
| <code>wget: error</code> | 网络连接失败 | 检查主机的网络连通性 (<code>ping ddns.oray.com</code>)。 |
4.2 强制诊断
如果日志显示更新成功 (<code>good</code> 或 <code>nochg</code>),但外部访问仍失败:
- 检查本地IP: 确认脚本获取的IP地址是否为公网IP。
- DNS缓存: 清除本地DNS缓存后再次尝试访问。
- 路由器配置: 确认路由器已正确配置端口转发 (NAT)。
5. 高级监控方案
5.1 日志轮替 (Logrotate)
为防止日志文件无限增大,必须配置日志轮替。
1. 创建 Logrotate 配置文件 <code>/etc/logrotate.d/ddns</code>:
/var/log/ddns_update.log {
daily
rotate 7
compress
missingok
notifempty
create 0600 root root
}
说明: 每天轮替一次 (<code>daily</code>),保留 7 个历史备份 (<code>rotate 7</code>),并压缩存储。
5.2 状态检查函数
在 <code>/usr/share/scripts/ddns.sh</code> 脚本的末尾添加一个简单的状态检查,确保脚本在非预期错误时能发出警报(例如,通过邮件或系统通知)。
状态检查逻辑:
检查日志中最近一次更新是否在预期时间内(例如,10分钟内),如果长时间未更新,则可能 Cron 任务失败。
# 示例:检查最后一次更新时间
LAST_UPDATE=$(grep "更新完成" $LOG_FILE | tail -n 1 | awk '{print $1, $2}')
# 此处可集成邮件通知逻辑,如果 LAST_UPDATE 时间戳异常
