通过iptables实现共享上网及端口代理转发

一、环境准备

虚拟机器1:
1、NAT网:192.168.183.131 (可上外网)
2、LAN网:10.0.0.1

虚拟机器2:
LAN网:10.0.0.100

虚拟机器3:
LAN网:10.0.0.200

二、通过iptables进行SNAT(源地址转换)实现共享上网

目标:虚拟机器2和3 通过 虚拟机器1 共享上网
操作步骤:

# 在虚拟机器2和3上,默认网关指向1机器
# 设置默认网关,也可以在后面加上dev ens33
ip route add default via 10.0.0.1  

# 在虚拟机器1:
# 增加网卡设置静态IP为:10.0.0.1
# 调整iptables环境(初始化环境)
# 修改内核转发:
# 编辑/etc/sysctl.conf修改内容为net.ipv4.ip_forward = 1,然后执行sysctl -p使修改生效。
# 临时改变某个指定参数的值,如
sysctl -w net.ipv4.ip_forward=0
# 测试:ping www.baidu.com 结果通。
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
# 清空NAT表
iptables -t nat -F
  
# 方法1:适合于有固定外网地址的:
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o ens33 -j SNAT --to-source 192.168.183.131
# 方法2:适合变化外网地址(拨号上网):
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE    ##伪装
# 保存规则
[root@vms-ctos7-it-route131 ~]# iptables-save
# Generated by iptables-save v1.4.21 on Sun Dec 19 21:34:39 2021
*nat
:PREROUTING ACCEPT [2:154]
:INPUT ACCEPT [1:78]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -d 192.168.183.131/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.100:80
-A POSTROUTING -s 10.0.0.0/24 -o ens33 -j SNAT --to-source 192.168.183.131
COMMIT
# Completed on Sun Dec 19 21:34:39 2021
# Generated by iptables-save v1.4.21 on Sun Dec 19 21:34:39 2021
*filter
:INPUT ACCEPT [1030:54088]
:FORWARD ACCEPT [4:304]
:OUTPUT ACCEPT [1527:157352]
COMMIT
# Completed on Sun Dec 19 21:34:39 2021
[root@vms-ctos7-it-route131 ~]#

以上完成,即可上网(共享上网,不需要开启防火墙)。

三、通过iptables进行DNAT(目标地址转换)

目标:通过访问虚拟机器1的80端口,代理访问虚拟机2的nginx80端口
操作步骤:

# 1、虚拟机2安装nginx,验证服务是否正常
# 通过 192.168.183.131传输rpm包
scp nginx-1.20.1-1.el7.ngx.x86_64.rpm root@10.0.0.100:/root
# 在10.0.0.100执行安装
rpm -ivh nginx-1.20.1-1.el7.ngx.x86_64.rpm
# 开启并查看状态
systemctl start nginx
systemctl status nginx

# 回到192.168.183.131查看是否OK
[root@vms-ctos7-it-route131 ~]# curl http://10.0.0.100/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@vms-ctos7-it-route131 ~]#
# 此时,nginx已经启动成功!下面实现,访问192.168.183.131时,能访问nginx。

# 2、netfilter添加DSAT转换规则:
iptables -t nat -A PREROUTING -d 192.168.183.131  -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.100:80
# 3、同样开启内核转发
# 修改内核转发:
# 编辑/etc/sysctl.conf修改内容为net.ipv4.ip_forward = 1,然后执行sysctl -p使修改生效。
# 临时改变某个指定参数的值,如
sysctl -w net.ipv4.ip_forward=0
# 测试:ping www.baidu.com 结果通。
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
# 清空NAT表
iptables -t nat -F

此时,在浏览器上,输入192.168.183.131 即可访问到nginx页面。
由此可见,iptables作端口转发,也是非常简单的(转发,不需要开启防火墙)。

PS:以上两种情况,相关配置情况:

[root@vms-ctos7-it-route131 ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       tcp  --  0.0.0.0/0            192.168.183.131      tcp dpt:80 to:10.0.0.100:80

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.0.0/24          0.0.0.0/0
[root@vms-ctos7-it-route131 ~]#
[root@vms-ctos7-it-route131 ~]#  cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="8ff57dc6-0440-456a-b52f-744e2f0f808d"
DEVICE="ens33"
ONBOOT="yes"

[root@vms-ctos7-it-route131 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens37
TYPE="Ethernet"
BOOTPROTO="static"
DEFROUTE="no"
NAME="ens37"
DEVICE="ens37"
ONBOOT="yes"
IPADDR=10.0.0.1
NETMASK=255.255.255.0

# 模拟真实机器1
[root@vms-ctos7-it-real1 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="8ff57dc6-0440-456a-b52f-744e2f0f808d"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=10.0.0.100
NETMASK=255.255.255.0
DNS1=8.8.8.8
[root@vms-ctos7-it-real1 ~]# ip route
default via 10.0.0.1 dev ens33
10.0.0.0/24 dev ens33 proto kernel scope link src 10.0.0.100 metric 100
[root@vms-ctos7-it-real1 ~]#

# 模拟真实机器2
[root@vms-ctos7-it-real2 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="8ff57dc6-0440-456a-b52f-744e2f0f808d"
DEVICE="ens33"
ONBOOT="yes"
IPADDR=10.0.0.200
NETMASK=255.255.255.0
DNS1=8.8.8.8
[root@vms-ctos7-it-real2 ~]# ip route list
default via 10.0.0.1 dev ens33
10.0.0.0/24 dev ens33 proto kernel scope link src 10.0.0.200 metric 100
[root@vms-ctos7-it-real2 ~]#

相关命令集合:

# 显示网卡IP信息
ip addr       
# 显示ens33网卡IP信息
ip addr show ens33
# 开启或关闭ens33网卡
ip link set ens33 up/down 
# 设置ens33网卡IP地址10.0.0.100
ip addr add 10.0.0.100/24 dev ens33
# 删除ens33网卡IP地址10.0.0.200
ip addr del 10.0.0.200/24 dev ens33        

# 查看路由信息,也可以使用ip route命令
ip route list                                           
# 设置默认网关,也可以在后面加上dev ens33
ip route add default via 10.0.0.1                        
# 删除默认网关,也可以直接写ip route del default
ip route del default via 10.0.0.1                        
# 设置10.10.1.0网段的网关为10.0.0.1,数据走eth0接口
ip route add 10.10.1.0/24 via 10.0.0.1  dev eth0     
# 删除10.0.0.0/24网段的路由
ip route del 10.0.0.0/24    

# 清空指定网卡的所有ip
ip addr flush dev 接口
------------------------------------------
# 查看路由表:
route -n

# 添加到达目标主机的路由
route add -host 目标主机 gw 网关 dev 接口
route add -host 10.1.111.111 gw 10.2.111.111 dev eth0

# 添加到达目标网络的路由
route add -net 目标网络 netmask 子网掩码 gw 网关 dev 接口
# 或者 
route add -net 目标网络/子网掩码 gw 网关 dev 接口
route add -net 10.1.0.0 netmask 255.255.0.0 gw 10.2.111.111 dev eth0  
或者 route add -net 10.1.0.0/16 gw 10.2.111.111 dev eth0
 
# 添加默认路由
route add default gw 网关
# 比如给eth0添加一条默认路由,网关是10.2.111.111
route add default gw 10.2.111.111

# 删除路由记录:
# 删除到达目标主机的路由记录
route del -host 主机名
# 删除到达目标网络的路由记录
route del -net 目标网络/子网掩码
# 删除默认路由
route del default

Centos7极简单模式:
同样开启路由转发sysctl -w net.ipv4.ip_forward=1.

firewall-cmd --add-masquerade  --permanent
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=10.0.0.100:toport=80

常见操作

# 查看编号
iptables -L -n -t nat --line-number
# 根据编号删除
iptables -t nat -D PREROUTING 编号
# 开启转发
sysctl -w net.ipv4.ip_forward=1

# 场景一:实现本地端口转发
# 本地端口转发实在PREROUTING链中将端口做NAT转换:
iptable -t nat -A  PREROUTING -p tcp --dport   "$原端口"  -j REDIRECT --to-port  "$目标端口"

# 场景二、实现端口远程端口转发
# 在本地PREROUTING链中将端口进行NAT转换
# 然后通过FORWARD链转至POSTROUTING链中,
# 然后在POSTROUTING中将客户机地址进行SNAT的转换
1、DNAT转换  
iptable -t nat -A PREROUTING -d "$源地址" -p tcp -m tcp --dport  "$源端口" -j DNAT --to-destination "$目标地址:$目标端口"   

2、FORWARD放行: 
iptables -t filter - FORWARD -j ACCEPT
# 或者
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT

3、SNAT转换: 
iptable -t nat -A POSTROUTING -d "$目标地址" -p tcp -m tcp --dport "$目标端口" -j SNAT --to-source "$源地址:$源端口"

# 本机IP:10.10.10.1
# 目的IP:192.168.1.1
# UDP转发:
iptables -t nat -A PREROUTING  -d 10.10.10.1  -p udp --dport 10086 -j DNAT --to-destination 192.168.1.1:80
iptables -t nat -A POSTROUTING -d 192.168.1.1 -p udp --dport 80 -j SNAT --to-source 10.10.10.1:10086
iptables -A FORWARD -o eth0 -d 192.168.1.1 -p udp --dport 80 -j ACCEPT
iptables -A FORWARD -i eth0 -s 192.168.1.1 -p udp --sport 80 -j ACCEPT

# TCP转发:
iptables -t nat -A PREROUTING -d 10.10.10.1 -p tcp --dport 10086 -j DNAT --to-destination 192.168.1.1:80
iptables -t nat -A POSTROUTING -d 192.168.1.1 -p tcp --dport 80 -j SNAT --to-source 10.10.10.1:10086
iptables -A FORWARD -o eth0 -d 192.168.1.1 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i eth0 -s 192.168.1.1 -p tcp --sport 80 -j ACCEPT

实际案例

#!/bin/bash
# 转发协议
pro='tcp'

# 内网IP
src_host1='172.16.xx.13'
# 公网IP
src_host2='101.33.2xx.xxx'
# 访问端口
src_port=100xx

# 目标机器IP
Dst_Host='172.16.xx.9'
# 目标机器端口
Dst_Port=22

# 开启路由转发
sysctl -w net.ipv4.ip_forward=1

# 清空filter规则
iptables -F
# 清楚自定义
iptables -X
# 计数器清零
iptables -Z
# 清空nat表
iptables -t nat -F

# 允许进来和已连接继续
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# 或仅允许目标主机
# iptables -A FORWARD -p $pro -d $Dst_Host --dport $Dst_Port -j ACCEPT

# DNAT 转发过去
iptables -t nat -A PREROUTING -p $pro -d $src_host1 --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port
iptables -t nat -A PREROUTING -p $pro -d $src_host2 --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port

# SNAT 拉取回来
iptables -t nat -A POSTROUTING -p $pro -d $Dst_Host --dport $Dst_Port -j SNAT --to $src_host1
# 如果是通过内网转发的,则本条不需要配置
iptables -t nat -A POSTROUTING -p $pro -d $Dst_Host --dport $Dst_Port -j SNAT --to $src_host2

# 本地连接不经过prerouting,只经过output链,因此本机i访问可在output 链增加dnat规则
iptables -t nat -A OUTPUT -p $pro -d $src_host1 --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port
iptables -t nat -A OUTPUT -p $pro -d $src_host2 --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port

# 显示已有规则
iptables -t nat -L -n --line-number

云服务器
一般云服务器只有内网网卡,外网IP是映射IP;
因此只要转发内网IP,然后开启路由转发即可。
开启路由转发: sysctl -w net.ipv4.ip_forward=1

#!/bin/bash
pro='tcp'

src_host1='172.16.xx.13'
src_port=100xx

Dst_Host='172.16.xx.9'
Dst_Port=22

# 开启路由转发
sysctl -w net.ipv4.ip_forward=1

# 清空filter规则
iptables -F
# 清楚自定义
iptables -X
# 计数器清零
iptables -Z
# 清空nat表
iptables -t nat -F

# 允许进来和已连接继续
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# DNAT 转发过去
iptables -t nat -A PREROUTING -p $pro -d $src_host1 --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port

# SNAT 拉取回来
iptables -t nat -A POSTROUTING -p $pro -d $Dst_Host --dport $Dst_Port -j SNAT --to $src_host1

# 显示已有规则
iptables -t nat -L -n --line-number
posted @ 2021-12-19 20:31  刘文江  阅读(55)  评论(0)    收藏  举报  来源