commit e848a3274280030fb6e221ee6e8179b01b7bb624 Author: chunzhimoe Date: Fri Apr 10 17:18:40 2026 +0800 feat: 增加 Alpine Linux (OpenRC) 支持 diff --git a/port.sh b/port.sh new file mode 100644 index 0000000..8fb4163 --- /dev/null +++ b/port.sh @@ -0,0 +1,868 @@ +cat > /root/port-forward.sh << 'EOF' +#!/bin/bash + +# 端口转发管理脚本 +# 使用 socat 实现端口转发(含自动重启监控) +# 支持 systemd (Debian/Ubuntu/CentOS) 和 OpenRC (Alpine) + +SERVICE_PREFIX="port-forward" +WATCHDOG_SERVICE="port-forward-watchdog" +WATCHDOG_SCRIPT="/root/port-forward-watchdog.sh" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +# ============================================ +# 系统检测 +# ============================================ + +detect_system() { + if [ -f /etc/alpine-release ]; then + OS="alpine" + elif [ -f /etc/debian_version ]; then + OS="debian" + else + OS="unknown" + fi + + if command -v systemctl &> /dev/null && systemctl --version &> /dev/null 2>&1; then + INIT_SYS="systemd" + elif command -v rc-service &> /dev/null; then + INIT_SYS="openrc" + else + echo -e "${RED}错误: 不支持的初始化系统(需要 systemd 或 OpenRC)${NC}" + exit 1 + fi + + echo -e "${BLUE}系统: ${OS} | 初始化系统: ${INIT_SYS}${NC}" +} + +# ============================================ +# 包管理 +# ============================================ + +check_deps() { + # Alpine 下确保 bash 已安装 + if [ "$OS" = "alpine" ]; then + if ! command -v bash &> /dev/null; then + echo -e "${YELLOW}bash 未安装,正在安装...${NC}" + apk add --no-cache bash + fi + fi + + if ! command -v socat &> /dev/null; then + echo -e "${YELLOW}socat 未安装,正在安装...${NC}" + if [ "$OS" = "alpine" ]; then + apk add --no-cache socat + else + apt update && apt install socat -y + fi + if [ $? -eq 0 ]; then + echo -e "${GREEN}socat 安装成功!${NC}" + else + echo -e "${RED}socat 安装失败,请手动安装${NC}" + exit 1 + fi + fi +} + +# ============================================ +# 服务管理抽象层 +# ============================================ + +svc_create_forward() { + local svc_name=$1 + local local_port=$2 + local target_ip=$3 + local target_port=$4 + + if [ "$INIT_SYS" = "systemd" ]; then + cat > /etc/systemd/system/${svc_name}.service << SERVICEEOF +[Unit] +Description=Port Forward ${local_port} to ${target_ip}:${target_port} +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/socat TCP4-LISTEN:${local_port},reuseaddr,fork TCP4:${target_ip}:${target_port} +Restart=always +RestartSec=5 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target +SERVICEEOF + elif [ "$INIT_SYS" = "openrc" ]; then + cat > /etc/init.d/${svc_name} << SERVICEEOF +#!/sbin/openrc-run + +name="${svc_name}" +description="Port Forward ${local_port} to ${target_ip}:${target_port}" +command="/usr/bin/socat" +command_args="TCP4-LISTEN:${local_port},reuseaddr,fork TCP4:${target_ip}:${target_port}" +command_background=true +pidfile="/run/${svc_name}.pid" + +depend() { + need net +} +SERVICEEOF + chmod +x /etc/init.d/${svc_name} + fi +} + +svc_enable() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl enable ${svc_name} > /dev/null 2>&1 + elif [ "$INIT_SYS" = "openrc" ]; then + rc-update add ${svc_name} default > /dev/null 2>&1 + fi +} + +svc_disable() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl disable ${svc_name} > /dev/null 2>&1 + elif [ "$INIT_SYS" = "openrc" ]; then + rc-update del ${svc_name} default > /dev/null 2>&1 + fi +} + +svc_start() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl start ${svc_name} + elif [ "$INIT_SYS" = "openrc" ]; then + rc-service ${svc_name} start > /dev/null 2>&1 + fi +} + +svc_stop() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl stop ${svc_name} > /dev/null 2>&1 + elif [ "$INIT_SYS" = "openrc" ]; then + rc-service ${svc_name} stop > /dev/null 2>&1 + fi +} + +svc_restart() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl restart ${svc_name} + elif [ "$INIT_SYS" = "openrc" ]; then + rc-service ${svc_name} restart > /dev/null 2>&1 + fi +} + +svc_is_active() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + systemctl is-active ${svc_name} 2>/dev/null + elif [ "$INIT_SYS" = "openrc" ]; then + if rc-service ${svc_name} status 2>/dev/null | grep -q "started"; then + echo "active" + else + echo "inactive" + fi + fi +} + +svc_exists() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + [ -f "/etc/systemd/system/${svc_name}.service" ] + elif [ "$INIT_SYS" = "openrc" ]; then + [ -f "/etc/init.d/${svc_name}" ] + fi +} + +svc_delete() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + rm -f /etc/systemd/system/${svc_name}.service + elif [ "$INIT_SYS" = "openrc" ]; then + rm -f /etc/init.d/${svc_name} + fi +} + +svc_daemon_reload() { + if [ "$INIT_SYS" = "systemd" ]; then + systemctl daemon-reload + fi +} + +svc_list_forward_names() { + if [ "$INIT_SYS" = "systemd" ]; then + systemctl list-units --all --type=service --no-pager | grep "${SERVICE_PREFIX}" | grep -v watchdog | grep -v daily | awk '{print $1}' | sed 's/.service$//' + elif [ "$INIT_SYS" = "openrc" ]; then + ls /etc/init.d/${SERVICE_PREFIX}-* 2>/dev/null | grep -v watchdog | xargs -I{} basename {} 2>/dev/null + fi +} + +svc_get_target() { + local svc_name=$1 + if [ "$INIT_SYS" = "systemd" ]; then + grep ExecStart /etc/systemd/system/${svc_name}.service 2>/dev/null | sed -n 's/.*TCP4:\([^ ]*\).*/\1/p' + elif [ "$INIT_SYS" = "openrc" ]; then + grep command_args /etc/init.d/${svc_name} 2>/dev/null | sed -n 's/.*TCP4:\([^ "]*\).*/\1/p' + fi +} + +# ============================================ +# 端口转发管理 +# ============================================ + +add_single_forward() { + echo -e "${GREEN}=== 添加单个端口转发 ===${NC}" + read -p "请输入本机监听端口: " local_port + read -p "请输入目标IP地址: " target_ip + read -p "请输入目标端口: " target_port + + if [[ -z "$local_port" ]] || [[ -z "$target_ip" ]] || [[ -z "$target_port" ]]; then + echo -e "${RED}错误: 输入不能为空${NC}"; return 1 + fi + + local svc_name="${SERVICE_PREFIX}-${local_port}" + svc_create_forward "$svc_name" "$local_port" "$target_ip" "$target_port" + svc_daemon_reload + svc_enable "$svc_name" + svc_start "$svc_name" + + if [ "$(svc_is_active $svc_name)" = "active" ]; then + echo -e "${GREEN}✓ 端口转发添加成功!${NC}" + echo -e "本机端口: ${local_port} -> 目标: ${target_ip}:${target_port}" + else + echo -e "${RED}✗ 端口转发添加失败${NC}" + fi +} + +add_batch_forward() { + echo -e "${GREEN}=== 批量添加端口转发 ===${NC}" + read -p "请输入本机起始端口: " start_port + read -p "请输入本机结束端口: " end_port + read -p "请输入目标IP地址: " target_ip + read -p "请输入目标端口: " target_port + + if [[ -z "$start_port" ]] || [[ -z "$end_port" ]] || [[ -z "$target_ip" ]] || [[ -z "$target_port" ]]; then + echo -e "${RED}错误: 输入不能为空${NC}"; return 1 + fi + + echo -e "${YELLOW}即将创建 $((end_port - start_port + 1)) 个端口转发...${NC}" + read -p "确认继续? (y/n): " confirm + if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi + + for port in $(seq $start_port $end_port); do + local svc_name="${SERVICE_PREFIX}-${port}" + svc_create_forward "$svc_name" "$port" "$target_ip" "$target_port" + svc_enable "$svc_name" + svc_start "$svc_name" + echo -e "${GREEN}✓${NC} 端口 ${port} 转发已创建" + done + + svc_daemon_reload + echo -e "${GREEN}批量端口转发添加完成!${NC}" +} + +list_forwards() { + echo -e "${GREEN}=== 当前端口转发列表 ===${NC}" + echo "" + + local services + services=$(svc_list_forward_names) + + if [[ -z "$services" ]]; then + echo -e "${YELLOW}暂无端口转发${NC}" + else + printf "%-15s %-12s %-30s\n" "本机端口" "状态" "转发目标" + echo "--------------------------------------------------------" + + for svc_name in $services; do + local port=$(echo $svc_name | sed "s/${SERVICE_PREFIX}-//g") + local status=$(svc_is_active $svc_name) + + if [[ "$status" == "active" ]]; then + local status_color="${GREEN}运行中${NC}" + else + local status_color="${RED}已停止${NC}" + fi + + local target=$(svc_get_target $svc_name) + printf "%-15s %-20b %-30s\n" "$port" "$status_color" "$target" + done + fi + + echo "" + local watchdog_status=$(svc_is_active ${WATCHDOG_SERVICE}) + if [[ "$watchdog_status" == "active" ]]; then + echo -e "🛡️ Watchdog: ${GREEN}运行中(自动重启已开启)${NC}" + else + echo -e "🛡️ Watchdog: ${RED}未运行${NC}(菜单 8 可启动)" + fi + + if [ "$INIT_SYS" = "systemd" ]; then + local timer_status=$(systemctl is-active port-forward-daily.timer 2>/dev/null) + if [[ "$timer_status" == "active" ]]; then + local next=$(systemctl list-timers port-forward-daily.timer --no-pager 2>/dev/null | awk 'NR==2{print $1, $2}') + echo -e "⏰ 定时重启: ${GREEN}已开启${NC},下次: ${YELLOW}${next}${NC}" + else + echo -e "⏰ 定时重启: ${RED}未开启${NC}(菜单 9 可设置)" + fi + elif [ "$INIT_SYS" = "openrc" ]; then + if crontab -l 2>/dev/null | grep -q "port-forward-daily-restart"; then + local cron_time=$(crontab -l 2>/dev/null | grep "port-forward-daily-restart" | awk '{printf "%02d:%02d", $2, $1}') + echo -e "⏰ 定时重启: ${GREEN}已开启${NC},时间: ${YELLOW}每天 ${cron_time}${NC}" + else + echo -e "⏰ 定时重启: ${RED}未开启${NC}(菜单 9 可设置)" + fi + fi +} + +restart_single_forward() { + echo -e "${GREEN}=== 重启单个端口转发 ===${NC}" + read -p "请输入要重启的本机端口: " port + + local svc_name="${SERVICE_PREFIX}-${port}" + if ! svc_exists "$svc_name"; then + echo -e "${RED}错误: 端口 ${port} 的转发不存在${NC}"; return 1 + fi + + svc_restart "$svc_name" + sleep 1 + if [ "$(svc_is_active $svc_name)" = "active" ]; then + echo -e "${GREEN}✓ 端口 ${port} 重启成功!${NC}" + else + echo -e "${RED}✗ 重启失败${NC}" + fi +} + +restart_all_forwards() { + echo -e "${GREEN}=== 重启所有端口转发 ===${NC}" + read -p "确认重启所有转发? (y/n): " confirm + if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi + + local services + services=$(svc_list_forward_names) + + if [[ -z "$services" ]]; then + echo -e "${YELLOW}暂无端口转发${NC}"; return + fi + + local failed=0 success=0 + for svc_name in $services; do + local port=$(echo $svc_name | sed "s/${SERVICE_PREFIX}-//g") + svc_restart "$svc_name" + sleep 0.5 + if [ "$(svc_is_active $svc_name)" = "active" ]; then + echo -e "${GREEN}✓${NC} 端口 ${port} 重启成功"; ((success++)) + else + echo -e "${RED}✗${NC} 端口 ${port} 重启失败"; ((failed++)) + fi + done + + echo "" + echo -e "重启完成:${GREEN}成功 ${success} 个${NC},${RED}失败 ${failed} 个${NC}" +} + +# ============================================ +# Watchdog 自动重启监控 +# ============================================ + +install_watchdog() { + echo -e "${BLUE}=== 安装 Watchdog 自动监控 ===${NC}" + read -p "请输入检查间隔(秒,默认30): " interval + interval=${interval:-30} + + cat > ${WATCHDOG_SCRIPT} << WATCHEOF +#!/bin/bash +# Port Forward Watchdog - 支持 systemd 和 OpenRC +LOG_FILE="/var/log/port-forward-watchdog.log" +SERVICE_PREFIX="port-forward" + +if command -v systemctl &> /dev/null && systemctl --version &> /dev/null 2>&1; then + W_INIT="systemd" +elif command -v rc-service &> /dev/null; then + W_INIT="openrc" +else + echo "Unsupported init system" >> \$LOG_FILE + exit 1 +fi + +log() { + echo "\$(date '+%Y-%m-%d %H:%M:%S') \$1" | tee -a \$LOG_FILE +} + +w_list_services() { + if [ "\$W_INIT" = "systemd" ]; then + systemctl list-units --all --type=service --no-pager | grep \${SERVICE_PREFIX} | grep -v watchdog | grep -v daily | awk '{print \$1}' | sed 's/.service\$//' + elif [ "\$W_INIT" = "openrc" ]; then + ls /etc/init.d/\${SERVICE_PREFIX}-* 2>/dev/null | grep -v watchdog | xargs -I{} basename {} 2>/dev/null + fi +} + +w_is_active() { + if [ "\$W_INIT" = "systemd" ]; then + systemctl is-active \$1 2>/dev/null + elif [ "\$W_INIT" = "openrc" ]; then + if rc-service \$1 status 2>/dev/null | grep -q "started"; then + echo "active" + else + echo "inactive" + fi + fi +} + +w_restart() { + if [ "\$W_INIT" = "systemd" ]; then + systemctl restart \$1 + elif [ "\$W_INIT" = "openrc" ]; then + rc-service \$1 restart > /dev/null 2>&1 + fi +} + +log "=== Watchdog 启动,检查间隔: ${interval}秒,初始化系统: \$W_INIT ===" + +while true; do + services=\$(w_list_services) + + for service in \$services; do + status=\$(w_is_active \$service) + if [[ "\$status" != "active" ]]; then + log "⚠ 检测到 \$service 异常(状态: \$status),正在重启..." + w_restart \$service + sleep 2 + new_status=\$(w_is_active \$service) + if [[ "\$new_status" == "active" ]]; then + log "✓ \$service 重启成功" + else + log "✗ \$service 重启失败,状态: \$new_status" + fi + fi + done + + sleep ${interval} +done +WATCHEOF + + chmod +x ${WATCHDOG_SCRIPT} + + if [ "$INIT_SYS" = "systemd" ]; then + cat > /etc/systemd/system/${WATCHDOG_SERVICE}.service << SERVICEEOF +[Unit] +Description=Port Forward Watchdog - Auto Restart Monitor +After=network.target + +[Service] +Type=simple +ExecStart=/bin/bash ${WATCHDOG_SCRIPT} +Restart=always +RestartSec=10 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target +SERVICEEOF + elif [ "$INIT_SYS" = "openrc" ]; then + cat > /etc/init.d/${WATCHDOG_SERVICE} << SERVICEEOF +#!/sbin/openrc-run + +name="${WATCHDOG_SERVICE}" +description="Port Forward Watchdog - Auto Restart Monitor" +command="/bin/bash" +command_args="${WATCHDOG_SCRIPT}" +command_background=true +pidfile="/run/${WATCHDOG_SERVICE}.pid" + +depend() { + need net +} +SERVICEEOF + chmod +x /etc/init.d/${WATCHDOG_SERVICE} + fi + + svc_daemon_reload + svc_enable "${WATCHDOG_SERVICE}" + svc_start "${WATCHDOG_SERVICE}" + + if [ "$(svc_is_active ${WATCHDOG_SERVICE})" = "active" ]; then + echo -e "${GREEN}✓ Watchdog 安装成功!${NC}" + echo -e " 检查间隔: ${interval} 秒" + echo -e " 日志位置: /var/log/port-forward-watchdog.log" + echo -e " 实时日志: tail -f /var/log/port-forward-watchdog.log" + else + echo -e "${RED}✗ Watchdog 启动失败${NC}" + fi +} + +uninstall_watchdog() { + read -p "确认卸载 Watchdog? (y/n): " confirm + if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi + + svc_stop "${WATCHDOG_SERVICE}" + svc_disable "${WATCHDOG_SERVICE}" + svc_delete "${WATCHDOG_SERVICE}" + rm -f ${WATCHDOG_SCRIPT} + svc_daemon_reload + echo -e "${GREEN}✓ Watchdog 已卸载${NC}" +} + +# ============================================ +# 定时每日重启 +# ============================================ + +install_daily_restart() { + echo -e "${BLUE}=== 设置每日定时重启 ===${NC}" + read -p "请输入每天重启时间(小时,0-23,默认4点): " hour + hour=${hour:-4} + read -p "请输入分钟(0-59,默认0分): " minute + minute=${minute:-0} + + if ! [[ "$hour" =~ ^[0-9]+$ ]] || [[ $hour -gt 23 ]]; then + echo -e "${RED}错误: 小时必须为 0-23${NC}"; return 1 + fi + if ! [[ "$minute" =~ ^[0-9]+$ ]] || [[ $minute -gt 59 ]]; then + echo -e "${RED}错误: 分钟必须为 0-59${NC}"; return 1 + fi + + # 创建重启脚本(内嵌初始化系统检测) + cat > /root/port-forward-daily-restart.sh << DAILYEOF +#!/bin/bash +# 每日定时重启所有端口转发服务 - 支持 systemd 和 OpenRC +LOG_FILE="/var/log/port-forward-daily.log" + +if command -v systemctl &> /dev/null && systemctl --version &> /dev/null 2>&1; then + D_INIT="systemd" +elif command -v rc-service &> /dev/null; then + D_INIT="openrc" +fi + +log() { + echo "\$(date '+%Y-%m-%d %H:%M:%S') \$1" | tee -a \$LOG_FILE +} + +d_list_services() { + if [ "\$D_INIT" = "systemd" ]; then + systemctl list-units --all --type=service --no-pager | grep port-forward | grep -v watchdog | grep -v daily | awk '{print \$1}' | sed 's/.service\$//' + elif [ "\$D_INIT" = "openrc" ]; then + ls /etc/init.d/port-forward-* 2>/dev/null | grep -v watchdog | xargs -I{} basename {} 2>/dev/null + fi +} + +d_is_active() { + if [ "\$D_INIT" = "systemd" ]; then + systemctl is-active \$1 2>/dev/null + elif [ "\$D_INIT" = "openrc" ]; then + if rc-service \$1 status 2>/dev/null | grep -q "started"; then + echo "active" + else + echo "inactive" + fi + fi +} + +d_restart() { + if [ "\$D_INIT" = "systemd" ]; then + systemctl restart \$1 + elif [ "\$D_INIT" = "openrc" ]; then + rc-service \$1 restart > /dev/null 2>&1 + fi +} + +log "=== 开始每日定时重启(\$D_INIT)===" +services=\$(d_list_services) + +success=0; failed=0 +for service in \$services; do + d_restart \$service + sleep 1 + if [[ "\$(d_is_active \$service)" == "active" ]]; then + log "✓ \$service 重启成功" + ((success++)) + else + log "✗ \$service 重启失败" + ((failed++)) + fi +done + +log "=== 重启完成:成功 \${success} 个,失败 \${failed} 个 ===" +DAILYEOF + + chmod +x /root/port-forward-daily-restart.sh + + if [ "$INIT_SYS" = "systemd" ]; then + cat > /etc/systemd/system/port-forward-daily.service << SERVICEEOF +[Unit] +Description=Port Forward Daily Restart +After=network.target + +[Service] +Type=oneshot +ExecStart=/bin/bash /root/port-forward-daily-restart.sh +SERVICEEOF + + cat > /etc/systemd/system/port-forward-daily.timer << TIMEREOF +[Unit] +Description=Port Forward Daily Restart Timer +Requires=port-forward-daily.service + +[Timer] +OnCalendar=*-*-* ${hour}:${minute}:00 +Persistent=true + +[Install] +WantedBy=timers.target +TIMEREOF + + systemctl daemon-reload + systemctl enable port-forward-daily.timer + systemctl start port-forward-daily.timer + + if systemctl is-active port-forward-daily.timer > /dev/null 2>&1; then + echo -e "${GREEN}✓ 每日定时重启设置成功!${NC}" + printf " 重启时间: 每天 %02d:%02d\n" $hour $minute + echo -e " 日志位置: /var/log/port-forward-daily.log" + echo "" + echo -e " 下次执行时间:" + systemctl list-timers port-forward-daily.timer --no-pager | tail -2 + else + echo -e "${RED}✗ 定时器启动失败${NC}" + fi + elif [ "$INIT_SYS" = "openrc" ]; then + # Alpine 下使用 cron 实现定时任务 + if ! command -v crond &> /dev/null && ! pgrep crond > /dev/null 2>&1; then + echo -e "${YELLOW}正在安装 cron 服务...${NC}" + apk add --no-cache dcron + rc-service dcron start > /dev/null 2>&1 + rc-update add dcron default > /dev/null 2>&1 + fi + + # 移除旧条目并添加新条目 + crontab -l 2>/dev/null | grep -v "port-forward-daily-restart" | crontab - 2>/dev/null + (crontab -l 2>/dev/null; echo "${minute} ${hour} * * * /bin/bash /root/port-forward-daily-restart.sh") | crontab - + + echo -e "${GREEN}✓ 每日定时重启设置成功!${NC}" + printf " 重启时间: 每天 %02d:%02d\n" $hour $minute + echo -e " 日志位置: /var/log/port-forward-daily.log" + fi +} + +uninstall_daily_restart() { + read -p "确认取消每日定时重启? (y/n): " confirm + if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi + + if [ "$INIT_SYS" = "systemd" ]; then + systemctl stop port-forward-daily.timer 2>/dev/null + systemctl disable port-forward-daily.timer 2>/dev/null + rm -f /etc/systemd/system/port-forward-daily.timer + rm -f /etc/systemd/system/port-forward-daily.service + systemctl daemon-reload + elif [ "$INIT_SYS" = "openrc" ]; then + crontab -l 2>/dev/null | grep -v "port-forward-daily-restart" | crontab - 2>/dev/null + fi + + rm -f /root/port-forward-daily-restart.sh + echo -e "${GREEN}✓ 每日定时重启已取消${NC}" +} + +view_daily_log() { + echo -e "${BLUE}=== 每日重启日志(最近30行)===${NC}" + if [[ -f "/var/log/port-forward-daily.log" ]]; then + tail -30 /var/log/port-forward-daily.log + echo "" + echo -e "${YELLOW}实时监控: tail -f /var/log/port-forward-daily.log${NC}" + else + echo -e "${YELLOW}日志不存在,定时重启可能未运行过${NC}" + fi +} + +daily_restart_menu() { + while true; do + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE} ⏰ 每日定时重启管理${NC}" + echo -e "${BLUE}================================${NC}" + + if [ "$INIT_SYS" = "systemd" ]; then + local timer_status=$(systemctl is-active port-forward-daily.timer 2>/dev/null) + if [[ "$timer_status" == "active" ]]; then + echo -e "当前状态: ${GREEN}● 已开启${NC}" + local next=$(systemctl list-timers port-forward-daily.timer --no-pager 2>/dev/null | awk 'NR==2{print $1, $2}') + echo -e "下次执行: ${YELLOW}${next}${NC}" + else + echo -e "当前状态: ${RED}● 未开启${NC}" + fi + elif [ "$INIT_SYS" = "openrc" ]; then + if crontab -l 2>/dev/null | grep -q "port-forward-daily-restart"; then + local cron_entry=$(crontab -l 2>/dev/null | grep "port-forward-daily-restart") + local cron_min=$(echo "$cron_entry" | awk '{print $1}') + local cron_hr=$(echo "$cron_entry" | awk '{print $2}') + echo -e "当前状态: ${GREEN}● 已开启${NC}" + printf "执行时间: ${YELLOW}每天 %02d:%02d${NC}\n" $cron_hr $cron_min + else + echo -e "当前状态: ${RED}● 未开启${NC}" + fi + fi + + echo "--------------------------------" + echo "1. 设置每日定时重启" + echo "2. 立即手动执行一次重启" + echo "3. 查看重启日志" + echo "4. 取消每日定时重启" + echo "5. 返回上级菜单" + echo -e "${BLUE}================================${NC}" + read -p "请选择 [1-5]: " choice + + case $choice in + 1) install_daily_restart ;; + 2) + echo -e "${YELLOW}正在手动执行重启...${NC}" + bash /root/port-forward-daily-restart.sh 2>/dev/null || \ + restart_all_forwards + ;; + 3) view_daily_log ;; + 4) uninstall_daily_restart ;; + 5) return ;; + *) echo -e "${RED}无效选择${NC}" ;; + esac + done +} + +view_watchdog_log() { + echo -e "${BLUE}=== Watchdog 日志(最近50行)===${NC}" + if [[ -f "/var/log/port-forward-watchdog.log" ]]; then + tail -50 /var/log/port-forward-watchdog.log + echo "" + echo -e "${YELLOW}实时监控命令: tail -f /var/log/port-forward-watchdog.log${NC}" + else + echo -e "${YELLOW}日志不存在,Watchdog 可能未启动${NC}" + fi +} + +watchdog_menu() { + while true; do + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE} 🛡️ Watchdog 自动重启管理${NC}" + echo -e "${BLUE}================================${NC}" + + local w_status=$(svc_is_active ${WATCHDOG_SERVICE}) + if [[ "$w_status" == "active" ]]; then + echo -e "当前状态: ${GREEN}● 运行中${NC}" + else + echo -e "当前状态: ${RED}● 未运行${NC}" + fi + + echo "--------------------------------" + echo "1. 安装并启动 Watchdog" + echo "2. 停止 Watchdog" + echo "3. 启动 Watchdog" + echo "4. 查看 Watchdog 日志" + echo "5. 卸载 Watchdog" + echo "6. 返回主菜单" + echo -e "${BLUE}================================${NC}" + read -p "请选择 [1-6]: " choice + + case $choice in + 1) install_watchdog ;; + 2) svc_stop "${WATCHDOG_SERVICE}" && echo -e "${GREEN}✓ Watchdog 已停止${NC}" ;; + 3) svc_start "${WATCHDOG_SERVICE}" && echo -e "${GREEN}✓ Watchdog 已启动${NC}" ;; + 4) view_watchdog_log ;; + 5) uninstall_watchdog ;; + 6) return ;; + *) echo -e "${RED}无效选择${NC}" ;; + esac + done +} + +delete_forward() { + echo -e "${GREEN}=== 删除端口转发 ===${NC}" + read -p "请输入要删除的本机端口: " port + + local svc_name="${SERVICE_PREFIX}-${port}" + if ! svc_exists "$svc_name"; then + echo -e "${RED}错误: 端口 ${port} 的转发不存在${NC}"; return 1 + fi + + svc_stop "$svc_name" + svc_disable "$svc_name" + svc_delete "$svc_name" + svc_daemon_reload + echo -e "${GREEN}✓ 端口 ${port} 的转发已删除${NC}" +} + +delete_batch_forward() { + echo -e "${GREEN}=== 批量删除端口转发 ===${NC}" + read -p "请输入起始端口: " start_port + read -p "请输入结束端口: " end_port + + echo -e "${YELLOW}即将删除端口 ${start_port}-${end_port} 的转发...${NC}" + read -p "确认继续? (y/n): " confirm + if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi + + for port in $(seq $start_port $end_port); do + local svc_name="${SERVICE_PREFIX}-${port}" + if svc_exists "$svc_name"; then + svc_stop "$svc_name" + svc_disable "$svc_name" + svc_delete "$svc_name" + echo -e "${GREEN}✓${NC} 端口 ${port} 的转发已删除" + fi + done + + svc_daemon_reload + echo -e "${GREEN}批量删除完成!${NC}" +} + +main_menu() { + while true; do + echo "" + echo -e "${GREEN}================================${NC}" + echo -e "${GREEN} 端口转发管理脚本${NC}" + echo -e "${GREEN} (${INIT_SYS} | ${OS})${NC}" + echo -e "${GREEN}================================${NC}" + echo "1. 添加单个端口转发" + echo "2. 批量添加端口转发" + echo "3. 查看所有转发" + echo "4. 重启单个端口转发" + echo "5. 重启所有端口转发" + echo "6. 删除单个端口转发" + echo "7. 批量删除端口转发" + echo -e "8. 🛡️ Watchdog 自动重启管理" + echo -e "9. ⏰ 每日定时重启管理" + echo "0. 退出" + echo -e "${GREEN}================================${NC}" + read -p "请选择操作 [0-9]: " choice + + case $choice in + 1) add_single_forward ;; + 2) add_batch_forward ;; + 3) list_forwards ;; + 4) restart_single_forward ;; + 5) restart_all_forwards ;; + 6) delete_forward ;; + 7) delete_batch_forward ;; + 8) watchdog_menu ;; + 9) daily_restart_menu ;; + 0) echo "退出脚本"; exit 0 ;; + *) echo -e "${RED}无效选择,请重新输入${NC}" ;; + esac + done +} + +if [[ $EUID -ne 0 ]]; then + echo -e "${RED}此脚本必须以 root 权限运行${NC}" + exit 1 +fi + +detect_system +check_deps +main_menu +EOF + +chmod +x /root/port-forward.sh +echo -e "\033[0;32m脚本已创建成功!\033[0m" +echo "运行命令: bash /root/port-forward.sh" \ No newline at end of file