简要介绍Linux防火墙及iptables的常见用法
简介
防火墙主要用于屏蔽来自于互联网,或来自于企业内部的用户的攻击操作及防范非授权的访问的。一般工作于网络或主机的边缘,对于进出本网络或主机的报文根据事先定义的检查规则做匹配检测,对于被规则匹配到的报文做出相应处理,时刻检查出入防火墙的所有数据包,决定拦截或是放行哪些数据包。
根据设备来划分通常可分为硬件防火墙和软件防火墙:
- 硬件防火墙:专门的一台防火墙硬件设备,工作在整个网络入口处
- 软件防火墙:工作在主机中TCP/IP协议站上面的软件(工作在内核中)
根据防火墙工作位置又可分为网络防火墙和主机防火墙:
- 网络防火墙:工作与一个网络的边缘,能够实现对进出本网络的所有主机报文加以防护
- 主机防火墙:主要是用来防范单台主机的进出报文
iptables/netfilter
Linux上的防火墙套件为iptables/netfilter
,iptables是用户空间上配置与修改过滤规则的命令,生成的规则直接送往linux内核空间netfilter中,netfilter是Linux核心中的一个通用架构,用于接收并生效规则,起到防火墙作用,二者关系如下:
在netfilter上定义了5个钩子函数(hook function),分别作用于5个链上:
- 路由前,目标地址转换 == > PREROUTING
- 到达本机内部的报文必经之路 == > INPUT
- 由本机转发的报文必经之路 == > FORWARD
- 由本机发出的报文的必经之路 == > OUTPUT
- 路由后,源地址转换 == > POSTROUTING
netfilter提供了一系列的表(tables),每个表由若干个链(chains)组成,而每条链可以由一条或若干条规则(rules)组成,关系如下:
4表
raw
:用于配置数据包,raw 中的数据包不会被系统跟踪mangle
:用于对特定数据包的修改nat
:用于网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECTfilter
:过滤,定义是否允许通过防火墙
5链
INPUT
链:当接收到防火墙本机地址的数据包(入站)时,应用此链中的规则OUTPUT
链:当防火墙本机向外发送数据包(出站)时,应用此链中的规则FORWARD
链:当接收到需要通过防火墙发送给其他地址的数据包(转发)时,应用此链中的规则PREROUTING
链:在对数据包作路由选择之前,应用此链中的规则POSTROUTING
链:在对数据包作路由选择之后,应用此链中的规则
规则(处理机制)
ACCEPT
:允许数据包通过DROP
:直接丢弃数据包,不给任何回应信息REJECT
:拒绝数据包通过,同时会给数据发送端一个响应的信息SNAT
:源地址转换,解决内网用户用同一个公网地址上网的问题,仅作用于nat表上POSTROUTING,INPUT上。在进入路由层面的route之前,重新改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机MASQUERADE
:是SNAT的一种特殊形式,适用于像adsl这种临时会变的ip上DNAT
:目标地址转换,让互联网上主机访问本地内网上的某服务器上的服务,仅作用于nat表上PREROUTING和OUTPUT。和SNAT相反,IP包经过route之后、出本地的网络栈之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机,可以隐藏后端服务器的真实地址REDIRECT
:是DNAT的一种特殊形式,将网络包转发到本地host上(不管IP头部指定的目标地址是啥),方便在本机做端口转发LOG
:仅记录日志信息,然后将数据包传递给下一条规则RETURN
:一般用于自定义链上,自定义链被内置链引用时,当没有规则被匹配时,返回内置链的下一条规则
数据流向
与本机内部进程通信:
进入:–> PREROUTING –> INPUT
出去:–> OUTPUT –> POSTROUTING由本机转发:
请求:–>PREROUTING–>FORWARD–>POSTROUTING
响应:–>PREROUTING–>FORWARD–>POSTROUTING
数据流向及相应的表链关系图如下:
iptables命令用法
语法
iptables [-t table] COMMAND chain [num] [-m match [match-options]] [-j target [target-options]]
常用选项
链管理
-F
:flush, 清空规则链,无法还原-N
:new, 新建一条自定义链,被内建链上规则调用才能生效-X
:delete, 删除引用计数为0的自定义空链-P
:policy,设置默认策略,对filter表来讲,默认规则为ACCEPT或DROP-E
:重命名引用计数为0的自定义链-Z
:zero,计数器归零
规则管理-A
:Append,在尾后追加-I
:Insert,在指定位插入规则,省略位置则为链首-D
:Delete,删除指定规则-R
:Replace,将指定规则替换为新规则
显示-L
:list,列出表中的链上的规则;
-n
:numeric,以数值格式显示;-v
:verbose,显示详细格式信息,更详细-vv
,-vvv
-x
:exactly,计数器的精确结果;--line-numbers
:显示链中的规则编号
1 | iptables -vnL # 默认显示filter表规则,可指定表显示 |
匹配条件
通用匹配
[!] -s ADDR[/mask]
:指定报文源IP地址匹配的范围,可以是IP和网络地址,!
表示取反[!] -d ADDR[/mask]
:指定报文目标IP地址匹配的范围[!] -p PROTOCOL
:指定匹配报文的协议类型,一般有三种tcp, udp和icmp[!] -i INTERFACE
:数据报文流入的接口;只适用于PREROUTING, INPUT, FORWARD[!] -o INTERFACE
:数据报文流出的接口;只适用于OUTPUT, FORWARD, POSTROUITING
扩展匹配
-p tcp
--sport PORT[:PORT]
: tcp 指定源端口,可以是连续多个端口--dport PORT[:PORT]
: tcp 指定目标端口--tcp-flags
: tcp标示位,包括SYN,ACK,FIN,RST,URG,PSH,分2段,表示在左段的标示位中,只有右段中的为1
1 | # 不指定表默认为filter过滤 |
-p udp
--sport PORT[:PORT]
:udp 源端口,可连续--dport PORT[:PORT]
:udp 目标端口
1 | # 放行本机dns,本机172.16.60.1 |
-p icmp
--icmp-type 8
:echo-request,请求--icmp-type 0
:echo-reply,响应
1 | # 放行ping其它主机 |
-m multiport
多端口匹配,可用于匹配非连续(,)或连续端口(:),需指明相应tcp或udp协议
[!] --sports PORT[,PORT...]
[!] --dports PORT[,PORT...]
[!] --ports PORT[,PORT...]
1 | # 开放本机21,22,23,80端口 |
-m iprange
匹配指定范围内的地址,匹配一段连续的地址而非整个网络时有用
[!] --src-range FROM_IP[-TO_IP]
[!] --dst-range FROM_IP[-TO_IP]
1 | iptables -A INPUT -d 172.16.60.1 -p tcp --dport 23 -m iprange --src-range 172.16.60.1-172.16.60.100 -j ACCEPT |
-m string
字符串匹配,能够检测报文应用层中的字符串
[!] --string PATTERN
: 指定字符串[!] --hex-string "HEX_STRING"
: HEX_STRING为编码成16进制格式的字串
--algo {kmp|bm}
: 指定算法
iptables -I OUTPUT -m string –algo kmp –string “sex” -j DROP
-m time
基于时间做访问控制
--datestart YYYY[-MM][-DD[Thh[:mm[:ss]]]]
:开始日期--datestop YYYY[-MM][-DD[Thh[:mm[:ss]]]]
:结束日期--timestart hh:mm[:ss]
:开始时间--timestop hh:mm[:ss]
:[!]--monthdays day[,day...]
:指定日期[!]--weekdays day[,day]|1-7
:指定星期,可用Mon,Tue…或 Mo,Tu…或 1-7
1 | iptables -A INPUT -d 172.16.60.1 -p tcp --dport 90 -m time --timestart 08:20 --timestop 18:40 --weekdays Mon,Tue,Thu,Fri -j ACCEPT |
-m connlimit
连接数限制,对每IP所能够发起并发连接数做限制
--connlimit-upto N
:小于等于N--connlimit-above N
:大于等于
1 | iptables -A INPUT -d 172.16.60.1 -p tcp --dport 80 -m connlimit --connlimit-above 5 -j DROP |
-m limit
传输速率限制
[!] --limit n[/second|/minute|/hour|/day]
: 限制每秒,分,小时,天n个[!] --limit-burst N
: 峰值限制
1 | iptables -A INPUT -d 172.16.60.1 -p icmp --icmp-type 8 -m limit --limit 20/second --limit-burst 5 -j ACCEPT |
-m state
状态匹配,状态包括NEW
(新建连接), ESTABLISHED
(已建立的连接), RELATED
(有关联关系), INVALID
(无法识别),UNTRACKED
(未追踪)
[!] --state STATE
1 | iptables -I INPUT -d 172.16.60.1 -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT |
注:开启状态追踪机制必须加载nf_conntrack
模块,特定服务还需加载相应模块,如ftp需加载nf_conntrack_ftp
状态追踪编写法则:
- 所有进入或出去状态为
ESTABLISHED
都应该放行 - 严格检查进入状态为
NEW
的连接 - 所有状态有
INVALIED
都应该拒绝
相关文件
- /proc/sys/net/nf_conntrack_max:连接追踪功能所能容纳的连接的最大数目,建议调大
- /proc/net/nf_conntrack:记录当前追踪的所有连接
- /proc/sys/net/netfilter/*:不同协议或连接类型追踪时的属性
自定义链
iptables中的自定义链只能被内置引用使用,可用于自定义一系列针对性的规则方便被不同的内置链所引用,同时建议在最后添加一条RETURN规则,已便未匹配到时返回主链继续匹配。删除自定义链需清空引用,同时清空链中的规则
1 | # 自定义一条放行ping请求的链 |
NAT
网络地址转换,包括SNAT,DNAT,MASQUERADESNAT
:源地址转换,用于内网主机访问互联网,作用于nat表上POSTROUTING,INPUTDNAT
:目标地址转换,让互联网上主机访问本地内网上的某服务器上的服务,作用于nat表上PREROUTING和OUTPUT
-j SNAT --to-source SIP
:源地址转换-j DNAT --to-destination DIP[:PORT]
:目标地址转换,支持端口映射-j MASQUERADE
:动态获取,仅用于nat表的POSTROUTING
1 | # 本地内网172.16网段主机访问互联网时,将源地址转换在本公司的公网8.9.9.9上 |
保存和重载规则
使用iptables命令生成的规则在重启后将失效,所以可将规则保存至文件,重启时从文件中读取
1 | iptables-save > /PATH/TO/SOME_RULE_FILE # 将编写的规则保存到指定文件中 |
规则优化
- 可安全放行所有入站及出站,且状态为ESTABLISHED的连接
- 服务于同一类功能的规则,匹配条件严格的放前面,宽松放后面
- 服务于不同类功能的规则,匹配报文可能性较大扩前面,较小放后面
- 设置默认策略:
(a) 最后一条规则设定
(b) 默认策略设定