強化 SSH 登入系統

強化 SSH 登入系統的安全性教學。

SSH 對於遠端主機來說是為數不多的主要登入窗口,一旦被攻破基本上等於整台主機都在別人的掌控下,做好其安全防護的重要性自然不用再多說。

禁用 ROOT 登入

要登入 ssh 最起碼需要使用者名稱密碼或金鑰,而每個 linux 一定都會有 root,對攻擊者來說 root 就是最好的測試入口。

新增 sudo 使用者

在禁止 root 前需要新增一個使用者來代替 root 登入和操作,如果你已經有可以使用 sudo 的使用者那麼可以跳過這個步驟。

新增使用者

以 Debian/Ubuntu 為例

adduser 使用者名稱

adduser 會產生如下的結果:

Adding user `test' ... 
Adding new group `test' (1001) ...
Adding new user `test' (1001) with group `test' ...
Creating home directory `/home/test' ... 
Copying files from `/etc/skel' ...
New password:填入密碼
Retype new password:填入跟上面一樣的密碼
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
        Full Name []:留空即可
        Room Number []:留空即可
        Work Phone []:留空即可
        Home Phone []:留空即可
        Other []:留空即可
Is the information correct? [Y/n] y

打好密碼,資訊欄位可以選擇留空(直接按 Enter),最後確認輸入 y 即可

給予 sudo 權限

安裝 sudo ,如果已經可以使用 sudo 指令可以跳過

apt install sudo

將使用者加入 sudo 群組

usermod -aG sudo 使用者名稱

如此一來便新增了一個可以使用 sudo 的使用者。

SSH 設定

接下來要設定 ssh 禁止使用 root 登入

新增檔案 /etc/ssh/sshd_config.d/local.conf 並編輯

sudo vim /etc/ssh/sshd_config.d/local.conf

新增以下內容

PermitRootLogin no

修改好後儲存並重新啟動 sshd 服務

sudo systemctl restart sshd

如此一來即便密碼或金鑰正確也無法用 ssh 登入 root

用金鑰代替密碼登入

使用密碼具有較高的被暴力破解風險,尤其當你的密碼組成簡單喜歡使用單字、生日、手機號碼等常見資訊更是危險,因此應該使用更具安全性的加密演算法登入。

準備金鑰

ssh 支援多種不同加密方法產生的金鑰,這裡以 ssh-keygen 預設的 RSA 來說明,對其他加密有興趣的可以參考 選擇 SSH key 的加密演算法

使用 ssh-keygen 產生公私鑰

ssh-keygen -b 4096

如果不加參數 -b 預設會使用 2048 bits,一般建議長度最少2048,越短安全性越低。

ssh-keygen 會產生如下的結果:

Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\user/.ssh/id_rsa): Enter留空或輸入存放位置
Enter passphrase (empty for no passphrase): Enter留空或輸入密碼
Enter same passphrase again: Enter留空或重複輸入密碼
Your identification has been saved in C:\Users\user/.ssh/id_rsa.
Your public key has been saved in C:\Users\user/.ssh/id_rsa.pub.
  • 第一個選擇:
    Enter file in which to save the key (C:\Users\user/.ssh/id_rsa)
    意思是問你公私鑰要儲存在哪個位置,如果直接 Enter 留空儲存的位置會在括號內的預設路徑。使用預設位置有個好處,往後的 ssh 相關命令會自己套用公私鑰,不用再自己指定位置。

  • 第二個選擇:
    Enter passphrase (empty for no passphrase)
    要不要幫金鑰加上密碼: 如果按 Enter 留空則不會幫金鑰加上密碼,不加上密碼在登入時很方便,不用再打密碼一行 SSH 命令就可以搞定。加上密碼安全性較高,即便金鑰被偷了還需要知道密碼才能使用。

  • Enter same passphrase again:
    重複輸入確認密碼,如果不要密碼則依舊留空,如果要設置密碼則輸入跟剛剛一樣的密碼來確認。

使用後會產生 id_rsa 和 id_rsa.pub,分別為私鑰和公鑰。

添加公鑰到遠端主機

有兩種方法可以選擇:

1. 使用 ssh-copy-id (windows 不可用)

使用方法很簡單易行命令就可以完成

ssh-copy-id -i 公鑰位置 使用者名稱@遠端主機IP

如果公鑰生成在預設位置可以省略 -i 參數

以 ssh-copy-id -i test_rsa.pub user@remote_ip 示意

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "test_rsa.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
user@remote_ip's password: 輸入登入遠端主機的 SSH 密碼
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'user@remote_ip'"
and check to make sure that only the key(s) you wanted were added.

2. 手動添加(windows 可用)

其實 ssh-copy-id 做的事很簡單,我們也可以透過自己手動添加公鑰來達到相同功用。

創建 ~/.ssh/authorized_keys,如果已有可跳過創建步驟

ssh 登入要使用金鑰的使用者

ssh 使用者名稱@遠端主機IP

在要登入的使用者家目錄底下生成目錄 .ssh,確保其權限為 700 (drwx---)

mkdir -m 700 ~/.ssh

將公鑰內容(剛剛在本地端生成的 id_rsa.pub,其實是個純文字檔) 寫入遠端主機的 ~/ssh/authorized_keys

vim ~/.ssh/authorized_keys

將公鑰內容完整複製後儲存並關閉。

確保 ~/.ssh/authorized_keys 權限為 600 (-rw---)

chmod 600 ~/.ssh/authorized_keys

如此一來就完成了手動添加公鑰的流程。

測試金鑰登入

在修改 ssh 設定前先確保可以使用金鑰登入,免得到時把自己鎖在門外。

ssh -i 私鑰位置 使用者名稱@遠端主機IP

如果私鑰生成在預設位置可以省略 -i 參數

可以成功登入代表設置都正確,可以安心執行下一步驟。

SSH 設定

接下來要設定 ssh 禁止使用密碼登入

修改 /etc/ssh/sshd_config.d/local.conf

sudo vim /etc/ssh/sshd_config.d/local.conf

新增以下內容

PasswordAuthentication no

修改好後儲存並重新啟動 sshd 服務

sudo systemctl restart sshd

如此一來便不能使用密碼登入 ssh

修改 Port

ssh 的預設使用 port 22,這個資訊跟 linux 都有 root 帳號一樣是大家都知道的。雖然真的有心攻擊的人掃一下就找的到,不過卻能抵擋來自網路各處隨意攻擊的資源消耗。

SSH 設定

這裡假設修改 Port 為 12345

修改 /etc/ssh/sshd_config.d/local.conf

sudo vim /etc/ssh/sshd_config.d/local.conf

新增以下內容(Port 修改為 (請將 12345 修改為自己想要的 port number)

Port 12345

設定 SELinux

在 RHEL 類的系統預設啟用 SELinux,而 SELinux 預設只允許 SSH 使用 port 22。(如果沒有 SELinux 可以跳過這步驟)

添加 ssh 可使用的 port (請將 12345 修改為自己想要的 port number)

sudo semanage port -a -t ssh_port_t -p tcp 12345

設定防火牆

如果系統有裝防火牆要注意是否會拒絕你設定 port 的向內流量

這裡以預設會擋掉向內流量的 firewalld 為例

允許特定 port 的向內流量 (請將 12345 修改為自己想要的 port number)

sudo firewall-cmd --permanent --zone=public --add-port=12345/tcp

firewalld 重新讀取設定

sudo firewall-cmd --reload

重新啟動 SSHD 服務

最後重新啟動 sshd

sudo systemctl restart sshd

重新啟動後便會監聽新設定的 port

以後登入記得要加上 -p 參數來使用自定義 port (請將 12345 修改為自己想要的 port number)

ssh 使用者名稱@遠端主機IP -p 12345

使用 Fail2ban

fail2ban 是一個很好抵禦暴力破解的工具,使用在 sshd 上可以針對多次登入失敗的 IP 進行封鎖,此外還可以應用在多種其他服務上: ftp、mail、nginx等,使用起來非常簡單。

安裝

debian/ubuntu

sudo apt install fail2ban

REHL 類

sudo yum install fail2ban

設定

fail2ban 有許多設定選項,像是監測的 log、ban 的時間、ban 的方法、郵件通知等等。許多預設值寫在 /etc/fail2ban/jail.conf 不過裡面設定沒有啟用任何監控服務,想要啟用服務或是修改設定可以選擇在 /etc/fail2ban/jail.d/ 資料夾底下新增 .local 或 .conf 檔來複寫設定。

以 debian/ubuntu 來說預設安裝後會有設定檔 defaults-debian.conf,內容如下:

[sshd]
enabled = true

其內容是最簡單啟用 sshd 防護的範本, 因此當 debian/ubuntu 的 fail2ban 服務啟動時預設會監控 sshd 服務,不想要麻煩更改設定也可以使用預設設定即可。

我們也可以自己編寫屬於自己的設定檔

sudo vim /etc/fail2ban/jail.d/ssh.local

添加如下內容(內容可以自訂,這邊參考即可)

[sshd]
enabled = true
# port = 12345
findtime = 300
maxretry = 5
bantime  = 3600</code></pre>
  • enable = true
    啟用服務,在 [sshd] 欄位下代表啟動 sshd 的監控任務

  • # port = 12345
    如果你的 ssh 使用預設 port 22,可以不用這項設定留著前面的註解 # 符號,如果有更改過記得保註解拿掉並且把 12345 修改為你設定的 port。

  • findtime = 300
    搜尋時間的範圍,單位為秒。

  • maxretry = 5
    最大可嘗試次數 5

  • bantime = 3600
    ban 的時間,單位為秒。

結合上面的 findtime、maxretry、bantime 意思即為在 5分鐘內嘗試登入失敗 5 次以上的 IP 禁止其往後 1 小時登入。當然還有很多可以設定的選項,想了解更多可以查看 /etc/fail2ban/jail.conf 的內容,裡面的註解做了很多說明。

啟用服務

設定完後啟動服務

sudo systemctl enable --now fail2ban

如果服務原先就啟動了記得使用 restart 重啟服務

sudo systemctl restart fail2ban

啟動好後可以使用 fail2ban-client 命令查看其狀態

sudo fail2ban-client status

產生出如下內容:

Status
|- Number of jail:      1
`- Jail list:   sshd

意思是正在監控 1 項服務
服務列表有 sshd

可以在更進一步顯示出監控 sshd 的狀態

sudo fail2ban-client status sshd

產生出如下內容:

|- Filter
|  |- Currently failed: 2
|  |- Total failed:     802
|  <code>- File list:        /var/log/auth.log </code>
`- Actions
   |- Currently banned: 0
   |- Total banned:     30
   `- Banned IP list:

可以看到 fail2ban 曾經擋過 30 組 IP ( fail2ban 重啟的話次數會重新計算)

Built with Hugo
Theme Stack designed by Jimmy