诊断和解决 SSH 身份验证失败

您是否正在为 SSH 身份验证失败而困扰?这份综合指南提供了分步说明,用于诊断和解决常见问题。学习如何有效地使用客户端详细模式 (`ssh -vvv`) 来理解连接尝试,并解释服务器端日志 (`/var/log/auth.log` 或 `/var/log/secure`) 以明确地识别错误。我们涵盖了常见的陷阱,例如不正确的权限、配置错误的公钥和服务器设置,并提供了可操作的解决方案,以快速高效地恢复您的安全远程访问。

41 浏览量

诊断并解决 SSH 认证失败

安全外壳(SSH)是安全远程管理的基础,它能够为服务器和网络设备提供加密访问。然而,系统管理员和开发人员都常遇到认证失败的问题,这往往令人沮丧。这些问题可能源于多种原因,从简单的拼写错误到复杂的权限问题或配置错误。

本文旨在提供一份全面的指南,以有效地诊断和解决 SSH 认证失败。我们将深入探讨系统化的故障排除方法,强调客户端详细输出和服务器端日志分析的关键作用。通过理解如何解释这些诊断线索,您将能够找出大多数认证问题的根本原因,并恢复您的安全远程访问。

理解 SSH 认证方法

在深入故障排除之前,了解 SSH 采用的主要认证方法至关重要:

  • 密码认证:用户提供密码,服务器会根据其用户数据库或外部认证服务(如 PAM)进行验证。
  • 公钥认证:这种更安全的方法使用一对加密密钥:一个存储在客户端的私钥和一个存储在服务器上的相应公钥。认证时,客户端使用其私钥来证明其身份,而无需通过网络发送私钥。

两种方法都可能发生认证失败,但故障排除步骤通常有所不同。

初步检查和常见陷阱

在深入研究详细日志之前,进行一些基本检查是明智之举,因为许多问题往往只是简单的疏忽:

  • 正确的用户名和主机名:仔细检查您是否使用了正确的用户名和目标服务器的精确主机名或 IP 地址。
  • 网络连通性:您是否能连接到服务器?使用 ping 来验证基本的网络可达性。
    bash ping example.com
  • SSH 服务状态:SSH 服务器 (sshd) 是否在目标机器上运行?如果您有控制台访问权限,请检查其状态。
    bash sudo systemctl status sshd # 适用于基于 systemd 的系统(大多数现代 Linux) sudo service sshd status # 适用于较旧的 init 系统
  • SSH 端口:SSH 守护程序是在默认端口(22)还是自定义端口上监听?如果是自定义端口,您需要使用 -p 指定它。
  • 防火墙规则:是否有任何防火墙(客户端或服务器端)阻止了端口 22(或您的自定义 SSH 端口)?检查服务器防火墙,例如 ufwfirewalld 或 AWS 安全组。
    bash sudo ufw status sudo firewall-cmd --list-all

客户端诊断:利用详细模式

SSH 客户端提供详细模式 (-v-vv-vvv),这些模式提供了关于连接过程和认证尝试的详细调试输出。这些输出对于理解客户端认为认证失败的原因非常宝贵。

使用详细标志

  • -v:详细输出。
  • -vv:更详细的输出。
  • -vvv:甚至更详细的输出(通常对于认证问题最有用)。

示例命令:

ssh -vvv username@your_server_ip

解释详细输出

当您在详细模式下运行 ssh 时,请查找指示认证过程失败关键的行:

  • debug1: Authentications that can continue::此行告诉您 服务器 愿意接受哪些认证方法。如果您期望的方法(例如 publickey)未列出,则服务器配置阻止了它。
    debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
  • debug1: Offering public key::这表示您的客户端正在尝试使用特定的公钥进行认证。如果您期望公钥认证但未看到此行,则您的客户端未找到或未提供该密钥。
    debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:...
  • debug3: send_pubkey_test: ... trying private key: /home/user/.ssh/id_rsa:这确认客户端正在尝试使用特定的私钥。
  • debug1: Server accepts key: ...:这表示客户端认为公钥认证成功。如果您未看到此行,则密钥很可能被服务器拒绝。
  • debug1: No more authentication methods to try.:这通常出现在 Permission denied 错误之前,表示客户端已尝试所有可用的认证方法但未成功。
  • debug1: Permission denied (publickey,password).:这是最终的客户端错误,总结了服务器对所有尝试的拒绝。

提示:密切关注提供和接受的认证方法的顺序。如果提供了 publickey 但随后立即出现密码提示,这通常意味着服务器拒绝了公钥。

服务器端诊断:检查 SSH 服务器日志

虽然客户端详细输出显示了客户端 试图 做什么,但服务器日志提供了关于 服务器 拒绝认证尝试的明确信息。这通常是根本原因分析中最关键的步骤。

查找 SSH 服务器日志

SSH 服务器日志的位置因操作系统而异:

  • Debian/Ubuntu 及其衍生版/var/log/auth.log
  • RHEL/CentOS/Fedora 及其衍生版/var/log/secure
  • 基于 Systemd 的系统(大多数现代 Linux):您也可以使用 journalctl

查看和过滤服务器日志

使用 tailjournalctl 等工具实时监控日志或过滤 SSH 特定条目。

示例命令:

# 适用于 Debian/Ubuntu
sudo tail -f /var/log/auth.log | grep sshd

# 适用于 RHEL/CentOS
sudo tail -f /var/log/secure | grep sshd

# 适用于基于 systemd 的系统(查看当前日志最稳健的方式)
sudo journalctl -u sshd -f

# 从头开始查看所有 sshd 日志(如果故障发生较早,则有用)
sudo journalctl -u sshd

常见服务器日志条目及其含义

当您尝试连接时,查找与 sshd 相关的消息。以下是一些指示认证失败的常见条目:

  • Failed password for user from IP port ssh2:表示密码认证尝试失败。这可能是由于密码不正确,或者该用户不允许通过密码登录。
  • Authentication refused: bad ownership or modes for directory /home/user/.ssh:这是一个非常常见的公钥认证错误。服务器上的 .ssh 目录具有不正确的权限。
    • 解决方案chmod 700 /home/user/.ssh
  • Authentication refused: bad ownership or modes for file /home/user/.ssh/authorized_keys:另一个常见的公钥错误,表示 authorized_keys 文件具有不正确的权限。
    • 解决方案chmod 600 /home/user/.ssh/authorized_keys
  • sshd[PID]: error: Permissions 0777 for '/home/user/.ssh/authorized_keys' are too open.:明确指出了文件权限过于宽松的问题。出于安全原因,SSH 对权限要求非常严格。
  • User username from IP not allowed because not listed in AllowUsers:根据 /etc/ssh/sshd_config 中的 AllowUsers 指令,不允许该用户通过 SSH 登录。
  • User username from IP not allowed because listed in DenyUsers:该用户被 DenyUsers 明确拒绝了 SSH 访问。
  • input_userauth_request: invalid user username:提供的用户名在服务器上不存在。
  • Publickey authentication refused: authenticate using identity file.:这通常意味着客户端提供的公钥与该用户在服务器 authorized_keys 文件中的任何密钥都不匹配,或者密钥格式不正确。
  • Maximum authentication attempts exceeded for user from IP:客户端尝试了过多的认证方法或发送了过多的错误凭据。由 sshd_config 中的 MaxAuthTries 控制。
  • Connection closed by authenticating user IP port 22 [preauth]:如果找不到可接受的认证方法,或者客户端在失败后突然关闭连接,则可能发生此情况。

常见的认证失败场景和解决方案

让我们对常见的故障及其具体的补救措施进行分类。

1. 密码认证失败

  • 密码不正确:最直接的问题。仔细检查您的密码。注意键盘布局、Caps Lock 或 Num Lock。
  • 用户不允许sshd_config 文件 (/etc/ssh/sshd_config) 可能限制某些用户的登录。
    • PermitRootLogin no:阻止 root 用户登录(出于安全强烈推荐)。
    • AllowUsers username1 username2:只有指定的这些用户可以登录。
    • DenyUsers username:指定的这些用户不能登录。
    • AllowGroups groupname:只有指定组中的用户可以登录。
    • 解决方案:调整 sshd_config 指令并重新启动 sshd
  • PAM 问题:如果服务器使用可插拔认证模块(PAM),PAM 配置问题可能会阻止密码认证。检查 /var/log/auth.log 中是否有 PAM 特定错误。对于基本的 SSH 设置,这种情况较不常见。

2. 公钥认证失败

公钥认证通常更安全,但也更容易出现配置相关的错误。

  • 不正确的文件/目录权限(服务器端):这是迄今为止最常见的原因。出于安全考虑,SSH 对 ~/.ssh~/.ssh/authorized_keys 有严格的权限要求。
    • ~:用户的家目录不应是全局可写的(chmod 755 ~ 通常是安全的)。
    • ~/.ssh:必须是 700(仅所有者具有读写执行权限)。
      bash chmod 700 ~/.ssh
    • ~/.ssh/authorized_keys:必须是 600(仅所有者具有读写权限)。
      bash chmod 600 ~/.ssh/authorized_keys
    • 这些文件和目录的所有者必须是尝试登录的用户。
      bash sudo chown -R username:username ~/.ssh
  • authorized_keys 内容不正确~/.ssh/authorized_keys 中的公钥可能已损坏、包含多余字符或格式不正确。每个密钥应在一行上。确保正确格式的快速方法是使用客户端的 ssh-copy-id
    bash ssh-copy-id -i ~/.ssh/id_rsa.pub username@your_server_ip
    要在客户端验证您的公钥指纹,请使用: ssh-keygen -l -f ~/.ssh/id_rsa.pub
  • 客户端未提供密钥:私钥可能不在默认位置 (~/.ssh/id_rsa)、未加载到 ssh-agent 中,或者您未使用 -i 指定它。
    • 解决方案:确保您的私钥是 id_rsa(或 id_ed25519 等)位于 ~/.ssh 中并具有 600 权限。如果不是,请指定它:
      bash ssh -i /path/to/your/private_key username@your_server_ip
    • 如果使用 ssh-agent,请确保已添加您的密钥:
      bash eval "$(ssh-agent -s)" ssh-add ~/.ssh/your_private_key
  • sshd_config 不允许公钥认证:服务器的 SSH 守护程序可能配置为不允许公钥认证。
    • 检查 /etc/ssh/sshd_config 中的 PubkeyAuthentication yes
    • 检查 AuthorizedKeysFile .ssh/authorized_keys 以确保它指向正确的文件。默认通常没问题。
    • 解决方案:设置 PubkeyAuthentication yes 并重新启动 sshd
  • SELinux/AppArmor 干扰:在带有 SELinux 或 AppArmor 的系统上,这些安全模块有时可能会阻止 SSH 访问用户家目录或 .ssh 文件,即使文件权限正确。检查审计日志(/var/log/audit/audit.logsudo ausearch -m AVC -ts recent)以获取线索。这是一种高级场景。

3. 连接拒绝或超时

虽然这些不严格是“认证”失败,但它们通常发生在认证尝试之前并阻止其开始。

  • 防火墙阻止:检查客户端(例如,本地操作系统防火墙)和服务器(例如,ufwfirewalld、云安全组、网络 ACL)上的防火墙。确保端口 22(或自定义端口)是开放的。
  • SSH 服务器未运行sshd 服务可能未激活或已崩溃。
  • 端口/IP 不正确:尝试连接到错误的端口或 IP 地址。

一般调试技巧

  • 检查 sshd_config:始终检查服务器上的 /etc/ssh/sshd_config 文件,查找任何可能造成干扰的非默认设置。进行更改后,务必重新启动 SSH 守护程序:sudo systemctl restart sshd(或 sudo service sshd restart)。
  • 使用新用户/密钥进行测试:如果可能,创建新用户和新的公钥/私钥对。尝试使用此全新设置进行认证。如果成功,则问题特定于原始用户的配置。
  • 隔离问题:尝试从不同的客户端机器连接。如果成功,则问题特定于客户端。如果从多个客户端都失败,则问题特定于服务器。
  • 提高 LogLevel(服务器端):为了进行深度调试,您可以暂时在 /etc/ssh/sshd_config 中设置 LogLevel DEBUG 并重新启动 sshd。请记住在故障排除后恢复此设置,因为调试日志可能会非常冗长并占用磁盘空间。

结论

诊断 SSH 认证失败需要一种系统化的方法,结合客户端详细输出和服务器端日志分析。通过仔细检查 ssh -vvv 和 SSH 守护程序日志(auth.logsecure)提供的线索,您可以有效地找出确切的故障点,无论是密码不正确、公钥配置错误、严格的文件权限还是服务器端设置。

请记住从简单检查开始,然后转向客户端详细输出,最后利用服务器日志提供的明确见解。掌握这些技术,您将能够很好地解决即使是最复杂的 SSH 认证问题,并维护对远程系统的安全访问。