iptables - 使用服务名称或端口号、IP 地址或主机名?

HBr*_*ijn 6 networking linux firewall iptables nftables

iptables(和/或后续工具nftables)是用户空间实用程序,允许系统管理员配置 Linux 内核防火墙的 IP 数据包过滤规则,该规则作为不同的Netfilter 模块实现。(摘自维基百科

由于iptablesnftables是旨在由人们、系统管理员使用的用户空间实用程序,并且人们并不总是完全熟悉底层数字,因此它们接受 IP 协议(​​tcp、icmp、udp 等)的人类可读描述, IP 地址(主机名)和端口号(服务名称)。

从 UI 方面来看,使用人类可读的名称似乎是一件好事:

  • 作为一名管理员,我可能不是唯一一个能够更好地直观地理解:
    iptables --protocol udp
    与:iptables --protocol 17和类似的含义的人。
  • 主机名gateway.example.net通常比 IP 地址更有意义,例如192.0.2.1
  • 在 Web 服务器上,允许 HTTP 和 HTTPS 比允许 TCP/80 更明显。TCP/443。

这样做安全吗?

或者你应该远离它?

有什么注意事项?

HBr*_*ijn 11

效果可能并不总是如管理员所期望的。

一点背景:

Linux 内核中的netfilter模块对 IP 数据包进行操作。它们主要评估、处理和/或修改这些 IP 数据包的标头,通常不涉及数据部分(这更多的是深度数据包检测(DPI) 的领域)。

IP 数据包的标头不包含人类可读的名称,它们由IPprotocol number源和目的地IP-addressTCP 源和目的地port编号等组成。

为了实现最高效,Linux 内核中的数据包过滤器规则还与 IP 协议、端口号和 IP 地址的值一起存储,其格式与它们正在评估的数据包中的格式相同。

  • 当规则加载到内核中iptables并将nftables人类可读的输入转换为netfilter 内核模块所需并存储在其中的数值时。

  • 系统解析器用于转换协议、服务、网络名称和主机名。这使得实际的解析取决于您的配置(nsswitch.conf

  • iptables在运行命令时nftables将人类可读的输入转换为数值。

  • 只要没有显式刷新/删除/更新,生成的数字规则就会在内核中保持有效。

这也会产生一些并不立即明显的影响和/或后果。


使用协议名称iptables

一般来说,这是安全的,不会导致任何不必要的混乱。

默认情况下,该文件/etc/protocols用于将协议名称转换为协议编号iptables --protocol [human readable protocol name]

IP 协议名称(例如 UPD 和 TCP)不太可能引起混淆。


使用带有iptables或 的主机名nftables

默认文件/etc/networks可用于翻译 目的地和/或源中使用的网络名称。至少根据手册,我还从未见过有人在现实世界中使用过它。据我所知,getent networks network-name也没有提供返回网络掩码的方法,这使得使用网络名称不切实际。

默认文件/etc/hosts用于将主机名转换为目标和/或源中的 IP 地址,通常使用 DNS 作为后备。

不要使用主机名。

数据包过滤器适用于 IP 地址。也在防火墙配置中使用 IP 地址和 IP 地址范围。

当在防火墙规则中使用主机名时,iptables它将受到执行 iptables 命令时主机名解析的(单个)IP 地址的影响。
当无法解析主机名时,根本不会添加规则。

这似乎是显而易见的,也不是很有问题,但会导致许多极端情况,而在实践中却很常见。

  • 防火墙配置通常在启动时应用,然后完全激活网络,然后 DNS 解析将无法工作。例如,iptables -I INPUT --source bastion.example.com -j ALLOW当系统主机文件中没有条目 bastion.example.com 时,允许从堡垒主机进行远程管理的规则将不适用(在系统启动时)。(当拥有内部 DNS 时,谁愿意维护主机文件?)

  • 当转发 DNS 记录更新时:Linux 防火墙将继续使用旧的 IP 地址,直到规则被明确刷新/删除/更新(通过iptables再次运行命令)。

  • 当转发 DNS 记录是循环记录或使用地理位置时:通常仅使用单个 IP 地址。

    换句话说:iptables -I OUTPUT --destination www.google.com -j REJECT例如,只会部分阻止对 Google 的访问,持续时间不超过 300 秒。然后 DNS TTL 到期并查询www.google.com返回不同的 IP 地址,通常是有效防火墙规则中未阻止的新 IP 地址。

  • 通常使用主机名来拒绝不需要的访问已经是一个坏主意。
    系统通常只能看到来自传入连接的 IP 地址,并且需要对 IP 地址进行反向查找以确定关联的主机名。按主机名阻止会出现问题,原因有两个:

    • 反向 DNS 查找可能会很慢

    • 生成的主机名不可信,因为 IP 地址的所有者可以在反向 DNS 记录上设置他们想要的任何主机名。他们可以随意更改untrusted.example.nettrusted.example.com有些系统通过从 PTR 记录中对主机名进行第二次正向查找来解决这个问题,并且只接受两者匹配的系统。)

      iptables -A INPUT --source untrusted.example.net -j REJECT
      
      Run Code Online (Sandbox Code Playgroud)

    对于 iptables,问题略有不同,因为只会进行正向 DNS 查找。但尽管如此,当您使用 untrusted.example.net 而不是 IP 地址时,您将不再控制被阻止的内容。
    如果该 DNS 记录的所有者将 untrusted.example.net 更改为您的网关的 IP 地址,您将被锁定。
    如果所有者完全删除该记录,您也不再阻止他们的 IP。

另一个可能令人困惑的事情是:当显示防火墙规则时,如果通过反向 DNS 查找完成从 IP 地址到主机名的映射。通常,该 PTR 记录不存在,即使存在,生成的主机名也常常与创建规则时使用的主机名不对应。例如:

www.google.com.                 300 IN  A   172.217.168.228
228.168.217.172.in-addr.arpa. 18721 IN  PTR ams15s40-in-f4.1e100.net.
Run Code Online (Sandbox Code Playgroud)

可能还有其他一些我忘记的原因。


使用服务 名称iptables

尽管安全,但这似乎也会产生一些混乱。

当使用人类可读的“服务名称”(或别名和类似的/等)而不是端口号时,该文件/etc/services用于将服务名称转换为端口号。iptables --protocol tcp --source-port--sport--destination-port--dport

服务名称实际上是一个人类可读的端口号,并且(只要没有人修改 /etc/services)当管理员使用时, ssh它 与使用port相同22

iptables -I INPUT -p tcp --dport ssh -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

混乱的根源似乎是人们将服务名称 (ssh) 与应用程序协议 (ssh) 混淆了。
上面的规则不允许所有传入的 ssh 流量。
例如,当您的 ssh 服务器配置为侦听端口 22222 时,此规则不会打开该端口。
该规则仅允许所有流量到达端口 22。
它也不会阻止非 ssh 流量连接到端口 22。典型的 ssh 守护进程将无法正确响应,但诸如此类的请求http://hostname:22/也不会被数据包过滤器阻止。(这需要 DPI。)