From Fedora Project Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

使用 FirewallD 构建动态防火墙

FirewallD 提供了支持网络/防火墙区域(zone)定义网络链接以及接口安全等级的动态防火墙管理工具。它支持 IPv4, IPv6 防火墙设置以及以太网桥接,并且拥有运行时配置和永久配置选项。它也支持允许服务或者应用程序直接添加防火墙规则的接口。 以前的 system-config-firewall/lokkit 防火墙模型是静态的,每次修改都要求防火墙完全重启。这个过程包括内核 netfilter 防火墙模块的卸载和新配置所需模块的装载等。而模块的卸载将会破坏状态防火墙和确立的连接。


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

守护进程通过 D-BUS 提供当前激活的防火墙设置信息,也通过 D-BUS 接受使用 PolicyKit 认证方式做的更改。

“守护进程”

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

通过所谓的直接接口,其他的服务(例如 libvirt )能够通过 iptables 变元(arguments)和参数(parameters)增加自己的规则。

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

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

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

在软件安装,初次启动或者是首次联网时,将会出现一个选择器。通过它你可以选择要使用的防火墙方案。其他的解决方案将保持完整,可以通过更换模式启用。

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

什么是区域?

网络区域定义了网络连接的可信等级。这是一个一对多的关系,这意味着一次连接可以仅仅是一个区域的一部分,而一个区域可以用于很多连接。 大多数区域是可变的,但是也有一些不可变的区域。不可变区域不能定制,并且也没有办法对它们进行重载。

预定义的服务

服务是端口和/或协议入口的组合。备选内容包括 netfilter 助手模块以及 IPv4、IPv6地址。

端口和协议

定义了 tcp 或 udp 端口,端口可以是一个端口或者端口范围。

ICMP 阻塞

可以选择 Internet 控制报文协议的报文。这些报文可以是信息请求亦可是对信息请求或错误条件创建的响应。

伪装

私有网络地址可以被映射到公开的IP地址。这是一次正规的地址转换。

端口转发

端口可以映射到另一个端口以及/或者其他主机。

哪个区域可用?

由firewalld 提供的区域按照从不信任到信任的顺序排序。

丢弃 (不可变)

任何流入网络的包都被丢弃,不作出任何响应。只允许流出的网络连接。

阻塞 (不可变)

任何进入的网络连接都被拒绝,并返回 IPv4 的 icmp-host-prohibited 报文或者 IPv6 的 icmp6-adm-prohibited 报文。只允许由该系统初始化的网络连接。

公开

用以可以公开的部分。你认为网络中其他的计算机不可信并且可能伤害你的计算机。只允许选中的连接接入。(You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.)

外部

用在路由器等启用伪装的外部网络。你认为网络中其他的计算机不可信并且可能伤害你的计算机。只允许选中的连接接入。

隔离区(dmz)

用以允许隔离区(dmz)中的电脑有限地被外界网络访问。只接受被选中的连接。

工作

用在工作网络。你信任网络中的大多数计算机不会影响你的计算机。只接受被选中的连接。

家庭

用在家庭网络。你信任网络中的大多数计算机不会影响你的计算机。只接受被选中的连接。

内部

用在内部网络。你信任网络中的大多数计算机不会影响你的计算机。只接受被选中的连接。

受信任的 (不可变)

允许所有网络连接。




计划和提议功能

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 (进度)

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