Firewalld
firewalld 是由Red Hat开发的一个防火墙守护进程。它默认使用nftables。来自项目主页
- Firewalld提供了一个动态管理的防火墙,支持网络/防火墙区域,用于定义网络连接或接口的信任级别。它支持IPv4、IPv6防火墙设置、以太网桥和IP集合。运行时和永久配置选项是分开的。它还为服务或应用程序提供了一个直接添加防火墙规则的接口。
安装
用法
您可以使用firewall-cmd命令行实用程序控制防火墙规则。
firewall-offline-cmd实用程序可以在firewalld未运行时使用。它具有与firewall-cmd相似的语法。
GUI作为firewall-config提供,它随firewalld软件包一起提供。
使用nftables后端时,firewalld不完全控制主机的防火墙。由于nftables允许通过表使用多个"命名空间",firewalld会将所有规则、集合和链限制在firewalld表中。Firewalld不会完全刷新防火墙规则,它只会刷新firewalld表中的规则。
nftables允许多个链在同一时间点挂接到netfilter。由链*接受*的数据包仍然受挂接到该挂钩类型并*丢弃*情况下的其他链的规则的影响,处理总是立即停止,并且没有其他挂钩会处理该数据包。为了确保链的执行顺序具有可预测性,firewalld赋予其规则的优先级比默认nftables挂钩优先级值稍低。因此,在firewalld之外创建的防火墙规则(例如,由libvirt、Docker、Podman、systemd-nspawn等)将在firewalld规则之前被处理,并且由它们接受的数据包仍将受到firewalld规则的约束。
配置
可以使用firewall-cmd在运行时更改配置。
- 使用
--permanent选项。这将在防火墙服务重启或使用--reload命令重新加载规则之前*不会*更改运行时配置。 - 更改运行时配置并将其永久化,如#将运行时配置转换为永久配置中所述。
区域
区域是规则的集合,可以应用于特定的接口。
要对当前区域及其应用到的接口进行概述
# firewall-cmd --get-active-zones
一些命令(例如添加/移除端口/服务)需要指定一个区域。
可以通过传递--zone=zone_name参数按名称指定区域。
如果没有指定区域,则假定为默认区域。
区域信息
您可以列出所有区域及其完整的配置
# firewall-cmd --list-all-zones
或者仅列出特定区域
# firewall-cmd --info-zone=zone_name
更改接口区域
# firewall-cmd --zone=zone --change-interface=interface_name
其中zone是您想分配给接口的新区域。
使用NetworkManager管理区域
NetworkManager可以将不同的连接配置文件分配给不同的区域。例如,这允许将家庭Wi-Fi连接添加到“home”区域,工作Wi-Fi连接添加到“work”区域,所有其他Wi-Fi连接添加到默认的“public”区域。
列出连接配置文件
$ nmcli connection show
将“myssid”配置文件分配给“home”区域
$ nmcli connection modify myssid connection.zone home
默认区域
当连接新接口时,将应用默认区域。您可以使用以下命令查询默认区域的名称
# firewall-cmd --get-default-zone
可以使用以下命令更改默认区域。
# firewall-cmd --set-default-zone=zone
服务
服务是与特定守护进程对应的预设规则。例如,ssh服务对应于SSH,并在分配给区域时打开22端口。
要获取可用服务的列表,请输入以下命令
# firewall-cmd --get-services
您可以查询特定服务的相关信息
# firewall-cmd --info-service service_name
向区域添加或移除服务
将服务添加到区域
# firewall-cmd --zone=zone_name --add-service service_name
移除服务
# firewall-cmd --zone=zone_name --remove-service service_name
端口
可以直接在特定区域打开端口。
# firewall-cmd --zone=zone_name --add-port port_num/protocol
其中protocol可以是tcp或udp。
要关闭端口,请使用--remove-port选项,并提供相同的端口号和协议。
NAT masquerade
Masquerading是一种*源NAT*形式,其中源地址在内核中创建防火墙规则时是未知的,而是动态修改数据包的源地址为其出口接口的主IP地址[1]。
# firewall-cmd --permanent --zone=public --add-masquerade
自1.0.0版本以来,要在不同的防火墙区域之间实现NAT masquerade,您必须创建一个新的策略对象,用于过滤它们之间的流量
# firewall-cmd --new-policy internal-to-public --permanent # firewall-cmd --permanent --policy internal-to-public --add-ingress-zone internal # firewall-cmd --permanent --policy internal-to-public --add-egress-zone public # firewall-cmd --permanent --policy internal-to-public --set-target ACCEPT
端口转发
如果您在路由器上配置了firewalld,并且已按上述方式启用了NAT masquerading,那么通过firewalld设置端口转发很简单
# firewall-cmd --zone=public --add-forward-port=port=12345:proto=tcp:toport=22:toaddr=10.20.30.40
这将把防火墙公共接口上的端口12345/tcp转发到内部系统IP地址10.20.30.40上的端口22(标准SSH)。要移除此转发的端口
# firewall-cmd --zone=public --remove-forward-port=port=12345:proto=tcp:toport=22:toaddr=10.20.30.40
不幸的是,您必须输入完整的转发声明才能移除它,仅指定端口和协议是不够的。
富规则
使用富规则/富语言语法,可以以一种易于理解的方式创建更复杂的防火墙规则。
添加富规则
# firewall-cmd [--zone=zone_name] [--permanent] --add-rich-rule='rich_rule'
其中rich_rule是一个富语言规则。
例如,允许来自网络192.168.1.0/24到NFS服务的所有连接
# firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="nfs" accept'
允许来自192.168.2.3到端口1234/tcp的连接
# firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.2.3" port port="1234" protocol="tcp" accept'
有关更多富语言语法,请参阅firewalld.richlanguage(5)。
移除富规则
# firewall-cmd [--zone=zone_name] [--permanent] --remove-rich-rule='rich_rule'
技巧与提示
端口或服务超时
可以使用在添加命令期间传递的--timeout=value选项,在有限的时间内添加服务或端口。值是秒数,如果以m结尾是分钟,以h结尾是小时。例如,添加SSH服务3小时
# firewall-cmd --add-service ssh --timeout=3h
将运行时配置转换为永久配置
您可以使运行时(当前临时)配置永久化(这意味着它在重启后仍然存在)
# firewall-cmd --runtime-to-permanent
检查服务详细信息
默认支持的服务配置文件位于/usr/lib/firewalld/services/,用户创建的服务文件将位于/etc/firewalld/services/。
移除applet/系统托盘图标
该applet与firewalld不是分开打包的。位于/etc/xdg/autostart/firewall-applet.desktop的自动启动脚本可以被隐藏,但是:请参阅XDG Autostart#Directories。或者,通过将其添加到/etc/pacman.conf中的NoExtract来排除该文件不被安装。
故障排除
IPv6反向数据包过滤丢弃合法数据包
firewalld实现了一个IPv6反向数据包过滤器,该过滤器默认设置为严格模式。不幸的是,如果多个接口连接到同一个网络(例如,笔记本电脑同时连接有线和无线),则只有其中一个接口,由随机选择,会被反向路径查找返回。其他接口上的传入数据包将被丢弃。由于IPv4和其中一个IPv6启用的接口仍然工作,这往往会表现为间歇性连接问题,如连接尝试挂起或偏好较差的接口。通过在每个接口上运行ping -6 archlinux.org -I interface并观察只有其中一个接口获得任何响应,可以验证此问题。
解决方法是将反向路径过滤设置更改为松散模式。此设置仅检查反向路径是否存在,并与默认的IPv4反向路径过滤设置匹配(不由firewalld实现,但由内核实现并通过systemd配置)。
/etc/firewalld/firewalld.conf
... IPv6_rpfilter=loose ...