SELinux has a bit of a reputation for being arcane - and one that I think is well deserved.
The way I understand it, the context of a program that is running defines what the current policy will permit it to access or do. As such, as you've surmised, the haproxy_t type is allowed some permissions based on the http_port_t type.
Now let's try to actually figure out how to find this relationship.
Get SELinux label
As you know, ps -eZ
will list the SELinux labels of running processes - in the case of haproxy, that user:role:type:sensitivity
is system_u:system_r:haproxy_t:s0
. The important bit is the type, in this case haproxy_t.
Permissions
Now to find out which permissions this type has, we can use sesearch[1]:
sesearch -d -A -s haproxy_t
-d
shows only direct results - if you omit this, this will also show all objects from seinfo --type=haproxy_t -x
!
-A
searches for allow rules
-s haproxy_t
defines the source type as haproxy_t
Now we get quite a lot of results (106 on my CentOS 7 VM), because, as it happens, there are a lot of different, granular permissions defined.
At this point you need to to know something more about what you're searching for - either the class of what the permission applies to, the target type or the permission name itself.
Search by class
Let's go with class first: so we know that our source type is haproxy_t
, and we think that our class might be something to do with the internet, so it's a good bet that it might be tcp_socket.
sesearch -d -A -s haproxy_t -c tcp_socket
This will list all allow rules for the source type haproxy_t that have anything to do with tcp_socket. That's narrowed it down quite a bit, but it's still anyone's guess which one of these could be the ones we're looking for.
Search by specific permissions
Next, let's try with permissions - we know that we need our haproxy to bind and connect on specific ports, right? so we try the name_bind and the name_connect permissions.
sesearch -d -A -s haproxy_t -p "name_bind, name_connect"
Found 4 semantic av rules:
allow haproxy_t http_cache_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t commplex_main_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t http_port_t : tcp_socket { name_bind name_connect } ;
allow haproxy_t port_type : tcp_socket name_bind ;
This shows only 4 results, only 3 of which could be our culprit! These results are, as far as SELinux is concerned, the only ports any process with the context of haproxy_t is allowed to bind to.
Search by target type
This one is a bit of a cheat, because in this case we're actually looking for the target type! But, for the sake of completeness - for instance, if we wanted to find out what permissions haproxy_t gets from http_port_t, we can use the following:
sesearch -d -A -s haproxy_t -t http_port_t
Found 1 semantic av rules:
allow haproxy_t http_port_t : tcp_socket { name_bind name_connect } ;
and that, of course, gives us only one result, and the permissions that apply.
Ports
Now that we know the target objects, and that they are definitions of ports, we can find out exactly which ports they encompass. Well, let's find out:
semanage port -l | grep -E 'http_cache_port_t|commplex_main_port_t|http_port_t'
commplex_main_port_t tcp 5000
commplex_main_port_t udp 5000
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t upd 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
And so, we see that tcp port 5601 is nowhere on that list. Now, as far as SELinux cares, you can add that port to any of those types with the semanage port --add --type XXX --proto tcp 5601
command, and it'll work out. But since this is serving http, http_port_t seems the most applicable type.
Hopefully that demystifies it just a little bit.
[1] Available in the setools-console package.