PAM和权能是两个不同的概念
权能(Capabilities, 能力)
简介
在Ubuntu 22.04.2 LTS的终端中输入man capabilities
可以查看权能参考手册。
For the purpose of performing permission checks, traditional UNIX implementations distinguish two categories of processes: privileged processes (whose effective user ID is 0, referred to as superuser or root), and unprivileged processes (whose effective UID is nonzero). Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process’s credentials (usually: effective UID, effective GID, and supplementary group list).
早期的UNIX将effective user ID(euID)为0的进程视为特权进程,将euID不为0的视为非特权进程。特权进程可以绕过内核权限检查,而非特权进程则不行。
这种权限划分粒度是非常粗糙的。
Starting with kernel 2.2, Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled and disabled. Capabilities are a per-thread attribute.
从内核2.2版本开始,root用户的特权分解为不同的能力(capabilities,权能)。由此,每个进程都会有不同的能力(权能)。
能力列表
在Ubuntu 22.04.2 LTS的man capabilities
手册中,有41种不同的权能。具体介绍如下。
名称 | 最低版本 | 描述 |
---|---|---|
CAP_AUDIT_CONTROL | Linux 2.6.11 | 启用和禁用内核审计;改变审计过滤规则;检索审计状态和筛选规则 |
CAP_AUDIT_READ | Linux 3.16 | 允许通过多播网络链接套接字读取审核日志 |
CAP_AUDIT_WRITE | Linux 2.6.11 | 向内核审计日志写记录 |
CAP_BLOCK_SUSPEND | Linux 3.5 | 应用可阻止系统挂起的功能()epoll(7) EPOLL‐WAKEUP, /proc/sys/wake_lock) |
CAP_BPF | Linux 5.8 | 应用BPF特权操作;参见bpf(2)与bpf-helpers(7)。将BPF能力与过分臃肿的CAP_SYS_ADMIN能力分开。 |
CAP_CHECKPOINT_RESTORE | Linux 5.9 | Update /proc/sys/kernel/ns_last_pid (see pid_namespaces(7) ); employ the set_tid feature of clone3(2) ; read the contents of the symbolic links in /proc/[pid]/map_files for other processes.将检查点/恢复功能与过分臃肿的CAP_SYS_ADMIN能力分开。 |
CAP_CHOWN | 对文件UID和GID进行任意更改(参见chown(2) ) | |
CAP_DAC_OVERRIDE | 绕过文件读取、写入和执行权限检查(DAC,自主访问控制) | |
CAP_DAC_READ_SEARCH | 绕过文件读取、目录读取权限检查,绕过执行权限检查;调用open_by_handle_at(2);使用linkat(2) 的AT_EMPTY_PATH 标志,以用文件描述符创建指向文件的链接 | |
CAP_FOWNER | 绕过通常需要进程的文件系统UID与文件的UID匹配的操作的权限检查(例如,chmod(2) 、utime(2) ),不包括CAP_DAC_OVERRIDE 和CAP_DAC_READ_SEARCH 所涵盖的操作;在任意文件上设置inode标志(参见ioctl_iflags(2) );对任意文件设置访问控制列表(ACL);删除文件时忽略目录粘性位;修改任何用户拥有的粘性目录上的用户扩展属性;为open(2) 和fcntl(2) 中的任意文件指定O_NOATIME | |
CAP_FSETID | 文件被修改时,不清除set-user-ID和set-group-ID模式位;为GID与文件系统或调用进程的任何补充GID不匹配的文件设置set-group-ID位。 | |
CAP_IPC_LOCK | Lock memory (mlock(2) , mlockall(2) , mmap(2) , shmctl(2) ) | |
CAP_IPC_OWNER | 绕过在System V IPC对象上操作的权限检查 | |
CAP_KILL | 绕过发送信号的许可检查(参见kill(2) )。这包括使用ioctl(2) KDSIGACCEPT操作 | |
CAP_LEASE | Linux 2.4 | 对任意文件建立租约(请参见fcntl(2) ) |
CAP_LINUX_IMMUTABLE | 设置FS_APPEND_FL 和FS_IMMUTABLE_FL inode节点标志(参见ioctl_iflags(2) ) | |
CAP_MAC_ADMIN | Linux 2.6.25 | 允许MAC配置或状态更改。为Smack Linux Security Module (LSM)而实现 |
CAP_MAC_OVERRIDE | Linux 2.6.25 | 超控MAC。为Smack LSM而实现 |
CAP_MKNOD | Linux 2.4 | 使用mknod(2) 创建特殊文件 |
CAP_NET_ADMIN | 执行网络相关操作:接口配置;管理IP firewall(防火墙), masquerading(IP伪装), and accounting(IP记账);修改路由表;绑定到任何地址以进行透明代理;设定set type-of-service (TOS);清除驱动程序统计信息;设定混杂模式;允许多播;使用setsockopt(2) 设置以下套接字选项:SO_DEBUG 、SO_MARK 、SO_PRIORITY (对于0到6范围之外的优先级)、SO_RCVBUFFORCE 和SO_SNDBUFFORCE | |
CAP_NET_BIND_SERVICE | 将套接字绑定到Internet域特权端口(端口号小于1024) | |
CAP_NET_BROADCAST | (未使用)进行套接字广播,并监听多播 | |
CAP_NET_RAW | 使用RAW和PACKET套接字;绑定到任何地址以进行透明代理 | |
CAP_PERFMON | Linux 5.8 | 采用各种性能监测机制,包括:调用perf_event_open(2) ;采用具有性能影响的各种BPF操作。添加此能力,以将性能监视功能与过分臃肿的CAP_SYS_ADMIN 能力分离。另请参阅内核源文件Documentation/admin-guide/perf-security.rst |
CAP_SETGID | 对进程GID和补充GID列表进行任意操作;通过UNIX域套接字传递套接字凭据时伪造GID;在用户名称空间中写入组ID映射(参见user_namespaces(7) ) | |
CAP_SETFCAP | Linux 2.6.24 | 为文件设置任意能力 |
CAP_SETPCAP | 如果支持文件能力(从Linux 2.6.24开始):将主调线程的边界集中的任何功能添加到其可继承集;从边界集丢弃能力(通过prctl(2) PR_CAPBSET_DDROP );对安全比特标志进行更改。如果不支持文件功能(Linux 2.6.24 之前的内核):向任何其他进程授予或从任何其他进程中删除调用方允许的能力集中的任何能力。(当内核被配置为支持文件能力时,CAP_SETPCAP 的此属性不可用,因为CAP_SETPPAP 对这样的内核具有完全不同的语义) | |
CAP_SETUID | 对进程UID执行任意操作(setuid(2) );通过UNIX域套接字传递套接字凭据时伪造UID;在用户名称空间中写入用户ID映射(参见user_namespaces(7) ) | |
CAP_SYS_ADMIN | 注意:此能力过度臃肿。执行一系列系统管理操作,包括:quotactl(2) , mount(2) , umount(2) , pivot_root(2) , swapon(2) , swapoff(2) , sethostname(2) , setdomainname(2) ;执行特权syslog(2) 操作(Linux 2.6.37及之后,应使用CAP_SYSLOG 来允许此类操作);执行VM86_REQUEST_IRQ vm86(2) 命令;访问由CAP_CHECKPOINT_RESTORE 管理的同样的检查点/恢复功能(但后者的访问该功能的能力较弱);执行与CAP_BPF 所管理的相同的BPF操作(但后者的访问该功能的能力较弱);采用与CAP_PERFMON 相同的性能监控机制(但后者更倾向于使用较弱的功能);对任意System V IPC对象执行IPC_SET 和IPC_RMID 操作;覆盖RLIMIT_NPROC 资源限制;对受信任和安全扩展属性执行操作(参见xattr(7) );使用lookup_dcookie(2) ;使用ioprio_set(2) 分配IOPRIO_CLASS_RT 和IOPRIO_CLASS_IDLE I/O (在Linux 2.6.25之前)调度类;通过UNIX域套接字传递套接字凭据时伪造PID;在打开文件的系统调用中,超过/proc/sys/fs/file-max,即系统范围内对打开文件数量的限制(例如,accept(2) , execve(2) , open(2) 和pipe(2) );使用CLONE_* 标志来创建带有clone(2) 和unshare(2) 的新名称空间(但是,自从Linux 3.8开始,创建用户名称空间不需要任何能力);访问特权性能事件信息;调用setns(2) (需要在目标命名空间中具备CAP_SYS_ADMIN 能力);调用fanotify_init(2) ;执行特权KEYCTL_CHOWN 和KEYCTL_SETPERM keyctl(2) 操作;执行madvise(2) MADV_HWPOISON 操作;使用TIOCSTI ioctl(2) 将字符插入到除调用方的控制终端之外的终端的输入队列中;使用过时的nfsservctl(2) 系统调用;使用过时的bdflush(2) 系统调用;执行各种块设备ioctl(2) 特权操作;执行各种文件系统ioctl(2) 特权操作;在/dev/random设备上执行特权ioctl(2) 操作(参阅random(4) );安装seccomp(2) 过滤器,而无需首先设置no_new_prvs 线程属性;修改设备控制组的允许/拒绝规则;使用ptrace(2) PTRACE_SECCOMP_GET_FILTER 操作转储跟踪的seccomp过滤器;使用ptrace(2) PTRACE_SETOPTIONS 操作来挂起tracee’s seccomp protections(即PTRACE_O_SUSPEND_SECCOMP 标志);对许多设备驱动程序执行管理操作;通过写/proc/[pid]/autogroup来修改autogroup nice values(优先级?)(参见sched(7) ) | |
CAP_SYS_BOOT | 使用reboot(2) 以及kexec_load(2) | |
CAP_SYS_CHROOT | 使用chroot(2) ;使用setns(2) 更改挂载(mount)命名空间 | |
CAP_SYS_MODULE | 加载与卸载内核模块(参见init_module(2) 以及delete_module(2) );在2.6.25之前的内核中:从系统范围的能力边界集中删除能力 | |
CAP_SYS_NICE | 降低进程优先级(nice(2) ,setpriority(2) )并更改任意进程的优先级;为主调进程设置实时调度策略,并为任意进程设置调度策略和优先级(sched_setscheduler(2) , sched_setparam(2) , sched_setattr(2) );设置任意进程的CPU相关性(sched_setaffinity(2) );为任意进程设置I/O调度类和优先级(ioprio_set(2) );将migrate_pages(2) 应用于任意进程,并允许进程迁移到任意节点;将move_pages(2) 应用于任意进程;将MPOL_MF_MOVE_ALL 标志与mbind(2) 和move_pages(2) 一起使用 | |
CAP_SYS_PACCT | 使用acct(2) | |
CAP_SYS_PTRACE | 使用ptrace(2) 跟踪任意进程;将get_robust_list(2) 应用于任意进程;使用process_vm_readv(2) 和process_vm_writev(2) 从任意进程的内存传入或传出数据;使用kcmp(2) 检查内存 | |
CAP_SYS_RAWIO | 执行I/O端口操作(iopl(2) 以及ioperm(2) );访问/proc/kcore ;采用FIBMAP ioctl(2) 操作;打开设备以访问x86型号特定寄存器(MSRs,参见msr(4) );更新/proc/sys/vm/mmap_min_addr ;在低于/proc/sys/vm/mmap_min_addr 指定值的地址创建内存映射;/proc/bus/pci 中的映射文件;打开/dev/mem 以及/dev/kmem ;执行多种SCSI设备命令;在hpsa(4) 和cciss(4) 设备上执行某些操作;在其他设备上执行一系列特定于设备的操作; | |
CAP_SYS_RESOURCE | 使用ext2文件系统上的保留空间;进行ioctl(2) 调用以控制ext3日志记录;覆盖磁盘配额限制;增加资源限制(参见setrlimit(2) );覆盖RLIMIT_NPROC资源限制;覆盖控制台分配中的最大控制台数量;覆盖键盘映射的最大数量;允许实时时钟中断在64hz以上;将System V消息队列的msg_qbytes限制提高到/proc/sys/kernel/msgmnb 中的限制之上(请参阅msgop(2) 和msgctl(2) );当通过UNIX域套接字将文件描述符传递给另一个进程时,允许绕过RLIMIT_NOFILE 资源对“inflight”文件描述符数量的限制(参见UNIX(7) );使用F_SETPIPE_SZ fcntl(2) 命令设置管道容量时,覆盖/proc/sys/fs/pipe-size-max 限制;使用F_SETPIPE_SZ 将管道的容量增加到/proc/sys/fs/pipe-max-size 指定的限制之上;在创建POSIX消息队列时,覆盖/proc/sys/fs/mqueue/queues_max , /proc/sys/fs/mqueue/msg_max 以及/proc/sys/fs/mqueue/msgsize_max 限制(参见mq_overview(7) );采用prctl(2) PR_SET_MM 操作;将/proc/[pid]/oom_score_adj 设置为比使用CAP_SYS_RESOURCE 的进程上次设置的值更低的值。 | |
CAP_SYS_TIME | 设置系统时钟 (settimeofday(2) , stime(2) , adjtimex(2) );设置实时(硬件)时钟 | |
CAP_SYS_TTY_CONFIG | 使用vhangup(2) ;在虚拟终端上使用各种特权ioctl(2) 操作 | |
CAP_SYSLOG | Linux 2.6.37 | 执行syslog(2) 特权操作。有关哪些操作需要权限的信息,请参阅syslog(2) ;当/proc/sys/kernel/kptr_restrict 的值为1时,查看通过/proc 和其他接口公开的内核地址。(参阅proc(5) 中对kptr_restrict 的讨论) |
CAP_WAKE_ALARM | Linux 3.0 | 触发将唤醒系统的事件(设置CLOCK_REALTIME_ALARM 和CLOCK_BOOTTIME_ALALM 计时器) |
而在usr/src/linux-headers-5.19.0-35-generic/include/uapi/linux/capability.h
文件中对于权能的定义如下。可以看到二者的能力是相同的不过对于能力的描述存在不同之处。
/**
** POSIX-draft defined capabilities.
**/
/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
overrides the restriction of changing file ownership and group
ownership. */
#define CAP_CHOWN 0
/* Override all DAC access, including ACL execute access if
[_POSIX_ACL] is defined. Excluding DAC access covered by
CAP_LINUX_IMMUTABLE. */
#define CAP_DAC_OVERRIDE 1
/* Overrides all DAC restrictions regarding read and search on files
and directories, including ACL restrictions if [_POSIX_ACL] is
defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
#define CAP_DAC_READ_SEARCH 2
/* Overrides all restrictions about allowed operations on files, where
file owner ID must be equal to the user ID, except where CAP_FSETID
is applicable. It doesn't override MAC and DAC restrictions. */
#define CAP_FOWNER 3
/* Overrides the following restrictions that the effective user ID
shall match the file owner ID when setting the S_ISUID and S_ISGID
bits on that file; that the effective group ID (or one of the
supplementary group IDs) shall match the file owner ID when setting
the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
cleared on successful return from chown(2) (not implemented). */
#define CAP_FSETID 4
/* Overrides the restriction that the real or effective user ID of a
process sending a signal must match the real or effective user ID
of the process receiving the signal. */
#define CAP_KILL 5
/* Allows setgid(2) manipulation */
/* Allows setgroups(2) */
/* Allows forged gids on socket credentials passing. */
#define CAP_SETGID 6
/* Allows set*uid(2) manipulation (including fsuid). */
/* Allows forged pids on socket credentials passing. */
#define CAP_SETUID 7
/**
** Linux-specific capabilities
**/
/* Without VFS support for capabilities:
* Transfer any capability in your permitted set to any pid,
* remove any capability in your permitted set from any pid
* With VFS support for capabilities (neither of above, but)
* Add any capability from current's capability bounding set
* to the current process' inheritable set
* Allow taking bits out of capability bounding set
* Allow modification of the securebits for a process
*/
#define CAP_SETPCAP 8
/* Allow modification of S_IMMUTABLE and S_APPEND file attributes */
#define CAP_LINUX_IMMUTABLE 9
/* Allows binding to TCP/UDP sockets below 1024 */
/* Allows binding to ATM VCIs below 32 */
#define CAP_NET_BIND_SERVICE 10
/* Allow broadcasting, listen to multicast */
#define CAP_NET_BROADCAST 11
/* Allow interface configuration */
/* Allow administration of IP firewall, masquerading and accounting */
/* Allow setting debug option on sockets */
/* Allow modification of routing tables */
/* Allow setting arbitrary process / process group ownership on
sockets */
/* Allow binding to any address for transparent proxying (also via NET_RAW) */
/* Allow setting TOS (type of service) */
/* Allow setting promiscuous mode */
/* Allow clearing driver statistics */
/* Allow multicasting */
/* Allow read/write of device-specific registers */
/* Allow activation of ATM control sockets */
#define CAP_NET_ADMIN 12
/* Allow use of RAW sockets */
/* Allow use of PACKET sockets */
/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */
#define CAP_NET_RAW 13
/* Allow locking of shared memory segments */
/* Allow mlock and mlockall (which doesn't really have anything to do
with IPC) */
#define CAP_IPC_LOCK 14
/* Override IPC ownership checks */
#define CAP_IPC_OWNER 15
/* Insert and remove kernel modules - modify kernel without limit */
#define CAP_SYS_MODULE 16
/* Allow ioperm/iopl access */
/* Allow sending USB messages to any device via /dev/bus/usb */
#define CAP_SYS_RAWIO 17
/* Allow use of chroot() */
#define CAP_SYS_CHROOT 18
/* Allow ptrace() of any process */
#define CAP_SYS_PTRACE 19
/* Allow configuration of process accounting */
#define CAP_SYS_PACCT 20
/* Allow configuration of the secure attention key */
/* Allow administration of the random device */
/* Allow examination and configuration of disk quotas */
/* Allow setting the domainname */
/* Allow setting the hostname */
/* Allow mount() and umount(), setting up new smb connection */
/* Allow some autofs root ioctls */
/* Allow nfsservctl */
/* Allow VM86_REQUEST_IRQ */
/* Allow to read/write pci config on alpha */
/* Allow irix_prctl on mips (setstacksize) */
/* Allow flushing all cache on m68k (sys_cacheflush) */
/* Allow removing semaphores */
/* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
and shared memory */
/* Allow locking/unlocking of shared memory segment */
/* Allow turning swap on/off */
/* Allow forged pids on socket credentials passing */
/* Allow setting readahead and flushing buffers on block devices */
/* Allow setting geometry in floppy driver */
/* Allow turning DMA on/off in xd driver */
/* Allow administration of md devices (mostly the above, but some
extra ioctls) */
/* Allow tuning the ide driver */
/* Allow access to the nvram device */
/* Allow administration of apm_bios, serial and bttv (TV) device */
/* Allow manufacturer commands in isdn CAPI support driver */
/* Allow reading non-standardized portions of pci configuration space */
/* Allow DDI debug ioctl on sbpcd driver */
/* Allow setting up serial ports */
/* Allow sending raw qic-117 commands */
/* Allow enabling/disabling tagged queuing on SCSI controllers and sending
arbitrary SCSI commands */
/* Allow setting encryption key on loopback filesystem */
/* Allow setting zone reclaim policy */
/* Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility */
#define CAP_SYS_ADMIN 21
/* Allow use of reboot() */
#define CAP_SYS_BOOT 22
/* Allow raising priority and setting priority on other (different
UID) processes */
/* Allow use of FIFO and round-robin (realtime) scheduling on own
processes and setting the scheduling algorithm used by another
process. */
/* Allow setting cpu affinity on other processes */
/* Allow setting realtime ioprio class */
/* Allow setting ioprio class on other processes */
#define CAP_SYS_NICE 23
/* Override resource limits. Set resource limits. */
/* Override quota limits. */
/* Override reserved space on ext2 filesystem */
/* Modify data journaling mode on ext3 filesystem (uses journaling
resources) */
/* NOTE: ext2 honors fsuid when checking for resource overrides, so
you can override using fsuid too */
/* Override size restrictions on IPC message queues */
/* Allow more than 64hz interrupts from the real-time clock */
/* Override max number of consoles on console allocation */
/* Override max number of keymaps */
/* Control memory reclaim behavior */
#define CAP_SYS_RESOURCE 24
/* Allow manipulation of system clock */
/* Allow irix_stime on mips */
/* Allow setting the real-time clock */
#define CAP_SYS_TIME 25
/* Allow configuration of tty devices */
/* Allow vhangup() of tty */
#define CAP_SYS_TTY_CONFIG 26
/* Allow the privileged aspects of mknod() */
#define CAP_MKNOD 27
/* Allow taking of leases on files */
#define CAP_LEASE 28
/* Allow writing the audit log via unicast netlink socket */
#define CAP_AUDIT_WRITE 29
/* Allow configuration of audit via unicast netlink socket */
#define CAP_AUDIT_CONTROL 30
/* Set or remove capabilities on files.
Map uid=0 into a child user namespace. */
#define CAP_SETFCAP 31
/* Override MAC access.
The base kernel enforces no MAC policy.
An LSM may enforce a MAC policy, and if it does and it chooses
to implement capability based overrides of that policy, this is
the capability it should use to do so. */
#define CAP_MAC_OVERRIDE 32
/* Allow MAC configuration or state changes.
The base kernel requires no MAC configuration.
An LSM may enforce a MAC policy, and if it does and it chooses
to implement capability based checks on modifications to that
policy or the data required to maintain it, this is the
capability it should use to do so. */
#define CAP_MAC_ADMIN 33
/* Allow configuring the kernel's syslog (printk behaviour) */
#define CAP_SYSLOG 34
/* Allow triggering something that will wake the system */
#define CAP_WAKE_ALARM 35
/* Allow preventing system suspends */
#define CAP_BLOCK_SUSPEND 36
/* Allow reading the audit log via multicast netlink socket */
#define CAP_AUDIT_READ 37
/*
* Allow system performance and observability privileged operations
* using perf_events, i915_perf and other kernel subsystems
*/
#define CAP_PERFMON 38
/*
* CAP_BPF allows the following BPF operations:
* - Creating all types of BPF maps
* - Advanced verifier features
* - Indirect variable access
* - Bounded loops
* - BPF to BPF function calls
* - Scalar precision tracking
* - Larger complexity limits
* - Dead code elimination
* - And potentially other features
* - Loading BPF Type Format (BTF) data
* - Retrieve xlated and JITed code of BPF programs
* - Use bpf_spin_lock() helper
*
* CAP_PERFMON relaxes the verifier checks further:
* - BPF progs can use of pointer-to-integer conversions
* - speculation attack hardening measures are bypassed
* - bpf_probe_read to read arbitrary kernel memory is allowed
* - bpf_trace_printk to print kernel memory is allowed
*
* CAP_SYS_ADMIN is required to use bpf_probe_write_user.
*
* CAP_SYS_ADMIN is required to iterate system wide loaded
* programs, maps, links, BTFs and convert their IDs to file descriptors.
*
* CAP_PERFMON and CAP_BPF are required to load tracing programs.
* CAP_NET_ADMIN and CAP_BPF are required to load networking programs.
*/
#define CAP_BPF 39
/* Allow checkpoint/restore related operations */
/* Allow PID selection during clone3() */
/* Allow writing to ns_last_pid */
#define CAP_CHECKPOINT_RESTORE 40
#define CAP_LAST_CAP CAP_CHECKPOINT_RESTORE
线程能力集合
每个线程有多个能力的集合,这些集合与文件能力集合一起决定新线程所具备的能力。具体转换规则参考后面的“执行execve()时的能力变换”一节。
Permitted
effective capabilities的超集;对于一个effective set中没有CAP_SETPCAP能力的进程来说,其可以向本线程的inheritable set中添加能力,但此能力必须位于本线程的permitted set中。
如果线程从其permitted set中删除了某个能力,则它永远无法重新获取该能力(除非它execve(2)s a set-user-ID-root 程序,或其相关文件能力授予该能力的程序)。
Inheritable
这是在execve(2)中保留的一组功能。当执行任何程序时,inheritable capabilities保持可继承性,并且当执行具有在文件inheritable set中设置的对应位的程序时,将inheritable capabilities添加到permitted set。
Effective
这是内核用来为线程执行权限检查的一组能力。
Bounding (per-thread since Linux 2.6.25)
用于限制进程在execve(2)期间获得的能力。
从Linux 2.6.25开始,这是按照线程划分的能力集。在较旧的内核中,capability bounding set是系统范围内的属性,由系统上的所有线程共享。
Ambient (since Linux 4.3)
文件能力
从内核2.6.24开始,内核支持使用setcap(8)将能力集与可执行文件相关联。文件能力集存储在名为security.ability的扩展属性(请参见setxattr(2)和xattr(7))中。写入此扩展属性需要CAP_SETFCAP功能。文件能力集与线程的能力集一起确定execve(2)之后线程的能力。
Permitted
简称P。
Inheritable
简称I。
Effective
这不是一个集合,而是一个单独的比特(手册是这么说的)。简称E。
执行execve()时的能力变换
在执行 execve(2)时,内核使用以下算法计算进程的新能力:
P'(ambient) = (file is privileged) ? 0 : P(ambient)
P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & P(bounding)) | P'(ambient)
P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
P'(inheritable) = P(inheritable) [i.e., unchanged]
P'(bounding) = P(bounding) [i.e., unchanged]
其中:
P() 代表执行execve(2)之前的线程能力集
P'() 代表执行execve(2)之后的线程能力集
F() 代表线程的能力集
还需注意以下规则:
-
ambient capability set仅在Linux 4.3及以后版本中存在。当在execve(2)期间确定ambient set的转换时,特权文件(privileged file)是具有能力或set-user-ID或set-group-ID被置位的文件。
-
在Linux 2.6.25之前,bounding set是所有线程共享的系统范围内的属性。在execve(2)期间,以与上面针对P(bounding)所示的方式相同的方式,使用该系统范围的值来计算新的permitted set。
注意1:在上述能力转换期间,文件能力可能会被忽略(视为空),原因与忽略set-user-ID和set-group-ID位的原因相同;参见execve(2)。如果内核是使用no_file_caps选项启动的,则类似地会忽略文件能力。
注意2:根据上述规则,如果用户ID为非零的进程执行execve(2),则其permitted and effective sets中存在的任何能力都将被清除。有关用户ID为零的进程执行execve(2)时的功能处理,请参阅下面root下的capabilities和程序执行。(以后再补充)
权能操作实例
首先使用adduser
命令创建新用户,以供实验使用。
接下来以CAP_CHOWN
能力和chown
命令为例来展示Linux系统的权能机制。
chown
命令可以更改文件拥有者
首先明确chown
命令所调用的文件路径。
接着查看chown
命令所具有的权能。
发现/usr.bin/chown
文件不具有任何能力。因此在以普通用户身份执行chown
命令时会被拒绝。
接着我们为chown
命令设置CAP_CHOWN
权能。
再执行chown
命令,执行成功。
再取消能力,发现除非加上sudo
否则chown
命令不能成功执行。
能力与UGO机制
作为Linux内核最基础的自主访问控制机制,UGO访问控制早在Linux 0.11内核之前就已经实现。而能力机制则位于UGO之上,不能覆盖UGO机制。
即便有CAP_CHOWN
能力,如果对chown
命令没有执行能力,命令也不会成功执行。
即便没有CAP_CHOWN
能力,如果对chown
文件的s置位,命令也会成功执行。
Linux-PAM
简介
Linux-PAM(Pluggable Authentication Modules for Linux)是一套共享库,使本地系统管理员能够选择应用程序如何对用户进行身份验证。
+-----------------+
| application: X |
+-----------------+ / +----------+ +=================+
| authentication -[---->--\--] Linux- |--<--| PAM config file |
| + [----<--/--] PAM | |=================|
|[conversation()] [--+ \ | | | X auth .. a.so |
+-----------------+ | / +--n--n----+ | X auth .. b.so |
| | | __ | | | _____/
| service user | A | | |_____,-----'
| | | V A
+-----------------+ +------|-----|---------+ -----+------+
+---u-----u----+ | | |
|authentication|--[ a ]--[ b ]--[ c ]
+--------------+
| account |--[ b ]--[ d ]
+--------------+
| password |--[ b ]--[ c ]
+--------------+
| session |--[ e ]--[ c ]
+--------------+
PAM的大致架构如上图所示。
更多内容可以参考The Linux-PAM System Administrators’ Guide.
更多文档在https://github.com/linux-pam/linux-pam中的doc文件夹。
PAM配置
具体内容请查阅The Linux-PAM System Administrators’ Guide,本文仅介绍大概。
默认PAM 配置文件路径为/etc/pam.conf
或者 /etc/pam.d/*
;
pam.conf
文件的配置格式为。
server name module type ctrl flag module[path] ...[args..]
在pam.d
文件夹中,由于server name隐含在文件名之中,因此每行配置只需要后四个参数。
模块简要介绍
模块名称 | 功能 |
---|---|
pam_access.so | logdaemon风格的登录访问控制 |
pam_debug.so | 调试PAM栈 |
pam_deny.so | 锁定PAM模块(该验证模块可以用来禁止所有的访问) |
pam_echo.so | 打印文本信息 |
pam_env.so | 设置/取消设置环境变量 |
pam_exec.so | 调用外部命令 |
pam_faildelay.so | 更改每个应用程序的失败的延迟 |
pam_filter.so | 过滤模块,过滤用户与应用程序之间的I/O |
pam_ftp.so | 提供了一种可插入的匿名ftp访问模式 |
pam_group.so | 修改用户组访问权限 |
pam_issue.so | 将声明文件添加到用户提示(i.e. 用户登录时显示提示) |
pam_keyinit.so | 显示keyinit文件 |
pam_lastlog.so | 显示上次登录的日期 |
pam_limits.so | 限制用户资源 |
pam_listfile.so | 根据某个文件允许或禁止用户访问某个应用程序或服务 |
pam_localuser.so | 要求用户在/etc/passwd 中 |
pam_loginuid.so | 将用户的登录uid记录到进程属性 |
pam_mail.so | 通知用户有新的邮件 |
pam_mkhomedir.so | 创建用户主目录 |
pam_motd.so | 显示motd文件 |
pam_namespace.so | 设置专用(private)命名空间 |
pam_nologin.so | 阻止非root用户登录 |
pam_permit.so | 混杂模块(总是允许所有的访问) |
pam_pwhistory.so | 使用.pwshistory文件授予访问权限(建立密码历史档案,防止用户在一定时间内使用相同的密码) |
pam_rhosts.so | 使用.rhosts文件授予访问权限 (为服务执行标准网络认证) |
pam_rootok.so | 如果用户的UID为0,则通过验证 |
pam_securetty.so | 限制root用户的登录设备 |
pam_selinux.so | 设置默认安全上下文 |
pam_shells.so | 检查有效的登录shell(仅允许/etc/shells 内的shell) |
pam_succeed_if.so | 测试账户特性(基于账户特性决定是否通过验证) |
pam_time.so | 基于时间来控制是否允许访问 |
pam_timestamp.so | 使用缓存的成功身份验证尝试进行身份验证(为用户提供一段时间的管理权限) |
pam_umask.so | 设置文件模式创建掩码 |
pam_unix.so | 传统的密码验证 |
pam_userdb.so | 根据数据库进行身份验证 |
pam_warn.so | 记录所有PAM项目(将登录信息记录到系统日志中) |
pam_wheel.so | 只允许对wheely组成员进行root访问 |
pam_xauth.so | 在用户之间转发xauth密钥 |
应用实例
禁止用户使用sudo
命令。
在/etc/security/time.conf
中加入
sudo;*;songrunhan;!Al0000-2400
在/ect/pam.d/sudo
的头部加入
account required pam_time.so
可以看到,PAM阻止了sudo
命令。
Capability与Linux-PAM
下面研究如何通过Linux-PAM在特定用户登录时设置权能,并在用户登出时删除权能。
在/usr/local/bin/
下新建一个.sh
文件名称为chown_permission_adjust.sh
,文件内容如下所示。
#!/bin/bash
# echo "$PAM_TYPE"
# echo "$PAM_USER"
if [ "$PAM_USER" == "ossecurity" ] && [ "$PAM_TYPE" == "open_session" ]; then
setcap cap_chown=eip /usr/bin/chown
echo "ossecurity login"
elif [ "$PAM_USER" == "ossecurity" ] && [ "$PAM_TYPE" == "close_session" ]; then
setcap -r /usr/bin/chown
echo "ossecurity logout"
else
exit 0
fi
并将其UGO权限设置为root用户可执行。
之后在/etc/pam.d/common-session
文件的后部加入以下内容
session optional pam_exec.so debug log=/tmp/pam_exec.log seteuid /usr/local/bin/chown_permission_adjust.sh
将用户切换为ossecurity
后就可以执行chown
命令
同时,根据之前的设置,有日志输出。
问题总结
Capabilities文档中的process与thread
在man capabilities
的文档中既出现了“thread”(e.g. per-thread)也出现了“process”。尽管严格来讲“线程”和“进程”是两个不同的概念。但是我认为在该文档中这两个单词都是进程的意思。
ping
命令不需要CAP_NET_RAW
能力也能执行
首先,根据man ping 文档
。
ping在满足以下任意条件时需要CAP_NET_RAW能力
:
- 程序用于非回显查询(请参阅 -N 选项)
- 内核不支持非原始 ICMP 套接字
- 不允许用户创建一个 ICMP 回显套接字。
The program may be used as set-uid root.
在当前系统中,这三个要求均不满足。
其次,根据man icmp
文档。
参数ping_group_range (two integers; default: see below; since Linux 2.6.39)
允许创建 ICMP Echo 套接字的用户组 ID 范围(包括最小和最大组 ID)。默认值为“1 0”,这意味着不允许任何组创建ICMP Echo套接字。
然而在本机中,该设置为允许所有组创建ICMP Echo套接字。
最后,根据ping命令的源代码。
当前ping会优先使用SOCK_DGRAM
类型的socket而不是SOCK_RAW
。
实验环境
文中所有实验在VMware虚拟机上的Ubuntu 22.04.2 LTS系统中运行。uname -all
结果如下
Linux songrunhan-virtual-machine 5.19.0-35-generic #36~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 17 15:17:25 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
物理机硬件环境:
- CPU:AMD Ryzen 5 3600
- RAM:16GB@3200MHz
- GPU:Radeon RX550
物理机软件环境:
- OS:Windows 11 Pro, 64-bit (Build 22621.1413) 10.0.22621
- VMware:17.0.1 build-21139696
参考文献
https://tenforward.hatenablog.com/entry/2019/11/27/022547