49

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

61

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
22

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
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.