在日常的运维工作中,比如有好几台云服务器,但只有一台带有公网IP,其余内网直连,但是针对特殊场景需要把不带有公网IP的某些端口通过带有公网IP的进行转发,实现端口转发的工具或者软件有很多,比如rinetd、nginx等,或者使用iptables的内核转发功能也可以实现,本文主要是使用iptables来实现自动添加、删除、查看端口号
#!/bin/bash
# 检查内核是否已启用 IP 转发
if [[ $(cat /proc/sys/net/ipv4/ip_forward) -ne 1 ]]; then
echo "IP 转发没有开启,现在开启它。"
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
fi
# 检查是否安装了 lsof
if ! command -v lsof &> /dev/null; then
echo "lsof 未安装,正在尝试安装..."
# 检测操作系统类型并安装 lsof
if [[ -f /etc/os-release ]]; then
. /etc/os-release
case $ID in
debian|ubuntu)
sudo apt-get update
sudo apt-get install -y lsof
;;
centos|rhel|fedora)
sudo yum install -y lsof
;;
*)
echo "不支持的操作系统类型。请手动安装lsof。"
exit 1
;;
esac
else
echo "无法检测操作系统类型。请手动安装lsof。"
exit 1
fi
fi
# 添加端口转发的函数
add_nat() {
echo "请输入本机的端口:"
read LOCAL_PORT
# 检查端口是否已经被占用
if lsof -i :$LOCAL_PORT > /dev/null; then
echo "端口 $LOCAL_PORT 在这台机器上已经被占用。"
exit 1
fi
echo "请输入目标 IP:端口(例如 192.168.1.10:22):"
read DEST
# 检查输入格式
if [[ ! $DEST =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+$ ]]; then
echo "目标 IP 或端口格式不正确。"
exit 1
fi
# 添加到 iptables
sudo iptables -t nat -A PREROUTING -p tcp --dport $LOCAL_PORT -j DNAT --to-destination $DEST
echo "端口转发已添加。"
}
# 删除端口转发的函数
delete_nat() {
echo "请输入要删除的本机端口:"
read LOCAL_PORT
echo "请输入目标的IP和端口 (如 192.168.0.18:6379):"
read DEST
# 检查规则是否存在并删除
if sudo iptables -t nat -L PREROUTING -n -v | grep "dpt:$LOCAL_PORT" | grep "$DEST" > /dev/null; then
sudo iptables -t nat -D PREROUTING -p tcp --dport $LOCAL_PORT -j DNAT --to-destination $DEST
echo "端口转发已删除。"
else
echo "未找到相应的规则。"
fi
}
# 显示现有端口转发的函数
list_nat() {
echo "当前的端口转发规则:"
sudo iptables -t nat -L PREROUTING -n -v | grep DNAT
}
# 主逻辑
case "$1" in
add) add_nat ;;
del) delete_nat ;;
list) list_nat ;;
*) echo "使用方式:$0 {add|del|list}" ;;
esac
使用方法:bash nat.sh add 添加 list、查看、del删除