【操作系统之十三】Netfilter与iptables
一、Netfilter
Netfilter是由Rusty Russell提出的Linux 2.4内核防火墙框架,该框架既简洁又灵活,可实现安全策略应用中的许多功能,如数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换(Network Address Translation,NAT),以及基于用户及媒体访问控制(Media Access Control,MAC)地址的过滤和基于状态的过滤、包速率限制等。
1、关键技术
Netfilter主要采用连线跟踪(Connection Tracking)、包过滤(Packet Filtering)、地址转换、包处理(Packet Mangling)4种关键技术。
(1)连线跟踪
连线跟踪是包过滤、地址转换的基础,它作为一个独立的模块运行。采用连线跟踪技术在协议栈低层截取数据包,将当前数据包及其状态信息与历史数据包及其状态信息进行比较,从而得到当前数据包的控制信息,根据这些信息决定对网络数据包的操作,达到保护网络的目的。
当下层网络接收到初始化连接同步(Synchronize,SYN)包,将被netfilter规则库检查。该数据包将在规则链中依次序进行比较。如果该包应被丢弃,发送一个复位(Reset,RST)包到远端主机,否则连接接收。这次连接的信息将被保存在连线跟踪信息表中,并表明该数据包所应有的状态。这个连线跟踪信息表位于内核模式下,其后的网络包就将与此连线跟踪信息表中的内容进行比较,根据信息表中的信息来决定该数据包的操作。因为数据包首先是与连线跟踪信息表进行比较,只有SYN包才与规则库进行比较,数据包与连线跟踪信息表的比较都是在内核模式下进行的,所以速度很快。
(2)包过滤
包过滤检查通过的每个数据包的头部,然后决定如何处置它们,可以选择丢弃,让包通过,或者更复杂的操作。
(3)地址转换
网络地址转换 分为源NAT(Source NAT,SNAT)和目的NAT(Destination NAT,DNAT)2种不同的类型。SNAT是指修改数据包的源地址(改变连接的源IP)。SNAT会在数据包送出之前的最后一刻做好转换工作。地址伪装(Masquerading)是SNAT的一种特殊形式。DNAT 是指修改数据包的目标地址(改变连接的目的IP)。DNAT 总是在数据包进入以后立即完成转换。端口转发、负载均衡和透明代理都属于DNAT。
(4)包处理
利用包处理可以设置或改变数据包的服务类型(Type of Service,TOS)字段;改变包的生存期(Time to Live,TTL)字段;在包中设置标志值,利用该标志值可以进行带宽限制和分类查询。
2、Netfilter为Ipv4定义了5个钩子函数,这些钩子函数在数据报流过协议栈的5个关键点被调用,也就是说,IPv4协议栈上定义了5个“允许垂钓点”。在每一个“垂钓点”,都可以让netfilter放置一个“鱼钩”,把经过的网络包(Packet)钓上来,与相应的规则链进行比较,并根据审查的结果,决定包的下一步命运,即是被原封不动地放回IPv4协议栈,继续向上层递交;还是经过一些修改,再放回网络;或者干脆丢弃掉。
(1)数据报经过各个HOOK的流程如下:
数据报从进入系统,进行IP校验以后,首先经过第一个HOOK函数NF_IP_PRE_ROUTING进行处理;
然后就进入路由代码,其决定该数据报是需要转发还是发给本机的;
若该数据报是发被本机的,则该数据经过HOOK函数NF_IP_LOCAL_IN处理以后然后传递给上层协议;
若该数据报应该被转发则它被NF_IP_FORWARD处理;
经过转发的数据报经过最后一个HOOK函数NF_IP_POST_ROUTING处理以后,再传输到网络上。
本地产生的数据经过HOOK函数NF_IP_LOCAL_OUT 处理后,进行路由选择处理,然后经过NF_IP_POST_ROUTING处理后发送出去。
举例:客户端访问服务端的WEB服务时:
(2)每个钩子函数最后必须向Netfilter框架返回下列几个值其中之一:
(2.1)NF_ACCEPT继续正常传输数据报。这个返回值告诉Netfilter:到目前为止,该数据包还是被接受的并且该数据包应当被递交到网络协议栈的下一个阶段。
(2.2)NF_DROP丢弃该数据报,不再传输。
(2.3)NF_STOLEN模块接管该数据报,告诉Netfilter“忘掉”该数据报。该回调函数将从此开始对数据包的处理,并且Netfilter应当放弃对该数据包做任何的处理。但是,这并不意味着该数据包的资源已经被释放。这个数据包以及它独自的sk_buff数据结构仍然有效,只是回调函数从Netfilter获取了该数据包的所有权。
(2.4)NF_QUEUE对该数据报进行排队(通常用于将数据报给用户空间的进程进行处理)
(2.5)NF_REPEAT 再次调用该回调函数,应当谨慎使用这个值,以免造成死循环。
二、iptables
iptables不是防火墙,可以理解成客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的"安全框架"中,这个"安全框架"才是真正的防火墙,这个框架的名字叫netfilter。
netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。
1、规则
规则:根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理;
(1)匹配条件
(1.1)基本匹配条件
源地址Source IP,目标地址 Destination IP
(1.2)扩展匹配条件
扩展条件是netfilter中的一部分,以模块形式存在,如果想要使用这些条件,则需要依赖对应的扩展模块
比如:源端口Source Port, 目标端口Destination Port
(2)处理动作
处理动作在iptables中被称为target,动作也可以分为基本动作和扩展动作。
常用动作:
ACCEPT:允许数据包通过。
DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
DNAT:目标地址转换。
REDIRECT:在本机做端口映射。
LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。
2、规则链
Netfilter对IPV4设定了5个关卡,防火墙的作用就在于对经过关卡的报文匹配"规则",然后执行对应的"动作",
每个关卡上可能不止有一条规则,而是有很多条规则,当我们把这些规则串到一个链条上的时候,就形成了"链"。
每个经过这个"关卡"的报文,都要将这条"链"上的所有规则匹配一遍,如果有符合条件的规则,则执行规则对应的动作。
3、规则表
把具有相同功能的规则的集合叫做"表",iptables定义了4种表:
filter表:负责过滤功能,防火墙;内核模块:iptables_filter;
nat表:network address translation,网络地址转换功能;内核模块:iptable_nat
mangle表:拆解报文,做出修改,并重新封装的功能;iptable_mangle
raw表:关闭nat表上启用的连接追踪机制;iptable_raw
4、表链关系
PREROUTING的规则可以存在于:raw表,mangle表,nat表。
INPUT的规则可以存在于:mangle表,filter表,(centos7中还有nat表,centos6中没有)。
FORWARD的规则可以存在于:mangle表,filter表。
OUTPUT的规则可以存在于:raw表mangle表,nat表,filter表。
POSTROUTING的规则可以存在于:mangle表,nat表。
5、iptables命令
iptables命令规则格式
iptables [-t table] SUBCOMMAND chain [-m matchname[per-match-options]] -j targetname [per-target-options]
四表 增删改查 五链 匹配条件(隐式/显式8个) jump处理工作(ACCEPT/REJECT等)
(1)规则查看
-L:list, 列出指定鏈上的所有规则,本选项须置后
-n:numberic,以数字格式显示地址和端口号
-v:verbose,详细信息
-vv 更详细,竖向显示(像mysql中的\G)
-x:exactly,显示计数器结果的精确值,而非单位转换后的易读值
--line-numbers:显示规则的序号,可以简写为--line
#查看表中规则
iptables -t filter -L
iptables -t raw -L
iptables -t mangle -L
iptables -t nat -L
#查看某个关卡(链)规则
iptables -nvL INPUT
iptables -nvL FORWARD
iptables --line -vvnxL OUTPUT (更详细)
#查看指定表中指定链规则
iptables -t filter -L INPUT
#每个列对应数据含义
pkts:对应规则匹配到的报文的个数。
bytes:对应匹配到的报文包的大小总和。
target:规则对应的target,往往表示规则对应的"动作",即规则匹配成功后需要采取的措施。
prot:表示规则对应的协议,是否只针对某些协议应用此规则。
opt:表示规则对应的选项。
in:表示数据包由哪个接口(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则。
out:表示数据包由哪个接口(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则。
source:表示规则对应的源头地址,可以是一个IP,也可以是一个网段。
destination:表示规则对应的目标地址。可以是一个IP,也可以是一个网段。
(2)规则管理
-A:append,尾部追加
-I:insert, 头部插入,要指明插入至的规则编号,默认为第一条
-D:delete,删除;(1) 指明规则序号;(2) 指明规则本身
-R:replace,替换指定链上的指定规则编号
-F:flush,清空指定的规则链
-Z:zero,置零
iptables的每条规则都有两个计数器(policy ACCEPT 0 packets, 0 bytes):匹配到的报文的个数pkts和匹配到的所有报文的大小之和bytes
规则的顺序很重要,--line显示的序号就是匹配的顺序。
#增加规则
#filter表增加入链规则 对源IP192.168.12.106过来的包丢弃
iptables -t filter -I INPUT -s 192.168.12.106 -j DROP
#不加表默认是filter 追加入链规则 对源IP192.168.12.106过来的包接收
iptables -A INPUT -s 192.168.12.106 -j ACCEPT
#filter表增加入链规则 规则编号为2 对源IP192.168.12.106过来的包丢弃
iptables -t filter -I INPUT 2 -s 192.168.12.106 -j DROP
#删除规则
#删除指定序号规则
iptables -t filter -D INPUT 3
#根据匹配条件和动作删除规则
iptables -D INPUT -s 192.168.12.106 -j ACCEPT
#清空规则(不加链名 表示清空整个表)
iptables -t 表名 -F 链名
#修改规则-R(有坑 建议先删除后新增)
#注意要写全匹配条件 -s等 否则源地址列会变成0.0.0.0/0
iptables -t filter -R INPUT 1 -s 192.168.12.106 -j REJECT
#修改默认策略 修改FORWARD的默认策略变成DROP
iptables -t filter -P FORWARD DROP
#保存规则
centos6
service iptables save 规则默认保存在/etc/sysconfig/iptables文件中
centos7
#配置好yum源以后安装iptables-service
yum install -y iptables-services
#停止firewalld
systemctl stop firewalld
#禁止firewalld自动启动
systemctl disable firewalld
#启动iptables
systemctl start iptables
#将iptables设置为开机自动启动,以后即可通过iptables-service控制iptables服务
systemctl enable iptables
#保存
iptables-save > /etc/sysconfig/iptables
#重载
iptables-restore < /etc/sysconfig/iptables
(3)iptables匹配条件
报文在经过iptables的链时,会匹配链中的规则,遇到匹配的规则时,就执行对应的动作,如果链中的规则都无法匹配到当前报文,则使用链的默认策略(默认动作),链的默认策略通常设置为ACCEPT或者DROP。
#源地址匹配
-s 192.168.1.10 #匹配一个
-s 192.168.1.10,192.168.4.56 #匹配多个,使用逗号分隔
-s 192.168.1.10/16 #匹配网段
!-s 192.168.1.10 #条件取反
#目标地址匹配 -d
iptables -t filter -I INPUT -p 192.168.1.15 -j REJECT
#协议类型 -p
centos6中,-p选项支持如下协议类型:tcp, udp, udplite, icmp, esp, ah, sctp
centos7中,-p选项支持如下协议类型:tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
当不使用-p指定协议类型时,默认表示所有类型的协议都会被匹配到,与使用-p all的效果相同。
#网卡接口
-i选项用于匹配报文从哪个网卡流入
-o选项,匹配报文将由哪块网卡流出
-i选项只能用于PREROUTING链、INPUT链、FORWARD链
-o选项只能用于FORWARD链、OUTPUT链、POSTROUTING链
#扩展匹配条件
--dport 目标端口 需要指定协议-p 扩展模块-m
iptables -t filter -I INPUT -s 192.168.1.15 -p tcp -m tcp --dport 22 -j REJECT
--sport 源端口
iptables -t filter -I INPUT -s 192.168.1.15 -p tcp -m tcp --sport 22 -j REJECT
可以指定一个连续端口范围,比如:22:25 表示22、23、24、25端口,:22表示0-22,22:表示22至65535
指定离散的多个端口使用扩展模块multiport:
iptables -t filter -I INPUT -s 192.168.1.15 -p tcp -m multiport --dport 22,24,26 -j REJECT
iptables -t filter -I INPUT -s 192.168.1.15 -p tcp -m multiport --dport 22,24:30 -j REJECT