交互式 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-persistent
与netfilter-persistent
,用于规则持久化
四、脚本设计思路
-
交互式输入:在脚本运行时动态询问目标服务器 IP、TCP/UDP 本地端口和目标端口,支持只配置 TCP、只配置 UDP 或同时配置两种协议。
-
端口去重校验:使用关联数组记录已使用的本地端口,避免重复配置冲突。
-
规则添加:依次插入
INPUT
、nat PREROUTING
、nat POSTROUTING
、FORWARD
规则。 -
持久化与自启动:保存规则到
/etc/iptables/rules.v4
,并通过 systemd 服务在开机时自动恢复。 -
摘要输出:脚本结束后打印配置列表,方便后续查验。
五、交互式配置脚本详解
5.1 定义监听地址
-
默认绑定所有网卡(可改为具体 IP)。
5.2 交互输入
-
提示源服务器 IP
脚本启动时显示默认监听地址,提醒用户无需再输入。 -
是否继续添加
用户可输入yes
/no
来控制是否创建新规则。 -
IP 和端口格式校验
简单正则验证 IP 格式;端口必须为数字且不重复。
5.3 添加端口转发规则
-
INPUT:开放本机监听端口。
-
PREROUTING:实现目标地址转换(DNAT)。
-
POSTROUTING:伪装源地址(MASQUERADE)。
-
FORWARD:允许转发流量。
脚本会对 TCP 与 UDP 分别执行上述流程。
5.4 规则持久化与自启动
-
安装持久化工具
-
保存规则
-
创建 systemd 恢复服务
/etc/systemd/system/iptables-restore.service
内容: -
启用并启动
5.5 校验与摘要输出
脚本最后会打印所有已配置的端口转发,示例:
并提供常用校验命令:
六、常见问题与优化建议
-
重复规则清理
使用iptables -t nat -D …
删除重复或错误条目。 -
并发性能
-
大量规则时,建议将
iptables
命令集中到一次iptables-restore
中执行,减少进程开销。 -
可考虑使用
nftables
,在高流量场景下性能更优。
-
-
日志与监控
在规则链前添加-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

共有 0 条评论