SSH 禁止密碼登入和改 Port 方法

這裡會對 SSHD CONFIG 作出兩個改動,分別為「禁止 SSH 使用密碼登入」和「更改 SSH Port」。

這篇文章的內容來自Ubuntu Server 安裝後的安全設定的一部分,因篇幅過長,所以進行了摘錄。

操作平台:Ubuntu Server 20.04 (LTS)

本文將對 SSHD CONFIG 進行兩項調整:

  • 禁止 SSH 使用密碼登入(請謹慎選擇)
  • 更改 SSH 登入端口

備份

請在進行任何修改前,先對現有的設定檔進行備份:

1
2
mkdir ~/ssh_backup/
sudo cp -a /etc/ssh ~/ssh_backup/

禁止 SSH 使用密碼登入(慎選)

許多人主張應禁用密碼登入,改為使用私鑰登入。我個人則視情況選擇使用密碼或私鑰登入。

若選擇密碼登入,我會利用密碼管理器(例如:Bitwarden)生成長度數十位的隨機密碼。在我看來,只要密碼長度足夠(≥20位),安全性就已經足夠。

下面,我們將進行禁用密碼登入,改為使用私鑰登入的操作:

  1. 首先,在你的電腦上(注意,不是伺服器!),你需要生成一對密鑰(公鑰和私鑰)。在 Terminal 中輸入:
1
ssh-keygen -t ed25519

對於出現的所有問題,你基本上可以直接選擇預設值。

你可以設置一個 passphrase(每次使用私鑰登入時,都需要輸入一次 passphrase,如果覺得麻煩,可以查詢 Google ssh-agent)。我們不建議這個 passphrase 與你在伺服器上使用的用戶密碼相同。

完成後,你會看到以下的畫面:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 例子:我輸入了 ssh-keygen -t ed25519 -C "[email protected]"

Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/oldestdream/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/oldestdream/.ssh/id_ed25519
Your public key has been saved in /Users/oldestdream/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [email protected]

從以上畫面,你可以找到私鑰和公鑰的存儲位置:

私鑰:/Users/oldestdream/.ssh/id_ed25519

公鑰: /Users/oldestdream/.ssh/id_ed25519.pub

  1. 將剛剛建立的公鑰傳送到你的伺服器上。 注意:這裡需要傳送的是公鑰,而非私鑰!

在 macOS 上,你可以輸入以下命令:

1
ssh-copy-id -i $HOME/.ssh/id_ed25519.pub <username_of_new_acct>@<your_server_ip>

成功後,你會看到以下的訊息:

1
2
3
4
5
6
7
8
9
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/oldestdream/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

在 Windows 上,可以輸入:

1
type $env:USERPROFILE\\.ssh\\id_ed25519.pub | ssh <username_of_new_acct>@<your_server_ip> "if umask 077 && mkdir -p .ssh && cat > .ssh/authorized_keys; then echo success; else echo failure; fi;"

見到 success 而不是 failure 便代表成功了。

如果你希望多台電腦都能登入伺服器,我建議在進行下一步之前,先在這些電腦上重複剛才的兩個步驟。

否則,當你稍後想從其他電腦登入時,可能會遇到一些困擾。

我通常會將桌面電腦、筆記本電腦,甚至手機的公鑰都傳送到伺服器上。這樣即使其中一台電腦出現問題,我仍然可以進行登入。

以上的步驟會在伺服器上的 ~/.ssh/authorized_keys 文件中添加你提供的公鑰。你也可以手動編輯該文件,自行添加公鑰。

  1. 接著,我們嘗試登入伺服器

請根據你的情況修改 <username_of_new_acct><your_server_ip>。如果你能夠成功登入而無需輸入密碼,那麼就表示你已經成功了:

1
ssh <username_of_new_acct>@<your_server_ip>

如果你發現需要輸入密碼,且你正在使用 Windows,那麼可能是由於 Windows 的換行符號導致的。

你可以嘗試使用密碼登入,然後使用 vi 編輯器刪除伺服器上 ~/.ssh/authorized_keys 文件行末的 ^M,然後再試一次。

然後,我們將修改 sshd 的設定文件,使其只能通過私鑰登入。

首先,輸入以下命令,這將幫助我們決定接下來是選擇簡單的方法還是傳統的方法:

1
grep "^Include /etc/ssh/sshd_config.d/\*.conf" /etc/ssh/sshd_config

如果你看到以下的輸出,

1
Include /etc/ssh/sshd_config.d/*.conf

那麼表示我們可以選擇簡單的方法,否則,我們需要選擇傳統的方法。

簡單方法

只需執行以下命令:

1
sudo nano /etc/ssh/sshd_config.d/10-restrict-login.conf

在此,檔案名稱可以根據你的需要進行修改,但副檔名 .conf 必須保留。

然後,將以下內容複製並貼入:

1
2
3
4
ChallengeResponseAuthentication no
PasswordAuthentication no
PermitRootLogin prohibit-password
PermitEmptyPasswords no

接著進行保存:

Command /Ctrl + O, 再 Enter 保存。

Command /Ctrl + X, 退出 nano。

完成後,請跳過下面的「傳統方法」部分。

傳統方法

請輸入以下命令以開始修改設定檔:

1
sudo nano /etc/ssh/sshd_config

接下來,我們需要修改幾個地方:

注意:如果需要修改的行首有井號 #,請記得先刪除該井號。

找到 ChallengeResponseAuthentication 這一行,並修改如下:

1
ChallengeResponseAuthentication no

找到 PasswordAuthentication 這一行,並修改如下:

1
PasswordAuthentication no

找到 PermitRootLogin 這一行,並修改如下:

1
PermitRootLogin prohibit-password

找到 PermitEmptyPasswords 這一行,並修改如下:

1
PermitEmptyPasswords no

然後進行保存:

Command /Ctrl + O, 再 Enter 保存。

Command /Ctrl + X, 退出 nano。

至此,傳統方法已完成!請繼續閱讀下文。

錯誤檢查

不論你選擇簡單方法或傳統方法,我們都需要進行錯誤檢查:

請執行以下命令以檢查是否存在錯誤:

1
sudo sshd -t

如果沒有任何訊息出現,那麼就表示設定無誤。

若出現錯誤,由於我們之前已在 ~/ssh_backup/ 目錄下做了備份,因此可以取回備份並重新進行修改。

  1. 重啟 sshd 以使新的設定生效:
1
sudo systemctl restart sshd
  1. 請不要立即關閉目前的 Terminal, 我們需要確認是否能成功登入。

請在你的電腦(非伺服器)上開啟一個新的 Terminal, 嘗試登入,看看是否能夠無需密碼即可成功登入。

1
ssh <username_of_new_acct>@<your_server_ip>

再進行一次測試,確認是否禁止使用密碼登入:

1
ssh -o PubkeyAuthentication=no <username_of_new_acct>@<your_server_ip>

如果出現 Permission denied (publickey). 的訊息,那麼恭喜你,設定成功了。

更改 SSH Port

SSH 預設使用的端口為 22。根據實際經驗,將其更改為其他端口可以減少一些滋擾。

這就像大家的家門都設在同一個位置(端口 22),而你把這個門口封掉,然後在另一個位置開一個新門口,回家時就從新門口進入。

實際上,有心人仍可以四處尋找你的新門口,但他們通常不會花費太多時間和精力來搜索,他們更傾向於去尋找那些沒有改變門口的家,嘗試開門看看,或者看是否有窗戶沒有關好。

建議將 SSH 端口更改為 1024 至 49151 之間的隨機數字,但需要避開下面網頁列出的端口,以減少衝突的可能性。

List of TCP and UDP port numbers – Wikipedia

確定想改的端口後,輸入以下命令來確保防火牆允許該端口用於登入,以防出現意外:

1
sudo ufw allow <number_from_1024_to_49151>/tcp

接下來,請先輸入以下命令,這將有助於我們決定接下來選擇簡單方法還是傳統方法:

1
grep "^Include /etc/ssh/sshd_config.d/\*.conf" /etc/ssh/sshd_config

輸入命令後,如果出現以下這句:

1
Include /etc/ssh/sshd_config.d/*.conf

那麼我們接下來可以選擇簡單方法,否則則選擇傳統方法。

簡單方法

我們只需要執行以下命令:

1
sudo nano /etc/ssh/sshd_config.d/10-custom-port.conf

在這個命令中,檔案名稱部分可以自由更改,但 .conf 是必須的。

輸入 Port 和選好的數字,例如 Port 42468

1
2
Port <number_from_1024_to_49151>
# e.g. Port 42468

然後保存:

Command /Ctrl + O, 再 Enter 保存。

Command /Ctrl + X, 退出 nano。

完成!接下來,請跳過「傳統方法」的部分。

傳統方法

輸入以下命令來開始修改設定檔:

1
sudo nano /etc/ssh/sshd_config

找到 Port, 並將其更改為:

1
2
Port <number_from_1024_to_49151>
# e.g. Port 42468

Command /Ctrl + O, 再 Enter 保存。

Command /Ctrl + X, 退出 nano。

傳統方法完成!請繼續往下閱讀。

錯誤檢查

不論你選擇簡單方法或傳統方法,我們都需要進行錯誤檢查:

請執行以下命令以檢查是否存在錯誤:

1
sudo sshd -t

如果沒有任何訊息出現,那麼就表示設定無誤。

若出現錯誤,由於我們之前已在 ~/ssh_backup/ 目錄下做了備份,因此可以取回備份並重新進行修改。

  1. 重啟 sshd 以使新的設定生效:
1
sudo systemctl restart sshd
  1. 請不要立即關閉目前的 Terminal, 我們需要確認是否能成功登入。

請在你的電腦(非伺服器)上開啟一個新的 Terminal, 嘗試登入,看看是否能夠無需密碼即可成功登入。

1
2
ssh -p <port_number> <username_of_new_acct>@<your_server_ip>
# e.g. ssh -p 42468 [email protected]

如果你曾經更改過密鑰的存放位置,你可能需要加上 -i 參數:

1
2
ssh -p <port_number> -i <path_of_private_key> <username_of_new_acct>@<your_server_ip>
# e.g. ssh -p 42468 -i $HOME/.ssh/blog_oldestdream [email protected]

成功登入即表示操作完成。

儲存設定檔,減少重複輸入

我們可以透過建立一個設定檔來儲存 IP、Port、用戶名等資訊,避免每次登入時都需要重新輸入。

ssh 的設定檔保存位置:

macOS 用家可以在自己的電腦上輸入:

1
2
echo $HOME/.ssh/
# e.g. /home/oldestdream/.ssh/

Windows 用家可以輸入:

1
2
echo $env:USERPROFILE\\.ssh\\
# e.g. C:\\Users\\oldestdream\\.ssh\\

在上述所顯示的路徑中,建立一個新的檔案名為 config,並將以下的內容複製進去,然後進行修改。

如果你沒有改用私鑰登入,可以刪掉 IdentityFile 這一行。

如果你沒有更改 SSH Port,可以刪掉 Port 這一行,或者輸入Port 22

1
2
3
4
5
Host <alias_of_this_host>
  HostName <your_server_ip>
  User <username_of_new_acct>
  IdentityFile <path_of_private_key>
  Port <port_number>

範例:

macOS: /home/oldestdream/.ssh/config

Windows: C:\\Users\\oldestdream\\.ssh\\config

1
2
3
4
5
Host blog
HostName 123.123.123.123
User oldestdream
IdentityFile ~/.ssh/id_ed25519
Port 42468

之後登入伺服器時,只需輸入以下的命令即可。

1
2
ssh <alias_of_this_host>
# e.g. ssh blog
comments powered by Disqus