iptables SNAT 和DNAT的转化配置实验
原文链接:http://www.jb51.net/LINUXjishu/402441.html
DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映谢。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映谢。
这是我们在设置Linux网关或者防火墙时经常要用来的两种方式。以前对这两个都解释得不太清楚,现在我在这里解释一下。
首先,我们要了解一下IP包的结构,如下图所示:
在任何一个IP数据包中,都会有Source IP Address与Destination IP
Address这两个字段,数据包所经过的路由器也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。而iptables的DNAT与SNAT就是根据这个原理,对Source
IP Address与Destination IP Address进行修改。
然后,我们再看看数据包在iptables中要经过的链(chain):
图中正菱形的区域是对数据包进行判定转发的地方。在这里,系统会根据IP数据包中的destination ip
address中的IP地址对数据包进行分发。如果destination ip
adress是本机地址,数据将会被转交给INPUT链。如果不是本机地址,则交给FORWARD链检测。
这也就是说,我们要做的DNAT要在进入这个菱形转发区域之前,也就是在PREROUTING链中做,比如我们要把访问202.103.96.112的访问转发到192.168.0.112上:
iptables -t nat -A PREROUTING -d 202.103.96.112 -j DNAT --to-destination 192.168.0.112
这个转换过程当中,其实就是将已经达到这台Linux网关(防火墙)上的数据包上的destination ip address从202.103.96.112修改为192.168.0.112然后交给系统路由进行转发。
而SNAT自然是要在数据包流出这台机器之前的最后一个链也就是POSTROUTING链来进行操作
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 58.20.51.66
这个语句就是告诉系统把即将要流出本机的数据的source
ip
address修改成为58.20.51.66。这样,数据包在达到目的机器以后,目的机器会将包返回到58.20.51.66也就是本机。如果不做这个操作,那么你的数据包在传递的过程中,reply的包肯定会丢失。
注意,DNAT target只能用在nat表的PREOUTING 和 OUTPUT 链中,或者是被这两条链调用的链里。但还要注意的是,包含DNAT target的连不能被除此之外的其他链调用,如POSTROUTING。
代码如下:
Option --to-destination
Example iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10
Explanation指定要写入IP头的地址,这也是包要被转发到的地方。上面的例子就是把所有发往地址15.45.23.67的包都转发到一段LAN使用的私有地址中,即192.168.1.1到192.168.1.10。如前所述,在这种情况下,每个流都会被随机分配一个要转发到的地址,但同一个流总是使用同一个地址。我们也可以只指定一个IP地址作为参数,这样所有包都被转发到同一台机子。我们还可以在地址后指定一个或一个范围的端口。比如:--to-destination
192.168.1.1:80或192.168.1.1:80-100。SNAT的语法和这个target的一样,只是目的不同罢了。要注意,只有先用--protocol指定了TCP或UDP协议,才能使用端口。
因为DNAT要做很多工作,所以我要再啰嗦一点。我们通过一个例子来大致理解一下它是如何工作的。比如,我想通过Internet连接发布我们的网站,但是HTTP
server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP
server的IP是%HTTP_IP(当然这是内网的了)。为了完成我们的设想,要做的第一件事就是把下面这个简单的规则加入到nat表的PREROUTING链中:
代码如下:
iptables -t nat -A PREROUTING --dst$INET_IP -p tcp --dport 80 -j DNAT / --to-destination $HTTP_IP
现在,所有从Internet来的、到防火墙的80端口去的包都会被转发(或称作被DNAT)到在内网的HTTP服务器上。如果你在Internet上试验一下,一切正常吧。再从内网里试验一下,完全不能用吧。这其实是路由的问题。下面我们来好好分析这个问题。为了容易阅读,我们把在外网上访问我们服务器的那台机子的IP地址记为$EXT_BOX。
包从地址为$EXT_BOX的机子出发,去往地址为$INET_IP的机子。
包到达防火墙。
防火墙DNAT(也就是转发)这个包,而且包会经过很多其他的链检验及处理。
包离开防火墙向$HTTP_IP前进。
包到达HTTP服务器,服务器就会通过防火墙给以回应,当然,这要求把防火墙作为HTTP到达$EXT_BOX的网关。一般情况下,防火墙就是HTTP服务器的缺省网关。
防火墙再对返回包做Un-DNAT(就是照着DNAT的步骤反过来做一遍),这样就好像是防火墙自己回复了那个来自外网的请求包。
返回包好像没经过这么复杂的处理、没事一样回到$EXT_BOX。
现在,我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户机的IP为$LAN_BOX,其他设置同上。
包离开$LAN_BOX,去往$INET_IP。
包到达防火墙。
包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP传输包的特点,只根据目的地的不同而改变目的地址,但不因传输过程要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交代一下原因)。
包离开防火墙,到达HTTP服务器。
HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX。
回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包扔掉而去等待“真正”的回复包。
针对这个问题有个简单的解决办法,因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达的那个地址,所以我们只要对这些包做SNAT操作即可。比如,我们来考虑上面的例子,如果对那些进入防火墙而且是去往地址为$HTTP_IP、端口为80的包做SNAT操作,那么这些包就好像是从$LAN_IP来的了。这样,HTTP服务器就会把回复包发给防火墙,而防火墙会再对包做Un-DNAT操作,并把包发送到客户机。解决问题的规则如下:
iptables -t -nat -A POSTROUTING -p tcp --dst$HTTP_IP --dport 80 -j SNAT / --to-source $LAN_IP
要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配包。
警告:我们刚才写的这条规则会对日志产生很大影响,这种影响应该说是很不好的,因为来自Internet包在防火墙内先后经过了DNAT和SNAT处理,才能到达HTTP服务器(上面的例子),所以HTTP服务器就认为包是防火墙发来的,而不知道真正的源头是其他的IP。这样,
当它记录服务情况时,所有访问记录的源地址都是防火墙的IP而不是真正的访问源。我们如果想根据这些记录来了解访问情况就不可能了。因此上面提供的“简单办法”并不是一个明智的选择,但它确实可以解决“能够访问”的问题,只是没有考虑到日志而已。
其他的服务也有类似的问题。比如,你在LAN内建立了SMTP服务器,那你就要设置防火墙以便能转发SMTP的数据流。这样你就创建了一个开放SMTP的中继服务器,随之而来的就是日志的问题了。
一定要注意,这里所说的问题只是针对没有建立DMZ或类似结构的网络,并且内网的用户访问的是服务器的外网地址而言的。(译者注:因为如果建立的DMZ,或者服务器和客户机又被分在不同的子网里,那就不需要这么麻烦了。因为所有访问的源头都不在服务器所在的网里,所以就没有必要做SNAT去改变包的源地址了,从而记录也就不是问题了。如果内网客户是直接访问服务器的内网地址那就更没事了)
比较好的解决办法是为你的LAN在内网建立一台单独的DNS服务器(译者注:这样,内网客户使用网站名访问HTTP服务器时,DNS就可以把他解析成内网地址。客户机就可以直接去访问HTTP服务器的内网地址了,从而避免了通过防火墙的操作,而且包的源地址也可以被HTTP服务器的日志使用,也就没有上面说的日志问题了。),或者干脆建立DMZ得了(这是最好的办法,但你要有钱哦,因为用的设备多啊)。
对上面的例子应该考虑再全面些,现在还有一个问题没解决,就是防火墙自己要访问HTTP服务器时会发生什么,能正常访问吗?你觉得呢:)很可惜,现在的配置还是不行,仔细想想就明白了。我们这里讨论的基础都是假设机子访问的是HTTP服务器的外网地址,那客户机就会看到页面内容,不过这不是它想看到的(它想要的在DNAT上了),如果没有HTTP服务,客户就只能收到错误信息了。前面给出的规则之所以不起作用是因为从防火墙发出的请求包不会经过那两条链。还记得防火墙自己发出的包经过哪些链吧:)
我们要在nat表的OUTPUT链中添加下面的规则:
代码如下:
iptables -t nat -A OUTPUT --dst$INET_IP -p tcp --dport 80 -j DNAT / --to-destination $HTTP_IP
有了最后这条规则,一切都正常了。和HTTP服务器不在同一个网的机子能正常访问服务了,和它在一个网内的机子也可以正常访问服务了,防火墙本身也可以正常访问服务了,没有什么问题了。
我想大家应该能明白这些规则只是说明了数据包是如何恰当的被DNAT和SNAT的。除此之外,在filter表中还需要其他的规则(在FORWARD链里),以允许特定的包也能经过前面写的(在POSTROUTING链和OUTPUT链里的)规则。千万不要忘了,那些包在到达FORWARD链之前已经在PREROUTING链里被DNAT过了,也就是说它们的目的地址已经被改写,在写规则时要注意这一点。
iptables SNAT 和DNAT的转化配置实验的更多相关文章
- iptables snat和dnat
iptables中的snat和dnat是非常有用的,感觉他们二个比较特别,所以单独拿出来说一下. dnat是用来做目的网络地址转换的,就是重写包的目的IP地址.如果一个包被匹配了,那么和它属于同一个流 ...
- iptables snat 和dnat说明
iptables中的snat和dnat是非常有用的,感觉他们二个比较特别,所以单独拿出来说一下. dnat是用来做目的网络地址转换的,就是重写包的目的IP地址.如果一个包被匹配了,那么和它属于同一个流 ...
- Iptables防火墙(SNAT和DNAT)
1.SNAT:源地址转换 实现内网访问外网,修改IP地址,使用POSTROUTING 命令:iptables -t nat -A POSTROUTING -s 192.168.1.10/2 ...
- 10.Linux防火墙iptables之SNAT与DNAT
Linux防火墙iptables之SNAT与DNAT 目录 Linux防火墙iptables之SNAT与DNAT SNAT策略及应用 SNAT策略概述 SNAT策略典型应用环境 SNAT策略原理 SN ...
- 详解Linux下iptables中的DNAT与SNAT设置(转)
详解Linux下iptables中的DNAT与SNAT设置 这篇文章主要介绍了Linux下iptables中的DNAT与SNAT设置,是Linux网络配置中的基础知识,需要的朋友可以参考下 原文连 ...
- Iptables 下 SNAT、DNAT和MASQUERADE三者之间的区别
Iptables 中可以灵活的做各种网络地址转换(NAT,Network Address Translation) 网络地址转换(NAT)主要有两种:SNAT 和 DNAT,但是也有一种特例 MASQ ...
- [转] Linux下防火墙iptables用法规则详及其防火墙配置
from: http://www.cnblogs.com/yi-meng/p/3213925.html 备注: 排版还不错,建议看以上的链接. iptables规则 规则--顾名思义就是规矩和原则,和 ...
- Linux下防火墙iptables用法规则详及其防火墙配置
转:http://www.linuxidc.com/Linux/2012-08/67952.htm iptables规则 规则--顾名思义就是规矩和原则,和现实生活中的事情是一样的,国有国法,家有家规 ...
- [daily] SNAT和DNAT
SNAT,DNAT,MASQUERADE都是NAT MASQUERADE是SNAT的一个特例 SNAT是指在数据包从网卡发送出去的时候,把数据包中的源地址部分替换为指定的IP,这样,接收方就认为数据包 ...
随机推荐
- Java才是世界上最好的语言,Java在高频交易中替代C++
高频交易 高频交易是指从那些人们无法利用的极为短暂的市场变化中寻求获利的计算机化交易,比如,某种证券买入价和卖出价差价的微小变化,或者某只股票在不同交易所之间的微小价差.在高频交易中,自动化应用程序每 ...
- MySQL主主数据同步
环境 操作系统版本:CentOS 6.5 64位MySQL版本:mysql5.6节点1IP:192.168.0.235 主机名:taojiang1-mysql-01节点2IP:192.168.0.23 ...
- 框架篇:见识一下linux高性能网络IO+Reactor模型
前言 网络I/O,可以理解为网络上的数据流.通常我们会基于socket与远端建立一条TCP或者UDP通道,然后进行读写.单个socket时,使用一个线程即可高效处理:然而如果是10K个socket连接 ...
- Pytest学习(六) - conftest.py结合接口自动化的举例使用
一.conftest.py作用 可以理解成存放fixture的配置文件 二.conftest.py配置fixture注意事项 pytest会默认读取conftest.py里面的所有fixture co ...
- 跟我一起学Redis之Redis事务简单了解一下
前言 关系数据库中的事务,小伙伴们应该是不陌生了,不管是在开发还是在面试过程中,总有两个问题逃不掉: 说说事务的特性: 事务隔离级别是怎么一回事? 事务处理不好,数据就可能不准确,最终就会导致业务出问 ...
- Table is marked as crashed and should be repaired 解决办法
遇到这个问题几个敲命令轻松搞定 1.首先进入mysql命令台: mysql -u root -p 回车 输入密码 2.查询所有的库 mysql> show databases; 3.进入数据库 ...
- 13flask密码加密
一,了解密码加密方式 密码具有私有性较强的特性,预测密码加密对个人隐私的保护有这非常大的作用.在用flask搭建网站时候若服务器有被攻破的风险,要是用户表中密码字段也被拿走,后果将不堪设想. 在密码保 ...
- CentOS修改镜像源头
CentOS6改为阿里镜像源: 1. cd /etc/yum.repos.d 2. mv CentOS-Base.repo CenOS-Base.repo.bak 3. wget http://mir ...
- tcp syn-synack-ack 服务端 接收 SYN tcp_v4_do_rcv分析
rcv 分析: /* The socket must have it's spinlock held when we get * here, unless it is a TCP_LISTEN soc ...
- mysql中数据类型DECIMAL(M,D)的说明
本文转载自Boblim的文章http://www.cnblogs.com/fnlingnzb-learner/p/8108119.html 在MySQL数据类型中,例如INT,FLOAT,DOUBLE ...