我們這兩天監測到一位客戶的 VPS 持續維持 100% 的 CPU 利用率很長一段時間,然後昨天客戶向我們報告他的 VPS 無法登錄了,從我們這邊來看他的 VPS 正在運行,而且網絡也有反應,只不過 CPU 利用率滿負荷而已,VPSee 收到客戶消息的第一反應是客戶的 VPS 被 CC (Challenge Collapsar) 攻擊了,後來客戶告訴我們他沒有做網站,只是開了一些 shell 帳號供別人通過 ssh 使用,這有可能是其中某個帳號(被黑了以後)放了 fork 炸彈,這是非常簡單而且很常用的一類惡意程序,原理很簡單,就是通過不停的 fork 進程來達到消耗 Linux 系統所有資源的目的,使得系統無法(沒有資源)運行其他程序。比如被 fork 炸了以後,就會出現:
-bash: fork: retry: Resource temporarily unavailable
下面就是一個最簡單的 bash fork 炸彈:
: () { : | : & } ; :
上面幾個符號看上去很復雜,其實如果寫成下面這個樣子就好懂了,: 是函數名,執行一個調用自己的遞歸並且 pipe 到自己,& 表示後台執行程序,最後的一個 : 是在函數外調用和執行 : () 這個函數的意思:
: () {
: | : &
}; :
如何避免 fork 炸彈呢?方法很簡單,只要限制每個用戶可以調用的進程數就可以避免,這個可以通過修改 vi /etc/security/limits.conf 文件來設定:
# vi /etc/security/limits.conf
vpsee hard nproc 32
@student hard nproc 32
@faculty hard nproc 64
上面的配置文件意思是說限制 vpsee 這個用戶只能 fork 32 個進程;然後限制 student 這個用戶組的每個成員最多能 fork 32 個進程;限制 faculty 這個用戶組的每個成員最多能 fork 64 個進程。不過要事先檢查系統是否有 pam_limits.so 這個模塊以及是否已經加載:
# ls /lib64/security/pam_limits.so
/lib64/security/pam_limits.so
# vi /etc/pam.d/login
session required pam_loginuid.so
如果自己是 Linux 普通用戶,不是 root 用戶不能修改 limits.conf 和重啟系統的話,可以用 ulimit 來臨時限制自己允許創建的進程數,ulimit 有 Hard 和 Soft 兩種方法限制,用 Hard 的話可以減少最大可用的進程數,但是就不能重新增大這個限制了;用 Soft 的話可以自己自由增大和減小限制(ulimit,-H 和 -S 的詳細說明可以參看 man ulimit)。不同的 Linux 版本對這個 ulimit -u 的默認值不同,在 CentOS 上默認情況下最大運行進程數是 8256,在 Fedora 上是 1024,所以這個要看不同的發行版本,不過這個無所謂,反正可以改,不過改成32後就不能再改成比32更大的了(比如64),只能再改成比32小的,ulimit 不帶 -H 和 -S 參數的時候同時設置 Hard 和 Soft:
$ ulimit -u
8256
$ ulimit -u 32
$ ulimit -u 64
-bash: ulimit: max user processes: cannot modify limit: Operation not permitted
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 8256
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
12下一頁