这篇博客的主要内容是介绍防火墙netfilter,在linux操作系统上,这是第三代防火墙。前两代是
ipfwadm和ipchains,netfilter的功能非常强大,它的地位绝不亚于其他收费系列的防火墙软件。
首先,补充自己的知识,人们常说的iptables,并不是防火墙,其实真正的防火墙是netfilter,
是编译进内核的模块,而iptables只是为了方便用户去写规则的工具,iptables写好的规则,被netfilter
读取之后立即生效。
iptables包含5个链,4个表,每个链都包含表,具体情况看下图
4张表:
filter:filter是netfilter最重要的机制,其任务是执行数据包的过滤操作,也起到了防火墙作用
nat:nat也是防火墙不可或缺的机制,现在用的比较多的就是为了地址转换
mangle:mangle是一种特殊的机制,可以修改经过防火墙内的数据包
raw:负责加快数据包穿过防火墙的速度,提升防火墙的性能
5条链:
INPUT:指的是“网络上其他主机发送给本机进程的数据包”
OUTPUT:如果是“由本机进程”所流出的数据包,即为OUTPUT类型的包
FROWARD:如果数据包对本机而言只是路过,本机只是起到转发的作用,即转发
PREROUTING:发生在前半段路由决策之前,一般用于DNAT转换
POSTROUTING:发生在后半段的路由决策之后,一般用于SNAT转换
那么,iptables是如何工作的呢,先看下面的流程图
首先,客户端的请求的报文会到达PREROUTING这个链,这个链在DNAT的时候应用的多
然后,报文会到达路由选择,根据报文的信息判断,报文送到本机还是进行转发
转发:报文会通过FORWARD这条链
送达本机:报文先会经过INPUT这个链,规则会对报文进行处理
通过本机内部,到达本机的进程进行处理,处理后输出
报文流出时,经过OUTPUT链,会被这条链的规则匹配
之后,报文到达报文流出的路由选择,也有规则匹配,或是规定从哪个网卡流出
iptables的命令主要分为两个部分:
iptables的命令参数
iptables的规则语法
这里,我们主要介绍的filter表
iptables的基本语法
iptables [-t TABLE] COMMAND CHAIN CRETIRIA -j TARGET
-t TABLE:
这里的TABLE主要指的就是上面的4个链,默认为filter
COMMAND:
主要是对链的操作:
-F:清空规则链,如果不指定的话,默认全部清空
实例:[[email protected] ~]# iptables -t filter -F
默认情况下为filter表,可以不加-t filter
-N:用于自己新建一条新的规则链
实例:[[email protected] ~]# iptables -t filter -N ssh_in
新建一个自定义的链,链名为ssh_in
-X:删除规则链,只对自定义规则链有效
实例:[[email protected] ~]# iptables -t filter -X ssh_in
删除上面新建的自定义的链
-Z:计数器归零
一般查看计数:iptables -L -n -v -x
计数主要分为pkts和bytes
表示,已经匹配到的包数和字节数
实例:[[email protected] ~]# iptables -L -n -v -x
Chain INPUT (policy ACCEPT 239 packets, 19921 bytes)
pkts bytes target prot opt in out source destination
我们先用iptables -L 进行查看,我们可以看到在INPUT链上,接收的包为239个,
字节数为19921字节
[[email protected] ~]# iptables -Z
[[email protected] ~]# iptables -L -n -v -x
Chain INPUT (policy ACCEPT 5 packets, 356 bytes)
pkts bytes target prot opt in out source destination
对filter链进行计数器清零,再次查看,包数减少,因为ssh的连接上,仍有包传输
-P:设定默认的策略,对于filter表,默认为ACCEPT和DROP两种
实例:将默认策略改为DROP,但是,之前,要放行ssh的连接
[[email protected] ~]# iptables -A INPUT -p tcp –dport 22 -j ACCEPT
[[email protected] ~]# iptables -A OUTPUT -p tcp –sport 22 -j ACCEPT
[[email protected] ~]# iptables -P INPUT DROP
[[email protected] ~]# iptables -P OUTPUT DROP
[[email protected] ~]# iptables -L -n -v -x
Chain INPUT (policy DROP 23 packets, 1906 bytes)
可以看出INPUT链上,DROP规则有数据,原因是局域网内的广播包
-E:将自定义的规则链重命名
实例:新创建一条自定义链httpd_in,然后重命名为web_in
[[email protected] ~]# iptables -N httpd_in
[[email protected] ~]# iptables -E httpd_in web_in
针对链中的规则
-A:添加一条心的规则,一般情况下,是最后生效的
实例:流经INPUT和OUTPUT的链的数据放行
[[email protected] ~]# iptables -A INPUT -j ACCEPT
[[email protected] ~]# iptables -A OUTPUT -j ACCEPT
其实,这就相当于默认规则为ACCEPT
-I:插入一条新的规则,默认情况下,会被插到最前面
实例:插入一条让web通行的,查到第二条规则
[[email protected] ~]# iptables -I INPUT 2 -p tcp –dport 80 -j ACCEPT
[[email protected] ~]# iptables -I OUTPUT 2 -p tcp –sport 80 -j ACCEPT
上面没有提到的,后面将会解释
我们可以使用:iptables -L -n –line-numbers
可以看出每条规则所对应的序号
-D:删除规则链
实例:删除上面的INPUT链上,匹配到web服务的规则
[[email protected] ~]# iptables -D INPUT 2
-R:替换,将新的规则与旧的规则进行替换,要指定哪条链
实例:将上面提到的OUTPUT链上,匹配到web的规则改为允许任意服务都匹配
[[email protected] ~]# iptables -R OUTPUT 2 -p tcp -j ACCEPT
查询已经设定的规则:
-L:list,列出已经设定的规则
-n:以数字的形式显示主机和端口号,可以避免反解
-v:详细的格式显示规则,还有-vv,-vvv
–line-numbers:上面用过了,显示序号
-x:不对计数器的结果做单位换算,从而可以显示精确值
匹配条件:
通用匹配:
-s 地址:指定报文的源地址,地址可以为ip,网络地址
可以用:–src ,–source
实例:从211.70.160.0/24这个网络来访问我们web服务的主机都放行
[[email protected] ~]# iptables -A INPUT -s 211.70.160.0/24 -p tcp –dport 80 -j ACCEPT
-d 地地:指定报文的目标地址,也可以是ip和网络地址
可以用:–dst ,–destination
实例:从211.70.160.0/24这个网络来访问我们web服务的主机都放行
[[email protected] ~]# iptables -A OUTPUT -d 211.70.160.0/24 -p tcp –sport 80 -j ACCEPT
-p 协议:指定报文匹配的协议,有tcp,udp,icmp
icmp协议:
–icmp-type:指定icmp协议的匹配类型
0:回显响应,ping的响应报文
8:回显请求,ping的请求报文
实例:不允许任何主机ping我们的web服务器
[[email protected] ~]# iptables -A INPUT -p icmp –icmp-type 8 -j DROP
-i 接口:指定数据报文流入的接口
-o 接口:指定数据报文流出的接口
实例:假设,数据包进入的方向为eth0,出去的方向为eth1,且访问web服务都放行
[[email protected] ~]# iptables -A INPUT -i eth0 -p tcp –dport 80 -j ACCEPT
[[email protected] ~]# iptables -A OUTPUT -o eth1 -p tcp –sport 80 -j ACCEPT
扩展匹配:只有在通用匹配是指定了协议时,才可以使用扩展匹配
-p [tcp|udp]:
–sport PORT[-PORT]:指定源端口
–dport PORT[-PORT]:指定目标端口
–tcp-flags:指定tcp的标志位,udp没有
tcp的标志位有:SYN,ACK,FIN,RST
实例:这里主要介绍–tcp-flags,如果tcp的报文不正常,标志位都为1时,不放行
[[email protected] ~]# iptables -A INPUT -p tcp –tcp-flags all all -j DROP
第一个all是检查所有标志位,第二个all是指都为1的标志位
实例:iptables -A INPUT -p tcp –tcp-flags all syn
指的是匹配所有的标志位,而且syn必须为1,也可以使用–syn
all表示所有位,none则表示不匹配
显示扩展:其必须要指明使用的是哪个模块进行扩展的,之后才有使用扩展选项
-m state –state
multiport:支持多端口匹配
可用于连续的或者是非连续的端口,一次最多指定15个端口
专用选项:
–source-ports,–sports port[,port,port:port]
逗号表示离散的,分号表示连续的
–distination-ports,–dports
–ports
实例:清除上面的规则后,将请求ssh和web服务的放行,前提是,更改默认规则为ACCEPT
[[email protected] ~]# iptables -A INPUT -p tcp -m multiport –dports 22,80 -j ACCEPT
[[email protected] ~]# iptables -A OUTPUT -p tcp -m multiport –sports 22,80 -j ACCEPT
iprange:匹配指定范围内地址
匹配一段连续的地址,而不是整个网络
专用选项:
–src-range IP[-IP]
–dst-range IP[-IP]
string:字符串匹配,能够检测报文应用层中的字符串
匹配时,一定要指定其匹配的算法:kmp,bm
专用选项:
–algo {kmp|bm}:任选其中的一种算法
–string "STRING" :指定匹配的字符串
–hex-string "HEX_STRING":HEX_STRING:编码为16进制的字符串
实例:过滤网页中出现qq的字眼
[[email protected] ~]# iptables -A INPUT -p tcp –dport 80 -m string –algo bm –string "qq" -j DROP
time:基于时间做访问控制:
专用选项:
–datestart YYYY[-MM][-DD[Thh[:mm[::ss]]]]
–datestop YYYY[-MM][-DD[Thh[:mm[::ss]]]]
上面两项匹配的是日期时间
–timestart hh:mm:[:ss]
–timestop hh:mm[:ss]
这两项指的是小时分钟上的时间
–weekdays Mon,Tue,Wed,Thu,Fri,Sat,Sun
匹配的是星期几
实例:规则网内的主机,在早上8:00到17:00不能上网,且是上班期间
[[email protected] ~]# iptables -I INPUT -p tcp –dport 80 -m time –timestart 08:00
–timestop 15:00 ! –weekdays Sat,Sun -j DROP
上面用到!表示取反,即上班时间
connlimit:连接数目上的限制,对每个IP所能发起的并发数进行限制
专用选项:
–connlimit-above N
实例:当单个ip的连接数目达到5个是,不允通行
[[email protected] ~]# iptables -A INPUT -m connlimit –connlimit-above 5 -j DROP
规则中的意思是,大于等于5个的时候允许通行,其他情况就被默认规则匹配
limit:对于数据传输速率的限制
专用选项:
–limit n[/second |/minute | /hour | /day]
–limit-burst n:这是一个容器,对于之前没有发起请求的客户端,
第一次可以发起的请求数
实例:假设,对第一次发起请求的客户端,速率为5/second,一般的客户端3/second
[[email protected] ~]# iptables -A INPUT -m limit –limit 3 –limit-burst 5 -j DROP
大于这个数的被DROP掉了,没达到的被默认规则匹配
state:状态检查,这是iptables防火墙的特色所在
专用选项:
–state
追踪的状态的:
NEW:新建一个会话
ESTABLISHED:已经建立的连接
RELATED:有关联的关系连接,对于ftp这种服务特别适用
INVALID:无法识别的连接
适用nat或是state时,都会使用到iptables的连接追踪功能,这对于请求量比较大的服务器上
最好关闭,连接追踪,否则会造成大量的用户请求失败,万一出现这种情况,
马上卸载追踪的模块:modprobe nf_conntrack
调整连接追踪功能所容纳的最大的连接数目
/proc/sys/net/nf_conntrack_max
当前追踪的所有连接
/proc/net/nf_conntrack
不同的协议或是连接类型追踪时的属性
/proc/sys/net/netfilter目录下
实例:放行被动模式下的ftp服务
在对我们的ssh连接的基础上,把默认规则设为DROP
首先,我们在主机上安装vsftpd的ftp软件:
[[email protected] ~]# yum install -y vsftpd
装载支持ftp的追踪模块:
modprobe nf_conntrack_ftp
放行请求的报文:
对于NEW状态的21号端口请求放行:
[[email protected] ~]# iptables -I INPUT -p tcp –dport 21 -m state –state NEW -j ACCEPT
对于已经建立NEW状态的ftp服务放行
[[email protected] ~]# iptables -A INPUT -p tcp -m state –state ESTABLISHED,RELATED -j ACCEPT
对于响应报文进行放行:
[[email protected]t ~]# iptables -I OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
对于不同的服务,可以将同一个服务创建一个自定义链
自定义的链,默认情况是不生效的,只有调用时才会生效
创建自定义的链
iptables [-t TABLE] -N chain
实例:为httpd服务添加进入
[[email protected] ~]# iptables -t filter -N httpd_in
[[email protected] ~]# iptables -A httpd_in -p tcp –dport 80
-m iprange –src-range 211.70.160.10-211.70.160.30
[[email protected] ~]# iptables -A httpd_in -p tcp –dport 80
-m state –state NEW -j ACCEPT
状态为NEW的报文被接受,ESTABLISHED状态的报文被主链的匹配
[[email protected] ~]# iptables -A INPUT -m state –state ESTABLISHED -j ACCEPT
这样的话,规则,就被优化了,不需要逐条定义,只需要定义一条httpd服务的自定义链
然后,在INPUT和OUTPUT上允许ESTABLISHED状态通行
调用自定义的链
[[email protected] ~]# iptables -A INPUT -p tcp –dport 80 -j httpd_in
Chain httpd_in (1 references)一次调用
自定义链的TARGET
RETURN:自定义的链没有匹配到任何报文时,将返回其主链
当规则不匹配时,跳回主链
[[email protected] ~]# iptabels -A httpd_in -j RETURN
删除自定义链,且引用数为0
iptables [-t TABLE] -X chain
删除被主链调用的关系
[[email protected] ~]# iptabels -D INPUT 4
清空自定义链的规则
[[email protected] ~]# iptables -F httpd_in
然后删除httpd_in的自定义链
[[email protected] ~]# iptables -X httpd_in
重命名自定义的链
iptables [-t TABLE] -E old_chain new_chain
[[email protected] ~]# iptables -E httpd_in web_
防火墙的应用是:主机防火墙+网络防火墙
处理目标:
内置目标:
DROP #丢弃报文,不返回任何信息,建议使用
REJECT #丢弃报文,并返回一定的信息
ACCEPT #接受报文
自定义的链:
RETURN #退出自定义链,返回主链
写规则时的主要事项:
对服务端而言:报文是先进后出的
对客户端而言:报文是先出后进的
客户端的端口是随机的,一般不需要限定
优化规则:
尽量减少规则的条目,彼此不想管的匹配机会较多的放在上面
对于同一匹配规则,更严格的放在最上面
保存规则链:
iptables-save > /path/file_name #保存至指定位置
service iptables save #保存至/etc/sysconfig/iptables-config
总结:防火墙对于一个服务器的安全非常重要,好的规则,有着非常高的匹配效率,也能达到预定的期望,对于这些,我们还是要多记多练