对DNAT和SNAT的个人理解

理解iptablies的DNAT和SNAT,对于理解LVS的负载均衡有很好的承接作用,但是之前在理解DNAT和SNAT一直卡在为什么要在postrouting还是prerouting链上设置,所以写此博客以此加深记忆。

iptables的报文流向

首先要理解的是iptables的报文流向,如图所示是,上层协议及用户层空间,以下均为系统的内核空间,因此iptables是工作在内核级的程序。

从图中可以分析出,报文流向有三个:

1.prerouting–>route rules–>input–>user space:流向用户空间

2.user space–> output–>route rules–>postrouting:从用户空间流出

3.prerouting–>route rules–>forward–>postrouting:经过forward做转发功能

iptables上网nat规则 iptables nat原理_源地址

SNAT和DNAT

NAT(net address translate):网络地址转换,由于IPV4地址数量资源匮乏,无法满足需求如此巨大的互联网,于是聪明的网络工程师就搞出了nat这个东西。
NAT原理:如图所示,局域网中使用的都是ipv4的私有地址,然后通过nat代理转发局域网中的所有请求和响应,所以局域网与互联网是不能直接“见面”的,而局域网中的地址都是私有地址,也就是说任何一个局域网都可以使用,使得ip地址复用。。

iptables上网nat规则 iptables nat原理_iptables上网nat规则_02


SNAT(source nat):源地址转换,以上图为例,就是Host A/B/C所在的网络为局域网,server(假设地址为210.33.5.22)所在的网络为公网。SNAT就是将局域网中的地址转换,NAT(假设面向局域网地址为192.168.1.3,面向公网地址为210.33.5.11)代为转发。

Host A (192.168.1.2)-->server(210.33.5.22)  

snat转发过程:
host A (192.168.1.2)--> nat(192.168.1.3)
nat(210.33.5.11)-->server(210.33.5.22)

#nat接收报文并修改请求报文中source地址为本机的公网地址(210.33.5.11),
然后发送给server(210.33.5.22)

所以服务器端收到的是来自nat的请求。那么在iptables中如何设置呢?
首先由于是nat,所以肯定用到的是nat表,那么报文的流向就是:

prerouting-->forward-->postrouting

那么要设置在prerouting还是postrouting呢?(nat表中不支持forward)
如果是在prerouting定义,那必然不符合逻辑,因为后面还要查路由规则,如果本机由多个公网地址呢?报文的目标地址已经是server地址,也就是非nat的地址,也就是说本身就是要穿过nat,而snat的目的就是要转换源地址,所以必须在postrouting时修改源地址为本机的公网地址。

DNAT:(destination nat):目标地址转换,公网地址发送回应包给局域网的主机时,nat将公网地址返回给自己的地址转换为局域网地址。

dnat回应包转发过程:
server(210.33.5.22)-->nat(210.33.5.11)
server(210.33.5.22)--> host A (nat将目标地址修改为:192.168.1.2)

#作为回应包,因为发出的请求包时从nat发出去的,所以server自然也是将包回应给nat,
而nat中已经记录了当时地址转换的局域网地址,所以nat将原本回应给自己的包,
修改目标地址转发给局域网内发起请求的主机。

由SNAT设置了postrouting可知,要设置DNAT规则,须在prerouting时设置。
这是因为如果是在postrouting设置,那么由于server的相应包是给nat的,所以nat就会以为是发送给自己的,直接收下并往INOUT链上走,而不是转发,自然就到实现不了DNAT的功能,所以在prerouting上设置时,判断是否要转发,即可决定数据报文的走向。