更新 port.sh

This commit is contained in:
chunzhi 2026-03-04 06:59:53 -05:00
parent aff41079f6
commit c06cb76c76

491
port.sh
View File

@ -2,18 +2,18 @@ cat > /root/port-forward.sh << 'EOF'
#!/bin/bash
# 端口转发管理脚本
# 使用 socat 实现端口转发
# 使用 socat 实现端口转发(含自动重启监控)
SCRIPT_NAME="Port Forward Manager"
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'
NC='\033[0m' # No Color
BLUE='\033[0;34m'
NC='\033[0m'
# 检查是否安装 socat
check_socat() {
if ! command -v socat &> /dev/null; then
echo -e "${YELLOW}socat 未安装,正在安装...${NC}"
@ -27,20 +27,16 @@ check_socat() {
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
echo -e "${RED}错误: 输入不能为空${NC}"; return 1
fi
# 创建 systemd 服务
cat > /etc/systemd/system/${SERVICE_PREFIX}-${local_port}.service << SERVICEEOF
[Unit]
Description=Port Forward ${local_port} to ${target_ip}:${target_port}
@ -51,16 +47,16 @@ 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}"
@ -69,28 +65,21 @@ SERVICEEOF
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
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
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]
@ -102,6 +91,7 @@ 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
@ -111,82 +101,414 @@ SERVICEEOF
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} | awk '{print $1}')
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
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
printf "%-15s %-10s %-30s\n" "本机端口" "状态" "转发目标"
echo "--------------------------------------------------------"
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')
status=$(systemctl is-active $service)
if [[ "$status" == "active" ]]; then
status_color="${GREEN}运行中${NC}"
systemctl restart $service
sleep 0.5
if [[ "$(systemctl is-active $service)" == "active" ]]; then
echo -e "${GREEN}${NC} 端口 ${port} 重启成功"; ((success++))
else
status_color="${RED}已停止${NC}"
echo -e "${RED}${NC} 端口 ${port} 重启失败"; ((failed++))
fi
# 从服务文件中提取目标信息
target=$(grep ExecStart /etc/systemd/system/$service | grep -oP 'TCP4:\K[^ ]+')
printf "%-15s %-20b %-30s\n" "$port" "$status_color" "$target"
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
if [[ -z "$port" ]]; then
echo -e "${RED}错误: 端口不能为空${NC}"
return 1
fi
service_name="${SERVICE_PREFIX}-${port}.service"
if [[ ! -f "/etc/systemd/system/$service_name" ]]; then
echo -e "${RED}错误: 端口 ${port} 的转发不存在${NC}"
return 1
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
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
@ -196,54 +518,55 @@ delete_batch_forward() {
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 -e "${GREEN}================================${NC}"
echo "1. 添加单个端口转发"
echo "2. 批量添加端口转发"
echo "3. 查看所有转发"
echo "4. 删除单个端口转发"
echo "5. 批量删除端口转发"
echo "6. 退出"
echo "4. 重启单个端口转发"
echo "5. 重启所有端口转发"
echo "6. 删除单个端口转发"
echo "7. 批量删除端口转发"
echo -e "8. 🛡️ Watchdog 自动重启管理"
echo -e "9. ⏰ 每日定时重启管理"
echo "0. 退出"
echo -e "${GREEN}================================${NC}"
read -p "请选择操作 [1-6]: " choice
read -p "请选择操作 [0-9]: " choice
case $choice in
1) add_single_forward ;;
2) add_batch_forward ;;
3) list_forwards ;;
4) delete_forward ;;
5) delete_batch_forward ;;
6) echo "退出脚本"; exit 0 ;;
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
}
# 检查是否为 root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}此脚本必须以 root 权限运行${NC}"
echo -e "${RED}此脚本必须以 root 权限运行${NC}"
exit 1
fi
# 检查并安装 socat
check_socat
# 启动主菜单
main_menu
EOF
# 设置执行权限
chmod +x /root/port-forward.sh
echo -e "\033[0;32m脚本已创建成功\033[0m"
echo "运行命令: bash /root/port-forward.sh"