SSH 密钥是安全服务器认证的黄金标准,用加密密钥对替代密码。无论你是在设置新的开发机器、配置 CI/CD 流水线,还是加固生产服务器,理解如何生成和管理 SSH 密钥都是一项基本技能。本综合指南涵盖了从密钥算法选择(Ed25519 vs RSA vs ECDSA)到高级 SSH 配置、代理管理和常见问题排查的所有内容。
什么是 SSH 密钥?
SSH(安全外壳协议)密钥是用于身份认证的加密密钥对。不必每次连接远程服务器时都输入密码,SSH 密钥让你使用公钥加密来证明身份。这比基于密码的认证更安全、更方便。
SSH 密钥对由两个文件组成:
- 私钥: 私钥:保存在本地机器上。绝对不要与任何人共享此文件。它类似于打开门锁的物理钥匙。
- 公钥: 公钥:放置在每一台你想访问的服务器上。它类似于锁 — 任何人都可以看到它,但只有匹配的私钥才能打开它。
SSH 密钥认证的工作流程
# SSH Key Authentication Flow
Client Server
│ │
│── 1. Connection request ─────>│
│ │
│<── 2. Random challenge ───────│ (encrypted with your public key)
│ │
│── 3. Decrypted response ─────>│ (signed with your private key)
│ │
│<── 4. Access granted ─────────│ (response verified)
│ │这意味着即使攻击者截获了网络流量,他们也无法在没有你的私钥的情况下冒充你。而密码则可能被键盘记录器、钓鱼攻击或暴力破解所获取。
Ed25519 vs RSA vs ECDSA:算法对比
SSH 密钥生成有多种可用算法。最常见的三种是 RSA、ECDSA 和 Ed25519。每种都有不同的安全属性、性能特征和兼容性考量。
| 特性 | Ed25519 | RSA | ECDSA |
|---|---|---|---|
| 引入时间 | 2014(OpenSSH 6.5) | 1995(SSH-1) | 2011(OpenSSH 5.7) |
| 安全级别 | ~128 位(等效于 RSA-3072) | 112 位 (2048) / 128 位 (3072) / 192 位 (4096) | 128 位 (P-256) / 192 位 (P-384) |
| 私钥大小 | 64 字节(固定) | ~3,200 字节(4096 位) | ~256 字节(P-256) |
| 公钥大小 | 32 字节(固定) | ~512 字节(4096 位) | ~64 字节(P-256) |
| 签名速度 | 非常快 | 慢 | 快 |
| 验证速度 | 非常快 | 快 | 中等 |
| 兼容性 | OpenSSH 6.5+(2014),大多数现代系统 | 通用(所有 SSH 实现) | OpenSSH 5.7+,但 NIST 曲线存在争议 |
| 推荐 | 新密钥的最佳选择 | 如不支持 Ed25519 则使用 4096 位 | 一般不推荐 — 优先使用 Ed25519 |
Ed25519 是新 SSH 密钥的推荐算法。它以较小的密钥大小提供出色的安全性,操作速度快,并且能抵抗多类实现攻击。RSA-4096 仍然是不支持 Ed25519 的系统的可靠备选。由于对 NIST P-256 曲线的担忧以及对随机数生成质量的敏感性,通常不推荐使用 ECDSA。
生成 Ed25519 SSH 密钥
Ed25519 密钥是现代标准。它们快速、安全,生成紧凑的密钥文件。以下是逐步生成方法:
步骤 1:打开终端(Linux/macOS)或 Git Bash / PowerShell(Windows)。
步骤 2:运行使用 Ed25519 算法的 ssh-keygen 命令:
ssh-keygen -t ed25519 -C "your_email@example.com"步骤 3:当提示输入文件位置时,按 Enter 接受默认值(~/.ssh/id_ed25519),或指定自定义路径:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Press Enter for default, or type a custom path like:
# /home/user/.ssh/id_ed25519_github步骤 4:在提示时输入强密码短语(推荐),或按 Enter 跳过:
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
# Use a strong passphrase like: correct-horse-battery-staple步骤 5:验证密钥已创建:
ls -la ~/.ssh/id_ed25519*
# Expected output:
-rw------- 1 user user 464 Jan 15 10:30 /home/user/.ssh/id_ed25519
-rw-r--r-- 1 user user 105 Jan 15 10:30 /home/user/.ssh/id_ed25519.pub
# View your public key:
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com该命令生成两个文件:id_ed25519(私钥)和 id_ed25519.pub(公钥)。-C 标志添加注释(通常是你的邮箱)以帮助识别密钥。
Ed25519 常用 ssh-keygen 参数:
-t ed25519: -t ed25519:指定 Ed25519 算法。-C "comment": -C "注释":添加标识注释(通常是你的邮箱)。-f /path/to/key: -f /path/to/key:指定输出文件路径。-N "passphrase": -N "密码短语":非交互式设置密码短语(在脚本中有用)。-a 100: -a 100:密码短语保护的 KDF 轮数(越高 = 暴力破解越慢)。默认为 16。
# Generate Ed25519 key with all options in one command:
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_ed25519_work -a 100
# Generate key non-interactively (for scripts):
ssh-keygen -t ed25519 -C "deploy@ci" -f ~/.ssh/id_deploy -N "" -a 16生成 RSA SSH 密钥(4096 位)
如果你需要与不支持 Ed25519 的旧系统兼容,请使用最小密钥长度为 4096 位的 RSA。RSA-2048 仍然被认为是安全的,但未来的安全余量较小。
步骤 1:运行使用 RSA 和 4096 位的 ssh-keygen 命令:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"步骤 2:按照上述相同的提示操作(文件位置和密码短语)。
步骤 3:验证密钥:
ls -la ~/.ssh/id_rsa*
# Expected output:
-rw------- 1 user user 3,381 Jan 15 10:35 /home/user/.ssh/id_rsa
-rw-r--r-- 1 user user 749 Jan 15 10:35 /home/user/.ssh/id_rsa.pub
# View the public key:
cat ~/.ssh/id_rsa.pub
# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ... your_email@example.com
# Verify key details:
ssh-keygen -l -f ~/.ssh/id_rsa.pub
# 4096 SHA256:abc123... your_email@example.com (RSA)重要: 重要:永远不要使用少于 2048 位的 RSA 密钥。自 2013 年以来,RSA-1024 已被认为不安全。为获得最大安全余量,始终使用 4096 位。
RSA 常用 ssh-keygen 参数:
-b 4096: -b 4096:指定 4096 位密钥长度(现代 OpenSSH 默认为 3072)。-o: -o:使用新的 OpenSSH 私钥格式(更能抵抗暴力破解)。这是 OpenSSH 7.8 以来的默认格式。
SSH 密钥文件位置
SSH 密钥和配置文件存储在 ~/.ssh/ 目录中。了解此目录结构对管理 SSH 设置至关重要。
~/.ssh/
├── id_ed25519 # Ed25519 private key (chmod 600)
├── id_ed25519.pub # Ed25519 public key (chmod 644)
├── id_rsa # RSA private key (chmod 600)
├── id_rsa.pub # RSA public key (chmod 644)
├── config # SSH client config (chmod 600)
├── known_hosts # Server fingerprints (chmod 644)
└── authorized_keys # Allowed public keys (chmod 600, server-side)| 文件 | 用途 | 权限 |
|---|---|---|
| ~/.ssh/ 目录 | 父目录也必须具有正确的权限 | 700 (drwx------) |
| id_ed25519 | Ed25519 私钥 | 600 (-rw-------) |
| id_ed25519.pub | Ed25519 公钥 | 644 (-rw-r--r--) |
| id_rsa | RSA 私钥 | 600 (-rw-------) |
| id_rsa.pub | RSA 公钥 | 644 (-rw-r--r--) |
| config | SSH 客户端配置文件 | 600 (-rw-------) |
| known_hosts | 你已连接过的服务器指纹列表(防止中间人攻击) | 644 (-rw-r--r--) |
| authorized_keys | 允许登录此服务器的公钥列表(服务器端) | 600 (-rw-------) |
在 Windows 上,SSH 目录通常位于 C:\Users\你的用户名\.ssh\。如果你使用 Git Bash,它会像 Linux/macOS 一样映射到 ~/.ssh/。
SSH 配置文件(~/.ssh/config)
SSH 配置文件是一个强大的工具,让你定义连接预设、管理多个密钥和配置高级选项。你可以创建命名别名,而不是输入冗长的 SSH 命令。
基本配置示例
创建或编辑 ~/.ssh/config:
# ~/.ssh/config
# Personal server
Host myserver
HostName 203.0.113.50
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519
# Now connect with just:
# ssh myserver
# Instead of:
# ssh -i ~/.ssh/id_ed25519 deploy@203.0.113.50为不同服务使用多个密钥
如果你为 GitHub、GitLab 和生产服务器使用不同的密钥:
# ~/.ssh/config
# GitHub (personal account)
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
# GitHub (work account)
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
# GitLab
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
IdentitiesOnly yes
PreferredAuthentications publickey
# Production server
Host production
HostName prod.example.com
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes
# Usage:
# git clone git@github.com-personal:myuser/repo.git
# git clone git@github.com-work:company/repo.git
# ssh productionProxyJump:通过堡垒机连接
如果你需要通过跳板机(堡垒机)SSH 到内部服务器:
# ~/.ssh/config
# Bastion / Jump host
Host bastion
HostName bastion.example.com
User jumpuser
IdentityFile ~/.ssh/id_ed25519
Port 22
# Internal server (accessed through bastion)
Host internal-server
HostName 10.0.1.50
User admin
IdentityFile ~/.ssh/id_ed25519
ProxyJump bastion
# Chained jump: client → bastion1 → bastion2 → target
Host deep-internal
HostName 10.0.2.100
User admin
ProxyJump bastion,bastion2现在你可以直接连接:ssh internal-server。SSH 会自动先跳转通过堡垒机。
通配符和默认设置
为所有连接应用默认设置:
# ~/.ssh/config
# Default settings for all hosts
Host *
AddKeysToAgent yes
IdentitiesOnly yes
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
# Settings for all *.example.com hosts
Host *.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519_work
Port 2222常用 SSH 配置选项
IdentityFile: IdentityFile:要使用的私钥路径。IdentitiesOnly: IdentitiesOnly yes:仅使用指定的密钥,不尝试代理中的其他密钥。ForwardAgent: ForwardAgent yes:将本地 SSH 代理转发到远程服务器(谨慎使用)。ServerAliveInterval: ServerAliveInterval 60:每 60 秒发送一个保活数据包以防止断开连接。ProxyJump: ProxyJump bastion:通过另一个 SSH 主机路由连接。Port: Port 2222:连接到非标准 SSH 端口。
将 SSH 密钥添加到 GitHub / GitLab
使用 SSH 密钥是 GitHub 和 GitLab 进行 Git 操作认证的推荐方式。以下是设置方法:
步骤 1:复制你的公钥
显示并复制你的公钥:
# Linux / macOS
cat ~/.ssh/id_ed25519.pub
# macOS — copy directly to clipboard:
pbcopy < ~/.ssh/id_ed25519.pub
# Linux (with xclip):
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# Windows (PowerShell):
Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard
# Windows (Git Bash):
clip < ~/.ssh/id_ed25519.pub步骤 2:将密钥添加到 GitHub
步骤 3:将密钥添加到 GitLab
步骤 4:测试连接
验证你的 SSH 密钥是否正常工作:
# Test GitHub connection:
ssh -T git@github.com如果成功,你会看到类似以下的消息:
Hi username! You've successfully authenticated, but GitHub does not provide shell access.对于 GitLab:
# Test GitLab connection:
ssh -T git@gitlab.com
# Expected output:
Welcome to GitLab, @username!步骤 5:使用 SSH 克隆仓库
现在你可以使用 SSH URL 而不是 HTTPS 来克隆仓库:
# Clone via SSH (recommended):
git clone git@github.com:username/repository.git
# Instead of HTTPS:
# git clone https://github.com/username/repository.git将现有仓库从 HTTPS 切换到 SSH:
# Check current remote URL:
git remote -v
# origin https://github.com/username/repo.git (fetch)
# Switch to SSH:
git remote set-url origin git@github.com:username/repo.git
# Verify:
git remote -v
# origin git@github.com:username/repo.git (fetch)SSH 代理:在内存中管理密钥
SSH 代理是一个后台进程,将你的私钥保存在内存中,这样你就不必每次使用 SSH 密钥时都输入密码短语。如果你的密钥受密码短语保护(应该如此),它特别有用。
启动 SSH 代理
在 Linux/macOS 上:
# Start the SSH agent in the background:
eval "$(ssh-agent -s)"
# Output: Agent pid 12345
# Add to your shell profile (~/.bashrc, ~/.zshrc) to start automatically:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
fi在 Windows 上(PowerShell):
# PowerShell (run as Administrator to enable the service):
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
# Verify it is running:
Get-Service ssh-agent
# Status: Running将密钥添加到代理
将你的私钥添加到代理:
# Add a specific key:
ssh-add ~/.ssh/id_ed25519
# Enter passphrase for /home/user/.ssh/id_ed25519:
# Identity added: /home/user/.ssh/id_ed25519 (your_email@example.com)
# Add RSA key:
ssh-add ~/.ssh/id_rsa添加所有默认密钥:
# Add all default keys (id_rsa, id_ed25519, etc.):
ssh-add列出代理中的密钥
查看当前加载在代理中的所有密钥:
# List keys with fingerprints:
ssh-add -l
# 256 SHA256:abc123... your_email@example.com (ED25519)
# 4096 SHA256:def456... your_email@example.com (RSA)
# List keys with full public key:
ssh-add -LmacOS 钥匙串集成
在 macOS 上,你可以将 SSH 密钥密码短语存储在系统钥匙串中,使其在重启后仍然有效:
# Add key to macOS Keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519将以下内容添加到 ~/.ssh/config 以自动从钥匙串加载密钥:
# ~/.ssh/config (macOS)
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519设置密钥生命周期
为安全起见,你可以设置超时,使密钥在一段时间不活动后自动移除:
# Add key with 1-hour timeout:
ssh-add -t 3600 ~/.ssh/id_ed25519
# Add key with 8-hour timeout (workday):
ssh-add -t 28800 ~/.ssh/id_ed25519
# Remove all keys from the agent:
ssh-add -D代理转发
代理转发让你在远程服务器上使用本地 SSH 密钥,无需将密钥复制到那里。当你需要从一个服务器 SSH 到另一个服务器时使用(例如在部署服务器上从 GitHub 拉取):
# Forward agent for a single connection:
ssh -A user@server.example.com
# Or configure in ~/.ssh/config:
Host deploy-server
HostName deploy.example.com
User deploy
ForwardAgent yes
# On the remote server, you can now use your local keys:
# ssh -T git@github.com ← works without copying keys to the server警告: 警告:代理转发会将你的密钥暴露给远程服务器上具有 root 权限的任何人。仅在你信任的服务器上使用。考虑使用 ProxyJump 作为更安全的替代方案。
SSH 密钥密码短语
密码短语为你的私钥文件添加了一层加密。即使有人窃取了你的私钥文件,没有密码短语他们也无法使用它。
为什么要使用密码短语?
- 笔记本被盗:如果你的笔记本被盗,密码短语可以防止对你的服务器的即时访问。
- 恶意软件:如果恶意软件读取了你的 ~/.ssh/ 目录,加密的密钥没有密码短语就无法使用。
- 共享机器:如果其他人可以访问你的用户账户,密码短语是你的最后一道防线。
- 合规性:许多安全标准(SOC 2、ISO 27001)要求加密私钥。
使用强密码短语创建密钥
生成新密钥时,ssh-keygen 会提示输入密码短语。使用强大、唯一的密码短语:
# Generate key with increased KDF rounds for stronger passphrase protection:
ssh-keygen -t ed25519 -C "your_email@example.com" -a 100
# When prompted, use a strong passphrase:
# Good: correct-horse-battery-staple (4+ random words)
# Good: My$ecure_Key_2024!ForWork (mixed characters)
# Bad: password123 (too simple)
# Bad: qwerty (dictionary word)更改现有密钥的密码短语
你可以更改(或添加)现有密钥的密码短语,无需重新生成:
# Change passphrase on an existing key:
ssh-keygen -p -f ~/.ssh/id_ed25519
# Output:
Enter old passphrase:
Enter new passphrase:
Enter same passphrase again:
Your identification has been saved with the new passphrase.移除密码短语(不推荐)
如果你需要未加密的密钥(例如用于自动化脚本),可以移除密码短语:
# Remove passphrase (enter empty string as new passphrase):
ssh-keygen -p -f ~/.ssh/id_ed25519
Enter old passphrase:
Enter new passphrase: # ← Press Enter (empty)
Enter same passphrase again: # ← Press Enter (empty)警告: 警告:没有密码短语的密钥存在重大安全风险。对于自动化系统,考虑使用 ssh-agent、权限受限的部署密钥或密钥管理器。
增加 KDF 轮数
-a 标志控制对密码短语应用多少轮密钥派生。更高的值使暴力破解更慢:
# Default KDF rounds: 16 (fast, less secure against brute-force)
ssh-keygen -t ed25519 -C "email@example.com"
# Increased KDF rounds: 100 (slower key loading, much harder to brute-force)
ssh-keygen -t ed25519 -C "email@example.com" -a 100
# High KDF rounds: 200 (very slow, maximum brute-force resistance)
ssh-keygen -t ed25519 -C "email@example.com" -a 200
# Note: KDF rounds affect how long it takes to decrypt the key
# with the passphrase, NOT the SSH connection speed.
# -a 100 adds ~1 second to key loading time.SSH 密钥安全最佳实践
文件权限
不正确的权限是最常见的 SSH 问题之一。SSH 会拒绝使用权限过于宽松的密钥或配置文件:
# If permissions are wrong, SSH will show errors like:
# "WARNING: UNPROTECTED PRIVATE KEY FILE!"
# "Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open."
# "It is required that your private key files are NOT accessible by others."设置正确的权限:
# Set correct permissions for the .ssh directory:
chmod 700 ~/.ssh
# Set correct permissions for private keys:
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/config
# Set correct permissions for public keys:
chmod 644 ~/.ssh/id_ed25519.pub
chmod 644 ~/.ssh/id_rsa.pub
# Set correct permissions for authorized_keys (server-side):
chmod 600 ~/.ssh/authorized_keys
# Set correct permissions for known_hosts:
chmod 644 ~/.ssh/known_hosts
# Verify all permissions at once:
ls -la ~/.ssh/
# drwx------ 2 user user 4096 Jan 15 10:30 .
# -rw------- 1 user user 464 Jan 15 10:30 id_ed25519
# -rw-r--r-- 1 user user 105 Jan 15 10:30 id_ed25519.pub
# -rw------- 1 user user 222 Jan 15 10:30 config定期轮换密钥
密钥轮换可以限制密钥泄露时的影响范围。最佳实践:
- 至少每年生成一次新密钥(或按照组织的策略)。
- 在移除旧密钥之前,将新公钥添加到所有服务器。
- 确认新密钥有效后,从 authorized_keys 中移除旧公钥。
- 从 GitHub/GitLab/Bitbucket 撤销旧密钥。
- 记录每个密钥的生成时间和部署位置。
# Key rotation workflow:
# 1. Generate new key
ssh-keygen -t ed25519 -C "email@example.com-2025" -f ~/.ssh/id_ed25519_2025
# 2. Add new public key to server
ssh-copy-id -i ~/.ssh/id_ed25519_2025.pub user@server
# 3. Test new key works
ssh -i ~/.ssh/id_ed25519_2025 user@server
# 4. Remove old public key from server
ssh user@server "sed -i '/old_key_comment/d' ~/.ssh/authorized_keys"
# 5. Update local SSH config to use new key
# Edit ~/.ssh/config and change IdentityFile paths
# 6. Remove old local key files
rm ~/.ssh/id_ed25519_old ~/.ssh/id_ed25519_old.pub在服务器上禁用密码认证
配置好 SSH 密钥认证后,禁用密码认证以防止暴力破解攻击:
编辑 /etc/ssh/sshd_config:
# /etc/ssh/sshd_config
# Disable password authentication
PasswordAuthentication no
# Disable challenge-response authentication
ChallengeResponseAuthentication no
# Disable PAM (optional, depends on your setup)
# UsePAM no
# Enable public key authentication (should be default)
PubkeyAuthentication yes
# Disable root login
PermitRootLogin no
# Allow only specific users
AllowUsers deploy admin重启 SSH 服务:
# Debian / Ubuntu:
sudo systemctl restart sshd
# RHEL / CentOS / Fedora:
sudo systemctl restart sshd
# Older systems:
sudo service ssh restart警告: 警告:在禁用密码认证之前,确保你的 SSH 密钥登录可以正常工作。否则,你可能会把自己锁在服务器外面。
其他安全措施
- 使用非标准 SSH 端口(例如 Port 2222)以减少自动扫描噪音。
- 安装 fail2ban 以阻止登录失败次数过多的 IP 地址。
- 禁用 root 登录:在 sshd_config 中设置 PermitRootLogin no。
- 使用 AllowUsers 或 AllowGroups 限制哪些用户可以通过 SSH 登录。
- 启用双因素认证(2FA)以增加额外的安全层。
- 监控 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(RHEL/CentOS)以发现可疑活动。
常见 SSH 密钥问题排查
Permission Denied (publickey)
这是最常见的 SSH 错误。它表示服务器拒绝了你的密钥。常见原因和修复方法:
# Fix: Specify the correct key explicitly
ssh -i ~/.ssh/id_ed25519 user@server.example.com
# Fix: Copy your public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com
# Or manually:
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Fix: Correct server-side permissions
ssh user@server "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys""Permissions are too open" 错误
如果你看到 "WARNING: UNPROTECTED PRIVATE KEY FILE!" 或 "Permissions 0644 for 'id_ed25519' are too open",说明 SSH 拒绝使用该密钥,因为其他人可以读取它:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.修复权限:
# Fix permissions:
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh在 Windows 上,右键点击文件 > 属性 > 安全 > 高级,移除除你的用户账户之外的所有权限。
调试 SSH 连接
使用 -v、-vv 或 -vvv 标志获取不同级别的调试输出:
# Verbose mode (increasing detail):
ssh -v user@server.example.com # Level 1: basic debug info
ssh -vv user@server.example.com # Level 2: more detail
ssh -vvv user@server.example.com # Level 3: maximum detail
# Example debug output (key parts):
debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Server accepts key: /home/user/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Authentication succeeded (publickey).在调试输出中查找以下关键行:
"Offering public key": "Offering public key":显示 SSH 正在尝试哪些密钥。"Server accepts key": "Server accepts key":确认密钥已被接受。"Authentication succeeded": "Authentication succeeded":登录成功。"No more authentication methods to try": "No more authentication methods to try":所有提供的密钥都被拒绝。
Host Key Verification Failed
如果服务器的主机密钥已更改(例如服务器重建),你会看到警告。移除旧的主机密钥:
# Remove a specific host key:
ssh-keygen -R server.example.com
# Remove by IP address:
ssh-keygen -R 203.0.113.50
# Remove by IP and port:
ssh-keygen -R "[server.example.com]:2222"
# Then reconnect and accept the new host key:
ssh user@server.example.com
# The authenticity of host 'server.example.com' can't be established.
# ED25519 key fingerprint is SHA256:xyz789...
# Are you sure you want to continue connecting (yes/no)? yes警告: 警告:仅在你预期主机密钥已更改时才执行此操作(例如服务器重建)。意外的更改可能表示中间人攻击。
连接超时
- 验证服务器正在运行并在正确的端口上接受连接。
- 检查防火墙(ufw、iptables 或云安全组)。
- 尝试使用特定端口连接:ssh -p 2222 user@server。
- 在 SSH 配置中添加 ServerAliveInterval 以防止空闲断开。
# Test connectivity:
ssh -v -o ConnectTimeout=10 user@server.example.com
# Check if the port is open:
nc -zv server.example.com 22
# or
telnet server.example.com 22
# Add keep-alive to prevent idle timeout (~/.ssh/config):
Host *
ServerAliveInterval 60
ServerAliveCountMax 3常见问题
应该使用 Ed25519 还是 RSA 作为 SSH 密钥?
为所有新的 SSH 密钥使用 Ed25519。Ed25519 提供与 RSA-4096 等效或更好的安全性,密钥大小显著更小(公钥 32 字节 vs ~512 字节),签名和验证更快,并且能抵抗某些实现攻击。只有当你需要与不支持 Ed25519 的非常旧的系统(2014 年之前)兼容时,才使用 RSA-4096。
不使用密码短语的 SSH 密钥安全吗?
没有密码短语的 SSH 密钥存在重大安全风险。如果你的私钥文件被泄露(笔记本被盗、恶意软件、备份暴露),攻击者可以立即访问信任该密钥的所有服务器。始终使用强密码短语,并依赖 ssh-agent 来避免重复输入。对于自动化系统,使用权限最小化的部署密钥或密钥管理器。
如何为不同的 GitHub 账户使用多个 SSH 密钥?
为每个账户创建单独的密钥,并在 ~/.ssh/config 中配置不同的 Host 别名。例如,设置 Host github-personal 使用 HostName github.com 和 IdentityFile ~/.ssh/id_ed25519_personal,设置 Host github-work 使用 IdentityFile ~/.ssh/id_ed25519_work。然后使用别名克隆:git clone git@github-personal:user/repo.git。
SSH 私钥泄露后应该怎么做?
立即从所有服务器(authorized_keys)、GitHub、GitLab 和任何其他服务中移除泄露的公钥。生成新的密钥对并部署新的公钥。审查密钥可能被泄露期间的日志以查找未授权访问。如果该密钥用于生产服务器,考虑进行全面的安全审计。
可以将 RSA 密钥转换为 Ed25519 吗?
不可以,你无法在密钥算法之间进行转换。你必须使用 ssh-keygen -t ed25519 生成新的 Ed25519 密钥对,然后将新的公钥添加到你的服务器和服务(GitHub、GitLab 等)。你可以在过渡期间保留旧的 RSA 密钥作为备份,然后在新的 Ed25519 密钥部署到所有地方后将其移除。