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:路由之前
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
|
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -j ACCEPT
|
1
|
# iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -j ACCEPT
|
1
|
# iptables -t filter -L -n --line-numbers
|
1
2
|
# iptables -F
# iptables -L -n -v
|
1
|
# iptables -F -t filter
|
1
|
# ifconfig eth0:0 192.168.1.188
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -j ACCEPT
|
1
|
# iptables -t filter -A OUTPUT -o eth0 -s 172.16.251.171 -j ACCEPT
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p tcp -j ACCEPT
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p icmp -j REJECT
|
1
|
# iptables -I INPUT -d 172.16.251.171 -p tcp --dport 80 -m connlimit --connlimit-above 3 -j DROP
|
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
|
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
|
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
|
1
|
# iptables -A OUTPUT -s 172.16.251.244 -m state --state ESTABLISHED -j ACCEPT
|
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链上调用链
|
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
|
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
|
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
|
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
|
1
2
|
# iptables -t filter -A INPUT -i lo -j ACCEPT
# iptables -t filter -A OUTPUT -o lo -j ACCEPT
|
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
|
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
|
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
|
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
|
1
|
# iptables -D INPUT 3
|
1
2
|
# iptables -I INPUT -i lo -j ACCEPT 默认插入为第一行
# iptables -I INPUT 2 -i lo -j ACCEPT 插入为第二行
|
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
|