bash 如何在不实际执行 ssh 的情况下查找远程主机是否可通过 SSH 访问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35741323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find if remote host is reachable over SSH without actually doing ssh
提问by Todd A. Jacobs
I have multiple remote hosts connected to my local host (server-A). TO ensure/filter the list of hosts which are genuinely reachable to localhost , I do ping test.
我有多个远程主机连接到我的本地主机(服务器-A)。为了确保/过滤真正可以访问 localhost 的主机列表,我进行了 ping 测试。
ping -c1 <remotehost-IP>
if [ "$?" != "0" ];then
echo "Not reachable.Exiting..."
exit 1;
fi
However ping test could not provide me any check to ensure that filtered remotehost-IPs are reachable over SSH connection /port 22.
但是,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
Query:
询问:
Above check work for me if connection is refused. However, if SSH connection is possible then I enter into the remote host or proceed to password prompt. Which cause barrier to check return code.
如果连接被拒绝,上面的检查对我有用。但是,如果可以进行 SSH 连接,那么我会进入远程主机或继续密码提示。这会导致检查返回码的障碍。
So I wanted to know if there is any way to check if the remote IP WOULD be reachable or not reachable over SSH beforehand. ?
所以我想知道是否有任何方法可以事先检查远程 IP 是否可以通过 SSH 访问。?
回答by Ze_Gitan
Netcat should also do the job.
Netcat 也应该完成这项工作。
nc -z host 22
-z specifies that no data be sent and to only scan for running daemons
-z 指定不发送数据并且只扫描正在运行的守护进程
The output will look something like this:
输出将如下所示:
Connection to localhost 22 port [tcp/ssh] succeeded!
So if you want to handle this a little more programmatically you could just throw the output to /dev/null and then check that the $? is equal to 0 to verify that the connection is available.
所以如果你想以编程方式处理这个问题,你可以将输出扔到 /dev/null 然后检查 $? 等于 0 以验证连接是否可用。
回答by Slack Flag
This is the simplest command that satisfies the question (without need for nmap or nc):
这是满足问题的最简单命令(不需要 nmap 或 nc):
ssh -o PubkeyAuthentication=no -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -o ChallengeResponseAuthentication=no host.foo.com 2>&1 | grep "Permission denied"
Explanation: attempt to connect with the usual auth methods disabled and grep STDERR for "Permission denied". Returns exit status 0 if the host is serving SSH, regardless of credentials, and does not hang waiting for password input.
说明:尝试连接禁用的常用身份验证方法并 grep STDERR 获取“权限被拒绝”。如果主机正在为 SSH 提供服务,无论凭据如何,并且不会挂起等待密码输入,则返回退出状态 0。
回答by Todd A. Jacobs
A Bash-Specific Solution
特定于 Bash 的解决方案
If you are using the Bash shell specifically, then you have access to TCP and UDP sockets. For example:
如果您专门使用 Bash shell,那么您可以访问 TCP 和 UDP 套接字。例如:
if (exec 3<>/dev/tcp/74.207.252.238/22) 2> /dev/null; then
echo open
else
echo closed
fi
This won't tell you if the actual protocol in use is really SSH, but is often sufficient to determine that a given port is listening. Your mileage may vary.
这不会告诉您实际使用的协议是否真的是 SSH,但通常足以确定给定的端口正在侦听。你的旅费可能会改变。
回答by Basile Starynkevitch
The other answers are checking if some process is listening on the remote machine on the SSH port 22.
其他答案是检查某个进程是否正在 SSH 端口 22 上侦听远程计算机。
But that process might not be an sshd
daemon (some sysadmins are starting other daemons on that port, e.g. some HTTPS service...).
但该进程可能不是sshd
守护进程(某些系统管理员正在该端口上启动其他守护进程,例如某些 HTTPS 服务...)。
Or the remote sshd
daemon has been configured with a non-POSIX shell. For example, as a GCC contributor, I am using ssh
thru svn
to gcc.gnu.org
but I cannotrun a shell command there...
或者远程sshd
守护程序已配置为非 POSIX shell。例如,作为 GCC 贡献者,我正在使用ssh
thru svn
togcc.gnu.org
但我无法在那里运行 shell 命令......
So I believe you should really try the ssh
command. If the remote machine is POSIX and you expect to have some Posix shell runnable thru ssh
, try ssh remotehost /bin/true
(or perhaps ssh remotehost 'echo $$'
, with the hope that echo
would be a remote shell builtin)
所以我相信你真的应该试试这个ssh
命令。如果远程机器是 POSIX 并且您希望通过 某些 Posix shell 运行ssh
,请尝试ssh remotehost /bin/true
(或者ssh remotehost 'echo $$'
,希望是echo
内置的远程 shell)
Also, an ssh
command could temporarily fail (e.g. because the remote host has too many processes running under your user, so the fork
inside sshd
would fail)
此外,ssh
命令可能会暂时失败(例如,因为远程主机在您的用户下运行的进程太多,因此fork
内部sshd
会失败)
If you want that inside some program, consider using some library like libssh.
如果您希望在某个程序中使用它,请考虑使用诸如libssh 之类的库。
BTW, you can configure your local.ssh/config
to never ask any password (or pass with -F
some specific configuration file ensuring that no password is asked), or (as commented by CodeGnome), use ssh -o BatchMode=yes
to disable password prompts.
顺便说一句,您可以将本地配置.ssh/config
为从不询问任何密码(或通过-F
某些特定的配置文件确保不询问密码),或者(如CodeGnome所评论),用于ssh -o BatchMode=yes
禁用密码提示。
回答by dbndhjefj
You could use nmap
:
你可以使用nmap
:
nmap -p 22 --open -sV 172.26.192.0/24 > sshservers
回答by Todd A. Jacobs
Grep Output from Nmap
来自 Nmap 的 Grep 输出
If you need an exit status, grep the results from nmap and use the exit status from grep. For example:
如果您需要退出状态,请从 nmap 中 grep 结果并使用 grep 中的退出状态。例如:
$ nmap -sT -Pn -p 22 host.example.com | egrep 'open\s+ssh'
22/tcp open ssh
In this example, the exit status will be from grep, not nmap. Grep will return 0
if the port is open, and 1
if it isn't. You can use the results directly, or branch off of $?
. For example:
在这个例子中,退出状态将来自 grep,而不是 nmap。0
如果端口打开,1
则Grep 将返回,否则将返回。您可以直接使用结果,也可以从$?
. 例如:
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