关于 Linux 中 firewalld 的一些笔记整理

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波

写在前面


  • 嗯,今天和小伙伴们分享一些 firewall 的笔记
  • 内容涉及:
    • zone 的介绍具和具体规则的添加
    • 服务,端口和协议,ICMP 阻塞,SNAT/DNAT,IP伪装,端口转发等Demo
    • firewall 离线命令(服务未启动规则预设方式)
  • 理解不足小伙伴帮忙指正

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。——–王小波


系统服务 firewalld 主要用于 管理防火墙链和规则,相对于 iptables.services ,它更灵活,表意性更强。对应的管理工具:firewall-cmd、firewall-config。

需要说明的是,如果你在启动 firewalld 服务之前,使用 ipatables 添加了一些防火墙规则,那么,在启动后,添加的规则会消失。 iptables 是一个 内核命令。他不需要任何服务就可以使用 ,而 iptables.servicefirewalld.service 是用于 管理 iptables 链和规则的工具,它们存在的意义即可以在系统启动时自动加载保存的防火墙规则,在关机时卸载对应的规则。 单纯的通过 iptables 命令设置的 防火墙规则是基于内存的,类似 /proc 目录一样,会随着系统重启消失。

所以如果你通过命令 iptables 配置了对应的规则。那么在开启 firewalld 之前一定要导出 之前配置的 iptables 规则。

1
2
┌──[root@vms152.liruilongs.github.io]-[~]
└─$iptables-save > ips

先来看下区域这个概念:

什么是区域?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
What is a zone?
A network zone defines the level of trust for network connections. This is a one to many
relation, which means that a connection can only be part of one zone, but a zone can be used
for many network connections.

The zone defines the firewall features that are enabled in this zone:

Predefined services
A service is a combination of port and/or protocol entries. Optionally netfilter helper
modules can be added and also a IPv4 and IPv6 destination address.

Ports and protocols
Definition of tcp or udp ports, where ports can be a single port or a port range.

ICMP blocks
Blocks selected Internet Control Message Protocol (ICMP) messages. These messages are
either information requests or created as a reply to information requests or in error
conditions.

Masquerading
The addresses of a private network are mapped to and hidden behind a public IP address.
This is a form of address translation.

Forward ports
A forward port is either mapped to the same port on another host or to another port on
the same host or to another port on another host.

Rich language rules
The rich language extends the elements (service, port, icmp-block, masquerade,
forward-port and source-port) with additional source and destination addresses, logging,
actions and limits for logs and actions. It can also be used for host or network white
and black listing (for more information, please have a look at
firewalld.richlanguage(5)).

For more information on the zone file format, please have a look at firewalld.zone(5).

帮助文档查看

1
2
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$man firewalld.zones| cat

区域用于定义了在该区启用的防火墙功能:一个网络区域定义了网络连接的信任级别。这是一种一对多的的关系,这意味着一个连接只能是一个区域的一部分,但一个区可以被用于许多网络连接。可以把区域理解为一堆防火墙规则的别名。这些规则可以是常见的:服务,端口和协议,ICMP 阻塞,NAT,IP伪装,端口转发

查看当前防火墙的默认区域

1
2
3
4
5
6
┌──[root@vms153.liruilongs.github.io]-[~]
└─$firewall-cmd --state
running
┌──[root@vms153.liruilongs.github.io]-[~]
└─$firewall-cmd --get-default-zone
trusted

可以设置的区域

1
2
3
┌──[root@vms153.liruilongs.github.io]-[~]
└─$ firewall-cmd --get-zones
block dmz drop external home internal public trusted work

这些是由 firewalld 提供的区域,根据区域的默认信任级别从不受信任到受信任排序:

  • drop:任何传入的网络数据包都被丢弃,没有回复。只能进行传出网络连接。
  • block:任何传入的网络连接都会被 icmp-host-prohibited 消息拒绝,IPv4 和 icmp6-adm-prohibited IPv6。只有在此系统内发起的网络连接是可能的。
  • public:用于公共场所。您不相信网络上的其他计算机不会损害您的计算机。仅接受选定的传入连接。
  • external:用于启用伪装的外部网络,尤其是路由器。您不相信网络上的其他计算机不会损害您的计算机。仅接受选定的传入连接。
  • dmz:对于您的非军事区中的计算机,这些计算机可公开访问,但对您的内部网络的访问权限有限。仅接受选定的传入连接。
  • work: 用于工作区域。您大多相信网络上的其他计算机不会损害您的计算机。仅接受选定的传入连接。
  • home:用于家庭区域。您大多相信网络上的其他计算机不会损害您的计算机。仅接受选定的传入连接。
  • internal:用于内部网络。您大多相信网络上的其他计算机不会损害您的计算机。仅接受选定的传入连接。
  • trusted:接受所有网络连接。

一般情况下,我们用的比较多是 trustedpublic 这两个区域。 trusted 一般用与添加类似黑名单一样的规则public 添加类似白名单规则,。

关于区域的其他的一些命令:

设置查看默认区域

1
2
3
4
5
6
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --set-default-zone=work
success
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --get-default-zone
work

指定网卡设置查看区域

1
2
3
4
5
6
7
8
9
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --get-zone-of-interface=ens32
no zone
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --zone=public --add-interface=ens32
success
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --get-zone-of-interface=ens32
public

查看所有网卡的区域

1
2
3
4
5
6
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --get-active-zones
public
interfaces: ens32
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

规则添加

设置好区域之后,我们需要添加对应的规则,这里我们以 publictrusted 这两个区域为例:

注意: 添加完规则一定要重载才可以使配置生效

当前在public 区域,我们期望运行一些端口通信或者服务,添加某些允许的规则

添加 允许服务通信

1
2
3
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --add-service=http
success

添加允许 端口/协议通信

1
2
3
4
5
6
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --add-port=30001/tcp
success
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --add-port=30005/udp
success

可以通过 firewall-cmd --list-all 查看当前端口的预设区域信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --list-all
trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources:
services: http
ports: 30001/tcp 30005/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks: timestamp-request timestamp-reply
rich rules:

┌──[root@vms152.liruilongs.github.io]-[~]
└─$

当前在 trusted 区域,我添加一些 icmp 协议的限制的规则,用于解决,ICMP 时间戳请求响应漏洞

添加 icmp-block 规则

1
2
3
4
5
6
7
8
9
10
11
12
┌──[root@vms16.liruilongs.github.io]-[~]
└─$firewall-cmd --add-icmp-block=timestamp-request --permanent
success
┌──[root@vms16.liruilongs.github.io]-[~]
└─$firewall-cmd --add-icmp-block=timestamp-reply --permanent
success
┌──[root@vms16.liruilongs.github.io]-[~]
└─$firewall-cmd --reload
success
┌──[root@vms16.liruilongs.github.io]-[~]
└─$firewall-cmd --list-icmp-blocks
timestamp-request timestamp-reply

查看区域的全部规则信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──[root@vms16.liruilongs.github.io]-[~]
└─$firewall-cmd --list-all
trusted
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks: timestamp-request timestamp-reply
rich rules:

配置 NAT

NAT 的出现,缓解了 IP 不够用的问题,使得我们可以通过 局域网访问到公网,实现私有 IP 到公共 IP 不同网段的访问,可以通过一台 Linux 机器,开启路由功能,通过 iptables 的 NAT 路由转发表实现。 使用 firewalld,可以配置以下网络地址转换(NAT)类型:

  • IP 伪装
  • 源 NAT,SNAT(Source Network Address Translation)
  • 目标 NAT(DNAT)
  • 重定向

需要做一些准备工作。开启 ipv4 的地址转发

1
2
3
4
5
6
7
┌──[root@vms152.liruilongs.github.io]-[~]
└─$echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
┌──[root@vms152.liruilongs.github.io]-[~]
└─$sysctl -p
net.ipv4.ip_forward = 1
┌──[root@vms152.liruilongs.github.io]-[~]
└─$

伪装和源 NAT(SNAT)

配置开启 IP 地址伪装

1
2
3
4
5
6
7
8
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --zone=external --add-masquerade
success
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --zone=external --query-masquerade
yes
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --zone=external --delete-masquerade --permanent

更改数据包的源 IP 地址。例如,互联网服务提供商不路由私有 IP 范围,如 10.0.0.0/8。如果您在网络中使用私有 IP 范围,并且用户应该能够访问 Internet 上的服务器,需要将这些范围内的数据包的源 IP 地址映射到公共 IP 地址。

比如提供的 公网 IP 为 39.27.24.141, 你通过这个公网 IP 请求服务,实际你在内网机器 192.168.26.3 上面发出请求,使用 NAT 做了映射,根据 参考模型,网络层会添加目标端和源端的 IP 地址,通过 路由寻址获取下一跳地址,但是你请求源端地址是 192.168.26.3 这个 私有 IP 地址,所以公网 IP 的服务,没办法响应你的请求,那这个时候你可以更改 192.168.26.3 这个私有 IP 为做 NAT 的对应公网,否则数据出的去,但是回不来。

伪装和 SNAT 相互类似。不同之处是:

  • 伪装自动使用传出接口的 IP 地址。因此,如果传出接口使用了动态 IP 地址,则使用伪装
  • SNAT 将数据包的源 IP 地址设置为指定的 IP 地址,且不会动态查找传出接口的 IP 地址。因此,SNAT 要比伪装更快。如果传出接口使用了固定 IP 地址,则使用 SNAT

配置 SNAT

内部访问外部,将source ipsrc_net网段来的数据包伪装成external区域对应的网卡的地址

rich规则

1
2
firewall-cmd --zone=external --permanent \
--add-rich-rule='rule family="ipv4" source address="<src_net/mask>" masquerade’

设置NAT规则也可实现(设置POSTROUTING),将 源IP 192.168.100.0/24 修改为 eth0 对应的IP地址,修改后的地址可以是 区域或者IP或则网卡

1
2
3
4
5
6
7
firewall-cmd --permanent --direct \
--passthrough ipv4 -t nat POSTROUTING -o eth0 -j MASQUERADE -s 192.168.100.0/24

firewall-cmd --permanent --direct \
--passthrough ipv4 -t nat -A POSTROUTING -s <internal_ip|internal_net/mask> -j SNAT --to-source <external_ip>
firewall-cmd --permanent --direct \
--passthrough ipv4 -t nat POSTROUTING -o ens0 -j MASQUERADE -s <internal_ip|internal_net/mask>

目标 NAT(DNAT)

使用此 NAT 类型重写传入数据包的目标地址和端口。例如,如果您的 Web 服务器使用私有 IP 范围内的 IP 地址,那么无法直接从互联网访问它,您可以在路由器上设置 DNAT 规则,以便将传入的流量重定向到此服务器。

1
2
firewall-cmd  --permanent --direct \
--passthrough ipv4 -t nat -A PREROUTING -d <external_ip> -j DNAT --to-destination <internal_ip>

重定向(端口转发)

这个类型是 IDT 的特殊示例,它根据链 hook 将数据包重定向到本地机器。例如,如果服务运行在与其标准端口不同的端口上,您可以将传入的流量从标准端口重定向到此特定端口。

将访问本机’external_port’端口流量转发到’internal_ip’

1
2
firewall-cmd --zone=external --permanent \
--add-forward-port=port=<external_port>:proto=tcp:toaddr=<internal_ip>

将访问本机’external_port’端口流量转发到’internal_ip’的’internal_port’

1
2
firewall-cmd --zone=external --permanent \
--add-forward-port=port=<external_port>:proto=tcp:toport=<internal_port>:toaddr=<internal_ip>

区域 Target和信任源IP

target是就是对该区域内流经的数据包作最终的处理动作,

1
firewall-cmd --zone=public --set-target=DROP 

要允许来自特定IP地址(或范围)的所有传入流量,使用–zone选项指定区域,并使用–add-source选项指定源IP

1
firewall-cmd --zone=public --add-source=192.168.100.10

防火墙区域预设(防火墙离线命令)

如果我们希望在防火墙启动之前设置相关区域,比如 K8s 集群中,在集群部署中我们关闭的 firewalld ,但是在之后的运维中我们需要开启防火墙,比如处理漏洞,那么这个时候我们可用通过 firewall-offline-cmd 命令来 在 firewalld 为启动之前设置区域或者规则。

注意的是:需要成为 root 用户才能使用 firewall-offline-cmd

  • firewall-offline-cmd 只能提供有关永久环境的信息,也可以更改它。它使用带文件 IO 处理程序的 firewalld 核心。
  • firewall-offline-cmd 可以在 firewalld 运行时使用,但不推荐使用。大约五秒钟后,使用 firewall-offline-cmd 所做的更改会在防火墙中可见。

帮助文档查看

1
2
┌──[root@vms152.liruilongs.github.io]-[~]
└─$man firewall-offline-cmd

看一个 Demo ,在运行的 k8s 集群中我们遇到了一个漏洞,解决这个漏洞需要开启防火墙。但是防火墙默认的区域是 public ,它会限制 k8s 的一些节点通信端口,并且会影响集群上的 SDN,所以我们需要在启动之前设置为 trusend

1
2
3
4
5
6
7
8
9
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --get-default-zone
FirewallD is not running
┌──[root@vms152.liruilongs.github.io]-[~]
└─$firewall-cmd --state
not running
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$firewall-offline-cmd --version
0.6.3

当前防火墙未启动,通过命令修改默认区域

1
2
3
4
5
6
7
8
9
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$firewall-offline-cmd --get-default-zone
public
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$firewall-offline-cmd --set-default-zone=trusted
success
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$firewall-offline-cmd --get-default-zone
trusted

然后我们启动防火墙,查看设置的区域

1
2
3
4
5
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$systemctl start firewalld.service
┌──[root@vms152.liruilongs.github.io]-[/var/spool]
└─$firewall-cmd --get-default-zone
trusted

博文参考

https://firewalld.org/documentation/zone/predefined-zones.html

https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/securing_networks/assembly_configuring-nat-using-firewalld_using-and-configuring-firewalld

https://blog.51cto.com/huanghai/2656485

发布于

2022-12-03

更新于

2023-06-21

许可协议

评论
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×