端口转发原理h2
端口转发(Port Forwarding), 也称为端口映射(Port Mapping),是一种网络技术,它允许将网络流量从一个 IP 地址和端口重定向到另一个 IP 地址和端口。 在 Linux 系统中, 我们通常使用 iptables
工具来实现端口转发。
基础防火墙规则配置h2
在开始配置端口转发之前,我们需要先配置一些基础的防火墙规则,包括开启 IP 转发、允许转发流量和配置 NAT 表。
echo 1 > /proc/sys/net/ipv4/ip_forward # 开启 IP 转发iptables -A FORWARD -j ACCEPT # 允许转发iptables -t nat -A POSTROUTING -j MASQUERADE # 配置 NAT 表
解释:
echo 1 > /proc/sys/net/ipv4/ip_forward
: 开启 IP 转发功能,允许 Linux 系统作为路由器转发数据包。iptables -A FORWARD -j ACCEPT
: 允许所有转发流量通过防火墙,即允许从一个网卡转发到另一个网卡的数据包。iptables -t nat -A POSTROUTING -j MASQUERADE
: 配置网络地址转换(NAT), 将转发的数据包的源 IP 地址转换为本机 IP 地址,以便目标机器能够正常响应。
添加端口转发规则h2
以下示例展示了如何将本地端口 80 的流量转发到 192.168.2.123
的 80 端口。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.2.123:80iptables -t nat -A POSTROUTING -p tcp -d 192.168.2.123 --dport 80 -j MASQUERADE
解释:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.2.123:80
:-t nat
: 指定操作的表为 NAT 表,用于网络地址转换。-A PREROUTING
: 将规则添加到PREROUTING
链,该链用于处理进入本机的数据包。-p tcp
: 指定协议为 TCP。--dport 80
: 指定目标端口为 80。-j DNAT
: 执行目标地址转换(DNAT)。--to-destination 192.168.2.123:80
: 将目标地址转换为192.168.2.123:80
。
iptables -t nat -A POSTROUTING -p tcp -d 192.168.2.123 --dport 80 -j MASQUERADE
:-t nat
: 指定操作的表为 NAT 表。-A POSTROUTING
: 将规则添加到POSTROUTING
链,该链用于处理即将离开本机的数据包。-p tcp
: 指定协议为 TCP。-d 192.168.2.123
: 指定目标 IP 地址为192.168.2.123
。--dport 80
: 指定目标端口为80.-j MASQUERADE
: 执行地址伪装,将源 IP 地址转换为本机 IP 地址。
删除端口转发规则h2
以下示例展示了如何删除将本地端口 80 的流量转发到 192.168.2.123
的 80 端口的规则。
iptables -t nat -D PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.2.123:80iptables -t nat -D POSTROUTING -p tcp -d 192.168.2.123 --dport 80 -j MASQUERADE
解释:
- 与添加规则类似,只是将
-A
改为-D
,表示删除规则。
查看转发规则h2
使用以下命令可以查看当前配置的端口转发规则:
iptables -t nat -L -n
解释:
-t nat
: 指定查看 NAT 表。-L
: 列出规则。-n
: 使用数字格式显示 IP 地址和端口,而不是使用主机名和服务名。
端口转发管理脚本h2
为了方便管理端口转发规则,我们提供了一个 forward_port
脚本。 该脚本可以帮助您更方便地添加、删除和查看转发规则。
使用方法h3
以下是一些脚本的使用示例:
root@localhost:~# forward_port list当前端口转发规则列表:----------------------------------------[TCP] 本地端口: 8000 转发目标: 192.168.2.142:8000root@localhost:~# forward_port add tcp 8001 100.88.88.104 8000添加完成root@localhost:~# forward_port list当前端口转发规则列表:----------------------------------------[TCP] 本地端口: 8000 转发目标: 192.168.2.142:8000[TCP] 本地端口: 8001 转发目标: 100.88.88.104:8000root@localhost:~# forward_port del tcp 8001删除完成root@localhost:~# forward_port list当前端口转发规则列表:----------------------------------------[TCP] 本地端口: 8000 转发目标: 192.168.2.142:8000
脚本代码h3
以下是 forward_port
脚本的完整代码:
#!/bin/bash
# 检查是否具有 root 权限if [ "$EUID" -ne 0 ]; then echo "请使用 sudo 运行此脚本" exit 1fi
# 显示帮助信息show_help() { echo "用法:" echo " $0 list # 显示所有端口转发规则" echo " $0 add tcp|udp 本地端口 目标IP 目标端口 # 添加转发规则" echo " $0 del tcp|udp 本地端口 # 删除转发规则" echo "" echo "示例:" echo " $0 add tcp 8080 192.168.1.100 80" echo " $0 del tcp 8080"}
# 列出当前转发规则list_forwards() { # 获取 PREROUTING 规则 rules=$(iptables -t nat -L PREROUTING -n --line-numbers | grep "dpt:" | grep "to:")
if [ -z "$rules" ]; then echo "当前没有端口转发规则" return fi
echo "当前端口转发规则列表:" echo "----------------------------------------"
while IFS= read -r line; do # 提取规则信息 protocol=$(echo "$line" | grep -o 'tcp\|udp' | tr '[:lower:]' '[:upper:]') local_port=$(echo "$line" | grep -o 'dpt:[0-9]*' | cut -d':' -f2) target=$(echo "$line" | grep -o 'to:[0-9.]*:[0-9]*' | cut -d':' -f2,3)
if [ ! -z "$protocol" ] && [ ! -z "$local_port" ] && [ ! -z "$target" ]; then target_ip=$(echo "$target" | cut -d':' -f1) target_port=$(echo "$target" | cut -d':' -f2) echo "[$protocol] 本地端口: $local_port 转发目标: $target_ip:$target_port" fi done <<< "$rules"}
# 检查转发规则是否已存在check_forward_exists() { local proto=$1 local port=$2
iptables -t nat -L PREROUTING -n | grep "dpt:$port" | grep -q "$proto" return $?}
# 添加转发规则add_forward() { local proto=$1 local local_port=$2 local target_ip=$3 local target_port=$4
# 验证参数 if [[ ! "$proto" =~ ^(tcp|udp)$ ]]; then echo "错误: 协议必须是 tcp 或 udp" return 1 fi
if [[ ! "$local_port" =~ ^[0-9]+$ ]] || [ "$local_port" -lt 1 ] || [ "$local_port" -gt 65535 ]; then echo "错误: 无效的端口号 $local_port" return 1 fi
if [[ ! "$target_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "错误: 无效的 IP 地址 $target_ip" return 1 fi
if [[ ! "$target_port" =~ ^[0-9]+$ ]] || [ "$target_port" -lt 1 ] || [ "$target_port" -gt 65535 ]; then echo "错误: 无效的目标端口号 $target_port" return 1 fi
# 检查规则是否已存在 if check_forward_exists "$proto" "$local_port"; then echo "${proto^^} $local_port 已经有转发规则了" return 1 fi
# 添加转发规则 iptables -t nat -A PREROUTING -p "$proto" --dport "$local_port" -j DNAT --to-destination "$target_ip:$target_port" iptables -t nat -A POSTROUTING -p "$proto" -d "$target_ip" --dport "$target_port" -j MASQUERADE
if [ $? -eq 0 ]; then echo "添加完成" else echo "添加失败" return 1 fi}
# 删除转发规则del_forward() { local proto=$1 local port=$2
# 验证参数 if [[ ! "$proto" =~ ^(tcp|udp)$ ]]; then echo "错误: 协议必须是 tcp 或 udp" return 1 fi
if [[ ! "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then echo "错误: 无效的端口号 $port" return 1 fi
# 检查规则是否存在 if ! check_forward_exists "$proto" "$port"; then echo "未找到 ${proto^^} 端口 $port 的转发规则" return 1 fi
# 获取目标地址信息用于删除 POSTROUTING 规则 target_info=$(iptables -t nat -L PREROUTING -n | grep "dpt:$port" | grep "$proto") target_ip=$(echo "$target_info" | grep -o 'to:[0-9.]*:[0-9]*' | cut -d':' -f2) target_port=$(echo "$target_info" | grep -o 'to:[0-9.]*:[0-9]*' | cut -d':' -f3)
# 删除规则 iptables -t nat -D PREROUTING -p "$proto" --dport "$port" -j DNAT --to-destination "$target_ip:$target_port" 2>/dev/null iptables -t nat -D POSTROUTING -p "$proto" -d "$target_ip" --dport "$target_port" -j MASQUERADE 2>/dev/null
if [ $? -eq 0 ]; then echo "删除完成" else echo "删除失败" return 1 fi}
# 主程序case "$1" in list) list_forwards ;; add) if [ $# -ne 5 ]; then echo "错误: add 命令需要4个参数" show_help exit 1 fi add_forward "$2" "$3" "$4" "$5" ;; del) if [ $# -ne 3 ]; then echo "错误: del 命令需要2个参数" show_help exit 1 fi del_forward "$2" "$3" ;; *) show_help exit 1 ;;esac
exit 0
脚本使用说明:
forward_port list
: 列出当前所有端口转发规则。forward_port add tcp|udp 本地端口 目标IP 目标端口
: 添加新的端口转发规则。tcp|udp
: 指定协议。本地端口
: 要监听的本地端口。目标IP
: 要转发的目标 IP 地址。目标端口
: 要转发的目标端口。
forward_port del tcp|udp 本地端口
: 删除指定的端口转发规则。tcp|udp
: 指定协议。本地端口
: 要删除的转发规则对应的本地端口。
总结h2
本文档介绍了如何在 Linux 系统中配置端口转发,包括手动配置 iptables
规则以及使用提供的 forward_port
脚本进行管理。希望这些内容能够帮助您更好地理解和使用 Linux 的端口转发功能。