1

我有一个服务器设置,可以在一定时间后随机化它的 SSH 端口,并将端口发布到它的 Web 服务器上可用的 .txt 文件。然后,我在客户端上编写了一个简单的脚本,该脚本从 Web 服务器 .txt 文件中获取新端口并更新~/.ssh/config中的特定主机端口号。

因为~/.ssh/config无法解析 Bash 变量,所以我使用 ProxyCommand 调用脚本(我使用的是 JumpHost,而 JH 端口是动态端口)。

我的 ~/.ssh/config 如下:

Host jumphost
HostName jumphost.example.com
Port 51638
User bob
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null

Host myserver
HostName myserver.com
Port 2222
User bob
ProxyCommand ~/.ssh/get_dynamic_port.sh ssh -W %h:%p jumphost

Bash 脚本如下(get_dynamic_port.sh):

#!/bin/sh
PORT=$(curl -s http://jumphost.example.com/port.txt)
OLDIP=`grep -w "jumphost.example.com" -A 1 ~/.ssh/config | awk '/Port/ {print $2}'`
LINE_NUMBER=`grep -n "jumphost.example.com" -A 1 ~/.ssh/config | grep -v "jumphost.example.com" | awk '{print $1}' FS="-"`
sed -i'.bak' -e "${LINE_NUMBER}s/$OLDIP/$PORT/" ~/.ssh/config

该脚本工作正常并更新了 jumphost.example.com 的端口,但不幸的是我无法连接,ssh 在下面的调试输出中运行:

macosx:$ ssh -vvv myserver
OpenSSH_7.9p1, LibreSSL 2.7.3
debug1: Reading configuration data ~/.ssh/config
debug1: ~/.ssh/config line 54: Applying options for myserver
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 48: Applying options for *
debug1: Executing proxy command: exec ~/.ssh/get_dynamic_port.sh ssh -W myserver:2222 jumphost
debug1: identity file ~/.ssh/id_rsa type -1
debug1: identity file ~/.ssh/id_rsa-cert type -1
debug1: identity file ~/.ssh/id_dsa type -1
debug1: identity file ~/.ssh/id_dsa-cert type -1
debug1: identity file ~/.ssh/id_ecdsa type -1
debug1: identity file ~/.ssh/id_ecdsa-cert type -1
debug1: identity file ~/.ssh/id_ed25519 type -1
debug1: identity file ~/.ssh/id_ed25519-cert type -1
debug1: identity file ~/.ssh/id_xmss type -1
debug1: identity file ~/.ssh/id_xmss-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_7.9
ssh_exchange_identification: Connection closed by remote host

应该注意的是,在 jumphost 服务器上跟踪安全日志文件不会显示任何连接尝试,这可能是错误的迹象。

jumphost 配置在没有动态端口脚本的情况下可以正常工作,并且如上所述,脚本实际上正在正确更改 jumphost 的端口,但之后 ssh 就失败了。

任何关于如何实现这一目标或我可能做错了什么的想法都将不胜感激。我可以使用 crontab 条目每隔一段时间运行一次脚本来更新 jumphost 端口,但我宁愿只在建立连接时更新 jumphost 端口,这样看起来更干净一些。

谢谢 :)

4

1 回答 1

1

使用“jumphosts”的现代方式是使用-J选项 ( ProxyJump)。

使用该ProxyCommand选项仍然有效,并且可以通过调用脚本来灵活地运行任意设置代码,如此处所示。但是,您的代码最终必须运行适当的 ssh 命令来执行“跳转”。

典型的配置选项如下所示:

Host jump
    Hostname jumphost.fqdn
    User juser

Host final
    Hostname final.fqdn
    User fuser
    ProxyCommand ssh -W %h:%p jump

您运行ssh final它会打开一个从 localhost 到 的连接jump,然后打开另一个 from jumptofinal并启用必要的转发。

在您的配置中,您已替换ProxyCommand为执行某些设置的 shell 脚本。之后您仍然需要运行类似于普通 ssh 命令的内容。

给定一个像你这样的配置行:

ProxyCommand ~/.ssh/get_dynamic_port.sh ssh -W %h:%p jumphost

调用普通 ssh 命令(作为参数传递给 shell 脚本)的最简单方法是在最后调用它:

#!/bin/sh

# ... custom stuff ...

# new final line:
eval "$@"
于 2019-02-26T06:23:59.270 回答