一个程序被加载到内存当中运行,那么在内存内的那个数据就被称为进程(process)。进程是操作系统上非常重要的概念,所有系统上面跑的数据都会以进程的类型存在。
1、什么是进程(process)
在Linux系统中,触发任何一个事件时,系统都会将它定义为一个进程,并且给予这个进程一个ID,称为PID,同时依据触发这个进程的用户与相关属性关系,给予这个PID一组有效的权限设置。
1.1、进程与程序(process & program)
如何产生一个进程呢?就是”执行一个程序或命令“就可以触发一个事件而取得一个PID。系统应该是仅认识二进制文件的,要让系统工作的时候,当然是启动一个二进制文件,那个二进制文件就是程序(program)。
系统通过PID来判断该process是否具有权限进行工作,它很重要。这个进程衍生出来的其他进程在一般状态下,也会沿用这个进程的相关权限。
程序(program):通常为二进制程序,放置在存储媒介中(硬盘,光盘等),以物理文件的形式存在;
进程(process):程序被触发后,执行者的权限与属性、程序的权限与属性、程序的程序代码与所需数据等都会贝加载到内存中,操作系统并给予这个内存内的单元一个标识符(PID),可以说,进程就是一个正在运行中的程序。
子进程与父进程:
很多朋友会发现,咦,我明明将有问题的进程关闭了,怎么过一会它又自动产生了。而且与之前的PID还不一样。不要怀疑,如果不是crontab工作调度的影响的话,肯定还有一个父进程存在。所以你杀掉子进程后,父进程就会主动再生一个。这时候就需要擒贼先擒王,搞掉父进程。
fork and exec:过程调用的流程
其实子进程和父进程之间的关系还挺复杂的,最大的复杂点在于进程互相之间的调用,在Linux的过程调用中通常被称为 fork-and-exec 的流程!进程都会通过父进程以复制(fork)的方式产生一个一模一样的子进程,然后被复制出来的子进程再以exec的方式来执行实际进行的进程,最终就成为一个子进程的存在。
系统或网络服务:常驻在内存的进程
有执行完就结束的进程、有一直执行的进程。
如crond这个进程所管理的,在启动后在后台当中一直持续不断运行,套句以前Dos时代的话,那就是常驻内存当中的进程。
常驻内存当中的进程通常都是负责一些系统所提供的功能以服务用户各项任务,因此这些常驻进程就会被我们成为服务(daemon)。
1.2、Linux的多用户、多任务环境
其实在Linux下面执行一个命令时,系统会将相关的权限、属性、程序代码与数据等均加载到内存,并给予这个单元一个进程标识符(PID),最终该命令可以今次那个的任务则与这个PID的权限相关。
多用户环境:
Linux系统上面具有多种不同的账号,每种账号都有其特殊的权限,只有root拥有至高无善的权限。 其他账号都要接受一些限制。
多任务行为:
CPU速度高达几个GHz,这代表CPU每秒可以运行1 000 000 000次,所以CPU每秒可以在各个工作间进行切换,每个工作仅占去CPU的几次命令而已。
多重登录环境的七个基本终端窗口:
在Linux当中,默认提供了6个cmd和一个图形界面,使用 Alt + [ F1-7 ]来切换不同终端机接口。这个东西很有用,特别是在某个进程死掉的时候。
特殊的进程管理行为:
老实说,Linux几乎可以说绝对不会死机,因为他可以在任何时候,将某个被困住的进程傻吊,然后在重新执行该进程。
bash环境下的工作管理(job control):
在单一bash接口下,可不可以进行多个工作呢?
将命令放入后台执行:cp file1 file2 &;
多用户、多任务的系统资源分配问题考虑:
多用户多任务确实有很多好处,但在管理上也有困扰,还有资源占用问题。
2、工作管理(job control)
工作管理(job control)使用在bash环境下的,当我们登录系统取得bash shell之后,在单一终端机下同时进行多个工作的行为管理。如一边复制一边数据查找一边vi。
2.1、什么是工作管理
在进行工作管理的行为中,其实每个工作都是目前bash的子进程,即彼此之间是有相关性的。我们无法以job control的方式由tty1的环境去管理 tty2的bash。
由于假设我们只有一个终端,因此在可以出现提示符让你操作的环境就称为前台(foreground),至于其他工作就可以让你放入后台(background)去暂停或运行。要注意的是,放入后台的工作想要运行时,它必须不能够与用户互动。举例来说,vi绝对不可能在后台里面执行。并且放入后台的工作是不可以使用 Ctrl + C来终止的。
要注意的是:
这些工作所触发的进程必须来自于你shell的子进程(只管理自己的bash);
前台:你可以控制与执行命令的这个环境称为前台(foreground)的工作;
后台:可以自行运行的工作,你无法使用 Ctrl + C 来终止它,可使用 bg/fg调用该工作;
后台中执行的进程不能等待 terminal/shell的输入(input)。
2.2、job control的管理
实际进行job控制命令如下。
直接将命令丢到后台中执行的 "&":
在某个命令后面加上 & 代表将该命令丢到后台去执行,此时bash会给于这个命令一个“工作号码”(job number),就是那个 [1]。放在后台执行最大的好处就是不用担心被 Ctrl + C 中断。
但如果有stdout、stderr,它的数据依旧是输出到屏幕上。因此我们需要把输出信息重定向。
tar -zpcf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1
工作号码(job number)只与您这个bash环境有关,但是它是这个命令触发的,所以当然是一个进程,因此也是有PID的。
将目前的工作丢到后台中“暂停”:Ctrl+Z
在vi的一般模式下,按下Ctrl+Z,屏幕上面会出现[1],表示这是第一个工作,而那个+代表最近一个被丢进后台的工作,且目前在后台下默认会被取用的那个工作(与fg命令相关)。而那个Stopped则代表目前这个工作的状态。在默认的情况下,使用Ctrl+Z丢到后台当中的工作都是“暂停”状态。
查看目前的后台工作状态:jobs
如果目前我有两个工作在后台当中,两个工作都是暂停的,而如果我仅输入fg时,那么那个[2]所代表的工作会被那搞前台当中来处理。
其实+号代表最近被放到后台的工作号码,-号代表最近最后第二个被放置到后台中的工作号码。而超过最后第三个以后的工作,就不会有 +/-符号存在了!
将后台工作拿到前台来处理:fg
让工作在后台下的状态变成运行中:bg
我们可以Ctrl+Z将目前的工作丢到后台下面去“暂停”,那如何让后台暂停的工作“Run”呢?
管理后台当中的工作:kill
如何将一个后台当中的工作直接删除呢?这时候就需要给予该工作一个信号(Signal),让它知道怎么做才好啊!
特别留意一下,-9通常是在强制删除一个不正常的工作时所使用的的,-15则是以正常步骤结束一项工作(15也是默认值),两者并不相同哈。
另外,kill后面接的数字默认是PID,如果想要管理bash的工作控制,请加上%数字了,这点留意。
2.3、脱机管理问题
要注意的是,我们在工作管理当中提到的“后台”指的是在终端机模式下可以避免Ctrl+C中断的一个情景,并不是放到系统的后台去。所以,工作管理的后台依旧与终端机有关。
如果你用远程连接的方式连接到Linux主机,并且将工作以&的方式放到后台去了,在工作尚未结束的情况下你脱机了,则该工作会被中断掉而不会继续进行。
这时候使用nohup命令来处理,nohup命令可以让你在脱机或注销系统后,还能够让工作继续进行。
nohup并不支持bash内置命令,因此你的命令必须要是外部命令才行。
3、进程管理
一个称职的系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真是很难解决的问题!
3.1、进程的查看
利用静态的ps或者动态的top命令,还能以pstree来查阅程序树之间的关系。
ps:将某个时间点的进程运行情况选取下来
直接记住两个不同的参数,一个是只查阅自己bash的“ps -l”,另一个是查看所有运行的程序"ps aux(没有 -)"。
F:代表这个进程标志(process flags),说明这个程序的权限。
若为4表示此进程权限为root;
若为1表示此子进程仅可进行复制(fork)而无法实际执行;
S:代表这个进程的状态(state)
R(Running):正在运行中;
S(Sleep):该进程目前正在休眠状态(idle),但可被唤醒(signal);
D:不可被唤醒的睡眠状态,通常这个进程在等待I/O;
T:停止状态(stop),可能是在工作控制(后台暂停)或除错(traced)状态;
Z(Zombie):僵尸状态,程序已经终止但却无法被删除至内存外。
UID/PID/PPID:
C:代表CPU的使用率;
PRI/NI:Priority/Nice的缩写,代表此进程被CPU所执行的优先级,数值越小代表该进程越快被CPU执行;
ADDR/SZ/WCHAN:ADDR是kernel function,指出该进程在内存的哪个部分,如果是running,一般就会显示“-”,SZ代表此进程用掉了多少内存,WCHAN表示目前进程是否运行中,同样,若为“-”表示正在运行;
TTY:登录者终端机位置,若为远程登录则使用动态终端接口(pts/n);
TIME:使用掉的CPU时间,是此进程实际花费CPU运行的时间,而不是系统时间;
CMD:command的缩写,此程序触发进程的命令为何。
查看系统所有进程:ps aux
一般来说,ps aux会按PID的顺序来排序显示。
VSZ:该进程使用小的虚拟内存量(KB);
RSS:该进程占用的固定的内存量(KB);
TTY:该进程是在哪个终端上面运行,tty1-6是本机,pts/n则是网络连接主机;
START:该进程被触发启动的时间;
TIME:该进程实际使用CPU运行的时间;
COMMAND:该进程的实际命令。
僵尸进程(Zombie):
通常,造成僵尸进程的成因是该进程应该已经执行完毕,或者是因故应该要终止了,但是改进程的父进程却无法完整将该进程结束掉,而造成那个进程一直在内存当中。
如果你发现某个程序的CMD后面还有<defunct>时,就代表该程序是僵尸程序啦。
top:动态查看进程的变化
相对于ps是选取一个时间点的进程状态,top则可以持续检测出进程运行的状态。
第一行(top...):这一行显示的信息分别为:
目前的开机时间(17:08:38);开机到目前为止所经过的时间(up 7 days);已经登录系统的用户人数(2 user);系统在1,5,15分钟的平均工作负载,越小代表越闲置。
第二行(Task...):显示的是目前进程的总量与个别进程在什么状态(running,sleeping,stopped,zombie)。
第三行(CPUs):显示CPU的整体负载。wa代表I/Owait,如果是多核,可以按下数字1来切换成不同的CPU的负载率。
第四行与第五行:表示目前物理内存与虚拟内存的使用情况,swap尽量少用,如果swap被大量使用,表示系统的物理内存实在不足!
第六行:这个是top进程中输入命令时显示状态的地方;
至于top下半部分的界面,则是每个进程使用的资源情况。
PR,进程的优先顺序,越小越先;
NI:Nice,与Priority有关,也是越小越早被执行;
TIME+:CPU使用时间的累加
top -d 2 -p pid
pstree
由进程树我们可以清晰的看到,所有的进程都是依附在init这个进程下面的。仔细一看,这个进程的PID是1哦。因为它是由Linux内核所主动调用的第一个进程!
如果子进程挂点或者老是杀不死,那就通过pstree找到其父进程。
3.2、进程的管理
进程之间可以互相控制!程序是如何互相管理的呢?其实是通过给与该进程一个信号(signal)去告知改程序你想让它做什么。
kill -signal PID | jobnumber%
# -signal和-num是一样的
killall -signal 命令名称
利用执行命令的名称来给予信号。
总之,要删除某个进程,我们可以使用PID或者是启动该进程的命令名称。而如果要删除某个服务呢?最简单的方法就是利用killall,因为它可以将系统当中所有以某个命令名称启动的进程全部删除。
3.3、关于进程的执行顺序(优先级)
我们知道Linux是多用户,多任务的环境,单系统有很多进程在休眠(sleeping)状态,如果所有进程都被唤醒,那么CPU应该要处理哪个进程呢?也就是哪个进程的优先序比较高!
下图近视示意图,并非较优先者一定会被运行两次。
Priority和Nice值:
我们Linux给予进程一个所谓的“优先执行序(Priority,PRI)”,PRI值越低代表越优先的意思。不过这个PRI值是由内核动态调整的,用户无法直接调整PRI值。
一般来说,PRI与NI的相关性如下:
PRI(new)=PRI(old)+ NICE
需要注意,如果原本的PRI为80,并不是我们给于一个NICE=5,就会让PRI变成85。因为PRI是由系统动态决定的。另外,nice的值是有正负的,当nice为负时,那么该程序就会降低PRI而会变得优先被处理。
此外:
nice值范围为 -20~19;
root可随意调整自己或他人进程的nice值,范围如上;
一般用户仅可调整自己的nice值,且范围为0~19,避免一般用户抢占系统资源;
调整nice值:
一种是一开始执行时就立即给于一个特定的nice值,用nice命令;
一种是调整已经存在的PID的nice值,用renice命令;
nice是用来调整进程的执行优先级!那么通常什么时候要将nice值调大呢?如备份工作,这样可以使得资源的分配更为公平。
除了这两者之外,top也是可以调整nice值的。
3.4、系统资源的查看
free:查看内存使用情况
一般来说,swap最好不要被使用,尤其swap最好不要被使用20%以上,那你绝对需要扩大物理内存了。
uname:查看系统与内核相关信息
uptime:查看系统启动时间与工作负载
netstat:跟踪网络
dmesg:分析内核产生的信息
系统在开机的时候,内核会去检测系统的硬件,你的某些硬件到底有没有被识别出来,那就与这个时候的检测有关。但这些检测的过程都是没有显示或者是一闪而过了。这时候就可以利用dmesg命令查看这些信息。
所有内核检测的信息,不管是开机的时候还是系统运行过程中,反正只要是内核产生的信息都会被记录到内存中的某个保护区段。dmesg能够将该区段的信息读出来。
vmstat:检测系统资源变化
内存字段(procs),r等待运行中的进程数量,b不可被唤醒的进程数量,这两个选项越多代表系统越忙碌;
内存字段(memory),swpd虚拟内存被使用的容量,free未被使用的内存容量,buff用于缓冲存储器,Cache用于高速缓存;
内存交换空间(swap),si由此盘中将程序取出的量,so由于内存不足而将没用的程序写入到磁盘的swap的容量。如果si/so数值太大,表示内存内的数据经常得在磁盘与内存之间传来传去,系统性能会很差;
磁盘读写(io),bi由磁盘写入的块数量,bo写入到磁盘去的块数量,值越高,系统I/O非常忙碌;
系统(system),in每秒被中断的进程次数,cs每秒进行的事件切换次数,值越大代表系统与接口设备的通信非常频繁;
CPU选项,us非内核层CPU使用状态,sy内核层所使用的CPU状态,id闲置的状态,wa等待I/O所耗费的CPU状态,st被虚拟机所盗用的CPU使用状态。
4、特殊文件与程序
1、具有SUID/GUID权限的命令执行状态
整个SUID的权限会生效是由于具有该权限的程序被触发,而我们知道一个程序被触发会变成进程,所以,执行者可以具有程序所有者的权限就是在改程序变成进程的那个时候。
SUID权限仅对二进制程序(binary program)有效;
执行者对于该程序需要具有x可执行权限;
本权限仅在执行该程序的过程中有效(run time);
执行者将具有该程序所有者(owner)的权限。
4.2、/proc/*代表的意义
其实,所谓的进程都是在内存当中,而内存当中的数据有都是写入到/proc/*这个目录下的,所以我们可以直接查看/proc目录中的文件
数字代表了某个进程的PID。
/proc/下相关文件与对应的内容:
4.3、查询已打开文件或已执行程序打开的文件
fuser:通过文件(文件系统)找出正在使用该文件的程序
ACCESS选项:
c:此进程在当前的目录下(非子目录);
e:可被触发为执行状态;
f:是一个被打开的文件;
r:代表顶层目录(root directory);
F:改文件被打开了,不过在等待回应中;
m:可能为分享的动态函数库。
lsof:列出被进程所打开的文件名
相对于fuser是由文件或者设备去找出使用该文件的进程,lsof是通过进程所打开的文件。
pidof:找出某个正在执行的进程的PID
5、SELinux初探
建议不要关掉SELinux
5.1、什么是SELinux
Security Enhanced Linux,安全强化的Linux之意。
当初开发SELinux是为了解决系统内部员工资源的勿用所导致的问题,为了控制这方面的权限与进程的问题。现在SELinux已经是整合到内核的一个模块。
其实SELinux是在进行程序、文件等权限设置依据的一个内核模块。由于启动网络服务的也是程序,因此刚好也是能够控制网络服务能否访问系统资源的一道关卡。
传统文件权限与账号的关系:自主访问控制,DAC
当某个进程想要对文件进行访问时,系统就会根据该进程的所有者/用户组,并比较文件的权限。但是各种权限的设置对root是无效的。这种访问文件系统的方式被称为“自主访问控制”(Discretionary / Access Control,DAC)。但这种方式有两个缺点:一是root具有最高权限;二是用户可以取得进程来更改文件资源的访问权限,如以文件是777。
以策略规则制定特色程序读取特定文件:委托访问控制,MAC
为了避免DAC容易发生的问题,因此SELinux导入了强制访问控制(Mandatory Access Control,MAC)的方法。强制访问控制(MAC)可以针对特定的进程与特定的文件资源来进行控制的权限!即使你是root,那么在使用不同的进程时,你所取得的资源并不一定是root,而要看此时该进程的设置而定。SELinux提供了一些默认策略(Policy),在强制访问控制的设置下,我们的进程能够活动的空间就变小了。
5.2、SELinux的运行模式
SELinux是通过MAC的方式来控管进程,它控制的主体是进程,而目标则是该进程能否读取的“文件资源”。
主体(Subject):
SELinux主要想管理的就是进程,因此可以将“主体”与进程划上等号。
目标(Object):
主体能否访问的“目标资源”一般是文件系统,可将与文件系统划上等号。
策略(Policy):
由于进程与文件数量庞大因此SELinux会依据某些服务来制定基本的访问安全性策略。这些策略内还会有详细的规则(rule)来指定不同的服务开放某些资源的访问与否。目前Centos7里面提供三种策略,分别是:
targeted:针对网络服务限制较多,针对本机限制少,是预设策略;
minimum:由target修订下来,仅针对选择的程序来保护;
mls:完整的SELinux限制,限制方面较为严格。
安全上下文(security context):
主体能不能访问目标除了策略指定之外,主体与目标的安全上下文必须一致才能顺利访问,这个安全上下文有点类似文件系统中的rwx。安全上下文设置错误,某些服务就无法访问文件系统(目标资源)。
安全上下文存在于主体进程中与目标文件资源中。事实上,安全上下文是放置到文件的inode内的,因此主体进程想要读取目标文件资源时,同样需要读取inode,这inode内就可以比较安全上下文以及rwx等权限值是否正确,而给于适当的读取权限依据。
使用 ls -Z查看安全上下文
安全上下文用(Security context):分为三个字段:
Identify:Role:Type
#身份标识:角色:类型
身份标识(Identity):
相当于账号身份识别,主要有以下类型,
unconfined_u:不受限制的用户,大部分是用户通过bash创建的文件;
system_u:系统用户,大部分是系统自己产生的文件。
角色(Role):
通过角色字段,我们可以知道这个数据是属于程序、文件资源还是代表用户。一般用户角色有:
object_r:代表的是文件或目录等文件资源;
system_r:代表的是进程,不过,一般用户也会被指定成system_r。
类型(Type最重要):
基本上,一个主体进程能不能读取到这个文件资源与类型字段有关。类型字段在文件与进程的定义不大相同:
type:在文件资源(Object)上面称为类型(Type);
domain:在主体程序(Subject)中则称为域(domain)!
domain需要与type搭配,则该程序才能够顺利读取文件资源。
进程与文件SELinux type字段的相关性:
看一下目前系统中的程序在SELinux下的安全文本
5.3、SELinux的启动、关闭与查看
目前SELinux依据启动与否,共有三种模式,分别如下:
enforcing:强制模式,代表SELinux正在运行,并且已经正确开始限制domain/type了;
permissive:宽容模式,代表SELinux正在运行,不过仅会有警告信息并不会实际限制domain/type的访问,这种模式可以用来SELinux的调试之用;
disable:关闭。
getenforce #显示目前SELinux的模式
并不是所有程序都会被SELinux所管制。
通过sestatus查看SELinux的策略(Policy):
SELinux的配置文件/etc/selinux/config:
SELinux的启动与关闭
如果你要启动SELinux的话,请将SELinux设置妥当。
5.4、SELinux策略内的规则管理
SELinux各项规则的(on|off)值查询getsebool
使用seinfo,sesearch查询SELinux各项规则,seinfo需要通过yum 安装
修改SELinux规则的布尔值setbool
setsebool最好记得一定要加上-P选项,这样才能将设置写入文件。
5.5、SELinux安全文本的修改
使用chcon手动修改文件的SELinux type
使用restorecon让文件恢复正确的SELinux type
建议只要记得restorecon搭配 -Rv同时加上某个目录就可以啦,比chcon轻松。
semanage预设目录的安全性文本查询与修改
通过semange增加、修改、删除预设的SELinux type
semange的功能很多,主要用到的仅有fcontext这个动作而已。
重点:
程序 (program):通常為 binary program ,放置在儲存媒體中 (如硬碟、光碟、軟碟、磁帶等),為實體檔案的型態存在;
进程(process):程式被觸發後,執行者的權限與屬性、程式的程式碼與所需資料等都會被載入記憶體中, 作業系統並給予這個記憶體內的單元一個識別碼 (PID),可以說,程序就是一個正在運作中的程序;
进程彼此之間是有相關性的,故有父进程與子进程之分。而 Linux 系統所有程序的父程序就是 systemd 這個 PID 為 1 號的程序。
在 Linux 的程序呼叫通常稱為 fork-and-exec 的流程!程序都會藉由父进程以複製 (fork) 的方式產生一個一模一樣的子程序, 然後被複製出來的子程序再以 exec 的方式來執行實際要進行的程式,最終就成為一個子程序的存在。
常駐在記憶體當中的程序通常都是負責一些系統所提供的功能以服務使用者各項任務,因此這些常駐程式就會被我們稱為:服務 (daemon)。
在工作管理 (job control) 中,可以出現提示字元讓你操作的環境就稱為前景 (foreground),至於其他工作就可以讓你放入背景 (background) 去暫停或運作。
與 job control 有關的按鍵與關鍵字有: &, [ctrl]-z, jobs, fg, bg, kill %n 等;
程序管理的觀察指令有: ps, top, pstree 等等;
程序之間是可以互相控制的,傳遞的訊息 (signal) 主要透過 kill 這個指令在處理;
程序是有優先順序的,該項目為 Priority,但 PRI 是核心動態調整的,使用者只能使用 nice 值去微調 PRI
nice 的給予可以有: nice, renice, top 等指令;
vmstat 為相當好用的系統資源使用情況觀察指令;
SELinux 當初的設計是為了避免使用者資源的誤用,而 SELinux 使用的是 MAC 委任式存取設定;
SELinux 的運作中,重點在於主體程序 (Subject) 能否存取目標檔案資源 (Object) ,這中間牽涉到政策 (Policy) 內的規則, 以及實際的安全性本文類別 (type);
安全性本文的一般設定為:『Identify:role:type』其中又以 type 最重要;
SELinux 的模式有: enforcing, permissive, disabled 三種,而啟動的政策 (Policy) 主要是 targeted;
SELinux 啟動與關閉的設定檔在: /etc/selinux/config;
SELinux 的啟動與觀察: getenforce, sestatus 等指令;
重設 SELinux 的安全性本文可使用 restorecon 與 chcon;
在 SELinux 有啟動時,必備的服務至少要啟動 auditd 這個;
若要管理預設的 SELinux 布林值,可使用 getsebool, setsebool 來管理!