此文档说明如何在 ubuntu 上启用 SELinux,测试环境为虚拟机,开始前一定一定一定先来个快照,不要问我为什么有三个一定。
ubuntu 默认安装的安全组件为 apparmor,网上文档说最好卸载掉 apparmor,可能冲突之类的问题,说法可能有点有误啊,apparmor 和 selinux 不兼容,当启用 selinux 后,apparmor 是不会生效的,所以应该是没有冲突这一说法,想卸载的可以执行以下命令。
sudo systemctl stop apparmor
sudo apt purge apparmor
sudo apt install selinux-basics
此命令会安装 SELinux default 策略,以及相关库、工具等等
sudo apt install auditd
auditd 用来收集 SELinux 相关日志,特别是访问拒绝日志
sudo apt install setools setoos-gui
包含了 SELinux 策略分析工具 apol
sudo apt install selinux-policy-dev
开发 selinux 相关程序需要用到此开发包
sudo selinux-activate
此命令做了两件事:
增加启动参数 security=selinux,意思是说系统的安全模块为 selinux,内核启动时,许多模块都需要传入相关参数,来开启或关闭某些功能。
启动参数位于 /boot/grub/grub.cfg 文件,sudo selinux-activate
之后我们可以看到如下字样:
linux /boot/vmlinuz-5.15.0-53-generic root=UUID=a1b7da65-54d8-415f-b4c0-6dc75fa37cf8 ro security=selinux quiet splash $vt_handoff
当前系统的启动参数可以通过命令 cat /proc/cmdline
查看
在 / 根目录下创建 .autorelabel 文件,selinux 有一个开机自启动脚本,它会检查 .autorelabel 文件是否存在,如果存在,那么便会开始给整个文件系统上面的文件打上标签,可以理解为初始化客体安全上下文的操作,具体细节后面讲述。
SELinux 有三种模式:
SELinux 的配置文件为 /etc/selinux/config
,如下所示:
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
# default - equivalent to the old strict and targeted policies
# mls - Multi-Level Security (for military and educational use)
# src - Custom policy built from source
SELINUXTYPE=default
# SETLOCALDEFS= Check local definition changes
SETLOCALDEFS=0
这是默认的配置,有两项重要的内容:
NOTE:第一次使能 SELinux 时,千万千万千万不要将设置 SELINUX=enforcing,千万千万千万不要执行 sudo selinux-config-enforcing
命令,它会设置 SELINUX=enforcing。不要问我为什么有三个千万,网上有的教程就是让第一次使能 SELinux 的朋友执行 SELINUX=enforcing,这不是坑人吗
重启 ubuntu,在启动时,应该会出现如下所示的界面:
这就是在为整个文件系统打标签,可能需要等待一会儿,因为给磁盘上文件打标签本质上是在设置文件的 xattr 属性,所以比较慢
按照上面的步骤,不出意外的话应该是可以正常启动的,不能正常启动的解决方法见后
sestatus
命令查看当前 SELinux 状态
rand@rand-virtual-machine:~$ sestatus
SELinux status: enabled //SELinux 处于使能状态
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: default
Current mode: permissive //SELinux 当前模式为 permissive,setenforce 命令可以修改
Mode from config file: permissive //config文件中记录的模式
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: requested (insecure)
Max kernel policy version: 33
其他项的含义后面再详述,这里看到状态为 enabled、模式为 permissive 就行
getenforce 可以查看当前的 SELinux 模式
rand@rand-virtual-machine:~$ getenforce
Permissive
setenforce 可以修改当前的模式,0 表示 permissive,1 表示 enforcing
SELinux 刚使能,不要去执行 setenforce 1
开启 enforcing 模式,会死机的
ls -Z
可以查看文件的安全上下文(标签)
rand@rand-virtual-machine:~$ ls -Z
system_u:object_r:user_home_t:s0 公共的
system_u:object_r:user_home_t:s0 模板
system_u:object_r:user_home_t:s0 视频
system_u:object_r:user_home_t:s0 图片
安全上下文总共由四部分组成,第三部分 user_home_t 则是前文说到的类型,这里表示 “视频” “图片” 这几个目录的类型为 user_home_t。其余部分后面再讲述
ps -Z
可以查看进程的安全上下文
rand@rand-virtual-machine:~$ ps -Z
LABEL PID TTY TIME CMD
system_u:system_r:initrc_t:s0 2306 pts/0 00:00:00 bash
system_u:system_r:initrc_t:s0 2513 pts/0 00:00:00 ps
bash 这个进程的类型为 initrc_t
不能正常开机,多半两个问题:
如何解决呢?
系统启动时按下 Esc 键,进入如下界面:
第一个选项中按下 e 键,进入如下界面:
找到 linux 这一行,这一行便是启动参数,这里添加 selinux=0,"="两边不要有空格,selinux=0 表示禁止 selinux
按下 ctrl+x 重启,不出意外的话可以正常重启,执行 sestatus 命令,发现 selinux 禁止了
rand@rand-virtual-machine:~$ sestatus
SELinux status: disabled
NOTE,此种方式修改启动参数只当前启动有效,如果想要永久生效,可以自己手动修改 /boot/grub/grub.cfg 文件
如果出现意外了,还是不能重启?
同样的系统启动时 Esc 进入grub,然后选择 “Ubuntu 的高级选项”,英文应该是 “Advanced options for ubuntu”
然后选择一个 recovery mode 回车
选择 root
此时会拉起一个 shell,让你登录 root 账户,这里需要 root 的密码,root 密码可能需要进入系统进行初始设置但你又进不去系统,死锁?反正这里先假设你有 root 账户
获取到 root shell 之后,修改 /etc/selinux/config 文件中的 SELINUX=permissive,或者 SELINUX=disabled 直接禁掉
在 / 根目录下 touch .autorelabel
创建文件,加一重保险,执行 echo -F > .autorelabel
这是为了强制对文件系统按照当前策略配置文件打标签,具体原因后面篇章详述
设置完成后,reboot 重启,应该是能正常重启了
还不能重启?恢复快照吧,在初期不熟悉 SELinux 的时候,使能时可能会遇到各种感觉匪夷所思的问题,所以最好时备份一下。
好了,本文就先到这里,后面篇章再说明动态添加策略以开启 enforcing 模式的问题,有什么问题欢迎来讨论交流。