前言
一直以來我都是在我的電腦使用 ssh key 機制登入我的遠端 ubuntu server,有一天突然出現登入失敗的訊息:Permission denied (publickey)
,但我確認我並沒有異動任何 ssh key 登入設定,公私鑰的配對也沒有錯誤。研究了很久後終於發現是我上次 ubuntu server 切換預設 shell 沒切換好所造成的。以下就來紀錄這次遇到問題、發生原因和解決過程。
問題發生前
我的 ubuntu server 一直以來是使用 fish shell,最近因為發現在更新 node 和 npm 版本會失敗(How to manage my node version using Fish Shell),我索幸將 fish shell 換成我平常在用的 zsh shell。
以下是我印象中的的更換方式:
sudo apt update
sudo apt install zsh
# 設定 zsh
zsh
sudo apt remove fish
chsh -s /bin/zsh
# 事後檢討:
# 盡可能使用 chsh -s $(which zsh),確保新的 shell 路徑正確
# 並且等確認沒問題後,再移除舊的 shell
結果之後再次使用 ssh key 登入就出現 Permission denied (publickey)
。
問題根因
我確認我並沒有異動任何 ssh key 登入設定,公私鑰的配對也沒有錯誤,最後向有管過 server 的朋友詢問後才發現:因為登入角色的 shell 仍然是 fish shell,但此時 fish shell 已被移除,導致登入失敗!有發現嗎?其實 ssh key 有登入成功,但因為登入後啟動 shell 的過程發生錯誤,ubuntu 直接當成是 ssh key 登入失敗所致,所以回傳 Permission denied (publickey)。
解決方式
想盡辦法進入 server 將登入角色的 shell 切換成已安裝的任何 shell。
Digital Ocean: Recovery Console
我現在登入不了 server,而基於安全問題,平常 root 登入權限也是鎖住的。我只好使用我的 VPS 平台 Digital Ocean 提供的 web console 進行調整。
然而 Digital Ocean 一般的 Droplet Console 我不知為何登不進去,所以只好選擇速度比較慢的 Recovery Console。
以下提供 Digital Ocean Recovery Console 的救援方法:
1. 進入 Droplet 管理介面,左方 menu 選擇 Recovery 頁面
- 選擇【Boot from Recovery ISO】
- 點擊右上角的 ON 開關,切成 OFF(關機),待關機成功,再切回 ON
2. 左方 menu 選擇 Access 頁面
- 點擊 <Launch Recovery Console> 按鈕
接下來就會開啟一個新視窗,使用 Web 的方式登入 server 的 Recovery Console。
我們這邊使用 root 進行登入,如果密碼忘記了,可以使用上圖下方的 Reset root password 進行密碼重置,新密碼會寄到你的 email。
3. 位於 Recovery Console 中
由於這是 Recovery 環境,首頁會有 1~6 點的選項,你必需按照規則操作。
此時你的 Server 資料還尚未 mount 起來,所以請先輸入 1
並按 enter,進行你的資料掛載。你的資料會被掛載到 /mnt
這個路徑下。
接下來輸入 6
並按 enter,進入 bash shell。
接下來可以先使用 cat 來確認一下 shell 的使用情況:
cat /mnt/etc/passwd
上述指令會列出一段字,描述 shell 的使用情況。找到你平常所登入的角色。以我的例子來說,我平常是使用 jsying 登入:
...
jsying:x:1000:1000:,,,:/home/jsying:/usr/bin/fish
...
這時候可以看到 jsying 這個角色的 shell 仍然是 fish!我們現在要將他改為我們有的 bash shell 或 zsh shell。
可以使用 which 來確認 shell 的位置,以 zsh 為例:
which zsh
# 印出: /usr/bin/zsh
這時候我們就回到 passwd 進行修改:
nano /mnt/etc/passwd
將 /usr/bin/fish 替換成 /usr/bin/zsh:
...
jsying:x:1000:1000:,,,:/home/jsying:/usr/bin/zsh
...
接下來使用 Ctrl + X
進行儲存即可。
4. 關閉 Recovery Console,回到 Digital Ocean 管理介面
- 回到 Recovery 頁面
- 選擇【Boot from Hard Drive】
- 點擊右上角的 ON 開關,切成 OFF(關機),待關機成功,再切回 ON(從硬碟開機)
5. 大功告成
終於可以用一般的方式登回 server 了⋯⋯Web Console 的速度真的是慢到想哭。
後記
真的沒想到更換 shell 可以造成這樣的災難,而 ubuntu 回應的錯誤訊息也讓我造成誤解(一直往 ssh key 的方向查問題),最後好在是透過一位有網管經驗的朋友得到了解答。於是我決定記錄下來,希望可以幫助到有相同困擾的人。