Troubleshooting SELinux
- WHAT?
A system with SELinux in the
enforcing
mode may cause access denials that may prevent applications from running correctly. You can useaudit2allow
orsetroubleshoot
to analyze denial messages in a user-friendly way.- WHY?
This article provides instructions on how to solve access denials caused by SELinux without decreasing the security of your system.
- EFFORT
It takes approximately 30 minutes to read the article.
- GOAL
You will be able to use one of the further described tools to debug SELinux denials.
- REQUIREMENTS
A running system with enabled SELinux.
1 The /var/log/audit/audit.log
file #
By default, if SELinux is the reason something is not working, a log
message to this effect is sent to the
/var/log/audit/audit.log
file.
/var/log/audit/audit.log
If you see an empty
/var/log/audit/audit.log
, it usually means that the auditd
service is not
running. In this case, proceed as follows:
Start the
auditd
service:>
sudo
systemctl start auditd
Enable the service in the targets of your system, using
>
sudo
systemctl enable auditd
The /var/log/audit/audit.log
file stores messages of access
denials, service events and so on.
In
Example 1: “Example lines from /etc/audit/audit.log
”,
you can see a partial example of the contents of
/var/log/audit/audit.log
.
/etc/audit/audit.log
#type=DAEMON_START msg=audit(1348173810.874:6248): auditd start, ver=1.7.7 format=raw kernel=3.0.13-0.27-default auid=0 pid=4235 subj=system_u:system_r:auditd_t res=success type=AVC msg=audit(1348173901.081:292): avc: denied { write } for pid=3426 comm="smartd" name="smartmontools" dev=sda6 ino=581743 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:293): avc: denied { remove_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:294): avc: denied { unlink } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:295): avc: denied { rename } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582373 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:296): avc: denied { add_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:297): avc: denied { create } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:298): avc: denied { write open } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:299): avc: denied { getattr } for pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316
A single message looks as follows:
type=AVC msg=audit(1348173901.081:299): avc: denied { getattr } for pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
Every line of the message can be broken down into sections. For example, the sections in the last line are:
type=AVC
:Every SELinux-related audit log line starts with the type identification, for example,
type=AVC
. Note that a message with thetype=SYSCALL
that follows one with a different type and has the same value ofmsg
may provide further information regarding the event.msg=audit(1348173901.309:300)
:This is the time stamp, which is written in epoch time, the number of seconds that have passed since Jan 1, 1970. You can use
date -d
on the part up to the dot in the epoch time notation to find out when the event happened:>
date -d @1348173901
Thu Sep 20 16:45:01 EDT 2012avc: denied { append }
:The specific action that was denied. In this case, the system has denied the appending of data to a file. While browsing through the audit log file, you can see other system actions, such as write open, getattr and more.
for pid=1316
:the process ID of the command or process that initiated the action
comm="rsyslogd"
:the specific command that was associated with that PID
name="smartmontools"
:the name of the subject of the action
dev=sda6 ino=582296
:the block device and inode number of the file that was involved
scontext=system_u:system_r:syslogd_t
:the source context, which is the context of the initiator of the action
tclass=file
:a class identification of the subject
2 Analyzing /var/log/audit/audit.log
with audit2allow
#
Instead of interpreting the events in
/var/log/audit/audit.log
yourself, you can use the
audit2allow
command.
The command helps analyze the
cryptic log messages in /var/log/audit/audit.log
. An
audit2allow
troubleshooting session always consists of
three different commands. First, you would use audit2allow -w
-a
to present the audit information in a more readable way. The
audit2allow -w -a
by default works on the
audit.log
file. If you want to analyze a specific
message in the audit.log
file, copy it to a temporary file and analyze
the file with:
>
sudo
audit2allow -w -i FILENAME
>
sudo
audit2allow -w -i testfile
type=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316 comm="rsyslogd" name="acpid" dev=sda6 ino=582296 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
- This was caused by:
A missing type enforcement (TE) allow rule.
To generate a loadable module to allow this access, run
>
sudo
audit2allow
To find out which specific rule has denied access, you can use
audit2allow -a
to show the enforcing rules from all
events that were logged into the audit.log
file, or
audit2allow -i FILENAME
to
show it for messages that you have stored in a specific file:
>
sudo
audit2allow -i testfile
#============= syslogd_t ============== allow syslogd_t apmd_log_t:file append;
To create an SELinux module with the name mymodule
that you can load to allow the access that was previously denied, run
>
sudo
audit2allow -a -R -M mymodule
If you want to do this for all events that have been logged into the
audit.log
file, use the -a -M
command arguments. To do it only for specific messages that are in a
specific file, use -i -M
as in the example below:
>
sudo
audit2allow -i testfile -M example
******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i example.pp
As indicated by the audit2allow
command, you can now
run this module by using the semodule -i
command,
followed by the name of the module that audit2allow
has created for you (example.pp
in the above
example).
3 Analyzing AVC messages using setroubleshoot
#
To analyze AVC denial messages in a user-friendly way, you can use
the setroubleshoot
tool.
3.1 Overview of setroubleshoot
#
3.1.1 What is setroubleshoot
? #
setroubleshoot
is a tool that collects SELinux audit
events from the kernel and analyses these events. If such an event
occurs, setroubleshoot
informs the administrator.
3.1.2 setroubleshoot
components #
The SELinux troubleshooting process involves the following components, all of which are installed on SLE Micro by default.
setroubleshoot-server
provides the following tools:setroubleshootd
—the main daemon handling incoming requests and plug-in definitions. The daemon is activated on demand and does not require running via thesystemd
service. It can be managed only by a privileged user and a dedicatedsetroubleshoot
user.a database of alerts in the file
/var/lib/setroubleshoot/setroubleshoot_database.xml
sealert
—a command-line user interface to analyze the/var/log/audit.log
sedispatch
—an audit dispatcher that scans SELinux AVC messages and transforms them into a DBus message, then passed to the daemon.
setroubleshoot-plugins
—the plug-ins are used for AVC message analysis and provide suggestions on how to fix problems.
3.1.3 How does setroubleshoot
work? #
setroubleshoot
comprises a daemon and analysis
plug-ins. When a plug-in detects a problem, it is reported to the daemon,
which then checks whether this is a known problem. If not, the new
problem is added to the database along with a suggested solution.
3.1.4 Benefits of setroubleshoot
#
setroubleshoot
provides the following functionalities
to help you solve problems on your SELinux secured systems:
Sending alerts to the administrator when there is an AVC denial.
Automatic analysis of AVC denials.
Suggesting possible fixes, such as adjusting system configuration or installing updates and so on.
Browsing of previous alerts.
3.2 Configuring setroubleshoot
#
Even though the configuration of setroubleshoot
does
not require adjustment, you may face particular use cases when you need
to change the defaults. The following sections provide the usual use
cases.
The configuration file for setroubleshoot
is
/etc/setroubleshoot
. Usually, you do not have to
modify the configuration besides setting the e-mail notifications. However,
if you need to change the configuration, you can either edit the file, or
you can use the setroubleshootd
command to configure a
particular item. The command syntax is the following:
#
setroubleshootd -c SECTION.OPTION=VALUE
For example, to set the from_address
option, run the
command as follows:
#
setroubleshootd -c email.from_address="example@mail.com"
3.2.1 Configuring setroubleshoot
logging level #
The default logging level (the value of sealert_log
and setroubleshootd_log
) is set to
warning
. However, you can set the value to one of the
following:
- critical
Only serious errors that prevent the system from functioning are logged.
- error
Serious errors that may influence the system are reported.
- warning
An indication that something unexpected happened, or that a problem might occur in the near future. However, the system works as expected.
- info
A confirmation that the system is running correctly is logged.
- debug
Detailed information for debugging purposes is logged.
3.2.2 Configuring setroubleshoot
to send e-mail notifications #
setroubleshoot
can send you e-mail notifications if
there is an AVC denial in the system.
To get these notifications, proceed as follows:
Open the
/etc/setroubleshoot/setroubleshoot.conf
.In the file, adjust the following configuration items to suit your needs:
- smtp_host
If the SMTP server does not run on the local host, fill in the server address.
- smtp_port
The default is 25. Usually, this value does not require any adjustment.
- from_address
Add the sender address.
- subject
Configure a generic subject of all messages.
- recipients_filepath
Specify the location of the notification recipients list.
- use_sendmail
Set to
true
if you use SendMail.
Create the mail recipients file on the path defined by the
recipients_filepath
option (/var/lib/setroubleshoot/email_alerts-recipients
by default).Each e-mail address must be on a separate line. Comments are denoted with the # symbol.
3.2.3 Configuring the setroubleshoot
database #
You can change the amount of records in the
setroubleshootd
database, its location or the file
name prefix.
database_dir
Specify an absolute path to the directory where the database XML file should reside.
filename
Configure a custom prefix of the database file name. The file name then looks as follows:
FILENAME_PREFIX_database.xml
.max_alerts
Defines the maximum number of records in the database. Specify
0
for an unlimited number of records.max_alert_age
Alerts older than the set limit are deleted from the database. You can use the units: year, month, day, hour, minute and second even in the plural form and you can use more than one unit, for example,
3 weeks 2 days
, which equals to 23 days. If left empty, there is no limit.
3.2.4 Configure setroubleshoot
to collect information from remote servers #
You can configure setroubleshoot
to gather SELinux
audit data from remote servers. To do so, configure the address list.
- [listen_for_client] address_list
On the server side.
- [client_connect_to] address_list
On the client side.
Addresses on the list are in this format:
[{FAMILY}]ADDRESS[:PORT_NUMBER]
Where {FAMILY} is {inet}
or
{unix}%{path}s
. If the address family is
inet
, you can optionally specify a port number,
otherwise the port number is set to the default specified by the
default_port
configuration option. The default value
{unix}%{path}s hostname
means listening on the local
Unix domain socket.
3.3 Running the /var/log/audit/audit.log
analysis #
To let the setroubleshoot
tool analyze the audit log
file, run the command:
>
sudo
sealert -a /var/log/audit/audit.log
In the following example output, there are two port values assigned to the SSHD service:
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------
SELinux is preventing sshd from name_bind access on the tcp_socket port 2222.
***** Plugin bind_ports (92.2 confidence) suggests ************************
If you want to allow sshd to bind to network port 2222
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 2222 1
where PORT_TYPE is one of the following: ssh_port_t, vnc_port_t, xserver_port_t.
***** Plugin catchall_boolean (7.83 confidence) suggests ******************
If you want to allow nis to enabled
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
Do
setsebool -P nis_enabled 1
***** Plugin catchall (1.41 confidence) suggests **************************
If you believe that sshd should be allowed name_bind access on the port 2222 tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'sshd' --raw | audit2allow -M my-sshd
# semodule -X 300 -i my-sshd.pp
Additional Information:
...
First Seen 2024-02-07 14:26:27 UTC
Last Seen 2024-02-08 03:30:12 UTC
Local ID b5cbdd75-3f8d-425d-af75-f6cbf1540ffd
Raw Audit Messages
type=AVC msg=audit(1707363012.797:25): avc: denied { name_bind } for pid=841 comm="sshd" src=2222 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0
Hash: sshd,sshd_t,unreserved_port_t,tcp_socket,name_bind
The |
4 Legal Notice #
Copyright© 2006–2024 SUSE LLC and contributors. All rights reserved.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled “GNU Free Documentation License”.
For SUSE trademarks, see https://www.suse.com/company/legal/. All other third-party trademarks are the property of their respective owners. Trademark symbols (®, ™ etc.) denote trademarks of SUSE and its affiliates. Asterisks (*) denote third-party trademarks.
All information found in this book has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither SUSE LLC, its affiliates, the authors, nor the translators shall be held liable for possible errors or the consequences thereof.