常见连接问题

连接被拒绝(Connection Refused)

问题表现

ssh: connect to host example.com port 22: Connection refused

可能原因和解决方案

  1. SSH服务未运行 “`bash

    检查SSH服务状态

    sudo systemctl status sshd

    sudo service ssh status

启动SSH服务

sudo systemctl start sshd

sudo service ssh start

设置开机自启

sudo systemctl enable sshd


2. **端口配置错误**
```bash
# 检查SSH配置中的端口
sudo grep "^Port" /etc/ssh/sshd_config

# 检查端口是否被监听
sudo netstat -tlnp | grep :22
# 或
sudo ss -tlnp | grep :22

# 使用正确端口连接
ssh -p 2222 user@hostname
  1. 防火墙阻止 “`bash

    检查防火墙状态

    sudo ufw status

    sudo iptables -L

允许SSH端口

sudo ufw allow 22

sudo iptables -A INPUT -p tcp –dport 22 -j ACCEPT


### 连接超时(Connection Timeout)

#### 问题表现
```bash
ssh: connect to host example.com port 22: Connection timed out

排查步骤

  1. 网络连通性测试 “`bash

    测试网络连通性

    ping example.com

测试端口连通性

telnet example.com 22

nc -zv example.com 22

路由跟踪

traceroute example.com


2. **DNS解析问题**
```bash
# 测试DNS解析
nslookup example.com
# 或
dig example.com

# 直接使用IP地址连接
ssh user@192.168.1.100
  1. 网络代理设置 “`bash

    检查代理设置

    echo $http_proxy echo $https_proxy

通过代理连接

ssh -o ProxyCommand=“nc -X connect -x proxy:8080 %h %p” user@hostname


### 权限被拒绝(Permission Denied)

#### 密钥认证失败
```bash
# 详细调试信息
ssh -vvv user@hostname

# 检查密钥权限
ls -la ~/.ssh/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

# 测试密钥
ssh-keygen -y -f ~/.ssh/id_rsa

# 检查公钥是否正确部署
ssh user@hostname "cat ~/.ssh/authorized_keys"

服务器端权限问题

# 检查用户主目录权限
ls -la /home/user/
chmod 755 /home/user

# 检查.ssh目录权限
ls -la /home/user/.ssh/
chmod 700 /home/user/.ssh
chmod 600 /home/user/.ssh/authorized_keys

# 检查文件所有者
sudo chown -R user:user /home/user/.ssh

认证问题排查

密钥认证调试

客户端调试

# 详细调试输出
ssh -vvv user@hostname

# 仅使用公钥认证
ssh -o PreferredAuthentications=publickey user@hostname

# 指定特定密钥
ssh -i ~/.ssh/specific_key user@hostname

# 禁用其他认证方式
ssh -o PasswordAuthentication=no -o ChallengeResponseAuthentication=no user@hostname

服务器端调试

# 查看SSH日志
sudo tail -f /var/log/auth.log | grep sshd
# 或
sudo journalctl -u sshd -f

# 临时启用调试模式
sudo /usr/sbin/sshd -D -d

# 检查SSH配置
sudo sshd -t
sudo sshd -T

常见认证配置问题

  1. SELinux问题 “`bash

    检查SELinux状态

    getenforce

查看SELinux日志

sudo ausearch -m avc -ts recent

恢复SSH相关文件的SELinux上下文

sudo restorecon -R ~/.ssh sudo restorecon -R /home/user/.ssh


2. **SSH配置错误**
```bash
# 检查关键配置项
sudo grep -E "^(PubkeyAuthentication|PasswordAuthentication|PermitRootLogin)" /etc/ssh/sshd_config

# 常见配置修复
# /etc/ssh/sshd_config
PubkeyAuthentication yes
PasswordAuthentication yes  # 或 no,根据需要
PermitRootLogin no  # 安全考虑
AuthorizedKeysFile .ssh/authorized_keys

性能问题诊断

连接缓慢

DNS反向解析问题

# 禁用DNS反向解析
# /etc/ssh/sshd_config
UseDNS no

# 重启SSH服务
sudo systemctl restart sshd

GSSAPI认证延迟

# 客户端禁用GSSAPI
ssh -o GSSAPIAuthentication=no user@hostname

# 配置文件设置
# ~/.ssh/config
Host *
    GSSAPIAuthentication no

传输速度慢

加密算法优化

# 使用快速加密算法
ssh -c aes128-gcm@openssh.com user@hostname

# 配置文件设置
# ~/.ssh/config
Host fast-server
    HostName server.example.com
    Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com
    Compression yes

网络优化

# 启用TCP窗口缩放
echo 'net.core.rmem_max = 134217728' | sudo tee -a /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# 调整SSH缓冲区
# /etc/ssh/sshd_config
TcpKeepAlive yes
ClientAliveInterval 30
ClientAliveCountMax 3

文件传输问题

SCP/SFTP传输失败

权限问题

# 检查目标目录权限
ssh user@hostname "ls -la /target/directory/"

# 检查磁盘空间
ssh user@hostname "df -h"

# 检查文件系统权限
ssh user@hostname "touch /target/directory/test && rm /target/directory/test"

传输中断恢复

# 使用rsync恢复传输
rsync -avz --partial --progress -e ssh large-file user@hostname:/path/

# SFTP恢复传输
sftp user@hostname
sftp> reput interrupted-file.txt

文件完整性验证

# 传输前计算校验和
md5sum large-file.txt

# 传输后验证
ssh user@hostname "md5sum /path/large-file.txt"

# 使用rsync验证
rsync -avz --checksum -e ssh large-file.txt user@hostname:/path/

网络问题排查

连接不稳定

保持连接活跃

# 客户端配置
# ~/.ssh/config
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    TCPKeepAlive yes

# 服务器端配置
# /etc/ssh/sshd_config
ClientAliveInterval 60
ClientAliveCountMax 3
TCPKeepAlive yes

网络质量测试

# 测试网络延迟
ping -c 10 hostname

# 测试网络带宽
iperf3 -c hostname

# 测试丢包率
mtr hostname

防火墙和NAT问题

端口转发调试

# 测试本地端口转发
ssh -L 8080:target:80 -v user@gateway
telnet localhost 8080

# 测试远程端口转发
ssh -R 8080:localhost:80 -v user@server
# 在服务器上测试
telnet localhost 8080

NAT穿透

# 使用autossh保持连接
autossh -M 20000 -R 8080:localhost:80 user@public-server

# 配置自动重连
# ~/.ssh/config
Host tunnel
    HostName public-server.com
    RemoteForward 8080 localhost:80
    ServerAliveInterval 30
    ServerAliveCountMax 3
    ExitOnForwardFailure yes

系统级问题

资源限制

连接数限制

# 检查当前连接数
ss -tn | grep :22 | wc -l

# 检查SSH配置限制
sudo grep MaxStartups /etc/ssh/sshd_config
sudo grep MaxSessions /etc/ssh/sshd_config

# 调整限制
# /etc/ssh/sshd_config
MaxStartups 20:30:100
MaxSessions 20

文件描述符限制

# 检查当前限制
ulimit -n

# 检查SSH进程限制
sudo cat /proc/$(pgrep sshd)/limits

# 调整限制
# /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536

日志分析

系统日志

# 查看SSH相关日志
sudo grep sshd /var/log/auth.log | tail -50
sudo journalctl -u sshd --since "1 hour ago"

# 查看系统资源使用
top
htop
iotop

自定义日志分析

#!/bin/bash
# SSH连接分析脚本

echo "=== SSH连接统计 ==="
sudo grep "Accepted" /var/log/auth.log | awk '{print $9}' | sort | uniq -c | sort -nr

echo "\n=== 失败登录尝试 ==="
sudo grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr

echo "\n=== 最近连接 ==="
sudo grep "Accepted" /var/log/auth.log | tail -10

故障排除工具

SSH调试工具

ssh-audit

# 安装ssh-audit
pip3 install ssh-audit

# 审计SSH服务器
ssh-audit hostname

# 审计特定端口
ssh-audit hostname:2222

nmap扫描

# 扫描SSH端口
nmap -p 22 hostname

# 详细扫描
nmap -sV -p 22 hostname

# 扫描SSH版本和算法
nmap --script ssh2-enum-algos hostname

网络诊断工具

tcpdump抓包

# 抓取SSH流量
sudo tcpdump -i any -n port 22

# 保存到文件
sudo tcpdump -i any -n port 22 -w ssh-traffic.pcap

# 分析特定主机
sudo tcpdump -i any -n host hostname and port 22

Wireshark分析

# 过滤SSH流量
tcp.port == 22

# 分析SSH握手
ssh.protocol

# 查看加密算法协商
ssh.kex

应急处理

紧急访问

控制台访问

# 物理控制台
# 直接在服务器上操作

# 虚拟控制台(云服务器)
# 通过云服务商的Web控制台

# IPMI/iDRAC
ipmitool -I lanplus -H ipmi-hostname -U username -P password sol activate

单用户模式

# 重启到单用户模式
# 在GRUB菜单中添加 single 或 1

# 修复SSH配置
sudo nano /etc/ssh/sshd_config
sudo systemctl restart sshd

配置恢复

备份和恢复

# 备份SSH配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
cp ~/.ssh/config ~/.ssh/config.backup

# 恢复默认配置
sudo cp /etc/ssh/sshd_config.backup /etc/ssh/sshd_config
sudo systemctl restart sshd

# 重新生成主机密钥
sudo rm /etc/ssh/ssh_host_*
sudo ssh-keygen -A
sudo systemctl restart sshd

预防措施

监控和告警

连接监控脚本

#!/bin/bash
# SSH连接监控

HOST="critical-server"
MAX_ATTEMPTS=3

for i in $(seq 1 $MAX_ATTEMPTS); do
    if ssh -o ConnectTimeout=10 -o BatchMode=yes $HOST "echo 'SSH OK'" >/dev/null 2>&1; then
        echo "SSH connection to $HOST: OK"
        exit 0
    else
        echo "SSH connection to $HOST: FAILED (attempt $i/$MAX_ATTEMPTS)"
        sleep 5
    fi
done

# 发送告警
echo "SSH connection to $HOST failed after $MAX_ATTEMPTS attempts" | mail -s "SSH Alert" admin@company.com

日志轮转

# /etc/logrotate.d/ssh-custom
/var/log/ssh-custom.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    postrotate
        /bin/kill -HUP $(cat /var/run/rsyslogd.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

定期维护

健康检查清单

  • [ ] SSH服务状态正常
  • [ ] 配置文件语法正确
  • [ ] 密钥权限设置正确
  • [ ] 日志文件大小合理
  • [ ] 防火墙规则有效
  • [ ] 系统资源充足
  • [ ] 网络连通性正常
  • [ ] 证书未过期

自动化检查脚本

#!/bin/bash
# SSH健康检查脚本

echo "=== SSH健康检查报告 ==="
echo "检查时间: $(date)"
echo

# 检查SSH服务状态
echo "1. SSH服务状态:"
systemctl is-active sshd
echo

# 检查配置文件
echo "2. 配置文件语法:"
sudo sshd -t && echo "配置文件语法正确" || echo "配置文件语法错误"
echo

# 检查端口监听
echo "3. 端口监听状态:"
ss -tlnp | grep sshd
echo

# 检查磁盘空间
echo "4. 磁盘空间:"
df -h | grep -E "(Filesystem|/$|/var|/home)"
echo

# 检查内存使用
echo "5. 内存使用:"
free -h
echo

# 检查最近的连接
echo "6. 最近的SSH连接:"
sudo grep "Accepted" /var/log/auth.log | tail -5
echo

echo "=== 检查完成 ==="

小结

SSH故障排除是一个系统性的过程,需要从网络、系统、配置、权限等多个层面进行分析。关键要点包括:

  1. 系统化排查:按照网络连通性 → 服务状态 → 配置正确性 → 权限设置的顺序
  2. 详细日志分析:充分利用SSH的详细调试输出和系统日志
  3. 工具辅助:使用专业的网络和SSH诊断工具
  4. 预防为主:建立监控机制,定期检查和维护
  5. 应急准备:准备多种访问方式和恢复方案

掌握这些故障排除技能,能够快速定位和解决SSH相关问题,确保系统的稳定运行。


上一章节SSH高级用法
教程首页SSH基础概念