了解如何通过使用 Iptables 保护 SSH 来增强系统安全性。本指南提供分步说明,以保护您的系统免受未经授权的访问和潜在的网络攻击。
Secure Shell (SSH) 协议允许在不受信任的网络中进行加密的远程系统管理和文件传输。SSH 通过采用多种加密技术保护服务器和客户端之间的连接,保护用户的指令、身份验证和输出免受不必要的访问和攻击。SSH 被广泛用于数据中心和几乎所有运行 UNIX 变体的组织。
“Iptables”是一个命令行工具,用作 Linux 内核中 Netfilter 防火墙的标准管理界面。它允许您构建和更改规范数据包过滤和重定向的规则。Iptables 需要根(超级用户)能力。关于安全措施,将它们分层和组合而不是仅仅依赖一个是至关重要的。
Iptables 及其更新版本 nftables 是使用 netfilter 数据包过滤套件的两种常见方式。虽然不是最用户友好的,但它的用户空间工具提供了建立防火墙规则的最完整和一致的方法。
使用 Iptables 保护 SSH
本文将演示如何将系统流量仅限于 SSH 协议。首先,我们将回顾远程访问以及为什么 SSH 通常是首选选项。接下来,我们将研究如何完全隔离除 SSH 之外的机器。
遥控
由于虚拟化、容器化和云服务提供商等创新,系统自主产生并不常见。因此,我们需要一种预先确定的方法来输入它们。例如,我们通常在一个新的 Linux 系统启动并运行后就可以通过 SSH 访问。
自然地,我们获取远程环境访问权限的方法对其安全性至关重要。与任何实际场所一样,我们至少需要一个入口和一个出口形式的门。用计算机的话来说,我们必须接受至少通过一个端口号的流量。
虽然还有其他获得访问权限的选项,但管理员更喜欢 SSH 协议,因为它具有安全性和适应性。事实上,安全 shell 连接不仅仅用于交互式 shell 访问。
SSH 的默认端口是 22,其传输层协议是 TCP。这在限制进出系统的数据包范围时至关重要。重要的是,我们可以利用 SSH 更改特定系统的进一步过滤标准,这意味着它可能是安全的唯一批准的远程访问协议。
在探索这样做的原因之后,我们可能会使用安全外壳协议设置独占远程访问。在处理 iptables 时,我们必须记住,一个错误的命令可能会将我们锁定在系统之外。即使如此,如果我们勤奋并按照正确的顺序遵循规则,我们就可以通过已经建立的 SSH 连接配置所有内容。
检查现有的 iptables 规则
我们将通过检查现有的 iptables 规则来启动本节。为此,我们将执行以下代码行:
sudo iptables -L
从上面的输出中,我们可以看到我们的 iptables 规则集中没有预先设置的过滤。
连接数限制
为防止暴力攻击,将一个 IP 地址在端口 22 上的连接数限制为每分钟几次,然后禁止尝试连接该 IP。
创建 sshguard 规则链
每个 IP 地址每分钟最多允许两个新连接。
sudo /sbin/iptables -N sshguard # Include log whenever you like sudo /sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --rcheck --seconds 60 --hitcount 2 -j LOG --log-prefix "SSH-shield:" sudo /sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --update --seconds 60 --hitcount 2 -j DROP sudo /sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --set -j ACCEPT sudo /sbin/iptables -A sshguard -j ACCEPT
对于 ssh 流量,请使用 sshguard 链。
sudo /sbin/iptables -A INPUT -p tcp --dport 22 -j sshguard
代码分解:
- recent – 是一个内核组件(Core Netfilter Configuration),允许您构建最近发布的动态 IP 地址列表。该模块支持多种设置。
- —名称——程序列表的名称。该列表的默认名称是 DEFAULT。
- — rcheck——此选项检查数据包发送者的地址是否在列表中。如果在列表中找不到该地址,则返回 false。
- —更新——此选项检查数据包的发件人地址是否在列表中。如果地址存在,则该地址的条目将被更新。如果列表中没有地址,则函数返回 false。
- — hitcount – 如果地址在列表中并且从它接收到的数据包数量大于或等于与 rcheck 或更新结合时提供的值,则计数器满足条件
- seconds – 它定义地址可以保留的时间段(从地址包含在列表中开始)。
- — set — 将发件人的地址添加到列表中。如果该地址已存在于列表中,它将被更新。
- – Drop – 使用 -Drop 命令从列表中删除地址。如果找不到地址,函数将返回 false。
允许本地流量
许多程序依赖于通过环回网络接口(例如 lo)传输的本地主机通信。
我们可能会为此流量声明一个例外,因为它不应该对我们的完全访问权限构成安全风险:
sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A OUTPUT -o lo -j ACCEPT
在这种情况下,我们将 (-A, -append) 规则添加到 OUTPUT 和 INPUT 链,以在 lo 通道上接受 (-j ACCEPT, -jump ACCEPT) 流量作为起点 (-o, -out-interface ) 和端点 (-o, -out-interface) (-i, –in-interface)。
允许 SSH
我们现在准备好允许 SSH 流量进入我们的系统。我们使用标准端口 22,尽管 SSH 可能在多个端口上运行。
允许 SSH 的 iptables 指令引入了许多新概念:
sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT sudo iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
我们再次将规则附加到 OUTPUT 和 INPUT 链。仅接受来自(-sport,-source-port)和(-dport 或-destination-port)端口 22 的 TCP(-p tcp,-protocol tcp)通信。
此外,我们使用扩展模块来匹配 (-m, -match) 并验证以下内容:
- 作为 TCP 的进料
- 状态为 ESTABLISHED (–state) 的传出数据
这表明我们只接受来自指定源端口的出站通信,通过已建立的 TCP 连接。
创建主要策略
在进行最终配置之前,我们必须保证以下几点:
- SSH 访问功能正常。
- 如果出现错误,我们有一种恢复访问的方法。
作为一般规则,INPUT 链应默认设置为 DROP。在这种情况下,我们通过对 OUTPUT 流量应用相同的策略 (-P, -policy) 来限制更多。
为了安全起见,我们可以将所有内容放在一条线上并在超时后重置它,以确保我们的连接不会永久中断:
sudo iptables -P INPUT DROP; iptables -P OUTPUT DROP; sleep 30; iptables -P INPUT ACCEPT; iptables -P OUTPUT ACCEPT
这给了我们 30 秒的时间来确保 SSH 访问(仍然)按预期工作,尽管策略已更改。如果没有,我们可以回来。否则,我们可以使以下政策永久化:
sudo iptables -P INPUT DROP sudo iptables -P OUTPUT DROP
当以这种方式配置时,iptables 默认情况下禁止任何数据在所有接口上进入或退出系统,除非它匹配允许它的规则。
动态 ssh 端口打开/关闭
一点 iptables 规则将帮助您避免不必要地打开端口。
要获得 shell 访问权限,您必须先敲 1500 端口:
例如,远程登录:
telnet server 1500
或者,如果您使用的是浏览器,请执行以下代码行:
http://192.168.0.2:1500
因此,如果您尝试敲 1498 端口,该端口将被关闭且无法访问。
sudo iptables -N sshguard
如果地址在列表中,则允许连接
sudo iptables -A sshguard -m state --state NEW -m recent --rcheck --name SSH -j ACCEPT
允许数据包用于预先存在的连接
sudo iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT sudo iptables -A sshguard -j DROP
将地址附加到现有列表
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -j LOG --log-prefix "SSH-open:" sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -m recent --name SSH --set -j DROP
从列表中删除现有地址
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1499 -m recent --name SSH --remove -j DROP
对于 ssh 流量,请使用 sshguard 链。
sudo iptables -A INPUT -p tcp --dport 22 -j sshguard
注意:该端口只能由打开它的 IP 地址访问。
在指定的时间内,打开 ssh 端口。
另一个示例显示如何在特定时间为指定 IP 地址打开 ssh 端口。
确定 SSH 流量的链
sudo iptables -N sshguard sudo iptables -F sshguard
如果显示 IP 地址并且最后一次连接是在 108000 秒(30 小时)内建立的,则允许连接
sudo iptables -A sshguard -m state --state NEW -m recent --update --seconds 108000 --name SSH -j ACCEPT
允许数据包用于预先存在的连接
sudo iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT
阻止列表中不存在的 IP 地址
sudo iptables -A sshguard -j DROP
启动 SSH
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 222 -m recent -name SSH --set
使用 sshguard 链过滤 ssh 流量。
sudo iptables -A INPUT -p tcp --dport 22 -j sshguard
要获得 ssh 访问权限,您必须首先 ping 端口 22,如下所示:
ssh user@server.name -p 22
执行该行代码后,您与端口 22 的 IP 连接将被授予规定的持续时间,并且每个后续的 ssh 连接都将延长到该时间。如果您不打算延长持续时间,请使用 –rcheck 而不是 –update –seconds 108000。该端口仅对打开时的 IP 地址开放。
还可以通过执行以下代码行来确定允许哪些 IP 地址进行 ssh:
cat /proc/net/ipt_recent/SSH
结论
本文回顾了如何使用 iptables 保护 SSH。所有连接都通过 SSH 加密和验证。SSH 为 IT 和信息安全 (infosec) 专家提供了一种远程管理 SSH 客户端的安全方式。SSH 对设备进行身份验证而不需要密码保护来建立 SSH 服务器和客户端之间的连接。使用 iptables 保护 SSH 是关键,因为它有助于加强您的安全系统。系统管理员使用 iptables 创建包含数据包处理规则链的表。每个表对应一种特定类型的数据包处理。通过顺序遍历链中的规则来处理数据包。我希望这篇文章对您有所帮助。如果是,请在下面的评论部分留言。
原创文章,作者:主机说,如若转载,请注明出处:https://www.hostingtalk.cn/the-guide-to-securing-ssh-with-iptables/