1

I have a MariaDB server on CentOS 7. The server shall play slave and replicate the a remote master server. The remote master server can be reached through an SSH tunnel. The SSH tunnel "inlet" is at 127.0.0.1:3307.

Connecting to this endpoint using the MariaDB client program works.

However, the MariaDB server is unable to connect. In the MySQL error log, one finds: Slave I/O: error connecting to master '[email protected]:3307' - retry-time: 60 maximum-retries: 86400 message: Can't connect to MySQL server on '127.0.0.1' (13 "Permission denied"), Internal MariaDB error code: 2003.

Evidently, one immediately thinks of SELinux putting the kibosh on nonstandard connections outgoing from a MariaDB server.

After having put SELinux in permissive mode (edit /etc/selinux/config and reboot), the good phociform process manages to connect.

Let's examine /var/log/audit/audit.log which logs SELinux denial events (among other) using ausearch (further info on auditd in "a brief introduction to auditd")

ausearch --comm mysqld

This gives entries like:

time->Wed Mar 21 18:52:53 2018
type=PROCTITLE msg=audit(1521654773.504:120): proctitle="/usr/sbin/mysqld"
type=SYSCALL msg=audit(1521654773.504:120): arch=c000003e syscall=42 success=no exit=-115 a0=41 a1=7fd1f4028ad0 a2=10 a3=72 items=0 ppid=1 pid=1342 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null)
type=AVC msg=audit(1521654773.504:120): avc:  denied  { name_connect } for  pid=1342 comm="mysqld" dest=3307 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket

(syscall 42 is sys_connect)

Very cool.

Now, I still have to read through The Manual (and maybe it won't even help), so the question:

What command do I execute to let MariaDB connect to 127.0.0.1:3307? Because I want to re-enable SELinux.

1
  • Are there any relevant AVC type log entries? Do you have any custom audit rules in place?
    – sebasth
    Mar 21, 2018 at 20:20

2 Answers 2

2

SELinux policies control every action that a process can execute on a given object - like files, devices, or sockets. If a daemon has been configured to listen or communicate using a nonstandard port, then the targeted policy denies that action, as it should. Labels are used to control ports. To find the label for MariaDB, use semanage, and filter the results with grep using its well-known port number.

semanage port -l | grep 3306

This produces the following output.

mysqld_port_t tcp 1186, 3306, 63132-63164

To alter the rule for this label, use semanage again as follows for port 3307.

semanage port -a -t mysqld_port_t -p tcp 3307

After executing the command above, check the rule again to see that 3307 is now permitted.

semanage port -l | grep 3307

This should show 3307 in the list of ports.

mysqld_port_t tcp 3307, 1186, 3306, 63132-63164
2
  • Testing this now... Mar 22, 2018 at 15:28
  • Yes... it works. Thanks! Also added an additional answer as I have taken the time to look at the SELinux messaging subsystem (though all is not yet clear). Mar 22, 2018 at 16:01
1

If the package setroubleshoot-server has been installed (recommended), then the program setroubleshootd will be invoked via dbus from the audit daemon auditd (although indirectly) and given SELinux AVC records to process:

SELinux Notification and Logging Cascade

Note that setroubleshootd is not actually a "daemon" (it used to be) but an invoked-on-activity program that exits again if all is quiet.

setroubleshootd will log to syslog, and you will see AVC denial information. By default, this will end up in /var/log/messages unless rsyslog has been configured differently.

setroubleshootd will also notify dbus clients interested in SELinux events like sealert or GUI widgets.

Use sealert to examine AVC records. The man page says: "The two most useful command line options are -l to "lookup" an alert ID and -a to "analyze" a log file."

Looking at /var/log/messages, one will now see things like:

setroubleshoot: SELinux is preventing mysqld from
name_connect access on the tcp_socket port 3307. For complete SELinux
messages run: sealert -l 90cd70e9-0bb2-4668-b165-d5be37e26b22

..and additional lines of very readable information which turn out to be a goo part of the output of sealert -l 90cd70e9-0bb2-4668-b165-d5be37e26b22.

So let's run sealert -l 90cd70e9-0bb2-4668-b165-d5be37e26b22 -- this gives us good advice (not that this record was obtained while SELinux was enabled):

SELinux is preventing mysqld from name_connect access on the tcp_socket port 3307.

*****  Plugin connect_ports (85.9 confidence) suggests   *********************

If you want to allow mysqld to connect to network port 3307
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 3307
    where PORT_TYPE is one of the following: dns_port_t, dnssec_port_t,
    kerberos_port_t, mysqld_port_t, ocsp_port_t, tram_port_t.

*****  Plugin catchall_boolean (7.33 confidence) suggests   ******************

If you want to allow nis to enabled
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
You can read 'None' man page for more details.
Do
setsebool -P nis_enabled 1

*****  Plugin catchall_boolean (7.33 confidence) suggests   ******************

If you want to allow mysql to connect any
Then you must tell SELinux about this by enabling the 'mysql_connect_any' boolean.
You can read 'None' man page for more details.
Do
setsebool -P mysql_connect_any 1

*****  Plugin catchall (1.35 confidence) suggests   **************************

If you believe that mysqld should be allowed name_connect access on the
port 3307 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 'mysqld' --raw | audit2allow -M my-mysqld
# semodule -i my-mysqld.pp


Additional Information:
Source Context                system_u:system_r:mysqld_t:s0
Target Context                system_u:object_r:unreserved_port_t:s0
Target Objects                port 3307 [ tcp_socket ]
Source                        mysqld
Source Path                   mysqld
Port                          3307
Host                          foobar.example.com
Source RPM Packages
Target RPM Packages
Policy RPM                    selinux-policy-3.13.1-166.el7_4.9.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     foobar.example.com
Platform                      Linux foobar.example.com
                              3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7
                              19:03:37 UTC 2018 x86_64 x86_64
Alert Count                   36
First Seen                    2018-03-22 16:04:59 CET
Last Seen                     2018-03-22 16:39:59 CET
Local ID                      90cd70e9-0bb2-4668-b165-d5be37e26b22

Raw Audit Messages
type=AVC msg=audit(1521733199.870:201): avc:  denied  { name_connect }
for  pid=1352 comm="mysqld" dest=3307
scontext=system_u:system_r:mysqld_t:s0
tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket


Hash: mysqld,mysqld_t,unreserved_port_t,tcp_socket,name_connect

So, with 85.9 confidence ("I'll be baaack!")

"If you want to allow mysqld to connect to network port 3307 then you need to modify the port type. Do semanage port -a -t PORT_TYPE -p tcp 3307" where PORT_TYPE is mysqld_port_t!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .