如何查找远程主机是否可以通过SSH访问,而不用实际执行ssh

我有多台远程主机连接到本地主机(server-A)。 为了确保/过滤真正可以到本地主机的主机列表,我做了pingtesting。

ping -c1 <remotehost-IP> if [ "$?" != "0" ];then echo "Not reachable.Exiting..." exit 1; fi 

然而,pingtesting不能提供任何检查以确保通过SSH连接/端口22可达到过滤的remotehost-IP。

  non-root-user@localhost>ssh 172.26.192.15 ssh: connect to host 172.26.192.15 port 22: Connection refused non-root-user@localhost>echo $? 1 non-root-user@localhost>ssh -v 172.26.192.15 OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Connecting to 172.26.192.15 [172.26.192.15] port 22. debug1: connect to address 172.26.192.15 port 22: Connection refused ssh: connect to host 172.26.192.15 port 22: Connection refused 

查询:

以上检查工作,如果连接被拒绝。 但是,如果可以使用SSH连接,则可以进入远程主机或进入密码提示。 这是检查返回码的原因。

所以我想知道是否有任何方法可以通过SSH预先检查远程IP是否可以访问或不可达。 ?

一个Bash特定的解决方案

如果您正在使用Bash shell,那么您可以访问TCP和UDP套接字。 例如:

 if (exec 3<>/dev/tcp/74.207.252.238/22) 2> /dev/null; then echo open else echo closed fi 

这并不能告诉你实际使用的协议是否真的是SSH,但通常足以确定给定的端口正在监听。 你的旅费可能会改变。

Netcat也应该做这个工作。

 nc -z host 22 

-z指定不发送数据,只扫描正在运行的守护进程

输出结果如下所示:

 Connection to localhost 22 port [tcp/ssh] succeeded! 

所以,如果你想以编程的方式处理这一点,你可以把输出到/ dev / null,然后检查$? 等于0来验证连接是否可用。

其他的答案是检查某个进程是否在SSH端口22上的远程机器上侦听。

但是这个过程可能不是一个sshd守护进程(一些系统管理员正在启动其他守护进程,例如某些HTTPS服务)。

或者远程sshd守护进程已经配置了一个非POSIX shell。 例如,作为一个GCC贡献者,我使用ssh thru svngcc.gnu.org但是我不能在那里运行一个shell命令…

所以我相信你应该真的尝试ssh命令。 如果远程机器是POSIX,并且你希望有一些通过ssh运行的Posix shell,请尝试使用ssh remotehost /bin/true (或者可能是ssh remotehost 'echo $$' ,希望echo可以是远程shell内置的)

另外,一个ssh命令可能会暂时失败(例如,因为远程主机有太多的进程在你的用户下运行,所以sshd内的fork会失败)

如果你想在一些程序里面,考虑使用像libssh这样的库 。

顺便说一句,你可以配置你的本地 .ssh/config永远不要求任何密码(或传递-F某些特定的配置文件,确保没有密码问)或(如CodeGnome评论),使用ssh -o BatchMode=yes禁用密码提示。

你可以使用nmap

 nmap -p 22 --open -sV 172.26.192.0/24 > sshservers 

来自Nmap的Grep输出

如果您需要退出状态,请grep nmap的结果并使用grep的退出状态。 例如:

 $ nmap -sT -Pn -p 22 host.example.com | egrep 'open\s+ssh' 22/tcp open ssh 

在这个例子中,退出状态将来自于grep,而不是nmap。 如果端口打开,Grep将返回0如果不是,则返回1 。 你可以直接使用结果,或分支$? 。 例如:

 nmap -sT -Pn -p 22 host.example.com | egrep -q 'open\s+ssh' if [[ $? -ne 0 ]]; then echo 'Not reachable. Exiting ...' > /dev/stderr exit 1 fi 

这是满足问题的最简单的命令(不需要nmap或nc):

 ssh -o PubkeyAuthentication=no -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -o ChallengeResponseAuthentication=no host.foo.com 2>&1 | grep "Permission denied" 

说明:尝试使用通常的auth方法禁用,grep STDERR为“权限被拒绝”。 如果主机正在服务于SSH,则返回退出状态0,而不管凭据如何,并且不挂起等待密码输入。