如何在尝试建立 SSH 连接之前执行端口敲击序列(或执行端口敲击的命令)?
最好使用预装的ssh
命令,但如果没有“标准替代方案”,也愿意切换。
答案1
您也可以尝试使用选项代理命令。
它使您能够控制用于连接服务器的命令;听起来很麻烦,但我还没有发现任何问题。
来自ssh_配置文档:
代理命令
指定用于连接服务器的命令。命令字符串延伸到行尾,并使用用户的 shell“exec”指令执行,以避免 shell 进程延迟。
在命令字符串中,任何出现的 都
%h
将被要连接的主机名、%p
端口和%r
远程用户名替换。该命令基本上可以是任何内容,并且应该从其标准输入读取并写入其标准输出。它最终应该连接到SSHD(8)服务器在某台机器上运行,或在某处执行。主机密钥管理将使用所连接主机的sshd -i
来完成(默认为用户输入的名称)。将命令设置为将完全禁用此选项。请注意,对于使用代理命令的连接,不可用。HostName
none
CheckHostIP
该指令与北卡罗来纳州(1)及其代理支持。例如,以下指令将通过 192.0.2.0 上的 HTTP 代理进行连接:
ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
例子
假设你有一个命令或脚本在你的路径中进行敲击:knock.sh <host> <port1 port2 ... portX>
并且你想要连接到某个主机:myhost.net
您可以将以下内容添加到您的~/.ssh/config
Host thehost
HostName myhost.net
ProxyCommand bash -c 'knock.sh %h <port1 port2 ... portX>; nc %h %p'
- %h => 主机名 (myhost.net)
- %p => 端口 (22)
您可以使用以下命令连接到您的主机:ssh user@thehost
您还应该能够直接从命令行使用该选项:
ssh -o ProxyCommand="bash -c 'knock.sh %h <port1 port2 ... portX>; nc %h %p'" [email protected]
笔记
如果程序默认将数据写入标准输出,它会被隐藏,如果您需要看到它,请在-v
后面添加ssh
。
还要注意,ssh
在执行连接之前必须执行敲击,因此完成连接所需的总时间会更大。
我当前的配置已启用端口转发,目前还没有问题。
答案2
nc
像在接受的答案中那样将所有流量作为 ProxyCommand传送的另一种方法是Match host/exec
向 ~/.ssh/config 添加一行,该行仅在连接之前有效地执行您的knock
命令:
Match host thehost exec "knock -d 500 %h 1234 5678"
Match host thehost.domain.com exec "knock -d 500 %h 1234 5678"
这一行实际上除了执行之外没有做任何其他事情knock
,因为指令后面没有任何内容。
更新
为了使敲击有条件(并防止延迟和大量冗余的防火墙规则),请在敲击之前使用 netcat 进行探测:
Match host thehost exec "nc -zw 3 %h 22 || knock -d 500 %h 1234 5678"
Match host thehost.domain.com exec "nc -zw 3 %h 22 || knock -d 500 %h 1234 5678"
该-w 3
标志用于指定探测的 3 秒超时。
已更新,考虑到 Adrien 的评论
答案3
根据关于端口敲击的 Ubuntu 帮助页面,您可以执行以下操作:
knock
通过运行安装程序sudo apt-get install knockd
编写脚本来
~/bin
为特定服务器建立 SSH 连接:#!/bin/sh knock hostname port1 port2 port3... ssh hostname
使用以下命令使脚本可执行
chmod +x ~/bin/whatever
- 关闭终端,重新打开并运行
whatever