适用于 Ubuntu 家用路由器的安全 iptables 规则集

适用于 Ubuntu 家用路由器的安全 iptables 规则集

我使用 Ubuntu 14.04 服务器作为我的主要家用路由器和防火墙。它具有 DNS、DHCP 并使用 iptables 来保护一切。Iptables 还充当 nat。

在 eth0 上我有传入的互联网连接,在 eth1 上我有用于提供 DNS 和 DHCP 的 LAN。所有客户端(连接到 eth1)都应该能够正常执行任何出站操作。在 LAN 上我有几台机器,我想使用 PREROUTING 从外部连接到它们。

但是,最近我发现我的规则集在 INPUT 的 *filter 上定义了 ACCEPT,但在末尾没有定义任何 DROP。因此,我现在在传入上定义了 DROP。发现这一点后,我有点担心,想仔细检查整个规则集,看看是否遗漏了更多内容。

这套 iptables 是否足以确保一切安全?据我了解,PREROUTING 和 FORWARD 可以设置为 ACCEPT,因为如果没有匹配项,它将命中 INPUT,然后被默认规则 DROP。这是正确的吗?

*filter
:INPUT DROP
-A INPUT -i eth1 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -i eth0 -p udp -m udp --dport 53 --sport 53 -m state --state NEW -j    ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

:FORWARD ACCEPT
-A FORWARD -i eth0 -j ACCEPT

:OUTPUT ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT
-A PREROUTING -i eth0 -p tcp -m tcp -s x.x.x.x --dport 8466 -j DNAT --to-destination 192.168.0.149:8465
-A PREROUTING -i eth0 -p tcp -m tcp -s x.x.x.x --dport 5667 -j DNAT --to-destination 192.168.0.111:5666
-A PREROUTING -i eth0 -p tcp -m tcp -s x.x.x.x --dport 5666 -j DNAT --to-destination 192.168.0.201:5666
-A PREROUTING -i eth0 -p tcp -m tcp -s x.x.x.x --dport 2548 -j DNAT --to-destination 192.168.0.201:548
-A PREROUTING -i eth0 -p tcp -m multiport --dports 32400,32469 -j DNAT --to-destination 192.168.0.201

:INPUT ACCEPT

:OUTPUT ACCEPT

:POSTROUTING ACCEPT
-A POSTROUTING -o eth0 -j MASQUERADE

COMMIT

答案1

是的,这是正确的。

有一件奇怪的事情:你的 DNS 服务器对外开放了???这会使你的 LAN 遭受 DNS DDoS 攻击。你不是说要让你的 DNS 服务器对外开放吗?里面? (-i eth1)。如果你把它开放给外界,有一些方法可以减轻DNS DDos攻击的影响,你知道吗?

只是为了确保你所说的是真心话:

  1. 您正在网关上运行 ssh 服务器和 http 服务器(仅在端口 80 上?为什么不在端口 443 上?)。

  2. 你想要一个单身的可以访问端口 8466、5667、5666 和 2548 的 IP 地址。

  3. 相反,你允许每一个IP 连接端口 32400 和 32469。

(以防万一您感到疑惑:这里没有游戏玩家)。

你为什么放弃icmp数据包?它们执行有用的功能。

与公众的看法相反,您不需要添加规则来丢弃格式错误的数据包,也不需要丢弃私有、不可路由 IP 地址的数据包。换句话说,这是一个足够的规则集:您可能希望阅读这里专业人士对 iptables 规则集的看法,尤其是第一个答案。

答案2

我必须反驳前面的答案。这种设置不安全。基本上,通过这样做

:FORWARD ACCEPT -A FORWARD -i eth0 -j ACCEPT

您允许所有来自外部的流量转发到内部。因此您不需要 PREROUTING 条目。

因此,如果我是与你的公网 IP 位于同一子网的攻击者(在同一地区使用同一 ISP 的人)。如果我直接在 ISP 上连接一台机器,这样我就可以获得它的一个公网 IP,我可以创建一个路由,例如

ip route add 192.168.0.0/24 via <your_public_ip>

(我只需扫描互联网寻找我子网上的其他人就可以获得你的公共 IP)

然后我就可以这样做了curl http://192.168.0.201:548,你的防火墙会很乐意将该请求转发到你本地网络上的机器。实际上,我可以通过以下方式扫描你的网络:

nmap -sn -T4 192.168.0.0/24

我将获得您网络上所有正在运行的 IP 的列表。

然后对于每一个我可以做:

nmap -sS -T4 192.168.0.201

然后我就可以得到打开端口的列表。我通过创建 2 个虚拟机并模拟路由器和客户端计算机(我在其上运行 Nginx 服务器)验证了这一点。我能够从“WAN”端访问“LAN”端的 Nginx 服务器,尽管没有 PREROUTING 规则允许这样做。我还能够扫描“LAN”端,这样只有 1 个虚拟机正常运行 :-)

你需要做的是:

:FORWARD DROP -A FORWARD -i eth1 -o eth1 -j ACCEPT -A FORWARD -i eth1 -o eth0 -j ACCEPT -A FORWARD -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT

上述规则默认会删除所有转发。请注意,如果您需要在其他接口之间转发,则需要添加条目。然后其他规则会执行:

  1. 接受从 LAN 端到 LAN 端的转发(这是可选的,但你可能有一些需要它的设置。例如,我的 LAN 接口是一个由多个接口组成的网桥,就像一个交换机,所以我需要那个规则)
  2. 接受从 LAN 到 WAN 的转发
  3. 仅当数据包在 PREROUTING 中被接受并发送到 DNAT 目标,或者它们来自已建立的连接或与其相关(认为与连接相关的 ICMP 数据包)时,才接受从 WAN 到 LAN 的转发

但是另一个答案是正确的,即您正在将 DNS 暴露给互联网,这是不寻常的。此外,暴露端口 22 和端口 80 可能不是最好的主意。在网上查找,有很多方法可以改进您的设置,例如速率限制和使用 IPS(甚至像 fail2ban 一样简单),尤其是强化 SSH 并切换到 HTTPS。

丢弃来自私有 IP 空间的数据包可能没有必要,但丢弃无效数据包仍然是一件好事。无论如何,只要您使用 conntrack,它就会“标记”无效数据包,所以为什么不使用此功能并避免路由稍后将被应用程序丢弃的数据包。只需杀死它们。

结束语:当您不知道如何测试自己的防火墙时,您应该考虑使用防火墙发行版(例如 ipfire、OPNsense 等)或至少使用 Linux 机器上可以开箱即用的软件(例如 shorewall)。这样做的好处是更容易获得安全设置,但缺点当然是您不会学习 iptables。如果要学习 iptables,请先在“生产路由器”上使用真正的路由器防火墙设置。在机器或 VM 设置上使用 iptables,在这里询问其他问题,例如如何测试和验证防火墙。一旦您证明了这一点,就将其放入“prod”中。:-) 这就是我的做法,所以我只将其作为建设性建议。

相关内容