DevToolBox免费
博客

SSH Keygen:Ed25519 vs RSA 完全指南

9 分钟阅读作者 DevToolBox

SSH 密钥是安全服务器认证的黄金标准,用加密密钥对替代密码。无论你是在设置新的开发机器、配置 CI/CD 流水线,还是加固生产服务器,理解如何生成和管理 SSH 密钥都是一项基本技能。本综合指南涵盖了从密钥算法选择(Ed25519 vs RSA vs ECDSA)到高级 SSH 配置、代理管理和常见问题排查的所有内容。

什么是 SSH 密钥?

SSH(安全外壳协议)密钥是用于身份认证的加密密钥对。不必每次连接远程服务器时都输入密码,SSH 密钥让你使用公钥加密来证明身份。这比基于密码的认证更安全、更方便。

SSH 密钥对由两个文件组成:

  • 私钥: 私钥:保存在本地机器上。绝对不要与任何人共享此文件。它类似于打开门锁的物理钥匙。
  • 公钥: 公钥:放置在每一台你想访问的服务器上。它类似于锁 — 任何人都可以看到它,但只有匹配的私钥才能打开它。

SSH 密钥认证的工作流程

1. 你尝试连接服务器:ssh user@server.example.com
2. 服务器发送一个用你的公钥加密的随机挑战。
3. 你的 SSH 客户端使用私钥解密挑战并发送响应。
4. 服务器验证响应。如果正确,你就通过了认证,全程无需发送密码。
# 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。每种都有不同的安全属性、性能特征和兼容性考量。

特性Ed25519RSAECDSA
引入时间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_ed25519Ed25519 私钥600 (-rw-------)
id_ed25519.pubEd25519 公钥644 (-rw-r--r--)
id_rsaRSA 私钥600 (-rw-------)
id_rsa.pubRSA 公钥644 (-rw-r--r--)
configSSH 客户端配置文件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 production

ProxyJump:通过堡垒机连接

如果你需要通过跳板机(堡垒机)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

1. 前往 GitHub.com > Settings > SSH and GPG keys > New SSH key。
2. 给密钥一个描述性标题(例如 "工作笔记本 2024")。
3. 将你的公钥粘贴到 "Key" 字段中。
4. 点击 "Add SSH key"。

步骤 3:将密钥添加到 GitLab

1. 前往 GitLab.com > Preferences > SSH Keys。
2. 粘贴你的公钥,设置标题和可选的过期日期。
3. 点击 "Add key"。

步骤 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 -L

macOS 钥匙串集成

在 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 错误。它表示服务器拒绝了你的密钥。常见原因和修复方法:

提供了错误的密钥:使用 ssh -i ~/.ssh/id_ed25519 user@server 指定正确的密钥。
公钥不在 authorized_keys 中:将你的公钥添加到服务器上的 ~/.ssh/authorized_keys。
服务器上的权限错误:服务器端的 ~/.ssh/ 目录和 authorized_keys 必须具有正确的权限。
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 密钥部署到所有地方后将其移除。

相关工具

哈希生成器 - 生成 SHA-256、MD5 和其他哈希值,用于验证文件完整性和密钥指纹。密码生成器 - 为你的 SSH 密钥创建强大的随机密码短语。
𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

#Hash Generator🔑Password Generator📜PEM / Certificate Decoder

相关文章

bcrypt vs Argon2 vs scrypt:2026 密码哈希对比

对比 bcrypt、Argon2id 和 scrypt 密码哈希。基准测试、安全分析、5 种语言代码示例和 OWASP 推荐。

2025 年密码强度要求:NIST 指南与最佳实践

基于 NIST SP 800-63B 的现代密码强度要求。最小长度、复杂度规则、黑名单、MFA 以及与旧做法的变化。