背景
此篇文章我们将利用 iptables
做网关,实现 snat
和 dnat
snat
:源地址转换
dnat
:目的地址转换
实验环境如下,总共有 4
台主机 A、B、C、D
,其中 B
服务器作为网关,有2长网卡,内网地址为 172.16.1.11
,外网地址为 192.168.0.11
(这里的外网是假外网地址,能到达实验效果就行);内网还有 C、D
两台服务器,一台 Linux
,一台 Windows
。
实验要达到的效果
snat
:C、D
通过B
去访问外网A
服务器上的服务,此时在A
服务器上,看到的访问者地址为B
服务器的外网地址dnat
:A
通过B
去访问内网C
服务器上的服务,此时在C
服务器上,看到的访问者地址为B
服务器的内网地址
能达到上面说的2种效果,就说明我们的实验是成功的。
SNAT和DNAT说明
SNAT
: 源地址转换,在 Postrouting
链上操作
DNAT
: 目的地址转换,在 Prerouting
链上操作
为什么要在 Postrouting
和 Prerouting
链上操作??
我们以该系列第一篇文章的 终极流量流向图
为背景来展开说明
1、我们的目的是 snat
和 dnat
,所以流量走最下面那条链路效率是最高的(prerouting
--> forward
--> postrouting
),没必要还去 input
或者 output
链绕一圈。
2、要进行地址转换,必须需要 nat
表。
结合上面2个条件,我们可以把链确认在 prerouting
和 postrouting
之间。接着再往下看。
为什么 snat
要在 postrouting
链上??
为什么 dnat
要在 prerouting
链上??
我们先来回顾一下 routing
作用:判断数据包的目的地址是否是本机地址?如果是,则进入 input
链,再到应用程序;如果不是,则进入 forward
链,再到 postrouting
。
snat
的目的是源地址转换,将数据包的 源地址
转换为 本机出口地址
。如果在 prerouting
进行 snat
,那针对源地址的限速、限流、禁止访问等等规则就不生效了,因为此时数据包的源地址正是本机地址。所以源地址转换只能在出口进行操纵,也就是 postrouting
链。
dnat
的目的是目的地址转换,将数据包的 目的地址
转换为 其它服务器地址
,在此实验场景中是内网地址。
dnat
场景下有个背景是需要我们了解的,客户端其实是不知道 iptables
服务器后面还有其它服务,客户端以为它要请求的服务地址就是 iptales
服务器地址,所以在客户端发来的数据包中,目的地址为 iptables
服务器地址。(其实和反向代理差不多,客户端不知道他请求的其实是一个网关服务)
如果此时不在 prerouting
链中进行 目的地址转换
,那这个数据包经过 route
判断时就会顺势进入 input
链,再到用户层,而用户层根本就没有程序来处理这个数据包。所以 dnat
是在 prerouting
链上进行操作。