我们有一个自动化工具,它试图通过SSHlogin并发送命令,这在服务器运行时工作正常。 另一方面,当服务器启动时,我们的工具检查ssh端口(22)是否打开,如果打开,它会尝试连接到服务器并发送命令。
但是,当服务器处于启动顺序并且我们的自动化工具检查端口22是否打开时,它会尝试使用ssh客户端连接到服务器,但服务器拒绝或ssh客户端返回错误“ssh端口未打开”。
我们试图用telnet来调查这个问题,看到在启动序列中,sshd启动并打开端口22,并开始监听,但是它以某种方式再次closures端口并在一段时间内再次打开它。 这与我们的自动化工具尝试login的时间完全相同。
我的问题是 我们如何确保ssh端口成功打开并准备好接受命令?
谢谢您的回复,最好的问候
首先,自动化工具似乎没有validationssh的退出状态。 我会尽力解决那里的问题。
一个解决scheme是试图填补创build该工具的团队的错误。
另一个解决scheme是将ssh命令包装在一个脚本中,这个脚本可以透明地执行。 例如,在/opt/myproject/ssh_wraper.sh中创build一个脚本
在这里你可以有这样的东西:
SSH_EXIT_STATUS=255 while [[ $SSH_EXIT_STATUS -eq 255 ]];do ssh .... SSH_EXIT_STATUS=$? done
您可以在login之前放置一个循环,等待端口打开。
until nc -zvw 1 $host 22; do sleep 2 done ssh $host $cmd
如果你不想要一个无限循环的风险,如果条件永远不会实现,你可以设置一个“或”值。 锻炼留给读者。 🙂
easist解决scheme是否有自动化工具尝试login,如果失败,等待x分钟,然后再试一次?
在服务器启动的时候,可能会发生这样的奇怪事情。
你可以尝试试试从ssh user@host "echo 0 > /dev/zero"这样的退出状态。
如果命令成功完成,您将得到0 (表示系统已准备就绪)。 尝试失败将导致退出代码为255 。
你可能要考虑使用-o ConnectTimeout=和-o ConnectionAttempts= 。
不过,我也同意Steve的观点。 也许只是等一会儿。 根据您的工具尝试探测端口的积极性,在尝试login之前增加延迟。
你可以尝试的是添加一个脚本到你的服务器的引导序列(例如在/etc/rc.local中),这将closures端口22上的防火墙。这个脚本(如/ etc / rc.local)将在所有其他init脚本之后执行。 所以只要你的服务器没有完成启动顺序,端口22仍然是无法访问,在防火墙后面。 它具有不修改自动化工具的优点。
基于RHEL6操作系统。 也许init脚本在你的发行版上是不同的。
这是我在AWS中启动服务器时所做的工作,并且为了使其可用于SSH连接,我正在使用bash来执行此操作:
status="notknown" until [[ $status == "running" ]]; do status=$(EC2 tools command to get the status) if [[ $status != "running" ]]; then sleep 3; fi