Thursday, November 20, 2014

SElinux: allow httpd to connect to a specific port

My system is running CentOS 6.4 with apache2.2.15. SElinux is enforcing and I'm trying to connect to a local instance of redis through my python/wsgi app. I get Error 13, Permission denied. I could fix this via the command:

setsebool -P httpd_can_network_connect

However, I don't exactly want httpd to be able to connect to all tcp ports. How can I specify which ports/networks httpd is allowed to connect to? If I could make a module to allow httpd to connect to port 6379 ( redis ) or any tcp on, that would be preferable. Not sure why my paranoia is so strong on this, but hey...

Anyone know?

To get semanage command on system, install policycoreutils-python package:

# yum install policycoreutils-python

By default, the SELinux policy will only allow services access to recognized ports associated with those services:

# semanage port -l | egrep '(^http_port_t|6379)'

http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000

PHP script to test connection:

# cat redis.php
$redis=new Redis();
$connected= $redis->connect('', 6379);

if(!$connected) {
  die( "Cannot connect to redis server.\n" );

echo "Connected successfully.\n";

# curl http://localhost/redis.php

Cannot connect to redis server.

Add Redis port (6379) to SELinux policy:

# semanage port -a -t http_port_t -p tcp 6379

# semanage port -l | egrep '(^http_port_t|6379)'

http_port_t tcp 6379, 80, 81, 443, 488, 8008, 8009, 8443, 9000

# curl http://localhost/redis.php

Connected successfully.

You can also install setroubleshoot-server RPM and run: sealert -a /var/log/audit/audit.log - it will give you a nice report with useful suggestions (including command above).

You could temporary put selinux in permissive mode and let httpd connect to redis, then generate and build a custom policy module using audit2allow.

No comments: