交互式 Bash 脚本:快速实现 Linux 服务器 TCP/UDP 端口转发与持久化

一、背景与目的

在多服务器架构或内外网隔离的场景下,经常需要将外网访问请求通过一台跳板机(或网关机)转发到内部服务器的指定服务端口。手工配置 iptables 命令容易出错、重复且难以维护,本文通过一个交互式脚本示例,讲解如何快速、可靠地在服务器上实现 TCP/UDP 端口转发,并保证在重启后规则持续生效。


二、端口转发原理简介

Linux 上的端口转发主要依赖 netfilter 框架中的以下机制:

  • PREROUTING(nat 表):对进入本机的数据包进行 DNAT(目标地址转换),将目标 IP:Port 改为后端服务器的 IP:Port。

  • POSTROUTING(nat 表):对出站到后端服务器的流量做 MASQUERADE(源地址伪装),确保后端服务器的响应回到跳板机。

  • FORWARD(filter 表):允许转发后的数据包在内核中流转。

  • INPUT(filter 表):开放跳板机本地监听端口,允许外部访问。

  • sysctl net.ipv4.ip_forward=1:开启内核 IP 转发功能。


三、环境与前置条件

  • 操作系统:Debian/Ubuntu 系列

  • 已安装 Bash 与 iptables 工具

  • 具备 root 权限

  • 安装包:iptables-persistentnetfilter-persistent,用于规则持久化


四、脚本设计思路

  1. 交互式输入:在脚本运行时动态询问目标服务器 IP、TCP/UDP 本地端口和目标端口,支持只配置 TCP、只配置 UDP 或同时配置两种协议。

  2. 端口去重校验:使用关联数组记录已使用的本地端口,避免重复配置冲突。

  3. 规则添加:依次插入 INPUTnat PREROUTINGnat POSTROUTINGFORWARD 规则。

  4. 持久化与自启动:保存规则到 /etc/iptables/rules.v4,并通过 systemd 服务在开机时自动恢复。

  5. 摘要输出:脚本结束后打印配置列表,方便后续查验。


五、交互式配置脚本详解

5.1 定义监听地址

# 默认对外监听地址
SOURCE_IP="0.0.0.0"
  • 默认绑定所有网卡(可改为具体 IP)。

5.2 交互输入

  • 提示源服务器 IP
    脚本启动时显示默认监听地址,提醒用户无需再输入。

  • 是否继续添加
    用户可输入 yes/no 来控制是否创建新规则。

  • IP 和端口格式校验
    简单正则验证 IP 格式;端口必须为数字且不重复。

5.3 添加端口转发规则

# 仅示例:对 TCP 进行端口转发
iptables -I INPUT -p tcp --dport ${src} -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport ${src} -j DNAT --to-destination ${ip}:${dst}
iptables -t nat -A POSTROUTING -d ${ip} -p tcp --dport ${dst} -j MASQUERADE
iptables -A FORWARD -d ${ip} -p tcp --dport ${dst} -j ACCEPT
iptables -A FORWARD -s ${ip} -p tcp --sport ${dst} -j ACCEPT
  • INPUT:开放本机监听端口。

  • PREROUTING:实现目标地址转换(DNAT)。

  • POSTROUTING:伪装源地址(MASQUERADE)。

  • FORWARD:允许转发流量。

脚本会对 TCP 与 UDP 分别执行上述流程。

5.4 规则持久化与自启动

  1. 安装持久化工具

    DEBIAN_FRONTEND=noninteractive \
    apt-get update && apt-get install -y iptables-persistent netfilter-persistent
  2. 保存规则

    mkdir -p /etc/iptables
    iptables-save > /etc/iptables/rules.v4
  3. 创建 systemd 恢复服务
    /etc/systemd/system/iptables-restore.service 内容:

    [Unit]
    Description=Restore iptables rules
    Before=network-pre.target
    [Service]
    Type=oneshot
    ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
    RemainAfterExit=yes

    [Install]
    WantedBy=multi-user.target

  4. 启用并启动

    systemctl daemon-reload
    systemctl enable iptables-restore.service
    systemctl start netfilter-persistent
    systemctl enable netfilter-persistent

5.5 校验与摘要输出

脚本最后会打印所有已配置的端口转发,示例:

✅ 当前端口转发配置:
----------------------------------------

源服务器: 0.0.0.0
目标: 12.22.222.22
TCP: 0.0.0.0:9090 -> 12.22.222.22:8080
UDP: 0.0.0.0:7070 -> 12.22.222.22:6060
----------------------------------------

并提供常用校验命令:

iptables -L -n -v
iptables -t nat -L -n -v
nc -vz [目标IP] [端口]
systemctl status iptables-restore.service
systemctl status netfilter-persistent

六、常见问题与优化建议

  1. 重复规则清理
    使用 iptables -t nat -D … 删除重复或错误条目。

  2. 并发性能

    • 大量规则时,建议将 iptables 命令集中到一次 iptables-restore 中执行,减少进程开销。

    • 可考虑使用 nftables,在高流量场景下性能更优。

  3. 日志与监控
    在规则链前添加 -j LOG,将转发流量写入系统日志,便于排障。


七、总结

通过一个交互式脚本,可以极大简化端口转发配置过程,避免手动输入繁琐命令、降低出错风险,并实现规则持久化与自动恢复。本文示例可根据实际场景扩展,例如批量导入、Web 界面管理或与容器编排集成,进一步提升可维护性和自动化程度。

希望这篇文章能帮助你快速上手并灵活运用服务器端口转发。

 

 

#!/bin/bash
###########################################
# 多服务器端口转发配置脚本(交互输入优化版)
###########################################

# 默认对外监听地址
SOURCE_IP="0.0.0.0"
declare -A SERVER_CONFIGS
declare -A USED_PORTS

# 检查端口是否已被使用
check_port_duplicate() {
    local port=$1
    if [[ -n "${USED_PORTS[$port]}" ]]; then
        echo "❌ 端口 $port 已被使用,请重新输入。"
        return 1
    fi
    return 0
}

# 添加服务器配置(支持仅TCP/仅UDP/同时添加)
add_server_config() {
    echo "源服务器 IP: $SOURCE_IP (默认)"
    while true; do
        read -rp "是否添加新服务器?[yes/no] (默认 yes): " add_more
        add_more=${add_more:-yes}
        [[ "$add_more" =~ ^[Nn] ]] && break

        read -rp "请输入目标服务器 IP (例如 12.22.222.22): " server_ip
        if [[ ! "$server_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
            echo "⚠️ IP 格式不正确,请重新输入。"
            continue
        fi

        # TCP 端口输入(可选)
        tcp_src=""; tcp_dst=""
        read -rp "请输入要转发的 TCP 本地端口(留空跳过TCP转发): " tcp_src
        if [[ -n "$tcp_src" ]]; then
            if ! [[ "$tcp_src" =~ ^[0-9]+$ ]] || ! check_port_duplicate "$tcp_src"; then
                echo "⚠️ TCP 源端口无效或重复。"
                continue
            fi
            read -rp "请输入 TCP 目标端口: " tcp_dst
        fi

        # UDP 端口输入(可选)
        udp_src=""; udp_dst=""
        read -rp "请输入要转发的 UDP 本地端口(留空跳过UDP转发): " udp_src
        if [[ -n "$udp_src" ]]; then
            if ! [[ "$udp_src" =~ ^[0-9]+$ ]] || ! check_port_duplicate "$udp_src"; then
                echo "⚠️ UDP 源端口无效或重复。"
                continue
            fi
            read -rp "请输入 UDP 目标端口: " udp_dst
        fi

        if [[ -z "$tcp_src" && -z "$udp_src" ]]; then
            echo "⚠️ 请至少配置 TCP 或 UDP 端口之一。"
            continue
        fi

        # 保存配置并标记端口
        SERVER_CONFIGS["$server_ip"]="$tcp_src:$tcp_dst $udp_src:$udp_dst"
        [[ -n "$tcp_src" ]] && USED_PORTS["$tcp_src"]=1
        [[ -n "$udp_src" ]] && USED_PORTS["$udp_src"]=1

        echo "✅ 已添加: $server_ip"
        [[ -n "$tcp_src" ]] && echo "   - TCP 转发: $SOURCE_IP:$tcp_src -> $server_ip:$tcp_dst"
        [[ -n "$udp_src" ]] && echo "   - UDP 转发: $SOURCE_IP:$udp_src -> $server_ip:$udp_dst"
    done
}

install_required_packages() {
    echo -e "\n步骤1: 安装必要的软件包..."
    DEBIAN_FRONTEND=noninteractive apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y iptables-persistent netfilter-persistent
}

setup_port_forward() {
    local ip="$1" proto="$2" src="$3" dst="$4"
    echo "配置 $proto 转发: $SOURCE_IP:$src -> $ip:$dst"
    iptables -I INPUT -p "$proto" --dport "$src" -j ACCEPT
    iptables -t nat -A PREROUTING -p "$proto" --dport "$src" -j DNAT --to-destination "$ip:$dst"
    iptables -t nat -A POSTROUTING -d "$ip" -p "$proto" --dport "$dst" -j MASQUERADE
    iptables -A FORWARD -d "$ip" -p "$proto" --dport "$dst" -j ACCEPT
    iptables -A FORWARD -s "$ip" -p "$proto" --sport "$dst" -j ACCEPT
}

setup_autostart_service() {
    cat >/etc/systemd/system/iptables-restore.service <<EOF
[Unit]
Description=Restore iptables rules
Before=network-pre.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload && systemctl enable iptables-restore.service
}

# 仅 root 可运行
[[ $EUID -ne 0 ]] && { echo "请使用 root 权限运行脚本。"; exit 1; }

# 执行配置流程
add_server_config
install_required_packages

echo -e "\n步骤2: 开启 IP 转发..."
if ! grep -q '^net.ipv4.ip_forward=1' /etc/sysctl.conf; then
    echo 'net.ipv4.ip_forward=1' >>/etc/sysctl.conf
fi
sysctl -p

echo -e "\n步骤3: 应用所有转发规则..."
for ip in "${!SERVER_CONFIGS[@]}"; do
    IFS=' ' read -r tcp_cfg udp_cfg <<<"${SERVER_CONFIGS[$ip]}"
    if [[ "${tcp_cfg%%:*}" ]]; then
        setup_port_forward "$ip" tcp "${tcp_cfg%%:*}" "${tcp_cfg#*:}"
    fi
    if [[ "${udp_cfg%%:*}" ]]; then
        setup_port_forward "$ip" udp "${udp_cfg%%:*}" "${udp_cfg#*:}"
    fi
done

echo -e "\n步骤4: 保存规则到 /etc/iptables/rules.v4"
mkdir -p /etc/iptables
iptables-save >/etc/iptables/rules.v4

setup_autostart_service

echo -e "\n步骤5: 启动并启用持久化服务"
systemctl start netfilter-persistent && systemctl enable netfilter-persistent

# 输出摘要
cat <<EOF

✅ 当前端口转发配置:
----------------------------------------
源服务器: $SOURCE_IP
EOF
for ip in "${!SERVER_CONFIGS[@]}"; do
    IFS=' ' read -r tcp_cfg udp_cfg <<<"${SERVER_CONFIGS[$ip]}"
    echo "目标: $ip"
    [[ "${tcp_cfg%%:*}" ]] && echo "  TCP: $SOURCE_IP:${tcp_cfg%%:*} -> $ip:${tcp_cfg#*:}"
    [[ "${udp_cfg%%:*}" ]] && echo "  UDP: $SOURCE_IP:${udp_cfg%%:*} -> $ip:${udp_cfg#*:}"
done
echo "----------------------------------------"

cat <<'END'

🔍 验证示例:
 1. iptables -L -n -v
 2. iptables -t nat -L -n -v
 3. nc -vz [目标IP] [端口]
 4. systemctl status iptables-restore.service
 5. systemctl status netfilter-persistent
END

 

版权声明:本文内容采用 CC BY-NC-SA 4.0 协议许可,转载请注明
文章名称:交互式 Bash 脚本:快速实现 Linux 服务器 TCP/UDP 端口转发与持久化
文章链接:https://www.baizi.net/chatgpt/407.html
文章链接:https://www.baizi.net/chatgpt/407.html
根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24小时内从您的设备中彻底删除下载内容,否则一切后果请您自行承担,如果您喜欢该程序,请购买注册正版以得到更好的服务。
联系方式(#替换成@):serverr#baizi.net

THE END
分享
二维码
海报
交互式 Bash 脚本:快速实现 Linux 服务器 TCP/UDP 端口转发与持久化
一、背景与目的 在多服务器架构或内外网隔离的场景下,经常需要将外网访问请求通过一台跳板机(或网关机)转发到内部服务器的指定服务端口。手工配置 iptables……
<<上一篇
下一篇>>