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

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

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

由于和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 更加明显。

这样做安全吗?

或者你应该远离这个?

有哪些注意事项?

答案1

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

一点背景知识:

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

IP 数据包的报头不包含人类可读的名称,它们包括诸如知识产权protocol number, A源和目标IP-addressTCP 源和目标port号码ETC。

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

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

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

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

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

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


使用协议名称iptables

总的来说这是安全的并且不会引起任何不必要的混乱。

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

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


使用主机名使用iptablesnftables

默认文件/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当系统 hosts 文件中没有条目 bastion.example.com 时,允许从堡垒主机进行远程管理的规则将不适用(在系统启动时)。(当他们拥有内部 DNS 时,谁愿意维护 hosts 文件?)

  • 当正向 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
      

    对于 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.

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


使用服务名称iptables

虽然安全,但这似乎也引起了一些混乱。

该文件/etc/services用于翻译服务名称到端口号当端口号被替换为人类可读的“服务名称” 与……一起使用iptables --protocol tcp --source-port(或别名--sport及类似物--destination-port/--dport等)。

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

iptables -I INPUT -p tcp --dport ssh -j ACCEPT

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

相关内容