带有ProxyCommand和BASH脚本的SSH配置动态端口

时间:2019-02-25 19:22:44

标签: bash ssh ssh-config

我有一个服务器设置,可以在一段时间后将它的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端口,这样看起来有点干净。 >

谢谢:)

1 个答案:

答案 0 :(得分:1)

现代的使用“跳跃主机”的方法是使用-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,这将打开从本地主机到jump的连接,然后打开一个从jumpfinal的连接,并启用必要的转发。

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

给出一条类似于您的配置行:

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

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

#!/bin/sh

# ... custom stuff ...

# new final line:
eval "$@"