514 lines
18 KiB
Bash
514 lines
18 KiB
Bash
#!/bin/bash
|
||
|
||
# --- 脚本元信息与颜色定义 ---
|
||
GREEN="\033[32m"
|
||
RED="\033[31m"
|
||
YELLOW="\033[0;33m"
|
||
NC="\033[0m"
|
||
GREEN_ground="\033[42;37m" # 全局绿色
|
||
RED_ground="\033[41;37m" # 全局红色
|
||
Info="${GREEN}[信息]${NC}"
|
||
Error="${RED}[错误]${NC}"
|
||
Tip="${YELLOW}[提示]${NC}"
|
||
|
||
# --- 脚本欢迎界面 ---
|
||
cop_info(){
|
||
clear
|
||
echo -e "${GREEN}#######################################################
|
||
# ${RED}Debian DDNS 一键脚本 (最终修正版)${GREEN} #
|
||
# 作者: ${YELLOW}LaoWang & AI ${GREEN}#
|
||
# https://blog.wlens.top ${GREEN}#
|
||
# ${YELLOW}优化: 缓存ZoneID, 重构更新逻辑, 加固文件权限${GREEN} #
|
||
#######################################################${NC}"
|
||
echo -e "${Info}此版本已修复所有已知BUG,感谢您的耐心。 "
|
||
echo
|
||
}
|
||
|
||
# --- 环境检查 ---
|
||
|
||
# 检查系统
|
||
if ! grep -qiE "debian|ubuntu" /etc/os-release; then
|
||
echo -e "${Error}本脚本仅支持 Debian 或 Ubuntu 系统。"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查root权限
|
||
check_root(){
|
||
if [[ $(whoami) != "root" ]]; then
|
||
echo -e "${Error}请以root身份执行该脚本!"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 检查并安装curl和jq
|
||
check_curl() {
|
||
if ! command -v curl &>/dev/null || ! command -v jq &>/dev/null; then
|
||
echo -e "${YELLOW}未检测到 curl 或 jq,正在安装...${NC}"
|
||
apt-get update && apt-get install -y curl jq
|
||
if [ $? -ne 0 ]; then
|
||
echo -e "${RED}安装 curl/jq 失败,请手动安装后重试。${NC}"
|
||
exit 1
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# --- 核心安装与文件生成 ---
|
||
|
||
# 安装DDNS相关文件
|
||
install_ddns(){
|
||
# 备份旧版本,避免覆盖
|
||
if [ -d "/etc/DDNS" ]; then
|
||
echo -e "${Tip}检测到已存在的DDNS目录,将备份为 /etc/DDNS.bak_$(date +%s)"
|
||
mv /etc/DDNS "/etc/DDNS.bak_$(date +%s)" 2>/dev/null
|
||
fi
|
||
|
||
# 创建工作目录
|
||
mkdir -p /etc/DDNS
|
||
|
||
# 将此脚本自身复制为系统命令
|
||
cp "$0" /usr/bin/ddns && chmod +x /usr/bin/ddns
|
||
|
||
# 创建纯净的配置文件 (仅包含用户可配置项)
|
||
cat <<'EOF' > /etc/DDNS/.config
|
||
Domain="your_domain.com"
|
||
Domainv6="your_domainv6.com"
|
||
Email="your_email@gmail.com"
|
||
Api_key="your_api_key"
|
||
|
||
Telegram_Bot_Token=""
|
||
Telegram_Chat_ID=""
|
||
EOF
|
||
chmod 600 /etc/DDNS/.config # 安全加固:设置配置文件权限
|
||
|
||
# 创建独立的IP状态文件
|
||
touch /etc/DDNS/.old_ipv4 && chmod 600 /etc/DDNS/.old_ipv4
|
||
touch /etc/DDNS/.old_ipv6 && chmod 600 /etc/DDNS/.old_ipv6
|
||
|
||
# ================================================================= #
|
||
# 创建全新的、语法完全正确的DDNS执行脚本
|
||
# ================================================================= #
|
||
cat <<'EOF' > /etc/DDNS/DDNS
|
||
#!/bin/bash
|
||
|
||
# DDNS工作目录
|
||
WORK_DIR="/etc/DDNS"
|
||
# 日志文件
|
||
LOG_FILE="/var/log/ddns.log"
|
||
|
||
# --- 全局变量 ---
|
||
declare -A ZONE_ID_CACHE
|
||
|
||
# --- 基础函数 ---
|
||
|
||
log() {
|
||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||
}
|
||
|
||
send_telegram_notification(){
|
||
local message="$1"
|
||
if [[ -n "$Telegram_Bot_Token" && -n "$Telegram_Chat_ID" ]]; then
|
||
log "正在发送Telegram通知..."
|
||
curl -s --connect-timeout 10 -X POST "https://api.telegram.org/bot$Telegram_Bot_Token/sendMessage" \
|
||
-d chat_id="$Telegram_Chat_ID" -d text="$message" >> "$LOG_FILE" 2>&1
|
||
else
|
||
log "Telegram通知未配置或配置不完整,跳过发送。"
|
||
fi
|
||
}
|
||
|
||
# --- Cloudflare API 函数 ---
|
||
|
||
get_root_domain() {
|
||
echo "$1" | awk -F. '{print $(NF-1)"."$NF}'
|
||
}
|
||
|
||
get_zone_id() {
|
||
local full_domain=$1
|
||
local root_domain
|
||
root_domain=$(get_root_domain "$full_domain")
|
||
|
||
if [[ -n "${ZONE_ID_CACHE[$root_domain]}" ]]; then
|
||
log "从缓存命中 Zone ID for $root_domain: ${ZONE_ID_CACHE[$root_domain]}"
|
||
echo "${ZONE_ID_CACHE[$root_domain]}"
|
||
return
|
||
fi
|
||
|
||
log "通过API获取 Zone ID for $root_domain..."
|
||
local zone_id_val
|
||
ZONE_ID_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$root_domain" \
|
||
-H "X-Auth-Email: $Email" \
|
||
-H "X-Auth-Key: $Api_key" \
|
||
-H "Content-Type: application/json")
|
||
zone_id_val=$(echo "$ZONE_ID_RESPONSE" | jq -r '.result[] | select(.name=="'"$root_domain"'") | .id' 2>/dev/null)
|
||
|
||
if [ -z "$zone_id_val" ]; then
|
||
log "错误: 无法获取 Zone ID for '$root_domain'. 检查邮箱、API Key或根域名。API响应: $ZONE_ID_RESPONSE"
|
||
send_telegram_notification "DDNS 错误: 无法获取 ${root_domain} 的 Cloudflare Zone ID。"
|
||
echo ""
|
||
else
|
||
log "获取成功! Zone ID for $root_domain: $zone_id_val. 已缓存。"
|
||
ZONE_ID_CACHE["$root_domain"]="$zone_id_val"
|
||
echo "$zone_id_val"
|
||
fi
|
||
}
|
||
|
||
get_dns_record_id() {
|
||
local zone_id=$1
|
||
local record_type=$2
|
||
local domain_name=$3
|
||
|
||
log "尝试获取 DNS Record ID for $domain_name (Type $record_type)..."
|
||
DNS_ID_RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?type=$record_type&name=$domain_name" \
|
||
-H "X-Auth-Email: $Email" \
|
||
-H "X-Auth-Key: $Api_key" \
|
||
-H "Content-Type: application/json")
|
||
local dns_id_val
|
||
dns_id_val=$(echo "$DNS_ID_RESPONSE" | jq -r '.result[0].id' 2>/dev/null)
|
||
|
||
if [ -z "$dns_id_val" ]; then
|
||
log "警告: 无法获取 '$domain_name' 的 $record_type 记录 ID. 请确保该记录已存在。API响应: $DNS_ID_RESPONSE"
|
||
echo ""
|
||
else
|
||
log "DNS Record ID for $domain_name: $dns_id_val"
|
||
echo "$dns_id_val"
|
||
fi
|
||
}
|
||
|
||
update_dns_record() {
|
||
local record_type=$1
|
||
local domain=$2
|
||
local public_ip=$3
|
||
local old_ip=$4
|
||
local old_ip_file=$5
|
||
|
||
if [[ "$public_ip" == "$old_ip" ]]; then
|
||
log "$record_type 地址 ($public_ip) 未变化。"
|
||
return 0
|
||
fi
|
||
|
||
log "检测到 $record_type 地址变化: 旧[$old_ip] -> 新[$public_ip]"
|
||
|
||
local zone_id
|
||
zone_id=$(get_zone_id "$domain")
|
||
if [ -z "$zone_id" ]; then
|
||
log "错误: 因无法获取Zone ID,跳过 $domain 的更新。"
|
||
return 1
|
||
fi
|
||
|
||
local dns_id
|
||
dns_id=$(get_dns_record_id "$zone_id" "$record_type" "$domain")
|
||
if [ -z "$dns_id" ]; then
|
||
log "错误: 因无法获取DNS Record ID,跳过 $domain 的更新。"
|
||
send_telegram_notification "DDNS 错误: 更新 ${domain} ($record_type) 失败,无法获取 DNS Record ID。"
|
||
return 1
|
||
fi
|
||
|
||
log "正在更新 $domain ($record_type) -> $public_ip..."
|
||
response=$(curl -s -w "%{http_code}" -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$dns_id" \
|
||
-H "X-Auth-Email: $Email" \
|
||
-H "X-Auth-Key: $Api_key" \
|
||
-H "Content-Type: application/json" \
|
||
--data "{\"type\":\"$record_type\",\"name\":\"$domain\",\"content\":\"$public_ip\",\"ttl\":60,\"proxied\":false}")
|
||
|
||
http_code=${response: -3}
|
||
body=${response::-3}
|
||
|
||
if [ "$http_code" -eq 200 ] && [[ "$body" == *"\"success\":true"* ]]; then
|
||
log "成功: $domain 的 $record_type 记录已更新为 $public_ip"
|
||
echo "$public_ip" > "$old_ip_file"
|
||
echo "${domain} 的 ${record_type} 地址已更新为 ${public_ip}。旧IP为 ${old_ip}。"
|
||
return 0
|
||
else
|
||
log "失败: 更新 $domain 失败。HTTP Code: $http_code, Response: $body"
|
||
send_telegram_notification "DDNS 错误: 更新 ${domain} ($record_type) 失败. HTTP Code: ${http_code}."
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ==================== 主逻辑开始 ====================
|
||
log "====== DDNS 任务开始 ======"
|
||
cd "$WORK_DIR" || { log "错误: 无法进入DDNS工作目录 $WORK_DIR"; exit 1; }
|
||
|
||
source .config
|
||
|
||
# --- 获取并验证公网IP地址 (已整合老版本验证逻辑) ---
|
||
ipv4Regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
|
||
ipv6Regex="^([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$"
|
||
|
||
log "正在从多个源获取公网IP地址..."
|
||
raw_ipv4=$(curl -s4 --max-time 10 https://api.ipify.org || curl -s4 --max-time 10 https://ip.sb || curl -s4 --max-time 10 https://ipv4.icanhazip.com)
|
||
raw_ipv6=$(curl -s6 --max-time 10 https://api6.ipify.org || curl -s6 --max-time 10 https://ip.sb || curl -s6 --max-time 10 https://ipv6.icanhazip.com)
|
||
|
||
Public_IPv4=""
|
||
if [[ -n "$raw_ipv4" && "$raw_ipv4" =~ $ipv4Regex ]]; then
|
||
Public_IPv4="$raw_ipv4"
|
||
log "成功获取并验证公网 IPv4: $Public_IPv4"
|
||
else
|
||
log "警告: 获取到的IPv4内容不是有效地址: '$raw_ipv4'。将忽略IPv4更新。"
|
||
fi
|
||
|
||
Public_IPv6=""
|
||
if [[ -n "$raw_ipv6" && "$raw_ipv6" =~ $ipv6Regex ]]; then
|
||
Public_IPv6="$raw_ipv6"
|
||
log "成功获取并验证公网 IPv6: $Public_IPv6"
|
||
else
|
||
log "警告: 获取到的IPv6内容不是有效地址: '$raw_ipv6'。将忽略IPv6更新。"
|
||
fi
|
||
|
||
# --- 读取旧的 IP 地址 ---
|
||
Old_Public_IPv4=$(cat "$WORK_DIR/.old_ipv4" 2>/dev/null)
|
||
Old_Public_IPv6=$(cat "$WORK_DIR/.old_ipv6" 2>/dev/null)
|
||
log "旧IPv4: [$Old_Public_IPv4], 旧IPv6: [$Old_Public_IPv6]"
|
||
|
||
# --- 依次处理IPv4和IPv6的更新 ---
|
||
notification_message=""
|
||
update_result=""
|
||
|
||
if [[ -n "$Domain" && "$Domain" != "your_domain.com" && -n "$Public_IPv4" ]]; then
|
||
update_result=$(update_dns_record "A" "$Domain" "$Public_IPv4" "$Old_Public_IPv4" "$WORK_DIR/.old_ipv4")
|
||
if [[ $? -eq 0 && -n "$update_result" ]]; then
|
||
notification_message+="$update_result "
|
||
fi
|
||
else
|
||
log "跳过 IPv4 更新:未配置域名或未获取到有效的公网IP。"
|
||
fi
|
||
|
||
if [[ -n "$Domainv6" && "$Domainv6" != "your_domainv6.com" && -n "$Public_IPv6" ]]; then
|
||
update_result=$(update_dns_record "AAAA" "$Domainv6" "$Public_IPv6" "$Old_Public_IPv6" "$WORK_DIR/.old_ipv6")
|
||
if [[ $? -eq 0 && -n "$update_result" ]]; then
|
||
notification_message+="$update_result "
|
||
fi
|
||
else
|
||
log "跳过 IPv6 更新:未配置域名或未获取到有效的公网IP。"
|
||
fi
|
||
|
||
# --- 任务结束,发送汇总通知 ---
|
||
if [ -n "$notification_message" ]; then
|
||
log "IP发生变化,准备发送最终通知。"
|
||
send_telegram_notification "$notification_message"
|
||
else
|
||
log "所有IP均未变化或无需更新,不发送通知。"
|
||
fi
|
||
|
||
log "====== DDNS 任务结束 ======"
|
||
EOF
|
||
|
||
chmod 700 /etc/DDNS/DDNS
|
||
|
||
touch /var/log/ddns.log && chmod 644 /var/log/ddns.log
|
||
|
||
echo -e "${Info}DDNS 文件安装完成!"
|
||
echo -e "${Tip}核心逻辑脚本位于: ${YELLOW}/etc/DDNS/DDNS${NC}"
|
||
echo -e "${Tip}配置文件位于: ${YELLOW}/etc/DDNS/.config (权限600)${NC}"
|
||
echo -e "${Tip}IP状态文件权限已设置为 600。"
|
||
echo -e "${Tip}日志文件位于: ${YELLOW}/var/log/ddns.log${NC}"
|
||
echo
|
||
}
|
||
|
||
# --- 管理菜单与功能 ---
|
||
|
||
check_ddns_status(){
|
||
if systemctl is-active --quiet ddns.timer; then
|
||
ddns_status="running"
|
||
else
|
||
ddns_status="dead"
|
||
fi
|
||
}
|
||
|
||
test_telegram_notification(){
|
||
echo -e "${Tip}正在测试 Telegram 通知...${NC}"
|
||
source /etc/DDNS/.config
|
||
|
||
if [[ -z "$Telegram_Bot_Token" || -z "$Telegram_Chat_ID" ]]; then
|
||
echo -e "${Error}Telegram Bot Token 或 Chat ID 未配置。请先通过选项 ${GREEN}5${NC} 进行配置。${NC}"
|
||
return 1
|
||
fi
|
||
|
||
current_ipv4=$(curl -s4 --max-time 5 https://api.ipify.org || echo "N/A")
|
||
local test_message="DDNS (最终修正版) 测试通知。服务器IP: ${current_ipv4}。如果能收到此消息,说明Telegram通知功能正常。"
|
||
|
||
echo -e "${Info}尝试发送测试消息...详情请查看 /var/log/ddns.log"
|
||
|
||
(
|
||
Telegram_Bot_Token="$Telegram_Bot_Token"
|
||
Telegram_Chat_ID="$Telegram_Chat_ID"
|
||
LOG_FILE="/var/log/ddns.log"
|
||
source /etc/DDNS/DDNS
|
||
send_telegram_notification "$test_message"
|
||
)
|
||
|
||
echo -e "${Info}测试消息已发送(或尝试发送)。请查看 Telegram 和 ${YELLOW}/var/log/ddns.log${NC} 确认结果。"
|
||
}
|
||
|
||
go_ahead(){
|
||
echo -e "${Tip}请选择一个操作:
|
||
${GREEN}1${NC}:启动 / 重启 DDNS
|
||
${GREEN}2${NC}:停止 DDNS
|
||
${GREEN}3${NC}:修改要解析的域名
|
||
${GREEN}4${NC}:修改 Cloudflare API
|
||
${GREEN}5${NC}:配置 Telegram 通知
|
||
${GREEN}6${NC}:${RED}彻底卸载 DDNS${NC}
|
||
${GREEN}7${NC}:查看 DDNS 实时日志
|
||
${GREEN}8${NC}:测试 Telegram 通知
|
||
${GREEN}9${NC}:立即手动执行一次DDNS检查
|
||
${GREEN}0${NC}:退出脚本"
|
||
echo
|
||
read -p "请输入选项 [0-9]: " option
|
||
case "$option" in
|
||
0) exit 0 ;;
|
||
1) restart_ddns; main ;;
|
||
2) stop_ddns; main ;;
|
||
3) set_domain; restart_ddns; sleep 2; main ;;
|
||
4) set_cloudflare_api; restart_ddns; sleep 2; main ;;
|
||
5) set_telegram_settings; restart_ddns; sleep 2; main ;;
|
||
6) uninstall_ddns ;;
|
||
7) echo -e "${Info}正在显示实时日志... 按 ${RED}Ctrl+C${NC} 退出。"; tail -f /var/log/ddns.log; main ;;
|
||
8) test_telegram_notification; sleep 2; main ;;
|
||
9) echo -e "${Info}正在手动触发一次DDNS检查..."; systemctl start ddns.service; echo -e "${Info}已触发,请通过日志查看结果。"; sleep 2; main ;;
|
||
*) echo -e "${Error}无效的输入!"; sleep 2; main ;;
|
||
esac
|
||
}
|
||
|
||
uninstall_ddns(){
|
||
read -p "你确定要彻底卸载 DDNS 吗? 这会删除所有配置和脚本。[y/N]: " confirm
|
||
if [[ ! "${confirm,,}" =~ ^y$ ]]; then
|
||
echo -e "${Info}操作已取消。"
|
||
main
|
||
return
|
||
fi
|
||
echo -e "${Tip}正在停止并禁用 systemd 服务..."
|
||
systemctl disable --now ddns.service ddns.timer >/dev/null 2>&1
|
||
echo -e "${Tip}正在删除相关文件..."
|
||
rm -f /etc/systemd/system/ddns.service /etc/systemd/system/ddns.timer
|
||
rm -rf /etc/DDNS /usr/bin/ddns
|
||
rm -f /var/log/ddns.log
|
||
systemctl daemon-reload
|
||
echo -e "${Info}DDNS 已成功卸载!"
|
||
echo
|
||
}
|
||
|
||
set_cloudflare_api(){
|
||
echo -e "${Tip}开始配置 Cloudflare API..." && echo
|
||
read -p "请输入您的 Cloudflare 邮箱: " email
|
||
read -p "请输入您的 Cloudflare Global API Key: " api_key
|
||
|
||
if [ -z "$email" ] || [ -z "$api_key" ]; then
|
||
echo -e "${Error}邮箱和 API Key 不能为空!"
|
||
return 1
|
||
fi
|
||
|
||
sed -i "s/^Email=.*/Email=\"$email\"/" /etc/DDNS/.config
|
||
sed -i "s/^Api_key=.*/Api_key=\"$api_key\"/" /etc/DDNS/.config
|
||
|
||
echo -e "${Info}Cloudflare API 设置已更新!"
|
||
}
|
||
|
||
set_domain(){
|
||
echo && echo -e "${Tip}开始配置要解析的域名..."
|
||
|
||
echo -e "${Tip}请输入要解析的 IPv4 域名 (如: v4.yourdomain.com, 回车跳过):"
|
||
read -p "IPv4 域名: " domain_v4
|
||
sed -i "s/^Domain=.*/Domain=\"$domain_v4\"/" /etc/DDNS/.config
|
||
|
||
echo -e "${Tip}请输入要解析的 IPv6 域名 (如: v6.yourdomain.com, 回车跳过):"
|
||
read -p "IPv6 域名: " domain_v6
|
||
sed -i "s/^Domainv6=.*/Domainv6=\"$domain_v6\"/" /etc/DDNS/.config
|
||
|
||
echo -e "${Info}域名设置已更新!"
|
||
}
|
||
|
||
set_telegram_settings(){
|
||
echo && echo -e "${Tip}开始配置 Telegram 通知 (全部留空则禁用)..."
|
||
read -p "请输入您的 Telegram Bot Token: " token
|
||
read -p "请输入您的 Telegram Chat ID: " chat_id
|
||
|
||
sed -i "s/^Telegram_Bot_Token=.*/Telegram_Bot_Token=\"$token\"/" /etc/DDNS/.config
|
||
sed -i "s/^Telegram_Chat_ID=.*/Telegram_Chat_ID=\"$chat_id\"/" /etc/DDNS/.config
|
||
|
||
echo -e "${Info}Telegram 设置已更新!"
|
||
}
|
||
|
||
run_ddns(){
|
||
if [ ! -f "/etc/systemd/system/ddns.service" ]; then
|
||
cat > /etc/systemd/system/ddns.service <<EOF
|
||
[Unit]
|
||
Description=Dynamic DNS Update Service (Cloudflare)
|
||
After=network.target nss-lookup.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
ExecStart=/bin/bash /etc/DDNS/DDNS
|
||
WorkingDirectory=/etc/DDNS
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
fi
|
||
|
||
if [ ! -f "/etc/systemd/system/ddns.timer" ]; then
|
||
cat > /etc/systemd/system/ddns.timer <<EOF
|
||
[Unit]
|
||
Description=Run DDNS job every 5 minutes
|
||
|
||
[Timer]
|
||
OnBootSec=2min
|
||
OnUnitActiveSec=5min
|
||
Unit=ddns.service
|
||
|
||
[Install]
|
||
WantedBy=timers.target
|
||
EOF
|
||
fi
|
||
|
||
systemctl daemon-reload
|
||
restart_ddns
|
||
}
|
||
|
||
restart_ddns(){
|
||
echo -e "${Info}正在启动/重启 DDNS 定时任务..."
|
||
systemctl start ddns.service
|
||
systemctl enable --now ddns.timer >/dev/null 2>&1
|
||
echo -e "${Info}DDNS 服务已启动。将每5分钟检查一次IP变更。"
|
||
}
|
||
|
||
stop_ddns(){
|
||
echo -e "${Info}正在停止 DDNS 定时任务..."
|
||
systemctl disable --now ddns.timer >/dev/null 2>&1
|
||
systemctl stop ddns.service >/dev/null 2>&1
|
||
echo -e "${Info}DDNS 已停止。"
|
||
}
|
||
|
||
main(){
|
||
if [[ -z "$IS_RECURSIVE" ]]; then
|
||
cop_info
|
||
fi
|
||
|
||
if [ ! -f "/etc/DDNS/.config" ] || [ ! -f "/usr/bin/ddns" ]; then
|
||
echo -e "${Tip}首次运行,开始安装流程..."
|
||
install_ddns
|
||
set_cloudflare_api
|
||
set_domain
|
||
set_telegram_settings
|
||
run_ddns
|
||
echo
|
||
echo -e "${GREEN_ground} DDNS (最终修正版) 安装并配置成功! ${NC}"
|
||
echo -e "${Info}你可以随时再次运行此脚本或直接输入 ${GREEN}ddns${NC} 进行管理。"
|
||
echo -e "${Info}重要:请通过选项 ${GREEN}7${NC} 查看日志以确认首次运行是否成功。"
|
||
echo
|
||
else
|
||
check_ddns_status
|
||
if [[ "$ddns_status" == "running" ]]; then
|
||
echo -e "${Info}DDNS 状态: ${GREEN}已安装${NC} | ${GREEN}运行中${NC}"
|
||
else
|
||
echo -e "${Info}DDNS 状态: ${GREEN}已安装${NC} | ${RED}已停止${NC}"
|
||
fi
|
||
echo
|
||
fi
|
||
|
||
export IS_RECURSIVE=true
|
||
go_ahead
|
||
}
|
||
|
||
# --- 脚本执行起点 ---
|
||
check_root
|
||
check_curl
|
||
main |