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

时间:2016-03-02 07:49:28

标签: linux bash shell unix ssh

我有多个远程主机连接到我的本地主机(服务器-A)。为了确保/过滤真正可以访问localhost的主机列表,我会进行ping测试。

ping -c1 <remotehost-IP> 

if [ "$?" != "0" ];then
echo "Not reachable.Exiting..."
exit 1;
fi

然而,ping测试无法为我提供任何检查以确保通过SSH连接/端口22可以访问过滤的远程主机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连接可以,那么我进入远程主机或进入密码提示。这导致检查返回代码的障碍。

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

6 个答案:

答案 0 :(得分:5)

Netcat也应该做好这个工作。

nc -z host 22

-z指定不发送任何数据,仅扫描正在运行的守护程序

输出看起来像这样:

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

因此,如果你想以编程方式处理这个问题,你可以将输出抛出到/ dev / null,然后检查$?等于0以验证连接是否可用。

答案 1 :(得分:3)

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,但通常足以确定给定端口正在侦听。你的旅费可能会改变。

答案 2 :(得分:2)

这是满足问题的最简单的命令(不需要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 for&#34; Permission denied&#34;。如果主机正在为SSH服务,则返回退出状态0,无论凭据如何,并且不会等待密码输入。

答案 3 :(得分:1)

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

但是该进程可能不是sshd守护进程(某些系统管理员正在该端口上启动其他守护进程,例如某些HTTPS服务......)。

或者远程sshd守护程序已配置了非POSIX shell。例如,作为GCC的贡献者,我使用sshsvngcc.gnu.org,但我cannot在那里运行shell命令......

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

此外,ssh命令可能会暂时失败(例如,因为远程主机在您的用户下运行了太多进程,因此fork内的sshd将失败)

如果你想在某个程序中使用它,可以考虑使用像libssh这样的库。

顺便说一句,您可以将本地 .ssh/config配置为永不询问任何密码(或使用-F传递某些特定配置文件,确保不要求密码),或者(如CodeGnome所述,请使用ssh -o BatchMode=yes禁用密码提示。

答案 4 :(得分:0)

您可以使用nmap

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

答案 5 :(得分:0)

Nmap的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