每一个进程都会获得一个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(/.*)?"