It seems ridiculous that you can't set up a policy that allows nginx to write to a socket without first having an attempt denied and then running a tool that enables things that were denied.
Bem, não, o SELinux é o Controle de Acesso Obrigatório, as coisas são negadas por padrão e você tem que permitir explicitamente alguma coisa. Se os autores da política não consideraram uma pilha particular (franken) ou os autores de um daemon não a tornaram política consciente e escrita do SELinux, então você está por conta própria. Você tem que analisar o que seus serviços estão fazendo e como eles estão interagindo com o SELinux e criar sua própria política para permitir isso. Existem ferramentas disponíveis para ajudá-lo audit2why , audit2allow etc.
... Is this the only way?
Não, mas depende do que você está tentando fazer e de como você está tentando fazer o que a solução é. Por exemplo, você pode querer ligar o nginx (httpd_t) à porta 8010 (unreserved_port_t). Quando você inicia o nginx ele falha
Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8010 failed (13: Permission denied)
e você (eventualmente) procurar no log de auditoria e encontrar
type=AVC msg=audit(1457904756.503:41673): avc: denied { name_bind } for
pid=30483 comm="nginx" src=8010 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
Você pode executar isso por meio do audit2alllow e ingenuamente aceitar suas descobertas
allow httpd_t port_t:tcp_socket name_bind;
, que permite que o httpd_t se conecte a qualquer porta tcp. Isso pode não ser o que você quer.
Você pode usar sesearch para investigar a política e ver que tipos de porta httpd_t podem nomear_bind para
sesearch --allow -s httpd_t | grep name_bind
...
allow httpd_t http_port_t : tcp_socket name_bind ;
allow httpd_t http_port_t : udp_socket name_bind ;
...
Entre outros tipos, o http_t pode se vincular a http_port_t. Agora você pode usar semanage para cavar um pouco mais.
semanage port -l | grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
...
A porta 8010 não está listada. Como queremos que o nginx se ligue à porta 8010, não é irracional adicioná-lo à lista http_port_t
semanage port -a -t http_port_t -p tcp 8010
Agora o nginx terá permissão para nomear_bind para a porta 8010 nd e não para todas as portas tcp como acima.
How do you know exactly what is being enabled?
As alterações na política são relativamente fáceis de ler, executando suas mensagens acima por meio de auditoria2tudo recebemos
allow httpd_t httpd_sys_content_t:sock_file write;
allow httpd_t initrc_t:unix_stream_socket connectto;
, que parecem bastante auto-explicativos.
O primeiro deles refere-se ao arquivo com o inum 76151. Você pode usar find para obter seu nome (find / -inum 76151) e depois usar semanage fcontext -a -t ...
para alterar a política e restorecon para corrigir o contexto.
O segundo relaciona-se com /run/gunicorn/socket
, que novamente tem o contexto errado. Usando sesearch, podemos ver que http_t pode se conectar a unix_stream_sockets do tipo (entre outros) http_t. Então podemos mudar o contexto de acordo, por exemplo
semanage fcontext -a -t httpd_t "/run/gunicorn(/.*)?"
restorecon -r /run
Isso define o contexto de / run / gunicorn e a árvore | arquivos abaixo dele para httpd_t.
How is this supposed to work if your setting up machines under automation?
Você precisa analisar o sistema e fazer as alterações apropriadas no teste. Você então usa suas ferramentas de automação para implantar as mudanças, o fantoche e o ansible têm suporte para isso.
Claro que você pode fazer tudo em produção com o SElinux definido como permissivo. Colete todas as mensagens, analise-as e decida-as e implante-as.
Há muito mais para saber sobre o SELinux, mas esse é o limite de minhas habilidades, Michael Hampton é melhor e Mathew Ife é muito melhor de novo, eles podem ter mais a acrescentar.