一、基础检查:网络连接和SSH服务状态

当遇到SSH登录失败时,首先要确认最基本的网络连接和服务状态是否正常。

  1. 检查网络连通性:
# 使用ping命令测试服务器是否可达(示例IP:192.168.1.100)
ping -c 4 192.168.1.100

# 如果ping不通,可能是网络问题或防火墙阻挡
# 可以尝试telnet测试SSH端口(默认22)
telnet 192.168.1.100 22
  1. 检查SSH服务状态:
# 查看SSH服务是否运行(适用于systemd系统)
systemctl status sshd

# 如果服务未运行,尝试启动
sudo systemctl start sshd

# 检查SSH服务是否开机自启
systemctl is-enabled sshd
  1. 检查端口监听情况:
# 查看22端口是否被监听
sudo netstat -tulnp | grep 22
# 或者使用ss命令
sudo ss -tulnp | grep ssh

二、认证失败问题排查

如果网络和服务都正常,但认证失败,需要检查以下方面。

  1. 检查用户名和密码:
# 确保用户名正确(注意Linux区分大小写)
# 如果忘记密码,可以在服务器本地重置
sudo passwd username
  1. 检查认证日志:
# 查看SSH认证日志(位置可能因发行版不同而异)
sudo tail -f /var/log/auth.log
# 或者
sudo journalctl -u sshd -f
  1. 检查SSH配置文件:
# 查看/etc/ssh/sshd_config中的关键配置
sudo grep -E "PermitRootLogin|PasswordAuthentication" /etc/ssh/sshd_config

# 修改配置后需要重启服务
sudo systemctl restart sshd
  1. 检查用户权限:
# 检查用户是否被锁定
sudo passwd -S username

# 检查用户是否有登录shell
sudo grep username /etc/passwd
# 正常应该显示如:username:x:1000:1000::/home/username:/bin/bash

三、密钥认证问题排查

如果使用密钥认证失败,需要检查以下方面。

  1. 检查密钥文件权限:
# 本地密钥文件权限应为600
chmod 600 ~/.ssh/id_rsa

# 服务器上authorized_keys文件权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
  1. 检查密钥内容:
# 确保公钥已正确添加到服务器的authorized_keys
cat ~/.ssh/id_rsa.pub | ssh username@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
  1. 调试SSH连接:
# 使用-vvv参数获取详细调试信息
ssh -vvv username@server
  1. 检查SELinux影响:
# 如果启用了SELinux,可能需要恢复上下文
sudo restorecon -Rv ~/.ssh

四、防火墙和SELinux限制

防火墙和SELinux可能会阻止SSH连接。

  1. 检查防火墙规则:
# 对于iptables
sudo iptables -L -n

# 对于firewalld
sudo firewall-cmd --list-all

# 添加SSH端口例外(如果使用非标准端口)
sudo firewall-cmd --add-port=2222/tcp --permanent
sudo firewall-cmd --reload
  1. 检查SELinux状态:
# 查看SELinux状态
sestatus

# 临时禁用SELinux(不推荐生产环境)
setenforce 0

# 检查SSH端口是否被SELinux允许
semanage port -l | grep ssh
  1. 检查TCP Wrappers:
# 检查/etc/hosts.allow和/etc/hosts.deny
# 确保没有规则阻止SSH访问

五、高级问题排查

对于更复杂的问题,可能需要深入排查。

  1. 检查系统资源:
# 检查系统负载和内存
uptime
free -h

# 检查磁盘空间
df -h

# 检查inode使用情况
df -i
  1. 检查PAM配置:
# 查看SSH相关的PAM配置
cat /etc/pam.d/sshd

# 检查是否有登录限制
cat /etc/security/access.conf
  1. 检查系统日志:
# 查看系统日志中的相关错误
sudo dmesg | grep -i error

# 检查messages日志
sudo tail -f /var/log/messages
  1. 检查最大连接数:
# 查看当前SSH连接数
sudo netstat -ntp | grep ':22' | wc -l

# 修改最大连接数(在sshd_config中)
# MaxStartups 10:30:60

六、常见错误及解决方案

  1. "Connection refused"错误:
# 通常表示SSH服务未运行或端口被防火墙阻挡
# 解决方案:
sudo systemctl start sshd
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
  1. "Permission denied"错误:
# 可能原因:密码错误、密钥错误、用户被锁定等
# 解决方案:
# 1. 检查密码是否正确
# 2. 检查密钥权限和内容
# 3. 检查用户状态
  1. "Too many authentication failures"错误:
# 解决方案:
# 1. 在客户端配置中使用IdentitiesOnly选项
# 2. 减少密钥尝试次数
ssh -o IdentitiesOnly=yes username@server
  1. "Broken pipe"错误:
# 可能原因:网络不稳定或服务器配置问题
# 解决方案:
# 1. 在客户端配置中添加保活选项
ssh -o ServerAliveInterval=60 username@server

七、安全加固建议

在解决问题后,应考虑安全加固。

  1. 修改默认端口:
# 编辑/etc/ssh/sshd_config
Port 2222

# 更新防火墙规则
sudo firewall-cmd --add-port=2222/tcp --permanent
sudo firewall-cmd --reload
  1. 禁用root登录:
# 编辑/etc/ssh/sshd_config
PermitRootLogin no
  1. 使用密钥替代密码:
# 禁用密码认证
PasswordAuthentication no
  1. 配置fail2ban:
# 安装fail2ban
sudo apt install fail2ban  # Debian/Ubuntu
sudo yum install fail2ban  # CentOS/RHEL

# 配置SSH保护
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 编辑jail.local中的[sshd]部分

八、总结与最佳实践

通过以上步骤,应该能够解决绝大多数SSH登录问题。以下是一些最佳实践:

  1. 始终保持系统更新:
sudo apt update && sudo apt upgrade  # Debian/Ubuntu
sudo yum update                     # CentOS/RHEL
  1. 定期备份重要配置文件:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
  1. 使用配置管理工具:
# 例如使用Ansible管理SSH配置
- name: Ensure SSH is configured securely
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "^{{ item.regexp }}"
    line: "{{ item.line }}"
    state: present
  with_items:
    - { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
    - { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
  notify: restart sshd
  1. 监控SSH登录尝试:
# 使用工具如logwatch或自定义脚本监控/var/log/auth.log
  1. 建立应急访问通道:
# 例如配置串行控制台访问作为备用方案

通过系统化的排查和合理的安全配置,可以确保SSH服务既安全又可靠,为服务器管理提供稳定的远程访问通道。