如何在 LAN 中的系统上设置防火墙,以便某些端口仅对来自局域网的连接开放,而不对外部世界的连接开放?
例如,我有一个正在运行的盒子科学Linux 6.1(基于 RHEL 的发行版),我希望它的 SSH 服务器只接受来自本地主机或 LAN 的连接。我该怎么做呢?
答案1
随着内核的iptables完全空(iptables -F
),这将满足您的要求:
# iptables -A INPUT -p tcp --dport 22 -s 192.168.0.0/24 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 127.0.0.0/8 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP
这表示所有 LAN 地址都可以与 TCP 端口 22 通信,本地主机得到相同的考虑(是的,127.* 不仅仅是 127.0.0.1),并且来自与前两条规则不匹配的每个其他地址的数据包会被毫不客气地丢弃到这位桶。如果您想要主动拒绝 (TCP RST),而不是使 TCP 端口 22 成为数据包的黑洞,则可以使用REJECT
代替。DROP
如果您的 LAN 不使用 192.168.0.* 块,您自然需要更改第一行的 IP 和掩码以匹配 LAN 的 IP 方案。
如果您的防火墙已经配置了一些规则,这些命令可能不会执行您想要的操作。 (iptables -L
以 root 身份进行查找。)经常发生的情况是,现有规则之一会抓取您尝试过滤的数据包,因此附加新规则不起作用。虽然您可以使用-I
而不是-A
使用iptables
命令将新规则拼接到链的中间而不是附加它们,但通常最好找出链在系统启动时如何填充并修改该过程,以便您的新规则始终安装在正确的顺序。
RHEL 7+
在最新的 RHEL 类型系统上,最好的方法是使用firewall-cmd
或其等效的 GUI。这告诉操作系统的firewalld
守护进程您想要什么,这实际上是填充和操作您通过 看到的内容iptables -L
。
RHEL 6 及更早版本
在较旧的 RHEL 类型系统上,在订购时修改防火墙链的最简单方法是编辑/etc/sysconfig/iptables
.操作系统的 GUI 和 TUI 防火墙工具相当简单,因此一旦您开始添加像这样的更复杂的规则,最好返回到良好的旧配置文件。请注意,一旦开始执行此操作,如果您使用操作系统的防火墙工具修改配置,则可能会面临丢失更改的风险,因为它可能不知道如何处理此类手工规则。
将这样的内容添加到该文件中:
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 192.168.0.0/24 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 22 -s 127.0.0.0/8 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 22 -j DROP
在哪里添加它是棘手的一点。如果您在该文件中发现一行谈论--dport 22
,只需将其替换为上面的三行即可。否则,它可能应该位于第一个以 结尾的现有行之前-j ACCEPT
。一般来说,您需要熟悉该方法iptables有效,此时正确的插入点将显而易见。
保存该文件,然后service iptables restart
重新加载防火墙规则。请务必在登录控制台时执行此操作,以防您误操作!您不想在通过 SSH 登录时将自己锁定在计算机之外。
与上述命令的相似之处并非巧合。该文件的大部分内容由iptables
命令的参数组成。与上述的不同之处在于该iptables
命令被删除,并且INPUT
链名称变成了特殊的 RHEL 特定RH-Firewall-1-INPUT
链。 (如果您想更详细地检查该文件,您会在文件的前面看到他们基本上已重命名了INPUT
链。为什么?不能说。)
答案2
Linux 下防火墙设置的底层工具是iptables。还有更高级别的工具可用。不知道Scientific Linux有没有推荐的防火墙工具。
根据这个网页(我没有验证它是否适用于6.1),service iptables save
将保存当前的防火墙规则,并且这些保存的规则在启动时加载。因此,您需要通过iptables
命令(或任何其他方式)设置您想要的规则,然后运行service iptables save
以使您的设置持久化。
斯科特·帕克的博客文章是丢弃通常不需要且极有可能成为攻击一部分的“奇怪”数据包的开始。除此之外,您需要关闭所有传入端口,并仅打开您需要的端口。像这样的东西:
# Accept everything on the loopback interface
iptables -A INPUT -i lo -j ACCEPT
# Accept ICMP
iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
# Drop oddball packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Accept packets that are part of established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept selected incoming connections, e.g. ssh from 10.0.42.x
iptables -A INPUT -p tcp --dport 22 -s 10.0.42.0/24 -j ACCEPT
# Reject incoming connections that aren't explicitly accepted
iptables -A INPUT -j REJECT
答案3
首选的方法是使用iptables
.看起来其他人已经充分介绍了这一点,因此,为了完整起见,我将指出一种可用于大多数 Linux 发行版上的许多守护程序的替代访问控制方法。该访问控制方法由图书馆提供libwrap
。
要检查您最喜欢的守护程序是否受libwrap
支持,请尝试运行以下命令:
ldd `which sshd` | grep libwrap
如果得到非空结果,例如
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f84e7b0e000)
那么你就可以开始了。
几乎可以肯定,您的sshd
守护程序确实受到libwrap
支持,因此它应该查阅/etc/hosts.allow
和/etc/hosts.deny
文件以进行访问控制。假设您的本地 LAN 网络是192.168.100.0/24
,您可以否定访问sshd
所有客户端除了通过将以下内容放入文件中,可以在本地主机或本地 LAN 上进行设置/etc/hosts.deny
:
sshd: ALL EXCEPT 127.0.0.0/255.0.0.0, [::1]/128, 192.168.100.0/255.255.255.0
注意这个方法才不是实际上打开或关闭端口本身。它只是告诉使用这种访问控制方法的守护进程是接受还是拒绝来自与给定模式匹配的客户端的连接尝试。
有关完整的详细信息,请查看以hosts_access(5)
.
答案4
如果你有自己的基于 Linux 的防火墙,最好设置iptables
,正如其他人在此处所述。如果没有,并且防火墙是你的路由器,那么很可能默认配置已经阻止了外部访问,除非你明确启用端口转发(正如我最近在回答中所述对于这个问题)。
为了获得更高的安全性,您可以使用单独的子网进行 LAN 内连接。为此,请为每台计算机添加第二个 IP 地址,该地址仅在 LAN 内使用,而不能由路由器使用。假设整个 LAN 现在都使用192.168.0.xxx
地址,并且路由器(网关、防火墙)是192.168.0.1
。因此,为每台计算机添加第二个地址 - 例如:
ifconfig eth0:0 192.168.5.1/24
接下来,编辑sshd
配置以仅使用此地址(以便它不允许连接192.168.0.xxx
) - 编辑/etc/ssh/sshd_config
并修改ListenAddress
为新子网之一(192.168.5.1
在上面的示例中)。就是这样!如果您没有配置网关来路由该子网的通信,则应将其与外部隔离。