介紹
SSH是連接雲伺服器的事實標準方法。它堅固耐用,而且是可擴展的 — 當新的加密標準被開發時,它們可以用來生成新的SSH密鑰,確保核心協議保持安全。然而,沒有協議或軟件堆棧是完全防不勝防的,SSH在互聯網上被廣泛部署意味著它代表著一個非常可預測的攻擊面或攻擊向量,通過這個向量人們可以嘗試獲得訪問權限。
任何暴露在網絡中的服務都可能以這種方式成為目標。如果您審查一下運行在任何廣泛流量伺服器上的SSH服務的日誌,您往往會看到重複的、系統化的登錄嘗試,這代表著用戶和機器人一樣的暴力攻擊。儘管您可以對SSH服務進行一些優化,以減少這些攻擊成功的機會接近於零,比如禁用密碼驗證,改用SSH密鑰,但它們仍然可能構成輕微的持續性責任。
對於完全無法接受此風險的大規模生產部署,通常會在其SSH服務器前部署VPN,例如WireGuard,以便從外部互聯網無法直接連接到默認的SSH端口22,除非有額外的軟件抽象或閘道。這些VPN解決方案廣受信任,但會增加複雜性,可能會破壞一些自動化或其他小型軟件鉤子。
在全面採用VPN設置之前或之後,您可以實施一個名為Fail2ban的工具。Fail2ban通過創建規則來自動更改您的防火牆配置,以在一定次數的失敗登錄嘗試後禁止特定IP,從而顯著減輕暴力攻擊的影響。這將使您的服務器能夠在不需要您介入的情況下加強自身防禦這些訪問嘗試。
在本指南中,您將了解如何在Ubuntu 20.04服務器上安裝和使用Fail2ban。
先決條件
要完成本指南,您將需要:
-
一台Ubuntu 20.04服務器和一個具有sudo特權的非root用戶。您可以在我們的使用Ubuntu 20.04進行初始服務器設置指南中了解有關如何設置具有這些特權的用戶的更多信息。
-
可選地,第二台伺服器,您可以從中連接到第一台伺服器,並用於測試是否被故意封鎖。
步驟1 — 安裝Fail2ban
Fail2ban可在Ubuntu的軟體庫中找到。首先以非root用戶身份運行以下命令來更新您的套件清單並安裝Fail2ban:
安裝完Fail2ban後,它將自動設置一個後台服務。但是,它默認情況下是禁用的,因為其某些默認設置可能會引起不希望的效果。您可以使用systemctl
命令來驗證這一點:
Output○ fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled
Active: inactive (dead)
Docs: man:fail2ban(1)
您可以立即啟用Fail2ban,但首先您將查看一些其功能。
步驟2 — 配置Fail2ban
fail2ban服務將其配置文件保存在/etc/fail2ban
目錄中。有一個名為jail.conf
的默認文件。轉到該目錄並使用head -20
打印該文件的前20行:
Output#
# 警告:在0.9.0版本中進行了大量重構。請審查並
# 自定義設置以適應您的設置。
#
# 更改:在大多數情況下,您不應該修改此
# 文件,而應在jail.local文件中提供自定義設置,
# 或在jail.d/目錄下提供單獨的.conf文件,例如:
#
# 啟用JAIL的方法:
#
# 您不應該修改此文件。
#
# 它可能會在發行版更新中被覆蓋或改進。
#
# 在jail.local文件或jail.d/customisation.local文件中提供自定義。
# 例如,要更改所有JAIL的默認封鎖時間並啟用
# ssh-iptables JAIL,則以下(未註釋的)將出現在.local文件中。
# 請參閱man 5 jail.conf了解詳細信息。
#
# [DEFAULT]
正如您所看到的,此文件的前几行被注释了 – 它们以#
字符开头,表示它们应被视为文档而不是设置。 此外,您还会看到,这些注释指示您不要直接修改此文件。 相反,您有两个选项:要么在jail.d/
目录中创建多个Fail2ban的单独配置文件,要么创建并收集所有本地设置到一个jail.local
文件中。 jail.conf
文件将定期更新,就像Fail2ban本身一样更新,并将用作您尚未创建任何覆盖的默认设置的源。
在本教程中,您将创建jail.local
。 您可以通过复制jail.conf
来执行此操作:
现在您可以开始进行配置更改。 使用nano
或您喜欢的文本编辑器打开文件:
当您浏览文件时,本教程将审查一些您可能想要更新的选项。 位于文件顶部附近[DEFAULT]
部分下的设置将应用于Fail2ban支持的所有服务。 文件中的其他位置有[sshd]
和其他服务的标题,其中包含将覆盖默认设置的特定于服务的设置。
[DEFAULT]
. . .
bantime = 10m
. . .
bantime
参数设置了客户端在认证失败时被禁止的时间长度。 这是以秒为单位进行计量的。 默认情况下,此设置为10分钟。
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .
下面兩個參數是findtime
和maxretry
。它們共同確定了在何種條件下客戶端被認定為非法使用者並應該被封禁。
變數maxretry
設置了在findtime
定義的時間窗口內,客戶端可以嘗試驗證的次數,在被封禁之前。使用默認設置,fail2ban服務將在10分鐘的窗口內,如果客戶端連續5次嘗試登錄失敗,就會封禁該客戶端。
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .
如果您需要在Fail2ban採取行動時收到電子郵件提醒,您應該評估destemail
、sendername
和mta
設置。參數destemail
設置了應該接收封禁消息的電子郵件地址。sendername
設置了電子郵件中“From”字段的值。mta
參數配置了用於發送郵件的郵件服務。默認情況下,這是sendmail
,但您可能想使用Postfix或其他郵件解決方案。
[DEFAULT]
. . .
action = $(action_)s
. . .
此參數配置了Fail2ban在想要實施封禁時採取的操作。值action_
在此參數之前的文件中定義。默認操作是更新您的防火牆配置以拒絕來自有問題主機的流量,直到封禁時間過期。
默認提供了其他action_
腳本,您可以將$(action_)
替換為上述的:
…
# 封禁並發送一封帶有 whois 報告的電子郵件至目標郵箱。
action_mw = %(action_)s
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
# 封禁並發送一封帶有 whois 報告和相關日誌行的電子郵件
# 到目標郵箱。
action_mwl = %(action_)s
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
# 請參閱 action.d/xarf-login-attack 中的重要注意事項,以決定何時使用此操作
#
# 封禁並發送一封帶有 IP 地址濫用聯繫人的 xarf 電子郵件,並包括相關日誌行
# 到目標郵箱。
action_xarf = %(action_)s
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
# 封禁 CloudFlare 上的 IP 並發送一封帶有 whois 報告和相關日誌行的電子郵件
# 到目標郵箱。
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…
例如,action_mw
執行操作並發送電子郵件,action_mwl
執行操作,發送電子郵件並包括記錄,action_cf_mwl
除了執行以上操作外,還向與您帳戶關聯的 Cloudflare API 發送更新以在那裡封禁違規者。
個別監獄設置
接下來是處理個別服務的配置文件部分。這些由節標題指定,如 [sshd]
。
需要在標題下添加一行 enabled = true
以啟用這些節,以及其他設置。
[jail_to_enable]
. . .
enabled = true
. . .
默認情況下,SSH服務已啟用,其他所有服務均已禁用。
此處設置的其他一些設置包括將用於決定日誌中的一行是否表示身份驗證失敗的filter
以及告訴fail2ban該特定服務的日誌位於何處的logpath
。
filter
值實際上是對位於/etc/fail2ban/filter.d
目錄中的文件的引用,其.conf
擴展名已被移除。這些文件包含正則表達式(用於文本解析的常見縮寫),用於確定日誌中的一行是否是身份驗證失敗嘗試。在本指南中,我們不會深入探討這些文件,因為它們相當復雜,預定的設置與適當的行匹配得很好。
但是,您可以通過查看該目錄來查看可用的過濾器類型:
如果您看到一個與您正在使用的服務相關的文件,您應該使用文本編輯器打開它。大多數文件都有相當良好的注釋,您應該至少能夠了解腳本設計用於防禦的條件類型。這些過濾器的大多數在jail.conf
文件中具有適當的(已禁用)部分,如果需要,我們可以在jail.local
文件中啟用它們。
例如,假設您正在使用 Nginx 來提供網站,並且意識到您網站中的一個受密碼保護的部分正遭受到大量的登錄嘗試。您可以告訴 fail2ban 使用 nginx-http-auth.conf
文件來在 /var/log/nginx/error.log
文件中檢查此情況。
實際上,這已經在您的 /etc/fail2ban/jail.conf
文件中的一個名為 [nginx-http-auth]
的部分中設置好了。您只需要添加 enabled
參數:
. . .
[nginx-http-auth]
enabled = true
. . .
編輯完成後,保存並關閉文件。此時,您可以啟用 Fail2ban 服務,以便從現在開始自動運行。首先,執行 systemctl enable
:
然後,使用 systemctl start
首次手動啟動它:
您可以使用 systemctl status
驗證它是否正在運行:
Output● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab>
Active: active (running) since Tue 2022-06-28 19:29:15 UTC; 3s ago
Docs: man:fail2ban(1)
Main PID: 39396 (fail2ban-server)
Tasks: 5 (limit: 1119)
Memory: 12.9M
CPU: 278ms
CGroup: /system.slice/fail2ban.service
└─39396 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Jun 28 19:29:15 fail2ban20 systemd[1]: Started Fail2Ban Service.
Jun 28 19:29:15 fail2ban20 fail2ban-server[39396]: Server ready
在下一個步驟中,您將展示 Fail2ban 的運作。
步驟 3 — 測試封禁策略(可選)
從另一台伺服器,即將來將不需要登錄到您的 Fail2ban 伺服器的伺服器,您可以通過讓該第二台伺服器被封禁來測試這些規則。登錄到您的第二台伺服器後,嘗試通過 SSH 連接到 Fail2ban 伺服器。您可以嘗試使用不存在的名稱進行連接:
輸入隨機字符到密碼提示中。重複這個動作幾次。在某個時候,您收到的錯誤應該從權限被拒絕
變為連接被拒絕
。這表明您的第二台服務器已被Fail2ban服務器封禁。
在您的Fail2ban服務器上,您可以通過檢查iptables
輸出來查看新的規則。iptables
是一個用於與服務器上的低級端口和防火墻規則進行交互的命令。如果您遵循DigitalOcean的初始服務器設置指南,您將使用ufw
來管理更高級別的防火墻規則。運行iptables -S
將顯示ufw
已經創建的所有防火墻規則:
Output-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-N f2b-sshd
-N ufw-after-forward
-N ufw-after-input
-N ufw-after-logging-forward
-N ufw-after-logging-input
-N ufw-after-logging-output
-N ufw-after-output
-N ufw-before-forward
-N ufw-before-input
-N ufw-before-logging-forward
-N ufw-before-logging-input
-N ufw-before-logging-output
…
如果您將iptables -S
的輸出管道到grep
以在這些規則中搜索字符串f2b
,您可以看到fail2ban添加的規則:
Output-N f2b-sshd
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A f2b-sshd -s 134.209.165.184/32 -j REJECT --reject-with icmp-port-unreachable
-A f2b-sshd -j RETURN
包含REJECT --reject-with icmp-port-unreachable
的行將由Fail2ban添加,並應反映您第二台服務器的IP地址。
結論
您現在應該能夠配置一些對於您的服務的封禁策略了。Fail2ban 是保護任何使用身份驗證的服務的有用方式。如果您想了解更多關於 fail2ban 如何工作的信息,您可以查看我們關於fail2ban規則和文件如何工作的教程。
有關如何使用 fail2ban 來保護其他服務的信息,您可以閱讀有關如何在Ubuntu 14.04上使用Fail2Ban保護Nginx服務器和如何在Ubuntu 14.04上使用Fail2Ban保護Apache服務器的文章。
Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-20-04