Linux安全攻略-僵尸进程

原文地址:http://blog.chinaunix.net/uid-29033331-id-3857755.html 微软系列的东西现在已经非常受人们的喜爱,尤其是他独特人性化操作才让大家爱不释手,但是他也以漏洞之王为称,所以政府、企业等大型服务器是绝对没人敢用windows系列产品的。相比之下Linux在安全方面就闲得非常强壮。 而且照以后的发展趋势来看Linux将在各各领域占有绝对的优势,这个年代要是不懂Linux很难立足。所以今天我就带大家步入Linux最基本的安全领域—"进程"。 大家都知道Linux跟Win2K一样,都是多任务的操作系统,也就是说,在同一个时间内,可以有多个进程同时执行。如果大家对硬件体系有一定了解的话,就会知道,我们使用的个人计算机(PC)的CPU是在一个时间片断内只能执行一条指令,那么Linux是如何实现多进程同时执行的呢?这里Linux使用了一种称为"进程调度(process scheduling)"的武器,首先,为每个进程指派一定的运行时间,这个时间通常很短,短到以毫秒为 单位,然后依照某种规则,从众多进程中挑选一个投入运行,其他的进程暂时等待,当正在运行的那个进程时间耗尽,或执行完毕退出,或因某种原因暂停,Linux就会重新进行调度,挑选下一个进程投入运行。因为每个进程占用的时间片都很短,在我们使用者的角度来看,就好像多个进程同时运行一样了。我们了解了完了Linux多进程概念后,先来看看什么是进程? 一、进程概念: 当运行任何一个UNIX/Linux命令时,shell至少会建立一个进程来运行这个命令(这个进程也叫做父进程),所以可以把任何在UNIX/Linux系统中运行的程序叫做进程;但是进程并不是程序,进程是动态的,而程序是静态的,并且多个进程(这多个进程里除了父进程,其他的就是子进程)可以并发的调用同一个程序。 系统中每一个进程都包含一个task_struct数据结构,所有指向这些数据结构的指针组成一个进程向量数组,系统缺省的进程向量数据大小是512,表示系统中可同时容纳512个进程。进程的task_struct数据结构包括了进程的状态、调度信息、进程标识符等信息。 由于UNIX系统是一个多进程的操作系统,所以每一个进程都是独立的,都有自己的权限及任务,所以当某一进程失败时并不会导致别的进程失败。系统通过进程标识符来区分不同的进程,进程标识符是一个非负正数,他在任何时刻都是唯一的,当某个进程结束时,他的进程标识符可以分配给另外一个新进程。系统将标识符0分配给调度进程,标识符1分配给初始化进程。下面我来给大家演示一下进程由出生到死亡的一个流程图。 进程一生流程图: 出生: 编程中的一句fork(),爸爸妈妈(父进程)让小孩(子进程)出生了,并且继承里父母所有的东西,我们也可以把他看成克隆人。 生活: 然后随着exec(),小孩长大(新进程)脱胎换骨,离家独立,开始了为人民服务的职业生涯。 死亡: 人有生老病死,进程也一样,它可以是自然死亡,即运行到main函数的最后一个"}",从容地离我们而去;也可以是自杀,自杀有2种方式,一种是调用exit函数,一种是在main函数内使用return,无论哪一种方式,它都可以留下遗书,放在返回值里保留下来;它还甚至能可被谋杀,被其它进程通过另外一些方式结束他的生命(这里跟人有些不一样,在进程里,如果父进程死了,那么他创建的所有子进程也一起跟着死去)。死后安葬方式:这一过程也是必有的,不能说人在哪死后就不管他,也不把尸体搬走吧!:)进程死掉以后,会留下一具僵尸,wait()函数充当了殓尸工,把僵尸推去火化,使其最终归于无形。这就是进程完整的一生。 进程在运行期间,会用到很多资源,包括最宝贵的CPU资源,当某一个进程占用CPU资源时,别的进程必须等待正在运行的进程空闲CPU后才能运行,由于存在很多进程在等待,所以内核通过调度算法来决定将CPU分配给哪个进程。概念清晰后我们接下来看看Linux中,进程有哪几种状态。 二、Linux中的进程基本状态: 1、执行(R)状态:CPU正在执行,即进程正在占用CPU。 2、就绪(W)状态:进程已经具备的执行的一切条件,正在等待分配CPU的处理时间片。 3、停止(S)状态:进程不能使用CPU。 大家看到了在Linux中,正常来说进程有这么3种状态,但是在特殊情况下会多出一种状态,这就是我们要讲的"僵尸进程(Zombie)"。下面我们会仔细的讲解,接下来再介绍一下进程的管理。 三、Linux中的进程管理 管理分两种,一个是如何启动进程,另一个是如何调度进程。 1、启动进程 键入需要运行的程序的程序名,执行一个程序,其实也就是启动了一个进程。在Linux系统中每个进程都具有一个进程号(PID),用于系统识别和调度进程。启动一个进程有两个主要途径∶手工启动和调度启动,后者是事先进行设置,根据用户要求自行启动。由用户输入命令,直接启动一个进程便是手工启动进程。但手工启动进程又可以分为很多种,根据启动的进程类型不同、性质不同,实际结果也不一样。 (1) 前台启动 前台启动是手工启动一个进程的最常用的方式。一般来说用户输入一个命令"test",这就在前台启动了一个进程。这时候系统其实已经处于一个多进程状态。有许多运行在后台的、系统启动时就已经自动启动的进程正在悄悄运行着。这时如果有用户输入"test"命令以后赶紧使用"ps -x"来查看,但是却没有发现这个进程,原因是因为这个进程结束的太快,使用ps查看时该进程已经执行结束了。所以如果大家想看到进程的话,得 输入一个耗时的程序,我们下面会讲到。 (2) 后台启动 直接从后台手工启动一个进程用得比较少一些,除非是该进程甚为耗时,且用户也不急着需要结果的时候。假设用户要启动一个需要长时间运行的格式化文本文件的进程。为了不使整个shell在格式化过程中都处于"瘫痪"状态,从后台启动这个进程是明智的选择。 2、进程调度 当需要中断一个前台进程的时候,通常是使用Ctrl+c组合键;但是对于一个后台进程就不是一个组合键所能解决的了,这时就必须使用kill命令.该命令可以终止后台进程.至于终止后台进程的原因很多,或许是该进程占用的CPU时间过多;或许是该进程已经挂死.这种情况是经常发生的。Kill命令的工作原理是:向Linux系统的内核发送一个系统操作信号和某个程序的进程标识号,然后系统内核就可以对进程标识号指定的进程进行操作。 好了,进程的基本概念熟悉了以后大家会问那么到底什么是所谓的"僵尸进程"?,什么情况下会产生僵尸进程,如何杀掉僵尸进程?不用着急,我们先来熟悉一下有关Linux进程方面的编程。 首先我先给大家介绍几个非常重要的有关函数: fork(); 功能:创建一个新的进程。(fork()<0[出错]、fork()==0[子进程]、fork()>0[父进程] wait(); 功能:真正结束进程(收尸)。 exec(); 功能:执行外部程序。 好了,我现在让大家就看看我们神秘僵尸进程是什么样子的?下面我来用c写出父进程建立子进程的代码: /**********************************子进程正常出生和灭亡过程***************************************/ #i nclude #i nclude main() { fork(); /*开始创建一个子进程*/ if(fork()>0) /* 如果是父进程 */ wait(NULL); /* 收集僵尸进程 */ } 大家看完代码后,就会觉得这个代码正是我刚才讲的进程一生是怎么样的,进程死后,一定要为他收尸,否则他就会变成僵尸进程。下面就让我们来看看未能把死去的进程收尸会变成什么样子? /**********************************僵尸进程******zombie.c*****************************************************/ #i nclude #i nclude main() { fork(); /*开始创建一个子进程*/ if(fork>0) /* 如果是父进程 */ sleep(30); /* 休眠30秒,这段时间里,父进程什么也干不了 */ wait(NULL); /* 收起僵尸进程 */ /*因为父进程死了,子进程也得一起陪葬,那么我们就让父进程睡眠30秒,在这30秒内我们就可以看到僵尸进程。30秒过后,父进程醒来后就得死,所以到那时子进程也就死去。*/ } /********************************************************************************************/ 为了让大家更清楚的看到僵尸进程我们把这个僵尸进程代码编译,然后执行, #gcc -o zombie zombie.c 编译成功后我们开始执行这个程序因为代码里的sleep(30)是让父进程睡眠30秒,如果我们在前台执行我们这个程序,那么就不能执行其他shell命令了,所以这里我们在执行的命令后面加一个& 代表后台运行的意思。 #./zomber & 好了,我们在30秒内执行查看进程命令来看看我们这个zombie进程是什么样的? #ps -aux |grep zombie 这个命令是显示有关zombie的所有信息。 看到这里后,聪明的朋友会问,既然子进程是由父进程创造出来的,那么如果一个父程序执行完退出后,子进程不管是不是僵尸进程也直接就退出了,因为父进程死了嘛。那么这也不会造成多大危害啊?如果大家这么认为那可就错了,当我们刚才用ps命令观察进程的执行状态时,看到某些进程的状态栏为defunct,这就是所谓的"僵尸"进程。"僵尸"进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置 (slot)。由于进程表的容量是有限的,所以,defunct进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪,具体请看下面的代码: /***********************************无限创建子进程********************************************/ #i nclude #i nclude main() { for (;;) /*制作一个死循环*/ fork(); /*开始创建一个子进程*/ } /********************************************************************************************/ 懂C语言的朋友会知道for(;;)是一个死循环。那么这仅有2行代码的程序就可以把你的linux瞬间死机,因为他的作用是无限制的在内存里增加新的子进程,一个系统根据内存的容量会分配进程的最大限制,一旦同时运行的进程数超符合,那么你的机器必然会死机。 我这里分别用了2个用户进行测试过,一个是普通权限的用户,一个是Root用户,测试结果是"任何用户只要执行这个程序都会让机器死掉"。原因就是默认的Linux系统没有对普通用户的使用最大进程进行限制。所以这样对系统造成很大一个威胁,那么我们如 何避免普通用户非法执行过多资源或进程导致系统拖死,所以我们的给除了Root的用户做一下限制。 对普通用户进行限制: 第1步:首先进到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) 是限制内存使用为5MB"rss 5000", (* hard nproc 20 )是限制进程数为"nproc 50"。大家可以根据自己系统内存大小进行合理配置。 第2步:用vi编辑/etc/pam.d/login文件,然后加上下面这行保存退出就可以。 session required /lib/security/pam_limits.so 好了,现在我们已经对普通用户限制了进程和内存使用极限,修改完配置以后大家可以用Root和普通用户分别进行测试,结果当然是普通用户执行完我们刚才做的程序不会死机了。 一个系统的安全性不取决与打不打补丁,虽然打补丁很重要,但是对系统做出相应的配置也是相当重要的

时间: 2024-10-08 13:25:15

Linux安全攻略-僵尸进程的相关文章

《Linux深度攻略》一书,讲述Linux日常系统管理和服务器配置内容

Linux深度攻略 首先从介绍Linux系统的安装入手,讲述了Linux系统管理和服务器配置两部分的知识.系统管理方面内容有Linux系统简介和安装,Linux字符界面,目录和文件管理,Linux常用命令,Shell编程,用户和组群账户管理,权限.所有者和ACL,归档.压缩和备份,软件包管理,磁盘和文件系统管理,逻辑卷管理,进程和服务管理,任务计划以及Linux系统引导和启动.服务器配置方面内容有Linux网络基本配置,配置OpenSSH.VNC.NFS.DHCP.Samba.DNS.Apach

思维导图学 Linux Shell攻略之干货篇 mysql数据库脚本管理系统

以结果为导向的学习,才是最有效率学习.笔者以前也曾经隔三差五的学习linux shell编程来着.给我的感觉就是,今天学了,后天忘了,一星期之后就白学了. 还好,最近自己平时没啥事,一直照着<linux shell攻略>,学做一些小例子,看着自己写的shell程序,简单的几行程序,实现一些好玩的效果,信心满满.不知不觉间,慢慢坚持了2周. 说说自己的干货吧.其实就是一个linux 操作mysql数据库脚本管理系统. 功能谈不上复杂,就是在平时工作中,笔者要维护多套业务系统,这些业务系统主要功能

一起聊聊 Linux 系统中的僵尸进程

Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸.僵尸进程如何产生的?如果一个进程在其终止的时候,自己就回收所有分配给它的资源,系统就不会产生所谓的僵尸进程了.那么我们说一个进程终止之后,还保留哪些信息?为什么终止之后还需要保留这些信息呢?一个进程终止的方法很多,进程终止后有些信息对于父进程和内核还是很有用的,例如进程的ID号.进程的退出状态.进程运行的

linux脚本攻略

ls #列出以a和o开头的所有文件 [[email protected] ~]# ls anaconda-ks.cfg nss-pam-ldapd-0.9.8-1.gf.el7.x86_64.rpm openldap-clients-2.4.44-21.el7_6.x86_64.rpm original-ks.cfg tools [[email protected] ~]# ls [ao]* anaconda-ks.cfg openldap-clients-2.4.44-21.el7_6.x86

shell脚本学习1(Linux脚本攻略)

sudo <command> < arguments> 等价于root权限执行命令 赋予所有用户文件的可执行权限:chmod a+x script.sh 执行脚本:./script.sh#./表示当前的目录 命令1:echo "welcome to Bash" 命令2:printf "hello world" 区别:printf 不带换行! example1: #!/bin/bash printf "%-5s %-10s %-4s\

思维导图学 Linux Shell攻略之小试牛刀篇

曾听一位大神讲过,带着目的去学,知识往往能记得牢,记得稳.借助思维导图这个工具,对一些我感兴趣的知识点进行分类管理.以后方便自己复习. 我会以思维导图+代码段的方式,回滚学习linux shell编程. 转义/色彩 与用户交互的接口 #打印一个普通的字符串 [[email protected] ~]# echo "it's isa dog" it's is a dog   #打印一个带有单引号和换行符的字符串,单引号可正常输出,但换行符没有效果 #没有达到想要的效果 [[email p

Linux学习攻略分享,云计算应该怎么学?

要学好云计算首先就要养成在命令行下工作的习惯,一定要养成在命令行下工作的习惯,要知道X-window只是运行在命令行模式下的一个应用程序.在命令行下学习虽然一开始进度较慢,但是熟悉后,您未来的学习之路将是以指数增加的方式增长的.从网管员来说,命令行实际上就是规则,它总是有效的,同时也是灵活的.即使是通过一条缓慢的调制解调器线路,它也能操纵几千公里以外地远程系统. 用Unix思维思考Linux 由于Linux是参照Unix的思想来设计的,理解和掌握它就必须以Unix的思维来进行,而不能以Windo

Linux–Nginx攻略

什么是Nginx Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日.其将源代码以类BSD许可证的形式发布,因它的稳定性.丰富的功能集.示例配置文件和低系统资源的消耗而闻名.2011年6月1日,nginx 1.0.4发布. Nginx是一款轻量级的WEB服务器/反向代理服务器及电

&lt;linux shell 攻略&gt; 庖丁解牛 mysql数据库脚本管理系统

操作界面 这个小系统一共包含4个脚本 sh 功能 备注 oneKey.sh 主程序,调用其他程序,对外提供功能 menu.sh 勾画菜单 function.sh 提供操作数据库接口 valid.sh 操作mysql数据库,验证数据 menu.sh 画字符菜单 #!/bin/bash function print_main_menu(){ cat <<EOF ####################################### #    1)创建数据库