一、linux系统防火墙底层原理
centos6与centos7的防火墙组件都是应用层面的东西,他们的底层都是基于内核的netfilter(这是 Linux 内核的一部分)
netfilter顾名思义就是网络过滤,而防火墙的本质恰恰就是对数据包进行过滤或者一些改动, 所以netfilter可以被称之为内核防火墙。
但是直接去操作内核模块netfilter来插入/修改一些规则必然是非常复杂的,因为没几个人有开发内核的能力
为了简单一点,有人就做了一些封装,形成了上层的应用,
这就是centos6或centos7+中防火墙组件的由来,都是应用层的东西、都是基于netfilter的封装
也就是说无论是6还是7的系统防火墙本质都是配置netfilter的,真正干活的其实是内核的netfilter
二、各个linux防火墙组件构成
1、一个iptables命令:是一个命令行工具,它允许系统管理员设置和配置内核提供的防火墙规则。但用命令添加的都是临时的
对应软件包iptables.x86_64.xxx.rpm用于操作内核级防火墙和实时更改防火墙的行为, 但这些更改是短暂的,如果不保存,系统重启后,这些规则将不复存在。 iptables -I INPUT -i ens33 -s 192.168.80.0/24 -j DROP
2、一个iptables服务:是一个后台服务,它在系统启动时从 /etc/sysconfig/iptables 文件加载防火墙规则,而在系统关闭时保存当前的防火墙规则到该文件。
对应软件包iptables-services.x86_64.xxxx.rpm 可以用service iptables start 启动
总结:在centos6中,iptables命令与iptables服务的关系
1、iptables命令的作用
直接操作的是内核防火墙netfilter规则,所以一旦内核重启(也就是系统重启)则会丢失
2、iptables服务的作用
而iptables服务则用于保持防火墙设置的持久性, 原理就是: 在系统启动或者重启iptales服务时加载/etc/sysconfig/iptables文件内容然后配置到内核netfilter里 并在系统关闭时将当前的防火墙规则保存到该文件,这意味着一加载就是整体刷一下所有规则。
3、基于1的描述可以得出3个新的结论:
1.iptables命令与ipables服务底层都是在配置netfilter 2.即便你service iptables stop关闭了防火墙服务, 你之前添加的防火墙规则、还有你用iptables新增的规则都依然有效,只是重启系统后这些规则就会消失 3.你用iptables命令是直接修改内核netfilter规则,会立即生效,根本不需要你重启什么服务所以在生产环境要三四而后行
=====================》构成=命令行工具+服务
1、一个 firewall-cmd命令-----》很明显对应的是centos6中的iptables命令 2、一个firewalld服务---------》很明显对应的是centos6中的iptables服务
=====================》服务详解
在7中filewalld服务取代了iptables服务,二者是冲突的,只能启动一个, 你要想用过去的iptables服务,那必须先关闭掉firewalld服务,并且要下载iptables-service.x86_64.xxx.rpm包才行,了解就行,只有傻冒才会退回去干这种退步的事情 firewalld服务跟iptables服务比起来至少有两大好处: # 1.firewalld可以动态修改单条规则,而不需要像iptables服务那样,在修改了规则后必须得全部刷新才可以生效; # 2.firewalld在使用上要比iptables服务人性化很多,即使不明白“五张表五条链”而且对TCP/IP协议也不理解也可以实现大部分功能。
=====================》命令行工具详解
centos7中提供了更简单的firewall-cmd命令,力求取代6中的命令。 但是但是但是 虽然centos6中的iptables命令对小白不太友好,难学,但毕竟一些人是学会了的,你centos7说不让用就不让用了,那一群人要哭晕在厕所。 于是centos7对大家说,这么着吧,在centos7+之后,关于防火墙服务我肯定是要换成firewalld的,这个没商量,因为我太想进步了。 但是我也照顾一下你们过去那些吃着粗糠过来的屌丝们,iptables这个命令就给你们留着 于是你会发现在centos7+中还保留着iptables命令,屌丝们一边感谢官方的不杀之恩, 一边发现不太对劲就问题官方:那我用iptables命令岂不是只能临时添加重启内核则丢了,没有自动帮我持久化的服务啊。官方回答:滚一边去 相信:官方给你留着iptables命令的时间也并不会太长,且行且珍惜吧,要什么自行车 你要就想用iptables,还想能持久化,其实也并不是一定要用iptables服务,你就把你的iptables添加规则的命令 都写到一个脚本里,然后添加到/etc/rc.local里开启就执行,一样可以实现 所以懂了这些关系没有,netfilter内核防火墙才是核心,这个东西官方是不会动的, 上层的管理工具一定是趋向于越来越简单的,iptables命令这种晦涩对小白不友好的东西早就该扔进垃圾堆里了,这么看, 官方做的没毛病。
三、iptables的五链四表设计
数据流入linux系统,总结下来就涉及五种流向,或者叫5中链路
如上图:对于转发的数据包数据流向如下
PREROUTING –> FORWARD –> POSTROUTING
要进入用户空间的就走INPUT
从用户空间出来准备发出去的走OUTPUT
画个简图:
数据流入内核的5种链路,也正好对应iptables的5种链名,这些链路就好像是一道道关卡,我们就应该在这些链上添加防火墙规则
1、表是个啥?为啥要有表?
事实上没有表完全可以,你就用上一小节我们学的知识,就可以添加防火墙规则了,本质 就是在往链上加规则呗。
但是但是但是
随着你往链上添加的规则越来越多,假设你添加到了一万条,你会发现越来越难以管理,太混乱了,太乱了。 但这难不倒聪明的你,你发现这一万条规则里,非常有规律地可以分为几大类: 1、对于某些特定的数据包,我们希望阻止它们被 Netfilter 的连接跟踪系统处理。 1、对数据包做修改、打标记 2、对数据包里的ip地址做nat转换 3、对数据包做筛选,一些包过滤掉(最常用)
所以表到底是个啥
你猜的没错,上面的四大分类,就是iptables种四张表的由来,没错,表的本质就是对规则的进行了归类, 一种表代表的就是一类功能。表的诞生,是设计者对规则的功能进行总结归纳的结果。
总结下:
链:链就是关卡,防火墙规则就是加载链上的 表:表就是对不同的规则进行了归类,每种表都有自己特定的含义。 一种表就代表一类功能,所以每当你看到一种表的时候,就告诉自己,我看到的是xxx功能就行,表就是功能的代表。 上面的作图地址在这里:https://www.processon.com/diagraming/58883630e4b049e795e80bcf
四大类表-4大类功能
raw表的功能:代表阻止追踪,包含了/工作在PREROUTING、OUTPUT mangle表的功能:代表修改或做记号,包含了/工作在5个链都有了 nat表的功能:代表做源ip或目标ip转换,包含了/工作在PREROUTING、INPUT、OUTPUT、POSTROUTING filter表的功能:代表过滤,包含了/工作在INPUT、FORWARD、OUTPUT 所以请告诉我们5个链路上都可以加哪些功能的规则,你应该知道答案了。
数据包流入到流出,就好比是一个快递包裹送进快递站,然后由快递站处理后发出 5个链路就好比是:快递站里设置了5道流程或者关卡,数据包要通过这一个个关卡(具体走哪个关卡,看数据包自己) 4张表就好比是:一个个负责专门事项的检验员,他们四个有优先级之分,raw>mangle>nat>filter 如上图: 1、数据包走到第一道关卡PREROUTING:三个检验员按次序对包进行处理,raw先上、mangle再上、最后是nat 2、然后数据包可能会走入第二道关卡INPUT:两个检验员依次序对包进行处理,mangle先上,filter在上 。。。。。。。
详解如下
主机型防火墙 入站数据(来自外界的数据包,且目标地址是防火墙本机) PREROUTING --> INPUT --> 本机的应用程序 出站数据(从防火墙本机向外部地址发送的数据包) 本机的应用程序 --> OUTPUT --> POSTROUTING 网络型防火墙 转发数据(需要经过防火墙转发的数据包) PREROUTING --> FORWARD --> POSTROUTING 规则链内的匹配顺序 自上向下按顺序依次进行检查,找到相匹配的规则即停止(LOG策略例外,表示记录相关日志) 若在该链内找不到相匹配的规则,则按该链的默认策略处理(未修改的状况下,默认策略为允许) 更多内容见:https://www.cnblogs.com/linhaifeng/p/15979888.html
四、firewalld的新设计(更简单高效)
为啥在centos7中我用iptables命令查出来的结果发现多出了很多链,而不是五个基本的预定义链(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING)??????
因为firewalld使用了一种更复杂的策略来处理防火墙规则,新增了很多链对应到netfiler上, 而iptables与firewalld底层都是在操作netfilter表, 即netfilter表是二者共享的,所以firewalld新增东西,你用iptables当然能查出来!!!!
firewalld 通过添加额外的链和规则来支持区域(zones)概念。
其中每一个区域对应一个链,这样的设计使得 firewalld 可以更精细地控制不同类型的网络流量。 例如,它可以为一个特定的网络接口或者一个特定的 IP 地址范围定义不同的过滤规则。 此外,用户也可以自己创建自定义链。自定义链除了 iptables 自带的5个预定义链之外,由用户自定义的新链。 在自定义链中定义的规则需要被内置链引用才可以生效。
通过将网络划分成不同的区域,制定出不同区域之间的访问控制策略来控制不同程序区域间传送的数据流。例如,互联网是不可信任的区域,而内部网络是高度信任的区域。网络安全模型可以在安装,初次启动和首次建立网络连接时选择初始化。该模型描述了主机所连接的整个网络环境的可信级别,并定义了新连接的处理方式。有如下几种不同的初始化区域:
阻塞区域(block):任何传入的网络数据包都将被阻止。
工作区域(work):相信网络上的其他计算机,不会损害你的计算机。
家庭区域(home):相信网络上的其他计算机,不会损害你的计算机。
公共区域(public):不相信网络上的任何计算机,只有选择接受传入的网络连接。
隔离区域(DMZ):隔离区域也称为非军事区域,内外网络之间增加的一层网络,起到缓冲作用。对于隔离区域,只有选择接受传入的网络连接。
信任区域(trusted):所有的网络连接都可以接受。
丢弃区域(drop):任何传入的网络连接都被拒绝。
内部区域(internal):信任网络上的其他计算机,不会损害你的计算机。只有选择接受传入的网络连接。
外部区域(external):不相信网络上的其他计算机,不会损害你的计算机。只有选择接受传入的网络连接。
注:FirewallD的默认区域是public。
firewalld默认提供了九个zone配置文件:block.xml、dmz.xml、drop.xml、external.xml、 home.xml、internal.xml、public.xml、trusted.xml、work.xml,他们都保存在“/usr/lib /firewalld/zones/”目录下。
五、防火墙规则添加
iptables命令格式:iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]
1、注意事项
不指定表名时,默认指filter表
不指定链名时,默认指表内的所有链
除非设置链的默认策略,否则必须指定匹配条件
选项、链名、控制类型使用大写字母,其余均为小写
2、常用的管理选项
3、常用的控制类型
示例
# 在机器192.168.71.207上设置防火墙规则,放行某个ip访问22端口
先清空之前所有,排除干扰
iptables -t raw -F
iptables -t mangle -F
iptables -t nat -F
iptables -t filter -F
# 1、先把INPUT整体禁用
iptables -t filter -P INPUT DROP # 不指定-t,默认就是filter表
# iptables -t filter -P INPUT ACCEPT # 重新放开
# 2、然后再单独放行
iptables -t filter -A INPUT -p tcp --source 192.168.71.18 --dport 22 -j ACCEPT
iptables -t filter -A INPUT -p tcp --source 192.168.71.206 --dport 22 -j ACCEPT
# 3、查看
iptables -t filter -L -n # -L-n可以简写为-nL,但注意-n必须在前面
# 4、然后你可以在 192.168.71.206机器上测试,发现ping不同目标主机,但是可以ssh登录
ssh root@192.168.71.207 # 会慢一些,但是等等,可以链上。从侧面可以反馈出使用iptables会带来的一些问题
# 5、清空表中所有规则
iptables -t filter -F
# 6、删除某一条
iptables -t filter -nL --line-numbers # 先查看到规则号
iptables -t filter -D INPUT 2
命令iptables与firewall-cmd本质都是在操作内核的netfilter,所以firewall-cmd添加的东西iptables也能看到
一条iptables命令:iptables -t filter -A INPUT -p tcp –source 192.168.71.188 –dport 22 -j ACCEPT
我们换成fireall-cmd格式如下,执行后,再用iptables查看一下发现是可以看到的
firewall-cmd --list-all
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.71.18" port port="22" protocol="tcp" accept'
参数--permanent是为了使得这条规则永久生效,如果没有这个参数,那么当系统重启后,添加的这条规则就会消失。
为了让新的规则应用到实际的网络流量中,还需要额外执行一条命令对防火墙配置进行重新加载:
firewall-cmd --reload
这个命令会使修改后的防火墙规则立即生效。
firewall-cmd –list-all
删除规则
[root@localhost ~]# firewall-cmd --list-all 。。。 rule family="ipv4" source address="192.168.71.18" port port="22" protocol="tcp" accept # 删除时,把上面看到的规则贴到--remove-rich-rule的引号里就行,并且记住要--reload才能生效 [root@localhost ~]# firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.71.18" port port="22" protocol="tcp" accept' [root@localhost ~]# firewall-cmd --reload
iptables -t filter -nL也可以看到(在centos7中还可以看到,在centos9中就看不到了,并且centos9会明确告诉你用iptables操作防火墙规则马上就不再支持了)
更多内容参考:
iptables命令:https://www.cnblogs.com/linhaifeng/p/15979888.html
firewall-cmd: https://cloud.tencent.com/developer/article/1529105
六 一个有意思的案例
egon在百度时曾遇到过这么一个场景
背景:某台服务器上部署了对外公开的业务
问题:业务的访问速度,越来越慢,慢到一个接口的请求都需要花费2-5s不等
首次解决:
1、查看系统状态、负载、cpu、内存都没有明显的波动,内存用了60%-70%其实也还可以
但没管三七二十一,直接先加了一波硬件资源,
发现,真的屁用没用,好在没人发现我这么蠢的动作
二次解决:
现在开始沉下心来认真思考一下了,凡是应该动脑子,而不是闭着眼试
不过试试也有好处对吧哈哈哈哈,至少先确信是跟硬件资源没关系了哈哈哈
硬件资源够用的,那么问题必然是出在软件层面
开始整体性分析这台机器上都做过什么
1、应用软件问题的排除
尝试过,添加缓存让静态文件缓存到用户本地、加cdn,都没啥卵用,一样的慢
2、操作系统内核
这台机器为了为了防止一些爬虫、dos攻击、接口破解等问题,设置了多层防护,
其中在系统层面就用到了 本文介绍的防火墙,定制了一些脚本,定期分析系统状态、访问日志,
来添加防火墙规则,禁用ip
但是没用对添加行为做去重处理,导致大量的重复规则添加了到了系统防火墙中,一看内核防火墙
中有很多w条记录,具体多少w忘记了,但几万条肯定是有的,总之就是很多很多
而本文介绍的系统防火墙都本质走的都是内核netfilter,你添加的规则越多,对内核的处理压力越大,
但凡时一个数据包进入内核,都会经过netfilter过滤一遍,如果你的规则过多,
这会极大的降低内核的处理能力,所以就会出现,无论你其他环节怎么优化,接口处理速度就是很慢
因为系统内核慢下来了
写脚本,筛选重复规则,删除,速度立刻提了上来。于此同时内存也释放出来了很多