Linux内核防火墙工作原理
介绍
Linux内核防火墙提供的防火墙功能通过netfilter框架实现,并提供了IPtables、Firewalld工具配置和修改防火墙的规则。
Netfilter是一个安全框架,可以实现包过滤,NAT(net addr trans 网络地址转换),网络连接跟踪等功能。
Netfilter是防火墙真正的安全框架,位于内核空间当中
Netfilter的通用框架不依赖于具体的协议,而是为每种网络协议定义一套钩子函数。这些钩子函数在数据包经过协议栈的几个关键点时被调用,在这几个点中,协议栈将数据包及钩子函数作为参数,传递给netfilter框架。
对于每种网络协议定义的钩子函数,任何内核模块都可以对每种协议的一个或多个钩子函数进行注册,实现连接。这样当某个数据包被传递给netfiler框架的时候,内核能检测到是否有有关模块对该协议和钩子函数进行了注册。如果发现注册信息,就调用该模块注册时使用的回调函数,然后对应模块取检查、修改、丢弃该数据包及指示netfilter将该数据包传入用户空间的队列。
netfilter的体系结构
在IPV4中有5个HOOK点,我们称为钓鱼点,因为在这些地方,可以设置钩子函数(鱼钩)来获取符合条件的数据包(鱼)。
5个HOOK点
| HOOK点 | 说明 | 函数位置 | 应用举例 |
|---|---|---|---|
| NF_IP_PRE_ROUTING | 网络数据包进入系统,经过简单的检测后,数据包转交给该函数进行处理,然后根据系统设置的规则进行处理,如果数据包不被丢弃则交给路由函数进行处理。在该函数中可以替换IP包的目的地址,即DNAT |
由网卡传入主机的数据包,在没有经过IP层路由之前,会先经过这个点 | ip_rcv() |
过滤拒绝服务攻\NAT\计算 |
| NF_IP_LOCAL_IN | 所有发送给本机的数据包都要通过该函数进行处理,该函数根据系统设置的规则对数据包进行层处理,如果数据包不被丢弃则交给本地的应用程序
经过路由选择,要进入本机的数据包,会经过这个点 | ip_local_deliver()
在此处可进行碎片重组 | 防火墙过滤进入本机的包 |
| NF_IP_FORWARD | 所有不是发送给本机的数据包都要通过该函数进行处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃则转至NF_IP_POST_ROUTING进行处理。
经过路由,不是发往本机的包,需要向外发送,会经过这个点 | ip_forward()
之后进入ip_send() | |
| NF_IP_LOCAL_OUT | 所有从本地应用程序出来的数据包必须通过该函数进行处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃则交给路由函数进行处理
本机发往外部的数据包在经过路由之前会经过这个点 | ip_build_and_send_pkt()
ip_queue_xmit()
ip_build_xmit_slow()
ip_buid_xmit()
不同的上层协议会走不同的流程 | 防火墙过滤外发的数据包 |
| NF_IP_POST_ROUTING | 所有数据包在发送给其他主机之前需要通过该函数进行处理,该函数根据系统设置的规则对数据包进行处理,如果数据包不被丢弃,则将数据包发送给数据链路层。在该函数中可以替换IP包的源地址,即SNAT。
本机发送出去的包,在路由后会经过此点 | ip_finish_output() | 包计数功能实现 |
包过滤
每个函数都可以对数据包进行处理,最基本的操作是对数据包进行过滤。
可以通过iptables工具来向内核模块注册多个过滤规则,并且指明过滤规则的优先级。
包过滤操作:
| 操作 | 说明 |
|---|---|
| NF_ACCEPT | 继续正常的传递包 |
| NF_DROP | 丢弃包,停止传包 |
| NF_STOLEN | 已经接管了包,不要继续传送 |
| NF_QUEUE | 排列包 |
| NF_REPEAT | 再次使用该钩子 |
包选择
在netfilter框架中已经创建了一个包选择系统,这个包选择系统默认注册了3个表
分别是过滤表filter表、网络地址转换NAT表和Mangle表
IPtables
介绍
用户空间的客户端代理,将用户空间的安全设定通过代理执行到Netfilter中,所以能够实现的是软件防火墙
Netfilter和IPtables
- Netfilter ——内核空间;是真正去实现软件防火墙功能
iptables—— 用户空间;是一个用户空间的客户端代理软件
Netfilter+IPTABLES组成linux平台下的包过滤防火墙(免费)
Netfilter是Linux操作系统核心层的一个数据包处理模块,IPTABLES没有守护进程,所以它不是一个服务,而是内核提供的功能:
- 网络地址转换- 数据包内容修改- **数据包过滤的防火墙功能**
Iptables 基础
Iptables 根据它的rule进行匹配,对匹配到的规则的数据包进行action
- accept(接收)、reject(拒绝)、drop(丢弃)
rule存储在内核空间的信息过滤表中,这些规则包括:SIP(源地址) DIP(目的地址) 传输协议 (tcp udp ICMP等)和服务类型(http ftp等)
- Netfiller位于内核空间中,所有Iptables+Netfiller可以在内核空间中设置关卡,当用户去访问应用服务的时候,数据包时通过网卡流经内核空间之后到达用户空间。
当一个主机接收到一个数据包的时候。Netfilter 怎么工作?
- Netfilter 位于内核空间,是真正的防火墙,规则设置在Input和Output上 - 网卡驱动是在内核空间中,Netfilter也是在内核空间中,是由iptables+Netfilter - 内核空间可以在内核空间设置“关卡”, - 当用户去访问应用服务的时候,数据包通过网卡,经过内核空间流入到用户空间 - A:路由前 prerouting - B:转发 forward - C:路由后 postouting如果我们需要报文转发,不经过input链和output链
只需要:prerouting链,forward链,postrouting链
- Input链和output链 :作用域数据包用户空间和内核空间的流入流出
- preouting链 forward链 postouing链 :在内核空间中关于数据包的流入流出及转发
- preouting链
- 做判断,目标是否为本机,如果本地,发给input链
- 如果不是交由forward链
常见应用场景
- 到本地的某个进程的报文:prerouting ——> input ——>output ——>psotrouting
- 由本地转法的报文:prerouting ——>forward ——>postrouting
- 由本地响应的报文的流向:output ——>postrouting
链
- 防火墙的作用在于对经过的报文进行规则匹配,然后执行相应的动作;那么如果有多个“规则”组合到一起,我们就称之为“链”
- 每经过一条链,则需要把所有的规则匹配一遍,符合条件的规则,则执行相应的动作
多个规则组成链,经过链的数据报文需要将规则匹配一遍,一旦匹配到符合条件的规则就执行动作
表
每个链上都有一串规则,但是又许多类似的规则,这些规则可能是:
- 对ip或端口进行过滤 - 对报文进行修改 - 对网络地址进行转换等 将这些实现相似功能的规则放在一起,它们的集合叫表,多张表的规则的集合叫做链<br />iptables所有的规则的定义,都是定义到不同的表中iptables 提供的表
| 名称 | 作用 | 内核模块 |
|---|---|---|
| raw表 | 关闭nat上启用的连接追踪机制 | iptables_raw |
| mangle表 | 拆解报文,做出修改,并重新封装,内核模块 | iptables_mangle |
| nat表 | 网络地址转化 | iptables_nat |
| filter表 | 负责过滤功能,(包括防火墙使用的表) | iptables_filter |
- 优先级顺序; - raw——>mangle——>nat——>filter - 优先级越高的表中的规则优先匹配处理 |
||
- 所有定义的规则都在这四张表中 |
表链关系
每个链只能拥有某些规则,也就是某些表
链——表
| PREROUTING | raw mangle nat |
|---|---|
| INPUT | mangle filter nat |
| FROWARD | magle filter |
| OUTPUT | raw mangle nat filter |
| PSTROUTING | mangle nat |
实际使用的过程中,往往是以表为操作入口,操作的时候,通过表,查询所定义的规则,以及该表的规则所用与”链”
表——链
| raw表 | preouting,output |
|---|---|
| mangle表 | prerouting,input,forward,output,pistrouting |
| nat表 | input,output,postrouting,prerouting |
| filter表 | input,forward,output |
ps:
1.当一个数据包经过一个链的时候,会将当前链的所有规则都依次匹配,而定义的规则会都汇聚到表当中,匹配的时候,因为总有优先匹配,所以表就拥有了优先级
2.在Linux主机当中,如果想要支持转发,需要开启内核中的ip_forward
- [root@localhost net]# cat /proc/sys/net/ipv4/ip_forward
0
| ACCEPT | 允许数据包通过 |
|---|---|
| DROP | 直接丢弃数据包,无任何回应消息 |
| REJECT | 拒绝数据包通过,必要时会发出数据发送端一个响应的拒绝消息 |
| SNAT | 源地址转换,解决内网用户同一个公网地址的上网问题 |
| MASQUERADE | 是snat的一种特殊形式,适用于动态的,临时会变的ip |
| DNAT | 目的地址转换,解决外部网络访问内部局域网中的服务 |
| REDIECT | 在本地端口做端口映射(在docker中用的多) |
| LOG | 在/var/log/message文件中记录日志信息,然后将数据包传递给下一个规则,不对数据包进行任何的操作,只记录,让下一条规则去匹配 |
iptables的相关操作
规则查询
以filter进行实际的操作,fileter表负责过滤数据报文,eg:禁止(允许)哪些ip地址访问哪些端口等
- -t:指定表类型 raw mangle nat filter
- -L:列出表中的规则,默认所有的链规则
- -v:显示详细信息
- -x:显示数字信息
- -n:将信息以数字形式显示
- --line-number:显示有序号
[root@localhost ~]# iptables -t filter -vxL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1710 123282 ACCEPT all -- any any anywhere anywhere ctstate RELATED,ESTABLISHED
10 740 ACCEPT all -- lo any anywhere anywhere
80 7954 INPUT_direct all -- any any anywhere anywhere
80 7954 INPUT_ZONES_SOURCE all -- any any anywhere anywhere
80 7954 INPUT_ZONES all -- any any anywhere anywhere
0 0 DROP all -- any any anywhere anywhere ctstate INVALID
77 7802 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited
policy:当前链的默认策略
packets:当前链默认策略匹配到包的数量
bytes:当前默认策略匹配到的包的大小,-x显示精确的计数值
pkts:对应匹配到的报文数
bytes :对应匹配到的报文大小
target :规则对应的“动作”
prot:规则对应的“协议” , all所有协议
opt:规则对应的选项
in:数据包由哪个网卡(接口)流入,any任意网卡都生效,指定相应的网卡进行规则匹配策略
out:数据包由哪个网卡(接口)流出,any任意网卡都生效,指定相应的网卡进行规则匹配策略
source: 规则对应的源地址(ip地址或网段)
destination:规则对应的目标地址(ip地址或网段)
源地址和目标地址都是anywhere,因此iptables默认进行了名称解析,把anywhere解析成0.0.0.0
规则操作
增加规则:
- -A:追加规则(latest)
- -I:插入规则(first)+[number] 可以插入到指定位置
- -s:匹配条件中的源地址
-j:匹配条件中的动作
iptables -t
-A <匹配条件> -j eg:<br />禁止ping 172.16.0.1 - iptables -t filter -A INPUT -s 172.16.0.1/24 -j REGECT
禁止ping 172.16.0.1 192.168.10.10
- iptables -t filter -A INPUT -s 172.16.0.1 -j REJUCT
- iptables -t filter -I INPUT -s 192.168.10.10 -j DROP
删除规则:
- -D:删除指定‘链’中的规则+[num]指定规则
- -F:删除操作,删除所有操作
- 方法一:根据具体的匹配条件去删除规则
- iptables -t filter -D INPUT -s 192.168.10.2 -j DROP
- 方法二:可以根据规则的number进行删除
- iptables -t filter -D INPUT 2
- 方法一:根据具体的匹配条件去删除规则
修改操作:
- -R :修改指定规则
- -P:修改链的默认策略
- [root@test ~]# iptables -t filter -R INPUT 1 -s 172.16.10.0/24 -j ACCEPT
- [root@test ~]# iptables -t filter -P FORWARD DROP
保存规则:
- iptables‐save > /etc/sysconfig/iptables #系统启动后导入的规则
导入规则:
- iptables ‐restore < /etc/sysconfig/iptables
匹配条件
基本匹配条件
- -s:指定源地址
- -d:指定目标地址
- -p:指定协议
- -i /-o:指定网卡的流入和流出
- -i:用于网卡流入,PREROUTING,INPUT,FORWARD
- -o:用于网卡流出,OUPTUT, POSTROUTING
拓展匹配条件:需要拓展模块支持
- -m [模块名]:去使用拓展模式,定义拓展匹配条件
- tcp/udp 拓展模式:
- --dport :指定目的端口
- --sport:指定源端口
- iprange拓展模块:
- --src-range:指定源ip地址段
- --dest-range:指定目的IP地址段
- 192.168.0.0/24-192.168.31.0/24
- string模块:指定需要匹配报文中的字符串
- --algo:指定匹配算法(bm和kmp)
- --string:指定需要匹配的字符串
- time模块:时间段匹配,如果报文在到达时间范围内,则符合匹配条件
- --timestart[起始时间] --timestop[结束时间]
- --weekadys:指定周
- --mouthdays:指定月
- --datestart[指定日期] --datestop[结束日期]
- connlimit模块:限制每个IP地址同时连接到server端的连接数量,不需要指定ip地址,默认就是针对每个客户端ip地址
- connlimit-above 限制每个客户端ip的并发连接数量,,如果高于此数量则执行此响应动作
- connlimit-upto 限制每个客户端IP的并发连接数量,如果低于数量则执行响应动作
- iptables -t fliter -I INPUT -m connlimit --connlimit-above 2 -j REJUCT
eg:ssh连接:
限制每个客户端IP的ssh并发链接数量高于2都被拒绝
- ‐m connlimit ‐‐connlimit‐above 2 ‐j REJECT
限制每个客户端ip的ssh连接并发连接数低于2时,都被接收
- -p tcp --dport 22 -m connlimit --connnlimit-upto 2 -j -ACCEPT
- ‐p tcp ‐‐dport 22 ‐m connlimit‐‐connlimit‐above 2 ‐‐connlimit‐mask 24 ‐j REJECT 限制24网段的链接数量为2,配合后更加的灵活
- limit模块:对“报文到达的速率”进行限制的,就是限制单位时间内流入包的数量
- -m limit --limit [速率]
- 速率:
- /second
- /minute
- /hour
- /day
- ‐‐limit‐burst 空闲时可放行的包的数量,默认为5;而默认生成令牌的速度为每6s一个
- state 模块:对于连接报文中的状态可以分为::NET, ESTABLISHED, RELATED, INVALID, UNTARCKED
- 通过匹配连接状态,从而定义过滤规则
- NEW:连接中的第一个包,状态就是NEW
- ESTABLISHED:把NEW状态包后面的包的状态理解为ESTABLISHED,表示已经建立连接 RELATED:与“命令连接”中的报文有关系的,比如FTP服务,有两个进程,一个命令进程,一个数据 进程
- INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,我们是能够主动屏蔽状态为 INVALID的报文
- UNTRACKED:表示报文未被追踪时的状态,当报文的状态为UNTRACKED时通常表示无法找到相关连接
- iptables ‐t filter ‐I INPUT ‐m state ‐‐state ESTABLISHED,RELATED ‐j ACCEPT
- iptables ‐t filter ‐I INPUT ‐m state ‐j REJECT
- 表示只有回应我们的报文能够通过防火墙,如果是别人主动发送过来的新报文,则无法通过防火墙。
自定义链
当默认链的规则非常多的时候,不方便我们管理,如果INPUT链中存放着几百条规则,有针对http、ftp服务,当我们想修改http规则的时候,为了方便管理,则需要去创建自定义链
创建自定义链
- iptables -t filter -N [chain_name]
- -N:创建自定义链
- 增删改查同模式链的方法
- iptables ‐t filter ‐I my_chain ‐s 192.168.139.1 ‐j REJECT
- iptables ‐I INPUT ‐p icmp ‐j my_chain ps:表示引用链,禁ping
- http服务,只允许192.168.10.0/24以及172.16.0.0/16的客户端访问
- iptables -t filter -N http
- 1.iptables -t filter -A http -s 192.168.10.0/24 -j ACCEPT
- 2.iptables -t filter -A http -s 172.16.0.0/16 -j ACCEPT
[root@localhost ~]# iptables -t filter -N lars
[root@localhost ~]# iptables -t filter -A lars -s 192.168.0.0/24 -j DROP
[root@localhost ~]# iptables -t filter -I INPUT -j lars
[root@localhost ~]# ping 192.168.0.7
PING 192.168.0.7 (192.168.0.7) 56(84) bytes of data.
^C
--- 192.168.0.7 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9003ms
删除自定义链
iptables -t filter -F httpd # 1.清除自定义链中的规则
iptables -t filter -D INPUT 1 # 2.删除引用自定义链中的相关规则
iptables -t filter -X httpd # 3.通过-X参数删除自定义链
- ps:满足以下要求:
- 自定义链中没有任何模式的链引用,即自定义链的引用数为0
- 自定义链中没有任何规则,自定义链为空
iptables规则保存和恢复
- 保存规则:
- iptables-save > /etc/sysconfig/iptables
- iptables-save > /iptables/input1
- 恢复规则:
- IP tables-restore < /iptables/input1
Firewalld
介绍
Firewalld是一个支持定义网络区域(zone)及接口安全等级的动态防火墙管理工具。
利用Firewalld,用户可以实现防火墙、代理服务器以及网络地址转换
它具备IPv4和IPv6防火墙的设备支持。
它支持以太网桥
图形化配置工具:firewall-config
命令行配置工具:firewall-cmd
配置文件在/usr/lib/firewalld和/etc/firewalld目录中的XML文件中
firewalld和iptables的关系
相同点:
- firewalld和IP tables一样本身不具备防火墙工具,而是将用户空间的安全设定执行到内核空间中的Netfilter(安全框架)
差异:
1.firewalld service 在/usr/lib/firewalld/(系统配置)和/etc/firewalld/(用户配置)
iptables /etc/sysconfig/iptables 中储存配置
2.iptables每一个单独更改意味着清除旧的规则和从/etc/sysconfig/iptables读取新的配置文件
3.firewallde 不在创建任何新的规则,仅仅运行规则中的不同之处,因此firewalld可以在运行时间内,改变设置而不丢失现有的连接
NetworkManager服务:通知firewanlld一个接口归属某个区域,新加入的接口被分配到默认区域中
防火墙区域 zone
数据包首先从本地接口中进入,接下来将进入接口所对应的区域。
ps:一个网络接口只能与一个区域对应,即一个接口不能同时加入两个或以上的区域。
当数据包进入区域后,防火墙会根据区域内的规则进行逐一过滤,只有符合规则的数据包才能通过区域到达本机应用
不同区域对于网络连接的设置规范不同,系统中实际存在9个区域
从信任到不信任排列
| 区域 | 说明 |
|---|---|
| trusted(信任区域) | 信任所有网络连接 |
| internal(内部区域) | 用于企业等的内部网络,基本信任内部网络中的计算机不会威胁计算机安全 |
| home(家庭区域) | 基本信任家庭网络中的计算机不会危害计算机的安全 |
| work(工作区域) | 基本信任工作网络中的计算机不会危害计算机的安全 |
| dmz(非军事区域) | 隔离区,此区域内的计算机可以公开访问,可以有限地进入内部网络 |
| external(外部区域) | 通常是使用了伪装的外部网络,该区域内的计算机可能会危害计算机的安全 |
| public(公共区域) | 在公共区域使用,该区域内的计算机可能会危害计算机安全 |
| block(阻塞区域) | 拒绝,任何进入的网络连接都将被拒绝,并返回IPV4或IPV6的拒绝报文 |
| drop(丢弃) | 任何进入的网络连接都将被丢弃,没有任何回复 |
ps:最终决定连接是否被放行是区域中的规则,而不是区域中的描述。
firewalld管理操作
每个zone都有一套规则集,对每个接收到的请具体使用哪个zone,firewalld有三种方法来判断
- source 源地址优先级最高
- interface 接收请求的网卡
- firewall.conf 中配置的默认zone
[root@localhost ~]# cat /etc/firewalld/firewalld.conf | grep Zone
DefaultZone=public
firewalld-cmd命令
管理防火墙
| 查看默认zone | firewall-cmd —get-default-zone |
|---|---|
| 查看firewall的状态 | firewall-cmd —state |
| 查看当前活动的区域 | firewall-cmd —get-active-zones |
| 查看可用区域 | firewall-cmd —get-zones |
| 列出public域的所有配置 | [root@localhost ~]# firewall-cmd —zone=public —list-all public (active) target: default icmp-block-inversion: no interfaces: ens37 ens33 sources: services: ssh dhcpv6-client ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: |
| 列出所有区域的配置 | firewall-cmd —list-services |
| 列出所有预定的服务 | firewall-cmd —get-services |
| 设置默认域 | firewall-cmd —set-default-zone= [root@localhost ~]# firewall-cmd —set-default-zone=public Warning: ZONE_ALREADY_SET: public success |
| 设置网络地址到指定域 | firewalld-cmd —zone = |
| 删除指定区域的网络地址 | firewalld-cmd —zone= |
管理操作
| 添加,改变,删除网络接口到指定域中(域中会有一条规则) |
- firewall-cmd —list-interfaces
- firewall-cmd —add-interface
- [root@localhost ~]# firewall-cmd —add-interface en0
success
- firewall-cmd —change -interface
- firewall-cmd —remove -interface
- firewall-cmd —query-interface
|
| —- | —- |
| 添加、删除、列出服务 |
- firewalll-cmd —get-services 列出所有预定的服务
- firewall-cmd ‐‐add‐service
- firewall-cmd —list-services 列出所有区域的配置
- firewall-cmd ‐‐remove‐service
- firewall-cmd —query-service
- firewall-cmd ‐‐permanent 表示是否永久生效
|
| 列出、添加、删除端口 |
- firewall-cmd —list-ports
- firewall-cmd —add-port
[root@localhost ~]# firewall-cmd —add-port=22/tcp
success
删除sh服务的时候,添加tcp的 仍旧可以用ssh进行连接
- firewall-cmd ‐‐remove‐port
- firewall-cmd —query-port
|
| 永久生效 | —permanent |
| 重载防火墙 | firewall-cmd -‐reload |
添加服务 修改/usr/lib/firewalld/service/…xml文件 之后直接交给iptables/netfilter
添加端口 在iptables/netfilter中执行
系统配置firewalld的配置:/usr/lib/firewalld/
- 用户配置firewalld的配置:/etc/firewalld/
- 去将系统配合cp一份到用户配置当中进行修改
ftp服务器自定义端口1121,需要在work zone下放行 ftp做法。 方法一: [root@localhost ~]# cp /usr/lib/firewalld/services/ftp.xml /etc/firewalld/services [root@localhost ~]# vi /etc/firewalld/services/ftp.xml <port protocol="tcp" port="1121"/> [root@localhost ~]# cp /usr/lib/firewalld/zones/work.xml /etc/firewalld/zones/ [root@localhost ~]# cp /usr/lib/firewalld/zones/work.xml /etc/firewalld/zones/ <service name="ftp"/> [root@localhost ~]# firewall‐cmd ‐‐reload 重新加载! [root@localhost ~]# firewall‐cmd ‐‐zone=work ‐‐list‐service [root@localhost ~]# firewall‐cmd ‐‐service=ftp ‐‐get‐ports ‐‐permanent 方法二: firewall‐cmd ‐‐zone=work ‐‐add‐service=ftp ‐‐permanent firewall‐cmd ‐‐zone=work ‐‐service=ftp ‐‐add‐port=1121/tcp ‐‐permanent

