How to Configure SELinux to Allow HTTPD to Connect to Specific Ports (Redis 6379 Example)


2 views

When running Apache (httpd) under enforcing SELinux on CentOS/RHEL systems, you might encounter "Error 13: Permission denied" when your web applications attempt to make outbound network connections. While disabling SELinux entirely or using setsebool -P httpd_can_network_connect=1 would work, these solutions create unnecessary security risks by granting blanket network access.

SELinux implements Type Enforcement (TE) rules that control which domains (like httpd_t) can access which ports. To view current port assignments:

semanage port -l | grep http
# Output typically shows:
# http_port_t      tcp      80, 443, 8080, 8009

For Redis running on default port 6379:

semanage port -a -t http_port_t -p tcp 6379
# Verify the change:
semanage port -l | grep http_port_t

For more granular control when you can't modify existing port types:

# 1. Generate policy module template
audit2allow -a -M httpd_redis
# Review the generated httpd_redis.te file

# 2. Compile and load the module
make -f /usr/share/selinux/devel/Makefile httpd_redis.pp
semodule -i httpd_redis.pp

To restrict connections to only localhost (127.0.0.1):

# 1. Create a custom boolean
semanage boolean --modify --on --name httpd_connect_local

# 2. Create corresponding policy module
# (Example .te file contents)
module httpd_local 1.0;
require {
    type httpd_t;
    class tcp_socket name_connect;
}
allow httpd_t self:tcp_socket name_connect;
corenet_tcp_connect_http_port(httpd_t)

After making changes:

# Check SELinux denials
ausearch -m avc -ts recent

# Test connection from Apache
curl -v localhost:6379

# Temporary logging for debugging
semanage permissive -a httpd_t
  • Always test in permissive mode first: setenforce 0
  • Document all SELinux modifications for audit purposes
  • Consider creating custom SELinux types for sensitive services
  • Regularly review /var/log/audit/audit.log for new denials

When running a Python/WSGI application on CentOS 6.4 with Apache 2.2.15 under enforcing SELinux, you might encounter "Error 13: Permission denied" when trying to connect to Redis (port 6379) or other specific services. While the quick fix is:

setsebool -P httpd_can_network_connect=1

This grants Apache permission to connect to all network ports, which isn't ideal for security-conscious environments.

SELinux provides finer-grained control through port labeling. First, check current port assignments:

semanage port -l | grep http_port_t

To allow HTTPD to connect specifically to Redis (6379):

semanage port -a -t http_port_t -p tcp 6379

For connections only to 127.0.0.1, create a custom SELinux policy module:

cat << EOF > local_httpd_redis.te
module local_httpd_redis 1.0;

require {
    type httpd_t;
    type unreserved_port_t;
    class tcp_socket name_connect;
}

allow httpd_t unreserved_port_t:tcp_socket name_connect;
EOF

checkmodule -M -m -o local_httpd_redis.mod local_httpd_redis.te
semodule_package -o local_httpd_redis.pp -m local_httpd_redis.mod
semodule -i local_httpd_redis.pp

After making changes, verify with:

sealert -a /var/log/audit/audit.log

And test your connection. If issues persist, temporarily set SELinux to permissive mode for debugging:

setenforce 0

Remember that:

  • Port 6379 should still be firewalled appropriately
  • Redis should be configured with authentication
  • Consider using Unix domain sockets for local connections