您的位置:首页 > 运维架构 > Linux

进程管理与SELinux初探

2015-06-22 09:40 447 查看
每一个进程都会获得一个PID,系统就是通过这个PID来判断这个进程是否有权限进行工作的。在Linux下执行一个指令时,系统会将相关的权限、属性、程序代码与数据等加载到内存中,并给予这个单元一个进程标识符(PID),该指令可以进行的任务就与这个PID有关

当用bash提供的接口去执行另一个指令时,这个新的指令也会被触发形成新的进程(所以也会获得PID),这就是子进程,它父进程的PID是PPID(Parent PID)

Linux中进程之间的调用称为fork-and-exec流程,进程会通过父进程以复制(fork)的方式产生一个一模一样的进程,然后被复制出来的进程再以exec的方式来执行实际要进行的进程,最终成为一个子进程,流程如下:

1. 系统以fork的方式复制一个与父进程相同的暂存进程,这个进程与父进程唯一的差别就是PID不同,并且会增加一个PPID参数

2. 暂存进程开始以exec的方式加载实际要执行的进程,最终子进程的代码就会变成这个要执行的进程的代码



启动在背景中一直运作的进程就是常驻内存的进程,他们通常提供一些系统功能以服务用户,因此这些常驻进程就被称为服务(daemon)

在指令最后添加" &"可以将其放置到背景执行,终端接口同时可以进行其他工作,系统会显示这个指令的job number和PID,当背景进程完成后会在终端接口显示完成的消息。放入背景执行的工作必须是不能与用户进行互动的(如vim),并且放入背景后不能用ctrl+c来终止。虽然一个指令被丢到背景中执行,但数据依旧会输出到当前终端中而影响操作,所以最好将数据通过流传送到一个档案中(包括错误信息)

工作管理(job control)是用在bash环境下的,指登入系统取得bash shell后在单一终端机接口下同时进行多个任务的管理。所有被管理的任务都是当前bash的子进程,所以无法以job control的方式由tty1的环境去管理其他终端的bash。要进行job control有以下限制:

1. 这些工作所触发的进程必须来自于自己shell的子进程(只管理自己的bash),即使是root也不能将别人bash下的job拿来执行

2. 前景:可以控制与下达指令的环境成为前景

3. 背景:可以自行运作的工作,可使用bg/fg呼叫该工作。工作的状态可以分为暂停(stop)和运行中(running)

4. 背景中执行的进程不能等待terminal/shell的输入

将当前工作暂停并放到背景中:ctrl+z

屏幕上会显示这个工作的序号,有"+"则表示这是最近一个被放到背景中的工作,是使用fg指令默认会被取用的工作;同时会显示这个工作的状态,一般情况下使用ctrl+z放到背景中的工作都会处于暂停状态(Stopped)

观察当前背景工作的状态:jobs

jobs [-lrs]

-l:除了job number和指令串外还列出PID

-r:仅列出正在背景中运行(running)的工作

-s:仅列出正在背景中暂停(stopped)的工作

有"+"代表使用fg指令时预设的取用工作

将背景工作拿到前景处理:fg

fg %jobnumber

"%"可以不加

启动背景中暂停的工作:bg

bg %jobnumber

管理背景中的工作:kill

kill -signal [PID/%jobnumber]

kill -l

-l:列出目前kill能使用的signal有哪些,signal代表如何处理后面的工作,常用的有:

-1:重新读取参数的配置文件(类似重载reload)

-2:等于ctrl+c

-9:强制终止一个工作

-15:以正常的方式终止工作

kill之后默认接PID,如果要接job number要加%

脱机管理

之前提到的“背景”是指在终端机模式下可以避免ctrl+c中断的一个情景,并不是放到系统的背景去执行,所以工作管理的背景依旧和终端机有关。例如用远程登陆联到Linux主机,如果以"&"的方式将工作放到背景中,如果脱机则工作也会中断。要解决这个问题可以使用at指令,或者nohup指令。nohup可以让工作在脱机或系统注销登陆后还可以继续工作,但它不支持bash内建指令,所以指令必须是外部指令才行

在终端机前景中工作:nohup [指令参数]

在终端机背景中工作:nohup [指令参数] &

例:nohup ./check.sh &

此时指令的输出会被导向到~/nohup.out

ps:查看某个时间点的进程运作情况

ps aux:观察系统所有的进程数据

ps -lA:也是观察所有的进程数据,显示的字段与ps -l相同,但包括了系统的所有程序

ps axjf:同时显示进程树状态

-A:显示所有进程,与-e效果相同

-a:不显示与terminal有关的进程

-u:有效使用者(effective user)相关的进程

-Z:查阅进程的安全上下文(security context),参见SELinux部分

x:通常与a合用,可列出完整信息

输出格式设置:

l:详细的将PID信息列出

j:工作的格式(jobs format)

-f:做一个更为完整的输出

仅使用ps的话只会列出与当前用户操作环境(bash)有关的进程,最上层的父进程将只是用户的bash而不会延伸到init去。

使用ps -l所列出的各项的含义为:

F:进程标识符(process flag),说明这个进程的总结权限,常见的有:"4"表示权限为root;"1"表示此进程只能进行复制(fork)而没有实际执行(exec)

S:代表进程的当前状态

R(Running):运行中

S(Sleep):该进程正在睡眠状态(idle),可以被唤醒(signal)

D:不可被唤醒的睡眠状态,通常可能在等待IO

T:停止状态(stop),可能是在工作控制(背景暂停)或除错(traced)状态

Z(Zombie):僵尸状态,程序已经终止但却不法被移除内存

UID/PID/PPID:进程的拥有者/进程号/父进程号

C:CPU使用率,为百分比

PRI/NI:Priority/Nice的缩写,表示此进程被CPU执行的优先级,数值越小优先级越高

ADDR/SZ/WCHAN:均与内存有关。ADDR是kernel
function,指出该进程在内存的哪个部分,如果是正在running的程序一般会显示"-";SZ代表进程用掉了多少内存;WCHAN表示该进程是否在运行中,若是则显示"-"

TTY:登入者的终端机位置

TIME:使用掉的CPU时间,注意是实际消耗的CPU运行时间,而不是系统时间

CMD:command,此进程的触发指令

ps aux指令显示的项目:

USER:进程所属的使用者;

VSZ:该进程使用的虚拟内存(KB)

RSS:该进程使用的固定内存(KB)

TIME:该进程实际使用的CPU运行时间

僵尸进程通常的成因是进程已经执行完毕或应因故终止了,但该进程的父进程却无法完整的将该进程结束,导致它一直存在于内存中。当某个进程的CMD后接<defunct>时,就代表该进程是僵尸进程。通常僵尸进程已经无法管控,直接交给init进程来处理;而init进程是系统第一支执行的进程,是所有进程的父进程,所以无法杀掉该进程,只能重启

top:动态观察进程

top [-d 数字]

top [-bnp]

-d:后接数字,表示每隔多少秒更新结果,预设是5秒

-b:以批次的方式执行top

-n:与-b搭配,表示需要进行几次top结果输出

-p:指定某个PID进行观察

top执行过程中的指令:

?:显示可输入的指令

P:以CPU的使用率排序

M:以memory的使用排序

N:以PID排序

T:以使用的CPU累计时间(TIME+)排序

k:给某个PID一个信号(signal)

r:给某个PID新的nice值

q:离开top

top显示的内容:

第一行:当前时间,已开机时间,登入系统的用户人数,系统在1、5、15分中的平均负载(平均要同时运行几个进程,如果大于1要注意)

第二行:当前所有进程的统计信息

第三行:CPU的整体负载,每个项目可用"?"查阅。特别注意%wa,它代表IO wait,IO通常会影响系统速度。如果是多核心设备可以按下"1"来切换不同的CPU负载

第四行与第五行:物理内存与虚拟内存的使用情况。如果swap被大量使用表明系统物理内存不足

第六行:输入指令时显示状态的地方

top预设使用%CPU进行排序

例:将top信息进行两次,将结果输出到/tmp/top.txt

top -b -n 2 > /tmp/top.txt

pstree [-A/U] [-up]

-A:进程树之间以ASCII字符连接

-U:进程树之间以万国码字符连接,在某些终端下可能会有错误(预设)

-p:同时列出每个进程的PID

-u:同时列出每个进程所属的用户名

由pstree可以看到,所有进程都是由init进程产生的,它的PID是1。如果一个子进程挂点或是总是无法杀掉,则可以用pstree寻找到它的父进程

进程管理

进程之间的相互管理是通过信号(signal)去表明要进行什么操作



常用的是1,9,15,要传递signal要使用kill或killall指令

kill -signal PID/%jobnumber

用进程号或job number向进程传递signal

killall [-iIe] [command name]

-i:interactive,互动模式,进行删除会出现提示

-e:exact,表示与后接的command name要一致,但完整指令不能超过15个字符

-I:忽略指令名称大小写

Linux会给进程一个优先级(priority,PRI),PRI值越低代表优先级越高。PRI是由核心动态调整的,用户无法直接改变PRI的值。如果想要调整进程的优先级可以改变nice值NI。一般PRI与NI的关系是PRI(new) = PRI(old) + NI,但新的PRI需要经过系统分析决定。NI可正可负。

1. NI的值可调整的范围为-20~19

2. root可以随意调整自己或其他人的NI值,范围为-20 ~ 19

3. 一般用户只能调整自己进程的NI值,且范围仅为0 ~ 19(避免一般用户抢占系统资源)

4. 一般使用者仅能将NI值调高,例如NI原值为5,则未来仅能调整到大于5

可以将系统背景工作中不重要进程的NI值调高以更合理的分配系统资源

调整NI值的方法:

1. 一开始执行程序就立即给予一个特定的NI值:用nice指令

2. 调整某个已存在进程的NI值:用renice指令

top指令也可以调整NI值

nice [-n 数字] command

renice [数字] PID

修改父进程的NI值时,子进程的NI值也会被改变,NI值是在父进程到子进程传递的

free:观察内存使用

free [-b/k/m/g] [-t]

-b:直接输入free时显示的单位是KB,一使用b,k,m,g来调整

-t:在输出结果中显示物理内存与swap的总量

即使系统未进行太多工作,物理内存也会被大量使用,这是正常的,因为部分作为buffer,部分作为cache,也就是说系统在有效率的使用内存,目的是提高系统效能。而swap一般最好不要被使用,最好不要超过20%,否则表示物理内存不足,而且swap的效能比较差。

uname:查阅系统与核心相关的信息

-a:显示所有的系统相关信息

-s:显示系统核心名称

-r:显示系统和新版本

-m:显示系统的硬件名

-p:显示CPU的类型

-i:显示硬件平台

uptime:观察系统启动时间与工作负载(其实就是top的第一行)

netstat:追踪网络或插槽文件

netstat [-atunlp]

-a:将目前系统上所有的联机、监听、socket数据都列出来

-t:列出tcp网络封包的数据

-u:列出udp网络封包的数据

-n:使用端口号(port number)而非进程服务名称来显示

-l:列出目前正在网络监听(listen)的服务

-p:列出该网络服务进程的PID

netstat现实的结果分为两个部分,上面是网络的联机部分,下面是Linux上的socket程序部分

网络联机情况的字段:

Proto:网络的封包协议,主要是TCP或UDP封包

Recv-Q:由非用户程序连接到此socket复制的总byte数

Send-Q:由非远程主机传送过来的acknowledge总byte数

Local Address:本地IP:port情况

Foreign Address:远程主机的IP:port情况

State:联机状态,主要有建立(ESTABLISHED)和监听(LISTEN)

Linux系统上的进程可以接受不同进程发来的信息,这就是Linux上的socket file。socket file可以沟通两个进程之间的信息。netstat第二个部分socket部分字段:

Proto:一般是unix

RefCnt:连接到此socket的进程数

Flags:联机的标识符

Type:socket存取的类型,主要有需要确认联机的STREAM和不需要确认的DGRAM两种

State:若为CONNECTED则表示多个进程之间已经建立联机

Path:连接到此socket相关的进程路径或是相关数据的输出路径

dmesg:分析核心产生的信息

在系统开机时,核心会去侦测系统硬件,但过程会一闪而过。通过dmesg指令可以显示核心侦测的信息。核心侦测的所有信息都会被记录到内存中的保护区段,dmesg就是将这个区段的信息读取出来

vmstat:侦测系统资源变化,可以侦测CPU/内存/磁盘输入输出状态等

vmstat [-a] [延迟 [总侦测次数]] :CPU/内存等信息

-a:使用inactive/active取代buffer/cache的内存输出信息

-f:开机到目前为止系统复制(fork)的进程数

-s:将开机到目前为止一些事件导致的内存变化情况列表说明

-S:后接单位,如K/M

-d:列出磁盘的读写总量统计表

-p:后接分割槽,显示该分割槽的读写总量统计表

例:统计当前主机的CPU状态,每秒一次,共三次:vmstat 1 3

各字段的含义:

procs:"r"表示等待运行的进程数,"b"表示不可被唤醒的进程数。这两个项目越多表明系统越忙碌

memory:"swpd"表示虚拟内存的使用量,"free"表示未被使用的内存量,"buff"表示用作buffer的量,"cache"表示用于cache的量

swap:"si"表示从磁盘中取出的进程量,"so"表示由于内存不足而将没用的程序写入swap的量。如果si/so的值太大,表示内存中的数据常在磁盘和主存间传递,系统的效能会比较差

io(磁盘读写):"bi"表示从硬盘读取的block数,"bo"表示写入硬盘的block数,二者的值越高表示系统的IO越忙碌

system:"in"表示每秒的中断数,"cs"表示每秒进行的时间切换次数,这两个值越大表示系统与结构设备的沟通越频繁

cpu:"us"表示执行非核心代码的时间,"sy"表示执行核心代码的时间,"id"表示idle的时间,"wa"表示等待IO花费的时间,"st"表示被虚拟机盗用的时间

当系统非常忙碌时,可以用vmstat查看哪部分的资源被使用的最为频繁

具有SUID权限的进程被触发后,会取得一个新的进程和PID,该PID产生时通过SUID来给予该PID特殊的权限设定

/proc目录

进程都是在内存中的,而内存中的数据会被写入到/proc目录下,基本上当前主机上的各个进程的PID都是以目录的形态存在于/proc中。在每个进程的对应目录下,会有一些相关档案,其中比较重要的是"cmdline"中包含进程被启动的指令串,"environ"中则包括了这个进程环境变量的内容。针对整个Linux系统的参数就在/proc目录下,相关内容,具体内容如下:



fuser:通过档案或文件系统找出正在使用该档案的进程

fuser [-umv] [-k [i] [-signal]] file/directory

-u:除了进程的PID外还列出该进程的拥有者

-m:后接的档名会提到该文件系统的最顶层,对umount不成功很有效

-v:列出每个档案与进程还有指令的完整相关性

-k:找出使用该档案/目录的PID,并试图以SIGKILL这个信号给该进程

-i:必须与-k合用,在结束进程之前会进行询问

-signal:例如-1~15,若不加则预设为SIGKILL (-9)

fuser所列出项目中ACCESS的含义:

c:此进程在当前的目录下(非子目录)

e:可被触发为执行状态

f:是一个被开启的档案

r:代表顶层目录(/)

F:该档案已被开启,不过在等待回应中

m:可能为分享的动态函数库

lsof:列出被进程开启的档案文件名

lsof [-aUu] [+d]

-a:多项数据需要同时成立才能被列出

-U:仅列出Unix-like系统的socket文件类型

-u:后接username,列出该用户相关进程开启的档案

+d:后接目录,找出某个目录下已被开启的档案

pidof:找出某支正在执行的程序的PID

pidof [-sx] 进程名

-s:仅列出一个PID

-x:同时列出该进程可能的PPID哪个进程的PID

SELinux(Security Enhanced Linux)

之前提到的文件系统存取方式称为"自主式访问控制(Discretionary Access Control,DAC)",基本上就是依靠进程的拥有者与档案资源的rwx权限来决定有无存取能力。它无法限制root的权限,并且一旦某个目录的权限被设为777,该目录就可以被任何人任意存取。SELinux引入了"委任式访问控制(Mandatory Access Control,MAC)",它可以针对特定的进程与特定的档案进行权限管理,这样权限控制的对象就变成了进程而不是用户。并且,一个进程也不能任意使用系统档案资源,因为每个档案资源也有针对该进程设定的权限。

SELinux通过MAC方式来控制管理进程,控制的主体是进程,目标是该进程要处理的档案资源

主体(Subject):SELinux的主要管理对象

目标(Object):主体进程能否存取的目标资源,一般是文件系统

政策(Policy):SELinux会根据某些服务来制定基本的存取政策,这些政策内还会有详细的规则(rule)来指定不同的服务是否开放某些资源的存取

安全上下文(security context):主体能不能存取目标除了政策的规定之外,主体与目标的安全上下文必须一致才能顺利存取,有点类似文件系统的rwx



主体进程必须通过SELinux的政策规定后,才可以与目标资源的安全上下文进行比对,比对成功才能开始存取,并且最终能否存取目标还要看文件系统的rwx权限设定

安全上下文

安全上下文存在于主体进程与目标资源档案中。由于进程在内存中,所以安全上下文可以存入;对档案来说,安全上下文是存放在档案的inode内的,因此主体进程想要读取目标档案的资源时需要读取inode,然后才能比对安全上下文和rwx等权限设定是否正确。安全上下文可以通过【ls -Z】进行观察,主要有三个字段:

identify:role:type

1. 身份识别(identify)

相当于账号方面的身份识别,主要的身份识别有以下三种类型:

root:表示root的账号身份

system_u:表示系统方面的识别

user_u:代表一般使用者账号的相关身份

2. 角色(role)

通过角色字段,可以知道这个数据属于进程、档案资源还是代表使用者。一般有:

object_r:代表档案或者目录等档案资源

system_r:代表进程,不过一般使用者也会被指定为system_r

3. 类型(type)

这个字段比较重要,一个主体进程能不能读取档案资源就与这个字段有关,它在进程和档案上的定义不一样,分别是:

domain:在主体程序(subject)上称为领域(domain)

type:在档案资源(object)上称为类型(type)

主体进程取得的domain和目标档案资源type的相互关系:

1. 首先,触发一个可执行的目标档案

2. 该档案的类型会让这个档案所产生的主体进程(subject)具有一个领域(domain),政策(policy)针对这个领域已经指定了许多规则(rule),包括这个领域可以读取的目标资源类型

3. 如果进程的domain被设定为可以读取某个类型(type)的目标档案(object),并且rwx符合规范则可以进行文件读取

目前SELinux支持三种模式:

enforcing:强制模式,代表SELinux运行中,并且已经开始限制domain/type了

permissive:宽容模式,代表SELinux运行中,不过只会有警告信息,不会实际限制domain/type的存取。这种模式可以用来进行debug

disabled:关闭,SELinux没有运行

getenforce可以查询当前SELinux的状态

sestatus:查询SELinux的policy

sestatus [-vb]

-v:检查位于/etc/sestatus.conf内档案与进程的安全上下文内容

-b:将目前policy的bool值列出,即某些规则(rule)是否启动

SELinux的配置文件是/etc/selinux/config

要启动SELinux,需要将上述档案中的SELINUX一项设为enforcing或permissive;然后到/boot/grub/menu.lst档案中"kernel"字段后的"selinux=0"删除,因为它会使kernel自动忽略/etc/selinux/config的设定值而跳过SELinux加载

通过指令setenforce [0/1]可以在enforcing(1)和permissive(0)之间切换(不能在disabled模式下进行)

chcon:修改SELinux安全上下文

chcon [-R] [-t type] [-u user] [-r role] 档案

chcon [-R] --reference=范例文件 档案

-R:递归修改子目录

-t:后接安全上下文的类型

-u:后接身份识别,如system_u

-r:后接角色,如system_r

--reference=范例文件:以某个档案作为范例来修改后接的档案

restorecon:重置安全上下文

restorecon [-Rv] 档案或目录

-R:连同子目录一起修改

-v:将过程显示到屏幕上

SELinux所需的服务

setroubleshoot:错误信息写入/var/log/messages

该服务会将SELinux的错误信息与修正方法记录到/var/log/messages中

启动:chkconfig setroubleshoot on

列出执行等级:chkconfig --list setroubleshoot

只要3、5是on即可(on表示开机自启动)

auditd:详细资料写入/var/log/audit/audit.log

该服务会将SELinux发生的错误信息写入/var/log/audit/audit.log中,而且不仅仅会记录错误信息,启动和查看方法与setroubleshoot相同(把名字换成auditd)即可

audit2why:检查错误信息的汇报

audit2why < /var/log/audit/audit.log

信息中AVC是access vector cache的缩写,目的是记录所有与SELinux有关的存取统计资料

seinfo:政策查询

seinfo [-Atrub]

-A:列出SELinux的状态、规则布尔值、身份识别、角色、类别等所有信息

-t:列出SELinux的所有类别(type)种类

-r:列出SELinux的所有角色(role)种类

-u:列出SELinux的所有身份是被(user)种类

-b:列出所有规则的种类(布尔值)

sesearch:查询详细规则

sesearch [-a] [-s 主体类别] [-t 目标类别] [-b 布尔值]

-a:列出该类别或布尔值的所有相关信息

-t:后接类别

-b:后接布尔值的规则

结果有三个字段:allow;主体进程安全上下文类别;目标档案安全上下文类别

实际规范规则的是布尔值的项目,查询布尔值:

getsebool [-a] [布尔值条款]

-a:列出目前系统上的所有布尔值条款

关闭布尔值:

setsebool [-P] 布尔值=0/1

-P:将设定写入配置文件,一定要加

查询默、修改认安全上下文:

semanage {login/user/port/interface/fcontext/translation} -l

semanage fcontext -{a/d/m} [-first] file_spec

fcontext:主要用在安全上下文方面,-l是查询的意思

-a:增加,可以增加一些目录的默认安全上下文类型设定

-m:修改

-d:删除

例:给/srv/samba目录增加新的安全上下文public_content_t

semanage fcontext -a -t public_content_t "/srv/samba(/.*)?"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: