Unable to start Redis under SELinux

redisselinux

I having a rather persistent issue with my Redis instance. While SELinux is in enforcing mode, Redis server is unable to start:

[root@server ~]# service redis start
Starting redis-server:                                     [  OK  ]

But in fact, it did not start as shown by lsof. It returns no result:

[root@server ~]# lsof -i :6379

To futher confirm the it is not running, there is a redis log:

[5539] 21 Nov 03:44:34 # Opening port 6379: bind: Permission denied

Now, I am pretty new with SELinux managing so, please bear with me as I might have missed something. This is what I was able to see:

[root@server ~]# semanage port -l | grep "redis"
redis_port_t                   tcp      6379

[root@server ~]# semanage user -l
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles
....
redis           user       s0         s0                             user_r
....

The above redis user did not exist initially, but I tried adding it as redis-server really runs under it. That did not help…

Just to note, Redis server is used internally, so it listens only to 127.0.0.1:6379.

Does anyone have any ideas?

For the time being, I can put SELinux in permissive mode, but I would really like to tighten it up and do it "by-the-book".

UPDATE:

[root@server ~]# ausearch -ts recent -m avc
----
time->Thu Nov 24 13:48:13 2016
type=SYSCALL msg=audit(1480013293.595:34717): arch=c000003e syscall=49 success=no exit=-13 a0=4 a1=7ffea866c0f0 a2=10 a3=7ffea866be50 items=0 ppid=1 pid=16468 auid=0 uid=495 gid=495 euid=495 suid=495 fsuid=495 egid=495 sgid=495 fsgid=495 tty=(none) ses=5202 comm="redis-server" exe="/usr/sbin/redis-server" subj=unconfined_u:system_r:redis_t:s0 key=(null)
type=AVC msg=audit(1480013293.595:34717): avc:  denied  { name_bind } for  pid=16468 comm="redis-server" src=6379 scontext=unconfined_u:system_r:redis_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket

UPDATE(2)

[root@server ~]# rpm -qa | grep -i redis
redis-2.4.10-1.el6.x86_64
php56w-pecl-redis-2.2.7-1.w6.x86_64

SOLUTION:

Following @Matthew's suggestion, I started analyzing the redis_port_t and http_port_t:

[root@server ~]# semanage port -l | grep "redis_port_t"
redis_port_t                   tcp      6379

[root@server ~]# semanage port -l | grep "http_port_t"
http_port_t                    tcp      6379, 80, 81, 443, 488, 8008, 8009, 8443, 9000

And there it was! The port 6379 was added to both of port policies! And yes, I know remember doing this when I started the migration 🙁 (shame on me).

So, running this fixed the issue:

semanage port -d -t http_port_t 6379
semanage permissive -d redis_t // I don't need this anymore
service redis restart
lsof -i :6379

And there it was 🙂

redis-ser 4575 redis    4u  IPv4 236174      0t0  TCP localhost:6379 (LISTEN)

Best Answer

I think theres something odd going on in that policy of yours.

If you check the audit logs, it says whilst the SELinux source context is correctly labelled as redis_t the target context is labelled as http_port_t. This is despite what your policy says, that it should be redis_port_t.

This means whats in the kernel and whats in policy dont match. The port is still 6379 though.

You may want to check what you have configured for your http_port_t as well as your redis_port_t. As far as I understand, port policy bindings can only have one label per port/protocol, so I suspect whats in your policy store does not reflect whats in your server presently.

You may want to try doing a semodule -B to rebuild and reload your policy to try to fix the synchronization problem.

If no luck, search whats in the port listings for http_port_t and update the question.