跳轉到內容

SSH 密鑰登錄配置完全指南 | VPS 安全防護教程

SSH Key Authentication Security

購買 VPS 後,大部分服務商默認提供的是賬號密碼登錄。然而,隨著公網上惡意的掃描程序和自動化工具越來越多,僅僅使用密碼登錄有著極高被暴力破解(爆破)的風險。

最安全的做法是:改用 SSH 密鑰登錄,並關閉密碼登錄。這樣即便是世界上最頂級的黑客,在沒有你的私鑰的情況下也無法登入你的服務器。

什麼是 SSH 密鑰?

SSH 密鑰由兩部分組成:

  • 私鑰 (Private Key):存放在你自己的電腦上,絕對不能洩露給任何人。
  • 公鑰 (Public Key):上傳並保存在你的 VPS 服務器上。

登錄時,服務器通過公鑰來驗證你電腦上的私鑰,驗證匹配後即允許登錄,全程無需輸入密碼。

SSH 密鑰 vs 密碼登錄對比

特性密碼登錄SSH 密鑰登錄
安全性⭐⭐(易被爆破)⭐⭐⭐⭐⭐(幾乎無法破解)
便利性每次輸入密碼一鍵登錄(可配置免密)
抗暴力破解❌ 弱✅ 極強
多設備管理同一密碼風險高每設備獨立密鑰
自動化支持需存儲明文密碼腳本友好
推薦程度不推薦強烈推薦

步驟一:在本地電腦生成密鑰對

無論你使用的是 Windows、macOS 還是 Linux 電腦,目前的系統均內置了生成 SSH 密鑰的工具。

生成 Ed25519 密鑰(推薦)

打開你本地電腦的終端(Windows 可以使用 PowerShell 或 CMD,macOS 使用 Terminal),輸入以下命令並回車:

bash
ssh-keygen -t ed25519 -C "your_email@example.com"

注:-t ed25519 是一種更新、更安全、更高效的加密算法。如果較老的系統不支持,可使用 ssh-keygen -t rsa -b 4096。後面的郵箱只作為標識備註。

生成 RSA 密鑰(兼容舊系統)

bash
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

參數說明:

  • -t: 指定密鑰類型(ed25519 或 rsa)
  • -b: 密鑰位數(RSA 建議 4096)
  • -C: 註釋(通常是郵箱,便於識別)

交互式配置

輸入命令後,系統會連續向你詢問三個問題,通常直接一直按回車鍵即可:

  1. 保存路徑確認:默認保存在 ~/.ssh/id_ed25519(Windows 一般在 C:\Users\用戶名\.ssh\id_ed25519)。
  2. 設置密鑰保護密碼(passphrase):如果設置了,每次使用私鑰還需要輸入這個密碼。為圖方便可以直接留空回車。
  3. 再次確認密碼:留空回車。

Passphrase 建議:

  • 個人電腦:可以留空,方便免密登錄
  • 共享電腦:務必設置強密碼
  • 生產環境:建議配合 ssh-agent 使用

完成後,你的本地電腦上會生成兩個文件:

  • id_ed25519(這就是私鑰)- 保密!
  • id_ed25519.pub(這就是公鑰)- 可以公開

查看生成的密鑰:

bash
# 列出 .ssh 目錄內容
ls -la ~/.ssh/

# 查看公鑰內容
cat ~/.ssh/id_ed25519.pub

# 輸出示例:
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com

步驟二:將公鑰上傳到 VPS

目前你的公鑰還在本地,接下來我們要把它放到 VPS 服務器的指定位置。我們將它放在 root 賬戶下(如果你使用的是其它用戶如 ubuntu,請自行替換路徑):

方法 1:使用快捷命令 ssh-copy-id (推薦 macOS / Linux / 較新 Windows)

在本地電腦終端中輸入:

bash
ssh-copy-id root@你的VPS_IP地址

然後系統會提示你輸入 VPS 的 root 密碼,輸入完畢回車,公鑰就會被自動導入。

批量添加多個服務器:

bash
# 創建服務器列表文件
cat > servers.txt <<EOF
root@192.168.1.100
root@192.168.1.101
ubuntu@203.0.113.50
EOF

# 批量上傳公鑰
while read server; do
  ssh-copy-id "$server"
done < servers.txt

方法 2:手動複製公鑰

如果你覺得命令不好用,也可以通過手動方式:

  1. 用記事本(或用 cat 命令)打開本地的 id_ed25519.pub 文件,複製裡面那一長串以 ssh-ed25519 開頭的文本。
  2. 使用密碼正常登錄你的 VPS。
  3. 在 VPS 終端上執行以下命令:
    bash
    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    nano ~/.ssh/authorized_keys
  4. 將剛剛複製的公鑰文本粘貼進去。
  5. Ctrl + X,再按 Y,然後按回車保存退出。
  6. 最後設置權限:
    bash
    chmod 600 ~/.ssh/authorized_keys

方法 3:使用 scp 命令上傳

bash
# 從本地複製公鑰到服務器
scp ~/.ssh/id_ed25519.pub root@你的VPS_IP:/tmp/

# SSH 登錄服務器
ssh root@你的VPS_IP

# 在服務器上執行
mkdir -p ~/.ssh
cat /tmp/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
rm /tmp/id_ed25519.pub

權限要求總結

文件/目錄權限說明
~/.ssh700僅所有者可讀寫執行
~/.ssh/authorized_keys600僅所有者可讀寫
私鑰文件600絕對保密
公鑰文件644可以公開

步驟三:測試密鑰登錄是否成功

在沒關閉密碼登錄之前,務必先測試一次密鑰登錄是否生效! 如果生效了,再去關閉密碼,否則你可能會把你自己鎖在服務器外面!

基本測試

在本地電腦終端重新登錄服務器:

bash
ssh root@你的VPS_IP地址

如果你發現這一次沒有讓你輸入密碼就直接登錄進去了,恭喜你,密鑰配置成功!

指定私鑰文件測試

如果你有多個密鑰,可以指定使用哪個:

bash
ssh -i ~/.ssh/id_ed25519 root@你的VPS_IP地址

詳細調試模式

如果登錄失敗,使用 -v 參數查看詳細日誌:

bash
ssh -v root@你的VPS_IP地址

# 更詳細的日誌
ssh -vv root@你的VPS_IP地址

# 最詳細的日誌
ssh -vvv root@你的VPS_IP地址

常見錯誤及解決:

  • Permission denied (publickey):公鑰未正確安裝或權限錯誤
  • Connection refused:SSH 服務未啟動或端口錯誤
  • Connection timed out:防火牆阻止或 IP 錯誤

步驟四:關閉 SSH 密碼登錄(關鍵一步)

密鑰登錄成功後,我們需要徹底關掉傳統的賬號密碼登錄入口。

編輯 SSH 配置文件

  1. 在 VPS 終端中,編輯 SSH 配置文件:

    bash
    nano /etc/ssh/sshd_config
  2. 在文件中尋找以下這兩行配置項,把它們改成 no(如果前面有 # 號註釋,記得把 # 刪掉):

    text
    PasswordAuthentication no
    PermitEmptyPasswords no

    提示:在 nano 編輯器中可以按 Ctrl + W 搜索 "PasswordAuthentication"。

  3. 修改完成後,按 Ctrl + X,再按 Y,回車保存退出。

其他安全加固選項

在同一配置文件中,還可以優化以下設置:

text
# 禁用 root 直接登錄(推薦先創建普通用戶)
PermitRootLogin prohibit-password

# 修改 SSH 端口(避免使用默認 22)
Port 2222

# 限制登錄用戶
AllowUsers your_username

# 禁用 X11 轉發(不需要圖形界面時)
X11Forwarding no

# 設置登錄超時時間(秒)
ClientAliveInterval 300
ClientAliveCountMax 2

# 禁用 DNS 查詢(加快登錄速度)
UseDNS no

重啟 SSH 服務

  1. 重啟 SSH 動作使配置生效:
    bash
    systemctl restart sshd
    注意:Debian/Ubuntu 系統有時服務名叫 ssh,可以嘗試 systemctl restart ssh

重要提醒: 重啟前確保:

  • ✅ 已在另一個終端窗口測試密鑰登錄成功
  • ✅ 保留了 VNC 控制檯訪問權限(應急用)
  • ✅ 記錄了新的 SSH 端口(如果修改了)

SSH Agent - 密鑰管理神器

什麼是 SSH Agent?

SSH Agent 是一個密鑰管理程序,可以在內存中緩存你的私鑰,避免每次連接都輸入 passphrase。

啟動 SSH Agent

bash
# 啟動 agent
eval "$(ssh-agent -s)"

# 添加私鑰到 agent
ssh-add ~/.ssh/id_ed25519

# 列出已加載的密鑰
ssh-add -l

# 刪除所有密鑰
ssh-add -D

自動啟動配置

添加到 ~/.bashrc~/.zshrc

bash
# 自動啟動 ssh-agent
if [ -z "$SSH_AUTH_SOCK" ]; then
  eval "$(ssh-agent -s)"
  ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

macOS 集成鑰匙串

bash
# macOS 可以將密鑰存儲在鑰匙串中
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# 編輯 ~/.ssh/config
Host *
  UseKeychain yes
  AddKeysToAgent yes

SSH 配置文件進階

創建 SSH 客戶端配置

編輯本地 ~/.ssh/config 文件:

bash
nano ~/.ssh/config

基礎配置示例:

text
# 全局默認設置
Host *
    IdentityFile ~/.ssh/id_ed25519
    User root
    Port 22
    ServerAliveInterval 60
    ServerAliveCountMax 3
    ConnectTimeout 10

# 特定服務器配置
Host my-vps
    HostName 192.168.1.100
    User root
    Port 2222
    IdentityFile ~/.ssh/my_vps_key

Host work-server
    HostName 203.0.113.50
    User admin
    Port 22
    IdentityFile ~/.ssh/work_key

# 跳板機配置(堡壘機)
Host *.internal
    ProxyJump bastion.example.com
    User deploy

使用簡化命令:

bash
# 原本需要輸入
ssh -p 2222 -i ~/.ssh/my_vps_key root@192.168.1.100

# 現在只需輸入
ssh my-vps

常用配置參數

參數說明示例
HostName實際主機名或 IP192.168.1.100
User登錄用戶名root, ubuntu
PortSSH 端口22, 2222
IdentityFile私鑰路徑~/.ssh/id_ed25519
ProxyJump跳板機bastion.example.com
LocalForward端口轉發3306 localhost:3306
ServerAliveInterval保活間隔(秒)60

多密鑰管理

場景:不同服務器使用不同密鑰

生成多個密鑰:

bash
# 工作服務器密鑰
ssh-keygen -t ed25519 -f ~/.ssh/work_key -C "work@example.com"

# 個人服務器密鑰
ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "personal@example.com"

# GitHub 密鑰
ssh-keygen -t ed25519 -f ~/.ssh/github_key -C "github@example.com"

配置 ~/.ssh/config

text
# 工作服務器
Host work-*
    IdentityFile ~/.ssh/work_key
    User admin

# 個人服務器
Host personal-*
    IdentityFile ~/.ssh/personal_key
    User root

# GitHub
Host github.com
    IdentityFile ~/.ssh/github_key
    User git

查看和管理密鑰

bash
# 列出所有密鑰指紋
ssh-add -l

# 查看密鑰詳細信息
ssh-add -L

# 刪除特定密鑰
ssh-add -d ~/.ssh/old_key

# 刪除所有密鑰
ssh-add -D

SSH 證書認證(企業級)

什麼是 SSH 證書?

SSH 證書是由 CA(證書頒發機構)簽名的公鑰,提供更細粒度的訪問控制和自動過期機制。

創建 CA 密鑰

bash
# 在 CA 服務器上
ssh-keygen -t ed25519 -f ca_key -C "SSH CA Key"

簽署用戶密鑰

bash
# 簽署用戶公鑰,有效期 52 周
ssh-keygen -s ca_key -I user_id -n username -V +52w id_ed25519.pub

# 生成證書文件:id_ed25519-cert.pub

配置服務器信任 CA

bash
# 在 SSH 服務器上
echo "TrustedUserCAKeys /etc/ssh/ca_key.pub" >> /etc/ssh/sshd_config
systemctl restart sshd

優勢:

  • ✅ 集中管理密鑰
  • ✅ 自動過期
  • ✅ 細粒度權限控制
  • ✅ 易於撤銷

常見問題排查

Q1: 密鑰登錄失敗,提示 "Permission denied (publickey)"?

排查步驟:

  1. 檢查文件權限
bash
# 在服務器上執行
ls -la ~/.ssh/
# 應該顯示:
# drwx------ .ssh
# -rw------- authorized_keys

# 修復權限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
  1. 檢查公鑰格式
bash
# 確保公鑰在一行內
cat ~/.ssh/authorized_keys
# 不應該有換行符
  1. 檢查 SELinux(CentOS/RHEL)
bash
# 恢復正確的安全上下文
restorecon -Rv ~/.ssh
  1. 查看詳細日誌
bash
# 在服務器上查看
tail -f /var/log/auth.log
# 或
journalctl -u sshd -f

# 在客戶端使用調試模式
ssh -vvv root@your_server

Q2: 誤把自己的 IP 鎖在外面怎麼辦?

緊急救援方案:

  1. 使用 VNC 控制檯

    • 登錄雲服務商面板
    • 打開 VNC 控制檯
    • 臨時啟用密碼登錄
    bash
    nano /etc/ssh/sshd_config
    # 修改:PasswordAuthentication yes
    systemctl restart sshd
  2. 從其他可信 IP 登錄

    • 如果有其他已配置密鑰的設備
    • 或通過同事的電腦訪問
  3. 聯繫服務商重置

    • 大多數雲服務商提供密碼重置功能
    • 或通過工單系統請求幫助

預防措施:

  • ✅ 始終保留 VNC 訪問權限
  • ✅ 在白名單中添加備用 IP
  • ✅ 測試完成後再關閉密碼登錄

Q3: 如何在多臺服務器間同步密鑰?

方法 1:使用配置管理工具

bash
# Ansible 示例
ansible all -m authorized_key -a "user=root key='{{ lookup('file', '~/.ssh/id_ed25519.pub') }}'"

方法 2:使用腳本批量部署

bash
#!/bin/bash
servers=("192.168.1.100" "192.168.1.101" "203.0.113.50")

for server in "${servers[@]}"; do
  echo "Deploying to $server..."
  ssh-copy-id root@$server
done

方法 3:使用 Git 管理

bash
# 將 authorized_keys 納入版本控制
cd /etc/ssh
git init
git add authorized_keys
git commit -m "Update SSH keys"

# 在其他服務器上拉取
git pull
systemctl restart sshd

Q4: 密鑰文件丟失怎麼辦?

恢復步驟:

  1. 從備份恢復
bash
# 如果有備份
cp backup/id_ed25519 ~/.ssh/
chmod 600 ~/.ssh/id_ed25519
  1. 通過 VNC 重新部署
bash
# 在 VNC 控制檯中
# 1. 臨時啟用密碼登錄
# 2. 從本地重新上傳公鑰
# 3. 生成新密鑰對
  1. 重新生成密鑰
bash
# 在本地生成新密鑰
ssh-keygen -t ed25519 -f ~/.ssh/new_key

# 通過 VNC 部署新公鑰
# 然後更新所有服務器的 authorized_keys

預防建議:

  • ✅ 定期備份 .ssh 目錄
  • ✅ 使用密碼管理器存儲 passphrase
  • ✅ 在多個安全位置保存私鑰副本

Q5: 如何審計和清理無效密鑰?

查看當前授權密鑰:

bash
# 在服務器上
cat ~/.ssh/authorized_keys

# 查看最後登錄時間
lastlog

# 查看活躍會話
who
w

清理策略:

bash
#!/bin/bash
# 審計腳本

echo "=== SSH Key Audit ==="
echo ""
echo "Authorized keys:"
cat ~/.ssh/authorized_keys | wc -l
echo ""

echo "Recent logins:"
last -n 10
echo ""

echo "Active sessions:"
who

最佳實踐:

  • 每季度審查一次 authorized_keys
  • 移除離職員工或廢棄項目的密鑰
  • 記錄每個密鑰的用途和所有者
  • 使用註釋標識密鑰用途
text
ssh-ed25519 AAAA... user@company-laptop # John Doe, Dev Team
ssh-ed25519 BBBB... deploy@ci-server   # CI/CD Pipeline

額外建議與安全提醒

安全最佳實踐清單

必須做:

禁止做:

高級安全加固

1. 使用 Fail2ban 防護

bash
# 參考我們的 Fail2ban 教程
# 自動封禁多次失敗的 IP
apt install fail2ban

2. 啟用雙因素認證(2FA)

bash
# 安裝 Google Authenticator
apt install libpam-google-authenticator

# 配置 PAM
nano /etc/pam.d/sshd
# 添加:auth required pam_google_authenticator.so

# 配置 SSH
nano /etc/ssh/sshd_config
# 添加:AuthenticationMethods publickey,keyboard-interactive

3. 限制登錄來源 IP

bash
# 在 /etc/ssh/sshd_config 中
AllowUsers root@192.168.1.0/24
AllowUsers deploy@203.0.113.50

4. 使用 SSH 證書代替密鑰

  • 適合大型企業
  • 集中管理
  • 自動過期
  • 細粒度權限

保管好你的私鑰!

既然密碼登錄已經關閉,那麼本地電腦上的那個 id_ed25519 私鑰文件就是你連接這臺服務器的 唯一憑證。如果你重裝了電腦或者弄丟了這個私鑰文件,你將永遠無法再次登入這臺服務器!(除非主機面板提供了 VNC 救援控制檯)

私鑰備份策略:

  1. 加密存儲:使用 VeraCrypt 或 BitLocker 加密 U 盤
  2. 密碼管理器:1Password、Bitwarden 等支持附件存儲
  3. 紙質備份:打印 QR 碼或助記詞(極端情況)
  4. 多地點存儲:家中保險箱 + 銀行保管箱

不要把私鑰發送給任何人,尤其是不要將其上傳到公開的代碼倉庫(如 GitHub)。

按照以上步驟,你可以高枕無憂了,公網上的無聊掃描機器人再也無法攻破你的 SSH 堡壘。🔒✨


延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。

最後更新於: