Linux权能与PAM机制

实验环境:uname -a

Linux ubuntu 4.4.0-121-generic #145-Ubuntu SMP Fri Apr 13 13:47:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux


权能对应的系统调用

使用 sudo find / -name capability.h 查找到路径 /usr/src/linux-headers-4.4.0-121/include/uapi/linux/capbility.h ,整理可得下表:

权能 编号(相关系统调用) 解释
CAP_CHOWN 0(chown) 对文件的UIDs和GIDs做任意修改
CAP_DAC_OVERRIDE 1 忽略对文件的DAC访问限制
CAP_DAC_READ_SEARCH 2 忽略DAC中对文件和目录的读、搜索权限
CAP_FOWNER 3 忽略进程UID与文件UID的匹配检查
CAP_FSETID 4 文件修改时不清除setuid和setgid位,不匹配时设置setgid位
CAP_KILL 5(kill) 绕过发送信号时的权限检查
CAP_SETGID 6(setgid) 设置或管理进程GID
CAP_SETUID 7(setuid) 管理或设置进程UID
CAP_SETPCAP 8(capset) 允许授予或删除其他进程的任何权能
CAP_LINUX_IMMUTABLE 9(chattr) 允许设置文件的不可修改位(IMMUTABLE)和只添加(APPND-ONLY)属性
CAP_NET_BIND_SERVICE 10 允许绑定到小于1024的端口
CAP_NET_BROADCAST 11 允许socket发送监听组播
CAP_NET_ADMIN 12 允许执行网络管理任务
CAP_NET_RAW 13(socket) 允许使用原始套接字
CAP_IPC_LOCK 14(mlock) 允许锁定共享内存片段
CAP_IPC_OWNER 15 忽略IPC所有权检查
CAP_SYS_MOUDLE 16(init_module) 插入和删除内核模块
CAP_SYS_RAWIO 17 允许对ioperm/iopl的访问
CAP_SYS_CHROOT 18(chroot) 允许使用chroot()系统调用
CAP_SYS_PTRACE 19(ptrace) 允许跟踪任何进程
CAP_SYS_PACCT 20(acct) 允许配置进程记账
CAP_SYS_ADMIN 21 允许执行系统管理任务
CAP_SYS_BOOT 22(reboot) 允许重新启动系统
CAP_SYS_NICE 23(nice) 允许提升优先级,设置其他进程优先级
CAP_SYS_RESOURCE 24(setrlimit) 设置资源限制
CAP_SYS_TIME 25(stime) 允许改变系统时钟
CAP_SYS_TTY_CONFIG 26(vhangup) 允许配置TTY设备
CAP_MKNOD 27(mknod) 允许使用mknod()系统调用,创建特殊文件
CAP_LEASE 28(fcntl) 为任意文件建立租约
CAP_AUDIT_WRITE 29 允许向内核审计日志写记录
CAP_AUDIT_CONTROL 30 启用或禁用内核审计,修改审计过滤器规则
CAP_SETFCAP 31 设置文件权能
CAP_MAC_OVERRIDE 32 允许MAC配置或状态改变,为smack LSM实现
CAP_MAC_ADMIN 33 覆盖强制访问控制
CAP_SYSLOG 34(syslog) 执行特权syslog(2)操作
CAP_WAKE_ALARM 35 触发将唤醒系统的东西
CAP_BLOCK_SUSPEND 36(epoll) 可以阻塞系统挂起的特性
CAP_AUDIT_READ 37 允许通过一个多播socket读取审计日志

详情见man capabilities


基于PAM用户权限设置系统

PAM 的全称为“可插拔认证模块(Pluggable Authentication Modules)”。设计的初衷是将不同的底层认证机制集中到一个高层次的API中,从而省去开发人员自己去设计和实现各种繁杂的认证机制的麻烦。

PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so,PAM配置文件在/etc/pam.d/ 目录下,原理图如下:

pam

PAM中配置字段:

1
moudle_type  control_flag  moudle_path moudle_option/moudle_args
  1. module_type 为 相应服务指定模块类型
模块类型 说明
auth(验证模块) 用于验证用户或设置/销毁凭证
account(帐户管理模块) 将执行与访问、帐户及凭证有效期、密码限制/规则等有关的操作
session(会话管理模块) 定义用户登录前的,及用户退出后所要进行的操作.如:登录连接信息,用户数据的打开与关闭,挂载文件系统等
passwd(密码管理模块) 将执行与密码更改/更新有关的操作
  1. control_flag 将指定模块的堆栈行为,配置文件中列出模块被调用的顺序
控制标记 说明
required 堆栈中的所有 required 模块必须看作一个成功的结果。如果一个或多个 required 模块失败,则实现堆栈中的所有 required 模块,但是将返回第一个错误
requisite 如果本模块没有被满足,那本次认证一定失败,而且整个栈立即中止并返回错误信号
sufficient 如果标记为 sufficient 的模块成功并且先前没有 required 或 sufficient 模块失败,则忽略堆栈中的所有其余模块并返回成功
optional 如果堆栈中没有一个模块是 required 并且没有任何一个 sufficient 模块成功,则服务/应用程序至少要有一个 optional 模块成功
include 包含其他规则(服务),文件嵌套,可以互相调用,如:login,auth,system-auth等
[value1=action1 value2=action2 ….] 六种动作:ok ,done,bad,die,ignore,reset。

​ Example:auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so

  1. module_path 将指定实现模块的库对象的路径名称。默认情况下,它将被设为 /lib/securitylibpam
  2. module_options/module_args(可选字段)将指定可以传递给服务模块的选项或实参。

实验:配置用户userping ,设置cap_net_raw 权能。

  • 添加用户userping : sudo adduser userping
  • 查看并清除/bin/ping 的权能:

选区_057

  • 切换到用户userpingping 无法ping : su userping
  • userping 登录时给/bin/ping 添加权能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#####################################################
# File Name: ping_cap.sh
# Author: xsyin
# mail: shouyinXu@163.com
# Created Time: 2018年04月30日 星期一 16时05分57秒
####################################################

#!/bin/sh
[ "$PAM_TYPE" == "open_session" ] || exit 0

if [ "$PAM_USER" == "userping" ]; then
setcap cap_net_raw=eip /bin/ping
echo "SUCCESS"
else
echo "FAILURE"
fi

  • ping_cap.sh 移动到 /usr/local/bin 路径下,并设置为可执行:
1
sudo chmod u+x /usr/loca/bin/ping_cap.sh
  • 所有登录都使用common-session 模块:

选区_058

因此在common-session 模块中添加规则:

1
session  optional  pam_exec.so debug log=/tmp/pam_exec.log seteuid /usr/local/bin/ping_cap.sh

必须模块,开启了debug模式,用户userping 每次登录会执行ping_cap.sh

  • 切换到userping 用户:

选区_059

出错多次,最终调试成功:

选区_060

总结

优点:userping 用户无法执行特权命令,通过pam 可赋予一些特权操作。

缺点:本实验中修改了ping 的文件权能,影响了其他用户。退出userping 后,ping 命令变成有效了。

过渡C版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*************************************************************************
> File Name: ping_cap.c
> Author: xsyin
> Mail: shouyinXu@163.com
> Created Time: 2018年04月30日 星期一 14时56分35秒
> Make: gcc ping_cap.c -lcap -o ping_cap
************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>

#undef _POSIX_SOURCE

extern int errno;

const char *path_p = "/bin/ping";

void listCaps(){
cap_t caps = cap_get_file(path_p);
ssize_t y = 0;
printf("The file %s was give capabilities %s\n",path_p, cap_to_text(caps, &y));
fflush(0);
cap_free(caps);
}

int main(int argc, char const *argv[])
{


uid_t uid = getuid();

if(uid != 1000)
return 0;

printf("uid:%d\n", uid);

cap_value_t cap_values[] = {CAP_NET_RAW};
cap_t caps = cap_init();
cap_set_flag(caps,CAP_PERMITTED,1,cap_values,CAP_SET);
cap_set_flag(caps,CAP_EFFECTIVE,1,cap_values,CAP_SET);
cap_set_flag(caps,CAP_INHERITABLE,1,cap_values,CAP_SET);
if(cap_set_file(path_p,caps))
perror("cap_set_file() ERROR: ");
else
printf("success\n");
cap_free(caps);
listCaps();

return 0;
}

缺陷:未搞清楚如何获取PAM正在授权的用户,无法判断切换至userping 用户时设置权能。