防火墙上的网络地址转换有3类
- SNAT 源地址转换
- DNAT 目的地址转换
- 端口映射
SNAT
源地址转换,让本地网络中的主机通过某一特定地址访问外部网络,具体实现一般都在POSTROUTING链上,因为如果数据包是发给本机的。如果在PREROUTING链上做,不就是相当于浪费功夫吗吗,因为最后也是要发给自己,结果在发给自己之前还做了一层转换,所以有点浪费资源了。综合来说在POSTROUTING上做最合适。
为什么要进行源地址转换呢。我们想象一个场景,我们只有一个公网IP但是这时候我们有很多主机需要上网,我们内网的主机上网肯定需要公网IP才能上网。这时候我们只有一个公网IP,就可以进行SNAT转换,吧访问互联网的数据包都发给那个拥有公网ip的网关。网关进行SNAT转换,将源地址转换为公网IP地址。公网上数据包响应请求的时候发给网关。由网关再把目标地址转换回来。这样有2个好处。第一.保证了内网主机的安全。第二,解决了ipv4地址紧缺的问题。
常用的几个选项
--to-source [ipaddr[-ipaddr]][:port[-port]] ##表示要指定的新的源IP,这里可以是多个地址
--random ##如果上面是多个地址,这个选项可以用来表示随机选一个地址当作源地址
MASQUERADE 如果这里的网关地址会一直变化。也就是将要指定的新的源IP一直变化的话,这里可以使用这个选项。具体例子
##iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j MASQUERADE
原理图
实现
实现也比较简单我们准备3台机器,网络拓扑图也就和原理图一样。
网关(网关有2个ip)
- 192.168.253.128
- 192.168.0.104
内网IP
- 192.168.253.129
外网IP
- 192.168.0.105
第一步,设置好网络环境。
网关:打开内核转发功能
sysctl net.ipv4.ip_forward=1
第二步
内网主机:增加一条路由,将去192.168.0.0网段的都发送给192.168.253.128这个网关
ip route add 192.168.0.0/24 via 192.168.253.128 dev eth0
第三步
外网主机:设置一下外网的路由条目,吧192.168.253.0网段的数据包。发送给192.168.0.104(网关)处理
ip route add 192.168.253.0/24 via 192.168.0.104 dev ens33
第四步
测试一下
现在我们在内网ping一下外网看能不能通
这里表示成功了。
第五步
网络环境配置好了。我们现在正式来做snat
在网关设置,将源地址为192.168.253.0网段的数据包做snat转换,将源地址改为192.168.253.104
iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j SNAT --to-source 192.168.0.104
有一点,如果这里的网关的IP是动态IP不是一个固定的外网ip则需要使用下面这条命令
iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j MASQUERADE
第六步
我们现在外网主机上安装httpd服务
yum install httpd -y
echo "hello nat" > /var/www/html/index.html ##制作一个测试页
systemctl start httpd ##启动服务
然后我们在外网这台主机上抓包
这里可以看到请求的ip已经变成网关的ip192.168.0.104了我们也可以再验证一下,我们在网关上,清空防火墙规则
然后再用内网访问一次,同时在外网抓包
清空规则之后,这里的源ip已经变成了192.168.253.129也就是内网IP了。说明确实是那条命令生效了
DNAT
DNAT 的全称为Destination Network Address Translation目的地址转换,原理和SNAT类似,只是DNAT修改的是目的地址。而SNAT修改的是源地址。
还有就是DNAT一般在PREROUTING链上修改。为什么呢。我们可以这样想。如果本地主机正好也开启了一个和服务端提供服务相同的端口,这时候,我们再去访问网关,网关将会将请求送到自己的用户空间,这样后端的服务器就没有收到请求。而客户端得到的也不是他想要的东西。所以综合考虑在PREROUTING会比较好。
那DNAT主要是为了解决什么样的问题呢?我们想象这样一个场景。假设我们不是客户端了。我们现在是服务端,要提供web服务。当用户来连接的时候,如果直接访问我们的真实服务器。这是不是不太好。相当于直接暴露在公网,有一些黑客很容易就攻击你。而如果我们告诉用户一个ip,让用户来连接这个ip。再由这个网关或者说防火墙进行DNAT,转发给后端。这样一来,至少有2个好处。第一,保证了后端主机的一定安全,因为没有直接暴露在公网。第二,如果躲在网关后面的服务器不止一台。我们还可以做一些负载均衡,让网站更健壮。(但是这种直接配置iptables来完成负载均衡的方法,一般不这么用了。)
常用的几个选项
--to-destination [ipaddr[-ipaddr]][:port[-port]] ##将要进行变换的DST地址。可以是多个
--random ##如果上面的地址有多个,则随机选一个指定。
实现
实验环境:
网关(网关有2个ip)
- 192.168.253.128
- 192.168.0.104
用户客户端
- 192.168.253.129
后端真实服务器IP
- 192.168.0.105
内容:环境还是差不多但是角色变了,我们这里用用户客户端去访问网关。由网关进行目的地址转换。
刚才的那些转发路由条目已经设置好了 ,我们只需要清空网关的规则,重新写一条规则就可以了
iptables -t nat -F ##清空nat表所有规则
iptables -t nat -X ##删除nat表中所有自定义的空链
iptables -t nat -A PREROUTING -d 192.168.253.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.105
然后我们测试一下,在客户端访问网关192.168.253.128
这个就比较明显了。我们访问的网关,但是收到了192.168.0.105这台服务器上的起始页信息。所以可以看出是成功了
端口映射
端口映射,顾名思义,就是修改端口。
实现比较简单直接简单说一下,试验环境就是上面的网络环境。实验内容:我们访问网关192.168.253.128的80端口。然后转发到后端192.168.0.105的8080端口。
网关:我们先清空网关的nat表
iptables -t nat -F ##清空nat表所有规则
iptables -t nat -X ##删除nat表中所有自定义的空链
iptables -t nat -A PREROUTING -d 192.168.253.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.105:8080
后端服务器:将httpd端口换到8080端口
修改配置文件/etc/httpd/conf/httpd.conf
Listen 8080##设置为8080
重启httpd服务
systemctl restart httpd
然后看一下8080端口起了没
再用客户端访问一次
访问成功。这里想说明的一点这个访问成功不是因为缓存,我们可以换一个起始页再测试
echo "i am 8080" > /var/www/html/index.html
再用客户端访问一次。