第16章 进程管理与SELinux初探

发布时间 2023-07-31 11:03:58作者: Evan-whc

第16章 进程管理与SELinux初探

  一个程序被加载到内在当中运作,那么在内存中的那个数据就被称为进程(process)。进程是操作系统上非常重要的概念,所有系统上面跑的数据都会以进程的形态存在。

16.1 什么是进程(process)

  在Linux系统中:触发任何一个事件时,系统都会将他定义成为一个进程,并且给予这个进程一个ID,称为PID,同时依据启发这个进程的用户与相关属性关系,给予这个PID一组有效的权限设定。

16.1.1 进程与程序(process & program)

  • 程序(program):通常为binary program,放置在储存媒体中(如硬盘、光盘、软盘、磁带等),为实体文件的形态存在。
  • 进程(process): 程序被触发后,执行者的权限与属性、程序的程序代码与所需数据等都会被加载内存中,操作系统并给予这个内存内的单元一个标识符(PID),可以说 ,进程就是一个正在运作中的程序。
  • 系统或网络服务:常驻在内存的进程

16.2 工作管理(job control)

16.2.2 job control的管理

  • 直接将指令丢到背景中执行的&
    例如:
    tar -zpcf /tmp/etc.tar.gz /etc &
  • 将“目前”的工作丢到背景中“暂停”:[ctrl]-z
    比如把vim的编辑工作用ctrl-z丢到背景执行后,屏幕上会出现[1],表示这是第一个工作,而那个+代表最近一个被丢进背景的工作,且目前在背景下预设会被取用的那个工作(与fg这个指令有关)!而那个Stopped则代表目前这个工作的状态。在预设的情况下,使用[ctrl]-z丢到背景当中的工作都是【暂停】的状态哦!
  • 观察目前的背景工作状态:jobs
jobs [-lrs]
选项与参数:
-l: 除了列出job number与指令串之外,同时列出PID的号码:
-r: 仅列出正在背景run的工作
-s: 仅列出正在背景当中暂停(stop)的工作。
  • 将背景工作拿到前景来处理:fg
    fg(foreground)
fg %jobnumber
选项与参数:
%jobnumber: jobnumber为工作号码(数字)。注意,那个%是可有可无的!
  • 让工作在背景中的状态变成运作中:bg
    范例:
    jobs; bg %3; jobs
  • 管理背景当中的工作:kill
    如果想要将背景中的工作直接移除呢?或者是将该工作重新启动呢?这个时候就得需要给予该工作一个讯号(signal)。此时,kill这个指令就派上用场啦!
kill -signal %jobnumber
kill -l 
选项与参数:
-l: 这个是L的小写,列出目前kill能够使用的讯号(signal)有哪些?
signal: 代表给予后面接的那个工作什么样的指示哦!用man 7 signal可知
-1: 重新读取一次参数的配置文件(类似reload)
-2: 代表与由键盘输入[ctrl]-c同样的动作
-9: 立刻强制删除一个工作
-15: 以正常的进程方式终止一项工作。与-9是不一样的。
另外,kill后面接的数字默认会是PID,如果想要管理bash的工作控制,就得要加上%数字了。
范例:
`kill -9 %2`

16.2.3 脱机管理问题

  要注意的是,我们在工作管理当中提到的“背景”指的是在终端机模式下可以避免[ctrl]-c中断的一个情境,你可以说那个是bash的背景,并不是放到系统的背景去哦!所以,工作管理的背景依旧与终端机有关啦!在这样的情况下,如果你是以远程联机的方式连接到你的Linux主机,并且将工作以&的方式放到背景去,请问,在工作尚未结束的情况下你脱机了,该工作还会继续进行吗?答案是“否”!不会继续进行,而是会被中断掉。
  那怎么办?如果我的工作需要进行一大段时间,我又不能放置在背景下,那该如何处理呢?首先,你可以参考前一章的at来处理即可!因为at是将工作放置到系统背景,而与终端机无关。如果不想要使用at的话,那你也可以尝试nohup这个指令来处理哦!这个nohup可以让你在脱机或注销系统后,还能够让工作继续进行。他的语法有点像这样:

nohup [指令与参数]
nohup [指令与参数] &

  需要注意的是,nohup并不支持bash内建的指令,因此你的指令必须要是外部指令才行。

16.3 进程管理

16.3.1 进程的观察

  • ps: 将某个时间点的进程运作情况撷取下来
ps aux    <==观察系统所有的进程数据
ps -lA    <==也是能够观察所有系统的数据
ps axjf    <==连同部分进程树状态
选项与参数:
-A: 所有的process均显示出来,与-e具有相同的效用
-a: 不与terminal有关的所有process
-u: 有效使用者(effective user)相关的process
-x: 通常与a这个参数一起使用,可列出较完整信息
输出格式规划:
l: 较长、较详细的将该PID的信息列出
j: 工作的格式(jobs formal)
-f: 做一个更为完整的输出
常用的两个选项为:
一个是只能查阅自己bash进程的[ps -l]
另一个则是可以查阅所有系统运作的进程[ps aux]
  • top: 动态观察进程的变化
top [-d 数字] | top [-bnp]
选项与参数:
-d: 后面可以接秒数,就是整个进程画面更新的秒数。预设是5秒
-b: 以批次的方式执行top,还有更多的参数可以使用哦!通常会搭配数据流重导向来将批次的结果输出成为文件。
-n: 与-b搭配,意义是,需要进行几次top的输出结果
-p: 指定某些PID来进行观察监测
在top执行过程中可以使用的按键指令:
    ?: 显示在top中可以输入的按键指令
    P:以CPU的使用资源排序显示
    M:以Memory的使用资源排序显示
    N: 以PID来排序哦
    T: 由该Process使用的CPU时间累积(TIME+)排序
    k: 给予某个PID一个讯号(signal)
    r: 给予某个PID重新制订一个nice值。
    q: 离开top软件的按键
  • pstree
pstree [-AIU] [-up]
选项与参数:
-A:各进程树之意的连接以ASCII字符来连接
-U:各进程树之间的连接以万国码的字符来连接。在某些终端接口下可能会有错误
-p: 并同时列出每个process的PID
-u: 并同时列出每个process的所属帐号名称

16.3.2 进程的管理

  那么进程是如何互相管理的呢?其实是透过给予该进程一个讯号(signal)去告知进程你想要做什么?你可以使用kill -l或者是man 7 signal都可以查询到!主要的讯号代号与名称对应及内容是:

代号 名称 内容
1 SIGHUP 重新启动
2 SIGINT 相当于输入[ctrl]-c,中断
9 SIGKILL 强制中断
15 SIGTERM 正常终止进程
19 SIGSTOP 相当于输入[ctrl]-z,暂停一个进程
  • kill -signal PID
  • killall -signal 指令名称
    可以利用‘下达指令的名称’来给予某个进程一个讯号。
killall [-iIe] [command name]
选项与参数:
-i: interactive的意思,交互式的,若需要删除时,会出现提示字符给用户
-e: exact的意思,表示‘后面接的command name要一致’,但整个完整的指令不能超过15个字符
-I:指令名称(可能含参数)忽略大小写

16.3.4 系统资源的观察

  • free: 观察内存使用情况
free [-b|-k|-m|-g|-h] [-t] [-s N -c N]
选项与参数:
-b: 直接输入free时,显示的单位是Kbytes,我们可以使用b,m,k,g来显示单位,也可以直接让系统自己指定单位(-h)
-t: 在输出的最终结果,显示物理内存与swap的总量
-s: 可以让系统每几秒输出一次,不间断的一直输出的意思
-c: 与-s一起处理~让free列出几次的意思~
  • uname: 查阅系统与核心相关信息
uname [-asrmpi]
选项与参数:
-a: 所有系统相关的信息,包括底下的数据都会被列出来
-s: 系统核心名称
-r: 核心的版本
-m: 本系统的硬件名称,例如i686或x86_64等
-p: CPU的类型
-i: 硬件的平台
  • uptime: 观察系统启动时间与工作负载
    这个指令很单纯呢!就是显示出目前系统已经开机多久的时间,以及1,5,15分钟的平均负载就是了。还记得top吧?没错啦!这个uptime可以显示出top画面的最上面一行!
  • netstat: 追踪网络或插槽文件
    这个指令常被用在网络的监控方面,不过,在进程管理方面也是需要了解的啦!基本上,netstat的输出分为两大部分,分别是网络与系统自己的进程相关性部分:
netstat -[atunlp]
选项与参数:
-a: 将目前系统上所有的联机、监听、Socket数据都列出来
-t: 列出tcp网络封包的数据
-u: 列出udp网络封包的数据
-n: 不以进程的服务名称,以埠号(port number)来显示
-l: 列出目前正在网络监听(listen)的服务
-p: 列出该网络服务的进程PID
  • dmesg: 分析核心产生的讯息
    范例一:输出所有的核心开机时的信息
    dmesg | more
    范例二:搜寻开机时,硬盘的相关信息为何
    dmesg | grep -i vda
  • vmstat: 侦测系统资源变化
    如果你想要动态的了解一下系统资源的运作,那么这个vmstat确实可以玩一玩!vmstat可以侦测【CPU/内存/磁盘输入输出状态】等等。
vmstat [-a] [延迟 [总计侦测次数]] <==CPU/内存等信息
vmstat [-fs]  <==内存相关
vmstat [-S 单位]  <==设定显示数据的单位
vmstat [-d]  <== 与磁盘有关
vmstat [-p 分区槽]  <== 与磁盘有关
选项与参数:
-a: 使用inactive/active(活跃与否)取代buffer/cache的内存输出信息
-f: 开机到目前为止,系统复制(fork)的进程数
-s: 将一些事件(开机至目前为止)导致的内存变化情况列表说明
-S:后面可以接单位,让显示的数据有单位。例如K/M取代bytes的容量
-d: 列出磁盘的读写总量统计表
-p: 后面列出分区槽,可显示该分区槽的读写总量统计表

16.4.2 /proc/* 代表的意义

  其实,我们之前提到的所谓的进程都是在内存当中嘛!而内存当中的数据又都是写入到/proc/这个目录下的,所以啰!我们当然可以直接观察/proc这个目录中的文件啊!
  基本上,目前主机上面的各个进程的PID都以目录的形态存在于/proc当中。举例来说,我们开机所执行的每一支程序systemd他的PID是1,这个PID的所有相关信息都写入在/proc/1/
当中!
  针对整个Linux系统,/proc目录底下的文件与对应的内容是这样的:

档名 文件内容
/proc/cmdline 加载kernel时所下达的相关指令与参数!查阅此文件,可了解指令是如何启动的!
/proc/cpuinfo 本机的CPU的相关信息
/proc/devices 记录了系统各个主要装置的代号
/proc/filesystems 目前系统已经加载的文件系统啰!
/proc/inerrupts 目前系统上面的IRQ分配情况
/proc/ioports 各个装置的I/O地址
/proc/kcore 内存的大小
/proc/loadavg 三个平均负载值
/proc/meminfo 使用free列出的内存信息
/proc/modules Linux已经加载的模块列表
/proc/mounts 已经挂载的数据
/proc/swaps 系统挂载的内存在这里
/proc/patitions 所有的partition
/proc/uptime 就是用uptime时出现的信息
/proc/version 核心的版本
/proc/bus/* 一些总线的装置,还有USB的装置也记录在此喔!

16.4.3 查询已开启文件或已执行进程开启之文件

  • fuser: 藉由文件(或文件系统)找出正在使用该文件的进程
fuser [-umv] [-k [-i] [-signal]] file/dir
选项与参数:
-u: 除了进程的PID之外,同时列出该进程的拥有者
-m: 后面接的那个档名会主动的上提到该文件系统的最顶层,对umount不成功很有效!
-v: 可以列出每个文件与进程还有指令的完整相关性!
-k: 找出使用该文件/目录的PID,并试图以SIGKILL这个讯号给予该PID
-i: 必须与-k配合,在删除PID之前会询问使用者意愿!
-signal: 例如-1 -15等等,若不加的话,预设是SIGKILL(-9)啰!
  • lsof: 列出被进程所开启的文件档名

    选项与参数:
    -a:多项数据需要【同时成立】才显示出结果时
    -U:仅列出Unix Like系统的Socket文件类型
    -u:后面接username,列出该使用者相关进程所开启的文件
    +d:后面接目录,亦即找出某个目录底下已经被开启的文件!
    
  • pidof: 找出某支正在执行的程序的PID

pidof [-sx] program_name
选项与参数:
-s: 仅列出一个PID而不列出所有的PID
-x:同时列出该program name可能的PPID那个进程的PID

16.5 SELinux初探

16.5.1 什么是SELinux

  他是"Security Enhanced Linux"的缩写,字面上的意义就是安全强化的Linux之意!

  • 当初设计的目标:避免资源的误用
  • 传统的文件权限与帐号关系:自主式访问控制,DAC
  • 以政策规则订定特定进程读取特定文件:委任式访问控制,MAC

16.5.2 SELinux的运作模式

  • 主体(Subject)
  • 目标(Object)
  • 政策(Policy)
    在CentOS 7.x里面仅有提供三个主要的政策,分别是:
    • targeted: 针对网络服务限制较多,针对本机限制较少,是预设的政策
    • minimum: 由target修订而来,仅针对选择的进程来保护
    • mls: 完整的SELinux限制,限制方面较为严格。
  • 安全性文本(security context)
    可以使用 ls -Z来观察安全性文本属性,安全性文本是放置到文件inode内的。里面有三个字段:
    Identify:role:type
    这三个字段的意义仔细说明一下吧:
  • 身份识别(Identify):
    • unconfined_u: 不受限的用户,也就是说,该文件来自于不受限的进程所产生的!
    • system_u: 系统用户,大部分就是系统自己产生的文件啰!
  • 角色(Role):
    • object_r: 代表的是文件或目录等的文件资源
    • system_r: 代表的就是进程啦!
  • 类型(Type)(最重要!):
    在预设的targeted政策中,Identify与Role字段基本上是不重要的!重要的在于这个类型(type)字段!基本上,一个主体进程能不能读取到这个文件资源,与类型字段有关!
    • type: 在文件资源(Object)上面称为类型(Type)
    • domain: 在主体进程(Subject)则称为领域(domain)了!
  • 进程与文件SELinux type字段的相关性

16.5.3 SELinux三种模式的启动、关闭与观察

  目前SELinux依据启动与否,共有三种模式,分别如下:

  • enforcing: 强制模式,代表SELinux运作中,且已经正确的开始限制domain/type了
  • permissive: 宽容模式:代表SELinux运作中,不过会有警告讯息并不会实际限制domain/type的存取
  • disabled: 关闭,SELinux并没有实际运作。

  获取目前系统的SELinux模式,是透过getenforce!
  getenforce

  如何知道SELinux的政策(Policy)为何呢?可以使用sestatus来观察:

sestatus [-vb]
选项与参数:
-v: 检查列于/etc/sestatus.conf内的文件与进程的安全性文本内容
-b: 将目前政策的规则布尔值列出,亦即某些规则(rule)是否要启动(0/1)之意。
  • SELinux的启动与关闭
    上面是默认的政策与启动的模式!如果改变了政策则需要重新启动:如果由enforcing或permissive改成disabled,或由disabled改成其他两个,那也必须要重新启动。你只可以在SELinux运作下切换成为强制(enforcing)或宽容(permissive)模式,不能够直接关闭SELinux的!
setenforce [0|1]
选项与参数:
0: 转成permissive宽容模式
1: 转成Enforcing强制模式

16.5.4 SELinux政策内的规则管理

  • SELinux各个规则的布尔值查询 getsebool
    如果想要查询系统上面全部规则的启动与否(on/off,亦即布尔值),很简单的透过sestatus -b或getsebool -a均可!
getsebool [-a] [规则的名称]
选项与参数:
-a: 列出目前系统上面的所有SELinux规则的布尔值为开启或关闭值
  • SELinux各个规则规范的主体进程能够读取的文件SELinux type查询seinfo,sesearch
    先安装好我们所需要的软件才行!
    yum install /mnt/Packages/setools-console-*
seinfo [-Atrub]
-A: 列出SELinux的状态、规则布尔值、身份识别、角色等所有信息
-u: 列出SELinux的所有身份识别(user)种类
-r: 列出SELinux的所有角色(role)种类
-t: 列出SELinux的所有类别(type)种类
-b: 列出所有规则的种类(布尔值)
sesearch [-A] [-s 主体类别] [-t 目标类别] [-b 布尔值]
选项与参数:
-A:列出后面数据中,允许【读取或放行】的相关数据
-t: 后面还要接类别,例如-t httpd_t
-b: 后面还要接SELinux的规则,例如 -b httpd_enable_ftp_server

范例一:找出crond_t这个主体进程能够读取的文件SELinux type
sesearch -A -s crond_t | grep spool

  • 修改SELinux规则的布尔值setbool
setsebool [-P] [规则名称] [0|1]
选项与参数:
-P: 直接将设定值写入配置文件,该设定数据未来会生效的!

范例一:查询httpd_enable_homedirs这个规则的状态,并且修改这个规则成为不同的布尔值

getsebool httpd_enable_homedirs
setsebool -P httpd_enable_homedirs 1
getsebool httpd_enable_homedirs

16.5.5 SELinux安全文本的修改

  • 使用chcon手动修改文件的SELinux type
chcon [-R] [-t type] [-u user] [ -r role] 文件
chcon [-R] --reference=范例文件 文件
选项与参数:
-R:连同该目录下的次目录也同时修改
-t: 后面接安全性文本的类型字段!例如httpd_sys_content_t
-u: 后面接身份识别,例如system_u
-r: 后面接角色,例如system_r
-v: 若有变化成功,请将变动的结果列出来
--reference=范例文件:拿某个文件当范例来修改后续接的文件的类型!

范例一:查询一下/etc/hosts的SELinux type,并将该类型套用到/etc/cron.d/checktime上

ll -Z /etc/hosts
chcon -v -t net_conf_t /etc/cron.d/checktime
ll -Z /etc/cron.d/checktime
  • 使用restorecon让文件恢复正确的SELinux type
restorecon [-Rv] 文件或目录
-R:连同次目录一起修改
-v: 将过程显示到屏幕上

范例三:将/etc/cron.d/底下的文件通通恢复成预设的SELinux type!
restorecon -Rv /etc/cron.d

  • semanage 默认目录的安全性文本查询与修改
semanage {login|user|port|interface|fcontext|translation} -l
semanage fcontext -{a|d|m} [-first] file_spec
选项与参数:
fcontext: 主要用在安全性文本方面的用途,-l为查询的意思
-a: 增加的意思,你可以增加一些目录的默认安全性文本类型设定
-m: 修改的意思
-d:删除的意思

范例一:查询一下/etc /etc/cron.d的预设SELinux type为何?
semanage fcontext -l | grep -E '^/etc | ^/etc/cron'