SSH 金鑰認證機制

SSH 金鑰認證機制使用非對稱加密技術,提供更安全且便捷的遠端伺服器登入方式


目錄


什麼是 SSH 金鑰認證?

SSH 金鑰認證是一種基於非對稱加密(公鑰加密)的身份驗證機制,用於安全地連線遠端伺服器。

核心優勢

相比傳統密碼認證:

  • 🔒 更安全:4096 位元 RSA 金鑰強度遠超普通密碼
  • 更便捷:無需每次輸入密碼,自動完成認證
  • 🎯 可撤銷:刪除伺服器上的公鑰即可撤銷存取權限
  • 📦 一對多:一個金鑰對可用於多台伺服器

為什麼需要 SSH 金鑰認證?

密碼認證的問題

  • 容易遭受暴力破解攻擊
  • 密碼強度難以保證
  • 多台伺服器需記住多組密碼
  • 無法精確控制存取權限

金鑰認證的解決方案

  • 數學上幾乎無法破解
  • 不需記憶複雜密碼
  • 統一使用同一金鑰對
  • 隨時可撤銷特定金鑰

核心概念

非對稱加密

SSH 金鑰認證使用非對稱加密技術,系統會生成一對金鑰:

金鑰類型 檔案名稱 保存位置 安全要求
私鑰 id_rsa 本地電腦 🔴 絕不能洩露
公鑰 id_rsa.pub 遠端伺服器 🟢 可以公開

金鑰對關係

公鑰加密的內容 → 只有對應的私鑰能解密
私鑰簽名的內容 → 可用公鑰驗證真實性

重要原則

  • 私鑰:相當於密碼,任何人拿到都能冒充你
  • 公鑰:只能用來驗證身份,無法用來登入

運作原理

SSH 金鑰認證流程

本地電腦                          遠端伺服器
---------                         -----------
1. 請求連線 ------------------>
   "我想登入"

2.              <--------------- 發送隨機挑戰資料
                                 "證明你有私鑰"

3. 用私鑰簽名
   (證明你擁有私鑰)
   簽名結果    ------------------>

4.                               用公鑰驗證簽名
                                 ✓ 驗證成功 → 允許登入
                                 ✗ 驗證失敗 → 拒絕連線

5.              <--------------- 建立加密連線
   開始安全通訊

詳細步驟說明

  1. 請求連線:客戶端向伺服器發起 SSH 連線請求
  2. 挑戰驗證:伺服器生成隨機資料要求客戶端簽名
  3. 私鑰簽名:客戶端使用本地私鑰對隨機資料進行簽名
  4. 公鑰驗證:伺服器使用存儲的公鑰驗證簽名是否正確
  5. 建立連線:驗證通過後建立加密的 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     # 存放允許登入的公鑰清單

說明

  • 伺服器在此檔案中查找客戶端的公鑰
  • 一行一個公鑰,可存放多個
  • 權限必須是 600644

實戰範例

範例 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 連接埠 222222
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).

可能原因

  1. 公鑰沒有正確複製到伺服器
  2. authorized_keys 檔案權限不正確
  3. 使用了錯誤的金鑰

解決方案

# 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 - 公鑰清單(伺服器)

一個原則

  • 私鑰絕不洩露,公鑰可以公開

兩個步驟

  1. 生成金鑰對
  2. 複製公鑰到伺服器

建立日期:2025-10-28 最後更新:2025-11-18

🔗相關文章