You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Paramiko随机出现Authentication Failed认证失败问题求助(用户名密码正确)

Paramiko随机出现Authentication Failed认证失败问题求助(用户名密码正确)

环境信息

  • Paramiko版本: 2.7.2
  • Python版本: 3.5.10
  • 操作系统: Linux, CentOS Linux 7 (Core)

问题描述

我们用Python通过Paramiko连接SSH服务器时,随机出现"authentication failed"错误,但有时候又能正常连接。直接用命令行SSH连接服务器完全没问题,而且确认用户名、密码、主机名都是正确的。

运行场景

  • 代码通过crontab以15分钟间隔定时执行
  • 认证失败的情况是随机发生的

代码片段

import paramiko  
import traceback
 
ssh = paramiko.SSHClient()  
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  
try:  
    ssh.connect(hostname, 22, username, password)  
    ssh.close()
except Exception as ssherror:  
    traceback.print_exc()

错误回溯

Traceback (most recent call last):  
File "sshToServer.py", line 15, in getCPUCount  
ssh.connect(hostname, 22, username, password)  
File "/home/user/env/lib/python3.5/site-packages/paramiko/client.py", line 446, in connect  
passphrase,  
File "/home/user/env/lib/python3.5/site-packages/paramiko/client.py", line 764, in _auth  
raise saved_exception  
File "/home/user/env/lib/python3.5/site-packages/paramiko/client.py", line 751, in _auth  
self._transport.auth_password(username, password)  
File "/home/user/env/lib/python3.5/site-packages/paramiko/transport.py", line 1509, in auth_password  
return self.auth_handler.wait_for_response(my_event)  
File "/home/user/env/lib/python3.5/site-packages/paramiko/auth_handler.py", line 250, in wait_for_response  
raise e  
paramiko.ssh_exception.AuthenticationException: Authentication failed.

可能的原因及解决思路

1. SSH服务器的速率限制/防暴力破解机制

很多SSH服务器(比如OpenSSH)默认会对频繁的认证请求做速率限制,尤其是来自同一IP的重复尝试。你的脚本15分钟执行一次看起来不频繁,但如果服务器端的规则比较严格,或者同一时间段有其他设备也在连这个服务器,可能会触发临时的封禁/限制。

解决方法

  • 检查服务器端的/var/log/secure日志(CentOS下),搜索对应客户端IP的认证记录,看是否有Failed password之外的提示(比如maximum authentication attempts exceeded或者too many failures
  • 给脚本添加重试机制,遇到认证失败时短暂延迟后重试几次,示例代码:
import paramiko  
import traceback
import time

ssh = paramiko.SSHClient()  
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())  
max_retries = 3
retry_delay = 5  # 秒
success = False

for attempt in range(max_retries):
    try:  
        ssh.connect(hostname, 22, username, password, timeout=10)  
        print("连接成功")
        ssh.close()
        success = True
        break
    except paramiko.ssh_exception.AuthenticationException as ae:
        if attempt < max_retries -1:
            print(f"认证失败,第{attempt+1}次重试...")
            time.sleep(retry_delay)
        else:
            traceback.print_exc()
    except Exception as ssherror:  
        traceback.print_exc()
        break

2. Paramiko的认证顺序问题

Paramiko在_auth方法中会尝试多种认证方式(比如先尝试密钥认证,再尝试密码认证),如果服务器端的认证方式顺序和Paramiko不匹配,或者中间有超时,可能会导致密码认证被跳过或者失败。

解决方法
ssh.connect()中明确指定只使用密码认证,避免尝试其他不需要的认证方法:

ssh.connect(hostname, 22, username, password, look_for_keys=False, allow_agent=False)
  • look_for_keys=False:禁用尝试本地密钥文件认证
  • allow_agent=False:禁用尝试SSH代理认证

3. 网络波动导致的认证数据包丢失

如果客户端和服务器之间的网络不稳定,认证过程中的数据包可能丢包,导致认证失败。这种情况的失败也是随机的。

解决方法

  • connect()中添加timeout参数,避免长时间等待无响应:ssh.connect(hostname, 22, username, password, timeout=10)(单位:秒)
  • 结合前面的重试机制,遇到超时或认证失败时重试

4. 服务器端的PAM模块限制

CentOS的SSH可能使用PAM进行认证,PAM的某些规则(比如pam_tally2模块的失败次数限制)可能会临时锁定账号,导致随机认证失败。

解决方法

  • 服务器端执行pam_tally2 --user 你的用户名,查看是否有失败次数累计导致的临时锁定
  • 检查/etc/pam.d/sshd配置,看是否有相关的限制规则,必要时调整

期望目标

希望能实现稳定连接SSH服务器,不再出现随机的认证失败问题。

备注:内容来源于stack exchange,提问作者Bonthu Srinivasa rao

火山引擎 最新活动