cat > /root/port-forward.sh << 'EOF' #!/bin/bash # 端口转发管理脚本 # 使用 socat 实现端口转发(含自动重启监控) 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' check_socat() { if ! command -v socat &> /dev/null; then echo -e "${YELLOW}socat 未安装,正在安装...${NC}" apt update && apt install socat -y if [ $? -eq 0 ]; then echo -e "${GREEN}socat 安装成功!${NC}" else echo -e "${RED}socat 安装失败,请手动安装${NC}" exit 1 fi 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 cat > /etc/systemd/system/${SERVICE_PREFIX}-${local_port}.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 systemctl daemon-reload systemctl enable ${SERVICE_PREFIX}-${local_port} systemctl start ${SERVICE_PREFIX}-${local_port} if [ $? -eq 0 ]; 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 cat > /etc/systemd/system/${SERVICE_PREFIX}-${port}.service << SERVICEEOF [Unit] Description=Port Forward ${port} to ${target_ip}:${target_port} After=network.target [Service] Type=simple ExecStart=/usr/bin/socat TCP4-LISTEN:${port},reuseaddr,fork TCP4:${target_ip}:${target_port} Restart=always RestartSec=5 StartLimitInterval=0 [Install] WantedBy=multi-user.target SERVICEEOF systemctl enable ${SERVICE_PREFIX}-${port} > /dev/null 2>&1 systemctl start ${SERVICE_PREFIX}-${port} echo -e "${GREEN}✓${NC} 端口 ${port} 转发已创建" done systemctl daemon-reload echo -e "${GREEN}批量端口转发添加完成!${NC}" } list_forwards() { echo -e "${GREEN}=== 当前端口转发列表 ===${NC}" echo "" services=$(systemctl list-units --all --type=service --no-pager | grep ${SERVICE_PREFIX} | grep -v watchdog | awk '{print $1}') if [[ -z "$services" ]]; then echo -e "${YELLOW}暂无端口转发${NC}" else printf "%-15s %-12s %-30s\n" "本机端口" "状态" "转发目标" echo "--------------------------------------------------------" for service in $services; do port=$(echo $service | sed "s/${SERVICE_PREFIX}-//g" | sed 's/.service//g') status=$(systemctl is-active $service) if [[ "$status" == "active" ]]; then status_color="${GREEN}运行中${NC}" else status_color="${RED}已停止${NC}" fi target=$(grep ExecStart /etc/systemd/system/$service 2>/dev/null | grep -oP 'TCP4:\K[^ ]+') printf "%-15s %-20b %-30s\n" "$port" "$status_color" "$target" done fi echo "" watchdog_status=$(systemctl is-active ${WATCHDOG_SERVICE} 2>/dev/null) if [[ "$watchdog_status" == "active" ]]; then echo -e "🛡️ Watchdog: ${GREEN}运行中(自动重启已开启)${NC}" else echo -e "🛡️ Watchdog: ${RED}未运行${NC}(菜单 8 可启动)" fi timer_status=$(systemctl is-active port-forward-daily.timer 2>/dev/null) if [[ "$timer_status" == "active" ]]; then 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 } restart_single_forward() { echo -e "${GREEN}=== 重启单个端口转发 ===${NC}" read -p "请输入要重启的本机端口: " port service_name="${SERVICE_PREFIX}-${port}.service" if [[ ! -f "/etc/systemd/system/$service_name" ]]; then echo -e "${RED}错误: 端口 ${port} 的转发不存在${NC}"; return 1 fi systemctl restart $service_name sleep 1 if [[ "$(systemctl is-active $service_name)" == "active" ]]; then echo -e "${GREEN}✓ 端口 ${port} 重启成功!${NC}" else echo -e "${RED}✗ 重启失败,查看日志: journalctl -u $service_name${NC}" fi } restart_all_forwards() { echo -e "${GREEN}=== 重启所有端口转发 ===${NC}" read -p "确认重启所有转发? (y/n): " confirm if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi services=$(systemctl list-units --all --type=service --no-pager | grep ${SERVICE_PREFIX} | grep -v watchdog | awk '{print $1}') if [[ -z "$services" ]]; then echo -e "${YELLOW}暂无端口转发${NC}"; return fi failed=0; success=0 for service in $services; do port=$(echo $service | sed "s/${SERVICE_PREFIX}-//g" | sed 's/.service//g') systemctl restart $service sleep 0.5 if [[ "$(systemctl is-active $service)" == "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 LOG_FILE="/var/log/port-forward-watchdog.log" SERVICE_PREFIX="port-forward" log() { echo "\$(date '+%Y-%m-%d %H:%M:%S') \$1" | tee -a \$LOG_FILE } log "=== Watchdog 启动,检查间隔: ${interval}秒 ===" while true; do services=\$(systemctl list-units --all --type=service --no-pager | grep \${SERVICE_PREFIX} | grep -v watchdog | awk '{print \$1}') for service in \$services; do status=\$(systemctl is-active \$service) if [[ "\$status" != "active" ]]; then log "⚠ 检测到 \$service 异常(状态: \$status),正在重启..." systemctl restart \$service sleep 2 new_status=\$(systemctl 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} 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 systemctl daemon-reload systemctl enable ${WATCHDOG_SERVICE} systemctl start ${WATCHDOG_SERVICE} if [[ "$(systemctl 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 systemctl stop ${WATCHDOG_SERVICE} 2>/dev/null systemctl disable ${WATCHDOG_SERVICE} 2>/dev/null rm -f /etc/systemd/system/${WATCHDOG_SERVICE}.service rm -f ${WATCHDOG_SCRIPT} systemctl 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 # 每日定时重启所有端口转发服务 LOG_FILE="/var/log/port-forward-daily.log" log() { echo "\$(date '+%Y-%m-%d %H:%M:%S') \$1" | tee -a \$LOG_FILE } log "=== 开始每日定时重启 ===" services=\$(systemctl list-units --all --type=service --no-pager | grep port-forward | grep -v watchdog | grep -v daily | awk '{print \$1}') success=0; failed=0 for service in \$services; do systemctl restart \$service sleep 1 if [[ "\$(systemctl 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 # 创建 systemd service(执行单元) 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 # 创建 systemd timer(定时器) 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 } uninstall_daily_restart() { read -p "确认取消每日定时重启? (y/n): " confirm if [[ "$confirm" != "y" ]]; then echo "操作已取消"; return; fi 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 rm -f /root/port-forward-daily-restart.sh systemctl daemon-reload 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}" timer_status=$(systemctl is-active port-forward-daily.timer 2>/dev/null) if [[ "$timer_status" == "active" ]]; then echo -e "当前状态: ${GREEN}● 已开启${NC}" 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 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}" w_status=$(systemctl is-active ${WATCHDOG_SERVICE} 2>/dev/null) 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) systemctl stop ${WATCHDOG_SERVICE} && echo -e "${GREEN}✓ Watchdog 已停止${NC}" ;; 3) systemctl 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 service_name="${SERVICE_PREFIX}-${port}.service" if [[ ! -f "/etc/systemd/system/$service_name" ]]; then echo -e "${RED}错误: 端口 ${port} 的转发不存在${NC}"; return 1 fi systemctl stop $service_name systemctl disable $service_name rm -f /etc/systemd/system/$service_name systemctl 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 service_name="${SERVICE_PREFIX}-${port}.service" if [[ -f "/etc/systemd/system/$service_name" ]]; then systemctl stop $service_name systemctl disable $service_name > /dev/null 2>&1 rm -f /etc/systemd/system/$service_name echo -e "${GREEN}✓${NC} 端口 ${port} 的转发已删除" fi done systemctl daemon-reload echo -e "${GREEN}批量删除完成!${NC}" } main_menu() { while true; do echo "" echo -e "${GREEN}================================${NC}" echo -e "${GREEN} 端口转发管理脚本${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 check_socat main_menu EOF chmod +x /root/port-forward.sh echo -e "\033[0;32m脚本已创建成功!\033[0m" echo "运行命令: bash /root/port-forward.sh"