如何创建一个 bash 脚本来检查 SSH 连接?
Posted
技术标签:
【中文标题】如何创建一个 bash 脚本来检查 SSH 连接?【英文标题】:How to create a bash script to check the SSH connection? 【发布时间】:2010-11-27 04:19:20 【问题描述】:我正在创建一个 bash 脚本,该脚本将登录到远程机器并创建私钥和公钥。
我的问题是远程机器不是很可靠,而且它们并不总是启动。我需要一个 bash 脚本来检查 SSH 连接是否已启动。在实际创建密钥以供将来使用之前。
【问题讨论】:
通常,运行ssh-keygen
在本地机器上生成密钥对,然后运行ssh-copy-id
将公钥复制到远程机器。看来你做事的方式不同。为什么,你的目标是什么?
由于您显然要更改远程计算机建立连接的方式,因此请考虑部署 mosh。 mosh.mit.edu 旨在补充不稳定连接上的 SSH。我有很好的经验。
@ephemient 我知道这有点晚了,但它们的关键是 not 用于本地机器或 not 用于本地机器似乎很简单用户。
【参考方案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 *** 隧道,但您可以添加任何对服务器具有 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
--------------------------------------
***-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)以上是关于如何创建一个 bash 脚本来检查 SSH 连接?的主要内容,如果未能解决你的问题,请参考以下文章