目錄
什麼是 SSH 金鑰認證?
SSH 金鑰認證是一種基於非對稱加密(公鑰加密)的身份驗證機制,用於安全地連線遠端伺服器。
核心優勢
相比傳統密碼認證:
- 🔒 更安全:4096 位元 RSA 金鑰強度遠超普通密碼
- ⚡ 更便捷:無需每次輸入密碼,自動完成認證
- 🎯 可撤銷:刪除伺服器上的公鑰即可撤銷存取權限
- 📦 一對多:一個金鑰對可用於多台伺服器
為什麼需要 SSH 金鑰認證?
密碼認證的問題:
- 容易遭受暴力破解攻擊
- 密碼強度難以保證
- 多台伺服器需記住多組密碼
- 無法精確控制存取權限
金鑰認證的解決方案:
- 數學上幾乎無法破解
- 不需記憶複雜密碼
- 統一使用同一金鑰對
- 隨時可撤銷特定金鑰
核心概念
非對稱加密
SSH 金鑰認證使用非對稱加密技術,系統會生成一對金鑰:
| 金鑰類型 | 檔案名稱 | 保存位置 | 安全要求 |
|---|---|---|---|
| 私鑰 | id_rsa |
本地電腦 | 🔴 絕不能洩露 |
| 公鑰 | id_rsa.pub |
遠端伺服器 | 🟢 可以公開 |
金鑰對關係
公鑰加密的內容 → 只有對應的私鑰能解密
私鑰簽名的內容 → 可用公鑰驗證真實性
重要原則:
- 私鑰:相當於密碼,任何人拿到都能冒充你
- 公鑰:只能用來驗證身份,無法用來登入
運作原理
SSH 金鑰認證流程
本地電腦 遠端伺服器
--------- -----------
1. 請求連線 ------------------>
"我想登入"
2. <--------------- 發送隨機挑戰資料
"證明你有私鑰"
3. 用私鑰簽名
(證明你擁有私鑰)
簽名結果 ------------------>
4. 用公鑰驗證簽名
✓ 驗證成功 → 允許登入
✗ 驗證失敗 → 拒絕連線
5. <--------------- 建立加密連線
開始安全通訊
詳細步驟說明
- 請求連線:客戶端向伺服器發起 SSH 連線請求
- 挑戰驗證:伺服器生成隨機資料要求客戶端簽名
- 私鑰簽名:客戶端使用本地私鑰對隨機資料進行簽名
- 公鑰驗證:伺服器使用存儲的公鑰驗證簽名是否正確
- 建立連線:驗證通過後建立加密的 SSH 連線
金鑰配置位置
本地電腦(客戶端)
~/.ssh/
├── id_rsa # 私鑰 (權限必須是 600)
├── id_rsa.pub # 公鑰
├── config # SSH 設定檔
├── known_hosts # 已知伺服器指紋
└── authorized_keys # (如果本機也是伺服器)
檔案說明:
id_rsa:私鑰檔案,需嚴格保密id_rsa.pub:公鑰檔案,可複製到遠端伺服器config:SSH 客戶端配置,設定連線參數known_hosts:記錄已連線過的伺服器指紋,防止中間人攻擊
遠端伺服器
~/.ssh/
└── authorized_keys # 存放允許登入的公鑰清單
說明:
- 伺服器在此檔案中查找客戶端的公鑰
- 一行一個公鑰,可存放多個
- 權限必須是
600或644
實戰範例
範例 1:首次設定 SSH 金鑰
目標:從零開始設定 SSH 金鑰認證
步驟 1:生成金鑰對
# 生成 4096 位元的 RSA 金鑰對
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 互動提示:
# Enter file in which to save the key: (直接按 Enter 使用預設)
# Enter passphrase: (可選,建議設定額外保護)
輸出結果:
Generating public/private rsa key pair.
Your identification has been saved in /Users/username/.ssh/id_rsa
Your public key has been saved in /Users/username/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:... your_email@example.com
步驟 2:將公鑰複製到遠端伺服器
# 方法一:使用 ssh-copy-id(推薦)
ssh-copy-id user@remote-server
# 方法二:手動複製
cat ~/.ssh/id_rsa.pub | ssh user@remote-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 方法三:直接貼上(如果已經登入伺服器)
# 在本地執行:
cat ~/.ssh/id_rsa.pub
# 複製輸出內容,在伺服器執行:
echo "貼上的公鑰內容" >> ~/.ssh/authorized_keys
步驟 3:驗證設定
# 使用金鑰登入(不需輸入密碼)
ssh user@remote-server
# 如果成功登入且沒有要求密碼,表示設定完成 ✅
範例 2:多台伺服器配置
情境:需要連線多台不同的伺服器
解決方案:
# 將同一個公鑰複製到多台伺服器
ssh-copy-id user@server1.example.com
ssh-copy-id user@server2.example.com
ssh-copy-id user@server3.example.com
# 之後連線任何一台都不需要密碼
ssh user@server1.example.com
ssh user@server2.example.com
ssh user@server3.example.com
範例 3:不同用途使用不同金鑰
情境:工作和個人專案使用不同金鑰
步驟 1:生成多個金鑰對
# 工作用金鑰
ssh-keygen -t rsa -b 4096 -C "work@company.com" -f ~/.ssh/id_rsa_work
# 個人用金鑰
ssh-keygen -t rsa -b 4096 -C "personal@email.com" -f ~/.ssh/id_rsa_personal
步驟 2:配置 SSH Config
# 編輯 ~/.ssh/config
nano ~/.ssh/config
配置內容:
# 工作伺服器
Host work-server
HostName work.company.com
User workuser
IdentityFile ~/.ssh/id_rsa_work
Port 22
# 個人伺服器
Host personal-server
HostName personal.example.com
User personaluser
IdentityFile ~/.ssh/id_rsa_personal
Port 22
# GitHub 工作帳號
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_work
# GitHub 個人帳號
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_personal
步驟 3:使用別名連線
# 使用配置好的別名
ssh work-server # 自動使用工作金鑰
ssh personal-server # 自動使用個人金鑰
# Git 操作
git clone git@github-work:company/repo.git # 使用工作金鑰
git clone git@github-personal:user/repo.git # 使用個人金鑰
範例 4:臨時使用特定金鑰
情境:一次性使用非預設的金鑰
# 使用 -i 參數指定金鑰
ssh -i ~/.ssh/id_rsa_custom user@server
# 複製檔案時指定金鑰
scp -i ~/.ssh/id_rsa_custom file.txt user@server:/path/
進階設定
SSH Config 完整範例
# ~/.ssh/config
# 預設設定(套用到所有主機)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
# 生產環境伺服器
Host prod-server
HostName 192.168.1.100
User admin
IdentityFile ~/.ssh/id_rsa_prod
Port 2222
ForwardAgent yes
# 開發環境伺服器
Host dev-server
HostName dev.company.com
User developer
IdentityFile ~/.ssh/id_rsa_work
Port 22
# 使用跳板機
Host internal-server
HostName 10.0.0.50
User admin
ProxyJump bastion-server
Host bastion-server
HostName bastion.company.com
User bastion-user
IdentityFile ~/.ssh/id_rsa_bastion
常用 SSH Config 選項
| 選項 | 說明 | 範例值 |
|---|---|---|
HostName |
實際主機位址 | 192.168.1.100 |
User |
登入使用者名稱 | admin |
IdentityFile |
私鑰檔案路徑 | ~/.ssh/id_rsa_custom |
Port |
SSH 連接埠 | 22 或 2222 |
ForwardAgent |
轉發認證代理 | yes / no |
ProxyJump |
跳板機 | bastion-server |
ServerAliveInterval |
保持連線間隔(秒) | 60 |
最佳實踐
1. 金鑰安全
# ✅ 正確:私鑰權限設為 600
chmod 600 ~/.ssh/id_rsa
# ✅ 正確:公鑰權限設為 644
chmod 644 ~/.ssh/id_rsa.pub
# ✅ 正確:.ssh 目錄權限設為 700
chmod 700 ~/.ssh
# ❌ 錯誤:權限過於寬鬆
chmod 777 ~/.ssh/id_rsa # 危險!SSH 會拒絕使用
2. 使用 Passphrase
# ✅ 生成金鑰時設定 passphrase
ssh-keygen -t rsa -b 4096 -C "email@example.com"
# 提示輸入 passphrase 時,設定一個強密碼
# 優點:
# - 即使私鑰被盜,沒有 passphrase 也無法使用
# - 雙重保護更安全
3. 定期輪換金鑰
# 建議每 1-2 年更換金鑰對
# 步驟:
# 1. 生成新金鑰對
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_new
# 2. 將新公鑰部署到所有伺服器
ssh-copy-id -i ~/.ssh/id_rsa_new.pub user@server
# 3. 驗證新金鑰可正常使用
ssh -i ~/.ssh/id_rsa_new user@server
# 4. 備份舊金鑰
mv ~/.ssh/id_rsa ~/.ssh/id_rsa.old
# 5. 啟用新金鑰
mv ~/.ssh/id_rsa_new ~/.ssh/id_rsa
4. 金鑰管理
# ✅ 不同用途使用不同金鑰
~/.ssh/id_rsa_work # 工作用
~/.ssh/id_rsa_personal # 個人用
~/.ssh/id_rsa_github # GitHub 專用
# ✅ 使用描述性的檔案名稱
~/.ssh/id_rsa_aws_prod # AWS 生產環境
~/.ssh/id_rsa_gcp_dev # GCP 開發環境
# ❌ 不要將所有用途混用同一把金鑰
5. 備份策略
# ✅ 安全備份私鑰
# 方法 1:加密備份
tar czf - ~/.ssh/id_rsa* | gpg -c > ssh-keys-backup.tar.gz.gpg
# 方法 2:存到加密的 USB
cp -r ~/.ssh /Volumes/EncryptedUSB/backup/
# ❌ 絕不要做的事
# - 上傳私鑰到 GitHub
# - 存到未加密的雲端硬碟
# - 透過 Email 傳送私鑰
# - 存到共享資料夾
6. 伺服器端設定
# 伺服器 /etc/ssh/sshd_config 建議設定
# 禁用密碼登入(強制使用金鑰)
PasswordAuthentication no
# 禁用 root 直接登入
PermitRootLogin no
# 只允許特定使用者
AllowUsers user1 user2
# 設定金鑰類型
PubkeyAuthentication yes
常見問題
問題 1:Permission denied (publickey)
症狀:
ssh user@server
# Permission denied (publickey).
可能原因:
- 公鑰沒有正確複製到伺服器
- authorized_keys 檔案權限不正確
- 使用了錯誤的金鑰
解決方案:
# 1. 確認公鑰已複製到伺服器
ssh user@server "cat ~/.ssh/authorized_keys"
# 應該要看到你的公鑰內容
# 2. 檢查本地私鑰權限
ls -la ~/.ssh/id_rsa
# 應該是 -rw------- (600)
# 3. 檢查伺服器端權限
ssh user@server "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
# 4. 使用詳細模式除錯
ssh -v user@server
問題 2:要求輸入 passphrase 太頻繁
問題:每次 SSH 連線都要輸入 passphrase
解決方案:使用 ssh-agent
# 啟動 ssh-agent
eval "$(ssh-agent -s)"
# 將私鑰加入 agent
ssh-add ~/.ssh/id_rsa
# 輸入一次 passphrase 後,本次終端機會話中就不用再輸入
# macOS:永久記住 passphrase
ssh-add --apple-use-keychain ~/.ssh/id_rsa
# Linux:開機自動啟動 ssh-agent
# 在 ~/.bashrc 或 ~/.zshrc 加入:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
fi
問題 3:如何撤銷某個金鑰的存取權限?
情境:某台電腦遺失或金鑰可能洩露
解決方案:
# 1. 登入伺服器
ssh user@server
# 2. 編輯 authorized_keys
nano ~/.ssh/authorized_keys
# 3. 刪除對應的公鑰那一行
# 或註解掉(在行首加 #)
# 4. 儲存並退出
# 該金鑰立即失效,無法再登入
問題 4:連線到新伺服器時出現警告
症狀:
The authenticity of host 'server (192.168.1.100)' can't be established.
RSA key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no)?
說明:
- 這是正常的安全機制
- 首次連線時 SSH 會記錄伺服器的指紋
處理方式:
# 方式 1:驗證指紋後輸入 yes
# (應該向伺服器管理員確認指紋是否正確)
yes
# 方式 2:如果是測試環境,可以跳過檢查(不建議)
ssh -o StrictHostKeyChecking=no user@server
# 方式 3:清除舊的主機指紋(伺服器重新安裝時)
ssh-keygen -R server_hostname
問題 5:多個 GitHub 帳號如何管理?
情境:工作和個人的 GitHub 帳號
解決方案:參考「範例 3」的配置方式
# ~/.ssh/config
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_work
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_personal
# 使用時
git clone git@github-work:company/repo.git
git clone git@github-personal:username/repo.git
總結
核心要點
SSH 金鑰認證 = 非對稱加密 + 私鑰簽名 + 公鑰驗證
金鑰對:
├─ 私鑰 (id_rsa) → 本地保管,絕不洩露
└─ 公鑰 (id_rsa.pub) → 複製到伺服器
流程:
1. 生成金鑰對
2. 複製公鑰到伺服器
3. 使用私鑰自動登入
快速參考
基本操作:
# 生成金鑰
ssh-keygen -t rsa -b 4096 -C "email@example.com"
# 複製公鑰到伺服器
ssh-copy-id user@server
# 登入(使用金鑰)
ssh user@server
# 指定特定金鑰
ssh -i ~/.ssh/custom_key user@server
檔案權限:
| 檔案/目錄 | 權限 | 指令 |
|---|---|---|
~/.ssh/ |
700 | chmod 700 ~/.ssh |
id_rsa (私鑰) |
600 | chmod 600 ~/.ssh/id_rsa |
id_rsa.pub (公鑰) |
644 | chmod 644 ~/.ssh/id_rsa.pub |
authorized_keys |
600 | chmod 600 ~/.ssh/authorized_keys |
記憶要點
三個核心檔案:
~/.ssh/id_rsa- 私鑰(本地)~/.ssh/id_rsa.pub- 公鑰(本地)~/.ssh/authorized_keys- 公鑰清單(伺服器)
一個原則:
- 私鑰絕不洩露,公鑰可以公開
兩個步驟:
- 生成金鑰對
- 複製公鑰到伺服器
建立日期:2025-10-28 最後更新:2025-11-18