SSH 金鑰完全指南:生成、設定、多帳號管理與安全加固

開發工具

SSH 金鑰:比密碼更安全的認證方式

對比 密碼 SSH 金鑰
認證方式 知識因子(你知道的) 持有因子(你擁有的)
暴力破解 可能 幾乎不可能
釣魚風險 高 低(私鑰不離開本機)
伺服器洩露 密碼明文/雜湊可撞庫 僅存公鑰,無法反推私鑰
便捷性 每次輸入 一次設定,自動認證

一、生成金鑰對

Ed25519(推薦)

ssh-keygen -t ed25519 -C "your@email.com"
參數 說明
-t ed25519 演算法類型(Ed25519,最安全最快)
-C 註解(通常用信箱識別)

RSA(相容性備選)

ssh-keygen -t rsa -b 4096 -C "your@email.com"
演算法 金鑰長度 安全性 效能 推薦
Ed25519 256 bit 最高 最快 ✅
ECDSA P256 256 bit 高 快 可選
RSA 4096 4096 bit 高 慢 相容性備選
RSA 2048 2048 bit 中 慢 ❌ 不推薦

生成過程

$ ssh-keygen -t ed25519 -C "dev@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase): ****
Enter same passphrase again: ****
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

強烈建議設定 passphrase:即使私鑰洩露,有 passphrase 也能防止直接被使用。


二、部署公鑰

GitHub / GitLab

# 複製公鑰
cat ~/.ssh/id_ed25519.pub | clip

# GitHub → Settings → SSH and GPG keys → New SSH key
# 貼上公鑰內容

伺服器

# 方法一:ssh-copy-id
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.com

# 方法二:手動追加
cat ~/.ssh/id_ed25519.pub | ssh user@server.com 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

驗證連線

ssh -T git@github.com
# Hi username! You've successfully authenticated...

ssh user@server.com
# 直接登入,無需密碼

三、多帳號設定

場景:工作 GitHub + 個人 GitHub

# 生成兩對金鑰
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_work
ssh-keygen -t ed25519 -C "personal@gmail.com" -f ~/.ssh/id_personal

SSH Config

# ~/.ssh/config
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_work
  IdentitiesOnly yes

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_personal
  IdentitiesOnly yes

Git 使用

# 工作儲存庫
git clone git@github-work:company/project.git

# 個人儲存庫
git clone git@github-personal:username/project.git

多平台設定

# ~/.ssh/config
Host github.com
  User git
  IdentityFile ~/.ssh/id_github

Host gitlab.com
  User git
  IdentityFile ~/.ssh/id_gitlab

Host gitee.com
  User git
  IdentityFile ~/.ssh/id_gitee

Host dev.azure.com
  User git
  IdentityFile ~/.ssh/id_azure

四、SSH Agent 管理

啟動 Agent

eval "$(ssh-agent -s)"

新增金鑰

ssh-add ~/.ssh/id_ed25519
# Enter passphrase: ****

# 查看已新增的金鑰
ssh-add -l
# 256 SHA256:xxx... dev@example.com (ED25519)

自動啟動(bashrc)

# ~/.bashrc 或 ~/.zshrc
if [ -z "$SSH_AUTH_SOCK" ]; then
  eval "$(ssh-agent -s)"
  ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

keychain 持久化

# macOS 使用 Keychain 儲存 passphrase
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# Linux 使用 keychain
eval "$(keychain --eval id_ed25519)"

五、跳板機設定

場景:本機 → 跳板機 → 生產伺服器

# ~/.ssh/config
Host jumpbox
  HostName jump.example.com
  User jump-user
  IdentityFile ~/.ssh/id_jump

Host production
  HostName 10.0.1.100
  User deploy
  IdentityFile ~/.ssh/id_prod
  ProxyJump jumpbox
# 直接連線生產伺服器(自動經過跳板機)
ssh production

Agent 轉發

Host jumpbox
  HostName jump.example.com
  ForwardAgent yes

安全提示:僅在信任跳板機時啟用 Agent 轉發。


六、安全加固

伺服器端 sshd_config

# /etc/ssh/sshd_config
PermitRootLogin no                    # 禁止 root 登入
PasswordAuthentication no             # 禁止密碼登入
PubkeyAuthentication yes             # 僅允許金鑰登入
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3                       # 最大嘗試次數
LoginGraceTime 30                    # 登入逾時 30 秒
AllowUsers deploy admin              # 白名單使用者

金鑰權限

# 私鑰必須 600
chmod 600 ~/.ssh/id_ed25519

# .ssh 目錄必須 700
chmod 700 ~/.ssh

# authorized_keys 必須 600
chmod 600 ~/.ssh/authorized_keys

金鑰輪換

# 1. 生成新金鑰
ssh-keygen -t ed25519 -C "dev@example.com" -f ~/.ssh/id_ed25519_new

# 2. 部署新公鑰到所有伺服器/Git 平台
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server

# 3. 驗證新金鑰可用
ssh -i ~/.ssh/id_ed25519_new user@server

# 4. 移除舊公鑰
# 編輯伺服器 ~/.ssh/authorized_keys,刪除舊公鑰行

# 5. 刪除舊金鑰
rm ~/.ssh/id_ed25519_old

七、常見問題排查

問題 原因 解決
Permission denied 公鑰未部署 ssh-copy-id
Too many authentication failures Agent 中金鑰過多 IdentitiesOnly yes
Are you sure you want to continue connecting 首次連線 StrictHostKeyChecking=accept-new
連線慢 DNS 反查 UseDNS no(伺服器端)
金鑰不生效 權限錯誤 chmod 600 私鑰

除錯模式

ssh -vvv user@server.com
# 詳細輸出連線過程,定位認證失敗原因
#SSH#密钥#Git#免密登录#安全