From Fedora Project Wiki

使用 FirewallD 构建动态防火墙

FirewallD 是使用 D-BUS 接口来提供防火墙动态管理的一个服务守护进程。

为何使用 Firewall Daemon

现在的防火墙模型是静态的,所有的变更都需要完全重启防火墙来实现(包括内核 netfilter 防火墙模块的卸载和新配置所需模块的装载等)。而模块的卸载将会破坏状态防火墙和确立的连接。

相反,firewall daemon 动态管理防火墙,不需要重启整个防火墙便可应用更改。因而也就没有必要重载所有内核防火墙模块了。不过,要使用 firewall daemon 就要求防火墙的所有变更都要通过该守护进程来实现,以确保守护进程中的状态和内核里的防火墙是一致的。另外,firewall daemon 无法解析由 ip*tables 和 ebtables 命令行工具添加的防火墙规则。

守护进程通过 D-BUS 提供当前激活的防火墙设置信息,也通过 D-BUS 接受使用 PolicyKit 认证方式做的更改。同样,SELinux 访问限制策略也在考虑之内。

“守护进程”

应用程序、守护进程和用户可以通过 D-BUS 请求启用一个防火墙特性。特性可以是预定义的防火墙功能,如:服务、端口和协议的组合、可信接口/主机/网络区域、端口/数据报转发、伪装、ICMP 拦截或自定义规则等。该功能可以启用确定的一段时间也可以再次停用。

添加了新的虚拟化、网络设置、服务、端口、伪装、端口转发,ICMP 过滤和虚拟化技术链,以使防火墙设置更加的自由、安全和强健。使用 firewall daemon 向其中一个链添加规则多半不会干扰其他链。链的顺序以及其如何使用是固定的。

amanda 、ftp 、samba 和 tftp 服务的 netfilter 防火墙助手也被“守护进程”解决了,只要它们还作为预定义服务的一部分。附加助手的装载不作为当前接口的一部分。由于一些助手只有在由模块控制的所有连接都关闭后才可装载。因而,跟踪连接信息很重要,需要列入考虑范围。

静态防火墙(system-config-firewall)

使用 system-config-firewall 的实际静态防火墙模型仍将提供并且可用,但却不能与“守护进程”同时使用。用户或者管理员可以决定使用哪一种方案。

在软件安装,初次启动或者是首次联网时,将会出现一个选择器。通过它你可以选择要使用的防火墙方案。如果选择 firewall daemon ,那么就会停用 ip*tables 服务和并禁用 system-config-firewall 选项。配置将保持不变,可以通过 "lokkit --enabled" 再次启用 s-c-fw 。

firewall daemon 独立于 system-config-firewall,但二者不能同时使用。

计划和提议功能

D-BUS 接口

D-BUS 接口提供防火墙状态的信息,使防火墙的启用、停用或查询设置成为可能。

防火墙抽象模型

在 ip*tables 和 ebtables 防火墙规则之上添加抽象层使添加规则更简单和直观。要抽象层功能强大,但同时又不能复杂,并不是一项简单的任务。为此,不得不开发一种防火墙语言。使防火墙规则拥有固定的位置,可以查询端口的访问状态、访问策略等普通信息和一些其他可能的防火墙特性。

系统和会话(用户)配置

防火墙系统配置是整个系统的基本配置,它可以通过会话层(用户)配置来改变。会话层配置又受到策略和系统管理员的限制。

永久和临时配置

永久防火墙设置是在系统和服务重启后仍然存在的设置。而临时设置在系统或服务重启后便会丢失。重载防火墙服务将恢复所有设置(永久的或临时的)。

托盘小程序

托盘小程序 firewall-applet 为用户显示防火墙状态和存在的问题。它也可以用来配置用户允许修改的设置。

图形化配置工具

firewall daemon 主要的配置工具是 firewall-config 。它支持防火墙的所有特性,但是只能读取 libvirt 和 NetworkManager 防火墙配置。 管理员也可以用它来改变系统或用户策略。

命令行客户端

firewall-cmd 是命令行下提供大部分图形工具配置特性的工具。

对于 ebtables 的支持

要满足 libvirt daemon 的全部需求,在内核 netfilter 级上防止 ip*tables 和 ebtables 间访问问题,ebtables 支持是需要的。由于这些命令是访问相同结构的,因而不能同时使用。

对于 conntrack 的支持

要终止禁用特性已确立的连接需要 conntrack 。不过,一些情况下终止连接可能是不好的,如:为建立有限时间内的连续性外部连接而启用的防火墙服务。

用户交互模型

这是防火墙中用户或者管理员可以启用的一种特殊模式。应用程序所有要更改防火墙的请求将定向给用户知晓,以便确认和否认。为一个连接的授权设置一个时间限制并限制其所连主机、网络或连接是可行的。配置可以保存以便将来不需通知便可应用相同行为。 该模式的另一个特性是管理和应用程序发起的请求具有相同功能的预选服务和端口的外部链接尝试。服务和端口的限制也会限制发送给用户的请求数量。

网络区域:网络安全模型

网络区域为网络连接定义可信级别。例如:公共 WIFI 网络连接应该不信任,而家庭有线网络连接就应该完全信任。 网络安全模型可以在安装、初次启动和首次建立网络连接时选择初始化。该模型描述了主机所联的整个网络环境的可信级别,并定义了新连接的处理方式。

有不同的初始化区域:

  - 家庭/工作
  - 公共
  - 特殊连接

家庭和工作区域拥有最高的可信级别。允许所有流入的连接。相反,公共区域是完全不可信的,应禁止所有流入的连接。特殊连接模型要求用户根据需要调整连接的可信级别(默认是不信任)。

用户或者管理员可以根据需要定义新的区域或改写最初区域以改变行为。

网络安全模型可以为所有的连接设置统一的可信级或者为不同连接不同信任级。

用户策略支持

管理员可以规定哪些用户可以使用用户交互模式和限制防火墙可用特性。

端口元数据信息(由 Lennart Poettering 提议)

拥有一个端口独立的元数据信息是很好的。当前对 /etc/services 的端口和协议静态分配模型不是个好的解决方案也没有反映当前使用情况。应用程序或服务的端口是动态的,因而端口本身并不能描述使用情况。

元数据信息可以用来为防火墙制定简单的规则。下面是一些例子:

 允许外部访问文件共享应用程序或服务
 允许外部访问音乐共享应用程序或服务
 允许外部访问全部共享应用程序或服务
 允许外部访问 torrent 文件共享应用程序或服务
 允许外部访问 http 网络服务

这里的元数据信息不只有特定应用程序,还可以是一组使用情况。例如:组“全部共享”或者组“文件共享”可以对应于全部共享或文件共享程序(如:torrent 文件共享)。这些只是例子,因而,可能并没有实际用处。

这里是在防火墙中获取元数据信息的两种可能途径:

第一种是添加到 netfilter (内核空间)。好处是每个人都可以使用它,但也有一定使用限制。还要考虑用户或系统空间的具体信息,所有这些都需要在内核层面实现。

第二种是添加到 firewall daemon 中。这些抽象的规则可以和具体信息(如:网络连接可信级、作为具体个人/主机要分享的用户描述、管理员禁止完全共享的应归则等)一起使用。

第二种解决方案的好处是不需要为有新的元数据组和纳入改变(可信级、用户偏好或管理员规则等等)重新编译内核。这些抽象规则的添加使得 firewall daemon 更加自由。即使是新的安全级也不需要更新内核即可轻松添加。

防火墙规则

netfilter 防火墙总是容易受到规则顺序的影响,因为一条规则在链中没有固定的位置。在一条规则之前添加或者删除规则都会改变此规则的位置。 在静态防火墙模型中,改变防火墙就是重建一个干净和完善的防火墙设置,且受限于 system-config-firewall / lokkit 直接支持的功能。也没有整合其他应用程序创建防火墙规则,且如果自定义规则文件功能没在使用 s-c-fw / lokkit 就不知道它们。默认链通常也没有安全的方式添加或删除规则而不影响其他规则。

动态防火墙有附加的防火墙功能链。这些特殊的链按照已定义的顺序进行调用,因而向链中添加规则将不会干扰先前调用的拒绝和丢弃规则。从而利于创建更为合理完善的防火墙配置。

下面是一些由守护进程创建的规则,过滤列表中启用了在公共区域对 ssh 和 ipp-client 的支持:

 *filter
 :INPUT ACCEPT [0:0]
 :FORWARD ACCEPT [0:0]
 :OUTPUT ACCEPT [0:0]
 :FORWARD_ZONES - [0:0]
 :FORWARD_direct - [0:0]
 :INPUT_ZONES - [0:0]
 :INPUT_direct - [0:0]
 :IN_ZONE_public - [0:0]
 :IN_ZONE_public_allow - [0:0]
 :IN_ZONE_public_deny - [0:0]
 :OUTPUT_direct - [0:0]
 -A INPUT -m conntrack --ctstate INVALID -j REJECT --reject-with icmp-host-prohibited
 -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 -A INPUT -i lo -j ACCEPT
 -A INPUT -j INPUT_direct
 -A INPUT -j INPUT_ZONES
 -A INPUT -p icmp -j ACCEPT
 -A INPUT -j REJECT --reject-with icmp-host-prohibited
 -A FORWARD -m conntrack --ctstate INVALID -j REJECT --reject-with icmp-host-prohibited
 -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
 -A FORWARD -i lo -j ACCEPT
 -A FORWARD -j FORWARD_direct
 -A FORWARD -j FORWARD_ZONES
 -A FORWARD -p icmp -j ACCEPT
 -A FORWARD -j REJECT --reject-with icmp-host-prohibited
 -A OUTPUT -j OUTPUT_direct
 -A IN_ZONE_public -j IN_ZONE_public_deny
 -A IN_ZONE_public -j IN_ZONE_public_allow
 -A IN_ZONE_public -j REJECT --reject-with icmp-host-prohibited
 -A IN_ZONE_public_allow -p tcp -m tcp --dport 22 -j ACCEPT
 -A IN_ZONE_public_allow -p tcp -m tcp --dport 631 -j ACCEPT

使用 deny/allow 模型来构建一个清晰行为(最好没有冲突规则)。例如: ICMP 块将进入 IN_ZONE_public_deny 链(如果为公共区域设置了的话),并将在 IN_ZONE_public_allow 链之前处理。

该模型使得在不干扰其他块的情况下向一个具体块添加或删除规则而变得更加容易。

有用的扩展

sysctld

现在仍有 sysctl 设置没有正确应用。一个例子是,在 rc.sysinit 正运行时,而提供设置的模块在启动时没有装载或者重新装载该模块时会发生问题。

另一个例子是 net.ipv4.ip_forward ,防火墙设置、libvirt 和用户/管理员更改都需要它。如果有两个应用程序或守护进程只在需要时开启 ip_forwarding ,之后可能其中一个在不知道的情况下关掉服务,而另一个正需要它,此时就不得不重启它。

sysctl daemon 可以通过对设置使用内部计数来解决上面的问题。此时,当之前请求者不再需要时,它就会再次回到之前的设置状态或者是直接关闭它。

开发阶段

这些是计划阶段,根据要求和需要可能会随时间变化。

阶段 1 :Fedora 15

Fedora 15 将包含一些增强功能实现的概念验证,并作为预览和测试版本。默认不会安装和启用。

下面列表包含的是 GIT 版本库(2010-12-22)的实际状态:

  • 支持几乎所有的 system-config-firewall 特性。不支持自定义规则文件,但支持使用定制接口定制简单规则
  • 支持 iptables,ip6tables 和 ebtables
  • 简单的显示防火墙状态的面板小工具,也可以用来启用或停用防火墙服务
  • 命令行客户端
  • 面板小工具和命令行客户端不能处理 libvirt 和 NetworkManager 规则
  • 没有永久性防火墙特性(规则在重启服务和重启系统时丢失,但重载时保存规则)
  • 只有系统配置,没有会话(用户)配置
  • firewall-config 实用工具功能不完善
  • sysctl 对 ip_forwarding 的更改没有实现
  • ip*tables 和 ebtables 规则访问冲突未解决
  • 对 firewalld 进行测试的 system-config-firewall 版本为 1.2.28

阶段 2 :Fedora 17 (进度)

  • D-BUS 接口的清除与扩充
  • 完成 firewall-applet 和 firewall-config
  • 永久和临时防火墙规则
  • 地域支持

阶段 3 :Fedora 18 (进度)

  • 用户交互模式
  • 用户策略支持
  • 增强服务(如:libvirt)和应用程序接口
  • 可能:用 C 语言重新实现服务器的系统和会话配置

阶段 4 :Fedora 19 (进度)

  • 端口元数据信息(要求更大的系统改变)