用于检查 SSH 可用性的服务器列表

用于检查 SSH 可用性的服务器列表

我有一个 IP 地址列表,我需要通过 SSH 访问并记录是否可以访问它们。我会使用 Ping 脚本,但 DNS 可能已经重新分配了地址。我不关心那些我无法到达的人。如果 SSH 工作正常,我需要记录该 IP 地址,我不必担心密码或密钥,因为我不想登录到该盒子。我只是想看看是否可以通过 SSH 连接到他们。到目前为止我有:

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="path/to/ip_address.txt"
LOGFILE="path/to/logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
   echo "Cannot find IP address!"
   exit 1
fi

for IP_ADDRESS in `cat $IP_FILE` ; do

    ssh $IP_ADDRESS >> $LOGFILE 2>&1

我对脚本编写仍然很陌生,任何帮助都会很棒。我查看了“如何检查我是否可以通过 ssh 登录服务器?”由 LanceBaynes 发布,但它并不是我真正需要的。

我无法在这个盒子上安装任何东西。或者我会下载一个不错的扫描仪。像 Netcat 或 Nmap 一样,这两个都是不错的选择。

答案1

方法#1:ssh-keyscan

一种方法是使用命令ssh-keyscan来查看 ssh 守护进程是否已启动并正常运行。

只需循环访问 IP 地址和ssh-keyscan <ip> | grep -v ...每个服务器即可。如果服务器在那里,则运行该ssh-keyscan ... | grep -v ...命令返回的状态将为 0,其他任何值(1 或更高)意味着那里没有服务器。

例子

$ for IP_ADDRESS in `cat $IP_FILE` ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done

只是为了进一步分解它,以便清楚地了解发生了什么,将ssh-keyscan $IP_ADDRESS 2>&1运行,返回任何输出(两者stderr&stdout合并在一起)。然后,所有这些输出都通过管道传输到,grep -v "^$"对于返回输出的行(ssh 服务器正在运行),它将返回 0;对于不返回输出的服务器(这"^$"是一个空行),返回 1。

循环上的快速切线(for 与 while 以及它们如何解析)

上面的循环机制(for 循环)之所以有效,是因为文件只包含一个字符串,其中没有一个空格,并且每个“字符串”都以换行符终止。默认情况下,空格是特殊的分隔字符,用于指定 for 循环如何解析传递给它的参数。该字符由变量定义$IFS,并且可以被覆盖,例如它是换行符 ( IFS='^M')。

cat $IP_FILE您可以通过将替换为 来提高效率$( < $IP_FILE )。例如:

$ for IP_ADDRESS in $( < $IP_FILE ) ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done

如果文件中的行$IP_FILE包含空格,您可以覆盖$IFS刚才讨论的内容,以便将其设置为^M或使用 while 循环,即 ( while read -ra line ; do ... ; done < $IP_FILE)。

$ while read -ra IP_ADDRESS ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done < $IP_FILE

你的例子

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="ip.txt"
LOGFILE="logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
 echo "Cannot find IP address!"
 exit 1
fi

for IP_ADDRESS in `cat $IP_FILE` ; do
  #ssh $IP_ADDRESS >> $LOGFILE 2>&1
  ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
  [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
done

方法#2:nmap

您还可以使用该工具做一些事情nmap

$ nmap -A -iL ip.txt -p T:22

这将遍历该文件,ip.txt该文件可以包含主机名和 IP 地址,并将扫描每个端口的 TCP 端口 # 22,返回类似于以下内容的结果:

Nmap scan report for somehost.somedom.local (192.168.1.200)
Host is up (0.012s latency).
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey: 1024 2e:32:85:a2:56:23:01:f1:c2:8f:df:aa:83:7a:1e:ad (DSA)
|_2048 f6:a1:23:1d:aa:44:4a:ce:b4:d3:f4:fe:e1:00:47:b7 (RSA)

参考

答案2

您正在寻找 netcat 实用程序(二进制可执行文件称为nc)。它可以执行各种网络测试,其中也可以对 TCP 端口 22 进行仅连接测试。如果您使用的是较旧的 netcat 实用程序,则命令为:

nc -vz [ip.or.hostname] 22 -w [desired.timeout.value.in.seconds]

-z我相信更新版本默认删除了该选项。

例如:

[jadavis6@cmsoracle ~]$ nc -vz wfwhite.xxx.edu 22 -w 5
nc: connect to wfwhite.xxx.edu port 22 (tcp) timed out: Operation now in progress
[jadavis6@cmsoracle ~]$ echo $?
1
[jadavis6@cmsoracle ~]$ nc -vz ditirlns01.xxx.edu 22 -w 5
Connection to ditirlns01.xxx.edu 22 port [tcp/ssh] succeeded!
[jadavis6@cmsoracle ~]$ echo $?
0
[jadavis6@cmsoracle ~]$

答案3

有人提到了 netcat,但我会推荐 nmap,因为它是执行您想要的操作的命令之一。

nmap -iL path/to/ip_address.txt -p 22

这将为您提供所需的所有信息。

答案4

如果您无法安装任何东西,您应该能够执行类似的操作(改编自这里):

$ for ip in `cat ips.txt`; do 
    ssh -o PreferredAuthentications=publickey foobar@$ip "echo ''" 2>&1 | 
    grep denied >/dev/null && echo "$ip has SSH"; 
  done < ips.txt

这里的技巧是PreferredAuthentications。这告诉ssh尝试使用存储在 中的密钥信息进行连接~/.ssh。只要用户foobar无权访问远程系统(将其更改为您想要的任何随机名称),连接就会失败并出现“权限被拒绝”错误。这意味着将会grep denied成功,因此echo命令将会运行。&&表示如果上一个命令(此处为grep)成功,则运行下一个命令。

如果您在包含 IP 的文件上运行此脚本,它将仅打印出那些正在运行 ssh 服务的服务器。

相关内容