:::
顯示具有 Linux 標籤的文章。 顯示所有文章

CentOS安裝fail2ban記事

布丁布丁吃布丁

CentOS安裝fail2ban記事

image 

fail2ban是Linux上的一個以Python寫成的套件,主要功用是當有人登入時使用的帳號密碼錯誤達到指定次數之後,就將該IP擋住一定時間。這個方法可以用來阻止嘗試以暴力法猜測帳號密碼的攻擊,而且可以避免伺服器被DDoS(分散式阻斷服務攻擊)

然而我在安裝fail2ban的過程十分不順利,不像大部分網頁寫得如此輕鬆,我不確定是哪裡出了問題,但是現在我終於讓fail2ban順利運作了。

以下先做一些雜談,然後再來敘述整個安裝過程。


為什麼伺服器的SSH服務需要fail2ban?

現今Linux的管理工具以SSH為主,預設的連接埠是22、允許root可以登入、每次連線都可以嘗試5次錯誤。這個意思是,只要有心人以這個設定不斷地去做SSH連線,總有一天可以猜到你的root密碼,進而取得伺服器的終極管理權。

我之前的伺服器換過連接埠、也禁止root登入(透過修改/etc/ssh/sshd_config的Port設定跟PermitRootLogin no設定),但很遺憾的,它還是被駭客入侵了。不僅修改了我的SSH設定,也把防火牆全部清得一乾二淨,整臺伺服器變成了殭屍伺服器。我對於自己的天真感到非常慚愧,也深深地體會到光是改連接埠跟禁止root登入是不夠的。

fail2ban是搭配Linux的防火牆套件iptables一起運作。當有人猜測密碼達到預設的6次時,就在iptables中設定阻擋他的IP,讓他連連線都連不進來、無法繼續猜測密碼。預設的阻擋時間為10分鐘,更徹底一點可以讓登入失敗的人永遠都進不來。

fail2ban還可以用來阻擋FTP、Apache等其他需要登入的軟體,不過我的伺服器仍是以SSH連線為主,此篇也主要是講如何用fail2ban來強化SSH連線的安全。


安裝環境

Linux發行套件差異非常大,安裝、設定方式也有相當多的不同,敘述安裝的環境是非常重要的一件事情。

  • 發行版本:CentOS Linux release 6.0 (Final)
    這是RedHat系列的發行版本,與Fedora同系。
    (發行版本的資料會記錄在 /etc/redhat-release
  • yum.noarch 3.2.27-14.el6.centos @anaconda-centos-201106051823.i386/6.0
    CentOS的套件安裝主要是以yum為主。在此也是以yum來安裝fail2ban。他會在安裝fail2ban時自動安裝所相依的相關套件,例如python、tcpwrappers等,在此就不列出那些相依套件。
  • fail2ban.noarch 0.8.4-27.e16 @atrpms
    fail2ban的版本。網路上相當多設定都有些分歧,早期似乎是主要將設定寫在fail2ban.conf裡面,但這個版本是寫在 jail.conf 為主。稍後會講到設定的細節。
  • gamin.i686 0.1.10-9.el6 @anaconda-centos-201106051823.i386/6.0
    執行fail2ban的額外必要元件之一。
SSH環境

這個伺服器調整過SSH設定,SSH的連接埠改成了64022。請記住你修改過的SSH連接埠號碼,這在稍後設定fail2ban的時候會用到。


fail2ban的安裝與設定

接下來就要進入fail2ban的安裝與設定手續了。以下步驟都是以root帳戶的身分進行喔。

1. 用yum安裝fail2ban
1-1. 安裝fail2ban

利用yum安裝fail2ban的指令如下:

[root@server ~]# yum -y install fail2ban

yum會列出與fail2ban所有相依套件,並直接確認安裝。如果你想要一一確認哪些套件是否要安裝,請省略 -y 參數。

yum安裝的歷程會記錄在 /var/log/yum 中。如有需要確認已安裝的套件,可以回頭查詢這個記錄檔。

1-2. 設定套件庫atrpms

如果上述步驟不能安裝fail2ban、yum顯示找不到該套件的時候,你需要進入這個步驟。

yum會掃描套件庫來決定要如何安裝套件。然而由於fail2ban並不在預設的套件庫中,所以我們必須手動加入含有fail2ban的套件庫atrpms。

請編輯 /etc/yum.repos.d/CentOS-Base.repo

[root@server ~]# vim /etc/yum.repos.d/CentOS-Base.repo

在最後加入以下設定:

[atrpms]
name=Red Hat Enterprise Linux $releasever - $basearch - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable
gpgkey=http://ATrpms.net/RPM-GPG-KEY.atrpms
gpgcheck=1
enabled=1

這樣就可以利用1-1的語法來安裝fail2ban了。

2. 設定fail2ban

fail2ban的設定檔都在 /etc/fail2ban/ 目錄中,主要有兩個檔案:fail2ban.confjail.conf。以下各別說明需要設定的部份。

2-1. 設定fail2ban.conf

fail2ban.conf的位置在 /etc/fail2ban/fail2ban.conf 當中,請以以下指令開啟:

[root@server ~]# vim /etc/fail2ban/fail2ban.conf

這個設定檔需要調整的部份不多,請修改 logtarget 的參數如下:

#預設的參數
#logtarget = SYSLOG
#調整後的參數
logtarget = /var/log/fail2ban.log

這樣子fail2ban在執行時就會將記錄檔記錄到 /var/log/fail2ban.log 中。

在其他發行版本裏,似乎可以用預設的SYSLOG參數讓fail2ban記錄到指定位置,但是在CentOS中則需要手動指定絕對位置才行。

2-2. 設定jail.conf的backend

fail2ban主要的設定檔是jail.conf,位於 /etc/fail2ban/jail.conf 當中,請以以下指令開啟:

[root@server ~]# vim /etc/fail2ban/jail.conf

jail.conf需要設定的地方頗多,這邊我分成兩個部分來講解。首先先找到 [DEFAULT] 開頭的區塊,並找到backend參數進行設定:

#預設的參數
#backend = auto
#調整後的參數
backend = gamin

我原本使用預設的參數backend = auto,但是這樣fail2ban無法正常啟動。根據Fail2ban的說明,Fedora系的發行版本(包括此篇使用CentOS)如果在記錄中發現了「 fail2ban.comm   : WARNING Invalid command: ['add', 'ssh-iptables', 'auto'] 」錯誤訊息,那就得將backend參數從預設的 auto 改成 gamin

gamin是Linux的套件之一。你可以用yum來安裝它,指令如下:

[root@server ~]# yum -y install gamin

2-3. 設定jail.conf的[ssh-iptables]區塊

位於jail.conf中的 [ssh-iptables] 是用iptables來阻擋SSH嘗試錯誤連線的設定。以下我先列出我的設定,然後再來講述要修改的參數:

[ssh-iptables]
#是否啟用
enabled = true
#過濾名稱,使用預設的即可
filter = sshd
#iptables設定
action = iptables[name=SSH, port=64022, protocol=tcp]
#發生阻擋時的寄信設定
sendmail-whois[name=SSH, dest=pulipuli.chen@gmail.com, sender=root@server.nccu.edu.tw]

#需要掃描的記錄檔
logpath = /var/log/secure
#最高嘗試錯誤次數
maxretry = 2
#阻擋的時間,-1表示永久阻擋
bantime = -1

其中,跟預設值不一樣、需要調整的參數如下:

  • action中的port:預設值是 ssh ,也就是22。但是由於我修改的伺服器的SSH設定,目前的連接埠是64022,所以在此要設定為64022
  • sendmail-whois中的dest:預設是寄到 root ,也就是本機端的root帳戶的信箱。但是由於我並不是常常登入到此伺服器檢查root信箱,這個設定比較沒有意義,所以在此我設定為我自己的信箱位置。當fail2ban啟動、關閉、發生阻擋的時候,它都會寄通知信到這個位置。
  • sendmail-whois中的sender:這個設定會顯示在寄信的來源位置,預設是 fail2ban@mail.com 。為了辨識這個通知是來自於哪一台伺服器,在此最好給予它一個明確的名稱,包括這台伺服器的Domain Name跟目前執行fail2ban的帳戶,例如 root@server.nccu.edu.tw
  • logpath:預設值是 /var/log/sshd.log 。每個Linux發行版的SSH服務記錄登入訊息的位置都不太一樣,CentOS是將登入訊息記錄在 /var/log/secure 中,因此參數必須設置成此路徑。
  • maxretry:最高嘗試錯誤次數。一旦登入錯誤超過這個次數,fail2ban就會發生阻擋事件,將該IP擋在門外。預設是使用 [DEFAULT] 區塊中的maxretry = 5,在此我設定是更為嚴謹的 2。實際上,嘗試登入時可以比maxretry還多一次,例如maxretry = 5,那麼登入時可以錯誤6次才會被擋下。
  • bantime:發生阻擋事件之後,阻擋該IP的時間。預設是用 [DEFAULT] 區塊中的 bantime = 600,單位是秒,也就是10分鐘。但是這個阻擋時間實在太短,有人設定為 86400,也就是一整天。在此我設定為更嚴謹的 -1 ,表示永久阻擋。

jail.conf裡面還有許多其他服務的設定,但是預設都是關閉的,只有ssh-iptables預設開啟。如果你想利用fail2ban阻擋ftp、apache之類的嘗試登入攻擊,那麼你可以修改jail.conf的設定來達成這些目的。但是由於每個Linux發行版本都有所差異,因此參數設定都有些許不同,其他的服務就請上網找尋別人的討論吧。

2-4. 讓fail2ban重新啟動時不會重設阻擋IP規則

在預設的設定中,fail2ban每次重新啟動時都會遺忘被阻擋的IP設定。舉例來說,如果我的電腦因為登入失敗被fail2ban擋掉,那麼只要fail2ban重新啟動,那麼我的電腦又可以繼續去嘗試登入伺服器。

如果要讓fail2ban重新啟動時,不會重設阻擋的IP規則,則可以參考Vinnie Vedi的作法,修改 /etc/init.d/fail2ban 的內容。

修改的指令如下:

[root@server ~]# vim /etc/init.d/fail2ban

首先先找到start()的區塊,加入以下紅字的設定:

start() {
echo -n $"Starting fail2ban: "
getpid
if [ -z "$pid" ]; then
rm -rf /var/run/fail2ban/fail2ban.sock # in case of unclean shutdown
$FAIL2BAN -x start > /dev/null
RETVAL=$?
fi
if [ $RETVAL -eq 0 ]; then
touch /var/lock/subsys/fail2ban
echo_success
/sbin/service iptables restart # reloads previously banned ip's
else
echo_failure
fi

echo
return $RETVAL
}

再來找到stop()區塊,加入以下紅字的設定:

stop() {
echo -n $"Stopping fail2ban: "
getpid
RETVAL=$?
if [ -n "$pid" ]; then
/sbin/service iptables save # saves banned ip's
$FAIL2BAN stop > /dev/null
sleep 1
getpid
if [ -z "$pid" ]; then
rm -f /var/lock/subsys/fail2ban
echo_success
else
echo_failure
fi
else
echo_failure
fi
echo
return $RETVAL
}

這樣就大功告成了。

3. 設定fail2ban開機順序

網路上大部分的說法,都是使用 chkconfig 指令來將fail2ban加入開機自動啟動的設定之中。語法如下:

[root@server ~]# chkconfig --add fail2ban

設定好之後可以重開機測試看看,指令如下:

[root@server ~]# reboot

以下額外講述我在找尋fail2ban設定時,別人遇到的兩種無法正常啟動fail2ban情況:

fail2ban開啟順序必須在iptables之後

由於fail2ban是設定iptables以實作阻擋的功能,所以fail2ban必須比iptables更晚啟動。預設安裝的情況的確是如此運作。

有時候,有人會將iptables防火牆的規則寫在 /etc/rc.local,這是開機時最後執行的指令檔。而這些規則會蓋掉開機時fail2ban的設定。hondap遇到了這種情況,並提出了修改開機順序的方法,但是我覺得並不是很妥當。

我認為iptables的規則不應該寫在/etc/rc.local當中,而應該用以下指令來永久儲存iptables的規則檔:

[root@server ~]# /etc/init.d/iptables save

詳請請看鳥哥的iptables教學

Ubuntu無法正常開啟fail2ban的問題

使用Ubuntu系的使用者可能會遇到開機無法正常啟動fail2ban的問題,這是由於 /var/run/fail2ban/ 目錄在重開機的過程中被移除掉而導致fail2ban無法正常啟動的緣故。詳細的處理方法請看TECH BLOG的Fail2ban does not start after reboot這篇。

4. 啟動fail2ban

啟動fail2ban的語法如下:

[root@server ~]# service fail2ban start

如果你的service指令無法順利運作,也可以利用以下指令啟動fail2ban:

[root@server ~]# /etc/init.d/fail2ban start

需要注意的是,每次fail2ban的關閉、啟動,都會洗掉之前被阻擋的IP設定。舉例來說,如果我的電腦因為登入失敗被fail2ban擋掉,那麼只要fail2ban重新啟動,那麼我的電腦又可以繼續去嘗試登入伺服器。要保留fail2ban阻擋的IP規則的話,請參考2-4的方法修改 /etc/init.d/fail2ban

5. 檢查fail2ban是否運作

檢查fail2ban是否正常運作的方法有許多種,在此舉出三種:一種是用status指令檢查fail2ban的運作狀況,一種是檢查log記錄檔,最後一種則是觀察iptables的設定。

5-1. 檢查fail2ban的stauts

檢查fail2ban的狀態指令如下,而指令後面是正常狀態下的回應訊息:

[root@server ~]# service fail2ban status
Fail2ban (pid 1106) is running...
Status
|- Number of jail: 1
`- Jail list: ssh-iptables

其中 Number of jail: 1 這個訊息指出了我們在上面設定的一個阻擋規則:ssh-iptables,表示我們的設定正確,而fail2ban也有正常運作。

相反的,如果發生了 ERROR  Unable to contact server. Is it running? 錯誤訊息,那麼請依照Fail2ban的FAQ指示一一檢查吧。

5-2. 檢查fail2ban.log的記錄

如果你在上面的2-1步驟中設定了 /etc/fail2ban/fail2ban.conf ,並且正常啟動fail2ban,那麼應該可以找到 /var/log/fail2ban.log 這個檔案。

開啟指令如下:

[root@server ~]# vim /var/log/fail2ban.log

如果正常開啟的話,裡面會有記載以下資料(時間日期會有所不同):

2011-07-20 01:25:46,776 fail2ban.server : INFO   Changed logging target to /var/log/fail2ban.log for Fail2ban v0.8.4
2011-07-20 01:25:46,791 fail2ban.jail : INFO Creating new jail 'ssh-iptables'
2011-07-20 01:25:46,820 fail2ban.jail : INFO Jail 'ssh-iptables' uses Gamin
2011-07-20 01:25:46,955 fail2ban.filter : INFO Added logfile = /var/log/secure
2011-07-20 01:25:46,956 fail2ban.filter : INFO Set maxRetry = 2
2011-07-20 01:25:46,961 fail2ban.filter : INFO Set findtime = 600
2011-07-20 01:25:46,962 fail2ban.actions: INFO Set banTime = -1
2011-07-20 01:25:47,117 fail2ban.jail : INFO Jail 'ssh-iptables' started

相反的,如果fail2ban沒有正常啟動,那麼也可以檢查這個記錄檔,找找看有什麼問題。

5-3. 檢查iptables的規則

如果fail2ban有正常啟動的話,它應該會在iptables中加入fail2ban設定的規則。

觀察iptables規則的指令與結果如下:

[root@server ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
fail2ban-SSH tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:64022

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain fail2ban-SSH (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0

標示紅字的部分是fail2ban加入的規則,這條規則是根據上述2-3裏在jail.conf的[ssh-iptables]的action參數來設定的。

規則會將所有來源IP、目的IP的tcp封包,指定目的連接埠64022的封包轉移到fail2ban-ssh規則鏈(Chain)中,未來如果要阻擋某個指定IP,fail2ban會將阻擋的規則加入fail2ban-SSH規則鏈中。


實際操作fail2ban與應用

安裝與設定完fail2ban之後,接下來就是要測試看看它能不能正常運作。同時我也補充一些其他fail2ban教學比較少講的清除阻擋的方法,以及將要阻擋的IP永久加入iptables防火牆的方法。

5. 測試fail2ban

fail2ban的指令操作大部分可以靠 fail2ban-client 來進行。

5-1. 初始狀態

首先我們先看一下fail2ban中阻擋SSH連線的ssh-iptables的狀態:

[root@server ~]# fail2ban-client status ssh-iptables
Status for the jail: ssh-iptables
|- filter
| |- File list: /var/log/secure
| |- Currently failed: 0
| `- Total failed: 0
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 0

上面的訊息表示目前沒有任何IP被阻擋。

5-2. 登入錯誤

接著我在某台電腦利用PieTTY進行SSH連線登入,故意輸入錯誤的帳號與密碼。

2011-07-20_105103 登入錯誤(mask2)

由於我們設定maxretry = 2,所以當錯誤輸入第三次時,這台電腦就被擋下來了。而且錯誤訊息是「Network error: Software caused connection abort」,而不是SSH的登入錯誤訊息。

5-3. 阻擋之後的狀態
[root@server ~]# fail2ban-client status ssh-iptables
Status for the jail: ssh-iptables
|- filter
| |- File list: /var/log/secure
| |- Currently failed: 0
| `- Total failed: 2
`- action
|- Currently banned: 1
| `- IP list: 140.***.***.***
`- Total banned: 1

從狀態中可以看到,剛剛連線的IP已經被列入阻擋項目中。

5-4. 通知信

2011-07-20_111122 gmail (mask)

由於我們在2-3中設置了 sendmail-whois 參數,讓fail2ban在發生阻擋時自動寄送通知信,所以測試中被阻擋的電腦資訊就會自動地寄到我的信箱,如上圖。

fail2ban寄來的信件中,主旨都會以 [Fail2Ban] 開頭,因此可以搭配Gmail的篩選器(filter)功能來管理這些郵件。

6. 清除fail2ban的阻擋

如果有管理者手滑輸入錯誤密碼而被fail2ban擋住,那麼可以透過以下方法來刪除被fail2ban阻擋的IP。

假如來源IP「140.119.1.110」是正常的使用者,而他不小心被fail2ban阻擋了。那麼你應該可以在iptables看到fail2ban加入的阻擋規則(藍字是規則鏈名稱紅字是IP):

[root@server ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
fail2ban-SSH tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:64022

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain fail2ban-SSH (1 references)
target prot opt source destination
DROP all -- 140.119.1.110 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0

我們可以用iptables的語法來刪除被阻擋的IP:

[root@server ~]# iptables -D fail2ban-SSH -i eth0 –s 140.119.1.110 -j DROP

其中,fail2ban是規則鏈(Chain)的名稱,請看上面iptables規則訊息中的藍字;紅字的140.119.1.110就是你要刪除的IP。(感謝網友提醒,原本誤寫為-d,表示目標,應該改成-s才對)

需要注意的是,就算用iptables的語法刪除了被阻擋的IP,這個IP依舊會在fail2ban的狀態中留下記錄喔。

網卡代號eth0

如果你有多張網卡,而你設定iptables防火牆阻擋的網卡並不是第一張的「eth0」,那麼你可能需要修改一下這張網卡的參數。關於iptables防火牆詳細的設定教學,請參考鳥哥的網站

7. 重設fail2ban的狀態

只要重新啟動fail2ban就能重置狀態的記錄。

重新啟動fail2ban的語法是:

[root@server ~]# service fail2ban restart

需要注意的是,如果你沒有做過上述2-4的動作、修改 /etc/init.d/fail2ban 的話,那麼在重新啟動fail2ban的時候,被阻擋的IP規則也會一併被清除,這樣該IP又能夠再次嘗試登入你的伺服器了。

8. 在iptables設定永久阻擋的IP

當有人時常要嘗試登入你的伺服器,而多次被fail2ban阻擋在外時,你可以將該IP設定到iptables防火牆的規則中,讓他永久被阻擋在外。

詳細的設定可以參考鳥哥的iptables教學,在此我僅介紹在iptables中加入與刪除阻擋指定IP的語法。舉例來說,「213.131.252.251」這個IP老是要嘗試登入我的伺服器,而我主要的連線網卡代號是「eth0」,那麼我可以設定以下規則,把它永久阻擋在外:

[root@server ~]# iptables -A INPUT -i eth0 -s 213.131.252.251 -j DROP
[root@server ~]# iptables -A INPUT -i eth0 -d 213.131.252.251 -j DROP

如果想要刪除誤加的規則的話,請將 -A 改成 -D,其他語法相同:

[root@server ~]# iptables -D INPUT -i eth0 -s 213.131.252.251 -j DROP
[root@server ~]# iptables -D INPUT -i eth0 -d 213.131.252.251 -j DROP

題外話,「213.131.252.251」就是上次攻擊我伺服器的駭客電腦,這是真的建議要擋掉的一個IP啊!


結語

雖然目前不知道fail2ban是否真的能夠抵擋駭客的攻擊,但是我覺得這是非常重要的一個套件,也希望架設Linux伺服器的網管人員最好都幫你的伺服器安裝一下。

(more...)