如何在Ubuntu上使用端口敲门对攻击者隐藏SSH守护进程
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
根据定义,服务器被实现为一种提供服务并使用户可以访问应用程序和资源的手段。 但是,任何连接到互联网的计算机都不可避免地成为恶意用户和脚本的目标,他们希望利用安全漏洞。
防火墙存在并且应该用于阻止对服务未使用的端口的访问,但是仍然存在如何处理您想要访问但不想暴露给所有人的服务的问题。 您希望在需要时访问,但希望在其他情况下阻止它。
端口敲门是一种隐藏您在机器上运行的服务的方法。 它允许您的防火墙保护您的服务,直到您要求通过特定的网络流量序列打开一个端口。
在本指南中,我们将讨论如何使用 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。 我们将改为使用敲门守护程序来动态修改我们的规则集。 对于我们的教程,我们不会在初始 iptables 配置中添加 SSH 服务器。
使用此语法来建立您自己的规则:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
在这一点上,我们只添加了接受连接的规则,而不是丢弃它们。 我们仍然接受一切,我们只是明确了某些类型的流量。
现在,我们将删除我们没有明确允许的所有内容。 添加此规则:
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
。 我们只需键入以下内容即可安装它:
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/messages
。
如果你想指定一个不同的日志文件,你可以改用这个选项:
日志文件 = /path/to/log/file
下面,我们有两个部分。 这些部分的名称可以是任何名称。 它们用于将一组规则分组,每个规则将匹配一个事件。
例如,在我们的文件中,我们有一个部分将打开我们的 SSH 端口,还有一个部分将再次关闭它。
设置敲击模式的参数在这里:
序列 = 7000,8000,9000
这意味着如果同一个 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 部分几乎做同样的事情,但它使用不同的顺序,并从 iptables 中删除了打开与 SSH 的连接的规则。 我们可以点击这个序列来缩小我们打开的差距。
在实践中,您应该始终将这两个部分的顺序更改为基本上随机的顺序。 保持默认顺序有效地消除了端口敲门建立的任何安全性。
在我们进一步配置之前,让我们测试一下我们当前的设置。 保存并关闭文件。
实施敲门服务
现在我们已经配置了 knockd 以拥有一个有效的规则集,我们可以通过实现我们的守护进程来测试它。 请记住,尽管配置是有效的,但此时它并不安全,除非您更改每个敲击部分的端口序列。
我们需要通过编辑另一个文件来启用该服务。 使用 root 权限打开此文件:
sudo nano /etc/default/knockd
我们需要将 START_KNOCKD
选项更改为“1”以启动服务:
START_KNOCKD= 1
保存并关闭文件。
现在,我们可以通过键入以下内容来启动服务:
sudo service knockd start
这将启动守护程序并允许您通过敲击端口序列来更改 iptables 规则集。
端口敲击测试
我们现在应该使用我们配置的端口敲击序列来测试我们修改 iptables 规则的能力。
在 new 终端窗口中,我们可以使用工具来请求这些端口。 最好让您的其他会话保持打开状态,以防出现问题。 同样,如果您不小心将自己锁定,请使用控制面板中 Droplet 页面右上角的“控制台访问”按钮。
我们可以使用各种不同的工具来敲击。 一些流行的选择是 netcat
、nmap
,以及一个专门设计的客户端,恰当地称为 knock
。
我们将在本例中使用 nmap
,因为它默认安装在大多数 Linux 发行版和 OS X 上。
在敲门之前,让我们确认一下我们的 SSH 端口实际上目前是关闭的。 键入您通常用来连接到服务器的命令:
ssh root@ server_ip_address
sh:连接到主机 server_ip_address 端口 22:操作超时
您应该没有收到来自服务器的响应,并且 SSH 客户端应该超时。 这是因为我们的 SSH 守护进程当前被 iptables 阻止。 如果没有自动超时,请键入 ctrl-C 以结束 SSH 尝试
由于设置了序列超时参数,我们实际上只有非常有限的时间来命中正确的序列。 我们将使用一个小的内嵌 bash 脚本来快速敲开这些端口。
在您的本地机器上,键入如下命令:
对于 x 在7000 8000 9000 ; 做 nmap -Pn --host_timeout 201 --max-retries 0 -p $x server_ip_address ; 完毕
在命令中,将三个数字调整为您为序列选择的数字以打开 SSH 端口。 更改 server_ip_address 以反映服务器的地址。
这将在您列出的所有端口上按顺序调用 nmap。
完成后,您应该能够定期登录 SSH:
ssh root@ server_ip_address
我们可以通过敲击我们配置的其他序列来重新关闭端口:
对于 x 在9000 8000 7000 ; 做 nmap -Pn --host_timeout 201 --max-retries 0 -p $x server_ip_address ; 完毕
使用敲门实用程序敲门
更简单的敲门方法是使用 knockd
的制造商提供的 knock
实用程序。 这包含在 knockd 包中,因此您可以将它安装在我们的客户端计算机上,就像我们在服务器上所做的那样:
sudo apt-get install knockd
您也可以从 项目的网站 的“下载”部分下获取敲击客户端。 有可用的本地 OS X 和 Windows 客户端(甚至是 iOS 和 Android 客户端)。
一旦安装了 knock 客户端,您就可以使用以下语法轻松执行序列:
敲server_ip_address 序列
因此,对于我们的示例,您可以通过键入以下命令打开 SSH 端口:
敲server_ip_address 7000 8000 9000
这比提到的其他方法快得多。
我们可以通过键入以下内容来关闭端口:
敲server_ip_address 9000 8000 7000
配置 Knockd 以自动关闭连接
现在我们已经确定我们的端口敲门守护程序运行正常,让我们更改一些配置细节以使其更加健壮。
再次打开配置文件:
sudo nano /etc/knockd.conf
我们将利用 knockd 建立命令超时的能力,以便将我们的 SSH 匹配压缩为一条规则。 这意味着我们完成后不必记得敲门关闭 SSH 端口。
我们可以注释掉或删除“openSSH”和“closeSSH”部分。 我们将用一个我们简称为“SSH”的部分来替换它们:
[options] UseSyslog [SSH]
在这个新部分中,我们将建立一个序列、tcpflags 和序列超时,就像我们在其他部分中所做的一样。 我们还将包括我们用来打开 SSH 端口的命令:
[选项] UseSyslog [SSH] 序列 = 5438,3428,3280,4479 tcpflags = syn seq_timeout = 15 start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT
选择一个独特的端口序列。 如您所见,在此示例中,我们使用了四个端口。 只要能够在seq_timeout
参数指定的时间范围内全部敲开,我们就可以增加端口的数量。
start_command
参数与其他示例中使用的 command
参数相同。 我们选择使用这个变体只是为了更详细地说明我们正在做的事情。
在此之后,我们将添加一些新参数来帮助我们关闭端口:
[选项] UseSyslog [SSH] 序列 = 5438,3428,3280,4479 tcpflags = syn seq_timeout = 15 start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT cmd_timeout = 10 stop_command = /sbin /iptables -D 输入 -s %IP% -p tcp --dport 22 -j 接受
cmd_timeout
是 knockd 在执行 stop_command
变量中包含的命令之前将等待的秒数。
结果是,当使用正确的序列时,守护进程将打开 SSH 端口。 然后它将等待 10 秒,然后再次关闭端口。
保存并关闭文件。
通过重新启动守护程序来实施新规则:
sudo service knockd restart
我们可以使用这个端口敲击规则在指定的时间内轻松连接。 例如,我们可以使用此命令轻松连接到我们的服务器:
敲server_ip_address 5438 3428 3280 4479 && ssh root@ server_ip_address
我们在防火墙中创建的漏洞将在 10 秒后关闭。
结论
虽然端口敲门有时会被贬低地称为通过默默无闻的安全性(隐藏服务而不是实际保护它),但它是添加额外保护层以防止随机攻击的好方法。
您应该始终使用可用的本地工具来保护您的服务,以获得最佳结果。 但是,在这些方法之前添加诸如端口敲门方案之类的东西可以大大减少您的服务经历的暴力攻击或入侵尝试的数量。