SELinux and Apache - MySQL connections

A long-standing project at $WORK is to move the website to a new server. I'm also using it as a chance to get our website working under SELinux, rather than just automatically turning it off. There's already one site on this server, running Wordpress, and I decided to get serious about migrating the other website, which runs Drupal.

First time I fired up Drupal, I got this error:

avc:  denied  { name_connect } for  pid=30789 comm="httpd" dest=3306
scontext=system_u:system_r:httpd_t:s0
tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket

As documented here, the name_connect permission allows you to name sockets ("these are the mysql sockets, these are the SMTP sockets...") and set permissions that way. Okay, so now we're getting a note that prevented Drupal from working because SELinux has denied httpd access to the mysqld TCP port.

What suprised me is that the Wordpress site did not seem to be encountering this error. The two relevant parts of the config files are:

$db_url = 'mysqli://user:password@127.0.0.1/database';

define('DB_NAME', 'wp_db');
define('DB_USER', 'wp_db_user');
define('DB_PASSWORD', 'password');
define('DB_HOST', 'localhost');

Hm, the only difference is that localhost-vs-127.0.0.1 thing...

After some digging, it appears to be PHP's mysqli at work. From the documentation:

host: Can be either a host name or an IP address. Passing the NULL value or the string "localhost" to this parameter, the local host is assumed. When possible, pipes will be used instead of the TCP/IP protocol.

See the difference? Without looking up the code for mysqli, I think that an IP address -- even 127.0.0.1 -- makes mysqli just try TCP connections; using "localhost" makes it try a named pipe first. Since TCP connections to the MySQL port apparently aren't allowed by default CentOS SELinux policy, the former fails.

Solution: make it "localhost" in both, and remember not to make assumptions.