如何在Ubuntu VPS上仅使用Iptables配置端口碰撞

介绍

连接到互联网的服务器受到恶意用户,脚本和自动机器人的所有攻击和探测方式。有时,这是一种平衡措施,可确保您的服务器免受攻击,而不会影响对您的服务和资源的合法访问。 某些类型的服务意味着对公众互联网可见和消费。一个例子是Web服务器。其他类型的服务通常仅由系统管理员或选定数量的个人使用,并且不意味着是公共资源。 被称为 端口碰撞的一个概念是屏蔽适合后一描述过程的方式。端口碰撞通过覆盖与防火墙后面的进程相关联的端口来工作,直到发生特定的预定序列的网络活动。此时,端口碰撞服务重新配置防火墙以允许访问受保护的应用程序。 在前面的文章中,我们讨论了 如何启用端口通过特殊设计的端口碰撞服务 。在本文中,我们将讨论配置端口碰撞的另一种方法。 此方法不依赖外部应用程序来更改防火墙规则。 相反, iptables防火墙可以利用所谓的“最近”的状态跟踪模块做这一切在防火墙规则本身。 我们将在Ubuntu 12.04Droplet上进行配置,但任何类型的Linux服务器都应以类似的方式运行。 注: 本教程介绍IPv4的安全性。 在Linux中,IPv6安全性与IPv4分开维护。 例如,“iptables”仅维护IPv4地址的防火墙规则,但它有一个称为“ip6tables”的IPv6对等体,可用于维护IPv6网络地址的防火墙规则。 如果您的VPS配置为IPv6,请记住使用相应的工具保护IPv4和IPv6网络接口。 有关IPv6工具的更多信息,请参阅本指南: 如何配置工具使用IPv6在Linux VPS

Iptables端口碰撞概述

在我们进入实际配置之前,我们将描述最近的模块如何工作,以及它如何允许我们创建一个端口碰撞系统。 iptables的可加载模块 -m标志。最近的模块可以跟踪连接状态。我们可以使用它通过一系列链来漏斗我们的端口连接尝试,基于连接用户是否命中了每个以前需要的端口。 在我们的例子中,我们将阻止我们从互联网SSH守护,由我们代表 eth0接口。我们将动态重新配置我们的防火墙,以便在一系列端口按顺序“碰撞”后,临时允许来自我们计算机的SSH连接。 我们将用于本教程的顺序是:
  • 1111
  • 2222
  • 3333
这些值不应在实际配置中使用。 为了让用户正确地进行身份验证并导致iptables将SSH守护程序暴露到其IP地址,它们必须按顺序命中这些端口中的每一个,而不在其间发送非序列流量。如果我们实现这一点,我们将成功创建一个端口碰撞系统。

Iptables配置策略

为了实现上述设计,我们将使用几个不同的链。 首先,我们将接受我们不希望受到港口撞击的所有交通。这包括任何公共资源,如Web服务器,以及来自本地接口的已建立的连接和连接。 之后,我们将把所有未处理的入站流量重定向到一个新的链,我们将把大部分的规则。当实现一个大型,自包含的规则集时,这总是一个好主意,因为它提供了一个非常简单的方法来启用或禁用功能,只需将流量汇入或绕过新链。 我们称这个链条 碰撞 。 我们也将使用一些其他链。最近的模块允许我们对不同类型的流量进行分类,然后检查连接是否与先前设置的类别匹配。 我们将使用这个策略来标记发送数据包到第一个碰撞目标的IP地址。我们将有一个规则检查第一个标志,并检查第二个数据包是否被发送到第二个目标。如果是,它设置另一个标志,指示它得到两个答案到目前为止。如果第二分组与第二目标不匹配,则丢弃它并且重置标志。 额外的链使用这个相同的策略来检查适当的标志,如果它继续在正确的路径上传递它。最后,一旦按顺序请求了最后一个数据包,SSH守护程序就会短暂地暴露出来,只是为了成功地碰撞的IP地址。然后再次自动隐藏。 所以基本上,如果我们认为我们的端口碰撞定规则作为不同的门进入我们的服务,我们将有三个门为我们的三个碰撞。这意味着,有 四个不同的位置,一个请求的IP地址可以是在:
  • 初始状态 :这是所有IP地址都在,直到他们成功发送一个数据包的第一个目标磕状态。这不会被最近的模块设置,并且只是一种引用没有设置标志的客户端的方式。
  • auth1状态 :地址已成功碰撞了第一碰撞目标被标记为“auth1”。从这里,来自该主机的下一个分组确定该地址是否将被放回初始状态或移动到“auth2”状态。
  • auth2状态 :在这种状态下标记地址已经成功碰撞序列中的第一和第二目标。来自此主机的下一个数据包确定主机是否将被设置回初始状态或设置为“auth3”状态。
  • auth3状态 :已标记为“auth3”地址已成功地碰撞了所有三个端口,为了在时间的分配量。如果标记为“auth3”的地址尝试立即访问服务(在提供的窗口中),则将接受连接。如果接收到任何其他业务,则地址将被恢复到初始状态。
除了这些状态,其将是由最近模块设置的标志,每个门或判定点将被实现为链。链可以总结如下:
  • GATE1:确定在初始状态的地址是否应标为“auth1”。
  • GATE2:确定在“auth1”状态的地址是否应被处理到“auth2”或复位为“初始”状态。
  • GATE3:确定在“auth2”状态的地址是否应该被标记为“auth3”以允许SSH连接,或者重置为“初始”状态。
  • 决议 :该链是用来简单地打开端口的SSH服务为已成功碰撞客户。来自此链中不是发往SSH守护程序的客户端的任何流量将被删除,导致状态重新设置为“初始”。
正如你所看到的,我们在这里有很多决策点。每一种在 碰撞链及其子链的流量应被丢弃(除了从成功的碰撞客户的SSH守护交通),无论它是否匹配正确的端口。内部标记是唯一将跟踪成功尝试的事件,并且此逻辑不会暴露给客户端。 这对于端口碰撞实现是有效的是必要的。试图连接的人应该不接收关于他们进入的过程的哪个阶段或者即使这样的机制到位的反馈。

配置定期防火墙框架

我们将开始为我们的连接打下一个基本框架。上面讨论的策略将应用于INPUT链,该链处理所有传入连接。 我们将从清除现有的防火墙规则开始,以便我们可以从一个干净的slate开始。在刷新规则之前,总是一个好主意,重申空表中的默认策略是“ACCEPT”,以便维护当前连接:
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
这将确保我们从一个完全开放的防火墙开始,我们可以开始限制。 在我们开始限制之前,我们要添加我们将使用的附加链:
sudo iptables -N KNOCKING
sudo iptables -N GATE1
sudo iptables -N GATE2
sudo iptables -N GATE3
sudo iptables -N PASSED
在这一点上,我们应该有八个不同的链!我们将使用所有这些,除了OUTPUT和FORWARD链,这在我们的上下文中不涉及。 首先,我们应该添加我们不想处理的端口碰撞到INPUT链的流量。我们可以开始接受所有当前连接,这将允许我们当前的SSH连接保持不受影响:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
我们还应该接受来自本地机器的所有连接,因为服务通常需要彼此通信:
sudo iptables -A INPUT -i lo -j ACCEPT
如果您的服务应该保留在外部并可公开访问(例如Web服务器),请使用以下格式添加规则以允许此类型的连接:
sudo iptables -A INPUT -p protocol --dport port -j ACCEPT
在我们的示例中,我们假设我们有一个Web服务器在默认端口80上运行,我们将允许此流量:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
现在我们已经配置了基本的允许连接,我们可以将所有未在上述规则中处理的流量转移到我们的KNOCKING链中去做实际的碰撞逻辑:
sudo iptables -A INPUT -j KNOCKING

配置第一个门

当我们完成配置我们的“门”时,我们将它们全部挂在KNOCKING链中,以引导流量通过我们的逻辑测试。在我们这样做之前,我们应该开发我们的个别逻辑单元。 我们将开始定义我们的初始碰撞测试。当客户端连接时,我们只需要看看他们是否正在向我们的第一个目标发送数据包。如果它们是,我们将客户端标记为传递第一个测试并删除连接。如果他们不是,我们只是删除连接。 我们将首先在正确的端口尝试设置标志:
sudo iptables -A GATE1 -p tcp --dport 1111 -m recent --name AUTH1 --set -j DROP
这行做了很多事情。首先,它是一个规则附加到GATE1链。当使用的协议是“tcp”时,并且当它试图访问的端口是“1111”,我们的第一个碰撞的目标,这个规则将匹配。 如果这是真的,近期模块(调用 -m recent )的名称AUTH1(带,标志请求IP地址 --name AUTH1 --set规则)。这是我们将使用的标志,看看第二次碰撞是否匹配。在标志被设置之后丢弃分组,使得客户端不知道是否发生了任何事情。 接下来,我们将刚落,其他所有的数据包,因为发送到这个链条的任何信息 在寻找在这一点上匹配的第一个数据包:
sudo iptables -A GATE1 -j DROP
我们现在有我们的第一个港口。如果请求了正确的端口,则规则匹配和标记地址,或者不采取动作,并且简单地丢弃分组。

配置第二个门

第二门以与第一门几乎相同的方式配置。这 稍微复杂一些,虽然。 首先,将流量发送到此链中的逻辑将存在于主KNOCKING链中。这个链不必检查由第一个门设置的标志是否匹配,因为这将已经发生。 但是 ,它具有以除去任何标志它开始处理之前。如果它没有删除标志,那么地址可以用不同的名称标记,这可能导致地址成功碰撞只是扫描您的端口三次。这绝对不是我们想要的。 我们将在初步规则中再次使用最近的模块,这次只是为了清除名称:
sudo iptables -A GATE2 -m recent --name AUTH1 --remove
这是一个处理规则,所以我们不做任何决定或跳跃。我们只需剥离当前标志(将允许流量进入此链),并将其发送到下一个规则。 现在地址已经超过我们在这个链中的第一个规则,它处于一个没有标志的干净状态。此时,我们检查此连接尝试是否与下一个端口目标的正确匹配:
sudo iptables -A GATE2 -p tcp --dport 2222 -m recent --name AUTH2 --set -j DROP
这是以与第一门几乎相同的方式处理。我们只需设置AUTH2标志,指示请求地址通过第二个测试,如果正确的端口被碰撞。该标志被设置并且分组被再次丢弃,给予客户端没有他们的进展的指示。 下一个规则可能看起来有点奇怪。
sudo iptables -A GATE2 -j GATE1
你可以假设,在这一点上丢弃数据包是合乎逻辑的事情。然而,这将导致在一个具体情况下的尴尬局势。 如果我们在这里有一个“删除所有”的规则,在这一点上发送数据包的 第一个目标磕匹配,它不会被注册为碰撞序列的开端。 例如,如果我们的客户端意外地碰到第一个端口两次,它将不会注册正确,因为防火墙会看到这样的序列:
  • 第一个港口。防火墙标记第一个测试通过。将检查第二个端口接下来。
  • 第一个港口。不匹配第二个端口规则。序列被复位。将检查下一个第一个端口。
  • 第二港口。不匹配第一个端口规则。序列被复位。将检查下一个第一个端口。
  • 第三港口。不匹配第一个端口规则。序列被复位。将检查下一个第一个端口。
如你所见,第一,第二,第三序列已经完成,但防火墙已经弄糊涂了应该检查什么规则。在这种情况下,客户端必须在开始真实序列之前发送虚拟请求,以便在发生错误时重置链。 为了避免这种情况,我们将 只是丢弃该数据包在这一点上,并用它做。相反,我们将利用我们已经配置的GATE1链。如上所述,我们可以简单地将不匹配第二个目标的流量发送到第一个门:
sudo iptables -A GATE2 -j GATE1
这将导致客户端序列中的位置以两种方式之一重置。如果请求是针对第一个端口的,则该序列被重新启动为成功的第一次碰撞。如果它不是第一个端口,它会像往常一样丢弃。这避免了上述情况。

配置第三门

我们可以使用我们从第二门学到的知识,以相同的方式实现第三门。 首先,我们要清除给我们的地址的所有标志,以便这个运行通过链将设置正确的状态没有过期的标志从前:
sudo iptables -A GATE3 -m recent --name AUTH2 --remove
接下来,我们将测试连接尝试是否匹配第三个碰撞目标。如果是,我们设置AUTH3标志,表示客户端成功完成所有需要的碰撞。按照惯例,我们之后丢弃数据包。
sudo iptables -A GATE3 -p tcp --dport 3333 -m recent --name AUTH3 --set -j DROP
从这里,我们再次发送不匹配第三个碰撞的流量回到第一个门,看看是否应该算作一个成功的第一次碰撞重新启动序列:
sudo iptables -A GATE3 -j GATE1
在这一点上,已经完成正确碰撞键序列的客户端应该用AUTH3标记,这将使我们能够在PASSED链中轻松地为他们打开服务。

配置通过的链

此链用于打开SSH守护程序30秒到客户端成功碰撞正确的序列。 我们以与其他人相同的方式开始。只有从客户端发送的下一个数据包请求它时,SSH守护程序才可用。这迫使那些随机尝试通过碰撞的用户在每次尝试之间尝试SSH连接。 首先,我们做通常的标志重置:
sudo iptables -A PASSED -m recent --name AUTH3 --remove
接下来,我们接受来自进入此链的用户的SSH连接:
sudo iptables -A PASSED -p tcp --dport 22 -j ACCEPT
再次,我们通过我们的第一个链发送所有不匹配的流量,看看它是否匹配第一个端口碰撞目标:
sudo iptables -A PASSED -j GATE1
现在,我们已经配置了所有的子链,但是我们的一般KNOCKING链,它将流量传递到这些单独的链。

配置碰撞链

现在我们已经配置了所有的子链,我们可以将它们挂在我们通用的KNOCKING链中,并创建如何传递流量的逻辑。 首先,我们将把已成功完成所有碰撞的客户的流量直接传递到PASSED链。 我们有一些选择。我们可以实现一个时间限制,只给成功的客户端一个30秒的窗口连接到守护进程。之后,规则将不再成功匹配。
sudo iptables -A KNOCKING -m recent --rcheck --seconds 30 --name AUTH3 -j PASSED
接下来,我们将测试从最严格到最少的每个其他标志。我们可以添加10秒的时间限制之前的碰撞也过期。这将需要我们的客户端在10秒内完成碰撞的下一阶段,然后在另一个30秒内连接到SSH守护进程。
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH2 -j GATE3
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH1 -j GATE2
现在,我们希望像往常一样,将迄今为止没有匹配的所有流量都发送回GATE1。这将抓住任何尝试的第一次碰撞:
sudo iptables -A KNOCKING -j GATE1
这将基本上为我们的KNOCKING链设置默认丢弃策略,通过将GATE1逻辑隐式地添加到KNOCKING链的末尾。 在这一点上,我们有所有的碰撞链。我们添加了一些额外的结构来划分我们的逻辑。整个KNOCKING链结构及其子链链接到我们的常规输入链。 在这一点上,我们的端口碰撞机制被配置。现在是时候来测试它了。

测试我们的端口碰撞

有许多实用程序可用于生成我们的端口碰撞配置所需的TCP数据包。我们将使用 nmap命令,因为它是目前在默认情况下大多数系统。 默认情况下,Nmap使用TCP数据包。我们需要告诉它放弃其默认行为的主机发现部分,以便这些数据包不会干扰我们的碰撞。此外,我们希望我们的连接只在一秒钟后超时,以便我们可以继续下一个碰撞。 有了这些要求,单个碰撞可能看起来像这样。我们将使用我们的第一个碰撞实例作为例子:
nmap -Pn --host_timeout 201 --max-retries 0 -p 1111 your_server
因此,我们的整个碰撞序列可以由这些命令表示:
nmap -Pn --host_timeout 201 --max-retries 0 -p 1111 your_server
nmap -Pn --host_timeout 201 --max-retries 0 -p 2222 your_server
nmap -Pn --host_timeout 201 --max-retries 0 -p 3333 your_server
我们将有30秒连接我们的SSH客户端。 我们可以利用一些真正基本的bash脚本来自动化这一点。我们可以使用“for”循环来遍历我们的端口序列,然后将其传递给SSH客户端:
for x in 1111 2222 3333; do nmap -Pn --host_timeout 201 --max-retries 0 -p $x your_server && sleep 1; done && ssh user@your_server
这将碰撞第一个端口,等待一秒钟,碰撞下一个,依此类推,直到序列完成。然后它将尝试连接服务器的SSH守护程序。 我们可以把它放在一个文件中清理一下。我们叫它 knock_client 。在文本编辑器中创建:
nano knock_client
#!/bin/bah

ports="1111 2222 3333"
host="your_server"

for x in $ports
do
    nmap -Pn --host_timeout 201 --max-retries 0 -p $x $host
    sleep 1
done
ssh user@${host}
保存并关闭文件。 使用此命令使文件可执行:
chmod 755 knock_client
现在,我们可以连接到我们的服务器,通过键入:
./knock_client
现在我们已经验证了我们的规则按预期工作,我们可以通过在我们的服务器上下载一个单独的包来使防火墙规则持久:
sudo apt-get install iptables-persistent
我们可以通过启用此服务在启动时应用我们的规则:
sudo service iptables-persistent start

结论

到目前为止,您应该使用一个完全可操作的端口碰撞系统,只使用iptables防火墙中包含的功能。这有几个优点。首先,iptables是非常常用的,并经常审查安全问题。这意味着,只要你的规则做你 认为他们这样做,这应该是相当安全的。 此配置对单独的碰撞后台程序提供的另一个优点是,没有机会碰撞服务失败,并让您锁定在您的服务器之外。如果iptables服务失败,您至少可以输入您的服务器进行修复。
作者:Justin Ellingwood
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏