Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the concept of Linux Capabilities

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "what is the concept of Linux Capabilities". In daily operation, I believe many people have doubts about what the concept of Linux Capabilities is. The editor consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful for you to answer the doubts about "what is the concept of Linux Capabilities?" Next, please follow the editor to study!

Linux is a secure operating system, which gives all system permissions to a single root user, and only retains limited permissions to ordinary users. Root users have Super Admin privileges to install software, allow certain services, manage users, and so on.

As an ordinary user, if you want to perform some operations that only administrators have access to, there are only two ways: one is to enhance permissions through sudo, if there are many users, configuration management and access control will be very troublesome; the other is through SUID (Set User ID on execution), which allows ordinary users to allow an executable file whose owner is root to have the authority of root.

The concept of SUID is rather obscure, for example, take the commonly used passwd command as an example, changing a user's password requires root permission, but ordinary users can change their password through this command, that is, because / bin/passwd is set with the SUID identity, so when ordinary users execute the passwd command, the owner of the process is the owner of the passwd, that is, the root user.

Although SUID can solve the problem, it brings security risks. When running a command with SUID set, it usually requires only a small amount of privileges, but SUID gives it all the permissions that root has. These executables are the main targets of hackers, and if they find a loophole in them, they can easily use them to carry out security attacks. In short, the SUID mechanism increases the security attack surface of the system.

In order to have more fine-grained control over root permissions and achieve on-demand authorization, Linux introduces another mechanism called capabilities.

1. What is Linux capabilities?

The Capabilities mechanism was introduced after Linux kernel 2.2. the principle is simple: the privileges previously associated with superuser root (UID=0) are subdivided into different functional groups. Capabilites exists as an attribute of threads (Linux does not really distinguish between processes and threads), and each functional group can be enabled and disabled independently. In essence, kernel calls are classified, and kernel calls with similar functions are grouped into the same group.

In this way, the process of privilege checking becomes: when performing a privileged operation, if the thread's valid identity is not root, it checks whether it has the capabilities corresponding to the privileged operation, and decides whether it can perform the privileged operation.

Capabilities can be granted when the process is executing or can be inherited directly from the parent process. So in theory, if CAP_NET_BIND_SERVICE capabilities is assigned to the nginx executable, it can run as a normal user and listen on port 80.

Capability name describes CAP_AUDIT_CONTROL to enable and disable kernel auditing; change audit filtering rules Retrieving audit status and filtering rules CAP_AUDIT_READ allows you to read audit logs via multicast netlink sockets CAP _ AUDIT_WRITE write records to kernel audit logs CAP _ BLOCK_SUSPEND use features that can prevent system hang CAP_CHOWN modify file owner's permissions CAP_DAC_OVERRIDE ignore file's DAC access restrictions CAP_DAC_READ_SEARCH ignore file read and directory search DAC access restrictions CAP_FOWNER negligently Restrictions that the file owner ID must match the process user ID CAP_FSETID allows you to set the setuid bit of the file CAP_IPC_LOCK allows locking of shared memory fragments CAP_IPC_OWNER ignores IPC ownership check CAP_KILL allows you to signal processes that do not belong to you CAP_LEASE allows you to modify the FL_LEASE flag of the file lock CAP_LINUX_IMMUTABLE allows you to modify the file's IMMUTABLE and APPEND attribute tags CAP_MAC_ADMIN permission MAC configuration or state change CAP_MAC_OVERRIDE ignore DAC access restrictions for files CAP_MKNOD allows to use mknod () system call CAP_NET_ADMIN allows network management tasks CAP_NET_BIND_SERVICE allows binding to ports less than 1024 CAP_NET_BROADCAST allows webcast and multicast access CAP_NET_RAW allows use of original sockets CAP_SETGID allows change process GIDCAP_SETFCAP allows settings for files Setting any capabilitiesCAP_SETPCAP reference capabilities man pageCAP_SETUID allows you to change the UIDCAP_SYS_ADMIN of the process to allow you to perform system management tasks CAP_SYS_BOOT, such as loading or unmounting file systems, setting disk quotas, etc., allows system CAP_SYS_CHROOT to be restarted using chroot () system call CAP_SYS_MODULE to allow insertion and deletion of kernel modules CAP_SYS_NICE allows to raise priority and set priority for other processes CAP_SYS_PACCT allows BSD-style audit CAP_SYS_PTRACE for executing processes allows tracking of any process CAP_SYS_RAWIO allows direct access to / devport, / dev/mem, / dev/kmem and original block device CAP_SYS_RESOURCE ignore resource restrictions CAP_SYS_TIME allows you to change the system clock CAP_SYS_TTY_CONFIG allows you to configure TTY devices CAP_SYSLOG allows you to use syslog () system calls CAP_WAKE_ALARM allows you to trigger something that wakes up the system (such as CLOCK_BOOTTIME_ALARM timer) 2. Capabilities assignment and inheritance

Linux capabilities is divided into process capabilities and file capabilities. For processes, capabilities is subdivided into threads, that is, each thread can have its own capabilities. For a file, the capabilities is saved in the extended properties of the file.

The capabilities of the thread (process) and the capabilities of the file are described below.

Capabilities of the thread

Each thread has five capabilities collections, each represented by a 64-bit mask and displayed in hexadecimal format. The five capabilities collections are:

Permitted

Effective

Inheritable

Bounding

Ambient

Each collection contains zero or more capabilities. The specific meanings of these five sets are as follows:

Permitted

Defines the upper limit of the capabilities that a thread can use. It does not enable the thread's capabilities, but as a stipulation. That is, threads can add or remove capability from the Effective or Inheritable collection by calling capset (), provided that the added or removed capability is included in the Permitted collection (where the Bounding collection also has an impact, see below). If a thread wants to add or remove capability from the Inheritable collection, it must first include the capabiliy CAP_SETPCAP in its Effective collection.

Effective

When the kernel checks whether a thread can perform privileged operations, the object it checks is the Effective collection. As mentioned earlier, the Permitted collection defines an upper limit, and threads can delete a capability from the Effective collection and then restore the capability from the Permitted collection as needed, thus temporarily disabling capability.

Inheritable

When the exec () system call is executed, the capabilities that can be inherited by the new executable is included in the Inheritable collection. It is important to note that the capabilities contained in this collection is not automatically inherited to the new executable, that is, it is not added to the Effective collection of the new thread, it only affects the Permitted collection of the new thread.

Bounding

The Bounding collection is a superset of the Inheritable collection, and if a capability is not in the Bounding collection, even if it is in the Permitted collection, the thread cannot add the capability to its Inheritable collection.

The capabilities of the Bounding collection is passed to the child process's Bounding collection when the fork () system call is made, and remains unchanged after the execve system call.

You cannot add capabilities to the Bounding collection while the thread is running.

Once a capability is removed from the Bounding collection, it cannot be added back.

After a capability is removed from the Bounding collection, if the previous Inherited collection contains the capability, it will continue to be retained. However, if the capability is later removed from the Inheritable collection, it cannot be added back.

Ambient

A new capabilities collection called Ambient is added to the Linux 4.3 kernel to make up for the deficiency of Inheritable. Ambient has the following characteristics:

Capabilities,Ambient that is not set by Permitted and Inheritable cannot be set either.

When Permitted and Inheritable turn off a permission (such as CAP_SYS_BOOT), Ambient also turns off the corresponding permission. This ensures that the child process will also reduce the permissions after the permissions are reduced.

An unprivileged user who has a capability in the Permitted collection can be added to the Ambient collection so that its child processes can get the capability in the Ambient, Permitted, and Effective collections. It doesn't matter if I don't know why now. I'll tell you later through a specific formula.

The benefits of Ambient are obvious. For example, if you add CAP_NET_ADMIN to the Ambient collection of the current process, it can call the shell script through fork () and execve () to perform network management tasks, because CAP_NET_ADMIN automatically inherits.

Capabilities of the file

The capabilities of the file is saved in the extended properties of the file. If you want to modify these properties, you need a capability with CAP_SETFCAP. The file, together with the thread's capabilities, determines the capabilities of the thread after running the file through execve ().

The capabilities function of the file requires the support of the file system. If the file system is mounted with the nouuid option, the capabilities of the file will be ignored.

Similar to a thread's capabilities, the capabilities of a file contains three collections:

Permitted

Inheritable

Effective

The specific meanings of these three sets are as follows:

Permitted

The capabilities contained in this collection, when the file is executed, is calculated to intersect with the thread's Bounding collection, and then added to the thread's Permitted collection.

Inheritable

The intersection of this collection with the thread's Inheritable collection is added to the Permitted collection of the thread after executing execve ().

Effective

This is not a collection, just a flag bit. If the setting is on, the capabilities in the thread Permitted collection is automatically added to its Effective collection after execve () is executed. For some old executable files, because they do not call capabilities-related functions to set their own Effective collection, you can turn on the Effective bit of the executable file, so you can automatically add the capabilities in the Permitted collection to the Effective collection.

For more information, please refer to Linux capabilities's man page.

3. Changes in capabilities after running execve ()

The capabilities of threads and files is introduced above, which you may find a bit abstract and difficult to understand. The following is a specific calculation formula to illustrate how capabilities is determined after the execution of execve ().

We use P to represent the capabilities,P' of the thread before executing execve (), the capabilities,F of the thread after executing execve () to represent the capabilities of the executable. So:

> 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]

Let's explain one by one:

If the user is a root user, the Ambient set of threads after executing execve () is an empty set; if it is an ordinary user, the Ambient collection of threads after executing execve () will inherit the Ambient collection of threads before executing execve ().

The Inheritable collection of the thread before executing execve () intersects with the Inheritable collection of executable files, and will be added to the Permitted collection of threads after executing execve (); the capability bounding collection of executable files intersects with the Permitted collection of executable files, and it will also be added to the Permitted collection of threads after executing execve (); and the capabilities in the Ambient collection of threads after executing execve () will be automatically added to the Permitted collection of that thread.

If the executable has the Effective flag bit turned on, the capabilities in the thread Permitted collection is automatically added to its Effective collection after executing execve ().

The Inheritable collection of threads before executing execve () inherits from the Inheritable collection of threads after executing execve ().

Here are a few points that need to be emphasized:

The above formula is for the system call execve (). If it is fork (), then the capabilities information of the child thread completely copies the capabilities information of the parent process.

The Inheritable collection of executables has nothing to do with the thread's Inheritable collection, and the capabilities in the executable Inheritable collection is not added to the thread's Inheritable collection after execve () is executed. If you want the Inheritable collection of a new thread to contain a capability, you can only add that capability to the Inheritable collection of the current thread through capset () (because P'(inheritable) = P (inheritable)).

If you want the capabilities in the current thread's Inheritable collection to be passed to the new executable, the file's Inheritable collection must also contain these capabilities (because P'(permitted) = (P (inheritable) & F (inheritable)) |.).

When the capabilities of the current thread is passed to the new executable, it is simply passed to the Permitted collection of the new thread. If you want it to take effect, the new thread must add capabilities to the Effective collection through capset (). Or open the Effective flag bit of the new executable file (because P'(effective) = F (effective)? P'(permitted): P'(ambient)).

Before there is no Ambient collection, if a script cannot call capset (), but you want all threads in the script to get the capabilities in the script's Permitted collection, you can only add the capabilities in the Permitted collection to the Inheritable collection (P'(permitted) = P (inheritable) & F (inheritable) |.) and turn on the Effective flag bit (P'(effective) = F (effective)? P'(permitted): P'(ambient)). With the Ambient collection, things get a lot easier, which will be explained in more detail in subsequent articles.

If a thread with non-zero UID (normal user) executes execve (), then the capabilities in both the Permitted and Effective collections will be emptied.

If you switch from a root user to a normal user, the capabilities in both the Permitted and Effective collections will be cleared, unless SECBIT_KEEP_CAPS or a broader SECBIT_NO_SETUID_FIXUP is set.

The logical flow chart for the above calculation formula is as follows (excluding the Ambient set):

4. Simple exampl

Let's use an example to demonstrate the calculation logic of the above formula, taking the ping file as an example. If we add CAP_NET_RAW capability to the Permitted collection of the ping file (F (Permitted)), it will be added to the Permitted collection of the thread after execution (P'(Permitted)). Because the ping file is capabilities-aware, that is, it can call capset () and capget (), it calls capset () at run time to add CAP_NET_RAW capability to the thread's Effective collection.

In other words, if the executable is not capabilities-aware, we must turn on the Effective flag bit (F (Effective)) so that the capability is automatically added to the thread's Effective collection. A capabilities-aware executable is safer because it limits the amount of time a thread can use the capability.

We can also add capabilities to the Inheritable collection of the file, whose Inheritable collection intersects the Inheritable collection of the current thread and then adds it to the Permitted collection of the new thread. In this way, you can control the running environment of the executable file.

It seems reasonable, but there is one problem: if the valid user of the executable is a normal user and there is no Inheritable collection, that is, F (inheritable) = 0, then P (inheritable) will be ignored (P (inheritable) & F (inheritable)). Because this is the case with the vast majority of executables, the availability of the Inheritable collection is limited. We cannot make threads in the script automatically inherit the capabilities in the script file unless we make the script capabilities aware.

To change this, you can use the Ambient collection. The Ambient collection automatically inherits from the parent thread and is automatically added to the Permitted collection of the current thread. For example, in a Bash environment (such as an executing script) where the thread's Ambient collection contains CAP_NET_RAW capability, executing the ping file in that environment works fine, even if the file is a normal file (there is no capabilities and SUID is not set).

5. Ultimate case

Finally, take docker as an example. If you use an ordinary user to launch the official nginx container, the following error will occur:

Bind () to 0.0.0.0 failed 80 failed (13: Permission denied)

Because the Effective collection of the nginx process does not contain CAP_NET_BIND_SERVICE capability and does not have capabilities awareness (normal users), the startup fails. To start successfully, at least add the capability to the Inheritable collection of the nginx file, turn on the Effective flag bit, and add NET_BIND_SERVICE under the securityContext-> capabilities field in the Kubernetes Pod deployment list (this capability will be added to the Bounding collection of the nginx process), and finally add capability to the Permitted collection of the nginx file. In this way, it is done. Refer to the formula: P'(permitted) =. | (F (permitted) & P (bounding)) |. And P'(effective) = F (effective)? P'(permitted): P'(ambient).

If securityContext/allowPrivilegeEscalation is enabled in the container, the above settings will still take effect. If the nginx file is capabilities aware, you just need to add CAP_NET_BIND_SERVICE capability to its Inheritable collection and it will work.

At this point, the study of "what is the concept of Linux Capabilities" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report