Editor – A postagem do blog intitulada “NGINX: Alterações no SELinux ao atualizar para RHEL 6.6/CentOS 6.6” redireciona para aqui. Este artigo fornece informações atualizadas e generalizadas.
As configurações padrão do Security-Enhanced Linux (SELinux) no Red Hat Enterprise Linux (RHEL) moderno e distribuições relacionadas podem ser muito rígidas, focando mais na segurança do que na conveniência. Embora as configurações padrão não limitem o funcionamento do NGINX Open Source e do NGINX Plus em suas configurações padrão, outros recursos que você pode configurar podem ser bloqueados, a menos que você os permita explicitamente no SELinux. Este artigo descreve os possíveis problemas e as maneiras recomendadas para resolvê-los.
[Editor – Este artigo se aplica tanto ao NGINX Open Source quanto ao NGINX Plus. Para facilitar a leitura, o termo “NGINX” é usado em todo o texto.
CentOS é uma distribuição relacionada originalmente derivada do RHEL e é suportada pelo NGINX e NGINX Plus. Além disso, o NGINX Plus oferece suporte às distribuições relacionadas Amazon Linux e Oracle Linux. As configurações padrão do SELinux podem ser diferentes do CentOS e do RHEL; consulte a documentação do fornecedor.]
Visão geral do SELinux
O SELinux é habilitado por padrão em servidores RHEL e CentOS modernos. Cada objeto do sistema operacional (processo, descritor de arquivo, arquivo, etc.) é rotulado com um contexto SELinux que define as permissões e operações que o objeto pode executar. No RHEL 6.6/CentOS 6.6 e posteriores, o NGINX é rotulado com o contexto httpd_t
:
# ps auZ | grep nginx unconfined_u:system_r: httpd_t :s0 3234 ? Ss 0:00 nginx: processo mestre /usr/sbin/nginx \ -c /etc/nginx/nginx.conf unconfined_u:system_r: httpd_t :s0 3236 ? Ss 0:00 nginx: processo de trabalho
O contexto httpd_t
permite que o NGINX escute em portas comuns do servidor web, acesse arquivos de configuração em /etc/nginx e acesse conteúdo no local docroot padrão ( /usr/share/nginx ). Ele não permite muitas outras operações, como proxy para locais upstream ou comunicação com outros processos por meio de soquetes.
Para desabilitar temporariamente as restrições do SELinux para o contexto httpd_t
, para que o NGINX possa executar todas as mesmas operações que em sistemas operacionais não SELinux, atribua o contexto httpd_t
ao domínio permissivo . Veja a próxima seção para mais detalhes.
# semanage permissivo -a httpd_t
O SELinux pode ser executado nos modos de imposição , permissivo ou desabilitado (também chamados de domínios ). Antes de fazer uma alteração na configuração do NGINX que possa violar as permissões padrão (estritas), você pode alterar o SELinux do modo forçado para o modo permissivo , no seu ambiente de teste (se disponível) ou no ambiente de produção. No modo permissivo , o SELinux permite todas as operações, mas registra operações que violariam a política de segurança no modo de imposição .
Para adicionar httpd_t
à lista de domínios permissivos , execute este comando:
# semanage permissivo -a httpd_t
Para excluir httpd_t
da lista de domínios permissivos , execute:
# semanage permissivo -d httpd_t
Para definir o modo globalmente como permissivo , execute:
# setenforce 0
Para definir o modo globalmente como forçado , execute:
# setenforce 1
Resolvendo exceções de segurança do SELinux
No modo permissivo , as exceções de segurança são registradas no log de auditoria padrão do Linux, /var/log/audit/audit.log . Se você encontrar um problema que ocorre apenas quando o NGINX está sendo executado no modo de imposição , revise as exceções registradas no modo permissivo e atualize a política de segurança para permiti-las.
Por padrão, a configuração do SELinux não permite que o NGINX se conecte a servidores HTTP, FastCGI ou outros servidores remotos, conforme indicado por uma mensagem de log de auditoria como a seguinte:
tipo=AVC msg=audit(1415714880.156:29): avc: negado { name_connect } para pid=1349 \
comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
tipo=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 sucesso=não \
saída=-115 a0=b \a1=16125f8 a2=10 a3=7fffc2bab440 itens=0 ppid=1347 pid=1349 \
auid=1000 uid=497 gid=496 euid=497 suid=497 fsuid=497 egid=496 sgid=496 fsgid=496 \
tty=(nenhum) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 key=(null)
O comando audit2why
interpreta o código da mensagem ( 1415714880.156:29
):
# grep 1415714880.156:29 /var/log/audit/audit.log | audit2why type=AVC msg=audit(1415714880.156:29): avc: { name_connect } negado para pid=1349 \ comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \ tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket Foi causado por:
Um dos seguintes valores booleanos foi definido incorretamente.
Descrição:
Permitir que o httpd atue como um relé Permitir acesso executando: # setsebool -P httpd_can_network_relay 1 Descrição:
Permitir que scripts e módulos HTTPD se conectem à rede usando TCP.
Permitir acesso executando: # setsebool -P httpd_can_network_connect 1
A saída de audit2why
indica que você pode permitir que o NGINX faça conexões proxy habilitando uma ou ambas as opções booleanas httpd_can_network_relay
e httpd_can_network_connect
. Você pode habilitá-los temporariamente ou permanentemente, este último adicionando o sinalizador -P
conforme mostrado na saída.
O comando sesearch
fornece mais informações sobre as opções booleanas e está disponível se você instalar o pacote setools ( yum
install
setools
). Aqui mostramos a saída para as opções httpd_can_network_relay
e httpd_can_network_connect
.
httpd_can_network_relay
Aqui está a saída do comando sesearch
sobre a opção httpd_can_network_relay
:
# sesearch -A -s httpd_t -b httpd_can_network_relay Foram encontradas 10 regras av semânticas: permitir httpd_t gopher_port_t : tcp_socket name_connect ; permitir httpd_t http_cache_client_packet_t : pacote { enviar recebimento } ; permitir httpd_t ftp_port_t : tcp_socket name_connect ; permitir httpd_t ftp_client_packet_t : pacote { enviar recebimento } ; permitir httpd_t http_client_packet_t : pacote { enviar recebimento } ; permitir httpd_t squid_port_t : tcp_socket name_connect ; permitir httpd_t http_cache_port_t : tcp_socket name_connect ; permitir httpd_t http_port_t : tcp_socket name_connect ; permitir httpd_t gopher_client_packet_t: pacote {enviar recebimento}; permitir httpd_t memcache_port_t: tcp_socket name_connect;
Esta saída indica que httpd_can_network_relay
permite que processos rotulados com o contexto httpd_t
(como NGINX) se conectem a portas de vários tipos, incluindo o tipo http_port_t
:
# semanage porta -l | grep http_port_t http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
Para adicionar mais portas (aqui,8082
) para o conjunto de portas permitidas para http_port_t
, execute:
# semanage porta -a -t http_port_t -p tcp 8082
Se a saída deste comando disser que uma porta já
está definida
, como no exemplo a seguir, isso significa que a porta está incluída em outro conjunto. Não o reatribua para http_port_t
, porque outros serviços podem ser afetados negativamente.
# semanage porta -a -t http_port_t -p tcp 8080 /usr/sbin/semanage: Porta tcp/8080 já definida # semanage port -l | grep 8080 http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010
httpd_can_network_connect
Aqui está a saída do comando sesearch
sobre a opção httpd_can_network_connect
:
# sesearch -A -s httpd_t -b httpd_can_network_connect Encontradas 1 regras av semânticas: permitir httpd_t port_type : tcp_socket name_connect ;
Esta saída indica que httpd_can_network_connect
permite que processos rotulados com o contexto httpd_t
(como NGINX) se conectem a todos os tipos de soquete TCP que tenham o atributo port_type
. Para listá-los, execute:
# seinfo -aport_type -x
Por padrão, a configuração do SELinux não permite que o NGINX acesse arquivos fora de locais autorizados conhecidos, conforme indicado por uma mensagem de log de auditoria como a seguinte:
tipo=AVC msg=audit(1415715270.766:31): avc: negado { getattr } para pid=1380 \
comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \
scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=unconfined_u:object_r:default_t:s0 tclass=file
O comando audit2why
interpreta o código da mensagem ( 1415715270.766:31
):
# grep 1415715270.766:31 /var/log/audit/audit.log | audit2why type=AVC msg=audit(1415715270.766:31): avc: negado { getattr } para pid=1380 \ comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \ scontext=unconfined_u:system_r:httpd_t:s0 \ tcontext=unconfined_u:object_r:default_t:s0 tclass=file Foi causado por:
Regra de permissão de aplicação de tipo (TE) ausente.
Você pode usar audit2allow para gerar um módulo carregável para permitir esse acesso.
Quando o acesso ao arquivo é proibido, você tem duas opções.
Modifique o rótulo do arquivo para que o NGINX (como um processo rotulado com o contexto httpd_t
) possa acessar o arquivo:
# chcon -v --type=httpd_sys_content_t /www/t.txt
Por padrão, essa modificação é excluída quando o sistema de arquivos é renomeado. Para tornar a alteração permanente, execute:
# semanage fcontext -a -t httpd_sys_content_t /www/t.txt # restorecon -v /www/t.txt
Para modificar rótulos de arquivos para grupos de arquivos, execute:
# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?' # restorecon -Rv /www
httpd_t
Estenda a política para httpd_t
para permitir acesso a locais de arquivo adicionais:
# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te # cat nginx.te módulo nginx 1.0; require { tipo httpd_t; tipo default_t; tipo http_cache_port_t; classe tcp_socket nome_connect; classe arquivo { ler getattr aberto }; } #============= httpd_t =============== permitir httpd_t default_t:arquivo { ler getattr aberto }; #!!!! Este avc pode ser permitido usando um destes booleanos: # httpd_can_network_relay, httpd_can_network_connect allow httpd_t http_cache_port_t:tcp_socket name_connect;
Para gerar uma política compilada, inclua a opção -M
:
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
Para carregar a política, execute semodule
-i
e verifique o sucesso com semodule
-l
:
# semodule -i nginx.pp # semodule -l | grep nginx nginx 1.0
Essa alteração persiste após reinicializações.
Por padrão, a configuração do SELinux não permite que o NGINX escute ( bind()
) portas TCP ou UDP diferentes das padrão que estão na lista de permissões no tipo http_port_t
:
# semanage porta -l | grep http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443
Se você tentar configurar o NGINX para escutar em uma porta não permitida (com a diretiva listen
no contexto http
, stream
ou mail
na configuração do NGINX), você receberá um erro ao verificar ( nginx
-t
) ou recarregar a configuração do NGINX, conforme indicado por esta entrada de log do NGINX:
AAAA / MM / DD hh : mm : ss [emerg] 46123#0: bind() para 0.0.0.0:8001 falhou (13: Permissão negada)
Você pode usar semanage
para adicionar a porta desejada (aqui, 8001) ao tipo http_port_t
:
# semanage porta -a -t http_port_t -p tcp 8001
Recarregue o NGINX com a nova configuração.
# nginx -s recarregar
Muitos arquivos estão abertos
ErroQuando o limite do número de arquivos abertos ( RLIMIT_NOFILE
) é excedido, a seguinte mensagem aparece no log de erros:
Muitos arquivos estão abertos
Na maioria dos casos, o processo de trabalho do NGINX relata esse erro, mas você não pode usar a diretiva NGINX worker_rlimit_nofile
para aumentar o limite porque o SELinux não permite a chamada de sistema setrlimit()
, conforme relatado nas seguintes mensagens nos logs de erro e auditoria.
Em /var/log/nginx/error.log para CentOS/RHEL 7.4+:
AAAA / MM / DD hh : mm : ss [alerta] 12066#0: setrlimit(RLIMIT_NOFILE, 2342) falhou (13: Permissão negada)
Em /var/log/nginx/error.log para CentOS/RHEL 8.0+:
AAAA / MM / DD hh : mm : ss [alerta] 3327#0: setrlimit(RLIMIT_NOFILE, 65535) falhou (1: Operação não permitida)
Em /var/log/audit/audit.log para CentOS/RHEL 7.4+ e /var/log/messages para CentOS/RHEL 8.0+:
tipo=AVC msg=audit(1437731200.211:366): avc: negado { setrlimit } para pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:system_r:httpd_t:s0 tclass=process
Para aumentar o limite, execute este comando como usuário root
:
$ setsebool -P httpd_setrlimit 1
Se o processo mestre do NGINX relatar o erro, você precisa atualizar o arquivo de unidade
systemd
para o NGINX. Isso define o limite do descritor de arquivo para os processos mestre e de trabalho.
Crie um diretório para a configuração nginx.service
:
$ mkdir /etc/systemd/system/nginx.service.d
Adicione as seguintes linhas em /etc/systemd/system/nginx.service.d/nofile_limit.conf :
[Serviço]LimitNOFILE=65535
Recarregue a configuração do daemon systemd e reinicie o NGINX:
$ systemctl daemon-reload $ systemctl reiniciar nginx.service
Recursos adicionais
O SELinux é um recurso complexo e poderoso para gerenciar permissões do sistema operacional. Informações adicionais estão disponíveis nos seguintes documentos.
"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."