在文章NAT网络地址转换技术入门到详解中,我们介绍了NAT的原理,NAT的分类,以及每种类型的NAT的功能。
netfilter/iptables是用来实现NAT的内核软件和用户配置工具软件。本文中我们会来详细描述如何使用iptables配置和实现NAT。

1、确认Linux kernel内核版本

通常的Linux发行版都已经自带了netfilter和iptables这二个软件和其它NAT需要用到的其它内核模块(比如连接跟踪,IP转发等内核功能模块),所以通常只要拿来直接使用就可以了,我们并不需要对Linux内核做出编译与修改。如果你需要自己编译Linux kernal,可以参照HowTo on compiling Linux 2.4 and 2.6 kernels 这本书(你可以在这个网页找到这本书http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html)。

2、netfilter的nat table简介

我们已经知道netfilter框架里,包含了所谓的4表5链,这里我们会需要使用4表里的nat table来实现NAT功能。nat table 包含了4个链—PREROUTING, INPUT, POSTROUTING和OUTPUT。每个链都包含多条规则rules,一个报文会被按照顺序进行匹配,直到命中某条规则。我们可以用命令sudo iptables –t nat –L查到nat表格里的这些链。

xxx@raspberrypi:~ $ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

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

本文中不使用OUTPUT chain和INPUT chain,PREROUTING和POSTROUTING chains的名字就表明了他们的用途。在报文进入Linux后,Linux内核根据路由表做出路由决定前,去检查 PREROUTING chain里的规则,因此所以我们可以使用PREROUTING chain去改变报文的目标IP地址,然后让下一步让的路由表去根据新的目标IP地址决定如何处理报文(DNAT)。在Linux内核对某个报文根据路由表做出转发决定后,下一步会根据POSTROUTING chain中规则进行处理,这意味着在这里,我们可以改变要发送出去的报文的源IP地址(SNAT)。
在这里插入图片描述

注意:这里和报文从哪个网口进,哪个网口出没有关系,所有进入Linux的的非上送给Linux本机而是需要被转发的报文都会经过这条路径进行处理。

上图表示了 DNAT和SNAT是如何工作的。
DNAT意味着修改报文的目标IP地址,所以Linux内核必须在根据报文的目标IP地址查找路由表并决定如何转发IP报文前完成目标IP地址的修改 (所以由PREROUTING chain完成)。例如:如果我们要为一个私网服务器192.168.1.3做DNAT,那么当Linux路由器的从公网收到IP报文时,它需要收到的IP报文的目标IP地址成192.168.1.3,然后再交给Linux内核做路由查找和转发决定:

router:~# route -n
Kernel IP routing table
Destination 	Gateway	Genmask				Flags 	Metric 		Ref		Use Iface
192.168.1.0 	0.0.0.0	255.255.255.0		U		0			0		0 	eth1

Linux内核发现192.168.1.0/24网络是直接连接在Eth1网卡上的,所以它会直接将报文从Eth1发送给192.168.1.3。

SNAT 意味着修改了IP报文的源IP地址。 让我们考虑一下IP伪装Masquerade是怎么工作,这会有助于我们的理解。一个从192.168.1.3发出来的报文想要访问外网。

  • Linux内核会查找路由表,如果这个报文需要多某个接口发出去,那个就会修改报文的源IP地址成这个接口的IP地址。
  • 如果没有找到这个报文的命中的路由表项,就会路由到默认路由去,然后就会把报文的源IP地址修改成默认路由指向的那个接口。

在NAT table的末尾添加,插入,或者删除规则的命令的语法都非常类似:

  • Append在末尾添加: iptables –t nat –A
  • Insert插入到最前面: iptables –t nat –I
  • Delete删除: iptables –t nat –D
  • Delete all删除所有: iptables –t nat –F

这里 应该是PREROUTING, POSTROUTING, INPUT或者OUTPUT,替换成真正的规则。

注意:iptables –F 命令是删除了默认table, filter table里的所有chain的所有规则,如果你要删除nat table里的规则,需要用-t来指定table。

3、用iptables实现SNAT

SNAT是几种NAT技术里最常用的类型。以以下例子为例进行说明:
192.168.1.0/24是我们办公室的私网的网段。我们可以通过1.2.3.1/30这个IP访问外网,默认网关是1.2.3.2.
所有内网主机的默认网关是192.168.1.1。
在这里插入图片描述我们可以看到Linux router有二个以太网口:

  • Eth0, IP地址是192.168.1.1(掩码255.255.255.0),这个网口通过交换机连接到私网192.168.1.0/24网络上。
  • Eth1, IP地址是1.2.3.1(掩码255.255.255.252),连接到外网上
    我们可以用以下一条规则就为私网192.168.1.0/24里的所有设备都建立SNAT,并使得私网内的所有设备都可以访问外网:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 1.2.3.1

这条命令的作用和下面这条命令的作用是一样的,但使用下面这条IP伪装的命令,我们可以支持Eth1的动态的IP地址,而不需要像上面那条命令一样指定外网的IP地址(注意IP伪装Masquerade是用指定路由出口网卡的IP地址来替换源地址,所以它能支持动态的获取出口网卡的IP地址来替代):

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

假如我们的网络供应商说只有1024以下的端口可以被使用,那么我们除了修改源IP地址网还需要修改源端口,这个SNAT的规则也是可以用于修改端口的,如下所示将报文的源端口修改成1-1024之间未使用的端口号:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 1.2.3.1:1-1024

注意,如果么网里的笔记本电脑用户想要上IRC或者FTP的话,那么还需要针对ip_conntrack打上ip_conntrack_
irc和ip_conntrack_ftp 模块才行,原因在于NAT只工作在IP层,但IPC和FTP这种协议在用户层也带有IP地址的信息,所有需要额外的功能模块来处理用户层的IP信息替换工作。

modprobe ip_conntrack_irc
modprobe ip_conntrack_ftp
#或者
insmod ip_conntrack_irc
insmod ip_conntrack_ftp

以下我们通过几个例子来学习一下SNAT的一些进阶的设置,以解决SNAT中常见的一些问题:

3.1、 多对多(N:N)的SNAT

IRC网络的服务端是限制来自同一个IP的客户端连接数量的,意味着当私网内的多个主机都使用SNAT去访问IRC服务器时,IRC服务器会检测到来自于同一个IP(1.2.3.1)的客户端连接数量超出了上限,那到超出后IRC服务器就会拒绝连接。此时我们可以通过增加公网IP的数量,并将私网IP地址SNAT到不同的公网IP地址的方式来减少以每个公网IP地址为源IP地址的IRC连接数量。当我们拿到额外的1.2.4.0/27子网里的所有公网IP地址后,我们将SNAT规则修改如下:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 1.2.4.0-1.2.4.32

这样就解决了问题,但这样的命令的话,就使1.2.3.1这个公网IP没有被加到SNAT的IP池里,没有利用起这个公网IP地址,所以修改上述命令如下:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 1.2.4.0-1.2.4.32 --to 1.2.3.1

3.2、 将一个网段内的某个公网IP移除出SNAT可用的公有IP地址池

比如我们需要将1.2.4.15从可用的公网IP地址池中移除,那么我们可以使用以下命令

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to 1.2.4.0-1.2.4.14 --to 1.2.4.16-1.2.4.32 --to 1.2.3.1

3.3、 设置目标地址为特定IP地址或者网段的报文不做NAT

这个通常可以用做二个用途:

  • 防止私网用户修改网络配置后,将内网的访问报文转发到Linux router来后被Linux router误做SNAT而导致私网内的主机之间不可连接。

比如私网内的192.168.1.19主机,把自己的网络掩码从192.168.1.0/24改成了192.168.1.0/27意味着,192.168.1.19这个主机认为只有192.168.1.1-192.168.1.31这些IP地址和它是在同一个子网下的,所以当它去访问192.168.1.32这个IP地址时,它会先把报文发给它的默认网关192.168.1.1即Linux Router, 然后在没有配置SNAT时Linux Router会根据路由表将这个报文再转发给192.168.1.32这个主机,但此时设置了SNAT功能,所以Linux Router会把来自己192.168.1.19的所有报文的源地址都先修改成1.2.3.1或者其它公网IP后再把报文发给192.168.1.32,当192.168.1.32发回响应报文时就报影应报文发给了1.2.3.1,这个报文就回不到192.168.1.19了,所以导致192.168.1.19和192.168.1.32之间网络不通。我们用以下命令来解决这个问题,不对目标地址为192.168.1.0/24网段内的所有报文做SNAT功能。

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d ! 192.168.1.0/24 -j SNAT --to 1.2.4.0-1.2.4.32 --to 1.2.3.1

或者用-o eth1指定只对从Eth1发送出去的报文做SNAT:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.4.0-1.2.4.32 --to 1.2.3.1
  • 禁止私网内的用户访问某些公网的服务器(比如不对目标地址为1.3.3.0网段下的主机IP地址的报文做SNAT)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d ! 1.3.3.0/24 -j SNAT --to 1.2.4.0-1.2.4.32 --to 1.2.3.1
  • 局域网内二个不同网段的服务器之间的报文不做SNAT
    假设我们的私网内有二个网段192.168.1.0/24和192.168.2.0/24,二个网段都被连接到了Linux Router,那么需要添加如下的规则,避免对二个网段之间互相访问的报文被SNAT
iptables -t nat -I POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT
iptables -t nat -I POSTROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j ACCEPT

这二个命令会在NAT规则前插入这二个规则(其实-I会把当前规则插入到所有已经存在的规则的前面),当192.168.2.0/24和192.168.1.0/24之间相互通信时,报文会先分析并命中这二条规则,命中后就不会再分析后面的规则了,所以就不会发生SNAT。

3.4、通过端口号,设置允许或者禁止SNAT特定的协议

  • 黑名单制度
    假设领导不希望让特定员工访问IRC,我们知道IRC的服务器是工作在6666-6669端口的,所以我们只要把从这个员工的电脑的IP地址发出来去访问目标主机的6666-6669端口的报文全部丢弃则可,则可以插入如下规则实现:
iptables -t nat -I POSTROUTING -s 192.168.1.31 -p tcp --dport 6666:6669 -j DROP
  • 半白名单制度
    或者是只允许访问特定端口,比如某员工只允许他访问网页,其它协议服务都不可用,则我们可以只允许他访问TCP的80端口,其它数据一律丢弃:
iptables -t nat -I POSTROUTING -s 192.168.1.31 -p tcp --dport ! 80 -j DROP  

注意,这个不等同于白名单制度,这里丢弃的是非80端口的TCP协议,但UDP协议的通信依然是可以进行。

  • 白名单制度
    如果要做成白名单制度,需要在一条或者多条白名单规则后,添加一条丢弃所有报文的规则(配置实例待更新)。

4、用iptables实现DNAT

DNAT的功能与原理在NAT网络地址转换技术入门到详解中已经介绍过了,我们假设本文的读者已经明天了DNAT的功能与原理了,所以这里只简单如何配置与使用。

4.1、如果你需要从外网全权访问私网里的某个主机(比如192.168.1.50)。

将一个公网IP地址(比如1.2.4.1))绑定给192.168.1.50这个主机,这时我们就可以通过DNAT来实现这个功能:

iptables -t nat -A PREROUTING -d 1.2.4.1 -j DNAT --to 192.168.1.50

配置完后,我们对所有192.168.1.50的访问都可以通过1.2.4.1来完成。

4.2、从特定外网IP访问私网内某个服务器的某个业务

这是出于安全性考虑的最小授权原则出发,严格限制访问者(通过访问者的IP地址)和严格限制可以访问的服务。如需要从1.2.5.17访问192.168.1.100的内网web服务,那么在我们设置了以下规则后,他就可以通过1.2.4.2来访问192.168.1.100的内网web服务了。

iptables -t nat -A PREROUTING -s 1.2.5.17 -d 1.2.4.2 -p tcp --dport 80 -j DNAT --to 192.168.1.100

同样出于安全原因考虑,我们DNAT可以帮助我们做信息隐藏,增加安全性。比如,我们希望从外网的任意主机通过SSH访问内网web服务器,因为内网web服务器里往往有非常重要的信息,所以通过DNAT直接映射一个公网IP地址到内网web服务器的私网IP地址,并不是一个非常安全的方案,这会让我们的内网web服务器的SSH服务完全暴露在外,会增加受到网络攻击的风险,更安全的方式是把端口也做一个映射,而攻击者不知道我们把SSH端口映射到了哪个端口,这样会使得SSH端口对外隐藏起来,从而增加安全性(这本质上已经是PAT或者称为NAPT了)。如下用65521端口去映射22端口。

iptables -t nat -A PREROUTING -d 1.2.4.2 -p tcp --dport 65521 -j DNAT --to 192.168.1.100:22

这样的配置下,如果我们从外网想要ssh到内网web服务器的话,我们需要ssh 1.2.4.2:65521.

我们把公司的外网web服务器部署在192.168.1.200上,通过DNS服务将域名www.mycompany.com映射到1.2.4.5,为了使外网web服务器从外网可以访问,我们需要设置如下规则:

iptables -t nat -A PREROUTING -d 1.2.4.5 -p tcp --dport 80 -j DNAT --to 192.168.1.200

5、透明代理

透明代理是一种强制使用用户使用代理服务器的方法,使用透明代理不需要用户在他们的终端或者他们的浏览器上配置代理。使用代理服务器有好多好处,比如通过代理服务器上的网页cache来节省流量,访问控制(如:禁止危险文件的下载).
使用透明代理还有一个好外,是可以防止用户自行绕过代理服务器。这个可以防止用户访问黄赌毒等有害网站。如果你的代理服务器工作在Linux Router的3128端口,那么我们可以使用下面命令来实现透明代理:

iptables -t nat -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3128

将192.168.1.0/24网段过来的访问网页的IP报文都转发到3128端口。

如果你要让某些私网里的主机可以不需要通过代理而是直接访问外网,那么可以通过以下命令给它加一个例外:

iptables -t nat -I PREROUTING -s 192.168.1.50 -p tcp --dport 80 –j ACCEPT

在PRE-ROUTING里会命中这条规则,然后在POSTROUTING里通过SNAT功能访问外网。

6、以上场景的配置脚本

#!/bin/bash
IP=/sbin/iptables
#... some packet filtering rules
### NAT SECTION
#first of all, we want to flush the NAT table
$IP -t nat -F
############ SNAT PART
#特定电脑只能访问web和DNS.
#Don't SNAT any TCP connections from her computer except www and all
#udp connections except DNS
$IP -t nat -A POSTROUTING -s 192.168.1.31 -p tcp --dport ! 80 -j DROP
$IP -t nat -A POSTROUTING -s 192.168.1.31 -p udp --dport ! 53 -j DROP
#公司内部的二个子网间的通信不要做NAT
#Don't SNAT anything from 192.168.1.0/24 to 192.168.2.0/24
$IP -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j ACCEPT
#映射192.168.1.50成1.2.4.1使得192.168.1.50的数据访问固定从1.2.4.1发出
$IP -t nat -A POSTROUTING -s 192.168.1.50 -j SNAT --to 1.2.4.1
#从eth1出去的报文都要做SNAT
$IP -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.4.0-1.2.4.32 --to 1.2.3.1
############ DNAT PART
#Dnat映射192.168.1.50成1.2.4.1使得192.168.1.50可以通过1.2.4.1自由访问
$IP -t nat -A PREROUTING -d 1.2.4.1 -j DNAT --to 192.168.1.50
#DNAT 特定的外部主机1.2.5.17可以访问内网web服务器
$IP -t nat -A PREROUTING -s 1.2.5.17 -d 1.2.4.2 -p tcp --dport 80 -j DNAT --to 192.168.1.100
#DNAT转换SSH登录的端口
$IP -t nat -A PREROUTING -d 1.2.4.2 -p tcp -dport 65521 -j DNAT --to 192.168.1.100:22
#DNAT 将外网web服务器部署到内部主机上
$IP -t nat -A PREROUTING -d 1.2.4.5 -p tcp --dport 80 -j DNAT --to 192.168.1.200
############ 透明代理
#允许192.168.1.50绕过代理
$IP -t nat -A PREROUTING -s 192.168.1.50 -p tcp --dport 80 -j ACCEPT
#给所有其它人设置透明代理
$IP -t nat -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3128
### End of NAT section

7、验证配置脚本

我们可以查看一下nat table里的几条链来验证配置是不是被正确的配置下去。

root@router:~# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- 0.0.0.0/0 1.2.4.1 to:192.168.1.50
DNAT tcp -- 1.2.5.17 1.2.4.2 tcp dpt:80
to:192.168.1.100
DNAT tcp -- 0.0.0.0/0 1.2.4.2 tcp dpt:65521
to:192.168.1.100:22
DNAT tcp -- 0.0.0.0/0 1.2.4.5 tcp dpt:80
to:192.168.1.200
ACCEPT tcp -- 192.168.1.50 0.0.0.0/0 tcp dpt:80
REDIRECT tcp -- 192.168.1.0/24 0.0.0.0/0 tcp dpt:80 redir
ports 3128
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
DROP tcp -- 192.168.1.31 0.0.0.0/0 tcp dpt:!80
DROP udp -- 192.168.1.31 0.0.0.0/0 tcp dpt:!53
ACCEPT all -- 192.168.1.0/24 192.168.2.0/24
SNAT all -- 192.168.1.50 0.0.0.0/0 to:1.2.4.1
SNAT all -- 192.168.1.0/24 0.0.0.0/0 to:1.2.4.0-1.2.
4.32 1.2.3.1
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
root@router:~#

我们可以看到脚本里的配置项都已经正确的出现在nat table里。如果我们要验证功能是不是正确的话,那么就要搭建相应的服务器,发送相应的报文,然后通过TCPdump和ethereal之类的抓包工具来进行验证。
比如,我们在Linux router上抓包,然后从外网发起一个到1.2.4.1随机的目标端口上的连接,TCPdump会显示如下:

  1. 在Eth0上收到一个从2.2.2.2到1.2.4.1的包
  2. 在Eth0上从1.2.3.1发出一个报文,目标不可达
    在Eth1上没有任何报文,因为没有命中任何DNAT规则。如果命中的某个规则,则我们可以用-v选项来查看 (iptables –L –n –v)。

8、异常场景:Double NAT

Double NAT是用来解决连接见个IP地址重叠的网络的一种方法。如下图的网络,有二个局域网通过VPN连接到一起,不过这二个局域网的IP地址是重叠的,有二个解决方案:1)改变其中一个局域网的网段,重新部署,2)使用Double NAT来解决这个冲突。
在这里插入图片描述
正常情况下,二个局域网工作在不同的网段,我们通过二台Linux Router上的路由表配置,通过VPN的接口使得二个局域网可以正常通信而无需NAT。 但我们都知道,这里异常发生了,二个局域网用的是完全相同的网段,所以只靠路由功能没有办法让二个网络之间相互通信,我们要“假装”二个局域网使用的是不同的网段,才可以让二个局域网之间相互通信。所以,解决方案就是:我们告诉左边的局域网他对面的右边的局域网工作在192.168.20.0/24网段,然后告诉右边的局域网它对面的左边的局域网工作在192.168.10.0/24网段,这样二边就能正常通信了。
下面我们将以二台192.168.1.60为例来说明如何配置才能让它们俩正常通信,以这个为例,可以拓展到其它所有在192.168.1.0/24里的主机,做出相应的配置映射后也就能正常通信了。

配置完成后,我们的目标是让左边的192.168.1.60认为对面的192.168.1.60的IP地址是192.168.20.60;让右边的192.168.1.60认为对面的192.168.1.60的IP地址是192.168.10.60。

8.1、配置Linux Router 1 (左边)

  • Step 1
ifconfig eth1:0 192.168.10.1 netmask 255.255.255.0

这一步不是必须的。目标IP地址为192.168.10.0/24的IP报文会到达Linux Router 1,我们不想要通过默认路由转发这些报文,因为192.168.10.0/24是左边这个局域网假装的网段。

  • Step 2
route add –net 192.168.20.0 netmask 255.255.255.0 gw 10.10.10.2

增加这个路由,让目标IP地址为192.168.20.0/24的IP报文通过vpn1往10.10.10.2转发。

  • Step 3
iptables -t nat -A POSTROUTING -s 192.168.1.60 -d 192.168.20.60 -j SNAT --to 192.168.10.60

创建SNAT规则,把从192.168.1.60发192.168.20.60的报文的源IP地址改成192.168.10.60, 这样来假装左边的网络是192.168.10.0/24。

  • Step 4
iptables -t nat -A PREROUTING -d 192.168.10.60 -j DNAT --to 192.168.1.60

在Linux Router 1上配置DNAT规则,修改所有到达本路由器的目标地址是192.168.10.60的IP报文的目标IP地址为192.168.1.60,这样可以让报文正确的发到192.168.1.60。

8.2、配置Linux Router 2 (左边)

在Linux router 2上,基本是类似的配置,只是目标和源反一下。

  • Step 1
ifconfig eth1:0 192.168.20.1 netmask 255.255.255.0
  • Step 2
route add -net 192.168.10.0 netmask 255.255.255.0 gw 10.10.10.1

增加这个路由,让目标IP地址为192.168.10.0/24的IP报文通过vpn1往10.10.10.1转发。

  • Step 3
iptables -t nat -A POSTROUTING -s 192.168.1.60 -d 192.168.10.60 -j SNAT --to 192.168.20.60

创建SNAT规则,把从192.168.1.60发192.168.10.60的报文的源IP地址改成192.168.20.60, 这样来假装右边的网络是192.168.20.0/24。

  • Step 4
iptables -t nat -A PREROUTING -d 192.168.20.60 -j DNAT --to 192.168.1.60

在Linux Router 2上配置DNAT规则,修改所有到达本路由器的目标地址是192.168.20.60的IP报文的目标IP地址为192.168.1.60,这样可以让报文正确的发到192.168.1.60。

上述就是所有Double NAT所需要的配置,完成配置后,二个192.168.1.60就可以通信了。

  • 左边的192.168.1.60主机给右边的192.168.1.60主机通信时
    • 它认为右边的主机的IP地址是192.168.20.60。因为192.168.20.60是另外一个网段的IP地址,所以这个报文会被转发到默认网关(即Linux Router 1) 。
    • Linux Router 1 会分析PREROUTING chain 里的规则,发现没有命中任何规则,
    • 下一步,它会去查找本地路由表,发现送往192.168.20.60的包应该通过vpn1发往10.10.10.2,
    • 然后Linux Router分析POSTROUTING chain里的规则,发现命中“所以从192.168.1.60发往192.168.20.60的包,都应该把源IP地址从192.168.1.60改成192.168.10.60”这条规则,Linux Router 1按规则修改IP报文的源IP地址,
    • 然后在ip_conntrack里保存这条连接的信息。
    • 被修改了源IP地址后的报文被通过vpn1转发到10.10.10.2。
    • 等这个报文到达Linux Router 2后,Linux Router 2收到了一个从192.168.10.60发送192.168.20.60的报文。
    • Linux Router 2 分析它自己的PREROUTING chain里的规则,发现命中“如果一个报文的目标地址是192.168.20.60就将这个报文的目标地址修改为192.168.1.60”的规则。 Linux Router 2修改报文的目标地址成192.168.1.60。
    • 然后在它的本地路由表里查找到发往192.168.1.60的IP报文应该通过Eth0直接发送,
    • 然后分析POSTROUTING chain里的规则发现没在命中任何规则Linux Router 2 将这个报文转发给192.168.1.60。
  • 右边的192.168.1.60主机给左边的192.168.1.60主机通信时
    也是一样的流程,只是方向反了一下。

到此,我们就完成了重叠IP的二个主机通过Double NAT后成功通信了。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐