Loading... <p><strong><span style="font-size: 24px">一、前言</span></strong></p> <p style="text-indent: 2em">什么是iptables?当我们启动iptables时,使用service命令可以启动iptables。但是并非使用service启动的iptables就能说明其是一个服务。Iptables是一个便以我们写规则的工具,真正起作用的是内核中的netfilter一个框架。Netfilter内置了5个hook函数,当一个数据包交由此机器时,经过这5个hook函数的其中某个才能进入用户空间,或者转发出去。</p> <p><strong><span style="font-size: 24px">二、netfilter工作原理</span></strong></p> <p><img src="//cto.wang/usr/uploads/2016/07/20160703180501-61.png" title="1445756327450621.png" alt="netfilter2.png" /></p> <p></p> <p style="text-indent: 2em">当数据包到达目标主机时,经过PREROUTING链,经路由之后决定是否转发,不转发则进入INPUT链,到达用户空间。进程对外通信时,经由OUTPUT链出去,路由之后到达POSTROUTING链,经网卡出去。当一数据包经过PREROUTING链发现其不是到达本主机,那么数据包经过FORWARD链,到达 POSTROUTING链转发出去。本机进程对发送数据时,经由OUTPUT链路由之后进入POSTROUTING链出去。iptables匹配规则时,是自上而下匹配的,匹配到第一条规则时既跳出,否则一直往下匹配,没有则使用默认规则。</p> <p></p> <p style="text-indent: 2em">五个hook函数分别是PREROUTING,INPUT ,OUTPUT,POSTROUTING,FORWARD,我们把这五个钩子函数称为链,Netfilter实现了几功能,raw ,mangle,nat,filter。我们一般把这几个功能称为表,表之间有优先级关系,从低到高为filter—-nat—-mangle—-raw,表与链之间有对应关系,具体见图表。</p> <table> <tbody> <tr class="firstRow"> <td width="209" valign="top">filter</td> <td width="209" valign="top">INPUT</td> <td width="209" valign="top">FORWARD</td> <td width="209" valign="top">OUPUT</td> <td width="209" valign="top"></td> <td width="209" valign="top"></td> </tr> <tr> <td width="209" valign="top">nat</td> <td width="209" valign="top">PREROUTING(DNAT)</td> <td width="209" valign="top">POSTROUTING(SNAT)</td> <td width="209" valign="top">OUTPUT</td> <td width="209" valign="top"></td> <td width="209" valign="top"></td> </tr> <tr> <td width="209" valign="top">mangle</td> <td width="209" valign="top">PREROUTING</td> <td width="209" valign="top">INPUT</td> <td width="209" valign="top">FORWARD</td> <td width="209" valign="top">OUTPUT</td> <td width="209" valign="top">POSTROUTING</td> </tr> <tr> <td width="209" valign="top">raw</td> <td width="209" valign="top">PREROUTING</td> <td width="209" valign="top">OUTPUT</td> <td width="209" valign="top"></td> <td width="209" valign="top"></td> <td width="209" valign="top"></td> </tr> </tbody> </table> <p style="text-indent: 2em">iptables规则建立时,首先需要确定功能(表),确定报文流向,确定要实现的目标,确定匹配条件。iptables时,<span style="font-family: arial, helvetica, sans-serif">尽量遵循以下规则:<span style="line-height: 21px;font-size: 16px">尽量减少规则条目,彼此间无关联,访问条目大放上面,有关联(同一功能),规则更严格的放上面</span></span></p> <p><strong><span style="font-size: 24px">三、基本语法</span></strong></p> <p style="line-height: normal">iptables [-t TABLE] COMMAND CHAIN CRETIRIA -j TARGET</p> <p style="line-height: normal">-t TABLE : TABLE为nat,mangle,raw,filter中的一个,默认为filter</p> <p style="line-height: normal"> <strong>COMMAND</strong> </p> <p style="line-height: normal"> 链 : -F 清空规则链</p> <p style="line-height: normal"> -N 自建一条链</p> <p style="line-height: normal"> -X 删除一条自定义空链</p> <p style="line-height: normal"> -Z 计数器归零</p> <p style="line-height: normal"> -P 设置默认策略</p> <p style="line-height: normal"> -E 重命名自定义链</p> <pre class="brush:bash;toolbar:false">iptables –t nat -F iptables –t filter –N web_services iptables –t filter –X web_services iptables –t filter -Z iptables –t filter –P DROP iptables –t filter –E web_services www_services</pre> <p style="line-height: normal"> <strong>规则:</strong></p> <p style="line-height: normal"> -A 在规则链最后添加一条规则</p> <p style="line-height: normal"> -I 在规则链中插入一条规则,默认为第一条</p> <p style="line-height: normal"> -D 删除一条规则链</p> <p style="line-height: normal"> -R 替换规则链</p> <pre class="brush:bash;toolbar:false"> iptables –t filter –A www_services –p tcp –-dport 80 –j ACCEPT iptables –t filter –I www_services –p tcp –-dport 22 –j ACCEPT iptables –t filter –D www_services –p tcp –-dport 22 –j ACCEPT iptables –t filter –D www_services 1 iptables –t filter –R www_services –p tcp –dport 22 –j DROP</pre> <p style="line-height: normal"> <strong>查看:</strong></p> <p style="line-height: normal"> -L: List</p> <p style="line-height: normal"> 子选项:</p> <p style="line-height: normal"> -n: numeric</p> <p style="line-height: normal"> -v, -vv, -vvv</p> <p style="line-height: normal"> -x: eXactly</p> <p style="line-height: normal"> –line-numbers</p> <p style="line-height: normal"> iptables –t filter –L –n –v</p> <p style="line-height: normal"> CRETIRIA</p> <p style="line-height: normal"> <strong>通用匹配</strong>:</p> <p style="line-height: normal"> -s, –src, –source:</p> <p style="line-height: normal"> -d, –dst, –destination:</p> <p style="line-height: normal"> -p {tcp|udp|icmp}:</p> <p style="line-height: normal"> -i IN_IF:</p> <p style="line-height: normal"> -o OUT_IF:</p> <p style="line-height: normal"> <strong>扩展匹配:</strong></p> <p style="line-height: normal"> 调用netfilter额外模块实现特殊检查机制,(使用到相关功能,要使用iptables命令的-m选项来指定调用哪个模块)</p> <p style="line-height: normal"> <strong>隐式扩展:</strong></p> <p style="line-height: normal"> -p tcp [-m tcp]</p> <p style="line-height: normal"> –sport PORT[-PORT]</p> <p style="line-height: normal"> –dport</p> <p style="line-height: normal"> –tcp-flag 要检查标志位列表(用逗号分隔) 必须为1的标志位列表(逗号分隔)</p> <p style="line-height: normal"> -p icmp [-m icmp]</p> <p style="line-height: normal"> –icmp-type</p> <p style="line-height: normal"> 0: echo-reply, ping响应</p> <p style="line-height: normal"> 8: echo-request, ping请求</p> <pre class="brush:bash;toolbar:false">iptables -t filter -A INPUT -p icmp --icmp-type 8 -j DROP iptables -t filter -A INPUT -p tcp --tcp-flags syn,ack,rst,fin syn -j DROP iptables -t filter -A INPUT -p tcp --dport 80 --tcp-flags all none -j DROP</pre> <p style="line-height: normal"> <strong>显式扩展:</strong></p> <p style="line-height: normal"> -m 扩展模块名称</p> <p style="line-height: normal"> 模块:iptables,netfilter各拥有一部分代码</p> <p style="line-height: normal"> multiport: 多端口匹配,可用于匹配非连续或连续端口;最多指定15个端口;</p> <p style="line-height: normal"> –source-ports, –sports port[,port,port:port]</p> <p style="line-height: normal"> –destination-ports, –dports</p> <p style="line-height: normal"> –ports</p> <pre class="brush:bash;toolbar:false">iptables -I INPUT -d 192.168.19.128 -p tcp -m multiport --dports 22,80 -j ACCEPT iptables -I OUTPUT -s 192.168.19.128 -p tcp -m multiport --ports 22,80 -j ACCEPT</pre> <p></p> <p style="line-height: normal"> iprange: 匹配指定范围内的地址,匹配一段连续的地址而非整个网络时有用;</p> <p style="line-height: normal"> [!] –src-ragne IP[-IP]</p> <p style="line-height: normal"> [!] –dst-range</p> <pre class="brush:bash;toolbar:false">iptables -A INPUT -d 192.168.19.128 -p tcp --dport 23 -m iprange --src-range 192.168.19.129-192.168.19.135 -j ACCEPT iptables -A OUTPUT -s 192.168.19.128 -p tcp --sport 23 -m iprange --dst-range 192.168.19.129-192.168.19.135 -j ACCEPT</pre> <p></p> <p style="line-height: normal"> string: 字符串匹配,能够检测报文应用层中的字符串</p> <p style="line-height: normal"> –algo {kmp|bm}</p> <p style="line-height: normal"> –string "STRING"</p> <p style="line-height: normal"> –hex-string "HEX_STRING": HEX_STRING为编码成16进制格式的字串;</p> <p style="line-height: normal"> iptables -I OUTPUT -m string –algo bm –string "sex" -j DROP</p> <p style="line-height: normal"> time: 基于时间做访问控制</p> <p style="line-height: normal"> –datestart YYYY[-MM][-DD[Thh[:mm[:ss]]]]</p> <p style="line-height: normal"> –datestop</p> <p style="line-height: normal"> –timestart hh:mm[:ss]</p> <p style="line-height: normal"> –timestop hh:mm[:ss]</p> <p style="line-height: normal"> –weekdays day[,day]</p> <p style="line-height: normal"> iptables -I INPUT -d 192.168.19.128 -p tcp –dport 80 -m time –timestart 08:20 –timestop 18:00 –weekdays Mon,Tue,Thu,Fri -j REJECT</p> <p style="line-height: normal"> connlimit: 连接数限制,对每IP所能够发起并发连接数做限制;</p> <p style="line-height: normal"> [!] –connlimit-above [n]</p> <p style="line-height: normal"> iptables -A INPUT -d 172.16.100.7 -p tcp –dport 22 -m connlimit –connlimit-above 2 -j DROP</p> <p style="line-height: normal"> limit: 速率限制</p> <p style="line-height: normal"> –limit n[/second|/minute|/hour|/day]</p> <p style="line-height: normal"> –limit-burst n</p> <p style="line-height: normal"> iptables -A INPUT -d 192.168.19.128 -p icmp –icmp-type 8 -m limit –limit 20/minute –limit-burst 5 -j ACCEPT</p> <p style="line-height: normal"> state: 状态检查</p> <p style="line-height: normal"> –state</p> <p style="line-height: normal"> 连接追踪中的状态:</p> <p style="line-height: normal"> NEW: 新建立一个会话</p> <p style="line-height: normal"> ESTABLISHED:已建立的连接</p> <p style="line-height: normal"> RELATED: 有关联关系的连接</p> <p style="line-height: normal"> INVALID: 无法识别的连接</p> <p style="line-height: normal"> iptables -t filter -A OUTPUT -p tcp –sport 22 -m state –state NEW -j DROP </p> <p style="line-height: normal"> 放行被动模式下的FTP服务:</p> <p style="line-height: normal"> 1、装载模块/lib/modules/KERNEL_VERSION/kernel/net/netfilter/</p> <p style="line-height: normal"> 模块:nf_conntrack_ftp</p> <pre class="brush:bash;toolbar:false">modprobe nf_conntrack_ftp lsmod | grep nf_conntrack_ftp nf_conntrack_ftp 12913 0 nf_conntrack 79758 3 nf_conntrack_ftp,nf_conntrack_ipv6,xt_state</pre> <p style="line-height: normal"> 2、放行请求报文:</p> <p style="line-height: normal"> (1)放行NEW状态对21端口请求的报文;</p> <p style="line-height: normal"> iptables -A INPUT -p tcp –dport 21 -m –state NEW -j ACCEPT</p> <p style="line-height: normal"> (2) 放行ESTABLISHED以及RELATED状态的报文</p> <p style="line-height: normal"> iptables -A INPUT -m –state ESTABLISHED,RELATED -j ACCEPT</p> <p style="line-height: normal"> 3、放行响应报文:</p> <p style="line-height: normal"> (1) 放行ESTABLISHED以及RELATED状态的报文</p> <p style="line-height: normal"> iptables -A OUTPUT -m –state ESTABLISHED,RELATED -j ACCEPT</p> <p style="line-height: normal"> 由于系统对调整连接追踪功能所能容纳的连接有最大数目,视具体清空调整最大连接数目,或者不启用此功能</p> <p style="line-height: normal"> cat /proc/sys/net/nf_conntrack_max</p> <p style="line-height: normal"> 65536</p> <p style="line-height: normal"> 其中当前追踪的所有连接在/proc/net/nf_conntrack中</p> <p style="line-height: normal"> /proc/net/nf_conntrack</p> <p style="line-height: normal"> 不同协议或连接类型追踪时的属性,/proc/sys/net/netfilter目录:</p> <p style="line-height: normal"> TARGET: (-j target)</p> <p style="line-height: normal"> ACCEPT, REJECT, DROP, SNAT, DNAT, MASQERADE, RETURN, LOG, REDIRECT, MARK</p> <p style="line-height: normal"> <span class="Apple-tab-span"></span>SNAT:</p> <p style="line-height: normal"> <span class="Apple-tab-span"></span>–to-source SIP</p> <p style="line-height: normal"> <span class="Apple-tab-span"> </span>DNAT</p> <p style="line-height: normal"> <span class="Apple-tab-span"></span>–to-destination</p> <pre class="brush:bash;toolbar:false">iptables -t nat -A POSTROUTING -p tcp --dport 23210 -j SNAT --to-source 192.168.19.129 iptables -t nat -A PREROUTING -p tcp --dport 23220 -j DNAT --to-destination 192.168.19.129 iptables -A INPUT -d 192.168.19.128 -p tcp --dport 80 -j LOG --log-prefix "from iptables: "</pre> <p></p> <p><span style="font-size: 24px"><strong>四、 案例</strong></span></p> <p><strong><span style="font-size: 16px">4.1、实验拓扑图</span></strong></p> <p><img src="//cto.wang/usr/uploads/2016/07/20160703180501-37.png" title="1445761073270665.png" alt="iptables实验拓扑.png" /></p> <p><strong>4.2、配置过程</strong></p> <p><span style="font-family: 宋体;line-height: 17px">搭建环境</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">在firewall添加一块网卡,同时网络连接为自定义–VMnet3,webserver和client的网络连接也自定义在VMnet3上<br /></span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"> <img src="//cto.wang/usr/uploads/2016/07/20160703180502-89.png" title="1445761180702223.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Firewall配置ip,其中eth1网卡ip地址是自动获取的</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-41.png" title="1445761316202358.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Webserver</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-99.png" title="1445761341143008.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">添加网关</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-66.png" title="1445761378539947.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Client</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-20.png" title="1445761413266113.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">添加网关</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-73.png" title="1445761431337963.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">为了不让已有</span>iptables<span style="font-family:宋体">规则对实验产生影戏,先清空规则链</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">在所有主机上执行这些命令</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-74.png" title="1445761455635763.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">此时在</span>webserver<span style="font-family:宋体">或</span>client <span style="font-family:宋体">上无法</span>ping<span style="font-family:宋体">通外网</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-67.png" title="1445761484363442.png" alt="blob.png" /> </p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">当需要使用转发功能时,需要打开网络转发功能</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Vim /etc/sysctl.conf</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Net.ipv4.ip_forward=1</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px">Sysctl –p</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-5.png" title="1445761514381474.png" alt="blob.png" /> </p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">配置</span>SNAT</p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-94.png" title="1445761538601035.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">或者</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-10.png" title="1445761558914408.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">测试,在</span>webserver<span style="font-family:宋体">上测试</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-72.png" title="1445761576808527.png" alt="blob.png" /></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">远程主机返回应答的包到目标主机时,没有在防火墙上做地址转换,却依然能把数据包转发给</span>webserver<span style="font-family:宋体">,这是因为防火墙那台主机上维持了一张转换或的</span>IP<span style="font-family:宋体">或端口对应表,故无需人为去添加转换规则。</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">在防火墙上添加DNAT</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-37.png" title="1445765047228848.png" alt="blob.png" /></span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体">在物理机上访问</span>172.16.0.2<span style="font-family:宋体">的网站</span></p> <p class="MsoListParagraph" style="margin-left: 28px;text-indent: 0;line-height: 17px"><span style="font-family:宋体"><img src="//cto.wang/usr/uploads/2016/07/20160703180502-74-1.png" title="1445761625113329.png" alt="blob.png" /></span></p> <p><span style="font-size: 24px"><strong>五、总结</strong></span></p> <p style="text-indent: 2em">iptables可做主机防火墙和网络防火墙,做为网络防火墙时需要打开转发功能,iptables规则顺序很重要,其自上而下匹配的规则链,故需要一条一条检查规则链,故常用规则,特别是匹配次数大的放在上边,同一规则更严格的条目放在上面。</p> 最后修改:2021 年 12 月 10 日 10 : 53 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信