我使用 SSHMatch exec
功能在建立连接时触发脚本,例如:
Match host foo* exec "/some/script.sh"
Host foo
User ubuntu
[... rest of ssh config file truncated ...]
我面临的问题是 ssh 将继续进行任何连接,无论使用 exec 调用的脚本的退出代码如何(/some/script.sh
在本例中)。
如果脚本退出非零代码,有什么办法让它停止一切(不继续进行 ssh 连接)?
答案1
注意:如果脚本的作用已知,则可能有其他可能性,而不仅仅是阻止连接。例如,如果脚本要确定笔记本电脑当前是否正在使用/未使用某些特定网络,那么它可以使用ProxyJump
中间服务器进行连接,而不是断开连接。
假设脚本失败时退出时的值不为 0,您可以使用启用配置来反转脚本的返回条件!
,该配置将使连接在脚本失败时失败(当然您也可以反转脚本的退出代码)。那么Match
只有当脚本失败时才会使用该行下面的参数。
Match host foo* exec "! /some/script.sh"
... some settings to derail the connection: see below ...
Host foo
User ubuntu
[... rest of ssh config file truncated ...]
我不知道有哪个选项专门阻止连接,但某些参数可用于破坏连接。
可以使用任何保证连接失败的参数。某些功能可能取决于操作系统。以下是一些用于替换... some settings to derail the connection: see below ...
连接失败的示例行:
使用备用地址和端口
Hostname 127.0.0.1
并Port xxxx
确保它连接到没有任何监听的地方Hostname 127.0.0.1 Port 2345
仅当脚本失败时才会得到:
$ ssh foo ssh: connect to host 127.0.0.1 port 2345: Connection refused
具有 root 访问权限的人可以为此指定一个失败的 IP 地址(并且无需更改端口):
以 root 身份在 Linux 上运行的示例:
ip route add unreachable 192.0.2.2/32
然后只需:
Hostname 192.0.2.2
给予:
$ ssh foo ssh: connect to host 192.0.2.2 port 22: No route to host
(Linux) 绑定到
lo
接口,导致路由失败BindInterface lo
给予:
$ ssh foo ssh: connect to host foo port 22: Invalid argument
但这不会阻止 ssh 自身(例如:如果
foo
是系统自己的地址)。未知主机
GlobalKnownHostsFile /dev/null UserKnownHostsFile /dev/null StrictHostKeyChecking yes ConnectTimeout 1
这仍然会尝试连接,但会失败,因为它永远找不到主机提供的指纹:
$ ssh foo No ECDSA host key is known for foo and you have requested strict checking. Host key verification failed.
当然,如果脚本失败与连接问题有关,这还不够,但是超时可以缓解这种情况,只需 1 秒后即可得到此结果:
$ ssh foo ssh: connect to host foo port 22: Connection timed out