Linux PAM和AppArmor

发布时间 2023-11-02 13:55:08作者: 背对背依靠

PAM 介绍

PAM全称叫作Pluggable Authentication Modules,译为可插拔验证模块。1995年起源于sun公司,PAM是一个框架,通过PAM框架提供的接口,应用程序可以不关心基层具体的实现过程,直接调用接口实现身份验证功能。PAM还有一个功能就是在用户空间就是先对用户的资源进行限制。

PAM不是Linux内核的一个模块,而是一个许多Linux发行版系统的标准组件,使用这个组件为系统和应用程序提供身份验证的框架。

PAM由三部分组成,模块、库和配置文件。通过编写配置文件调用指定的库和模块,实现为特定的应用程序或服务实现身份验证管理以及资源限制的功能。

一般情况下,库文件、模块文件和配置文件的存放路径如下:

  • 库文件和模块文件:/lib/security 或 /lib64/security 目录中(ubuntu2004中,是放在/usr/lib/x86_64-linux-gnu/security)

  • 配置文件:主配置文件是:/etc/pam.conf 子配置文件时:/etc/pam.d/

例如:

在ubuntu2004中,pam的库和模块文件在:/usr/lib/x86_64-linux-gnu/security下

PAM 有一个主配置文件 /etc/pam.conf,这个文件使用得不多;更常见的是每个服务或程序都有其自己的配置文件,这些文件位于 /etc/pam.d/ 目录中。

身份验证管理

(1)创建配置文件
要使用PAM模块来实现对应用程序的身份验证进行管理,需要在/etc/pam.d/目录中创建一个和程序同名的配置文件

一般情况下也不上去创建什么配置文件,首先程序得支持pam,常见对应得文件才会生效。对于一些简单的使用,会修改pam自带的一些配置文件进行相关身份验证管理就行了。

例如:SSH服务的PAM配置文件是/etc/pam.d/sshd

(2)编辑配置

PAM的配置文件格式是:

操作类型 控制标志 模块名称 模块参数

操作类型:
表明定义的这条PAM规则是用来做什么的。

  • auth: 验证用户身份。

  • account: 验证用户是否有权进行所请求的操作

  • password: 密码管理

  • session: 设置用户登录前后的会话环境

控制的标志:

描述了当关联的模块执行失败时应如何处理。

  • required: 该模块必须执行成功。如果失败,用户不会立即得知,但最终的认证会失败

  • requisite: 如果该模块失败,立即返回并告诉用户认证失败

  • sufficient: 如果该模块成功,那么整体认证可以被认为是成功的(除非之前有 required 模块失败)

  • optional: 这个模块的执行结果不是必需的,除非它是唯一的模块

常用模块:

PAM的模块很多,一般常用的就这些。

  • pam_unix.so :处理 UNIX 风格的用户密码验证和更新策略

  • pam_pwquality.so : 这个模块定义了密码复杂度的要求。通过它,管理员可以设置密码的长度、字符类型、旧密码的记忆等多种策略。

  • pam_tally2.so :定义登录失败次数的跟踪功能、用户锁定功能

  • pam_limits.so :在用户级别实现对其可使用的资源的限制

用户密码策略管理

如果要设置用户密码的最小长度是8,每90天改一次密码,一天最多修改一次密码。这个时候就需要使用 pam_unix.so 库,通过这个库可以处理密码验证相关的操作。

(1)编辑 /etc/login.defs
这个配置文件为Linux系统中的用户账户管理定义了一系列默认参数。这些参数主要涉及用户登录、账户行为、密码策略等。

虽然/etc/login.defs 与 PAM 有关联,但它是一个独立的配置文件,不是由PAM直接管理的,所以不遵循PAM的配置文件格式。

但 /etc/login.defs 才是负责提供了某些默认的策略设置,而pam_unix.so 是实际执行身份验证的模块

(1)修改配置文件
将配置文件中的以下变量进行修改,即可实现用户密码管理

sudo vim /etc/login.defs
# 密码有效期
	PASS_MAX_DAYS 90
# 多久可以改一次密码 0表示不限制
	PASS_MIN_DAYS 1
# 密码的最小长度
	PASS_MIN_LEN 8
# 密码过期之前多少天开始警告用户
	PASS_WARN_AGE 28

密码复杂度配置

如果我想设置密码最小长度是8为,必须包含两个大写字母,一个小写字母,四个数字和一个其它符号。可以通过 pam_pwquality.so模块实现,在配置文件中找到和pam_pwquality.so模块相关的行,并在该行中指定参数即可实现。

(1)编辑配置文件

这个配置文件根据Linux发行版的不同可能所有不同,在Red Hat系列中,配置文件是:/etc/pam.d/system-auth。在debian系列中,配置文件是:/etc/pam.d/common-password

(2)修改配置文件的值

sudo vim /etc/pam.d/common-password

password requisite pam_pwquality.so  retry=3  minlen=8  ucredit=-2  lcredit=-1  dcredit=-4  ocredit=-1

说明:

  • minlen=8: 密码的最小长度应为8个字符

  • ucredit=-2: 密码中必须至少包含2个大写字母

  • lcredit=-1: 密码中必须至少包含1个小写字母

  • dcredit=-4: 密码中必须至少包含4个数字

  • ocredit=-1: 密码中必须至少包含1个其他的符号(例如,标点符号)

登录限制配置

如果我想配置限制非法登录次数为10次,10次后锁定普通账号及ROOT账号10分钟,可以通过调用pam_tally2.so模块实现,因为当用户尝试通过命令行界面登录系统时,login程序会使用这个文件中定义的PAM模块来处理认证、账户管理、会话管理以及密码管理。

(1)编辑配置文件

登录限制相关的配置是编辑/etc/pam.d/login文件

sudo vim /etc/pam.d/login

(2)修改配置文件

找到 pam_tally2.so 所在行,然后添加相关参数,如果没有就加一行。

auth required pam_tally2.so deny=10 onerr=fail even_deny_root unlock_time=600 root_unlock_time=600

空闲退出终端

如果想设置空闲指定时间自动退出终端,可以使用shell的 TMOUT这个环境变量实现。默认这个变量是0,即表示不限制,如果设置为非0,空闲了指定时间就会退出shell终端。

一般做法是将这个环境变量定义在 /etc/profile 这个shell脚本中实现持久化生效。

sudo vim /etc/profile
export TMOUT=300

用户资源管理

在用户空间对用户的资源使用进行限制,这是pam的两大基础功能之一。具体实现就是通过pam_limits.so 模块实现的,但是有一点不同的是,这个模块是单独设计了配置文件,是通过/etc/security/limits.conf(或 /etc/security/limits.d/ 目录下的文件)定义相关规则,后台调用pam_limits.so 模块实现。

所以/etc/security/limits.conf配置文件的风格和PAM的标准风格是不一样的。具体格式就是:

要对谁进行限制  限制的类型(通常是 soft 或 hard)  限制的资源类型  资源的限制值

限制类型说明:

常用的限制是软限制和硬限制,软限制是超过了资源限制值,只会警告你,不会拒绝你。而限制则是,超过资源限制值,直接拒绝你的操作。

资源类型说明:

资源类型常用的有两种,用户打开文件数量和用户可以拥有的最大进程数量,在一些高并发的场景下,默认的值(1024)可能不满足需求。

  • nofile:(number of file)描述用户打开文件的数量

  • nproc:(number of process)描述用户可以拥有的最大进程数量

例如:

   *        hard       nofile           2048

表示对所有用户(*)进行强制限制,限制用户最为可以打开的文件数量(nofile:number of files)为2048个

ulimit 命令

如果想查看当前用户在当前的 shell 会话中的一些资源限制,可以使用ulimit的 -a 参数来查看,如果想临时修改的话,通过 ulimit 对应参数 对应参数值 这种方式修改即可。

查看当前用户在当前shell中的资源限制:

ulimit -a

AppArmor 介绍

AppArmor是Linux的一个内核安全模块,它是 基于路径来限制程序能够访问的资源,从而增强系统的安全性。大多数情况下,在 Ubuntu 和 openSUSE 等发行版中默认启用了AppArmor模块,Red Hat系列的发行版默认启动的是SELinux模块。

AppArmor一般是用在 特定路径下隔离应用程序的环境,例如可以限制一个进程只能访问必要的文件和目录,此时该进程不会被允许访问系统上的任何其他文件或目录

AppArmor有两种工作模式:

enforce(强制)模式和complain(投诉)模式,强制模式下不符合策略的操作会被拒绝。而投诉模式下不会组织不符合策略的操作,只会记录到日志。

AppArmor规则策略文件:

AppArmor为进程定义的策略规则是存放在 /etc/apparmor.d/ 目录中,策略规则文件命名方式按照 进程所在的绝对路径命名(需要把/换为.)

例如:

为 /usr/sbin/named 定义的 AppArmor 策略文件将命名为 usr.sbin.named。因为named进程的路径是:/usr/sbin/named

AppArmor 策略文件也是特别简单的,只需要在配置文件里面加入相关文件路径,然后指定权限。策略生效后进程就只能按照定义的策略队则权限去访问一个文件了,给指定进程加了策略后,

配置文件格式如下:

进程的绝对路径 flags=(attach_disconnected) {
	文件绝对路径  运行操作的权限,

}
  • r:代表读取权限

  • w:代表写入权限

  • k:允许指定进程锁定文件

  • l:代表链接权限

  • m:代表执行权限,并将文件作为共享对象加载

例如:

给某个进程A编写一个策略文件,策略规则是只能以读权限访问B文件,那么除了B文件他有读权限,其它目录相对于这个进程来说,什么操作权限都没有。

/path/A flags=(attach_disconnected) {

  /path/to/file/B r, # 允许进程只读访问文件A
}

管理工具

AppAemor提供了很多工具来对策略进行管理

aa-status

aa-status是用于显示当前系统上运行的AppArmor策略状态,直接在命令行输入这个命令就可以显示相关信息

ehigh@ubuntu:~$ sudo aa-status
# 表示加载了25个策略配置文件
25 profiles are loaded.
# 25个策略配置文件用的都是enfoce模式
25 profiles are in enforce mode.
	# 有25个策略文件处于强制模式,并且列出对应的进程路径
   /usr/bin/evince
   /usr/bin/evince-previewer
   /usr/bin/evince-previewer//sanitized_helper
   /usr/bin/evince-thumbnailer
   /usr/bin/evince//sanitized_helper
   /usr/bin/man
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/NetworkManager/nm-dhcp-helper
   /usr/lib/connman/scripts/dhclient-script
   /usr/lib/cups/backend/cups-pdf
   /usr/sbin/cups-browsed
   /usr/sbin/cupsd
   /usr/sbin/cupsd//third_party
   /usr/sbin/mysqld
   /usr/sbin/named
   /usr/sbin/ntpd
   /usr/sbin/tcpdump
   /{,usr/}sbin/dhclient
   docker-default
   ippusbxd
   lsb_release
   man_filter
   man_groff
   nvidia_modprobe
   nvidia_modprobe//kmod
# 0个策略配置用的complain模式
0 profiles are in complain mode.
# 系统上有5个正在运行的进程有定义的AppArmor策略
5 processes have profiles defined.
# 这5个有定义的AppArmor策略的进程都处于强制模式。然后列出了这些进程及其ID,
5 processes are in enforce mode.
   /usr/sbin/cups-browsed (2804193)
   /usr/sbin/cupsd (2804192)
   /usr/sbin/mysqld (2560)
   /usr/sbin/named (493443)
   /usr/sbin/ntpd (958691)
# 没有进程处于投诉模式
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

例如:

sudo aa-status | grep named

/usr/sbin/named:表示 /usr/sbin/named 有一个与之关联的 AppArmor 策略

/usr/sbin/named (493443):表示当前正在运行的 /usr/sbin/named 进程有一个进程 ID 为 493443,并且该进程受到上面提到的 AppArmor 策略的保护

aa-enforce

aa-enforce:是用来将指定的AppArmor策略设置为强制模式,使用时指定策略文件的路径就行了。

aa-enforce <PROFILE_PATH>

# 重新加载生效
apparmor_parser -r /path/to/profile

aa-complain

aa-complain 工具用于将指定的AppArmor策略设置为投诉模式。

aa-complain <PROFILE_PATH>

# 重新加载生效
apparmor_parser -r /path/to/profile

禁用 AppAemor

(1)停止apparmor服务

sudo systemctl stop apparmor

(2)禁用apparmor服务

sudo systemctl disable apparmor