一、故障分类与排查框架
graph TD
A[连接失败] --> A1[网络问题]
A --> A2[认证失败]
A --> A3[配置错误]
B[连接缓慢] --> B1[DNS解析]
B --> B2[GSSAPI问题]
B --> B3[连接限流]
C[会话异常] --> C1[意外断开]
C --> C2[命令超时]
C --> C3[端口转发失败]
二、核心排查命令速查表
| **故障类型** | **排查命令** | **关键日志文件** |
| --- | --- | --- |
| 基础连接问题 | `ping HOST`<br>`telnet HOST 22`<br>`nc -zv HOST 22` | `/var/log/auth.log`<br>`/var/log/secure` |
| 认证问题 | `ssh -v user@HOST`<br>`ssh -T user@HOST` | `/var/log/secure`<br>`~/.ssh/config` |
| 性能问题 | `time ssh user@HOST exit`<br>`systemctl status sshd` | `journalctl -u sshd` |
| 防火墙问题 | `iptables -L -n`<br>`firewall-cmd --list-all` | `/var/log/kern.log` |
三、典型运维案例解析
案例1:密钥认证失败
**现象**:`Permission denied (publickey)`**排查过程**:
详细调试模式
ssh -vvv user@host
服务端检查(在目标服务器执行)
tail -f /var/log/auth.log
日志显示:Authentication refused: bad ownership or modes for directory /home/user/.ssh
权限检查
ls -ld /home/user /home/user/.ssh /home/user/.ssh/authorized_keys
发现 /home/user/.ssh 权限为 777(应为 700)
**解决方案**:
chmod 700 /home/user/.ssh
chmod 600 /home/user/.ssh/authorized_keys
chown -R user:user /home/user/.ssh
案例2:SSH连接缓慢(10+秒)
**问题诊断**:
连接耗时分析
time ssh user@host exit
real 0m10.23s
服务端配置检查
grep -E 'UseDNS|GSSAPIAuth' /etc/ssh/sshd_config
UseDNS yes
GSSAPIAuthentication yes
禁用问题参数(服务端配置)
echo "UseDNS no" | sudo tee -a /etc/ssh/sshd_config
echo "GSSAPIAuthentication no" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl reload sshd
**优化结果**:连接时间从10秒降至0.8秒
案例3:防火墙阻断SFTP连接
**现象**:SSH正常但SFTP连接失败**排查过程**:
检查网络层
tcpdump -i eth0 port 22 and host CLIENT_IP
显示连接SYN包未响应
防火墙检查
firewall-cmd --list-all | grep sftp
无相关规则
**解决方案**:
添加防火墙规则
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=sftp
firewall-cmd --reload
确认防火墙配置
firewall-cmd --list-all | grep service
services: ssh sftp dhcpv6-client
四、高级配置优化
1. 安全性强化配置
/etc/ssh/sshd_config
禁用不安全的认证方式
PasswordAuthentication no
ChallengeResponseAuthentication no
仅允许新协议
Protocol 2
限制用户访问
AllowUsers admin deploy
AllowGroups ssh-users
启用暴力破解防护
MaxAuthTries 3
MaxSessions 10
LoginGraceTime 1m
日志增强
LogLevel VERBOSE
2. 性能优化配置
/etc/ssh/sshd_config
提高并发处理能力
MaxStartups 100:30:200
优化加密算法
Ciphers aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha2-256,hmac-sha2-512
连接保活
ClientAliveInterval 60
ClientAliveCountMax 5
五、防火墙配置模板
UFW防火墙规则
仅允许特定IP段访问
sudo ufw allow proto tcp from 192.168.1.0/24 to any port 22
sudo ufw allow proto tcp from 10.0.0.0/8 to any port 22
sudo ufw default deny incoming
sudo ufw enable
iptables防火墙规则
保存为脚本 /usr/local/bin/ssh-firewall.sh
#!/bin/sh
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
六、自动化运维工具
1. 批量密钥部署脚本
#!/bin/bash
deploy_keys.sh
USER=$1
PUBKEY=$2
HOSTS="server1 server2 server3"
for host in $HOSTS; do
ssh admin@host "sudo mkdir -p /home/USER/.ssh &&
sudo chmod 700 /home/$USER/.ssh &&
echo 'PUBKEY' \| sudo tee /home/USER/.ssh/authorized_keys &&
sudo chmod 600 /home/$USER/.ssh/authorized_keys &&
sudo chown -R USER:USER /home/$USER/.ssh"
done
2. 暴力破解防护脚本
/usr/local/bin/ssh_defender.sh
#!/bin/bash
LOG=/var/log/auth.log
ATTEMPTS=3
tail -Fn0 $LOG | \
while read LINE; do
if echo "$LINE" | grep -q "Failed password"; then
IP=(echo "LINE" | grep -oP '([0-9]{1,3}\.){3}[0-9]{1,3}')
echo "(date) IP failed login attempt"
fail2ban-client set sshd banip $IP
elif echo "$LINE" | grep -q "Accepted"; then
IP=(echo "LINE" | grep -oP '([0-9]{1,3}\.){3}[0-9]{1,3}')
fail2ban-client set sshd unbanip $IP
fi
done
七、日志分析与审计
关键日志分析命令
统计失败登录
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr
分析成功登录
grep "Accepted" /var/log/auth.log | awk '{print 1,2,3,9,$11}'
检测暴力破解
awk '/Failed password/ {fail[$11]++}
/Accepted/ {success[$11]++}
END {for (ip in fail)
if (fail[ip] >= 3 && !(ip in success))
print "恶意IP:" ip " 尝试次数:" fail[ip]}' /var/log/auth.log
八、隧道与端口转发故障
案例:数据库端口转发失败
**现象**:`channel X: open failed: connect failed: Connection refused`**解决方案**:
检查目标服务是否监听回环地址
ssh -NL 3306:localhost:3306 user@dbserver
报错:connect failed
在dbserver检查数据库绑定
netstat -tuln | grep 3306
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
解决方案(修改数据库配置):
mysqld
bind-address = 0.0.0.0
持久化隧道解决方案
使用autossh保持隧道稳定
autossh -M 20000 -N \
-L 8080:localhost:80 \
-R 2222:localhost:22 \
user@relay-server
添加systemd服务(/etc/systemd/system/ssh-tunnel.service)
Unit
Description=AutoSSH Tunnel
After=network.target
Service
User=tunnel
ExecStart=/usr/bin/autossh -M 20000 -Nq \
-L 3306:db-host:3306 \
jump-server
Install
WantedBy=multi-user.target
九、多因素认证方案
Google Authenticator集成
服务器安装
sudo apt install libpam-google-authenticator
用户配置
google-authenticator
PAM配置(/etc/pam.d/sshd)
auth required pam_google_authenticator.so
SSH配置(/etc/ssh/sshd_config)
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
十、灾难恢复方案
紧急访问通道创建
1. 创建仅限本地的备用端口
sudo nano /etc/ssh/sshd_config.d/emergency.conf
Port 2222
ListenAddress 127.0.0.1
PermitRootLogin yes
PasswordAuthentication yes
2. 创建SSH-to-HTTPS隧道(当防火墙只开80/443)
ssh -R 80:localhost:2222 serveo.net
3. 本地连接(通过SSH over HTTPs)
ssh -p 2222 user@localhost -o "ProxyCommand=nc -X connect -x serveo.net:443 %h %p"
> **SSH运维黄金法则**:
>
> 1. **最小权限原则**:禁用root登录,限制用户权限
> 2. **双重验证**:密钥认证 + MFA
> 3. **网络隔离**:仅开放必要IP访问
> 4. **配置管理**:统一管理sshd_config和客户端配置
>
> **故障恢复优先级**:
>
> graph LR
> A[网络层] --> B[服务状态]
> B --> C[认证配置]
> C --> D[资源限制]
> D --> E[日志分析]
>
> **连接恢复三步法**:
>
> 1. `telnet host 22` - 验证TCP连通性
> 2. `ssh -vvv user@host` - 诊断协议流程
> 3. `journalctl -u sshd --since "5 min ago"` - 检查服务端日志
>
> **安全基线要求**:
>
> * 禁用SSHv1
> * 禁用密码认证
> * 禁用空密码
> * 启用登录超时
> * 限制用户和组访问
> * 配置空闲会话超时
> * 定期轮换主机密钥(每年)