今天看到一个命令 {:|:}
,初看不知其解,后来看了下是 Linux下的ForkBomb
这个命令Jaromil在2002年设计了最为精简的一个Linux Fork炸弹,整个代码只有13个字符,在shell中运行后几秒后系统就会宕机,完整命令:
:(){:|:&};:
我们把它展开
:() #下面要定义一个函数,函数名为小数点,没有可选参数。
{ #函数体开始
:|:& #首先它递归调用本函数,然后利用管道调用一个新进程(它要做的事情也是递归调用本函数),并将其放到后台执行
} #函数体结束
; #这段程序包含两个部分,首先定义了一个函数,然后调用这个函数
: #表示调用本函数
因为shell中函数可以省略function关键字,所以上面的十三个字符是功能是定义一个函数与调用这个函数,函数的名称为:,主要的核心代码是:|:&,可以看出这是一个函数本身的递归调用,通过&实现在后台开启新进程运行,通过管道实现进程呈几何形式增长,最后再通过:来调用函数引爆炸弹.因此,几秒钟系统就会因为处理不过来太多的进程而死机,解决的唯一办法就是重启
Fork炸弹带来的后果就是耗尽服务器资源,使服务器不能正常的对外提供服务,也就是常说的DoS(Denial of Service)。与传统1v1、通过不断向服务器发送请求造成服务器崩溃不同,Fork炸弹有种坐山观虎斗,不费一兵一卒斩敌人于马下的感觉。而且这个函数是不需要root权限就可以运行的。
预防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
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
这样就可以预防fork炸弹了