iptables详解(13):iptables动作总结之二

在本博客中,从理论到实践,系统的介绍了iptables,如果你想要从头开始了解iptables,可以查看iptables文章列表,直达链接如下

iptables零基础快速入门系列

 

概述

阅读这篇文章需要站在前文的基础上,如果你在阅读时遇到障碍,请参考之前的文章。

 

前文中,我们已经了解了如下动作

ACCEPT、DROP、REJECT、LOG

今天,我们来认识几个新动作,它们是:

SNAT、DNAT、MASQUERADE、REDIRECT

 

在认识它们之前,我们先来聊聊NAT,如果你对NAT的相关概念已经滚瓜烂熟,可以跳过如下场景描述。

 

NAT是Network Address Translation的缩写,译为”网络地址转换”,NAT说白了就是修改报文的IP地址,NAT功能通常会被集成到路由器、防火墙、或独立的NAT设备中。

为什么要修改报文的IP地址呢?我们来描述一些场景,即可知道为什么有这方面的需求了。

 

场景1:

假设,网络内部有10台主机,它们有各自的IP地址,当网络内部的主机与其他网络中的主机通讯时,则会暴露自己的IP地址,如果我们想要隐藏这些主机的IP地址,该怎么办呢?可以这样办,如下。

当网络内部的主机向网络外部主机发送报文时,报文会经过防火墙或路由器,当报文经过防火墙或路由器时,将报文的源IP修改为防火墙或者路由器的IP地址,当其他网络中的主机收到这些报文时,显示的源IP地址则是路由器或者防火墙的,而不是那10台主机的IP地址,这样,就起到隐藏网络内部主机IP的作用,当网络内部主机的报文经过路由器时,路由器会维护一张NAT表,表中记录了报文来自于哪个内部主机的哪个进程(内部主机IP+端口),当报文经过路由器时,路由器会将报文的内部主机源IP替换为路由器的IP地址,把源端口也映射为某个端口,NAT表会把这种对应关系记录下来。

示意图如下:

于是,外部主机收到报文时,源IP与源端口显示的都是路由的IP与端口,当外部网络中的主机进行回应时,外部主机将响应报文发送给路由器,路由器根据刚才NAT表中的映射记录,将响应报文中的目标IP与目标端口再改为内部主机的IP与端口号,然后再将响应报文发送给内部网络中的主机。整个过程中,外部主机都不知道内部主机的IP地址,内部主机还能与外部主机通讯,于是起到了隐藏网络内主机IP的作用。

上述整个过程中,就用到了NAT功能,准确的说是用到了NAPT功能,NAPT是NAT的一种,全称为Network Address Port Translation,说白了就是映射报文IP地址的同时还会映射其端口号,就像刚才描述的过程一样。

刚才描述的过程中,”IP地址的转换”一共发生了两次。

内部网络的报文发送出去时,报文的源IP会被修改,也就是源地址转换:Source Network Address Translation,缩写为SNAT。

外部网络的报文响应时,响应报文的目标IP会再次被修改,也就是目标地址转换:Destinationnetwork address translation,缩写为DNAT。

但是,上述”整个过程”被称为SNAT,因为”整个过程”的前半段使用了SNAT,如果上述”整个过程”的前半段使用了DNAT,则整个过程被称为DNAT,也就是说,整个过程被称为SNAT还是DNAT,取决于整个过程的前半段使用了SNAT还是DNAT。

 

其实刚才描述的场景不仅仅能够隐藏网络内部主机的IP地址,还能够让局域网内的主机共享公网IP,让使用私网IP的主机能够访问互联网。

比如,整个公司只有一个公网IP,但是整个公司有10台电脑,我们怎样能让这10台电脑都访问互联网呢?我们可以为这10台电脑都配置上各自的私网IP,比如”192.168″这种私网IP,但是互联网是不会路由私网IP的,如果想要访问互联网,则必须使用公网IP,那么,我们就需要想办法,能让这10台主机共享公司仅有的一个公网IP,没错,这与刚才描述的场景其实完全一致,我们只要在路由器上配置公网IP,在私网主机访问公网服务时,报文经过路由器,路由器将报文中的私网IP与端口号进行修改和映射,将其映射为公网IP与端口号,这时,内网主机即可共享公网IP访问互联网上的服务了,NAT表示意图如下

综上所述,SNAT不仅能够隐藏网内的主机IP,还能够共享公网IP,这在IPV4地址较为紧张的今天,是非常有用的。

 

场景2:

场景1中,我们描述的过程为SNAT的过程,虽然其过程中也牵扯到DNAT,但是由于整个过程的前半段使用了SNAT,所以整个过程称之为SNAT,那么在什么情况下,整个过程能称之为DNAT呢?

没错,当整个过程的前半段使用了DNAT时,整个过程被称为DNAT,具体场景如下。

公司有自己的局域网,网络中有两台主机作为服务器,主机1提供web服务,主机2提供数据库服务,但是这两台服务器在局域网中使用私有IP地址,只能被局域网内的主机访问,互联网无法访问到这两台服务器,整个公司只有一个可用的公网IP,怎样通过这个公网IP访问到内网中的这些服务呢?我们可以将这个公网IP配置到公司的某台主机或路由器上,然后对外宣称,这个IP地址对外提供web服务与数据库服务,于是互联网主机将请求报文发送给这公网 IP地址,也就是说,此时报文中的目标IP为公网IP,当路由器收到报文后,将报文的目标地址改为对应的私网地址,比如,如果报文的目标IP与端口号为:公网IP+3306,我们就将报文的目标地址与端口改为:主机2的私网IP+3306,同理,公网IP+80端口映射为主机1的私网IP+80端口,当私网中的主机回应对应请求报文时,再将回应报文的源地址从私网IP+端口号映射为公网IP+端口号,再由路由器或公网主机发送给互联网中的主机。

上述过程也牵扯到DNAT与SNAT,但是由于整个过程的前半段使用了DNAT,所以上述过程被称为DNAT

 

其实,不管是SNAT还是DNAT,都起到了隐藏内部主机IP的作用。

 

实验环境准备

好了,我们已经了解了SNAT与DNAT的相关概念,那么现在,我们可以动动手了,首先,准备一下实验环境

大致的实验环境是这样的,公司局域网使用的网段为10.1.0.0/16,目前公司只有一个公网IP,局域网内的主机需要共享这个IP与互联网上的主机进行通讯。

由于我们没有真正的公网IP,所以,我们使用私网IP:192.168.1.146模拟所谓的公网IP,示意图如下

如上述示意图所示,实验使用4台虚拟机,A、B、C、D

主机A:扮演公网主机,尝试访问公司提供的服务,IP地址为192.168.1.147

主机B:扮演了拥有NAT功能的防火墙或路由器,充当网关,并且负责NAT,公网、私网通讯的报文通过B主机时,报文会被NAT

主机C:扮演内网web服务器

主机D:扮演内网windows主机

上图中圆形所示的逻辑区域表示公司内网,网段为10.1.0.0/16,主机B、C、D都属于内网主机,主机B比较特殊,同时扮演了网关与防火墙,主机B持有公司唯一的公网IP(我们用了一个假的公网IP),局域网内主机如果想与公网主机通讯,需要共享此公网IP,由B主机进行NAT,所以,我们为主机B准备了两块网卡,公网IP与私网IP分别配置到这两块网卡中,同时,在虚拟机中设置了一个”仅主机模式”的虚拟网络,以模拟公司局域网。

 

聪明如你,应该已经发现了,上述实验环境与之前描述的”网络防火墙”的实验环境相差无几,只不过之前的环境并没有公网,私网的概念,而此刻,圆形逻辑区域之内为私网,圆形逻辑区域之外为公网。

 

环境具体准备过程如下

首先,创建一个虚拟网络,模拟公司内网。

点击vmware虚拟机的编辑菜单,打开”虚拟网络编辑器”,点击更改设置,添加”仅主机模式”的虚拟网络,下图中的VMnet6为已经添加过的虚拟网络,此处不再重复操作。

 

主机C与主机D的网关都指向主机B的私网IP,如下图所示

 

 

主机B有两块网卡,分别配置了私网IP与公网IP,私网IP为10.1.0.3,私网IP所在的网卡也存在于vmnet6中,模拟公网的IP为192.168.1.146,B主机的公网IP所在的网卡与A主机都使用桥接模式的虚拟网络,所以,B主机既能与私网主机通讯,也能与公网主机通讯。

由于B主机此时需要负责对报文的修改与转发,所以,需要开启B主机中的核心转发功能,Linux主机默认不会开启核心转发,这在前文中已经详细的描述过,此处不再赘述,如果你还不明白为什么,请回顾前文,使用临时生效的方法开启B主机的核心转发功能,如下图所示。

 

A主机的IP地址如下,可以与B主机进行通讯,但是不能与C、D进行通讯,因为此刻,A是公网主机,B既是公网主机又是私网主机,C、D是私网的主机,A是不可能访问到C和D的。

 

为了能够更好的区分公网服务与私网服务,我们分别在主机A与主机C上启动httpd服务,如下图所示。

 

好了,实验环境准备完毕,我们来一起动动手,实际操作一下。

 

动作:SNAT

在文章开头的场景中,我们已经描述过,网络内部的主机可以借助SNAT隐藏自己的IP地址,同时还能够共享合法的公网IP,让局域网内的多台主机共享公网IP访问互联网。

而此时的主机B就扮演了拥有NAT功能的设备,我们使用iptables的SNAT动作达到刚才所说的目的。

连接到B主机,添加如下规则。

如上图所示,上图中的规则表示将来自于10.1.0.0/16网段的报文的源地址改为公司的公网IP地址。

“-t nat”表示操作nat表,我们之前一直在灌输一个概念,就是不同的表有不同的功能,filter表的功能是过滤,nat表的功能就是地址转换,所以我们需要在nat表中定义nat规则。

“-A POSTROUTING”表示将SNAT规则添加到POSTROUTING链的末尾,在centos7中,SNAT规则只能存在于POSTROUTING链与INPUT链中,在centos6中,SNAT规则只能存在于POSTROUTING链中。

你可能会问,为什么SNAT规则必须定义在POSTROUTING链中,我们可以这样认为,POSTROUTING链是iptables中报文发出的最后一个”关卡”,我们应该在报文马上发出之前,修改报文的源地址,否则就再也没有机会修改报文的源地址了,在centos7中,SNAT规则也可以定义在INPUT链中,我们可以这样理解,发往本机的报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。

“-s 10.1.0.0/16″表示报文来自于10.1.0.0/16网段,前文中一直在使用这个匹配条件,我想此处应该不用赘述了。

“-j SNAT”表示使用SNAT动作,对匹配到的报文进行处理,对匹配到的报文进行源地址转换。

“–to-source 192.168.1.146″表示将匹配到的报文的源IP修改为192.168.1.146,前文中,我们已经总结过,某些动作会有自己的选项,”–to-source”就是SNAT动作的常用选项,用于指定SNAT需要将报文的源IP修改为哪个IP地址。

 

好了,只要站在前文的基础上,理解上述语句应该是分分钟的事情,聪明如你应该已经学会了,那么我们来测试一下。

目前来说,我们只配置了一条SNAT规则,并没有设置任何DNAT,现在,我们从内网主机上ping外网主机,看看能不能ping通,登录内网主机C,在C主机上向A主机的外网IP发送ping请求(假外网IP),示例如下

如上图所示,”内网主机”已经可以依靠SNAT访问”互联网”了。

 

为了更加清晰的理解整个SNAT过程,在C主机上抓包看看,查看一下请求报文与响应报文的IP地址,如下,在C主机上同时打开两个命令窗口,一个命令窗口中向A主机发送ping请求,另一个窗口中,使用tcpdump命令对指定的网卡进行抓包,抓取icmp协议的包。

从上图可以看到,10.1.0.1发出ping包,192.168.1.147进行回应,正是A主机的IP地址(用于模拟公网IP的IP地址)

看来,只是用于配置SNAT的话,我们并不用 手动的进行DNAT设置,iptables会自动维护NAT表,并将响应报文的目标地址转换回来。

 

那么,我们去A主机上再次重复一遍刚才的操作,在A主机上抓包看看,如下图所示,C主机上继续向A主机的公网IP发送ping请求,在主机A的网卡上抓包看看。

从上图可以看出,C主机向A主机发起ping请求时得到了回应,但是在A主机上,并不知道是C主机发来的ping请求,A主机以为是B主机发来的ping请求,从抓包的信息来看,A主机以为B主机通过公网IP:192.168.1.146向自己发起了ping请求,而A主机也将响应报文回应给了B主机,所以,整个过程,A主机都不知道C主机的存在,都以为是B主机在向自己发送请求,即使不是在公网私网的场景中,我们也能够使用这种方法,隐藏网络内的主机,只不过此处,我们所描述的环境就是私网主机共享公网IP访问互联网,那么可以看到,私网中的主机已经共享了192.168.1.146这个”伪公网IP”,那么真的共享了吗?我们使用内网主机D试试,主机D是一台windows虚拟机,我们使用它向主机A发送ping请求,看看能不能ping通。如下

windows主机也ping通了外网主机,在A主机上抓包,看到的仍然是B主机的IP地址。

那么,C主机与D主机能够访问外网服务吗?我们来看看。

在C主机上访问A主机的web服务,如下图所示,访问正常。

同理,在windows主机中访问A主机的web服务,如下图所示,访问正常。

 

好了,源地址转换,已经完成了,我们只依靠了一条iptables规则,就能够使内网主机能够共享公网IP访问互联网了。

 

动作DNAT

公司只有一个公网IP,但是公司的内网中却有很多服务器提供各种服务,我们想要通过公网访问这些服务,改怎么办呢?

没错,使用DNAT即可,我们对外宣称,公司的公网IP上既提供了web服务,也提供了windows远程桌面,不管是访问web服务还是远程桌面,只要访问这个公网IP就行了,我们利用DNAT,将公网客户端发送过来的报文的目标地址与端口号做了映射,将访问web服务的报文转发到了内网中的C主机中,将访问远程桌面的报文转发到了内网中的D主机中。

好了,理论说完了,来动手实践一下。

 

如下配置由 [ 运维工程师 王圣杰 ]  提供,我们一起来讨论一下。

如果我们想要实现刚才描述的场景,则需要在B主机中进行如下配置。

如上图所示,我们先将nat表中的规则清空了,从头来过,清空nat表规则后,定义了一条DNAT规则。

“-t nat -I PREROUTING”表示在nat表中的PREROUTING链中配置DNAT规则,DNAT规则只配置在PREROUTING链与OUTPUT链中。

“-d 192.168.1.146 -p tcp –dport 3389″表示报文的目标地址为公司的公网IP地址,目标端口为tcp的3389号端口,而我们知道,windows远程桌面使用的默认端口号就是3389,当外部主机访问公司公网IP的3389号端口时,报文则符合匹配条件。

“-j DNAT –to-destination 10.1.0.6:3389″表示将符合条件的报文进行DNAT,也就是目标地址转换,将符合条件的报文的目标地址与目标端口修改为10.1.0.6:3389,”–to-destination”就是动作DNAT的常用选项。

那么综上所述,上图中定义的规则的含义为,当外网主机访问公司公网IP的3389时,其报文的目标地址与端口将会被映射到10.1.0.6:3389上。

 

好了,DNAT规则定义完了,现在能够直接使用外网主机访问私网中的服务了吗?

理论上只要完成上述DNAT配置规则即可,但是在测试时,只配置DNAT规则后,并不能正常DNAT,经过测试发现,将相应的SNAT规则同时配置后,即可正常DNAT,于是我们又配置了SNAT

示例如下。

注:理论上只配置DNAT规则即可,但是如果在测试时无法正常DNAT,可以尝试配置对应的SNAT,此处按照配置SNAT的流程进行。

没错,与刚才定义SNAT时使用的规则完全一样。

 

好了,完成上述配置后,我们则可以通过B主机的公网IP,连接D主机(windows主机)的远程桌面了,示例如下。

找到公网中的一台windows主机,打开远程程序

 

输入公司的公网IP,点击连接按钮

注意:没有指定端口的情况下,默认使用3389端口进行连接,同时,为了确保能够连接到windows虚拟主机,请将windows虚拟主机设置为允许远程连接。

 

输入远程连接用户的密码以后,即可连接到windows主机

连接以后,远程连接程序显示我们连接到了公司的公网IP,但是当我们查看IP地址时,发现被远程机器的IP地址其实是公司私网中的D主机的IP地址。

上图证明,我们已经成功的通过公网IP访问到了内网中的服务。

 

同理,使用类似的方法,我们也能够在外网中访问到C主机提供的web服务。

示例如下。

如上图所示,我们将公司公网IP的801号端口映射到了公司内网中C主机的80端口,所以,当外网主机访问公司公网IP的801端口时,报文将会发送到C主机的80端口上。

这次,我们不用再次定义SNAT规则了,因为之前已经定义过SNAT规则,上次定义的SNAT规则只要定义一次就行,而DNAT规则则需要根据实际的情况去定义。

 

好了,完成上述DNAT映射后,我们在A主机上访问B主机的801端口试试,如下

可以看到,我们访问的是B主机的公网IP,但是返回结果显示的却是C主机提供的服务内容,证明DNAT已经成功。

 

而上述过程中,外网主机A访问的始终都是公司的公网IP,但是提供服务的却是内网主机,但是我们可以对外宣称,公网IP上提供了某些服务,快来访问吧!

我觉得我说明白了,你听明白了吗?

 

动作MASQUERADE

上文中,我们已经描述了SNAT,也就是源地址转换,那么我们现在来认识一个与SNAT类似的动作:MASQUERADE

当我们拨号网上时,每次分配的IP地址往往不同,不会长期分给我们一个固定的IP地址,如果这时,我们想要让内网主机共享公网IP上网,就会很麻烦,因为每次IP地址发生变化以后,我们都要重新配置SNAT规则,这样显示不是很人性化,我们通过MASQUERADE即可解决这个问题,MASQUERADE会动态的将源地址转换为可用的IP地址,其实与SNAT实现的功能完全一致,都是修改源地址,只不过SNAT需要指明将报文的源地址改为哪个IP,而MASQUERADE则不用指定明确的IP,会动态的将报文的源地址修改为指定网卡上可用的IP地址,示例如下:

如上图所示,我们指定,通过外网网卡出去的报文在经过POSTROUTING链时,会自动将报文的源地址修改为外网网卡上可用的IP地址,这时,即使外网网卡中的公网IP地址发生了改变,也能够正常的、动态的将内部主机的报文的源IP映射为对应的公网IP。

 

可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。

 

动作REDIRECT

使用REDIRECT动作可以在本机上进行端口映射

比如,将本机的80端口映射到本机的8080端口上

iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080

经过上述规则映射后,当别的机器访问本机的80端口时,报文会被重定向到本机的8080端口上。

REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中。

 

小结

为了方便以后回顾,我们对上述命令进行总结。

 

如果想要NAT功能能够正常使用,需要开启Linux主机的核心转发功能。

echo 1 > /proc/sys/net/ipv4/ip_forward

 

SNAT相关操作

配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,访问互联网,如果只是共享IP的话,只配置如下SNAT规则即可。

iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

 

如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作,如下命令表示将10.1网段的报文的源IP修改为eth0网卡中可用的地址。

iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE

 

DNAT相关操作

配置DNAT,可以通过公网IP访问局域网内的服务。

注:理论上来说,只要配置DNAT规则,不需要对应的SNAT规则即可达到DNAT效果。

但是在测试DNAT时,对应SNAT规则也需要配置,才能正常DNAT,可以先尝试只配置DNAT规则,如果无法正常DNAT,再尝试添加对应的SNAT规则,SNAT规则配置一条即可,DNAT规则需要根据实际情况配置不同的DNAT规则。

iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP

 

在本机进行目标端口映射时可以使用REDIRECT动作。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

配置完成上述规则后,其他机器访问本机的80端口时,会被映射到8080端口。

 

好了,这篇文章就总结到这里,希望能对你有所帮助~~~~~

 

 

© 版权声明
THE END
点赞115赞赏
分享
评论 共79条
    • 朱双印
    • 看见你在路上0
      楼主,请教一下,iptables可以转发UDP广播吗?
      16天前
    • 朱双印
    • 小风0
      我用tcpdump看了下, 服务器A 192.168.0.6 服务器B 192.168.0.12,192.168.10.12 服务器C 192.168.10.10 配置服务器B `iptables -t nat -I PREROUTING -p tcp --dport 3389 -j DNAT --to-destination 192.168.10.10:3389` 服务器A > 服务器B 服务器A > 服务器C 说明数据包从 经过服务器B后 变成 服务器A > 服务器C 意味着响应的时候会是 服务器C > 服务器A, 服务器A会丢弃这个数据包吧? 所以需要配置SNAT去修改转发给服务器C的数据包的源地址, `iptables -t nat -I POSTROUTING -s 192.168.0.0/16 -d 192.168.10.10 -p tcp --dport 3389 -j SNAT --to-source 192.168.10.12` 这时候是 服务器A > 服务器B 服务器B > 服务器C 服务器C > 服务器B 服务器B > 服务器A 所以配置DNAT的同时也要配置SNAT同步修改源地址,相当于转发数据包的同时告诉下一个服务器需要响应的地址。 我这样理解没错吧?
      25天前
    • 朱双印
    • 小马甲0
      Try this: iptables -t nat -I POSTROUTING -p udp -m udp --sport 123 -j MASQUERADE --to-ports 60000-61000
      1月前
    • 朱双印
    • 阿方索地方0
      老师好 ,请教下 MASQUERADE带来 的 性能 损耗有多少 ?
      3月前
    • 朱双印
    • takwang0
      作者你好,我现在只想把经过本机的报文的源端口号改变一下,其他的都不改,这个snat该怎么写呢?希望赐教
      4月前
    • 朱双印
    • takwang0
      博主你好,可否把snat修改端口的也补充一下
      4月前
    • 朱双印
    • qyq0
      你好,我用了你的这个做没有连通: 1)三台虚拟机,配置网络A:10.10.0.3/16,B:10.10.0.6/16,192.168.61.129 (A、B网关:10.10.0.6),C:192.168.61.128,网络配置后,A能ping通B两个网卡ip,A不能Ping C,C只能ping通192.168.61.129。 2)执行iptables -F;再执行:iptables -t nat -A POSTROUTING -s 10.10.0.0/16 -j SNAT --to-source 192.168.61.129 . 3)但是仍然是步骤1中的效果。请问老师,是怎么做到A访问C的?
      8月前
    • 朱双印
    • xiao0
      你这个写的太好了 ,对我来说 这篇文章值1000块, 原来你也用wordpress 哈哈 直接世界除了wiki和github 还有你 感谢google
      8月前
    • 朱双印
    • vivi0
      https://blog.csdn.net/cici_new_1987/article/details/114364669 我又把SNAT / DNAT动作做到 INOUT / OUTPUT链总结到这里了。
      
      之前说太多了,抱歉,因为评论不能删除....
      
      8月前
      • 积极讨论没有必要删除,把想法共享出来大家也会多个参考,加油~
        8月前@vivi
    • 朱双印
    • vivi0
      我好像都说错了
      8月前
    • 朱双印
    • vivi0
      在centos7中,SNAT规则也可以定义在INPUT链中,我们可以这样理解,发往本机的报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。 此处理解为:发网防火墙本机的数据包经过的是PREROUTING –> INPUT这两条链(不会走PREROUTING 和 POSTROUTING)。我们要在INPUT链做SNAT动作。报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。
      8月前
    • 朱双印
    • vivi0
      在centos7中,SNAT规则也可以定义在INPUT链中,我们可以这样理解,发往本机的报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。 INPUT这两条链。我们要在INPUT链做SNAT动作。报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。 参考https://www.jb51.net/LINUXjishu/402441.html#comments 这里的最后一个段落的例子。
      8月前
    • 朱双印
    • vivi0
      @嗨大方 我的意思就是 动作MASQUERADE 只能配合 -o. 下面bash代码举的是一个错误的例子。 这个例子的命令实际运行后,会出现错误提示。
      8月前
    • 朱双印
    • 嗨大方0
      @vivi 只能配合-o,是因为-o是出去的网卡。-i 是进来的网络流量。-s 1.1.1.1配合-i ,这不是相互矛盾吗
      8月前
    • 朱双印
    • vivi0
      动作MASQUERADE 只能配合参数-o 错误示例:
      
       ~]# iptables -t nat -I POSTROUTING -s 1.1.1.1 -i ens33 -j MASQUERADE
      iptables v1.4.21: Can't use -i with POSTROUTING
      
      Try `iptables -h' or 'iptables --help' for more information.
      
      
      8月前
    • 朱双印
    • vivi0
      在centos7中,SNAT规则也可以定义在INPUT链中,我们可以这样理解,发往本机的报文经过INPUT链以后报文就到达了本机,如果再不修改报文的源地址,就没有机会修改了。 <----作者博文中这句话不是很牵强吗?换做放到PREROUTING OUTPUT POSTROUTING 这些链都可以这么牵强附会的解释。
      8月前
    • 朱双印
    • focus0
      修改ip和端口是iptables的功能。
      10月前
    • 朱双印
    • focus0
      路由器工作在IP层,他不会修改ip和端口,只会修改源MAC和目的MAC.能不能解释一下一下这句话?(我这里说的是linux内核支持的路由表) """ 当网络内部的主机向网络外部主机发送报文时,报文会经过防火墙或路由器,当报文经过防火墙或路由器时,将报文的源IP修改为防火墙或者路由器的IP地址,当其他网络中的主机收到这些报文时,显示的源IP地址则是路由器或者防火墙的,而不是那10台主机的IP地址,这样,就起到隐藏网络内部主机IP的作用,当网络内部主机的报文经过路由器时,路由器会维护一张NAT表,表中记录了报文来自于哪个内部主机的哪个进程(内部主机IP+端口),当报文经过路由器时,路由器会将报文的内部主机源IP替换为路由器的IP地址,把源端口也映射为某个端口,NAT表会把这种对应关系记录下来。 """
      10月前
    • 朱双印
    • vivi0
      谢谢老师用心写作发表文章。 https://www.linuxidc.com/Linux/2013-08/88536.htm 此处讲的也很好,可以结合参考学习。
      12月前
      • 朱双印
        vivi0
        老师防火墙系列大作,逐一拜读过了....感恩! 😉 😆 😀 😳 🙂 😛 😉 https://blog.csdn.net/wenqian1991/article/details/50413538 此处技术文章讲的也很好,可以结合参考学习。
        12月前@vivi
    • 朱双印
    • microyy0
      谢谢老师,讲得非常详细,完全照顾了小白的入门学习,我感觉受益匪浅,但我有一点感觉没想明白,在做SNAT的场景中,如果C、D同时通过B来ping A,B怎么知道A发过来的回应包是针对C的还是D的,两种包的目的地址都是B的公网地址,源地址都是A的地址,B怎么知道哪个回应包是C的,哪个回应包是D的? 还有,SNAT的动作选项详解能不能说一下,在centos7中"--to"后面直接跟IP地址就可以,在Centos8中“--to”后面跟地址就直接提示"unknown option "--to"",感觉是iptables版本的问题,但不知道在centos8里面如何操作,希望老师指点一下。
      1年前
      • 朱双印
        wenxingujin0
        应该可以根据端口区分C还是D
        1年前@microyy
      • 朱双印
        anonymous0
        ICMP ping的头部是有标识符的,可以根据它分辨不同实例
        1年前@microyy
      • 朱双印
        xzt0
        文章的开头就已经说的很清楚了,开启SNAT动作后,在B主机上就会自动维护一个路由表,通过路由表就可以知道A主机是回复C的还是D的。
        1年前@microyy
    • 朱双印
    • 庚庚9110
      真是相见恨晚啊,要早些时候看到这个系列的博客,也不会对iptables如此恐惧,写得真好。
      1年前
    • 朱双印
    • 胡歌呵呵0
      作者写的非常好,我也按着把公司的vpn给搭建起来了,另外有个疑惑, 我外网服务器想内网网关服务器做ping的时候, 内网服务器,必须指定" -o eth0" 才行,下面是我内网做规则的命令,不知道是不是必须制定网卡,这个坑很大,花了非常多时间 iptables -t nat -A POSTROUTING -d 192.168.0.0/24 -o eth0 -j SNAT --to-source 192.168.0.20
      1年前
    • 朱双印
    • haha1230
      B配置核心转发后,AC是互通的,前面一篇“网络防火墙”中,是单独增加了一条拒绝规则,所以才造成无法PING通的情况。
      2年前
    • 朱双印
    • 色彩人生0
      博主,我想问一下,SNAT可以只对一个IP做规则吗?示例中我看的是一个网段内的服务器,但是我现在的情况是只对需要对一台服务器做配置。
      2年前
    • 朱双印
    • kenzhang10310
      你的文章很好,是否允许转发到我的博客?开头注明出处和来源。
      2年前
    • 朱双印
    • Chu0
      博主,你好!我有一个问题一直没有解决,网络结构如下图: https://i.imgur.com/ABnkFgB.png A(PC): 192.168.0.* B(Raspberry Pi) : 192.168.0.112 10.0.2.60 (tinc) C(VPS) : 107.172.191.182 10.0.2.251 (tinc) A与B是内网,同属于192.168.0.0/24,B与C通过tinc连接,同属于10.0.2.0/24,C有公网IP,现在想将B设置成网关,192.168.0.0/24下的设备可以通过将B(Raspberry Pi)设置成网关而连接到 C(VPS)实现上网,这个iptables该怎样设置啊?
      2年前
      • 朱双印
        新玩家0
        1.你不可能每次都设置静态ip所以先给树莓派上装个dhcp服务器,网关就设置成它自己的ip比如:192.168.1.1,其他pc连接树莓派的时候就会自动获取一个ip,具体dhcp的安装和配置可以百度。 2.在你树莓派上配置SNAT iptables -t nat -F iptables -t nat -I POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source=10.0.2.60
        2年前@Chu
    • 朱双印
    • 路过无名1
      DNAT在实际使用中,是需要SNAT配合的。上面的例子,如果外网设备的网关地址,也指向NAT主机,就不需要SNAT,但是实际场景,这是不存在的
      2年前
    • 朱双印
    • 散人零零一0
      本是青灯不归客,但因浊酒留风尘。星光不问赶路人,岁月不负有心人。
      2年前
    • 朱双印
    • 大学校猿0
      谢谢!这个是讲得最清晰最透彻的iptables教程。我真的是0基础,看完了全部博文,终于搞定了N2N下的网对网组网。网上大部分的教程逻辑是混乱的,容易给初学者很大的误导,真心推荐您的博文!再次感谢哈~
      2年前
      • 能对你有这种帮助我是从心里面感觉开心的,加油,共勉~
        2年前@大学校猿
    • 朱双印
    • 小学生0
      请教博主,能否实现ipv4到ipv6的nat转换?
      2年前
    • 朱双印
    • fischer0
      外部网路主机响应时请求时,路由器会在NAT表中找到某个内网地址和端口,然后在转发到内网,那这个查询条件是什么?
      2年前
      • 朱双印
        可爱小肉鸽0
        "内网地址"和"端口号",特别要注意这个端口号,是路由器做nat时,映射后的端口号,路由器计算出来的,不是你内网电脑最初的源端口号了~~~
        2年前@fischer
    • 朱双印
    • 小鬼0
      请问下大侠作者,对于SNAT,我们可以用MASQUERAED选项进行动态配置,那对于DNAT,可以有类似动态配置选项?因为对于DNAT,外网IP也是不固定的啊
      3年前
    • 朱双印
    • 默然0
      在已经有访问公网IP下的某个端口时,再进行这个端口的转发,这个情况配置的NAT是无法生效的:https://blog.csdn.net/dog250/article/details/17654157 不知道能不能解析一下这是什么造成的,链接上的文章说得不太清楚。。。
      3年前
    • 朱双印
    • 老张0
      再次感谢博主好文。又来找错别字了。 在C主机上向A主机的外网IP发送评(ping)请求 就能够是(使)内网主机能够共享公网IP访问互联网了 可以隐藏网内主机的IP地址。 感觉之前很多地方都是用的内网。
      3年前
    • 朱双印
    • 碧海蓝天0
      ###网关IP地址配置### [root@hostB ~]# ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:1c:42:a4:a2:f5 brd ff:ff:ff:ff:ff:ff inet 192.168.1.146/24 scope global eth0 valid_lft forever preferred_lft forever inet 192.168.1.148/24 scope global secondary eth0 valid_lft forever preferred_lft forever inet6 fe80::21c:42ff:fea4:a2f5/64 scope link valid_lft forever preferred_lft forever 3: eth1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:1c:42:e6:c2:06 brd ff:ff:ff:ff:ff:ff inet 10.1.0.3/24 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::21c:42ff:fee6:c206/64 scope link valid_lft forever preferred_lft forever ###网关iptables配置### [root@hostB ~]# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT tcp -- 0.0.0.0/0 192.168.1.148 tcp dpt:22 to:10.1.0.1:22 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 ###外网SSH访问内网### [root@hostA ~]# ssh 192.168.1.148 The authenticity of host '192.168.1.148 (192.168.1.148)' can't be established. ECDSA key fingerprint is SHA256:ujcBzNfBzItOB1H903OZeTXWKCU/jb+2v1Ifwm9G9f4. ECDSA key fingerprint is MD5:c7:bc:7a:8b:c2:c5:65:c8:1e:a6:3c:f7:01:00:87:51. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.1.148' (ECDSA) to the list of known hosts. root@192.168.1.148's password: Last login: Fri Sep 28 20:25:14 2018 from 192.168.1.147 [root@hostC ~]# ###结论### 不需要加SNAT,完全没有问题的。
      3年前
        • 朱双印
          hungryfotit0
          老哥儿 超想加你微信 从你的博客能干感受到你的思维 太棒了你这人
          2年前@朱双印
    • 朱双印
    • 梦想&生活0
      非常感谢博主的无私分享,受益匪浅。 有个小疑问,在模拟测试 iptables -t nat -I PREROUTING -d 192.168.0.146 -p tcp --dport 3389 -j DNAT --to-destination 10.1.0.9:3389这条规则时,我没有添加 SNAT规则,仍然可以成功地实现远程桌面连接,使用的系统是Ubuntu 14.04.5 和Windows XP专业版。 不知道什么情况下需要添加SNAT规则
      3年前
      • 朱双印
        alex0
        你是不是开了转发功能,开了就变成了路由器,两个网段在B上都是直连的,能直接路由数据,不需要NAT
    • 朱双印
    • 汤尼房0
      对文中的这段话“所以我们应该在报文到达路由层面之前就修改报文的目标地址,所以我们应该在PREROUTING链或OUTPUT链中定义DNAT规则”有些疑惑,OUTPUT链是在路由判断之后啊不是在路由层面之前,望朱哥帮忙解答一下
      3年前
      • 之前的路由次序有遗漏,已经修改为最新的完整路由次序,谢谢兄弟们的讨论,也是文章更加完善,加油~~
        3年前@汤尼房
    • 朱双印
    • binyao0
      做DNAT时,如果目标地址为内网中不同VLAN的IP段(意思是和iptables服务器内网网卡不在同一IP段),发现外网就无法连接指定的内网服务器。 请问如何解决?
      3年前
    • 朱双印
    • jayhello0
      确实干货多啊,看到的朋友多多支持下,只有鼓励作者才有更大的动力写出更优质的文章啊!!!!!
      3年前
    • 朱双印
    • Icy0
      使用MASQUERADE时,必须使用-o 参数?和-i有什么区别?
      3年前
      • 朱双印
        alex0
        outbound and inbound 指定数据包出站接口和入站接口
        1年前@Icy
    • 朱双印
    • liojio0
      有些细节没说清楚,无法理解本章设置forward后与“iptables网络防火墙”中设置forward后有什么区别,本章中设置forward后A、C不能通信,而在“iptables网络防火墙”一章中设置forward后A、C能实现通信,这两种说法是否有矛盾?不同点在哪?
      3年前
    • 朱双印
    • 我只看看0
      三层以下,以及二三层间有无什么安全机制呢?我知道ebtable,但是不知道怎么和iptable搭配,求指教!
      4年前
    • 朱双印
    • 飞翔的98K0
      主机A,桥接模式,公网IP:172.17.200.34 主机B,桥接模式,公网IP:172.17.200.54 仅主机模式,私网IP:192.168.83.130 主机C,仅主机模式,私网IP:192.168.83.128,网关:192.168.83.130 主机B开启ipv4_forward,清空FORWARD设置 主机B的SNAT和DNAT规则如下 iptables -t nat -nvL Chain PREROUTING (policy ACCEPT 13 packets, 1194 bytes) pkts bytes target prot opt in out source destination 2 388 DNAT all -- * * 0.0.0.0/0 172.17.200.54 to:192.168.83.130 Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 84 SNAT all -- * * 192.168.83.0/24 0.0.0.0/0 to:172.17.200.54 主机A和主机C都不存在禁ping的设置; ------------------------------------------------------------------------ 现在的情况是 C可以ping通A 但A不能ping通C 看了下tcpdump CpingA时,在B的eth1有明显的net转换 但是在ApingC时,在B的eth0没有转换 试了下,ApingB的私网IP,也ping不通,感觉就像我的DNAT配置的有问题,没有起到转换的操作,但是规则来看感觉又没什么问题 请博主看看
      4年前
    • 朱双印
    • 呀o0
      如果C,D的默认网关指向B,B开启内核转发功能,那么不配置任何SNAT规则C和D也是可以访问公网的吧,那这样的话iptables中加的SNAT规则有什么用处?
      4年前
      • B开启核心转发,C、D默认网关指向B,我测试时是不能访问公网的,你有做其他设置吗?
        4年前@呀o
        • 朱双印
          呀o0
          哦 抱歉,发现是开启了MASQUERADE
          4年前@朱双印
    • 朱双印
    • 国师0
      在centos7中,SNAT只能存在POSTROUTING和INPUT 链中,在centos6中只能存在”PREROUTING”链中.,有没有问题呀,感觉有点问题
      4年前
      • 不好意思,笔误了,应该是POSTROUTING链中,文章已经修改过来了,谢谢客官指正,常来呦~~
        4年前@国师
    • 朱双印
    • Pharys0
      利用公网IP访问内网服务时,只要配置DNAT就可以了吧?报文在返回时,自动就有了SNAT的功能。类似于,内网IP访问外网时,只需要配置SNAT,自动就有了报文返回时的映射。
      4年前
      • 理论上只配置DNAT就行了,但是我做测试的时候不行,测试的时候对应的SNAT必须配置,否则就是不通,后来我又做了测试,只配置DNAT规则即可。
        4年前@Pharys
      • 后来我又做了测试,只配置DNAT是可以的,报文相应时能够自动SNAT,但是我也记得特别清楚,在做实验时不配置SNAT就是不通,这个情况我争取回来再还原一下。
        4年前@Pharys
        • 朱双印
          Alex0
          做端口映射的时候,什么时候需要加SANT,我来解释下吧: 1.客户端IP:192.168.0.10/24 防火墙IP:192.168.0.1/24 服务器IP:192.168.0.8/24 ,这种情况就需要加SNAT,原因是防火墙将包转发到服务器后,服务器发现源地址是192.168.0.10的包,会直接丢给客户端,而数据包不会经过防火墙,而客户端收到192.168.0.8 过来的数据包是会丢弃的,因为客户机请求的是192.168.0.1的端口。而加上了SNAT,服务器接收到的源地址是192.168.0.1 的包,回包还是会发给防火墙。 2.客户端IP:192.168.10.10/24 防火墙IP:192.168.0.1/24 服务器IP:192.168.0.8/24,这里分2种: 1.如果服务器的网关设置的是防火墙的ip192.168.0.1,就不需要加SNAT,应为服务器的回包会从防火墙经过。 2.服务器网关不是防火墙的ip192.168.0.1 ,这里就需要加上SNAT,原理和前面说的一样。
          3年前@朱双印
          • 朱双印
            alex0
            同一个网段下的访问问题与SNAT有关系吗,他们之间的数据转发只发生在链路层,用不到网络层
            1年前@Alex
            • 朱双印
              vivi1
              参考这个文章: https://www.jb51.net/LINUXjishu/402441.html 找到如下文字所在的例子,可以回答你的问题。 "我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户机的IP为$LAN_BOX,其他设置同上。 包离开$LAN_BOX,去往$INET_IP。 包到达防火墙。 包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP传输包的特点,只根据目的地的不同而改变目的地址,但不因传输过程要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交代一下原因)。 包离开防火墙,到达HTTP服务器。 HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX。 回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包扔掉而去等待“真正”的回复包。"
              12月前@alex
    • 朱双印
    • cpj0
      朱兄 基本上按照你的思路进行配置了 内网ping外网时 从主机B抓包获取的结果 只有request 而没有reply 不知为何?
      4年前
      • 是SNAT对吧? 主机A有没有禁ping,直接从B主机上ping主机A,可以ping通吗? 兄弟,方便把你的配置贴出来吗?大家一块讨论下···
        4年前@cpj
        • 朱双印
          cpj0
          主机B配置eth0 192.168.1.66 eth0:1 172.30.1.11 分机C配置 eth0 172.30.1.12 网关172.30.1.11 主机A配置 192.168.1.111 主机B可以分别ping通 C和A 转发规则: iptables -t nat -d 192.0.0.0/8 -A POSTROUTING -j SNAT --to-source 192.168.1.67 现在问题是分机C ping 主机A时 从主机B抓包只有request : 08:22:49.759431 IP 172.30.1.12 > 192.168.1.111: ICMP echo request, id 2, seq 25, length 64 08:22:50.759442 IP 172.30.1.12 > 192.168.1.111: ICMP echo request, id 2, seq 26
          4年前@朱双印
          • echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 172.XXX.XXX.XXX/掩码 -j SNAT --to-source 192.168.1.66 兄弟,我觉得如果你想要SNAT的话,应该用类似这种规则 先把之前的规则清除了,按照上面的配置试试
            4年前@cpj
            • 朱双印
              cpj0
              已经开启了 都不行 感觉echo 1 > /proc/sys/net/ipv4/ip_forward 就没起作用
              4年前@朱双印
              • 如果转发压根没有起作用,是没有办法nat的,可以先配置好对应的路由条目,试试会不会转发
                4年前@cpj
                • 朱双印
                  cpj0
                  好的 多谢 我再看看吧
                  4年前@朱双印
    • 朱双印
    • 问天0
      朱兄 什么时候 写一个 tcpdump的教程啊 看iptables 看的真爽.
      4年前
      • 说实话,有些工具或命令我也只是会用个大概,不敢拿出来献丑,我尽量提升自己,给大家写文章啊~
        4年前@问天
    • 朱双印
    • 小石头0
      加油更啊兄弟,我要等养肥了再看,过瘾!
      4年前
    • 朱双印
    • mapix0
      赞 lz , 要持续更哦!
      4年前
      • 兄弟捧场~最近公司事情多,忙完会的,有你们支持一定会坚持写博客的。
        4年前@mapix