端口敲门是一种增强服务器安全性的方法,它通过对防火墙端口进行隐蔽控制来实现。 这些端口在默认情况下是关闭的,只有当收到预定义的“敲门”序列后才会按需打开。
端口敲门:一种“秘密敲门”机制
端口敲门的理念类似于 20 世纪 20 年代禁酒时期的“地下酒吧”。当时,进入这些场所需要知道特定的敲门方式。 端口敲门在数字世界中扮演着类似的角色,它允许你在不暴露所有端口的情况下,控制对服务器服务的访问。 你可以关闭防火墙上通常用于传入连接的端口,并设置一个特定的连接尝试模式作为“敲门”,在识别该模式后自动打开这些端口。 这种模式充当一个秘密口令,而另一组不同的敲门模式则可以用来关闭端口。
虽然端口敲门听起来很新奇,但它本质上属于“隐蔽式安全”的范畴,这种安全方法依赖于对访问方法的保密。这种策略的根本缺陷在于,一旦秘密泄露(不论是通过暴露、观察、猜测还是其他方式),安全性就会失效。 建议使用更强大的安全措施,如为 SSH 服务器启用基于密钥的登录。
更强大的网络安全通常是多层次的。 端口敲门可以作为多层次防御体系中的一层,尽管有人认为它可能不会对一个已经强化了的安全系统增加太多价值。网络安全是一个复杂的问题,不应仅仅依赖端口敲门作为唯一的防御措施。
安装 Knockd
为了演示端口敲门,我们将使用它来控制 SSH 端口(端口 22)。 我们将使用一个叫做 knockd 的工具。 对于 Ubuntu 或其他基于 Debian 的系统,可以使用 apt-get 包管理器安装它。 其他 Linux 发行版可以使用各自的包管理工具进行安装。
安装命令如下:
sudo apt-get install knockd
你可能已经在系统上安装了 iptables 防火墙,但可能还需要安装 iptables-persistent 软件包。 它用于处理保存的 iptable 规则的自动加载。
使用以下命令进行安装:
sudo apt-get install iptables-persistent
当 IPV4 配置屏幕出现时,按空格键选择“是”。
在 IPv6 配置屏幕中再次按空格键选择“是”并继续。
以下命令允许已建立的连接继续。 现在,我们将发出另一个命令来关闭 SSH 端口,以确保现有 SSH 连接不会中断:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
此命令的功能是:
-A
: 将规则附加到防火墙规则表的末尾。INPUT
: 规则应用于传入的连接。-m conntrack
: 使用 conntrack 模块,它与内核的网络连接跟踪功能配合使用。 它允许iptables根据数据包的连接状态采取操作。--ctstate ESTABLISHED,RELATED
: 规则应用于已建立的连接(即正在进行的连接)和 RELATED 连接(由已建立的连接触发的连接,例如下载文件)。-j ACCEPT
: 如果流量符合规则,则允许其通过防火墙。
现在我们可以使用以下命令来关闭端口:
sudo iptables -A INPUT -p tcp --dport 22 -j REJECT
该命令向防火墙添加以下规则:
-A
: 将规则附加到防火墙规则表的末尾。INPUT
: 规则应用于传入连接。-p tcp
: 规则应用于使用 TCP 协议的流量。--dport 22
: 规则特别针对端口 22(SSH 端口)的 TCP 流量。-j REJECT
: 如果流量符合规则,则将其拒绝,不允许通过防火墙。
我们需要启动 netfilter-persistent 守护进程,使用以下命令实现:
sudo systemctl start netfilter-persistent
我们需要 netfilter-persistent 进行 保存和重新加载循环,以便加载和控制 iptable 规则。
输入以下命令:
sudo netfilter-persistent save
sudo netfilter-persistent reload
现在,你已经安装了所需的实用程序,SSH 端口应该已关闭(但不会中断任何现有连接)。 接下来,我们需要配置秘密敲门。
配置 Knockd
你需要编辑两个文件来配置 knockd。 首先是 knockd 配置文件,如下所示:
sudo gedit /etc/knockd.conf
这将打开 gedit 编辑器,其中加载了 knockd 的配置文件。
我们需要修改这个文件以适应我们的需求。 我们主要关注 “openSSH” 和 “closeSSH” 部分。 每个部分都有四个条目:
sequence
: 打开或关闭端口 22 所需访问的端口序列。 默认的打开序列是 7000、8000 和 9000,默认的关闭序列是 9000、8000 和 7000。 你可以修改这些端口,也可以在列表中添加更多端口。 我们将使用默认设置。seq_timeout
: 触发打开或关闭操作所需访问端口的时间段。command
: 触发打开或关闭操作时发送到 iptables 防火墙的命令。 这些命令用于在防火墙中添加规则(以打开端口)或删除规则(以关闭端口)。tcpflags
: 每个端口在秘密序列中必须接收的数据包类型。 SYN(同步)数据包是 TCP 连接请求,也被称为 三次握手 的一部分。
“openSSH” 部分可以理解为 “必须在 5 秒内按顺序向端口 7000、8000 和 9000 发送 TCP 连接请求,才能将打开端口 22 的命令发送到防火墙。”
“closeSSH” 部分可以理解为 “必须在 5 秒内按顺序向端口 9000、8000 和 7000 发送 TCP 连接请求,才能将关闭端口 22 的命令发送到防火墙。”
防火墙规则
“openSSH” 和 “closeSSH” 部分的 “命令” 条目保持基本不变,只有一个参数不同。 它们的结构如下:
-A
: 将规则附加到防火墙规则列表的末尾(用于 openSSH 命令)。-D
: 从防火墙规则列表中删除命令(用于 closeSSH 命令)。INPUT
: 规则与传入的网络流量相关。-s %IP%
: 请求连接设备的 IP 地址。-p
: 网络协议; 这里是 TCP。--dport
: 目标端口; 在本示例中,它是端口 22。-j ACCEPT
: 跳转到防火墙内的 ACCEPT 目标。 这允许数据包通过,而不会被其余的规则丢弃。
knockd 配置文件编辑
下面我们将突出显示对文件进行的编辑(红色部分):
我们将 “seq_timeout” 延长到 15 秒。 这给出了足够的时间,如果用户手动触发连接请求,可能会需要这么长时间。
在 “openSSH” 部分,我们将命令中的 -A
(附加)选项更改为 -I
(插入)。 该命令会在防火墙规则列表的顶部插入新的防火墙规则。 如果保留 -A
选项,它将添加到列表的末尾。
防火墙规则从上到下依次检查传入流量。 我们已经有一个关闭端口 22 的规则。 因此,如果传入流量在看到允许流量的规则之前匹配到此规则,连接将被拒绝; 如果先匹配到新规则,则允许连接。
close 命令会删除 openSSH 添加的规则。 之后,预先存在的 “端口 22 已关闭” 规则将再次处理 SSH 流量。
完成这些修改后,保存配置文件。
knockd 控制文件编辑
knockd 控制文件更加简单。 但是,在编辑之前,我们需要知道网络连接的内部名称。 你可以使用以下命令来查找:
ip addr
用于撰写本文的机器上的连接名称是 enp0s3。 记下你的连接名称。
以下命令用于编辑 knockd 控制文件:
sudo gedit /etc/default/knockd
这是 gedit 中的 knockd 文件。
以下是一些需要修改的地方(以红色突出显示):
我们将 “START_KNOCKD=” 条目从 0 改为 1。
我们还从 “KNOCKD_OPTS=” 条目开头删除了哈希符号 #,并将 “eth1” 替换为我们的网络连接名称 enp0s3。 当然,如果你的网络连接是 eth1,则无需进行更改。
验证配置
现在是时候验证配置是否生效。 使用以下命令启动 knockd 守护进程:
sudo systemctrl start knockd
接下来,我们将切换到另一台机器并尝试连接。 我们也在这台计算机上安装了 knockd 工具,但不是为了设置端口敲门,而是因为 knockd 包提供了一个名为 knock 的工具。 我们将使用此工具来发送秘密序列,从而执行“敲门”。
使用以下命令将秘密连接请求发送到 IP 地址为 192.168.4.24 的端口敲门主机:
knock 192.168.4.24 7000 8000 9000 -d 500
这告诉 knock 向 IP 地址为 192.168.4.24 的计算机发送连接请求,依次发送到端口 7000、8000 和 9000,请求之间的延迟(-d)为 500 毫秒。
然后,用户 “dave” 向 192.168.4.24 发送 SSH 请求:
ssh [email protected]
他的连接被接受,他输入密码,远程会话开始。 他的命令提示符从 [email protected] 变为 [email protected] 。要注销远程计算机,他输入:
exit
他的命令提示符返回到本地计算机。 他再次使用 knock,这次以相反的顺序锁定端口,关闭远程计算机上的 SSH 端口:
knock 192.168.4.24 9000 8000 7000 -d 500
虽然这并不是一个特别有意义的远程会话,但它通过端口敲门演示了端口的打开和关闭过程,并足以在一个屏幕截图中展示。
那么,从另一边看,情况如何呢? 端口敲门主机上的系统管理员可以使用以下命令查看系统日志中的新条目:
tail -f /var/log/syslog
你会看到三个 openSSH 条目,它们在远程端口敲击实用程序尝试访问每个端口时被记录。
当触发序列的所有三个阶段都满足时,会记录 “芝麻开门” 信息,并发送将规则插入 iptables 规则列表的命令。 此规则允许来自具有正确秘密敲击的计算机 (192.168.4.23) 的特定 IP 地址通过端口 22 访问 SSH。
用户 “dave” 只连接了几秒钟,然后断开连接。
你会看到三个 closeSSH 条目,它们在远程敲击实用程序访问每个端口时生成,目的是关闭端口敲门主机上的端口 22。
在所有三个阶段都被触发后,我们再次收到 “芝麻开门” 信息,并发送命令到防火墙,以删除允许连接的规则。(为什么关闭端口时不是 “关门芝麻”?谁知道呢?)
现在,iptables 规则列表中关于端口 22 的唯一规则是我们在开始时输入的关闭端口的规则。 因此,端口 22 再次关闭。
总结
这就是端口敲门的技巧。 把它当作一种娱乐,不要在实际应用中过度依赖它。 如果你必须使用它,不要把它作为唯一的安全措施。