我有一个 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 循环)之所以有效,是因为文件只包含一个字符串,其中没有一个空格,并且每个“字符串”都以换行符终止。默认情况下,空格是特殊的分隔字符,用于指定 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 服务的服务器。