CentOS 6.5 iptables原理详解以及功能说明

原文链接:http://blog.51cto.com/tanxw/1389114

 

前言

   iptables其实就是Linux下的一个开源的信息过滤程序,包括地址转换和信息重定向等功能的,他由四表五链组成的,信息过滤功能十分强大,而所谓的硬件防火墙也就是一个Linux核心加页面操作程序做出来的,可以用于添加、编辑和移除规则。

 

正文

   如果我们的主机上有一块网卡、当用户请求到达时、首先会到达我们的硬件设备、而且我们应该知道、能够在硬件上接收数据并且能够做后续处理的只有内核、而内核中用于网络属性管理的是TCP/IP的协议栈、其实就是TCP/IP的模块。

   一个报文由网卡到达本主机的TCP/IP协议栈之后就要判断他的目标IP了、所以在TCP/IP协议栈有一个路由表、是由本机的路由模块实现的、如果他发现目标IP就是本机的IP地址、那就会继续检查他的目标端口、如果目标端口被本机上的某个用户进程注册使用了、那这个进程就监听在这个套接字上、所以检查到的这个端口的确是主机的某处进程在监听、那这个报文就会通过这个套接字通过用户空间转发给对应的进程了、所以这个报文就到达本机的内部去了。

   当我们的路由检查机制发现目标IP不是本机的IP地址、而后就要检查我们的路由是否允许做网络间的转发了、如果允许做向外转发、那他不会进入用户空间、直接在内核中直接交给另一块网卡(假如主机上有两块网卡)或另一个IP转发出去了、在内核中走一圈又出去了。

   什么叫内部转发:如果说我们主机上有两块网卡、或者说一块网卡有两个地址、一个地址可以接收请求、另一个地址可以把请求发出去、这就是网络间的转发机制

 

   然而我们所说的防火墙其实是由iptables和netfilter两部分组成的,iptables就是负责在netfilter上写规则的、而netfilter就是我们事先设好的卡哨、五个卡哨所组合起来叫netfilter、而iptables只是负责在卡哨上填充规则的、规则是真正检查者、卡哨是可以将你的通路都挡掉、而在内核中这些卡哨被称为勾子函数、所以规则才是真正能起来防护作用的机制、而netfilter只是让这些规则得以生效的、那对linux来讲、这些卡哨都是有名字的、每个勾子函数都有他的名字、根据这些报文的流向定义的名称、而这些名称在iptables上被称为叫链,iptables上的链有5条,这就是传说中的5个勾子函数:

   INPUT:从本机进来的
   OUTPUT:从本机出去的
   FORWARD:从本机转发的、本机内部出去了、无论如何也不会经过FORWARD

   POSTROUTING:路由之后
   PREROUTING:路由之前

 

iptables工作机制如下图:    wKiom1M7uDqDR6FKAAiP_XCuuag726.jpg

 

filter就是过滤信息的,那什么叫过滤:就是能够实现报文筛选的

NAT是什么呢:Network Address Translation 网络地址转换,在互联网上私有地址是不会被路由的、所以发报文时对方可以收到、但是无法响应你的请求、在这种情况下要想访问互联网只有做代理或用NAT,所谓在址转换就是将你请求报文中的源地址或目标地址改为我们所指定的地址这就叫地址转换:
   DNET:源地址转换
   SNET:目标地址转换

mangle:简单来讲、一个IP报文都有TTL值全称是"生存时间(Time To Live)"的、每经过一个网官IP首部都会减一的、本来你经过我这里的网官减一、但是我又加上一、像这种即不做过滤、也不做转换、而是改变了IP/TCP首部的其他信息、那这种机制就叫mangle机制。

 

raw:有限级最高,设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,提高性能。

 

规则是如何对报文进行检查的:
   要写一条规则、一定是匹配某些报文中的特征、如果这个报文的特征被这条规则的检查条件所匹配到、那就由后面的指定的处理机制进行处理了、这种处理机制有:源地址转换、目标地址转换、允许、拒绝、跳转。

其实我们做防火墙有两大策略:
通:所谓通就是做白名单、谁都不许通过、只有在名单中的可能通过。默认为堵
堵:做黑名单、谁都可以过、只是把那些在名单中的堵了。默认为通
   通和堵只对filter表有效、也只有filter表才需要做默认策略、通和堵本来就是过滤。

 

保存规则:service iptables save
   被保存到/etc/sysconfig/iptables文件中
   而start时会读取此文件中的内容经设置规则、如果我们不想让规则保存到默认文件的路径中、那我们可以指定保存的路径:
   #iptables-save > /path/to/some_rulefile
   要注意的是、当服务器启动后保存到指定文件是不会被读取的、那如果我们又想让文件生效怎么做呢、用输入重定向:
   # iptables-restore < /path/to/some_rulefile

   iptables/netfilter组合关系:
   netfilter:工作在内核空间、让规则能够生效的网络框架
   iptables:工作于用户空间、编写规则并且发送到netfilter上的

   其实iptables在Linux 2.0的时候被叫做ipfwadm,而在Linux2.2的时候通常被叫做ipchains,而到了Linux2.4及其以后的版本就叫做iptables、那至于到以后还叫不叫iptables就不得而知了。

 

iptables写规则:

   iptables [-t table] -N chain:定义一条自定义的新链
   iptables [-t table] -X [chain]:删除一条自定义空的规则链
   iptables [-t table] -E old-chain-name new-chain-name:为自定义链改名的
   iptables [-t table] -P chain target:为链指定默认策略
   iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]:清空链中的规则、如果不指定链那表中所有的链都清空了
       -F:清空链中的规则、规则有编号、在链中自上而下、从1开始 
       -L:list,列出表中的所有规则
           -n:数字格式显示IP和Port、如果不用-n、ip就会反解为主机名、端口反解成服务名、会很慢
           -v:以详细格式显示     
           -vv:更详细
           -vvv:更更详细
           -x:exactly,精确值、不执行单位换算
       --line-numbers:显示各规则的行号    
       -Z:zero,清零、把规则的计数器清零

   iptables [-t table] {-A|-D} chain rule-specification
   -A:append,附加一条规则、在规则的后面添加
   rule-specification:通常使用匹配条件 -j 处理机制

   iptables [-t table] -I chain [rulenum] rule-specification:在指定位置插入规则
   iptables [-t table] -R chain rulenum rule-specification:修改指定规则为新定义的
   iptables [-t table] -S [chain [rulenum]]:显示指定链上的规则

匹配条件:因为iptables是网络层的防火墙、他只能匹配协议、IP、TCP、UDP、ICMP、匹配条件肯定是根据底层的IP报文来检查、或都根据TCP、UDP、ICMP来检查
   这几种叫通用匹配
   -s IP:匹配源IP的、可以是IP也可以是网络地址、可以取反、用!号取么
   -d IP:匹配目标地址的、
   -p Proctol:匹配协议的[TCP|UDP|ICMP]、三者之一
   -i:数据报文流入的接口、数据包从哪个网卡进来呀、通常只用于INPUT、FORWARD、PRERUTING
   -o:数据报文流出的接口、OUTPUT、FORWARD、POSTROUTING

 

隐含扩展:当使用-p指定某一协议之后、那个协议自身所支持的扩展就叫做隐含扩展、使用[tcp|udp|icmp]指定某特定协议后、自动能对协议进行扩展。
   -p tcp、后面可以指定端口
       --dport m[-n]:目标端口、m[-n]可以使用一片连续的端口、还可以在前面用!号取反 
       --sport:源端口、这个跟上面的一样
       --tcp-flags:tcp的标志位匹配的 

   -p udp、udp只有端口
       --dport
       --sport
   -p icmp (8是ping的请求、0是ping的响应)
       --icmp-type

显式扩展:必须要明确指定的扩展模块
   -m 扩展名称 --专用选项1 --专用选项2

   multiport:多端口匹配、一次指定多个离散端口(一般不超过15个)
       --source-ports:源端口
       --destination-ports:指定目标商品端口
       --ports:指定多个端口、多个端口间用逗号隔开

   iprange:ip地址匹配范围、我们可以匹配指定的IP段
       [!] --src-range from[to]:指定源地址范围
       [!] --dst-range from[to]:指定目标地址范围

   time:指定时间范围
       --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定开始日期                               --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定结束日期
       --timestart hh:mm[:ss]:指定开始时间不指定日期
       --timestop hh:mm[:ss]:只指定结束时间不指定日期
       [!] --weekdays day[,day...]:指定周几的、"!"号取反

   string:对字符串的匹配的、包含有指定的字符串时做相应的处理
   --algo {bm|kmp}:英文中的字符比较高效的比较
   --string "string":要查找的字符串
   --hex-string

   connlimit:每IP对指定服务器的
       [!] --connlimit-above [n]

   limit:报文速率控制
       --limit[/second|/minute|/hour|/day]每秒、每分、每小时、每天
       --limit-burst #:一批最多个数、峰值

 

state:状态匹配

       --state:仅放行哪些连接的状态、也可以做状态连接追踪的。

   什么是状态连接追踪呢:

   就是对ip_conntrack,nf_conntrack做连接追踪的、简单来讲就是我们主机中的netfilter会在内核中建立一张表、对进出本主机的连接或会话进行记录、把访问本主机的信息记录下来、如果这张表中只能容纳1000条记录、而连接追踪数已经大于1000条、那1000条以上的连接就会被拒绝、虽然我们知道这些连接的相关状态和相关详细信息、但他内部默认的空间大小是有限的、而且很小、容易在一个非常繁忙的服务器上打满、那后续的连接将会被屏蔽、被拒绝、那很明显我们服务器将拒绝提供服务、所以不到万不得已时不要使用连接追踪的功能、启用时也要调空间的大小。

   只说命令请求的本身
   NEW:进来的请求为new
   ESTABLISHED:已建立的会话连接、响应和后续命令的发送都是established
   RELATED:相关联的、一旦启用一个数据连接、这个数据连接和命令连接就叫related
   INVALID:所有无法识别的连接都叫invalid

   iptables是能够实现状态检测机制的防火墙、使得其非常安全的、那状态检测机制通常依赖于state模块来实现、这个模块基于ip_conntrack、nf_conntrack在自己内存中维护一个会话表、能够追踪每一个连接请求、这种追踪会在内存中记录一个条目、每个条目都有一个倒记时的记时器、当记时器为零就会被清出去、但当为零之前一直在访问将重新被刷新、那么任何一个请求在连接前都会去查这张表netfilter、如果表中有这个条目、就叫做ESTABLISHED、如果没有这个条目就叫做NEW、如果说有条目、但这个条目跟本身连接没有关系、跟本身连接的别外一个连接有关系就叫做RELATED、无法识别的连接都叫做INVALID、像什么六个标志位都为1或都为零。

法则:
   1、对于进入状态为ESTABLISHED都应该放行
   2、对于出去的状态为ESTABLISHED都应该放行
   3、严格检查进入的状态为NEW的连接
   4、所有状态为INVALIED都应该拒绝

 

规则编写示例:
   1、所有来自172.16.0.0/16这个网段的地址经过172.16.100.7这个主机都允许、-A追加一条规则、在INPUT这条链上添加:    
 
1
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -j ACCEPT
 
   2、所有本机地址出去的、访问172.16.0.0/16的其实任意主机都允许:    
 
1
# iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -j ACCEPT
 
   3、显示所有规则条目的编号:  
 
1
# iptables -t filter -L -n --line-numbers
 
   4、清空表中所有链的规则、和查看iptables中的规则:    
 
1
2
# iptables -F
# iptables -L -n -v
 
   5、清空表中某条链的规则:    
 
1
# iptables -F -t filter
 
   6、给本机网卡添加一个ip地址:    
 
1
# ifconfig eth0:0 192.168.1.188
 
   7、只允许通过eth0这个接口进本机来    
 
1
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -j ACCEPT
 
   8、出去时只允许通过eth0这个网卡出去    
 
1
# iptables -t filter -A OUTPUT -o eth0 -s 172.16.251.171 -j ACCEPT
 
   9、限定协议的、通过eth0接口进来、并且协议是TCP的都允许:    
 
1
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p tcp -j ACCEPT
 
   10、清空规则后、通过eth0进来的、并且协议是ICMP的都拒绝
 
1
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p icmp -j REJECT
 
   11、限制每IP最多的请求个数、大于3个就drop    
 
1
# iptables -I INPUT  -d 172.16.251.171 -p tcp --dport 80 -m connlimit --connlimit-above 3 -j DROP
 
   12、放行ping其他主机:    
 
1
2
# iptables -A OUTPUT -s 172.16.251.171 -p icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p icmp --icmp-ytpe 0 -j ACCEPT
 
   13、对目标主机172.16.251.171的端口只在周1、2、3、4、5的8点到18点时间放行:    
 
1
2
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 timestop 18:00:00 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p tcp --sport 901 -j ACCEPT
 
   14、对目标主机172.16.251.244的端口放行已建立连接的和新建连接的:    
 
1
2
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 timestop 18:00:00 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p tcp --sport 901 -j ACCEPT
 
   15、在OUTPUT上只要是established的都放行    
 
1
# iptables -A OUTPUT -s 172.16.251.244 -m state --state ESTABLISHED -j ACCEPT
 
 
   16、自定义链、清除所有TCP标志位为全0的或全1的请求、和清除172.16的广播:    
 
1
2
3
4
5
6
7
# iptables -t filter -N clean_in
# iptables -A clean_in -d 172.16.251.244 -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -d 172.16.251.244 -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -d 172.16.251.244 -j RETURN 自定义链中返回链
# iptables -I INPUT -d 172.16.251.244 -j clean_in 在INPUT链上调用链
 
   17、在INPUT上开放22和80端口的访问规则:    
 
1
2
# iptables -I INPUT -d 172.16.251.171 -p tcp -m multiport --dports 22,80 -j ACCEPT
# iptables -I OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p tcp -m multiport --sports 22,80 -j ACCEPT
 
   18、开放本机23号端口给某个网段的主机访问:    
 
1
2
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 23 -m iprange --src-range 172.16.100.1-172.17.100.100 -j ACCEPT
# iptables -A INPUT -s 172.16.251.171 -p tcp --sport 23 -m iprange --dst-range 172.16.100.1-172.17.100.100 -j ACCEPT
 
   19、放行来自于172.16.0.0/16网络的主机对本机ssh服务的请求:    
 
1
2
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 22 -j ACCEPT
# iptables -t filter -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT
 
   20、放行172.16.0.0/16这个网段内80端口的访问    
 
1
2
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 80 -j ACCEPT
# iptables -t filter -A OUTPUT -s 172.16.251.171 -d 171.16.0.0/16 -p tcp --sport 80 -j ACCEPT
 
   21、从本机到本机的通信:    
 
1
2
# iptables -t filter -A INPUT -i lo -j ACCEPT
# iptables -t filter -A OUTPUT -o lo -j ACCEPT
 
   22、tcp的标志位全为1的错误报文:    
 
1
2
3
# iptables -N mychain
# iptables -A mychain -p --tcp-flags ALL ALL -j DROP  这个表示所有标志位全为1
# iptables -A mychain -p --tcp-flags ALL NONE -j DROP 标志位全为0
 
   23、放行本机的DNS服务、当本机不可以解析时要出去查询、如果本机服务可以解析就是上面两条、如果本机解析不了就会出去找、就用后面两条:    
 
1
2
3
4
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p udp --dport 53 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p udp --dport 53 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p udp --dport 53 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p udp --sport 53 -j ACCEPT
 
   24、放行本机的tfpt服务    
 
1
2
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p udp --dport 69 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p udp --sport 69 -j ACCEPT
 
   25、放行ping其他主机:    
 
1
2
# iptables -A OUTPUT -s 172.16.251.171 -p icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p icmp --icmp-ytpe 0 -j ACCEPT
 
   26、删除INPUT链上的第三条规则    
 
1
# iptables -D INPUT 3
 
   27插入为第一行:    
 
1
2
# iptables -I INPUT -i lo -j ACCEPT 默认插入为第一行
# iptables -I INPUT 2 -i lo -j ACCEPT 插入为第二行
 
   27、修改第一条规则:    
 
1
# iptables -t filter -R INPUT 1 -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 22 -i eth0 -j ACCEPT
 
 
结束:
   整理了很久才整理完、这个iptables的确是个大话题、好像到哪都能用得上、不管是面试还是工作中、基本上都离不开iptables、也不管是硬件防火墙还是这种软件防火墙、都是到处可见、然而、在完全弄懂这个软件防火墙的前提下、硬件防火墙绝对不在话下、玩转iptables对我们的工作大大的加分、也是一个高大上的技术哦。

 

原文地址:https://www.cnblogs.com/yizhipanghu/p/9857547.html