如何以编程方式检测可用的 ssh 身份验证类型?

问题描述 投票:0回答:5

我想编写一个监控插件来检查我网络上的各种主机,以确保未启用密码或交互式 SSH 身份验证。也就是说,我需要编写代码:

  1. 连接到 SSH 端口。
  2. 枚举可用的身份验证方法。
  3. 验证只有基于密钥的身份验证是可能的。

使用 python 或 bourne sh 代码(使用

ssh
)的方法对我来说最有趣,但其他语言、库或提示也很受欢迎。

security ssh monitoring openssh
5个回答
16
投票

我目前正在自己构建一个,但是,您可以使用 PreferredAuthentications 选项强制 ssh 输出(到 STDERR)支持的方法。这可以很容易地用 grep/python/选择的语言来解析。

HostA$ ssh -o PreferredAuthentications=none HostB
Permission denied (publickey,gssapi-with-mic).
HostA$ ssh -o PreferredAuthentications=none HostC
Permission denied (publickey,gssapi-with-mic,password,keyboard-interactive,hostbased).

7
投票

RFC 4252,它定义了 SSH 中的身份验证,说明如下:

身份验证方法由它们的名称标识,如定义 [SSH-ARCH]。 “无”方法是保留的,不得列为 支持的。但是,它可以由客户端发送。服务器必须 总是拒绝这个请求,除非客户端被授予访问权限 没有任何身份验证,在这种情况下,服务器必须接受 这个请求。发送这个请求的主要目的是得到 服务器支持的方法列表

所以你可以发送一个请求进行 none 身份验证以获取支持的列表。 但是,身份验证本身发生在某些较低级别的操作发生后(密钥交换是其中之一),因此您可能需要在 sh 脚本中编写 SSH 协议的一部分,这可能是一项非常重要的任务。


1
投票

您现在可以使用

nmap
内置的 NSE 脚本 ssh-auth-methods 来执行此操作:

# nmap -p 22 --script ssh-auth-methods 192.168.1.2

Starting Nmap 7.60 ( https://nmap.org ) at 2017-12-26 00:56 GMT
Nmap scan report for 192.168.1.2
Host is up (0.027s latency).

PORT   STATE SERVICE
22/tcp open  ssh
| ssh-auth-methods:
|   Supported authentication methods:
|     publickey
|_    keyboard-interactive
MAC Address: AA:BB:CC:DD:EE:FF (Apple)

Nmap done: 1 IP address (1 host up) scanned in 2.40 seconds

另外,有人做了一个类似python3的脚本.


0
投票

这是基于 Eadwacer 的回答的完整解决方案:

#!/bin/bash
set -u

for ip in 1.1.1.1 2.2.2.2; do
        ok=0
        for try in {1..3}; do
                echo "$ip: try #$try"
                OUT="$(timeout -s KILL 30s ssh -o PreferredAuthentications=none "root@$ip" 2>&1)"
                RES="$(echo "$OUT" | fgrep ': Permission denied (publickey).')"
                if [ "$RES" != "" ]; then
                        ok=1
                        echo '  Auth is OK.'
                        break
                else
                        echo '  Auth is BAD.'
                fi
                sleep 5
        done
        if [ "$ok" -eq 1 ]; then
                echo "$ip: final result: OK"
        else
                echo "$ip: final result: FAIL" >&2
                echo "  ssh output: $OUT" >&2
        fi
done

重试是为了避免由于超时等间歇性连接失败而导致的误报

这是示例运行的样子:

$ ./ssh-assert-key-auth-only.sh
1.1.1.1: try #1
  Auth is OK.
1.1.1.1: final result: OK
2.2.2.2: try #1
  Auth is BAD.
2.2.2.2: try #2
  Auth is BAD.
2.2.2.2: try #3
  Auth is BAD.
2.2.2.2: final result: FAIL
  ssh output: [email protected]: Permission denied (publickey,password).

调试信息被发送到

stdout
并且可以很容易地为非交互式运行静音:

$ ./ssh-assert-key-auth-only.sh >/dev/null
2.2.2.2: final result: FAIL
  ssh output: [email protected]: Permission denied (publickey,password).

您必须用 SSH 服务器的 IP 地址或主机名替换

1.1.1.1
2.2.2.2
。如果您想接受除“publickey”之外的其他内容,还应编辑
fgrep
中的字符串。


-1
投票

如果您需要 *nix 解决方案,您还可以连接到 OpenSSH 源。 如果 Windows 适合您 - 您也可以尝试一些 .NET 商业库,它们比 OpenSSH 源代码更方便:)

© www.soinside.com 2019 - 2024. All rights reserved.