Linux 端口映射管理脚本
Linux 端口映射管理脚本
使用方法:bash port_map.sh
点击查看代码
#!/bin/bash
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}请使用 root 权限运行${NC}"
exit 1
fi
declare -A map_list
map_count=0
check_ip() {
local ip=$1
if [[ ! $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then return 1; fi
IFS=. read -r a b c d <<< "$ip"
((a>=0&&a<=255&&b>=0&&b<=255&&c>=0&&c<=255&&d>=0&&d<=255))
}
check_port() {
local port=$1
[[ $port =~ ^[0-9]+$ ]] && ((port >=1 && port <=65535))
}
enable_ip_forward() {
echo 1 > /proc/sys/net/ipv4/ip_forward
grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf || echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p &>/dev/null
}
load_mapping_list() {
map_list=()
map_count=0
local line
while read line; do
local dport to_ip to_port
dport=$(echo "$line" | grep -oP 'dpt:\K\d+' 2>/dev/null | head -1)
to=$(echo "$line" | grep -oP 'to-destination:\K[\d.]+:\d+' 2>/dev/null) || to=$(echo "$line" | grep -oP 'to:\K[\d.]+:\d+' 2>/dev/null)
to_ip=${to%:*}
to_port=${to#*:}
if [ -n "$dport" ] && [ -n "$to_ip" ] && [ -n "$to_port" ]; then
((map_count++))
map_list[$map_count]="$dport|$to_ip|$to_port"
fi
done < <(iptables -t nat -L PREROUTING 2>/dev/null | grep -E 'DNAT|to-destination')
}
show_mapping_list() {
load_mapping_list
echo -e "\n${GREEN}=== 当前端口映射列表 ===${NC}"
echo -e "${YELLOW}序号 本机端口 → 目标IP:端口${NC}"
echo "-----------------------------------------"
if [ $map_count -eq 0 ]; then
echo -e "${YELLOW} 暂无映射规则${NC}"
else
for i in "${!map_list[@]}"; do
IFS='|' read -r dport to_ip to_port <<< "${map_list[$i]}"
echo -e " $i) $dport → $to_ip:$to_port"
done
fi
echo "-----------------------------------------"
}
add_forward() {
local to_ip=$1
local port=$2
iptables -t nat -D PREROUTING -p tcp --dport "$port" -j DNAT --to-destination "${to_ip}:${port}" 2>/dev/null
iptables -t nat -D POSTROUTING -d "$to_ip" -p tcp --dport "$port" -j MASQUERADE 2>/dev/null
iptables -D FORWARD -p tcp -d "$to_ip" --dport "$port" -j ACCEPT 2>/dev/null
iptables -t nat -A PREROUTING -p tcp --dport "$port" -j DNAT --to-destination "${to_ip}:${port}"
iptables -t nat -A POSTROUTING -d "$to_ip" -p tcp --dport "$port" -j MASQUERADE
iptables -A FORWARD -p tcp -d "$to_ip" --dport "$port" -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null
}
delete_forward_rule() {
local dport=$1
local to_ip=$2
local to_port=$3
iptables -t nat -D PREROUTING -p tcp --dport "$dport" -j DNAT --to-destination "${to_ip}:${to_port}" 2>/dev/null
iptables -t nat -D POSTROUTING -d "$to_ip" -p tcp --dport "$to_port" -j MASQUERADE 2>/dev/null
iptables -D FORWARD -p tcp -d "$to_ip" --dport "$to_port" -j ACCEPT 2>/dev/null
}
# ==================== 智能修改 ====================
modify_forward() {
show_mapping_list
if [ $map_count -eq 0 ]; then return; fi
read -p "请输入要修改的规则序号: " idx
if [ -z "${map_list[$idx]-}" ]; then
echo -e "${RED}无效序号${NC}"
return
fi
IFS='|' read -r old_port old_to_ip old_to_port <<< "${map_list[$idx]}"
echo -e "\n${YELLOW}当前规则:$old_port → $old_to_ip:$old_to_port${NC}"
read -p "新的目标IP [直接回车使用原IP]: " new_to_ip
new_to_ip=${new_to_ip:-$old_to_ip}
read -p "新的端口 [直接回车使用原端口]: " new_port
new_port=${new_port:-$old_port}
if ! check_ip "$new_to_ip"; then
echo -e "${RED}IP 格式错误${NC}"
return
fi
if ! check_port "$new_port"; then
echo -e "${RED}端口格式错误${NC}"
return
fi
# 删除旧的
delete_forward_rule "$old_port" "$old_to_ip" "$old_to_port"
# 添加新的
enable_ip_forward
add_forward "$new_to_ip" "$new_port"
echo -e "${GREEN}✔ 修改完成!${NC}"
echo -e "旧:$old_port → $old_to_ip:$old_to_port"
echo -e "新:$new_port → $new_to_ip:$new_port"
}
menu() {
while true; do
clear
echo -e "====== ${GREEN}Linux 端口映射管理脚本${NC} ======"
echo -e "当前本机IP: ${GREEN}$(hostname -I | awk '{print $1}')${NC}"
echo "1. 添加端口映射"
echo "2. 删除端口映射"
echo "3. 修改端口映射"
echo "4. 查看当前映射列表"
echo "5. 保存规则(重启不失效)"
echo "0. 退出"
echo "========================================"
read -p "请选择操作 [0-5]: " choice
case $choice in
1)
echo -e "\n${GREEN}=== 添加端口映射 ===${NC}"
read -p "目标内网IP: " to_ip
read -p "映射端口: " port
if check_ip "$to_ip" && check_port "$port"; then
enable_ip_forward
add_forward "$to_ip" "$port"
echo -e "${GREEN}✔ 添加成功${NC}"
echo "映射: 本机 $port → $to_ip:$port"
echo "测试: nc -zv $(hostname -I | awk '{print $1}') $port"
else
echo -e "${RED}IP或端口格式错误${NC}"
fi
;;
2)
show_mapping_list
[ $map_count -eq 0 ] && continue
read -p "输入要删除的序号: " idx
IFS='|' read -r dport to_ip to_port <<< "${map_list[$idx]}"
delete_forward_rule "$dport" "$to_ip" "$to_port"
echo -e "${GREEN}✔ 删除成功${NC}"
;;
3) modify_forward ;;
4) show_mapping_list ;;
5)
iptables-save > /etc/sysconfig/iptables 2>/dev/null || iptables-save >/dev/null
echo -e "${GREEN}✔ 规则已保存,重启不失效${NC}"
;;
0) echo -e "${GREEN}已退出${NC}"; exit 0 ;;
*) echo -e "${RED}输入错误,请重试${NC}" ;;
esac
echo -e "\n按回车返回菜单..."
read
done
}
menu
浙公网安备 33010602011771号