SSH 安全配置与密钥管理最佳实践

一、概述

SSH(Secure Shell)是远程服务器管理的核心工具。不安全的 SSH 配置可能导致服务器被入侵。本文详细介绍 SSH 安全加固和密钥管理的最佳实践。

二、SSH 协议基础

2.1 认证方式对比

认证方式 安全性 便捷性 推荐场景
密码认证 ★★☆☆☆ ★★★★☆ 临时访问、应急
密钥认证 ★★★★★ ★★★☆☆ 日常运维、自动化
双因素认证 ★★★★★ ★★☆☆☆ 高安全要求场景

2.2 SSH 工作流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
客户端                          服务器
| |
|------ TCP 连接建立 --------->|
| |
|<----- 协议版本协商 ----------|
| |
|------ 密钥交换 ------------->|
| |
|<----- 服务器公钥 -----------|
| |
|------ 用户认证 ------------->|
| |
|<----- 认证成功 -------------|
| |
|====== 加密会话建立 =========>|

三、SSH 服务端配置

3.1 配置文件位置

1
2
3
4
5
6
7
8
# 主配置文件
/etc/ssh/sshd_config

# 客户端配置
~/.ssh/config

# 主机密钥
/etc/ssh/ssh_host_*_key

3.2 基础安全配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# /etc/ssh/sshd_config

# 禁用密码认证(强制使用密钥)
PasswordAuthentication no

# 禁用空密码
PermitEmptyPasswords no

# 禁用 root 直接登录
PermitRootLogin no

# 限制登录用户
AllowUsers admin deploy

# 限制登录组
AllowGroups sshusers

# 修改默认端口(可选,减少扫描)
Port 2222

# 仅使用 SSH 协议版本 2
Protocol 2

# 监听特定地址
ListenAddress 0.0.0.0

3.3 会话安全配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 最大认证尝试次数
MaxAuthTries 3

# 最大并发未认证连接
MaxStartups 10:30:60

# 登录宽限时间
LoginGraceTime 60

# 客户端活跃检查间隔
ClientAliveInterval 300

# 客户端活跃检查次数
ClientAliveCountMax 2

# 禁用转发(根据需求)
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no

3.4 密钥算法配置

1
2
3
4
5
6
7
8
9
10
11
# 推荐的主机密钥算法
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# 推荐的密钥交换算法
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256

# 推荐的加密算法
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com

# 推荐的 MAC 算法
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

3.5 日志配置

1
2
3
4
5
# 日志级别
LogLevel VERBOSE

# 日志文件
SyslogFacility AUTH

四、SSH 密钥管理

4.1 生成密钥对

1
2
3
4
5
6
7
8
# 生成 Ed25519 密钥(推荐)
ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519

# 生成 RSA 密钥(4096 位)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa

# 生成 ECDSA 密钥
ssh-keygen -t ecdsa -b 521 -C "your_email@example.com" -f ~/.ssh/id_ecdsa

4.2 密钥参数说明

参数 说明
-t 密钥类型 (ed25519/rsa/ecdsa)
-b 密钥位数 (RSA/ECDSA)
-C 注释(通常是邮箱)
-f 输出文件路径
-N 设置 passphrase(空字符串表示无密码)

4.3 部署公钥到服务器

1
2
3
4
5
6
7
8
9
10
# 方法 1:使用 ssh-copy-id(推荐)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostname

# 方法 2:手动复制
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 方法 3:使用脚本批量部署
for host in server1 server2 server3; do
ssh-copy-id user@$host
done

4.4 authorized_keys 管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# authorized_keys 格式
# [选项] 密钥类型 公钥数据 注释

# 限制特定 IP 访问
from="192.168.1.0/24" ssh-ed25519 AAAA... user@work

# 限制命令执行
command="/usr/bin/rsync --server" ssh-ed25519 AAAA... backup@server

# 禁用端口转发
no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... restricted@user

# 完整示例
from="10.0.0.0/8",command="/bin/date",no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@office

4.5 密钥权限设置

1
2
3
4
5
6
7
8
9
# 本地密钥权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

# 服务器端权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh

五、SSH 客户端配置

5.1 客户端配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# ~/.ssh/config

# 全局默认设置
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3

# 生产服务器
Host prod-*
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
StrictHostKeyChecking yes

# 开发服务器
Host dev-*
User developer
Port 22
IdentityFile ~/.ssh/id_ed25519_dev
StrictHostKeyChecking no

# 跳板机配置
Host jump
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/id_ed25519

# 通过跳板机访问内网服务器
Host internal-*
ProxyJump jump
User admin
IdentityFile ~/.ssh/id_ed25519_internal

5.2 常用快捷命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用配置别名连接
ssh prod-web01

# 执行远程命令
ssh prod-web01 "systemctl status nginx"

# 传输文件
scp file.txt prod-web01:/tmp/
scp -r directory/ prod-web01:/tmp/

# 端口转发(本地)
ssh -L 8080:localhost:80 prod-web01

# 端口转发(远程)
ssh -R 9090:localhost:22 prod-web01

# SOCKS 代理
ssh -D 1080 prod-web01

六、高级安全配置

6.1 双因素认证(2FA)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装 Google Authenticator
# Ubuntu/Debian
sudo apt install libpam-google-authenticator

# CentOS/RHEL
sudo yum install google-authenticator

# 配置 PAM
# /etc/pam.d/sshd
auth required pam_google_authenticator.so

# 启用挑战 - 响应认证
# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

6.2 Fail2Ban 防护

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装 Fail2Ban
sudo apt install fail2ban

# 配置 SSH 防护
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 22,2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

# 重启服务
sudo systemctl restart fail2ban

6.3 证书认证(CA)

1
2
3
4
5
6
7
8
9
10
11
12
# 生成 CA 密钥
ssh-keygen -t ed25519 -f ssh_ca

# 签署用户密钥
ssh-keygen -s ssh_ca -I user_cert -n admin -V +52w ~/.ssh/id_ed25519.pub

# 配置服务器信任 CA
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca.pub

# 部署 CA 公钥到服务器
sudo cp ssh_ca.pub /etc/ssh/ca.pub

七、审计与监控

7.1 查看登录日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看成功登录
last

# 查看失败登录
lastb

# 查看当前登录用户
who

# 查看用户登录历史
lastlog

# 实时查看 SSH 登录
tail -f /var/log/auth.log | grep sshd

7.2 审计配置

1
2
3
4
5
6
7
8
9
10
# 启用详细日志
# /etc/ssh/sshd_config
LogLevel VERBOSE

# 使用 auditd 监控
sudo auditctl -w /etc/ssh/sshd_config -p wa -k sshd_config
sudo auditctl -w /etc/ssh/ -p wa -k ssh_keys

# 查询审计日志
ausearch -k sshd_config

7.3 安全扫描

1
2
3
4
5
6
# 使用 lynis 进行安全审计
sudo apt install lynis
sudo lynis audit system

# 检查 SSH 配置
sudo sshd -T | grep -E "(password|root|permit)"

八、常见问题排查

8.1 连接问题诊断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 详细调试模式
ssh -vvv user@hostname

# 测试端口连通性
nc -zv hostname 22
telnet hostname 22

# 检查防火墙
sudo ufw status
sudo iptables -L -n

# 检查 SSH 服务状态
sudo systemctl status sshd
sudo netstat -tlnp | grep :22

8.2 常见错误及解决

错误信息 可能原因 解决方案
Permission denied (publickey) 密钥未授权 检查 authorized_keys
Connection refused 服务未运行 systemctl start sshd
Connection timed out 防火墙阻挡 检查防火墙规则
Host key verification failed 主机密钥变更 删除~/.ssh/known_hosts 中对应条目
Bad owner or permissions 权限不正确 chmod 700 ~/.ssh && chmod 600 ~/.ssh/*

8.3 密钥权限修复脚本

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# fix_ssh_permissions.sh

echo "Fixing SSH permissions..."

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 644 ~/.ssh/known_hosts
chmod 600 ~/.ssh/config 2>/dev/null

echo "Permissions fixed."

九、安全加固检查清单

9.1 基础检查

  • 禁用密码认证
  • 禁用 root 登录
  • 修改默认端口(可选)
  • 限制允许登录的用户/组
  • 使用强密钥算法

9.2 进阶检查

  • 启用双因素认证
  • 配置 Fail2Ban
  • 设置会话超时
  • 禁用不必要的转发
  • 启用详细日志

9.3 运维检查

  • 定期轮换密钥
  • 审计登录日志
  • 清理未使用的 authorized_keys
  • 备份 SSH 配置
  • 监控异常登录

十、总结

SSH 安全是服务器安全的第一道防线。通过合理的配置和密钥管理,可以大幅降低被入侵的风险。建议:

  1. 强制使用密钥认证,禁用密码登录
  2. 定期轮换密钥,特别是人员变动时
  3. 启用日志审计,及时发现异常
  4. 使用跳板机,集中管理访问入口
  5. 实施最小权限,只开放必要的访问

安全是一个持续的过程,定期审查和更新 SSH 配置至关重要。