如何使用端口敲门在 Ubuntu 上对攻击者隐藏 SSH 守护进程
状态:已弃用
本文涵盖不再受支持的 Ubuntu 版本。如果您目前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
- 升级到 Ubuntu 14.04。
- 从 Ubuntu 14.04 升级到 Ubuntu 16.04
- 将服务器数据迁移到支持的版本
原因:
请参阅:
介绍
根据定义,服务器被实现为提供服务并使应用程序和资源可供用户访问的一种方式。然而,任何连接到 Internet 的计算机都不可避免地成为希望利用安全漏洞的恶意用户和脚本的目标。
防火墙存在并且应该用于阻止对服务未使用的端口的访问,但是仍然存在如何处理您想要访问但又不想向所有人公开的服务的问题。您希望在需要时访问,但在其他情况下希望它被阻止。
端口敲门是一种隐藏您在计算机上运行的服务的方法。它允许您的防火墙保护您的服务,直到您请求通过特定序列的网络流量打开端口。
在本指南中,我们将讨论如何使用 knockd
包在 Ubuntu 12.04 VPS 上实现端口敲门作为一种隐藏 SSH 守护进程的方法。
注意:本教程涵盖 IPv4 安全性。在 Linux 中,IPv6 安全性与 IPv4 分开维护。例如,\iptables 只维护 IPv4 地址的防火墙规则,但它有一个名为 \ip6tables 的 IPv6 副本,可用于维护 IPv6 网络地址的防火墙规则。
如果您的 VPS 配置为 IPv6,请记住使用适当的工具保护您的 IPv4 和 IPv6 网络接口。有关 IPv6 工具的更多信息,请参阅本指南:如何配置工具以在 Linux VPS 上使用 IPv6
端口敲门如何工作?
端口敲门通过配置服务来监视防火墙日志或数据包捕获接口以进行连接尝试来工作。如果进行了特定顺序的预定义连接尝试(或“敲门”),该服务将修改防火墙规则以在特定端口上打开连接。
这使您可以隐藏您的服务,直到您真正计划使用它们。这对于像 HTTP 服务器这样的东西是不切实际的,因为您希望连接始终可用。但它对于仅供已知合法用户使用的服务很有用,例如 SSH。
尽管敲门序列可以任意复杂,但就其本身而言,通常并不是唯一的安全措施。通常,服务自己的安全和身份验证方法随后会暴露给发出正确序列的用户。通过这种方式,端口敲门增加了一个额外的层,用户必须通过该层才能进行常规身份验证。
更有帮助的是,没有关于敲门尝试的反馈。入侵者扫描会发现所有常用端口都已关闭,如果他们尝试敲门序列,则必须在每次尝试之间检查端口是否打开。这通常足以劝阻或禁止攻击者。
出于我们的目的,我们将使用 Ubuntu 12.04 附带的 iptables 防火墙,并安装一个名为 knockd
的守护进程来提供端口碰撞功能。
配置 IPTables 以阻止大多数流量
在我们开始实际的端口敲门之前,我们需要配置一个基本的防火墙。我们想锁定大多数事情。
默认情况下,Ubuntu 会安装 iptables。但是,没有适当的默认规则,因此允许所有流量。要设计自己的规则集,您可以在此处了解如何使用 iptables 设置防火墙。
出于我们的目的,我们将使用该指南中的大部分规则。
首先允许本地计算机上的流量。这意味着接受服务器生成并发送给自身的流量。这允许服务相互通信而不会被阻塞:
sudo iptables -A INPUT -i lo -j ACCEPT
这向 \INPUT 链附加了一条规则。这条链处理所有进入服务器的连接。这条规则告诉 iptables 接受 \lo 网络接口上的所有流量,这是用于内部通信的本地环回接口。
接下来,我们要确保通过键入以下内容允许所有已建立的连接和与已建立连接相关的流量:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
此规则告诉 iptables 接受与已建立连接关联的流量。这一点很重要,因为一旦我们开始阻止连接,我们就不希望当前的 SSH 会话被切断。
接下来,您将希望允许持久的、全球可消费的服务。我的意思是,为需要始终运行和可见的服务添加规则。例如,如果您有一个在标准端口 80 上提供服务的网站,您希望始终允许该流量。
不要为我们将使用端口敲门器打开的服务向 iptables 添加规则。我们将改为使用 knocking 守护进程来动态修改我们的规则集。对于我们的教程,我们不会在初始 iptables 配置中添加 SSH 服务器。
使用此语法建立您自己的规则:
<前>
在这一点上,我们只添加了接受连接的规则,而不是丢弃它们。我们仍然接受一切,我们只是明确了某些类型的流量。
现在,我们将放弃所有未明确允许的内容。添加此规则:
sudo iptables -A INPUT -j DROP
任何未被上述规则处理的流量都将被丢弃。您可以通过键入以下内容来查看您的规则:
sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP
如您所见,我们仍然没有任何规则来接受新的 SSH 连接。
如果此时您的连接断开,您必须通过单击右上角的“控制台访问”按钮通过控制面板访问您的服务器:

这充当直接登录并且不使用 SSH,因此它不会受到您的规则的影响。
建立 iptables 规则后,使用 iptables-persistent
使它们持久化。通过键入以下内容安装它:
sudo apt-get install iptables-persistent
之后,通过键入以下内容启动服务:
sudo service iptables-persistent start
安装 Knockd 服务
我们将使用的端口碰撞感知服务称为 knockd
。我们可以通过简单地输入来安装它:
sudo apt-get install knockd
这将安装该实用程序,但默认情况下不会启动该服务。
这是一项安全预防措施,旨在防止守护进程立即阻塞重要流量。您必须配置并明确启用此服务。
配置 Knockd 以使用端口碰撞
要配置服务,我们必须编辑配置文件。使用 root 权限打开此文件:
sudo nano /etc/knockd.conf
您应该看到一个如下所示的文件:
[options]
UseSyslog
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 5
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
立即,您应该能够看到一些关于 knockd 如何工作的重要信息。您还应该开始意识到配置并不太复杂。
在“选项”部分,我们看到一个名为 UseSyslog
的指令。这告诉 knockd 它应该使用正常的 syslog 方法记录其信息。这会将日志插入到 /var/log/消息
。
如果你想指定一个不同的日志文件,你可以通过使用这个选项来实现:
<前>
在下面,我们有两个部分。这些部分的名称可以是任何名称。它们用于将一组规则分组,每个规则将匹配一个事件。
例如,在我们的文件中,我们有一个部分将打开我们的 SSH 端口,一个部分将再次关闭它。
设置敲击模式的参数在这里:
<前>
这意味着如果相同的 IP 在端口 7000 上请求连接,然后直接是端口 8000,最后是端口 9000,则这组规则将匹配。
该集合中的另外两个参数也控制活动是否匹配:
seq_timeout = 5
tcpflags = syn
第一个选项指定序列必须完成的时间量。
第二个指定一个标志,该标志必须出现在 tcp 数据包中才能被视为有效。我们在这里看到的 syn
的值通常用于区分我们想要的数据包和由 SSH 等程序在后台创建的数据包。
最后,我们看到命令:
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
您应该将此识别为 iptables 规则。正如部分标签 \openSSH 所指出的,当输入正确的序列时,该部分将为 SSH 连接打开一个端口。
但是,如果您在 iptables 配置期间留心,您会看到这个新规则使用 -A
选项将此规则附加到 INPUT 链的末尾.这会将此规则放在删除所有剩余连接的规则之后。
要解决这种情况,我们需要修改此命令。用规则替换命令以在列表顶部插入新规则。我们通过使用 -I
选项并将位置引用为规则 1 来执行此操作:
command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT
通过此更改,一条新规则将添加到 INPUT 链的顶部,以接受来自敲门用户的 SSH 连接。规则的 %IP%
部分将替换为发出可接受敲门声的 IP 地址。
第二个 SSH 部分做几乎相同的事情,但它使用不同的顺序,并从打开 SSH 连接的 iptables 中删除规则。我们可以点击这个序列来缩小我们打开的差距。
实际上,您应该始终将这两个部分的顺序更改为本质上随机的顺序。保持默认顺序有效地消除了端口碰撞建立的任何安全性。
在我们进一步配置任何东西之前,让我们测试一下我们当前的设置。保存并关闭文件。
实施 Knockd 服务
现在我们已经将 knockd 配置为具有有效的规则集,我们可以通过实现我们的守护进程来测试它。请记住,虽然配置有效,但此时它并不安全,除非您更改每个敲击部分的端口序列。
我们需要通过编辑另一个文件来启用该服务。使用 root 权限打开此文件:
sudo nano /etc/default/knockd
我们需要将 START_KNOCKD
选项更改为 \1 以启动服务:
<前>
保存并关闭文件。
现在,我们可以通过键入以下内容来启动服务:
sudo service knockd start
这将启动守护进程并允许您通过敲击端口序列来更改 iptables 规则集。
端口碰撞测试
我们现在应该使用我们配置的端口碰撞序列来测试我们修改 iptables 规则的能力。
在新的终端窗口中,我们可以使用工具来请求这些端口。最好让您的其他会话保持打开状态,以防出现问题。同样,如果您不小心将自己锁定在外面,请使用控制面板中 Droplet 页面右上角的“控制台访问”按钮。
我们可以使用各种不同的工具来敲门。一些流行的选择是 netcat
、nmap
和一个专门设计的客户端,适当地称为 knock
。
我们将在这个例子中使用 nmap
,因为它在大多数 Linux 发行版和 OS X 上默认安装。
在我们敲门之前,让我们确认我们的 SSH 端口目前实际上是关闭的。键入您通常用于连接到服务器的命令:
<前>
您应该不会收到来自服务器的响应,并且 SSH 客户端应该会超时。这是因为我们的 SSH 守护进程当前被 iptables 阻止了。如果没有自动超时,请键入 ctrl-C 结束 SSH 尝试
由于设置了序列超时参数,我们实际上只有非常有限的时间来命中正确的序列。我们将使用一个小的内联 bash 脚本来快速敲击这些端口。
在您的本地计算机上,键入如下命令:
<前>
在命令中,将三个数字调整为您为序列选择的数字以打开 SSH 端口。更改 server_ip_address 以反映您的服务器地址。
这将在您列出的所有端口上依次调用 nmap。
完成后,您应该能够定期登录 SSH:
<前>
我们可以通过敲击我们配置的其他序列来重新关闭端口:
<前>
使用 Knock Utility 进行端口敲门
一种更简单的敲击方法是使用 knockd
的制造商提供的 knock
实用程序。这包含在 knockd 包中,因此您可以像在服务器上一样将其安装在我们的客户端计算机上:
sudo apt-get install knockd
您还可以从项目网站的“下载”部分下获取敲客户。有原生 OS X 和 Windows 客户端可用(甚至 iOS 和 Android 客户端)。
安装敲门客户端后,只需使用以下语法即可轻松执行序列:
<前>
因此,对于我们的示例,您可以通过键入以下命令打开 SSH 端口:
<前>
这比提到的其他方法快得多。
我们可以通过键入以下内容来关闭端口:
<前>
配置 Knockd 以自动关闭连接
现在我们已经确定我们的端口碰撞守护程序正常运行,让我们更改一些配置细节以使其更加健壮。
再次打开配置文件:
sudo nano /etc/knockd.conf
我们将利用 knockd 建立命令超时的能力,以便将我们的 SSH 匹配压缩为一条规则。这意味着我们不必记得在完成后敲门关闭 SSH 端口。
我们可以注释掉或删除“openSSH”和“closeSSH”部分。我们将用我们简单称为“SSH”的单个部分替换它们:
[options]
UseSyslog
[SSH]
在这个新部分下,我们将建立一个序列、tcpflags 和序列超时,就像我们在其他部分中所做的那样。我们还将包含用于打开 SSH 端口的命令:
<前>
[SSH]
选择一个唯一的端口序列。如您所见,在此示例中我们使用了四个端口。我们可以增加端口的数量,只要在seq_timeout
参数指定的时间范围内都能敲到即可。
start_command
参数与另一个示例中使用的 command
参数相同。我们选择使用这个变体只是为了更详细地说明我们正在做的事情。
在此之后,我们将添加一些新参数来帮助我们关闭端口:
<前>
[SSH]
cmd_timeout
是 knockd 在执行包含在 stop_command
变量中的命令之前等待的秒数。
结果是,当使用正确的顺序时,守护进程将打开 SSH 端口。然后它将等待 10 秒,然后再次关闭端口。
保存并关闭文件。
通过重新启动守护进程来实施新规则:
sudo service knockd restart
我们可以使用这个端口敲门规则在指定的时间内轻松连接。例如,我们可以使用此命令轻松连接到我们的服务器:
<前>
我们在防火墙中创建的漏洞将在 10 秒内关闭。
结论
尽管端口敲门有时被贬低地称为通过模糊实现安全(隐藏服务而不是实际保护它),但它是添加额外保护层以防止随机攻击的好方法。
您应该始终使用可用的本机工具来保护您的服务以获得最佳结果。但是,在这些方法之前添加诸如端口碰撞方案之类的东西可以大大减少您的服务经历的暴力攻击或入侵尝试的次数。