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 重啟的話次數會重新計算)