SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

SSH 出現 Permission denied (publickey) 怎麼修正?

遇到「Permission denied (publickey)」不代表只有一種故障。使用 ssh -v 讀取 3 行關鍵輸出,區分使用者名稱、金鑰與伺服器設定問題,避免誤改設定導致自己無法登入。

「Permission denied (publickey)」實際代表的意義

「Permission denied (publickey)」表示用戶端送出了一個或多個公開金鑰,但伺服器沒有接受其中任何一把。網路連線正常,sshd 也正在執行;拒絕發生在驗證的最後一步。修正方式不必靠猜測,因為 ssh -v 會告訴你屬於五種原因中的哪一種。

括號內的文字表示伺服器願意接受的驗證方法。單獨出現 Permission denied (publickey) 表示該伺服器已停用密碼登入,因此沒有密碼可供退回使用。Permission denied (publickey,password) 表示伺服器提供密碼登入,而你也未能通過密碼驗證。

同一則訊息涵蓋五種不同的故障,而且刻意保持模糊。如果伺服器回覆「沒有這個使用者」或「未安裝該金鑰」,就會協助掃描有效帳號的人員。因此,不要一開始就更換金鑰或修改設定檔。先執行一個命令,讀取輸出的三行內容,五種可能原因就能縮小為一種。

先執行 ssh -v,讀取 3 行

在失敗的指令後加上 -v,再重新執行:

ssh -v deploy@203.0.113.10

精簡但符合實際情況的輸出如下:

OpenSSH_9.6p1 Ubuntu-3ubuntu13, OpenSSL 3.0.13 30 Jan 2024
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: Connection established.
debug1: Authenticating to 203.0.113.10:22 as 'deploy'
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:0eL/8sBw... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:0eL/8sBw... agent
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
deploy@203.0.113.10: Permission denied (publickey).

這 3 行包含了所需的全部資訊。

Authenticating to 203.0.113.10:22 as 'deploy' 是實際使用的使用者名稱。它不一定是你原本想使用的名稱,而是 ssh 根據命令列、~/.ssh/config 或本機登入名稱判定出的名稱。

Authentications that can continue: publickey 是伺服器接受的方法清單,會在嘗試任何金鑰前傳送。如果第一份清單缺少 publickey,表示伺服器已停用 public key 登入,因此任何金鑰都不可能成功。

Offering public key: ... 每把用戶端實際傳送的金鑰各列出 1 行,並顯示來源檔案及其 SHA256 fingerprint。沒有 Offering 行的金鑰,從未傳送到伺服器。

現在將問題分成 2 類:

  • 找不到你預期金鑰的 Offering public key 行。問題出在你的電腦,因為伺服器根本沒有收到你的金鑰。
  • 已提供該金鑰,但再次出現 Authentications that can continue: publickey。伺服器已收到該金鑰並拒絕使用,因此問題出在伺服器。

以下原因依實際發生的頻率排序。

原因 1:您使用了錯誤的使用者名稱

最常見的原因也是最不值得注意的一項。sshd 是 SSH(secure shell)伺服器 daemon,不會告訴您某個帳號不存在。它會以虛構的使用者名稱完成整個交換流程,最後以相同訊息拒絕連線,因為洩漏有效的帳號名稱會協助攻擊者。使用者名稱拼寫錯誤,看起來就像金鑰損壞。

先檢查 Authenticating to ... as 行。若其中顯示的是您筆電的登入名稱,而不是伺服器帳號,表示您在命令中省略了使用者名稱。

ssh -v deploy@203.0.113.10
ssh -v root@203.0.113.10

預設帳號取決於供應商建置的映像檔。截至 August 2026,Ubuntu cloud images 通常會提供 ubuntu 帳號,Debian images 會提供 debianadmin,Rocky Linux 和 AlmaLinux 會提供 rockyalmalinux;許多 VPS 供應商則會直接將您的金鑰安裝到 root。供應商的控制面板會記錄它建立的帳號。從伺服器外部執行的命令無法查詢這項資訊。

~/.ssh/config 中的 Host 區塊也會設定使用者名稱,而且優先於您本機的登入名稱:

Host vps-prod
  HostName 203.0.113.10
  User deploy

如果您自行建立帳號,卻無法以該帳號登入,金鑰可能只安裝在映像檔的預設使用者上,尚未複製到新帳號。這是 新 VPS 的前 10 分鐘內應完成的步驟,但很容易略過。

原因 2:你以為正在傳送的 key 並不是實際傳送的 key

根據預設,ssh 只會提供 ssh-agent 所持有的 key,以及 ~/.ssh 中一組固定檔名的 key:id_ed25519id_ecdsaid_rsa,還有這些檔名的硬體與 DSA 變體。儲存為 ~/.ssh/vps-prod 的 key 必須明確指定,ssh 才能找到。因此,詳細輸出中不會出現該 key 的 Offering public key 行。

指定檔案,並避免 agent key 取代它:

ssh -i ~/.ssh/vps-prod -o IdentitiesOnly=yes deploy@203.0.113.10

單獨使用 -i 並不足夠。當 agent 持有 key 時,ssh 仍會先提供 agent 的 key,最後才提供指定的檔案。這一點很重要,因為伺服器會將每個遭拒的 key 都計入 MaxAuthTries,其預設值為 6。若 agent 持有七個 key,可能會在嘗試到正確的 key 前耗盡限制,接著訊息會變成:

Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures

IdentitiesOnly=yes 會將嘗試限制在你指定的檔案。使用 ssh-add -l 列出 agent 目前持有的 key;如果 agent 已累積多年未使用的 key,則使用 ssh-add -D 清除。接著將設定寫入檔案,讓下次登入不必依賴記住 flags:

Host vps-prod
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/vps-prod
  IdentitiesOnly yes

還有一個 client 端的陷阱。若本機上的其他帳戶可以讀取 private key,ssh 會拒絕使用該 key。它會顯示警告,然後忽略該 key,因此這個 key 不會被提供,伺服器也永遠不會看到它:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/you/.ssh/vps-prod' are too open.

chmod 600 ~/.ssh/vps-prod 可修正此問題。透過 USB 隨身碟或 Windows share 搬移 key,是造成檔案 mode 遺失的常見原因。SSH key 管理基礎說明 key 的存放位置與命名方式。

原因 3:公開金鑰從未寫入 authorized_keys

如果 ssh -v 顯示金鑰已送出,但伺服器仍拒絕連線,下一個問題就是該金鑰是否位於帳戶的 authorized_keys 檔案中。由於目前無法透過 SSH 登入查閱,請開啟供應商的主控台進行確認。

sudo ls -l /home/deploy/.ssh/
sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys

authorized_keys 檔案上執行 ssh-keygen -lf,會為每個項目列印一個指紋:

256 SHA256:0eL/8sBw... you@laptop (ED25519)
3072 SHA256:9Tq2yZk... old-laptop (RSA)

將這些指紋與 Offering public key 行中的指紋比對。如果不在清單中,表示該金鑰未安裝到該帳戶,無論你記得自己做過什麼操作。

以下 4 種常見情況都可能造成問題:

  • 你貼上的是私密金鑰,而不是 .pub 檔案。公開金鑰行會以 ssh-ed25519ssh-rsa 開頭。私密金鑰則以 -----BEGIN OPENSSH PRIVATE KEY----- 開頭。
  • 貼上的內容換成了多行。每個項目都必須完整位於同一行,因此換行後的金鑰會被讀成多個損壞的項目,無法比對。
  • 金鑰寫入了 /root/.ssh/authorized_keys,但你是以 deploy 登入,或反過來。該檔案是每個帳戶個別使用的,不存在共用檔案。
  • 供應商的「新增我的金鑰」欄位只會將金鑰寫入映像檔的預設使用者,因此你稍後建立的帳戶,其 .ssh 目錄仍是空的。

以 root 身分從主控台新增金鑰時,請使用以下安全方式:

sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo tee -a /home/deploy/.ssh/authorized_keys >/dev/null <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyDataHere you@laptop
EOF
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys

之後再次執行 sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys。新的指紋現在應該會出現在清單中。若有一台機器仍可使用密碼登入,ssh-copy-id -i ~/.ssh/vps-prod.pub deploy@203.0.113.10 會執行相同操作,並替你正確設定模式。

原因 4:權限過於寬鬆時,為什麼 sshd 會忽略 authorized_keys

StrictModes yes 是 sshd 的預設值。在此設定下,只要 .ssh 檔案、.ssh 目錄或帳號的主目錄可由擁有者以外的任何人寫入,sshd 就會拒絕讀取 authorized_keys。原因很直接:如果群組或其他使用者可寫入主目錄,任何具備該權限的帳號都能替換 authorized_keys,進而接管登入。sshd 會將不受信任的路徑視為不存在金鑰。

用戶端只會看到一般的 Permission denied 訊息。伺服器日誌會記錄實際原因:

Authentication refused: bad ownership or modes for directory /home/deploy/.ssh

或是在檔案本身有問題時:

Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keys

sshd 接受的條件如下:

  • 主目錄:不可由群組寫入,也不可由其他使用者寫入。755750700 都符合。775777 不符合。
  • ~/.ssh:模式為 700
  • ~/.ssh/authorized_keys:模式為 600
  • 擁有權:這 3 個項目都必須由登入所用的帳號擁有,而不是由 root 擁有。

擁有權和模式同樣重要。/home/deploy/.ssh 中由 root 擁有的檔案,也會在相同檢查中失敗。當你以 sudo nano 建立檔案後忘記將擁有權改回來,就會發生這種情況。一次修正兩者:

sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chmod go-w /home/deploy
ls -ld /home/deploy /home/deploy/.ssh

最後一個命令會顯示結果。主目錄應為 drwxr-xr-x 或更嚴格,而 .ssh 應為 drwx------。如果目前還不清楚這些字串的意義,請先閱讀 如何讀取像 drwxr-xr-x 這樣的權限字串,再變更執行中伺服器的模式。

在 Rocky Linux 和 AlmaLinux 上,還應將 SELinux(security-enhanced Linux)列入排查範圍。透過非標準方式建立的 .ssh 目錄可能帶有錯誤的檔案標籤,因此即使模式正確,sshd 仍會被拒絕讀取。sudo restorecon -Rv /home/deploy/.ssh 會還原標籤,而 sudo ausearch -m avc -ts recent 可顯示是否由 SELinux 拒絕存取。

原因 5:sshd 設定為拒絕您的連線

在目前的 Ubuntu 或 Debian 系統上,只查看 /etc/ssh/sshd_config 並不足夠。該檔案開頭會載入 Include /etc/ssh/sshd_config.d/*.conf,而 OpenSSH 對任何設定都會採用首次讀取到的值。因此,像 50-cloud-init.conf 這類 drop-in 檔案會先讀取,其設定會覆寫主檔案較下方的內容。這就是為何修改內容看似正確,卻完全沒有產生效果。

請要求 sshd 顯示實際採用的設定:

sudo sshd -T | grep -Ei 'pubkeyauth|authorizedkeysfile|permitrootlogin|allowusers|allowgroups|denyusers'

正常的結果如下:

permitrootlogin prohibit-password
pubkeyauthentication yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2

請在自己的輸出中查找以下內容:

  • pubkeyauthentication no。系統永遠不會接受任何金鑰。這也會在 ssh -v 中顯示為第一個 Authentications that can continue: 清單,且其中沒有 publickey
  • authorizedkeysfile 指向其他位置,例如 /etc/ssh/authorized_keys/%u。此時會完全忽略家目錄中的檔案,並改套用新路徑的模式規則,也就是原因 4 所述的規則。
  • 存在 allowusersallowgroups。未列出的帳號會因為相同錯誤而遭拒絕,且不會顯示其他說明。denyusersdenygroups 的作用相反。
  • 當您嘗試以 root 登入時,存在 permitrootlogin noprohibit-password 是較實用的中間設定:root 可以使用金鑰,但不能使用密碼。

Match 區塊不會出現在純粹的 sshd -T 輸出中,因為其結果取決於連線者身分。請針對特定連線查詢:

sudo sshd -T -C user=deploy,host=vps.example.com,addr=198.51.100.7

還有一項設定會影響較舊的金鑰。OpenSSH 8.8 預設停止接受 SHA-1 簽章(ssh-rsa),因此使用多年的 RSA 金鑰可能會在伺服器升級後立即失效。用戶端會清楚顯示原因:

debug1: send_pubkey_test: no mutual signature algorithm

正確的修正方式是建立新金鑰:ssh-keygen -t ed25519 -C "deploy@vps-prod",然後依照上文所示安裝 .pub 檔案。在伺服器上設定 PubkeyAcceptedAlgorithms +ssh-rsa 可重新啟用舊簽章,讓您今天先登入伺服器。因此,請將此設定視為暫時連入伺服器的方法,而不是問題的最終解決方案。其他值得檢查的伺服器端設定,請參閱 強化 VPS 上的 SSH 伺服器

如何證明私鑰與已安裝的公鑰相符

這個錯誤大多難以判斷,是因為不知道兩個檔案是否成對。執行一個指令即可確認:

ssh-keygen -y -f ~/.ssh/vps-prod

這會輸出由私鑰推導出的公鑰。它不會讀取旁邊的 .pub 檔案,因此顯示的是私鑰實際對應的內容,而不是過時的 .pub 檔案所宣稱的內容。如果金鑰設有 passphrase,指令會要求輸入 passphrase;這也能證明你仍知道該 passphrase。

ssh-keygen -lf ~/.ssh/vps-prod.pub
ssh-add -l

第一個指令會輸出一個公鑰檔案的指紋。第二個指令會輸出 agent 目前持有的指紋。現在比對同一字串的 4 個來源:ssh -v 輸出的 Offering public key 行中的指紋、你的 .pub 檔案指紋、伺服器 authorized_keysssh-keygen -lf 中的指紋,以及伺服器日誌中的指紋。它們開始不一致的位置,就是問題所在。

登入失敗時查看伺服器日誌

伺服器會刻意不向用戶端提供有用資訊,但會記錄實際原因。先在主控台工作階段啟動日誌追蹤器,再從筆記型電腦執行失敗的 ssh 命令。

sudo journalctl -u ssh -f

Ubuntu 24.04 預設不會安裝 rsyslog,因此該系統可能不存在 /var/log/auth.log。在 Rocky Linux 和 AlmaLinux 上,服務單元名稱為 sshd,相同記錄也會寫入 /var/log/secure

在 sshd 設定中設定 LogLevel VERBOSE,然後重新載入服務。之後每次嘗試都會記錄伺服器實際收到的指紋:

Failed publickey for deploy from 198.51.100.7 port 49812 ssh2: ED25519 SHA256:0eL/8sBw...

這行記錄可判斷問題出在哪一端。若指紋是你認得的,表示伺服器已收到你的金鑰,但拒絕了它,請檢查原因 3、4 和 5。若指紋不是你認得的,表示用戶端送出了非預期的金鑰,請回到原因 2。

如果日誌仍不清楚,請在其他連接埠上以偵錯模式啟動第二個 sshd。它會以前景模式執行,處理一個連線、輸出判斷過程,然後結束:

sudo /usr/sbin/sshd -ddd -p 2222

在同一台伺服器的主控台工作階段中,透過回送位址連線到該服務:

ssh -p 2222 -i ~/.ssh/vps-prod -o IdentitiesOnly=yes deploy@127.0.0.1

透過 127.0.0.1 連線可避免防火牆影響測試。偵錯輸出會列出它開啟的檔案、比對的指紋,以及確切的拒絕原因,其中包括 Authentication refused: bad ownership or modes for directory /home/deploy 等行。找到答案後按下 Ctrl+C。整個過程不會影響連接埠 22 上的正式 sshd。

如何避免將自己鎖在伺服器外

每個會修改伺服器設定的步驟,都需要準備不依賴 SSH 的返回途徑。請在 SSH 仍可用時完成設定,不要等到 SSH 故障後才處理。

  1. 開啟供應商提供的主控台,透過 serial 或 VNC(virtual network computing)連線,並確認可以從該處登入。
  2. 確認你知道具備 sudo 權限之帳號的有效本機密碼。若沒有,請先從供應商主控台 重設 root 密碼
  3. 保留目前的 SSH 工作階段。開啟的工作階段可在 systemctl restart ssh 後持續存在,因此新設定錯誤時,仍可用它返回伺服器。
  4. 重新啟動前先檢查語法:檔案有效時,sudo sshd -t 不會輸出任何內容;檔案無效時,會輸出檔案名稱與行號。
  5. 開啟第二個終端機並重新登入,確認成功後再關閉第一個工作階段。錯誤的設定會阻止新的登入,但不會影響現有登入,因此目前所在的工作階段無法確認變更是否生效。

在 Debian 和 Ubuntu 上使用 sudo systemctl restart ssh 重新啟動;在 Rocky Linux 和 AlmaLinux 上使用 sudo systemctl restart sshd。在 Ubuntu 24.04 上,sshd 是從 socket unit 啟動的,因此修改 PortListenAddress 後,還需要執行 sudo systemctl restart ssh.socket 才會生效。

FAQ

為什麼同一把金鑰在另一台伺服器可用,卻出現 Permission denied (publickey)?

因為金鑰本身沒有問題,問題出在相關設定。執行 ssh -v,找出 Offering public key 行。如果未列出您的金鑰,表示 ssh 根本沒有送出該金鑰:檔案不在 ~/.ssh,未使用預設名稱,且也未載入 agent,因此請加入 -i /path/to/key -o IdentitiesOnly=yes。如果已列出金鑰,但伺服器仍拒絕連線,可能是該金鑰不在帳戶的 authorized_keys 中、其路徑可由群組寫入,或 sshd 設定封鎖了該使用者。伺服器日誌可區分這些情況。

如何查看 SSH 實際送出了哪一把金鑰?

ssh -v host 會為每把金鑰輸出一行 debug1: Offering public key:,其中包含來源檔案與 SHA256 指紋。ssh-add -l 會列出 agent 持有的指紋。ssh-keygen -lf ~/.ssh/id_ed25519.pub 會輸出單一金鑰檔案的指紋,ssh-keygen -y -f ~/.ssh/id_ed25519 則會輸出私密金鑰實際衍生出的公開金鑰。登入要成功,Offering 行中的指紋也必須出現在針對伺服器的 ssh-keygen -lf 執行結果中,該結果來自伺服器的 authorized_keys

為什麼 sshd 忽略我的 authorized_keys 檔案?

因為 StrictModes 預設為啟用,而該檔案、.ssh 目錄或家目錄可由群組或其他使用者寫入,或由錯誤的帳戶擁有。sshd 不會信任其他人可以修改的路徑,因此其行為就像不存在任何金鑰。將家目錄權限設為 755 或更嚴格,將 .ssh 設為 700,將 authorized_keys 設為 600,並讓這三者都由登入帳戶擁有。使用 LogLevel VERBOSE 後,伺服器會記錄 Authentication refused: bad ownership or modes for directory /home/deploy/.ssh

我的金鑰在伺服器升級後立即停止運作。發生了什麼變更?

如果這是 RSA 金鑰,最可能是 SHA-1 的變更。OpenSSH 8.8 預設停用 ssh-rsa SHA-1 簽章,因此只能以該方式簽章的金鑰現在會遭到拒絕。詳細的用戶端輸出會顯示 debug1: send_pubkey_test: no mutual signature algorithm。使用 ssh-keygen -t ed25519 產生現代金鑰,並安裝其 .pub 檔案。如果您需要立即恢復存取,可在伺服器上設定 PubkeyAcceptedAlgorithms +ssh-rsa,重新啟用舊簽章;新金鑰可用後,應移除該行。

我編輯了 sshd_config,現在完全無法登入。如何恢復存取?

使用供應商提供的主控台,該主控台不會透過 SSH 連線。使用本機密碼登入,執行 sudo sshd -t 查看語法錯誤及其行號,還原變更後重新啟動服務。接著檢查 sudo sshd -T,確認目前執行中的值,因為 /etc/ssh/sshd_config.d/ 中的檔案可能覆寫主要設定。如果您沒有本機密碼,先從主控台重設 root 密碼,再修復設定檔。