port/port.sh

910 lines
29 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# 安装脚本 - POSIX sh 兼容
# Alpine 下自动安装 bash 和 openrc
if [ -f /etc/alpine-release ]; then
if ! command -v bash > /dev/null 2>&1; then
echo "Alpine 系统检测到,正在安装 bash..."
apk add --no-cache bash
fi
if ! command -v rc-service > /dev/null 2>&1; then
echo "正在安装 OpenRC..."
apk add --no-cache openrc
mkdir -p /run/openrc
touch /run/openrc/softlevel
fi
fi
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
# Alpine 优先走 OpenRC不依赖 systemctl 检测
if [ "$OS" = "alpine" ]; then
if command -v rc-service > /dev/null 2>&1; then
INIT_SYS="openrc"
else
echo -e "${YELLOW}OpenRC 未安装,正在安装...${NC}"
apk add --no-cache openrc
mkdir -p /run/openrc
touch /run/openrc/softlevel
if command -v rc-service > /dev/null 2>&1; then
INIT_SYS="openrc"
else
echo -e "${RED}错误: OpenRC 安装失败${NC}"
exit 1
fi
fi
elif command -v systemctl > /dev/null 2>&1 && [ -d /etc/systemd/system ]; then
INIT_SYS="systemd"
elif command -v rc-service > /dev/null 2>&1; 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 2>&1; then
echo -e "${YELLOW}bash 未安装,正在安装...${NC}"
apk add --no-cache bash
fi
fi
if ! command -v socat > /dev/null 2>&1; 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
}
# 确保使用 bash 执行
if [ -z "$BASH_VERSION" ]; then
if command -v bash > /dev/null 2>&1; then
exec bash "$0" "$@"
else
echo "错误: 需要 bash 来运行此脚本"
exit 1
fi
fi
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"