Linux/SELinux/10 Systemd: Unterschied zwischen den Versionen
K Dirkwagner verschob die Seite SELinux/DOC/10 selinux systemd access control nach SELinux/DOC/10 SELinux systemd access control, ohne dabei eine Weiterleitung anzulegen |
Keine Bearbeitungszusammenfassung |
||
| Zeile 1: | Zeile 1: | ||
=== | === SELinux systemd Access Control === | ||
System services are controlled by the '''systemd''' daemon | |||
* In previous releases of Red Hat Enterprise Linux, daemons could be started in two ways | |||
* At boot time, the System V '''init''' daemon launched an '''init.rc''' script and then this script launched the required daemon | |||
* For example, the Apache server, which was started at boot, got the following SELinux label: <br/>system_u:system_r:httpd_t:s0 | |||
* An administrator launched the '''init.rc''' script manually, causing the daemon to run | |||
* For example, when the '''service httpd restart''' command was invoked on the Apache server, the resulting SELinux label looked as follows: <br/>unconfined_u:system_r:httpd_t:s0 | |||
When launched manually, the process adopted the user portion of the SELinux label that started it, making the labeling in the two scenarios above inconsistent | |||
* With the '''systemd''' daemon, the transitions are very different | |||
* As '''systemd''' handles all the calls to start and stop daemons on the system, using the '''init_t''' type, it can override the user part of the label when a daemon is restarted manually | |||
* As a result, the labels in both scenarios above are '''system_u:system_r:httpd_t:s0''' as expected and the SELinux policy could be improved to govern which domains are able to control which units | |||
When launched manually, the process adopted the user portion of the SELinux label that started it, making the labeling in the two scenarios above inconsistent | |||
=== 10.1. SELinux Access Permissions for Services === | === 10.1. SELinux Access Permissions for Services === | ||
In previous versions of Red Hat Enterprise Linux, an administrator was able to control, which users or applications were able to start or stop services based on the label of the System V Init script | In previous versions of Red Hat Enterprise Linux, an administrator was able to control, which users or applications were able to start or stop services based on the label of the System V Init script | ||
* Now, '''systemd''' starts and stops all services, and users and processes communicate with '''systemd''' using the '''systemctl''' utility | |||
* The '''systemd''' daemon has the ability to consult the SELinux policy and check the label of the calling process and the label of the unit file that the caller tries to manage, and then ask SELinux whether or not the caller is allowed the access | |||
* This approach strengthens access control to critical system capabilities, which include starting and stopping system services | |||
For example, previously, administrators had to allow NetworkManager to execute | For example, previously, administrators had to allow NetworkManager to execute '''systemctl''' to send a D-Bus message to '''systemd''', which would in turn start or stop whatever service NetworkManager requested | ||
* In fact, NetworkManager was allowed to do everything '''systemctl''' could do | |||
* It was also impossible to setup confined administrators so that they could start or stop just particular services | |||
To fix these issues, | To fix these issues, '''systemd''' also works as an SELinux Access Manager | ||
* It can retrieve the label of the process running '''systemctl''' or the process that sent a D-Bus message to '''systemd''' | |||
* The daemon then looks up the label of the unit file that the process wanted to configure | |||
* Finally, '''systemd''' can retrieve information from the kernel if the SELinux policy allows the specific access between the process label and the unit file label | |||
* This means a compromised application that needs to interact with '''systemd''' for a specific service can now be confined by SELinux | |||
* Policy writers can also use these fine-grained controls to confine administrators | |||
* Policy changes involve a new class called '''service''', with the following permissions | |||
class service | class service | ||
| Zeile 28: | Zeile 43: | ||
} | } | ||
For example, a policy writer can now allow a domain to get the status of a service or start and stop a service, but not enable or disable a service | For example, a policy writer can now allow a domain to get the status of a service or start and stop a service, but not enable or disable a service | ||
* Access control operations in SELinux and '''systemd''' do not match in all cases | |||
* A mapping was defined to line up '''systemd''' method calls with SELinux access checks | |||
* Table 10.1, “Mapping of systemd unit file method calls on SELinux access checks” maps access checks on unit files while Table 10.2, “Mapping of systemd general system calls on SELinux access checks” covers access checks for the system in general | |||
* If no match is found in either table, then the '''undefined''' system check is called | |||
Table 10.1. Mapping of systemd unit file method calls on SELinux access checks | Table 10.1. Mapping of systemd unit file method calls on SELinux access checks | ||
{| style="border-spacing:0;width:9.391cm;" | {| style="border-spacing:0;width:9.391cm;" | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
! align=center| systemd unit file method | ! align=center| systemd unit file method | ||
! align=center| SELinux access check | ! align=center| SELinux access check | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| DisableUnitFiles | || DisableUnitFiles | ||
|| disable | || disable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| EnableUnitFiles | || EnableUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnit | || GetUnit | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnitByPID | || GetUnitByPID | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnitFileState | || GetUnitFileState | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Kill | || Kill | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillUnit | || KillUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LinkUnitFiles | || LinkUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListUnits | || ListUnits | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LoadUnit | || LoadUnit | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| MaskUnitFiles | || MaskUnitFiles | ||
|| disable | || disable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| PresetUnitFiles | || PresetUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReenableUnitFiles | || ReenableUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reexecute | || Reexecute | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reload | || Reload | ||
|| reload | || reload | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrRestart | || ReloadOrRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrRestartUnit | || ReloadOrRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrTryRestart | || ReloadOrTryRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrTryRestartUnit | || ReloadOrTryRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadUnit | || ReloadUnit | ||
|| reload | || reload | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ResetFailed | || ResetFailed | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ResetFailedUnit | || ResetFailedUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Restart | || Restart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| RestartUnit | || RestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Start | || Start | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StartUnit | || StartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StartUnitReplace | || StartUnitReplace | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Stop | || Stop | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StopUnit | || StopUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TryRestart | || TryRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TryRestartUnit | || TryRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| UnmaskUnitFiles | || UnmaskUnitFiles | ||
|| enable | || enable | ||
|- | |- | ||
|} | |} | ||
Table 10.1. Mapping of systemd unit file method calls on SELinux access checks | Table 10.1. Mapping of systemd unit file method calls on SELinux access checks | ||
{| style="border-spacing:0;width:9.391cm;" | {| style="border-spacing:0;width:9.391cm;" | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
! align=center| systemd unit file method | ! align=center| systemd unit file method | ||
! align=center| SELinux access check | ! align=center| SELinux access check | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| DisableUnitFiles | || DisableUnitFiles | ||
|| disable | || disable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| EnableUnitFiles | || EnableUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnit | || GetUnit | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnitByPID | || GetUnitByPID | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUnitFileState | || GetUnitFileState | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Kill | || Kill | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillUnit | || KillUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LinkUnitFiles | || LinkUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListUnits | || ListUnits | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LoadUnit | || LoadUnit | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| MaskUnitFiles | || MaskUnitFiles | ||
|| disable | || disable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| PresetUnitFiles | || PresetUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReenableUnitFiles | || ReenableUnitFiles | ||
|| enable | || enable | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reexecute | || Reexecute | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reload | || Reload | ||
|| reload | || reload | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrRestart | || ReloadOrRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrRestartUnit | || ReloadOrRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrTryRestart | || ReloadOrTryRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadOrTryRestartUnit | || ReloadOrTryRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ReloadUnit | || ReloadUnit | ||
|| reload | || reload | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ResetFailed | || ResetFailed | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ResetFailedUnit | || ResetFailedUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Restart | || Restart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| RestartUnit | || RestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Start | || Start | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StartUnit | || StartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StartUnitReplace | || StartUnitReplace | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Stop | || Stop | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| StopUnit | || StopUnit | ||
|| stop | || stop | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TryRestart | || TryRestart | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TryRestartUnit | || TryRestartUnit | ||
|| start | || start | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| UnmaskUnitFiles | || UnmaskUnitFiles | ||
|| enable | || enable | ||
|- | |- | ||
|} | |} | ||
Table 10.2. Mapping of systemd general system calls on SELinux access checks | Table 10.2. Mapping of systemd general system calls on SELinux access checks | ||
{| style="border-spacing:0;width:9.931cm;" | {| style="border-spacing:0;width:9.931cm;" | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
! align=center| systemd general system call | ! align=center| systemd general system call | ||
! align=center| SELinux access check | ! align=center| SELinux access check | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ClearJobs | || ClearJobs | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| FlushDevices | || FlushDevices | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Get | || Get | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetAll | || GetAll | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetJob | || GetJob | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSeat | || GetSeat | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSession | || GetSession | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSessionByPID | || GetSessionByPID | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUser | || GetUser | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Halt | || Halt | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Introspect | || Introspect | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KExec | || KExec | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillSession | || KillSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillUser | || KillUser | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListJobs | || ListJobs | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListSeats | || ListSeats | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListSessions | || ListSessions | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListUsers | || ListUsers | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LockSession | || LockSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| PowerOff | || PowerOff | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reboot | || Reboot | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| SetUserLinger | || SetUserLinger | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateSeat | || TerminateSeat | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateSession | || TerminateSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateUser | || TerminateUser | ||
|| halt | || halt | ||
|- | |- | ||
|} | |} | ||
Table 10.2. Mapping of systemd general system calls on SELinux access checks | Table 10.2. Mapping of systemd general system calls on SELinux access checks | ||
{| style="border-spacing:0;width:9.931cm;" | {| style="border-spacing:0;width:9.931cm;" | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
! align=center| systemd general system call | ! align=center| systemd general system call | ||
! align=center| SELinux access check | ! align=center| SELinux access check | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ClearJobs | || ClearJobs | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| FlushDevices | || FlushDevices | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Get | || Get | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetAll | || GetAll | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetJob | || GetJob | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSeat | || GetSeat | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSession | || GetSession | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetSessionByPID | || GetSessionByPID | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| GetUser | || GetUser | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Halt | || Halt | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Introspect | || Introspect | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KExec | || KExec | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillSession | || KillSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| KillUser | || KillUser | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListJobs | || ListJobs | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListSeats | || ListSeats | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListSessions | || ListSessions | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| ListUsers | || ListUsers | ||
|| status | || status | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| LockSession | || LockSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| PowerOff | || PowerOff | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| Reboot | || Reboot | ||
|| reboot | || reboot | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| SetUserLinger | || SetUserLinger | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateSeat | || TerminateSeat | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateSession | || TerminateSession | ||
|| halt | || halt | ||
|- style="border:none;padding:0.049cm;" | |- style="border:none;padding:0.049cm;" | ||
|| TerminateUser | || TerminateUser | ||
|| halt | || halt | ||
|- | |- | ||
|} | |} | ||
'''Example 10.1. SELinux Policy for a System Service''' | '''Example 10.1. SELinux Policy for a System Service''' | ||
By using the | By using the '''sesearch''' utility, you can list policy rules for a system service | ||
* For example, calling the '''sesearch -A -s NetworkManager_t -c service''' command returns | |||
allow NetworkManager_t dnsmasq_unit_file_t : service { start stop status reload kill load } ; | allow NetworkManager_t dnsmasq_unit_file_t : service { start stop status reload kill load } ; | ||
allow NetworkManager_t nscd_unit_file_t : service { start stop status reload kill load } ; | allow NetworkManager_t nscd_unit_file_t : service { start stop status reload kill load } ; | ||
allow NetworkManager_t ntpd_unit_file_t : service { start stop status reload kill load } ; | allow NetworkManager_t ntpd_unit_file_t : service { start stop status reload kill load } ; | ||
allow NetworkManager_t pppd_unit_file_t : service { start stop status reload kill load } ; | allow NetworkManager_t pppd_unit_file_t : service { start stop status reload kill load } ; | ||
allow NetworkManager_t polipo_unit_file_t : service { start stop status reload kill load } ; | allow NetworkManager_t polipo_unit_file_t : service { start stop status reload kill load } ; | ||
=== 10.2. SELinux and journald === | === 10.2. SELinux and journald === | ||
In | In '''systemd''', the '''journald''' daemon (also known as '''systemd-journal''') is the alternative for the '''syslog''' utility, which is a system service that collects and stores logging data | ||
* It creates and maintains structured and indexed journals based on logging information that is received from the kernel, from user processes using the '''libc''' '''syslog()''' function, from standard and error output of system services, or using its native API | |||
* It implicitly collects numerous metadata fields for each log message in a secure way | |||
The '''systemd-journal''' service can be used with SELinux to increase security | |||
* SELinux controls processes by only allowing them to do what they were designed to do; sometimes even less, depending on the security goals of the policy writer | |||
* For example, SELinux prevents a compromised '''ntpd''' process from doing anything other than handle Network Time | |||
* However, the '''ntpd''' process sends '''syslog''' messages, so that SELinux would allow the compromised process to continue to send those messages | |||
* The compromised '''ntpd''' could format '''syslog''' messages to match other daemons and potentially mislead an administrator, or even worse, a utility that reads the '''syslog''' file into compromising the whole system | |||
The '''systemd-journal''' daemon verifies all log messages and, among other things, adds SELinux labels to them | |||
* It is then easy to detect inconsistencies in log messages and prevent an attack of this type before it occurs | |||
* You can use the '''journalctl''' utility to query logs of '''systemd''' journals | |||
* If no command-line arguments are specified, running this utility lists the full content of the journal, starting from the oldest entries | |||
* To see all logs generated on the system, including logs for system components, execute '''journalctl''' as root | |||
* If you execute it as a non-root user, the output will be limited only to logs related to the currently logged-in user | |||
'''Example 10.2. Listing Logs with '''journalctl'''''' | |||
It is possible to use '''journalctl''' for listing all logs related to a particular SELinux label | |||
* For example, the following command lists all logs logged under the '''system_u:system_r:policykit_t:s0''' label | |||
sudo journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0 | |||
Oct 21 10:22:42 localhost.localdomain polkitd[647]: Started polkitd version 0.112 | |||
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /etc/polkit-1/rules.d | |||
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /usr/share/polkit-1/rules.d | |||
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Finished loading, compiling and executing 5 rules | |||
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Acquired the name org.freedesktop.PolicyKit1 on the system bus Oct 21 10:23:10 localhost polkitd[647]: Registered Authentication Agent for unix-session:c1 (system bus name :1.49, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus) | |||
Oct 21 10:23:35 localhost polkitd[647]: Unregistered Authentication Agent for unix-session:c1 (system bus name :1.80 [/usr/bin/gnome-shell --mode=classic], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.utf8) | |||
For more information about '''journalctl''', see the journalctl(1) manual page | |||
[[Kategorie:SELinux/DOC]] | [[Kategorie:SELinux/DOC]] | ||
Version vom 25. März 2026, 10:55 Uhr
SELinux systemd Access Control
System services are controlled by the systemd daemon
- In previous releases of Red Hat Enterprise Linux, daemons could be started in two ways
- At boot time, the System V init daemon launched an init.rc script and then this script launched the required daemon
- For example, the Apache server, which was started at boot, got the following SELinux label:
system_u:system_r:httpd_t:s0 - An administrator launched the init.rc script manually, causing the daemon to run
- For example, when the service httpd restart command was invoked on the Apache server, the resulting SELinux label looked as follows:
unconfined_u:system_r:httpd_t:s0
When launched manually, the process adopted the user portion of the SELinux label that started it, making the labeling in the two scenarios above inconsistent
- With the systemd daemon, the transitions are very different
- As systemd handles all the calls to start and stop daemons on the system, using the init_t type, it can override the user part of the label when a daemon is restarted manually
- As a result, the labels in both scenarios above are system_u:system_r:httpd_t:s0 as expected and the SELinux policy could be improved to govern which domains are able to control which units
10.1. SELinux Access Permissions for Services
In previous versions of Red Hat Enterprise Linux, an administrator was able to control, which users or applications were able to start or stop services based on the label of the System V Init script
- Now, systemd starts and stops all services, and users and processes communicate with systemd using the systemctl utility
- The systemd daemon has the ability to consult the SELinux policy and check the label of the calling process and the label of the unit file that the caller tries to manage, and then ask SELinux whether or not the caller is allowed the access
- This approach strengthens access control to critical system capabilities, which include starting and stopping system services
For example, previously, administrators had to allow NetworkManager to execute systemctl to send a D-Bus message to systemd, which would in turn start or stop whatever service NetworkManager requested
- In fact, NetworkManager was allowed to do everything systemctl could do
- It was also impossible to setup confined administrators so that they could start or stop just particular services
To fix these issues, systemd also works as an SELinux Access Manager
- It can retrieve the label of the process running systemctl or the process that sent a D-Bus message to systemd
- The daemon then looks up the label of the unit file that the process wanted to configure
- Finally, systemd can retrieve information from the kernel if the SELinux policy allows the specific access between the process label and the unit file label
- This means a compromised application that needs to interact with systemd for a specific service can now be confined by SELinux
- Policy writers can also use these fine-grained controls to confine administrators
- Policy changes involve a new class called service, with the following permissions
class service {
start
stop
status
reload
kill
load
enable
disable
}
For example, a policy writer can now allow a domain to get the status of a service or start and stop a service, but not enable or disable a service
- Access control operations in SELinux and systemd do not match in all cases
- A mapping was defined to line up systemd method calls with SELinux access checks
- Table 10.1, “Mapping of systemd unit file method calls on SELinux access checks” maps access checks on unit files while Table 10.2, “Mapping of systemd general system calls on SELinux access checks” covers access checks for the system in general
- If no match is found in either table, then the undefined system check is called
Table 10.1. Mapping of systemd unit file method calls on SELinux access checks
| systemd unit file method | SELinux access check |
|---|---|
| DisableUnitFiles | disable |
| EnableUnitFiles | enable |
| GetUnit | status |
| GetUnitByPID | status |
| GetUnitFileState | status |
| Kill | stop |
| KillUnit | stop |
| LinkUnitFiles | enable |
| ListUnits | status |
| LoadUnit | status |
| MaskUnitFiles | disable |
| PresetUnitFiles | enable |
| ReenableUnitFiles | enable |
| Reexecute | start |
| Reload | reload |
| ReloadOrRestart | start |
| ReloadOrRestartUnit | start |
| ReloadOrTryRestart | start |
| ReloadOrTryRestartUnit | start |
| ReloadUnit | reload |
| ResetFailed | stop |
| ResetFailedUnit | stop |
| Restart | start |
| RestartUnit | start |
| Start | start |
| StartUnit | start |
| StartUnitReplace | start |
| Stop | stop |
| StopUnit | stop |
| TryRestart | start |
| TryRestartUnit | start |
| UnmaskUnitFiles | enable |
Table 10.1. Mapping of systemd unit file method calls on SELinux access checks
| systemd unit file method | SELinux access check |
|---|---|
| DisableUnitFiles | disable |
| EnableUnitFiles | enable |
| GetUnit | status |
| GetUnitByPID | status |
| GetUnitFileState | status |
| Kill | stop |
| KillUnit | stop |
| LinkUnitFiles | enable |
| ListUnits | status |
| LoadUnit | status |
| MaskUnitFiles | disable |
| PresetUnitFiles | enable |
| ReenableUnitFiles | enable |
| Reexecute | start |
| Reload | reload |
| ReloadOrRestart | start |
| ReloadOrRestartUnit | start |
| ReloadOrTryRestart | start |
| ReloadOrTryRestartUnit | start |
| ReloadUnit | reload |
| ResetFailed | stop |
| ResetFailedUnit | stop |
| Restart | start |
| RestartUnit | start |
| Start | start |
| StartUnit | start |
| StartUnitReplace | start |
| Stop | stop |
| StopUnit | stop |
| TryRestart | start |
| TryRestartUnit | start |
| UnmaskUnitFiles | enable |
Table 10.2. Mapping of systemd general system calls on SELinux access checks
| systemd general system call | SELinux access check |
|---|---|
| ClearJobs | reboot |
| FlushDevices | halt |
| Get | status |
| GetAll | status |
| GetJob | status |
| GetSeat | status |
| GetSession | status |
| GetSessionByPID | status |
| GetUser | status |
| Halt | halt |
| Introspect | status |
| KExec | reboot |
| KillSession | halt |
| KillUser | halt |
| ListJobs | status |
| ListSeats | status |
| ListSessions | status |
| ListUsers | status |
| LockSession | halt |
| PowerOff | halt |
| Reboot | reboot |
| SetUserLinger | halt |
| TerminateSeat | halt |
| TerminateSession | halt |
| TerminateUser | halt |
Table 10.2. Mapping of systemd general system calls on SELinux access checks
| systemd general system call | SELinux access check |
|---|---|
| ClearJobs | reboot |
| FlushDevices | halt |
| Get | status |
| GetAll | status |
| GetJob | status |
| GetSeat | status |
| GetSession | status |
| GetSessionByPID | status |
| GetUser | status |
| Halt | halt |
| Introspect | status |
| KExec | reboot |
| KillSession | halt |
| KillUser | halt |
| ListJobs | status |
| ListSeats | status |
| ListSessions | status |
| ListUsers | status |
| LockSession | halt |
| PowerOff | halt |
| Reboot | reboot |
| SetUserLinger | halt |
| TerminateSeat | halt |
| TerminateSession | halt |
| TerminateUser | halt |
Example 10.1. SELinux Policy for a System Service
By using the sesearch utility, you can list policy rules for a system service
- For example, calling the sesearch -A -s NetworkManager_t -c service command returns
allow NetworkManager_t dnsmasq_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t nscd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t ntpd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t pppd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t polipo_unit_file_t : service { start stop status reload kill load } ;
10.2. SELinux and journald
In systemd, the journald daemon (also known as systemd-journal) is the alternative for the syslog utility, which is a system service that collects and stores logging data
- It creates and maintains structured and indexed journals based on logging information that is received from the kernel, from user processes using the libc syslog() function, from standard and error output of system services, or using its native API
- It implicitly collects numerous metadata fields for each log message in a secure way
The systemd-journal service can be used with SELinux to increase security
- SELinux controls processes by only allowing them to do what they were designed to do; sometimes even less, depending on the security goals of the policy writer
- For example, SELinux prevents a compromised ntpd process from doing anything other than handle Network Time
- However, the ntpd process sends syslog messages, so that SELinux would allow the compromised process to continue to send those messages
- The compromised ntpd could format syslog messages to match other daemons and potentially mislead an administrator, or even worse, a utility that reads the syslog file into compromising the whole system
The systemd-journal daemon verifies all log messages and, among other things, adds SELinux labels to them
- It is then easy to detect inconsistencies in log messages and prevent an attack of this type before it occurs
- You can use the journalctl utility to query logs of systemd journals
- If no command-line arguments are specified, running this utility lists the full content of the journal, starting from the oldest entries
- To see all logs generated on the system, including logs for system components, execute journalctl as root
- If you execute it as a non-root user, the output will be limited only to logs related to the currently logged-in user
'Example 10.2. Listing Logs with journalctl'
It is possible to use journalctl for listing all logs related to a particular SELinux label
- For example, the following command lists all logs logged under the system_u:system_r:policykit_t:s0 label
sudo journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0 Oct 21 10:22:42 localhost.localdomain polkitd[647]: Started polkitd version 0.112 Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /etc/polkit-1/rules.d Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /usr/share/polkit-1/rules.d Oct 21 10:22:44 localhost.localdomain polkitd[647]: Finished loading, compiling and executing 5 rules Oct 21 10:22:44 localhost.localdomain polkitd[647]: Acquired the name org.freedesktop.PolicyKit1 on the system bus Oct 21 10:23:10 localhost polkitd[647]: Registered Authentication Agent for unix-session:c1 (system bus name :1.49, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus) Oct 21 10:23:35 localhost polkitd[647]: Unregistered Authentication Agent for unix-session:c1 (system bus name :1.80 [/usr/bin/gnome-shell --mode=classic], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.utf8)
For more information about journalctl, see the journalctl(1) manual page