Firewalld 防火墙常用指令教程-常用规则(禁止Ping | 放行端口)
- Linux的Firewalld防火墙
- 1.
firewalld
防火墙简介 - 2. 安装
firewalld
防火墙 - 3. 使用
firewall-cmd
进行管理 - 4. 使用富规则配置复杂
firewalld
策略
使用防火墙可以对外部的数据包进行过滤和阻止,尽可能减少暴露在网络上的危险以保护系统安全。在RHEL7
系的Linux系统中,已经将iptables
防火墙管理工具使用firewalld
代替。这篇文章的所有案例在RHEL8
上成功执行,如果遇到了问题请尝试变通或者在底部评论区与我留言。噗!这是我第一次做标题党哈哈哈。
更新日期:2020年3月4日(富规则配置举例、增加富规则中的icmp-type
过滤规则、优化了一些细节错误)。常见用法已经全部写在文章中,之后会不定期更新细节。
1. firewalld
防火墙简介
firewalld
提供了一个动态管理的防火墙,在对防火墙规则修改时不需要断开连接就可以激活规则,并且支持网络区域zones
,用来分配一个网络及相关连接一种程度上的信任。它已经对IPv4
和IPv6
进行支持。并且可以选择对规则临时或永久修改。
本文使用的firewalld
版本:0.7.0
1.1. firewalld
与iptables
的主要区别
iptables
在/etc/sysconfig/iptables-config
文件中存储配置。firewalld
在/etc/firewalld/
下存储XML配置文件。使用
iptables
时每一个规则的更改意味着要清除所有旧的规则,然后从/etc/sysconfig/iptables-config
配置文件中读取所有新的规则并载入。然而使用firewalld
可以临时的将新添加的规则载入使用,不会像iptables
一样丢失连接。
使用iptables
命令行和firewalld
工具和内核的NetFilter
(内核防火墙框架)的交互示意图如下。
可以看出
NetFilter
才是真正的“防火墙”,它是Linux操作系统核心层内部的一个数据包处理框架,由图可以看出,不论是iptables
命令行工具还是firewalld
工具,它们都会通过iptables command
与NetFilter
(内核防火墙框架)放出来的接口实现沟通并使防火墙的规则生效。
1.2. 对firewalld
Zone网络区的理解
基于对网络中的设备和通信所给予的信任程度不同,firewalld
防火墙可以用来将网络分割成不同的区域。
使用firewall-cmd --get-zones
查看默认提供的zone
,这些zone
提供了一些基本的规则,也可以修改并保存规则。比如在工作单位时我切换到home
Zone来屏蔽大多数让我分心的网络连接,然而回家后我需要娱乐娱乐,此时我将Zone改为home
或者我信任我家里的网络并且改为了trust
Zone,这样又可以悠闲的享受那些娱乐网站咯。
Zone类型 | 说明 | |
---|---|---|
block | 封锁 | 任何的连接都会被拒绝接收,并返回icmp(6)-host-prohibited 拒绝信息 |
dmz | 非军事区 | 处于此区域的设备可以公开访问,可以有限制的进入内部网络,仅接收经过选择的连接 |
drop | 抛弃 | 接收到的任何连接都会被悄无声息的抛弃掉,不返回任何相应,仅允许对外发出的连接 |
external | 外部 | 不信任来自网络的所有连接,仅接收经过选择的连接 |
home | 家庭区 | 用于家庭网络。信任网络中的大多数连接,仅接收经过选择的连接 |
internal | 内部 | 与home提供的默认规则相同 |
public | 公共 | 不能相信网络内的其他计算机不会对您的计算机造成危害,仅接收经过选择的连接 |
trust | 信任 | 可以接受任何的网络连接 |
work | 工作 | 与public提供的默认规则相同 |
上面的所有Zones每个网络接口可以使用一个Zone作为当前Zone。当接入网络连接后,NetWorkManager
将被分配为你设定好的默认Zone网络区,firewalld
默认的网络区为public
。
2. 安装firewalld
防火墙
安装firewalld
需要以root用户身份执行下面的命令,并且执行firewalld
命令时也要使用root用户身份执行。
dnf install firewalld
如果你安装了系统图形界面,并且也想使用图形化工具来管理firewalld
,请执行如下命令。
dnf install firewall-config
但是本文中不会涉及到使用图形化工具配置firewalld
防火墙
2.1. 启动防火墙
设置firewalld
防火墙为默认防火墙并随着系统启动服务
systemctl enable firewalld
启动防火墙
systemctl start firewalld
如果对
systemctl
命令不了解,可以在浏览守护进程和控制服务相关博文。
2.2. 检查防火墙是否运行
systemctl status firewalld.service
1 | systemctl status firewalld.service |
使用firewall-cmd --state
也可以查看防火墙运行状态
1 | firewall-cmd --state |
3. 使用firewall-cmd
进行管理
3.1. Zone网络区管理
3.1.1. 查看所有Zone网络区
firewall-cmd --list-all-zones
列出所有Zone的配置规则
1 | firewall-cmd --list-all-zones |
还可以精简的只输出Zone的名字
firewall-cmd --get-zones
3.1.2. 查看firewalld
默认Zone
firewall-cmd --get-default-zone
1 | firewall-cmd --get-default-zone |
3.1.3. 查询某个网络接口上使用的Zone
firewall-cmd --get-zone-of-interface=XXXX
1 | firewall-cmd --get-zone-of-interface=ens32 # 这里查看ens32网络接口当前的Zone |
3.1.4. 查看已激活的Zone的网络接口列表
firewall-cmd --get-active-zones
1 | firewall-cmd --get-active-zones |
3.1.5. 查询某一个Zone的详细规则信息
firewall-cmd --zone=public --list-all
1 | firewall-cmd --zone=public --list-all |
3.1.6. 修改当前默认的Zone网络区
比如设置默认网络区为public
,更改会立即生效。此时此刻,所有接口上默认绑定的Zone网络区都会切换到新的这个public
Zone网络区上。
firewall-cmd --set-default-zone=public
3.1.7. 修改网络接口上的Zone网络区
如果有许多网络接口,要更改当前ens32
网络接口绑定的Zone网络区为home
,可以执行如下命令。
firewall-cmd --zone=home --change-interface=ens32
3.1.8. 删除绑定在网络接口上的Zone网络区
如果你不想让某以网络接口绑定到任何的网络区上,你可以执行如下命令。但是这么做无异于裸奔在网络世界中!
firewall-cmd --remove-interface=ens32
1 | firewall-cmd --remove-interface=ens32 |
实际上任何一个网络接口都要绑定一个Zone网络区,如果将绑定的网络区删除,在
reload
firewall规则后会发现刚刚删除Zone的网络接口自动绑定到了trusted
的Zone网络区,也就是说不受到防火墙的任何规则限制,比较危险。
3.2. 重新加载firewalld
防火墙
3.2.1. 不中断用户连接
通常在对规则添加--permanent
永久生效的选项后,规则不会立即生效,需要重新加载防火墙后配置的永久规则才会生效。在不中断用户现有的连接的情况下,建议使用firewall-cmd --reload
来重新加载防火墙。
firewall-cmd --reload
3.2.2. 完全重载防火墙,并断开现有的用户连接
通常在firewalld
防火墙出现问题时才会使用这种方式重载防火墙,这种方式会断开现有的网络连接,即丢失状态信息!
firewall-cmd --complete-reload
3.3. 打开/关闭防火墙端口(放行端口)
如果本地需要开放一个端口供外部访问,那么你可以将这个端口添加到某一网络区的放行端口规则中。
3.3.1. 打开防火墙端口(放行端口)
firewall-cmd --add-port=portid[-portid]/protocol [--permanent] [--zone=zone]
参数(portid[-portid]):要开放的端口号,如果是一个范围则使用10000-12000
表达一个范围。
参数(protocol):TCP/UDP协议
可选参数(zone):将规则添加到哪个Zone网络区中,如果缺省该参数则添加到默认Zone网络区中。
可选选项(–permanent):规则永久保存,重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效,但是重新加载防火墙后规则会失效。
1 | firewall-cmd --add-port=6000-7000/tcp --permanent --zone=public # 在public网络区下放行6000~7000之间TCP通信协议的网络端口(闭区间),规则永久保存并且在下一次重新加载防火墙后生效。 |
下面在默认的网络区内永久放行单个TCP端口
1 | firewall-cmd --add-port=6000/tcp --permanent # 这里没有添加`--zone`的选项和参数,会自动添加到默认网络区中。 |
3.3.2. 关闭防火墙端口(关闭端口)
刚刚已经将端口放行,并且暴露在外。如果需要这个端口的服务不再使用,出于安全考虑你可以将这个端口从放行规则中删除掉。
firewall-cmd --remove-port=portid[-portid]/protocol [--permanent] [--zone=zone]
参数(–remove-port=portid[-portid]/protocol):你要移除的端口号/端口范围,注意表明是TCP协议还是UDP协议哦。和你添加的时候一样,如果添加时你写的是一个端口范围,那么删除时只能将全部的端口范围删除掉,不能只删除端口范围中一部分端口。
可选参数(–zone=zone):关闭指定网络区中的端口,如果缺省该参数,则从默认的网络区中删除端口。
可选选项(–permanent):规则永久保存,重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效,但是重新加载防火墙后规则会失效。
1 | firewall-cmd --remove-port=8080/tcp --permanent #关闭默认Zone网络区开放的TCP8080端口 |
3.4. 放行/关闭防火墙某一服务(放行服务)
firewalld中存储了常见服务的默认端口信息,如果你的服务没有更改过默认的端口号,那么可以直接使用firewald
放行服务,它会根据默认规则,自动放行一个或一组此服务需要的端口。只需要管理员来记忆服务名就好咯!
3.4.1. 查看所有支持的服务
firewall-cmd --get-services
你能看到所有firewald存储的默认服务端口号,如果此时你需要开启某一服务的端口就不需要记他们默认的端口号了,试试firewall-cmd --add-service=XXXX
。
3.4.2. 查询服务端口详细信息
刚才查询到了所有支持的服务,那firewalld给我们提供的默认服务的端口号究竟是啥呢?
firewall-cmd --permanent --service=https --get-port
返回443/tcp
。
3.4.3. 放行服务端口
firewall-cmd --add-service=service [--permanent] [--zone=zone] [--timeout=timeval]
参数(–add-service):要放行的服务名,如ssh、http、https。
可选参数(–zone=zone):将此规则添加到网络区,如果缺省该参数,添加到默认网络区内。
可选参数(–timeout=timeval):临时生效时间,不可与--permanent
连用。表达方式可以是--timeout=[100s | 100m | 100h]
。(timeval is either a number (of seconds) or number followed by one of characters s(seconds), m(minutes), h(hours))
可选选项(–permanent):规则永久保存,重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效,但是重新加载防火墙后规则会失效。
1 | firewall-cmd --add-service=https --permanent #永久放行在默认网络区内的https(443端口)服务 |
3.4.4. 关闭服务端口
如果关闭某一服务所对应的端口,那么将会时该服务无法对外部提供服务,请确定好删除的服务名,以免影响业务的正常服务!
你可以通过firewall-cmd --list-all
查看默认网络区下,当前开放了哪些服务与规则,确保在关闭之前,这些服务和端口是开放的状态。
firewall-cmd --remove-service=https [--permanent] [--zone=zone]
参数与规则与关闭端口类似,在此不再赘述。
3.5. 端口转发
端口转发可以将到达某一端口的数据包转发到本机或其他机器上另一个的一个端口上。使用端口转发功能需要现开启firewalld
的IP伪装功能。
使用firewall-cmd --list-forward-ports
可以查询所有端口转发规则。
3.5.1. 开启IP伪装
防火墙可以实现IP伪装,默认为关闭状态。可以使用firewall-cmd --query-masquerade
进行查询。
firewall-cmd --query-masquerade
查询默认Zone网络区内的ip伪装功能是否开启。
返回no
则为关闭状态。
firewall-cmd --add-masquerade [--permanent] [--zone=zone] [--timeout=timeval]
参数(–add-masquerade):开放IP转发功能。
可选参数(–zone=zone):将此规则添加到网络区,如果缺省该参数,添加到默认网络区内。
可选参数(–timeout=timeval):临时生效时间,不可与--permanent
连用。表达方式可以是--timeout=[100s | 100m | 100h]
。
可选选项(–permanent):规则永久保存,重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效,但是重新加载防火墙后规则会失效。
如果不需要IP地址伪装,使用下面的命令关闭。
firewall-cmd --remove-masquerade [--permanent] [--zone=zone]
3.5.2. 开启端口转发
请确保在开启端口转发前已经开启IP伪装功能。如果需要IPv6
的端口转发,请富规则方式配置。
firewall-cmd --add-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] [--permanent] [--zone=zone] [--timeout=timeval]
参数(–add-forward-port):
1 | portid:本机端口号 |
可选选项(–permanent):规则永久保存,重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效,但是重新加载防火墙后规则会失效。
其他参数不再赘述。
下面是一些使用端口转发的案例:
1 | firewall-cmd --add-masquerade # 开启IP伪装(转发到其他IP上时必须开启,仅转发本地端口则非必须开启) |
3.5.3. 关闭端口转发
使用 firewall-cmd --list-forward-ports
查询当前已加载所有的端口转发规则
1 | firewall-cmd --list-forward-ports #查询当前已加载所有的端口转发规则 |
当不需要这个规则时我们可以删除它。
firewall-cmd --remove-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] [--permanent] [--zone=zone] [--timeout=timeval]
参数部分不再解释。与添加时的意思相对应。可以先查询规则,确定好你要删除的规则后将规则填写到--remove-forward-port=
后即可。
注意:如果你添加端口转发规则时,选择了
--permanet
永久生效,那么在永久删除时也要添加上--permanet
选项。除非是想临时取消此这条规则。
1 | firewall-cmd --list-forward-ports #查询当前已加载所有的端口转发规则 |
4. 使用富规则配置复杂firewalld
策略
通过rich language
语法,可以建立复杂防火墙规则。并且还可以永久生效。这种语言使用关键词值,是 iptables
工具的抽象表示。
4.1. 富规则的命令格式
1 | firewall-cmd --add-rich-rule='rule' [--permanent] [--zone=zone] [--timeout=timeval] |
一条富规则绑定在一个Zone网络区下,一个网络区可以绑定多条富规则。如果几个规则相互影响或者冲突,则匹配第一条规则。
4.2. 理解多规则命令
4.2.1. family
[family="<rule family>"]
family rule
可以是IPv4或者IPv6,将对选择的流量进行限制。此处的参数可以省略不填写,但是source
或者destination
中出现了IP地址,则必须填写并指定rule
。省略则同时对IPv6和IPv4进行限制。
4.2.2. source
[ source [not] address="<address>" ]
源地址,不支持主机名。源地址可以是一个IPv4地址或IPv6地址或者一个网络地址段。可以使用not
写在地址前来反转你的地址所表达的限定范围。
4.2.3. destination
[ destination [not] address="<address>" ]
限制目标地址,与源地址使用相同的表示方法,同样支持not
反转。
4.2.4. element
element
为限定的规则。该项只能为下面的几个要素之一,不能将他们同时进行应用。根据你的需求选取一个要素进行限制。
4.2.4.1. service服务名称
此处填写firewalld
默认提供的服务名称。获取firewalld默认提供的服务清单可以使用此命令firewall-cmd --get-services
,也可以看上面的3.4章节了解firewalld内置服务。
service name="server"
4.2.4.2. port端口
port port=number_or_range protocol="tcp | udp"
number_or_range
端口既可以是一个端口号,也可以是一个端口范围,如6000-7111
。protocol
协议可以指定为tcp
或udp
。
4.2.4.3. protocol协议
protocol value=protocol_name_or_ID
protocol_name_or_ID
可以是一个协议名,也可以是协议ID,可以在/etc/protocols
文件中查看预设支持的协议。
4.2.4.4. icmp-block阻断
icmp-block name=icmptype_name
icmptype_name
为特定的icmp类型名,使用icmp-block
元素可以禁止一个或多个ICMP类型。所有的ICMP类型可以使用firewall-cmd --get-icmptypes
命令来查看。
4.2.4.5. icmp-type类型
此处可以为所选的icmp类型指定动作。
4.2.4.6. masquerade IP地址伪装
规则里的IP伪装。用源地址而不是目的地址来把伪装限制在一个范围内。
4.2.4.7 forward-port端口转发
forward-port port=number_or_range protocol=protocol to-port=number_or_range to-addr=address
number_or_range
可以是一个端口号或者端口范围。protocol
UDP/TCP协议。address
目的IP地址。
与firewall-cmd --add-forward-port
语法相近。如果省略address
,则为本地端口转发。
4.2.5. log日志
log [prefix=prefix text] [level=log level] limit value=rate/duration
记录访问请求。你可以指定日志记录等级,log level
记录等级可以是 emerg,alert,crit,error,warning,notice,info 或者 debug 中的一个。
rate/duration
,rate为次数,duration是持续时间,单位可以是s,m,h,d。最大限定值是 1/d ,意为每天最多有一条日志进入。
4.2.6. Action动作(accept|reject|drop)
使用accept
所有新的连接请求都会被允许。使用reject
连接将被拒绝,对方将会收到一个拒绝信息。使用drop
所有数据包会被丢弃,并且不会返回任何消息给对方。
4.3. 删除富规则
删除富规则与删除端口转发类似,直接将添加富规则的语言规则填写到--remove-rich-rule
选项里。首先应该查询目前所有生效的富规则。
4.3.1 查询所有富规则
firewall-cmd --list-rich-rules
之后会以一行行的形式返回每一条富规则。
4.3.2 删除富规则
firewall-cmd --remove-rich-rule='rule' [--permanent]
将查询到要删除的富规则复制到--remove-rich-rule=
参数后面,以防止输入出错。如果想永久删除,那么您需要添加--permanent
选项以永久保存。如果你在添加富规则时仅仅是临时生效,那么不应该填写此选项。
1 | firewall-cmd --list-rich-rules # 显示所有生效的富规则 |
4.4. 富规则配置实例
4.4.1 阻止echo-request
请求
阻止ICMP协议中的echo-request
也就是我们常说的禁止Ping。
firewall-cmd --add-rich-rule='rule icmp-type name="echo-request" drop' --permanent
使用Drop动作可以伪装成无法联系到主机的效果。
4.4.2 拒绝某一IP(段)访问本机ftp服务
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" service name="ftp" reject' --permanent
永久拒绝IP来自10.0.1.*的客户访问本机FTP服务器。
firewall-cmd --add-rich-rule='rule family="ipv6" source address="2409:8a18:600:b250::239" service name="ssh" log limit value="1/m" drop' --permanent
永久拒绝来自2409:8a18:600:b250::239的用户远程登录到本机SSH服务器,并且以每分钟一次的速率进行日志记录。
4.4.3 使用富规则进行端口转发
永久对当IP来自为192.168.1.175用户访问本机22端口时,将流量转发至192.168.1.3的22号tcp端口上。注意需要开启IP地址伪装,重载防火墙规则后生效。
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.175" forward-port port="22" protocol="tcp" to-addr="192.168.1.3"' --permanent
开启IP地址伪装,否则无法将流量转发到其他IP上。
firewall-cmd --add-masquerade --permanent
4.4.4 丢弃来自某IP域的所有连接
firewall-cmd --add-rich-rule='rule family="ipv4" source address="172.23.0.0/16" drop'
丢弃来自172.23.0.0/16
网段下的所有连接。
基本内容基本已经完成,后续会继续更新细节的地方。不过更新速度可能会慢一些了。如果第一时间想要得到最新更新消息可以加入我的电报群!同时如果您发现了文章中的任何处存在错误,请您务必与我联系,我会及时更改防止继续误导别人,在此表示十分感谢!
参考文章
我是一名Linux初学者,如果你与我一样喜欢折腾,喜欢Linux,那么请加入我的电报群:
https://t.me/yeefire_blog(Telegram),在这里畅所欲言,共同学习进步。