终于搞点iptables端口映射了,

搞了一天,终于搞定iptables了,,开头就对着人家配对了的配置对抄,但怎也不对,在网上搜了N多文章也不对,终于找到了一篇比较详细的,看了二次,终于配置成功,如今能够用端口映射访问内网的SSH和VNC等等的了
文章转载以下:linux

iptables 应用初探(nat+三层访问控制)
本文做者:张天成    zhangtiancheng#gmail.com 转发请注明出处。

    iptables是一个Linux下优秀的nat+防火墙工具,我使用该工具以较低配置的传统pc配置了一个灵活强劲的防火墙+nat系统,小有心得,看了网上也有不少这方面的文章,可是彷佛要么说的比较少,要么就是比较偏,内容不全,容易误导,我研究了一段时间的iptables同时也用了好久,有点滴经验,写来供你们参考,同时也备往后本身翻阅。
首先要说明的是,iptables操做的是2.4以上内核的netfilter.因此须要linux的内核在2.4以上。其功能与安全性远远比其前辈 ipfwadm,ipchains强大,iptables大体是工做在OSI七层的2、3、四层,其前辈ipchains不能单独实现对tcp/udp port以及对mac地址的的定义与操做,因此我想ipchains应该是仅仅工做在三层上的。

    咱们先简单介绍一下netfilter的大体工做流程,也就是一个数据包(或者叫分组、packet,我我的习惯叫包)在到达linux的网络接口的时候(网卡)如何处理这个包,而后再介绍一下如何用iptables改变或者说控制对这个数据包进行操做。netfilter内部分为三个表,分别是 filter,nat,mangle,每一个表又有不一样的操做链(Chains)。在filter(过滤)表中,也就是他的防火墙功能的这个表,定义了三个 Chain。分别是INPUT,FORWARD,OUTPUT。也就是对包的入、转发、出进行定义的三个过滤链。对于这个filter表的操做和控制也是咱们实现防火墙功能的一个重要手段;在nat(Network Address Translation、网络地址翻译)表中,也就是咱们用以实现地址转换和端口转发功能的这个表,定义了PREROUTING, POSTROUTING,OUTPUT三个链,下面咱们会对这三个链做详细的说明;而netfilter的mangle表则是一个自定义表,里面包括上面的filter以及nat表中的各类chains,它可让咱们进行一些自定义的操做,同时这个mangle表中的chains在netfilter对包的处理流程中处在一个比较优先的位置,下面有一张图清晰的描绘了netfilter对包的处理流程(该图摘自网上,不知做者是谁,在此深表敬意!),通常状况下,咱们用不到这个mangle表,在这里咱们就不作介绍了。
  你们能够看到,PREROUTING这个chain在最前面,当一个包来到linux的网络接口的时候先过mangle的PREROUTING,而后是 nat的PREROUTING,从这个chain的名字咱们能够看出,这个chain是在路由以前(pre-routing)要过的。为何要在路由以前过呢?你们能够看到这个图上,上面有一个菱形的部分叫ROUTING,这个ROUTING部分就是Linux的route box,也就是路由系统,它一样有很高深的功能,能够实现策略路由等等一些高级特性,此处咱们不作详细解释。单说这个PREROUTING链,由于在这个链里面咱们对包的操做是DNAT,也就是改变目的地址和(或端口),一般用在端口转发,或者nat到内网的DMZ区,也就是说当一个包过来的时候咱们要改变它的目的地址,你们能够想一想,若是一个包在改变目的地址以前就被扔进了route box,让系统选好路以后再改变目的地址,那么选路就多是错的,或者说毫无心义了,因此,PREROUTING这个Chain必定要在进Routing 以前作。好比说,咱们的公网ip是60.1.1.1/24,位于linux中的eth0,内网ip是10.1.1.1/24位于linux中的eth1, 咱们的内网有一台web服务器,地址是10.1.1.2/24,咱们怎么样能让internet用户经过这个公网ip访问咱们内部的这个web服务器呢?咱们就能够在这个PREROUTING链上面定义一个规则,把访问60.1.1.1:80的用户的目的地址改变一下,改变为10.1.1.2:80,这样就实现了internet用户对内网服务器的访问了,固然了,这个端口是比较灵活的,咱们能够定义任何一个端口的转发,不必定是80-->80,具体的命令咱们在下面的例子中介绍,这里咱们只谈流程与概念上的实现方法。好了,咱们接着往下走,这个包已通过了两个PREROUTING链了,这个时候,出现了一个分支转折的地方,也就是图中下方的那个菱形(FORWARD),转发!这里有一个对目的地址的判断(这里一样说明了PREROUTING必定要在最早,不只要在route box以前,甚至是这个对目的地址的判断以前,由于咱们可能作一个去某某某ip的地方转到本身的ip的规则,因此PREROUTING是最早处理这个包的 Chain)!若是包的目的地是本机ip,那么包向上走,走入INPUT链处理,而后进入LOCAL PROCESS,若是非本地,那么就进入FORWARD链进行过滤,咱们在这里就不介绍INPUT,OUTPUT的处理了,由于那主要是对于本机安全的一种处理,咱们这里主要说对转发的过滤和nat的实现。这里的FORWARD我简单说一下,当linux收到了一个目的ip地址不是本地的包,Linux会把这个包丢弃,由于默认状况下,Linux的三层包转发功能是关闭的,若是要让咱们的linux实现转发,则须要打开这个转发功能,能够改变它的一个系统参数,使用sysctl net.ipv4.ip_forward=1或者echo "1" > /proc/sys/net/ipv4/ip_forward命令打开转发功能。好了,在这里咱们让linux容许转发,这个包的目的地址也不是本机,那么它将接着走入FORWARD链,在FORWARD链里面,咱们就能够定义详细的规则,也就是是否容许他经过,或者对这个包的方向流程进行一些改变,这也是咱们实现访问控制的地方,这里一样也是Mangle_FORWARD而后filter_FORWARD,咱们操做任何一个链都会影响到这个包的命运,在下面的介绍中,咱们就忽略掉mangle表,咱们基本用不到操做它,因此咱们假设它是透明的。假设这个包被咱们的规则放过去了,也就是ACCEPT了,它将进入POSTROUTING部分,注意!这里我注意到一个细节问题,也就是上面的图中数据包过了FORWARD链以后直接进入了POSTROUITNG 链,我以为这中间缺乏一个环节,也就是route box,对于转发的包来讲,linux一样须要在选路(路由)以后才能将它送出,这个图却没有标明这一点,我认为它是在过了route box以后才进入的POSTROUITNG,固然了,这对于咱们讨论iptables的过滤转发来讲不是很重要,只是我以为流程上有这个问题,仍是要说明一下。一样的,咱们在这里从名字就能够看出,这个POSTROUTING链应该是路由以后的一个链,也就是这个包要送出这台Linux的最后一个环节了,这也是极其重要的一个环节!!这个时候linux已经完成(has done..^_^)了对这个包的路由(选路工做),已经找到了合适的接口送出这个包了,在这个链里面咱们要进行重要的操做,就是被Linux称为 SNAT的一个动做,修改源ip地址!为何修改源ip地址?不少状况须要修改源地址阿,最多见的就是咱们内网多台机器须要共享一个或几个公网ip访问 internet,由于咱们的内网地址是私有的,假如就让linux给路由出去,源地址也不变,这个包应该能访问到目的地,可是却回不来,由于 internet上的N多个路由节点不会转发私有地址的数据包,也就是说,不用合法ip,咱们的数据包有去无回。有人会说:“既然是这样,我就不用私有 ip了,我本身分配本身合法的地址不行吗?那样包就会回来了吧?”答案是否认的,ip地址是ICANN来分配的,你的数据包或许能发到目的地,可是回来的时候人家可不会转到你那里,internet上的路由器中的路由信息会把这个返回包送到那个合法的得到ip的地方去,你一样收不到,而你这种行为有可能被定义为一种ip欺骗,不少设备会把这样的包在接入端就给滤掉了,可能都到不了你要访问的那个服务器,呵呵。那么Linux如何作SNAT呢?好比一个内网的10.1.1.11的pc访问202.2.2.2的一个web服务器,linux的内网接口10.1.1.1在收到这个包以后把原来的PC的 ip10.1.1.11改变为60.1.1.1的合法地址而后送出,同时在本身的ip_conntrack表里面作一个记录,记住是内网的哪个ip的哪一个端口访问的这个web服务器,本身把它的源地址改为多少了,端口改为多少了,以便这个web服务器返回数据包的时候linux将它准确的送回给发送请求的这个pc.  大致的数据转发流程咱们说完了,咱们看看iptables使用什么样的参数来完成这些操做。在描述这些具体的操做以前,我还要说几个我对iptables的概念的理解(未必彻底正确),这将有助于你们理解这些规则,以实现更精确的控制。上文中咱们提到过,对包的控制是由咱们在不一样的Chain(链)上面添加不一样的规则来实现的,好比咱们对过滤表(filter table)添加规则来执行对包的操控。那么既然叫链,必定就是一条或者多条规则组成的了,这时就有一个问题了,若是多个规则对同一种包进行了定义,会发生什么事情呢?在Chain中,全部的规则都是从上向下来执行的,也就是说,若是匹配了第一行,那么就按照第一行的规则执行,一行一行的往下找,直到找到符合这个类型的包的规则为止。若是找了一遍没有找到符合这个包的规则怎么办呢?itpables里面有一个概念,就是Policy,也就是策略。一说这个东西你们可能就会以为比较麻烦,什么策略阿,我对于它的理解就是所谓这个策略就是chain中的最后一条规则,也就是说若是找了一遍找不到符合处理这个包的规则,就按照policy来办。这样理解起来就容易多了。iptables 使用-P来设置Chain的策略。好了,咱们言归正传,来讲说iptables到底怎样实现对包的控制先介绍一下iptables如何操做链对链的操做就那么几种,-I(插入) -A(追加) -R(替换) -D(删除) -L(列表显示)这里要说明的就是-I将会把规则放在第一行,-A将会放在最后一行。好比咱们要添加一个规则到filter表的FORWARD链iptables -t filter -A FORWARD -s 10.1.1.11 -d 202.1.1.1 -j ACCEPT上面的命令意思为:追加一个规则至filter表中的FORWARD链尾,容许(-j ACCEPT)源地址为10.1.1.11目的地址为202.1.1.1的数据包经过。其中-t后面跟的是表名,在-A后面跟Chain名,后面的小写的 -s为源地址,-d为目的地址,-j为处理方向。在iptables中,默认的表名就是filter,因此这里能够省略-t filter直接写成:iptables -A FORWARD -s 10.1.1.11 -d 202.1.1.1 -j ACCEPTiptables中的匹配参数:咱们在这里就介绍几种经常使用的参数,详细地用法能够man iptables看它的联机文档,你会有意外的收获。-s匹配源地址-d匹配目的地址-p协议匹配-i入接口匹配-o出接口匹配--sport,--dport源和目的端口匹配-j跳转,也就是包的方向其中还有一个!参数,使用!就是取反的意思。下面咱们简单举几个例子介绍一下。-s这个参数呢就是指定源地址的,若是使用这个参数也就是告诉netfilter,对于符合这样一个源地址的包怎么去处理,能够指定某一个单播ip地址,也能够指定一个网络,若是单个的ip地址其实隐含了一个32位的子网掩码,好比-s 10.1.1.11 其实就是-s 10.1.1.11/32 一样咱们能够指定不一样的掩码用以实现源网络地址的规则,好比一个C类地址咱们能够用-s 10.1.1.0/24来指定。-d参数与-s格式同样。-i参数是指定入接口的网络接口,好比我仅仅容许从eth3接口过来的包经过FORWARD链,就能够这样指定iptables -A FORWARD -i eth3 -j ACCEPT-o是出接口,与上同.咱们下面用一些简单的实例来step by step看看iptables的具体配置方法。实例一:简单的nat路由器环境介绍:linux 2.4 +2个网络接口Lan口:10.1.1.254/24 eth0Wan口:60.1.1.1/24 eth1目的:实现内网中的节点(10.1.1.0/24)可控的访问internet。首先将Lan的节点pc的网关指向10.1.1.254肯定你的linux的ip配置无误,能够正确的ping通内外的地址。同时用route命令查看linux的本地路由表,确认指定了可用的ISP提供的默认网关。使用sysctl net.ipv4.ip_forward=1打开linux的转发功能。iptables -P FORWARD DROP将FORWARD链的策略设置为DROP,这样作的目的是作到对内网ip的控制,你容许哪个访问internet就能够增长一个规则,不在规则中的ip将没法访问internet.iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT这条规则规定容许任何地址到任何地址的确认包和关联包经过。必定要加这一条,不然你只容许lan IP访问没有用,至于为何,下面咱们再详细说。iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -j SNAT --to 60.1.1.1这条规则作了一个SNAT,也就是源地址转换,未来自10.1.1.0/24的地址转换为60.1.1.1有这几条规则,一个简单的nat路由器就实现了。这时你能够将容许访问的ip添加至FORWARD链,他们就能访问internet了。好比我想让10.1.1.9这个地址访问internet,那么你就加以下的命令就能够了。iptables -A FORWARD -s 10.1.1.9 -j ACCEPT也能够精确控制他的访问地址,好比我就容许10.1.1.99访问3.3.3.3这个ipiptables -A FORWARD -s 10.1.1.99 -d 3.3.3.3 -j ACCEPT或者只容许他们访问80端口。iptables -A FORWARD -s 10.1.1.0/24 -p tcp --dport http -j ACCEPT更多的控制能够本身灵活去作,或者查阅iptables的联机文档。实例二:端口转发环境介绍:linux 2.4 +2个网络接口Lan口:10.1.1.254/24 eth0Lan内web server: 10.1.1.1:80Lan内ftp server: 10.1.1.2:21Wan口:60.1.1.1/24 eth1目的:对内部server进行端口转发实现internet用户访问内网服务器一样确认你的linux的各项配置正常,可以访问内外网。iptables -P FORWARD DROPiptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT也须要加入确认包和关联包的容许经过若是你要把访问60.1.1.1:80的数据包转发到Lan内web server,用下面的命令iptables -t nat -A PREROUTING -d 60.1.1.1 -p tcp --dport 80 -j DNAT --to 10.1.1.1:80ftp服务也一样,命令以下:iptables -t nat -A PREROUTING -d 60.1.1.1 -p tcp --dport 21 -j DNAT --to 10.1.1.2:21好了,命令完成了,端口转发也作完了,本例能不能转发呢?不能,为何呢?我下面详细分析一下。对于iptables好像往外访问的配置比较容易,而对内的转发彷佛就有一些问题了,在一开始的时候我就先说了一些关于netfilter的流程问题,那么我就简单说说作了这些配置以后为何有可能还不行呢?能引发这个配置失败的缘由有不少,咱们一个个的来讲:第一,本例中,咱们的FORWARD策略是DROP,那么也就是说,没有符合规则的包将被丢弃,无论内到外仍是外到内,咱们在这里依然不讨论那个确认包和关联包的问题,咱们不用考虑他的问题,下面我会详细说一下这个东西,那么如何让本例能够成功呢?加入下面的规则。iptables -A FORWARD -d 10.1.1.1 -p tcp --dport 80 -j ACCEPTiptables -A FORWARD -d 10.1.1.2 -p tcp --dport 21 -j ACCEPT有没有以为有一些晕?为何目的地址是10.xxx而不是60.xxx人家internet用户不是访问的60.xxx吗?呵呵,回到上面看看那个图吧, FORWARD链在什么位置上,它是在PREROUTING以后,也就是说当这个包到达FORWARD链的时候,目的地址已经变成10.xxx了,假如 internet用户的请求是这样202.1.1.1:1333-->60.1.1.1:80,在通过了咱们的PREROUTING链以后将变成 202.1.1.1:1333-->10.1.1.1:80,这个时候若是你设置一个目的地址为60.xxx的规则有用吗?呵呵,这是问题一。这个时候应该能够完成端口转发的访问了,可是有一些时候仍是不行?为何?看问题二。第二,内网server的ip配置问题,这里咱们以web server为例说明一下(ftp状况有一些特殊,下面咱们再详细讨论,说确认包和关联包的时候讨论这个问题),上面说到,有的时候能够访问了,有的时候却不行,就是这个web server的ip设置问题了,若是web server没有指定默认的网关,那么在做了上面的配置以后,web server会收到internet的请求,可是,他不知道往哪里回啊,人家的本地路由表不知道你那个internet的ip,202.1.1.1该怎么走。若是你使用截包工具在web server上面察看,你会发现server收到了来自202.1.1.1:1333-->10.1.1.1:80的请求,因为你没有给web server配置默认网关,它不知道怎么回去,因此就出现了不通的状况。怎么办呢?两个解决方法:一就是给这个server配置一个默认网关,固然要指向这个配置端口转发的linux,本例是10.1.1.254,配置好了,就必定能访问了。有一个疑问?难道不须要在FORWARD链上面设置一个容许 web server的ip地址访问外网的规则吗?它的包能出去?答案是确定的,能出去。由于咱们那一条容许确认包与关联包的规则,不然它是出不去的。第二种方法,比较麻烦一些,可是对服务器来讲这样彷佛更安全一些。方法就是对这个包再做一次SNAT,也就是在POSTROUTING链上添加规则。命令以下:iptables -t nat -A POSTROUTING -d 10.1.1.1 -p tcp --dport 80 -j SNAT --to 10.1.1.254ftp的方法相同。这条命令不太好懂??其实很简单,若是使用这条命令,那么你的web server不须要再设置默认网关,就能收到这个请求,只要他和linux的lan ip地址是能互访的(也就是说web server和Linux的Lan ip在一个广播域),咱们在根据上面的netfilter流程图来分析这个包到底被咱们怎么样了,首先一个请求202.1.1.1:1333--> 60.1.1.1:80被linux收到了,进入PREROUTING,发现一个规则(iptables -t nat -A PREROUTING -d 60.1.1.1 -p tcp --dport 80 -j DNAT --to 10.1.1.1:80)符合,好了,改你的目的地址,因而这个包变成了202.1.1.1:1333-->10.1.1.1:80,继续往前走,进入FORWARD链,okay,也有一条规则容许经过(iptables -A FORWARD -d 10.1.1.1 -p tcp --dport 80 -j ACCEPT),进入route box选路,找到合适的路径了,继续进入POSTROUTING链,耶?又发现一个符合的规则(iptables -t nat -A POSTROUTING -d 10.1.1.1 -p tcp --dport 80 -j SNAT --to 10.1.1.254),原来是一个SNAT,改你的源地址,因而这个包变成了10.1.1.254:xxxx-->10.1.1.1:80。为何用xxxx了,这里的端口是随机的,我也不知道会是什么。而整个的两次变化的过程都会记录在linux的ip_conntrack中,当web server收到这个包的时候,发现,原来是一个内网本身兄弟来的请求阿,又在一个广播域,不用找网关,把返回包直接扔给交换机了,linux在收到返回包以后,会根据他的ip_conntrack中的条目进行两次变换,返回真正的internet用户,因而完成这一次的访问。看了上面的两个例子,不知道你们是否清楚了iptables的转发流程,但愿对你们有所帮助,下面咱们就说说我一直在上面提到的关于那个 ESTABLISHED,RELATED的规则是怎么回事,到底有什么用处。说这个东西就要简单说一下网络的数据通信的方式,咱们知道,网络的访问是双向的,也就是说一个Client与Server之间完成数据交换须要双方的发包与收包。在netfilter中,有几种状态,也就是new, established,related,invalid。当一个客户端,在本文例一中,内网的一台机器访问外网,咱们设置了规则容许他出去,可是没有设置容许回来的规则阿,怎么完成访问呢?这就是netfilter的状态机制,当一个lan用户经过这个linux访问外网的时候,它发送了一个请求包,这个包的状态是new,当外网回包的时候他的状态就是established,因此,linux知道,哦,这个包是个人内网的一台机器发出去的应答包,他就放行了。而外网试图对内发起一个新的链接的时候,他的状态是new,因此linux压根不去理会它。这就是咱们为何要加这一句的缘由。还有那个 related,他是一个关联状态,什么会用到呢?tftp,ftp都会用到,由于他们的传输机制决定了,它不像http访问那样,Client_IP: port-->server:80  而后server:80-->Client_IP:port,ftp使用tcp21创建链接,使用20端口发送数据,其中又有两种方式,一种主动 active mode,一种被动passive mode,主动模式下,client使用port命令告诉server我用哪个端口接受数据,而后server主动发起对这个端口的请求。被动模式下, server使用port命令告诉客户端,它用那个端口监听,而后客户端发起对他的数据传输,因此这对于一个防火墙来讲就是比较麻烦的事情,由于有可能会有new状态的数据包,可是它又是合理的请求,这个时候就用到这个related状态了,他就是一种关联,在linux中,有个叫 ftp_conntrack的模块,它能识别port命令,而后对相应的端口进行放行。一口气写了这么多东西,不知道质量如何,你们凑和着看吧,但愿多多交流共同进步,我仍是一个linux的初学者,不免不少谬误,但愿高手赐教指正,以期不断进步。对了,还有几个在实际中比较实用(也比较受用:-))的命令参数,写出来供你们参考iptables -L -n这样的列表会跳过linux的domain lookup,有的时候使用iptables -L会比较慢,由于linux会尝试解析ip的域名,真是罗嗦,若是你的dns server比较不爽的话,iptables -L就会让你很不爽,加一个-n参数就行了。列表刷的就出来。固然了,若是你的linux就是作防火墙,建议把nameserver去掉,在 /etc/resolve.conf里面,由于有时候使用route命令也会比较慢列出来,非常不爽。iptables -L -v这个命令会显示链中规则的包和流量计数,嘿嘿,看看哪些小子用的流量那么多,用tc限了他。cat /proc/net/ip_conntrack查看目前的conntrack,可能会比较多哦,最好加一个|grep "关键字",看看你感兴趣的连接跟踪wc -l /proc/net/ip_conntrack看看总连接有多少条。iptables-save >/etc/iptables把当前的全部链备份一下,之因此放到/etc下面叫iptables,由于这样重起机器的时候会自动加载全部的链,常常地备份一下吧,不然若是链多,万一掉电重启,你仍是会比较痛苦。
相关文章
相关标签/搜索