51

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 127.0.0.1, that would be preferable. Not sure why my paranoia is so strong on this, but hey...

Anyone know?

1
  • Would it not be better to force it to go out through a proxy? That way you can a) have better control over what can be accessed b) have better auditing over what happened and when. May 13, 2015 at 9:56

3 Answers 3

63

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
# 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).

PHP script to test connection:

# cat redis.php 
<?php

$redis=new Redis();
$connected= $redis->connect('127.0.0.1', 6379);

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

echo "Connected successfully.\n";

?>
7
  • 3
    I had the problem on Fedora 23 to send e-mail (by connecting to 127.0.0.1 on port 25) from a perl script (using Net::SMTP) started from httpd. "Permission for httpd to connect to port 25" is not what one is looking for in that case. Indeed adding port 25 to SELinux type http_port_t fails because port 25 is already used (for another SELinux type): ValueError: Port tcp/25 already defined. The correct way to allow httpd to connect to port 25 is to set the corresponding SELinux policy boolean on: setsebool -P httpd_can_sendmail on (see getseebool -a). (continued in part 2) Jan 3, 2016 at 18:10
  • 1
    (continued from part 1) But if you want to send from a perl script, you have to explicitly create a SELinux module that allows that: sealert -b; sealert -a /var/log/audit/audit.log; grep perl /var/log/audit/audit.log | audit2allow -M mypol; semodule -v -i mypol.pp. Then it works! Jan 3, 2016 at 18:11
  • @DavidTonhofer Minor typo in the getsebool -a command (one fewer e).
    – davidjb
    Jun 22, 2018 at 0:33
  • 1
    @DavidTonhofer you don't have to create a new policy for existing port, you can modify it instead: semanage port -m -t http_port_t -p tcp 25, see semanage port --help
    – HTF
    Jun 22, 2018 at 5:54
  • For zabbix, there already is a specual boolean on CentOS 7.5: setsebool -P httpd_can_connect_zabbix true Feb 21, 2019 at 17:49
23

You may need to use

semanage port -m -t http_port_t -p tcp 6379

If semanage is missing then add the package policycoreutils-python

yum install policycoreutils-python
3
  • 1
    semanage may be in policycoreutils-python-utils now (at least on Fedora 23) Jan 3, 2016 at 17:28
  • 1
    CentOS 7 still includes semanage in policycoreutils-python.
    – jxmallett
    Apr 15, 2016 at 0:38
  • thank you for giving an answer to the question instead of something else. Jun 7, 2019 at 18:02
3

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

You must log in to answer this question.

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