O SELinux tem uma certa reputação de ser arcano - e um que eu acho que é bem merecido.
Do jeito que eu entendo, o contexto de um programa que está sendo executado define o que a política atual permitirá que ele acesse ou faça. Assim, como você imaginou, o tipo haproxy_t tem permissão para algumas permissões baseadas no tipo http_port_t.
Agora, vamos tentar descobrir como encontrar esse relacionamento.
Obtenha o rótulo do SELinux
Como você sabe, ps -eZ
listará os rótulos do SELinux dos processos em execução - no caso do haproxy, que user:role:type:sensitivity
é system_u:system_r:haproxy_t:s0
. O bit importante é o tipo, neste caso haproxy_t.
Permissões
Agora, para descobrir quais permissões esse tipo tem, podemos usar sesearch [1]:
sesearch -d -A -s haproxy_t
-
-d
mostra apenas resultados diretos - se você omitir isso, isso também mostrará todos os objetos deseinfo --type=haproxy_t -x
! -
-A
procura por regras de permissão -
-s haproxy_t
define o tipo de fonte como haproxy_t
Agora obtivemos muitos resultados (106 na minha VM do CentOS 7), porque, por acaso, há muitas permissões granulares diferentes definidas. Neste ponto, você precisa saber algo mais sobre o que está procurando - a classe a que a permissão se aplica, o tipo de destino ou o próprio nome da permissão.
Pesquisa por classe
Vamos primeiro à aula: por isso sabemos que o nosso tipo de fonte é haproxy_t
e pensamos que a nossa turma pode ter algo a ver com a internet, por isso é uma boa aposta que possa ser tcp_socket.
sesearch -d -A -s haproxy_t -c tcp_socket
Isso listará todas as regras de permissão para o tipo de origem haproxy_t que tem alguma coisa a ver com tcp_socket. Isso diminuiu bastante, mas ainda é um palpite de qual desses pode ser o que estamos procurando.
Pesquise por permissões específicas
Em seguida, vamos tentar com permissões - sabemos que precisamos do nosso haproxy para ligar e conectar em portas específicas, certo? por isso, tentamos as permissões name_bind e name_connect.
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 ;
Isso mostra apenas 4 resultados, dos quais apenas 3 podem ser nossos culpados! Esses resultados são, no que diz respeito ao SELinux, as únicas portas que qualquer processo com o contexto de haproxy_t tem permissão para se ligar.
Pesquisar por tipo de segmentação
Este é um truque, porque neste caso estamos realmente procurando pelo tipo de alvo! Mas, por questão de integridade - por exemplo, se quisermos descobrir quais permissões haproxy_t obtém de http_port_t, podemos usar o seguinte:
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 } ;
e isso, é claro, nos dá apenas um resultado e as permissões que se aplicam.
Portas
Agora que conhecemos os objetos de destino e que eles são definições de portas, podemos descobrir exatamente quais portas eles abrangem. Bem, vamos descobrir:
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
E assim, vemos que a porta tcp 5601 não está na lista. Agora, até onde o SELinux se importa, você pode adicionar essa porta a qualquer um desses tipos com o comando semanage port --add --type XXX --proto tcp 5601
, e isso funcionará. Mas como isso serve http, http_port_t parece o tipo mais aplicável.
Espero que isso o desmistifique um pouco.
[1] Disponível no pacote setools-console.