??? 好了,我現(xiàn)在讓大家就看看我們神秘僵尸進(jìn)程是什么樣子的?下面我來用c寫出父進(jìn)程建立子進(jìn)程的代碼:
/**********************************子進(jìn)程正常出生和滅亡過程****************************************/
#include <sys/types.h>
#include <unistd.h>
main()
{
???
??? fork(); /*開始創(chuàng)建一個(gè)子進(jìn)程*/
??? if(fork()>0) /* 如果是父進(jìn)程 */
?????? wait(NULL);??? /* 收集僵尸進(jìn)程 */
}
??? 大家看完代碼后,就會(huì)覺得這個(gè)代碼正是我剛才講的進(jìn)程一生是怎么樣的,進(jìn)程死后,一定要為他收尸,否則他就會(huì)編程僵尸進(jìn)程。下面就讓我們來看看未能把死去的進(jìn)程收尸會(huì)變成什么樣子?
/**********************************僵尸進(jìn)程******zombie.c*****************************************************/
#include <sys/types.h>
#include <unistd.h>
main()
{
?????? fork(); /*開始創(chuàng)建一個(gè)子進(jìn)程*/
??? if(fork>0) /* 如果是父進(jìn)程 */
?????? sleep(30);??? /* 休眠30秒,這段時(shí)間里,父進(jìn)程什么也干不了 */
?????? wait(NULL);??? /* 收起僵尸進(jìn)程 */
?? /*因?yàn)楦高M(jìn)程死了,子進(jìn)程也得一起陪葬,那么我們就讓父進(jìn)程睡眠30秒,在這30秒內(nèi)我們就可以看到僵尸進(jìn)程。
???? 30秒過后,父進(jìn)程醒來后就得死,所以到那時(shí)子進(jìn)程也就死去。*/
}
/********************************************************************************************/
??? 為了讓大家更清楚的看到僵尸進(jìn)程我們把這個(gè)僵尸進(jìn)程代碼編譯,然后執(zhí)行,
#gcc -o zombie zombie.c
編譯成功后我們開始執(zhí)行這個(gè)程序因?yàn)榇a里的sleep(30)是讓父進(jìn)程睡眠30秒,如果我們?cè)谇芭_(tái)執(zhí)行我們這個(gè)程序,那么就不能執(zhí)行其他shell命令了,所以這里我們?cè)趫?zhí)行的命令后面加一個(gè)& 代表后臺(tái)運(yùn)行的意思。
#./zomber &
好了,我們?cè)?0秒內(nèi)執(zhí)行查看進(jìn)程命令來看看我們這個(gè)zombie進(jìn)程是什么樣的?
#ps -aux |grep zombie
這個(gè)命令是顯示有關(guān)zombie的所有信息。具體操作請(qǐng)看圖(2)。
???
看到這里后,聰明的朋友會(huì)問,既然子進(jìn)程是由父進(jìn)程創(chuàng)造出來的,那么如果一個(gè)父程序執(zhí)行完退出后,子進(jìn)程不管是不是僵尸進(jìn)程也直接就退出了,因?yàn)楦高M(jìn)程死
了嘛。那么這也不會(huì)造成多大危害啊?如果大家這么認(rèn)為那可就錯(cuò)了,當(dāng)我們剛才用ps命令觀察進(jìn)程的執(zhí)行狀態(tài)時(shí),看到某些進(jìn)程的狀態(tài)欄為defunct,這
就是所謂的“僵尸”進(jìn)程。“僵尸”進(jìn)程是一個(gè)早已死亡的進(jìn)程,但在進(jìn)程表(processs
table)中仍占了一個(gè)位置(slot)。由于進(jìn)程表的容量是有限的,所以,defunct進(jìn)程不僅占用系統(tǒng)的內(nèi)存資源,影響系統(tǒng)的性能,而且如果其數(shù)
目太多,還會(huì)導(dǎo)致系統(tǒng)癱瘓,具體請(qǐng)看下面的代碼:
/***********************************無限創(chuàng)建子進(jìn)程********************************************/
#include <sys/types.h>
#include <unistd.h>
main()
{
?????? for (;;)? /*制作一個(gè)死循環(huán)*/
??????
???????? fork(); /*開始創(chuàng)建一個(gè)子進(jìn)程*/
}
/********************************************************************************************/
懂C語言的朋友會(huì)知道for(;;)是一個(gè)死循環(huán)。那么這僅有2行代碼的程序就可以把你的linux瞬間死機(jī),因?yàn)樗淖饔檬菬o限制的在內(nèi)存里增加新的子進(jìn)程,一個(gè)系統(tǒng)根據(jù)內(nèi)存的容量會(huì)分配進(jìn)程的最大限制,一旦同時(shí)運(yùn)行的進(jìn)程數(shù)超符合,那么你的機(jī)器必然會(huì)死機(jī)。
??
我這里分別用了2個(gè)用戶進(jìn)行測(cè)試過,一個(gè)是普通權(quán)限的用戶,一個(gè)是Root用戶,測(cè)試結(jié)果是“任何用戶只要執(zhí)行這個(gè)程序都會(huì)讓機(jī)器死掉”。原因就是默認(rèn)的
Linux系統(tǒng)沒有對(duì)普通用戶的使用最大進(jìn)程進(jìn)行限制。所以這樣對(duì)系統(tǒng)造成很大一個(gè)威脅,那么我們?nèi)绾伪苊馄胀ㄓ脩舴欠▓?zhí)行過多資源或進(jìn)程導(dǎo)致系統(tǒng)拖死,
所以我們的給除了Root的用戶做一下限制。
對(duì)普通用戶進(jìn)行限制:
第1步:首先進(jìn)到Linux終端用vi編輯/etc/security /limits.conf文件,在里面加入:
* hard core 0
* hard rss 5000
* hard nproc 20
?
?
這里的* 代表除了Root的所有用戶,(* hard core 0) 是禁止core files“core 0”,(* hard rss
5000) 是限制內(nèi)存使用為5MB“rss? 5000”, (* hard nproc 20 )是限制進(jìn)程數(shù)為“nproc
50“。大家可以根據(jù)自己系統(tǒng)內(nèi)存大小進(jìn)行合理配置。
第2步:用vi編輯/etc/pam.d/login文件,然后加上下面這行保存退出就可以。
session required /lib/security/pam_limits.so
??? 好了,現(xiàn)在我們已經(jīng)對(duì)普通用戶限制了進(jìn)程和內(nèi)存使用極限,修改完配置以后大家可以用Root和普通用戶分別進(jìn)行測(cè)試,結(jié)果當(dāng)然是普通用戶執(zhí)行完我們剛才做的程序不會(huì)死機(jī)了。
??? 一個(gè)系統(tǒng)的安全性不取決與打不打補(bǔ)丁,雖然打補(bǔ)丁很重要,但是對(duì)系統(tǒng)做出相應(yīng)的配置也是相當(dāng)重要的。