SSH 密钥登录配置全流程指南
将服务器的密码登录改为密钥登录,提升安全性,防止暴力破解攻击。
📋 目录
- 整体流程概览
- [第一步:生成 SSH 密钥对](#第一步生成 ssh 密钥对)
- 第二步:将公钥部署到服务器
- 第三步:测试密钥登录
- 第四步:禁用密码登录
- 第五步:验证配置
- 常见问题与解决
- 最佳实践
整体流程概览
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 生成密钥对 │ → │ 部署公钥到服务器 │ → │ 测试密钥登录 │ → │ 禁用密码登录 │
│ (本地电脑) │ │ (线上服务器) │ │ (验证成功) │ │ (安全加固) │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
⚠️ 重要提醒:
- 不要关闭当前 SSH 会话,直到新终端测试密钥登录成功
- 配置错误时,可用当前会话恢复,避免被锁在服务器外
第一步:生成 SSH 密钥对
Mac / Linux
# 1. 检查是否已有密钥
ls -la ~/.ssh/
# 2. 生成新密钥(推荐 Ed25519,更安全)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 或生成 RSA 密钥(兼容旧系统)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 3. 按提示操作
# - 保存路径:直接回车(默认 ~/.ssh/id_ed25519)
# - passphrase:建议设置(增加安全性)或回车跳过
输出示例:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/yourname/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/yourname/.ssh/id_ed25519
Your public key has been saved in /Users/yourname/.ssh/id_ed25519.pub
Windows(PowerShell 或 CMD)
# 1. 检查是否已有密钥
dir ~\.ssh\
# 2. 生成新密钥
ssh-keygen -t ed25519 -C "your_email@example.com"
# 3. 按提示操作(同上)
生成的文件
| 文件 | 说明 | 权限 |
|---|---|---|
~/.ssh/id_ed25519 | 私钥(保密,不要分享) | 600 |
~/.ssh/id_ed25519.pub | 公钥(可公开,部署到服务器) | 644 |
查看公钥内容
cat ~/.ssh/id_ed25519.pub
# 输出示例:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com
第二步:将公钥部署到服务器
方法一:使用 ssh-copy-id(Mac / Linux 推荐)
# 标准 SSH 端口(22)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostname
# 自定义端口(如 12222)
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 12222 user@hostname
# 或指定 SSH 选项
ssh-copy-id -i ~/.ssh/id_ed25519.pub -o "Port=12222" user@hostname
参数说明:
-i:指定公钥文件路径-p:SSH 端口号(放在主机名之前)user@hostname:服务器用户名和 IP
方法二:使用 ssh-copy-id(Windows Git Bash)
如果安装了 Git Bash:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostname
方法三:手动部署(通用方法)
1. 复制公钥内容
本地电脑:
cat ~/.ssh/id_ed25519.pub
# 复制输出内容,如:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
2. 登录服务器并配置
登录服务器(使用密码):
ssh user@hostname -p 12222
在服务器上执行:
# 1. 创建 .ssh 目录
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 2. 添加公钥(粘贴刚才复制的内容)
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 3. 修复权限(CentOS/RHEL 可能需要)
restorecon -R -v ~/.ssh 2>/dev/null || true
# 4. 验证文件内容
cat ~/.ssh/authorized_keys
第三步:测试密钥登录
⚠️ 关键步骤
不要关闭当前 SSH 会话! 新开一个终端窗口测试。
Mac / Linux 测试
# 标准端口
ssh -i ~/.ssh/id_ed25519 user@hostname
# 自定义端口
ssh -i ~/.ssh/id_ed25519 -p 12222 user@hostname
Windows(PowerShell / Git Bash)测试
# 标准端口
ssh -i ~/.ssh/id_ed25519 user@hostname
# 自定义端口
ssh -i ~/.ssh/id_ed25519 -p 12222 user@hostname
成功标志
- 直接登录成功,不需要输入密码
- 如果设置了 passphrase,会提示输入 passphrase(不是服务器密码)
失败排查
# 使用详细模式查看连接过程
ssh -v -i ~/.ssh/id_ed25519 -p 12222 user@hostname
# 查看服务器日志(需要另一个能登录的会话)
sudo tail -f /var/log/auth.log # Ubuntu/Debian
sudo tail -f /var/log/secure # CentOS/RHEL
第四步:禁用密码登录
Ubuntu / Debian
# 1. 备份原配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 2. 修改配置(使用 sed 自动替换)
sudo sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
# 3. 确认配置
sudo grep -E "^(PubkeyAuthentication|PasswordAuthentication|PermitRootLogin)" /etc/ssh/sshd_config
# 4. 重启 SSH 服务
sudo systemctl restart sshd
# 5. 检查服务状态
sudo systemctl status sshd --no-pager
CentOS / RHEL
# 1. 备份原配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 2. 修改配置(使用 sed 自动替换)
sudo sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
# 3. 确认配置
sudo grep -E "^(PubkeyAuthentication|PasswordAuthentication|PermitRootLogin)" /etc/ssh/sshd_config
# 4. 重启 SSH 服务
sudo systemctl restart sshd
# 5. 检查服务状态
sudo systemctl status sshd --no-pager
配置项说明
| 配置项 | 推荐值 | 说明 |
|---|---|---|
PubkeyAuthentication | yes | 启用公钥认证 |
PasswordAuthentication | no | 禁用密码认证 |
PermitRootLogin | prohibit-password | 禁止 root 密码登录,允许密钥登录 |
手动编辑配置(可选)
如果 sed 命令不生效,可手动编辑:
sudo vi /etc/ssh/sshd_config
# 或
sudo nano /etc/ssh/sshd_config
确保以下配置(取消注释并修改):
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password
AuthorizedKeysFile .ssh/authorized_keys
ChallengeResponseAuthentication no
UsePAM yes
第五步:验证配置
测试 1:密钥登录(应该成功)
ssh -i ~/.ssh/id_ed25519 -p 12222 user@hostname
预期: 直接登录成功
测试 2:密码登录(应该被拒绝)
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no -p 12222 user@hostname
预期:
user@hostname: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
测试 3:查看服务器日志
Ubuntu / Debian:
sudo grep "sshd" /var/log/auth.log | tail -20
CentOS / RHEL:
sudo grep "sshd" /var/log/secure | tail -20
成功标志:
- 新连接日志显示
Connection closed by ... [preauth] - 没有
Failed password记录(密码认证在验证前就被拒绝)
常见问题与解决
问题 1:密钥登录失败,仍然提示输入密码
可能原因:
- 公钥未正确部署到服务器
- 权限设置错误
- SSH 配置未生效
解决步骤:
# 1. 检查服务器上的 authorized_keys
ssh user@hostname
cat ~/.ssh/authorized_keys
# 2. 检查权限
ls -la ~/.ssh/
# 应该是:drwx------ .ssh 和 -rw------- authorized_keys
# 3. 修复权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 4. 检查 SSH 配置
sudo grep -E "^(PubkeyAuthentication|PasswordAuthentication)" /etc/ssh/sshd_config
# 5. 重启 SSH
sudo systemctl restart sshd
问题 2:ssh-copy-id 报错 "Too many arguments"
原因: 参数顺序错误
错误示例:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostname -p 12222 # ❌ 错误
正确示例:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 12222 user@hostname # ✅ 正确
# 或
ssh-copy-id -i ~/.ssh/id_ed25519.pub -o "Port=12222" user@hostname # ✅ 正确
问题 3:CentOS 7 SELinux 阻止密钥登录
症状: 权限正确但仍无法登录
解决:
# 1. 检查 SELinux 状态
getenforce
# 2. 修复安全上下文
restorecon -R -v ~/.ssh
# 3. 或临时禁用 SELinux 测试
sudo setenforce 0
问题 4:防火墙阻止 SSH 连接
Ubuntu:
sudo ufw allow 22/tcp
# 或自定义端口
sudo ufw allow 12222/tcp
CentOS:
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=12222/tcp
sudo firewall-cmd --reload
问题 5:被锁在服务器外
紧急恢复:
- 通过云服务商控制台(阿里云/腾讯云/AWS)使用 VNC 登录
- 恢复备份配置:
sudo cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config sudo systemctl restart sshd - 重新检查配置
最佳实践
1. 使用强密钥
- 优先使用 Ed25519(更安全、更快)
- RSA 密钥至少 4096 位
- 设置 passphrase 保护私钥
2. 密钥管理
# 为不同服务器生成不同密钥
ssh-keygen -t ed25519 -C "work-server" -f ~/.ssh/id_ed25519_work
ssh-keygen -t ed25519 -C "home-server" -f ~/.ssh/id_ed25519_home
# 配置 SSH config 简化登录
vi ~/.ssh/config
SSH config 示例:
# 工作服务器
Host work
HostName 121.41.109.44
Port 12222
User root
IdentityFile ~/.ssh/id_ed25519_work
# 家庭服务器
Host home
HostName 192.168.1.100
User ubuntu
IdentityFile ~/.ssh/id_ed25519_home
使用:
ssh work # 自动使用对应密钥
ssh home
3. 禁用 root 登录(可选)
# 修改 /etc/ssh/sshd_config
PermitRootLogin no
# 创建普通用户并授权
sudo adduser admin
sudo usermod -aG sudo admin # Ubuntu
sudo usermod -aG wheel admin # CentOS
4. 配置 fail2ban(防止暴力破解)
Ubuntu:
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
CentOS:
sudo yum install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
5. 定期轮换密钥
# 生成新密钥
ssh-keygen -t ed25519 -C "new-key-2026" -f ~/.ssh/id_ed25519_new
# 部署到服务器
ssh-copy-id -i ~/.ssh/id_ed25519_new user@hostname
# 测试成功后,从 authorized_keys 删除旧公钥
6. 备份私钥
# 备份到安全位置(加密 U 盘、密码管理器等)
cp ~/.ssh/id_ed25519 /mnt/secure_backup/
cp ~/.ssh/id_ed25519.pub /mnt/secure_backup/
# 设置严格权限
chmod 600 /mnt/secure_backup/id_ed25519
快速检查清单
- 已生成 SSH 密钥对(Ed25519 或 RSA 4096)
- 公钥已部署到服务器
~/.ssh/authorized_keys - 服务器权限正确(
.ssh700,authorized_keys600) - 密钥登录测试成功(新开终端验证)
- SSH 配置已修改(
PasswordAuthentication no) - SSH 服务已重启
- 密码登录测试被拒绝
- 当前 SSH 会话保持打开直到验证完成
- 已备份 SSH 配置文件
附录:各系统默认路径
| 系统 | SSH 配置文件 | 日志文件 | 重启命令 |
|---|---|---|---|
| Ubuntu 20.04+ | /etc/ssh/sshd_config | /var/log/auth.log | systemctl restart sshd |
| Debian 10+ | /etc/ssh/sshd_config | /var/log/auth.log | systemctl restart sshd |
| CentOS 7/8 | /etc/ssh/sshd_config | /var/log/secure | systemctl restart sshd |
| RHEL 7/8 | /etc/ssh/sshd_config | /var/log/secure | systemctl restart sshd |