原文: How to Use Port Knocking on Linux (and Why You Shouldn’t)
端口敲门是一种“暗号敲门”的技术
在20世纪20年代,当禁酒令盛行的时候,如果你想进入地下酒吧,你必须知道秘密的敲门声,并正确地敲出它才能进去。
敲门是一种现代的对应方法。如果你想让人们访问你电脑上的服务,但又不想打开你的防火墙进入互联网,你可以使用端口敲击法。它允许你关闭防火墙上允许传入连接的端口,并在预先安排的连接尝试模式下自动打开
这些端口,连接尝试序列作为暗号。另一个暗号则关闭该端口。
端口敲击是一种新奇的做法,但重要的是要知道它是一个通过隐蔽性实现安全的例子,而这个概念从根本上是有缺陷的。如何访问一个系统的秘密是安全的,因为只有特定群体中的人才知道它。但是,一旦这个秘密被揭露—无论是因为它被揭露、被观察、被猜测,还是被研究出来—你的安全就失效了。你最好用其他更强大的方式来保护你的服务器,比如要求SSH服务器使用基于密钥的登录方式。
最强大的网络安全方法是多层次的,所以,也许端口锁定应该是其中的一个层次。层数越多越好,对吗?然而,你可以争辩说,端口敲击对一个适当的加固的安全系统来说并没有增加多少(如果有的话)。
网络安全是一个庞大而复杂的话题,但你不应该把端口敲击作为你唯一的防御形式。
Installing knockd
sudo apt-get install knockd
您的系统可能已经安装了iptables防火墙,但您可能需要安装iptables-persistent软件包。它可以处理保存的iptables规则的自动加载。
输入以下内容进行安装:
sudo apt-get install iptables-persistent
以下命令告诉iptables允许已建立和正在进行的连接继续。现在我们将发出另一个命令来关闭SSH端口。
如果有人在我们发出此命令时通过SSH连接,我们不希望他们被切断:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
这条命令在防火墙上添加了一条规则,上面写着:
- -A:将该规则追加到防火墙规则表。就是说,把它加到底部。
INPUT: 这是一条关于传入连接的规则。
- -m conntrack: 防火墙规则对符合规则中标准的网络流量(数据包)采取行动。参数-m使iptables使用额外的数据包匹配模块—在这种情况下,称为conntrack的模块与内核的网络连接跟踪能力一起工作。
- -cstate ESTABLISHED,RELATED: 这指定了规则将适用的连接类型,即ESTABLISHED和RELATED连接。一个已建立的连接是一个已经在进行中的连接。相关连接是指由于已建立的连接的一个动作而产生的连接。也许有人想下载一个文件,这可能发生在一个由主机发起的新连接上。
- -j ACCEPT: 如果流量与规则匹配,就跳到防火墙中的ACCEPT目标。换句话说,该流量被接受并允许通过防火墙。
现在我们可以发出关闭端口的命令:
sudo iptables -A INPUT -p tcp --dport 22 -j REJECT
这个命令向防火墙添加一条规则,意思是:
- -A:将规则附加到防火墙规则表中,即将其添加到底部。
INPUT:此规则涉及传入连接。
- -p tcp:此规则适用于使用传输控制协议的流量。
- –dport 22:此规则专门适用于针对端口22(SSH端口)的TCP流量。
- -j REJECT:如果流量符合该规则,则跳转到防火墙中的REJECT目标。因此,如果拒绝了流量,则不允许通过防火墙。
我们必须启动netfilter-persistent守护程序。我们可以使用以下命令执行此操作:
sudo systemctl start netfilter-persistent
我们希望netfilter-persistent经过保存和重新加载周期,以便它可以加载和控制iptables规则。
输入以下命令:
sudo netfilter-persistent save
sudo netfilter-persistent reload
你现在已经安装了实用工具,并关闭了SSH端口(希望没有终止任何人的连接)。现在,是时候配置秘密敲门了。
Configuring knockd
现在我们需要编写配置文件 /etc/knockd.conf
我们将编辑这个文件以适应我们的需要。我们感兴趣的部分是 “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 “部分可以理解为 “必须向端口9000、8000和7000发出TCP连接请求,并在5秒内向防火墙发送关闭端口22的命令”。
The Firewall Rules
openSSH和closeSSH部分的 “命令 “条目保持不变,除了一个参数。它们是这样组成的:
- -A:将规则添加到防火墙规则列表的底部(对于openSSH命令)。
- -D: 从防火墙规则列表中删除该命令(对于closeSSH命令)。
INPUT: 这条规则关注的是传入的网络流量。
- -s %IP%: 请求连接的设备的IP地址。
- -p: 网络协议;本例中是TCP。
- -dport: 目标端口;在我们的例子中,是22端口。
- -j ACCEPT: 跳到防火墙中的接受目标。换句话说,让数据包通过其余的规则而不对其采取行动。
The knockd Configuration File Edits
我们把 “seq_timeout “延长到15秒。这很慷慨,但如果有人手动发射连接请求,他可能需要这么多时间。
在 “openSSH “部分,我们将命令中的-A(追加)选项改为-I(插入)。这个命令在防火墙规则列表的顶部插入了一个新的防火墙规则。如果你不使用-A选项,它就会追加防火墙规则列表并将其放在底部。
传入的流量会根据列表中的每个防火墙规则从上往下进行测试。我们已经有一个关闭22号端口的规则。因此,如果传入的流量在看到允许流量的规则之前就针对该规则进行测试,那么连接就会被拒绝;如果它先看到这个新规则,连接就会被允许。
关闭命令将openSSH添加的规则从防火墙规则中删除。SSH流量将再次由先前存在的 “22号端口已关闭 “规则处理。
在你做了这些编辑之后,保存该配置文件。
The knockd Control File Edits
knockd控制文件就更简单了。不过,在我们深入编辑之前,我们需要知道我们的网络连接的内部名称;要找到它,输入这个命令:
ip addr
这台机器用来研究这篇文章的连接被称为enp0s3。记下你的连接的名称。
下面的命令是对knockd控制文件的编辑:
sudo gedit /etc/default/knockd
这是修改之前的配置文件
修改后的配置文件
我们把 “START_KNOCKD=”条目从0改为1。
我们还删除了 “KNOCKD_OPTS=” 项开头的哈希#,并将 “eth1 “改为我们的网络连接名称enp0s3。当然,如果你的网络连接是eth1,你就不会改变它。
The Proof Is in the Pudding
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端口发出连接请求,它们之间有500毫秒的延迟。
然后一个叫 “dave “的用户向192.168.4.24发出一个SSH请求:
ssh dave@192.168.4.24
他的连接被接受,他输入了他的密码,他的远程会话开始了。他的命令提示符从dave@nostromo变为dave@howtogeek。要注销远程计算机,他键入:”:
exit
他的命令提示符返回到他的本地计算机。他再次使用knock,这一次,它以相反的顺序瞄准端口,关闭远程计算机上的SSH端口。
knock 192.168.4.24 9000 8000 7000 -d 500
无可否认,这并不是一个特别有成果的远程会话,但它展示了通过端口敲击来打开和关闭端口的情况,并适合于一张截图中。
那么,从另一边看这是什么样子呢?敲击端口的主机上的系统管理员使用下面的命令来查看到达系统日志中的新条目:
你看到三个openSSH条目。当每个端口被远程敲击工具锁定时,这些条目就会出现。
当触发序列的所有三个阶段都被满足时,一个写着 “OPEN SESAME “的条目被记录下来
将规则插入到iptables规则列表的命令被发送。它允许通过SSH在22端口从给出正确秘密敲门的PC的特定IP地址(192.168.4.23)访问。
用户 “dave “只连接了几秒钟,然后就断开了连接。
你看到三个closeSSH条目。这些条目是在每个端口被远程敲击工具锁定时提出的—它告诉敲击端口的主机关闭端口22。
在所有三个阶段都被触发后,我们再次得到 “OPEN SESAME “信息。该命令被发送到防火墙以删除该规则。(当它关闭端口时,为什么不是 “CLOSE SESAME”?谁知道呢?)
现在,iptables规则列表中关于22号端口的唯一规则是我们在开始时输入的关闭该端口的规则。所以,22号端口现在又被关闭了。