【问题标题】:How to create a bash script to check the SSH connection?如何创建一个 bash 脚本来检查 SSH 连接?
【发布时间】:2010-11-27 04:19:20
【问题描述】:

我正在创建一个 bash 脚本,该脚本将登录到远程机器并创建私钥和公钥。

我的问题是远程机器不是很可靠,而且它们并不总是启动。我需要一个 bash 脚本来检查 SSH 连接是否已启动。在实际创建密钥以供将来使用之前。

【问题讨论】:

  • 通常,运行ssh-keygen 在本地机器上生成密钥对,然后运行ssh-copy-id 将公钥复制到远程机器。看来你做事的方式不同。为什么,你的目标是什么?
  • 由于您显然要更改远程计算机建立连接的方式,因此请考虑部署 mosh。 mosh.mit.edu 旨在补充不稳定连接上的 SSH。我有很好的经验。
  • @ephemient 我知道这有点晚了,但它们的关键是 not 用于本地机器或 not 用于本地机器似乎很简单用户。

标签: bash ssh connection


【解决方案1】:

你可以用 ssh 给你的返回值来检查:

$ ssh -q user@downhost exit
$ echo $?
255

$ ssh -q user@uphost exit
$ echo $?
0

编辑:另一种方法是使用 nmap(您不需要密钥或登录信息):

$ a=`nmap uphost -PN -p ssh | grep open`
$ b=`nmap downhost -PN -p ssh | grep open`

$ echo $a
22/tcp open ssh
$ echo $b
(empty string)

但是您必须对消息进行 grep(nmap 不使用返回值来显示端口是否被过滤、关闭或打开)。

编辑2:

如果您对 ssh 端口的实际状态感兴趣,可以将 grep open 替换为 egrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered'

只是为了完整。

【讨论】:

  • 为了完整,你能指出哪个返回码代表成功,哪个代表SSH失败?
  • 想知道如果 SSH 尝试只是挂在那里怎么办?
  • 很好的答案!但是,您没有提到尝试 ssh 进入停机主机仅在例如超时后才会失败。 60 秒 - 这对于某些用途来说可能是令人望而却步的。此外,如果在~/.ssh/config 中定义主机名,则第一个ssh 方法有效,而第二个nmap 方法失败并显示Failed to resolve "<hostname>"。
  • 对命令完全没有解释......或者你实际上在做什么......什么是$??等
  • @ssc 您可以添加 -o 选项来限制超时持续时间。以下示例将其缩短为 5 秒:ssh -o ConnectTimeout=5 -q user@downhost exit
【解决方案2】:

你可以使用这样的东西

$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

如果 ssh 连接正常,这将输出“ok”

【讨论】:

  • 如果需要密码并且错误地输出不正确,这将失败,尽管远程是可连接的。
  • 好答案但是您应该删除BatchMode 选项,以使其即使在需要密码的系统上也能正常工作。
【解决方案3】:
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK

【讨论】:

  • 一行输出:(ssh -q -o "BatchMode=yes" -o "ConnectTimeout=3" user@host.com "echo 2>&1" && echo SSH_OK || echo SSH_NOK) |尾 -n1
【解决方案4】:

补充@Adrià Cidre的回复你可以这样做:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

if [[ $status == ok ]] ; then
  echo auth ok, do something
elif [[ $status == "Permission denied"* ]] ; then
  echo no_auth
else
  echo other_error
fi

【讨论】:

    【解决方案5】:

    ssh 下面的命令在连接成功时应该有一个退出代码0,否则一个非零值。

    ssh -q -o BatchMode=yes user@remote.com exit
    
    if [ $? != "0" ]; then
        echo "Connection failed"
    fi
    

    【讨论】:

    • 太棒了!我还建议添加 -o ConnectTimeout=5,以便在目标端口被过滤的情况下更快地退出。
    【解决方案6】:

    试试:

    echo quit | telnet IP 22 2>/dev/null | grep Connected
    

    【讨论】:

    • 这种方法的一个问题是它无法识别 ssh_config 中定义的主机(即 /etc/ssh/config 或 ~/.ssh/config)
    【解决方案7】:

    按照@user156676,检查ips范围:

    #!/bin/sh
    IP='192.168.0.'
    PWD='your_password'
    USR='your_usr'
    
    for i in $(seq 229 255);do
        sshpass -p $PWD ssh -q -o ConnectTimeout=3 ${USR}@${IP}${i} exit
        let ret=$?
        if [ $ret -eq 5 ]; then
            echo $IP$i "Refused!"  $ret
        elif [ $ret -eq 255 ] ; then
            echo $IP$i "Server Down!" $ret
        elif [ $ret -eq 0 ] ; then
            echo $IP$i "Connnected!" $ret
        else
            echo $IP$i "Unknown return code!" $ret
        fi  
    done
    

    【讨论】:

      【解决方案8】:

      万一有人只想检查远程机器上的端口 22 是否打开,这个简单的 netcat 命令很有用。我使用它是因为我无法使用 nmap 和 telnet。此外,我的 ssh 配置使用键盘密码验证。

      它是 GUESSWHOz 提出的解决方案的变体。

      nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"
      

      【讨论】:

        【解决方案9】:

        如果您想检查远程文件夹是否存在,或者是否真的要检查任何其他文件:

        if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
            # exists
        else
            # doesn't exist
        fi
        

        不要忘记"$(ssh ...)" 中的引号。

        【讨论】:

        • 这没有回答问题。 OP 想要检查是否可以建立 SSH 连接,而不是检查远程 ssh 位置中的文件。
        【解决方案10】:

        使用多个接口连接到服务器

        ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.61;[ $? = 1 ] || ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.51
        

        【讨论】:

          【解决方案11】:

          使用 BASH 4+ 脚本的示例:

          # -- ip/host and res which is result of nmap (note must have nmap installed)
          ip="192.168.0.1"
          res=$(nmap ${ip} -PN -p ssh | grep open)
          
          # -- if result contains open, we can reach ssh else assume failure) --
          if [[ "${res}" =~ "open" ]] ;then
              echo "It's Open! Let's SSH to it.."
          else
              echo "The host ${ip} is not accessible!"
          fi
          

          【讨论】:

            【解决方案12】:

            https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html

            以上链接是创建用于检查连接性的 Python 脚本。 您可以使用类似的方法并使用:

            ping -w 1 -c 1 "IP Address" 
            

            创建 bash 脚本的命令。

            【讨论】:

            • 这只会ping远程IP。不保证 ssh 连接是否可行。
            • 感谢您指出,这里是 ssh xlinu.blogspot.com/2019/09/… export user="username" export pass="password" export i="hostname" export SSHPASS=$pass sshpass -e ssh $ 的代码user@$i -q "echo $i 是可访问的"
            【解决方案13】:

            我编写了这个脚本来检查我的服务器 /etc/hosts 中所有主机的 netcat 和 SSH 连接

            逐行读取/etc/hosts,然后尝试netcat 22端口,然后ssh作为“sshuttle”用户

            检查网络健全性的快速方法

            脚本使用“sshuttle”用户,这是一个在我的所有主机上都有 pub/priv 密钥的帐户,并且可以在任何地方进行 ssh(非 root 帐户),我们使用此帐户来启动 sshuttle VPN 隧道,但您可以添加任何对服务器具有 SSH 访问权限的帐户

            https://gist.github.com/perfecto25/8687d563716ba4923c77162be724beda

            输出,

            ./conncheck.sh
            
            
            netcat is installed, proceeding..
            --------------------------------------
            tm-us1 (127.0.0.1): ssh OK | nc OK
            --------------------------------------
            localhost (127.0.0.1): ssh OK | nc OK
            --------------------------------------
            atlas (192.168.142.21): ssh ERROR | nc OK
            --------------------------------------
            hydra (192.168.142.22): ssh OK | nc OK
            --------------------------------------
            nemesis (192.168.140.23): ssh OK | nc OK
            --------------------------------------
            vulcan (192.168.140.24): ssh OK | nc OK
            --------------------------------------
            athena (192.168.140.27): ssh OK | nc OK
            --------------------------------------
            nas1 (192.168.100.101): ssh ERROR | nc OK
            --------------------------------------
            tm-dev (192.10.23.71): ssh ERROR | nc ERROR
            --------------------------------------
            WARNING: Your password has expired.
            Password change required but no TTY available.
            infra01 (192.10.23.186): ssh ERROR | nc OK
            --------------------------------------
            ns-us1 (192.10.23.252): ssh ERROR | nc OK
            --------------------------------------
            ns-us2 (192.10.23.182): ssh ERROR | nc OK
            --------------------------------------
            proxy-us1 (192.10.23.120): ssh OK | nc OK
            --------------------------------------
            simtm-us1 (192.10.23.236): ssh OK | nc OK
            --------------------------------------
            tm-us1 (192.10.23.104): ssh OK | nc OK
            --------------------------------------
            tm-us2 (192.10.23.215): ssh OK | nc OK
            --------------------------------------
            tm-dev (192.10.23.77): ssh OK | nc OK
            --------------------------------------
            WARNING: Your password has expired.
            Password change required but no TTY available.
            tm-uat (192.10.23.225): ssh ERROR | nc OK
            --------------------------------------
            vpn-us1 (192.10.23.193): ssh OK | nc OK
            --------------------------------------
            

            【讨论】:

              【解决方案14】:

              我觉得你在这里试图解决错误的问题。您不应该尝试使 ssh 守护进程更稳定吗?尝试运行monit 之类的东西,它将检查守护程序是否正在运行,如果没有运行则重新启动它(让您有时间找到 sshd 关闭您背后的根本问题)。还是网络服务麻烦?尝试查看man ifup。整个该死的事情只是想关闭你吗?好吧,这是一个更大的问题...尝试查看您的日志(从 syslog 开始)以查找导致您的 boxen 关闭的硬件故障或服务(可能是温度监视器?)。

              使您的脚本具有容错性非常好,但您可能还希望使您的 boxen 具有容错性。

              【讨论】:

              • Sam:有有效的用例让脚本检查它。例如(像我一样):我有一个 cron 作业在我的机器上运行,通过 rsync 将我的数据备份到我家的 nas。现在我在外面,甚至经常断开连接,如果连接不可用,我需要重新安排。我的boxen运行得很好,但俗话说:它总是电缆(a.k.a network)
              猜你喜欢
              • 2016-10-12
              • 2017-01-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-12-17
              • 1970-01-01
              • 1970-01-01
              • 2022-10-21
              相关资源
              最近更新 更多