如何创建一个bash脚本来检查SSH连接?


86

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

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


2
通常,运行时ssh-keygen会在本地计算机上生成密钥对,然后ssh-copy-id将公钥复制到远程计算机。看来您做事的方式有所不同。为什么,您的目标是什么?
短暂

1
由于您显然正在更改远程计算机建立连接的方式,因此请考虑部署moshmosh.mit.edu用于在不稳定的连接上补充SSH。我有很好的经验。
2013年

@ephemient我知道这有点晚了,但是看起来很简单,他们输入的密钥不是本地计算机的,也不是本地用户的。
被遗弃的购物车

Answers:


170

您可以使用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-port的实际状态感兴趣,可以grep openegrep 'open|closed|filtered'以下命令代替:

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

只是为了完整。


1
为了完整起见,您能指出哪个返回码表示成功,哪个表示SSH失败?
亨利·邱2015年

想知道SSH尝试只是挂在那里怎么办?
西伯斯赌博

2
好答案!但是,您没有提到尝试ssh进入故障主机仅在超时(例如60秒)后失败-这对于某些用法可能是禁止的。另外,如果在中定义了主机名~/.ssh/config,则第ssh一种方法有效,而第二种nmap方法失败Failed to resolve "<hostname>"
ssc

2
根本没有关于命令的解释……或者您实际上在做什么……是什么$??等
Toskan

#1的一种更简洁的形式: ssh -q user@downhost exit | echo $? 将连接结果通过管道
传递

22
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

2
一行输出:(ssh -q -o“ BatchMode = yes” -o“ ConnectTimeout = 3” user@host.com“ echo 2>&1” && echo SSH_OK || echo SSH_NOK)| tail -n1
Xdg


14

可以补充@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

7

尝试:

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

1
这种方法的一个问题是,它不承认在ssh_config中定义(即在/ etc / SSH / config或的〜/ .ssh /配置)的主机
鼎陈义

1

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

ssh -q -o BatchMode=yes user@remote.com exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi

大!我还建议添加-o ConnectTimeout = 5,以便在过滤目标端口的情况下更快地退出。
丹尼尔

0

万一有人只想检查远程计算机上的端口22是否打开,此简单的netcat命令很有用。我使用它是因为nmap和telnet对我不可用。此外,我的ssh配置使用键盘密码auth。

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

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

0

如果您想检查一个远程文件夹是否存在,或者是否真的进行任何其他文件测试:

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

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


这不能回答问题。OP希望检查是否可以建立SSH连接,而不检查远程ssh位置中的文件。
拉基布·菲哈

0

连接到具有多个接口的服务器

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

0

使用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

0

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

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

ping -w 1 -c 1 "IP Address" 

创建bash脚本的命令。


2
这将仅ping远程IP。不保证是否可以进行ssh连接。
RJ

感谢您指出,这是ssh的代码 xlinu.blogspot.com/2019/09/…export user =“用户名” export pass =“密码” export i =“主机名” export SSHPASS = $ pass sshpass -e ssh $ user @ $ i -q“ echo $ i是可访问的”
Dheeraj Kumar

-7

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

使脚本具有容错能力非常好,但是您可能还希望使Boxen容错。


4
Sam:在有效的用例中,脚本可以对其进行检查。例如(像我一样):我的计算机上运行了一个cron作业,以通过rsync将数据备份到我的家庭nas。现在我很在外面,甚至经常断开连接,如果连接不可用,需要重新安排时间。我的拳击手跑得很好,但俗话说:总是电缆(又名网络)
stwissel 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.