Este artigo é adequado para iniciantes, pois os dados são apresentados do simples ao complexo. Ao iniciar minha carreira como engenheiro de DevOps, esses materiais me faltavam. Vou tentar falar sobre como o Nginx funciona e algumas dicas e truques da experiência prática.
O NGINX é construído em uma arquitetura sem bloqueio e orientada a eventos. Ele tem um processo primário, vários processos de trabalho e dois processos de gerenciamento de cache. Para ver isso, basta executar o comando ps com os switches:
ps -ef --forest | grep nginx
O processo principal é executado como root e executa operações que requerem elevação, como:
configuração de leitura;
portas de abertura;
criação de novos processos.
Os trabalhadores fazem todo o trabalho:
Normalmente, o número de trabalhadores é igual ao número de núcleos da CPU. Isso permite que você use os recursos do sistema da maneira mais eficiente possível.
Worker_processes escutam em dois tipos de soquetes:
Os worker_processes esperam por um evento usando dois tipos de API: epoll ou kqueue . Ao receber um novo evento de cliente no soquete do ouvinte, o worker_process cria uma nova conexão de soquete.
Tendo recebido um evento no soquete de conexão, o worker_process executa esta solicitação. Depois de processar o evento, ele não fica bloqueado, mas entra em modo de espera e, assim, minimiza o número de trocas de contexto de um sistema operacional.
Com a arquitetura acima, atualizar a configuração do NGINX é tão simples quanto enviar um sinal SIGHUP para o processo primário. Com o NGINX configurado adequadamente, cada processo de trabalho é capaz de processar centenas de milhares de conexões ao mesmo tempo.
Depois disso, o worker_processes deixará de aceitar novas conexões, e as conexões atuais, tendo processado o evento, serão fechadas (sem aguardar o keep-alive). Assim que todas as conexões forem fechadas, o worker_process terminará. Isso permite que você atualize a configuração do servidor sem perder conexões, recursos ociosos ou interromper o atendimento ao cliente.
1. Verifique a exatidão da configuração escrita antes de aplicá-la
Depois de alterar ou criar uma configuração, você precisa verificar a sintaxe e a correção da gravação do arquivo de configuração. O Nginx permite que você verifique a correção da gravação da configuração com o seguinte comando:
nginx -t
2. Recarregue o Nginx sem reiniciar o serviço
É uma boa prática aplicar as configurações sem reiniciar o serviço. Isso não encerra as conexões atuais e elimina o período de espera ao carregar o serviço, ou seja, não há tempo de inatividade:
nginx -s reload
ou
/etc/init.d/nginx reload
ou
service nginx reload
3. Desabilite Nginx server_tokens
Por padrão, a diretiva server_tokens no Nginx exibe o número da versão do Nginx. É diretamente visível em todas as páginas de erro geradas automaticamente e em todas as respostas HTTP no cabeçalho do servidor.
Isso pode levar à divulgação de informações - um usuário não autorizado pode descobrir sua versão do Nginx. Ajudaria se você desabilitasse a diretiva server_tokens
no arquivo de configuração do Nginx definindo:
server_tokens off;
4. Desative os protocolos legados SSL/TLS
ssl_protocols TLSv1.2 TLSv1.3;
5. Desative quaisquer métodos HTTP indesejáveis
Desabilite todos os métodos HTTP que não serão usados e não precisam ser implementados no servidor web.
Se você adicionar a seguinte condição ao bloco de localização do arquivo de configuração do host virtual Nginx, o servidor permitirá apenas os métodos GET, HEAD
e POST
e filtrará métodos como DELETE
e TRACE
:
location / { limit_except GET HEAD POST { deny all; } }
Outra abordagem é adicionar a seguinte condição à seção do servidor (ou bloco do servidor). Pode ser considerado mais genérico, mas você deve ter cuidado com as declarações if no contexto de localização:
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; }
6. Configure e configure o acesso Nginx e logs de erro
Os logs de acesso e erro do Nginx são habilitados por padrão e localizados em logs/error.log
e logs/access.log,
respectivamente.
Você pode usar a diretiva error_log no arquivo de configuração do Nginx se quiser alterar o local. Você também pode usar esta diretiva para especificar os logs a serem registrados de acordo com seu nível de gravidade.
Por exemplo, a gravidade crítica fará com que o Nginx registre problemas críticos e todos os problemas com um nível de gravidade mais alto do que os críticos. Para definir o nível de gravidade como crítico, defina a diretiva error_log da seguinte maneira:
error_log logs/error.log crit;
Você pode encontrar uma lista completa dos níveis de gravidade error_log na documentação oficial do Nginx.
Você também pode alterar a diretiva access_log no arquivo de configuração Nginx para especificar um local não padrão para logs de acesso.
Por fim, você pode usar a diretiva log_format para personalizar o formato das mensagens registradas, conforme descrito na documentação do Nginx.
7. Conexões de trabalho do Nginx
Uma configuração crucial que configuramos é o número de processos de trabalho e o número de conexões de trabalho no arquivo de configuração do Nginx /etc/nginx/nginx.conf
.
Ajustaremos gradualmente o fluxo de trabalho e as conexões de trabalho para um valor maior ou menor para lidar com ataques DDoS:
events { worker_connections 20000; }
Essa configuração permite que cada processo de trabalho manipule até 20.000 conexões.
8. Limite de taxa de solicitação
Entre as muitas táticas valiosas para evitar ataques DDoS, uma das mais simples e eficazes é limitar a taxa de tráfego de entrada.
Por exemplo, você pode especificar a taxa na qual o NGINX aceita solicitações de entrada para a taxa média de seu serviço de um endereço IP de cliente específico por um período especificado.
Definimos a diretiva limit_req_zone no arquivo de configuração Nginx para limitar o número de solicitações:
limit_req_zone $binary_remote_addr zone=req_per_ip:1m rate=30r/m; server { location /login { limit_req zone=req_per_ip; } }
Este exemplo cria uma área de armazenamento chamada one que pode armazenar até 16.000 (1m) endereços IP exclusivos e 30r/m significa que apenas 30 solicitações por minuto são permitidas.
Em seguida, usamos a diretiva limit_req para limitar a velocidade das conexões a um local ou arquivo específico, neste caso, faça o login.
9. Limitando o número de conexões
Você pode limitar o número de conexões que podem ser abertas a partir de um único endereço IP de cliente, e aqui estamos definindo as diretivas limit_conn_zone e limit_conn
para restringir o número de conexões por endereço IP:
limit_conn_zone $binary_remote_addr zone=conn_per_ip:1m; server { location / { limit_conn conn_per_ip 10; } }
Este exemplo cria uma zona de armazenamento chamada conn_per_ip
para armazenar solicitações para a chave especificada, neste caso, o endereço IP do cliente, $binary_remote_addr. A diretiva limit_conn
então define dez conexões do endereço IP de cada cliente.
10. Opções de tempo limite
Conexões lentas podem representar uma tentativa de manter as conexões abertas por muito tempo. Como resultado, o servidor não pode aceitar novas conexões:
server { client_body_timeout 5s; client_header_timeout 5s; }
Neste exemplo, a diretiva client_body_timeout
especifica quanto tempo o Nginx espera entre as entradas do corpo do cliente e client_header_timeout
especifica quanto tempo o Nginx espera entre as entradas do cabeçalho do cliente. Ambos são definidos para 5 segundos.
11. Limite o tamanho dos pedidos
Da mesma forma, grandes valores de buffer ou grandes tamanhos de solicitação HTTP facilitam os ataques DDoS. Portanto, limitamos os seguintes valores de buffer no arquivo de configuração Nginx para mitigar ataques DDoS:
client_body_buffer_size 200K; client_header_buffer_size 2k; client_max_body_size 200k; large_client_header_buffers 3 1k;
Onde,
client_body_buffer_size 1k
— (padrão 8k ou 16k) A diretiva especifica o tamanho do buffer do corpo da solicitação do cliente;
client_header_buffer_size 1k
- a diretiva define o tamanho do buffer do cabeçalho para o cabeçalho da solicitação do cliente. Um tamanho de buffer de 1Kb é suficiente para a grande maioria das solicitações.
Aumente este valor se você tiver um cabeçalho personalizado ou um cookie gigante enviado por um cliente (como um cliente wap);
client_max_body_size 1k
- a diretiva define o tamanho máximo permitido do corpo da solicitação do cliente, especificado pela linha Content-Length no cabeçalho da solicitação.
Se o tamanho for maior que o especificado, o cliente receberá um erro "Request Entity Too Large" (413). Aumente esse valor quando estiver fazendo upload de arquivos usando o método POST;
large_client_header_buffers 2 1k
- a diretiva atribui o número e tamanho máximos de buffers para leitura de cabeçalhos grandes de uma solicitação do cliente.
Por padrão, o tamanho de um buffer é igual ao tamanho da página dependendo da plataforma, é 4K ou 8K.
Se a conexão entrar no estado de manutenção de atividade no final da solicitação de trabalho, esses buffers serão liberados.
Por exemplo, 2x1k aceitará um URI de dados de 2 KB. Também ajudará a combater bots ruins e ataques DoS.
12. Lista negra de IP
Se você puder identificar os endereços IP do cliente usados para o ataque, poderá colocá-los na lista negra com a diretiva de negação para que o NGINX e o NGINX Plus não aceitem suas conexões ou solicitações:
location / { deny 111.111.111.4; deny 111.111.111.0/24; }
Neste exemplo, o primeiro Negar bloqueia um endereço IP específico e o segundo Negar bloqueia todo o intervalo de endereços IP.
13. Lista de permissões de IP
Se seu site ou aplicativo só pode ser acessado a partir de um ou mais conjuntos ou intervalos específicos de endereços IP do cliente, você pode usar permitir e negar as diretivas juntas para permitir que apenas esses endereços acessem o site ou aplicativo:
location / { allow 111.111.111.4; deny all; }
Você pode restringir o acesso apenas a endereços em uma rede local específica. Aqui, a diretiva deny all bloqueia todos os endereços IP do cliente que não estão no intervalo especificado pela diretiva allow.
14. Bloqueie o acesso a um arquivo ou local
Você pode usar o Nginx para bloquear completamente o acesso a um arquivo ou local. Por exemplo, se você perceber que o arquivo register.php é alvo de um ataque, você pode bloquear completamente o acesso a este arquivo:
location /register { deny all; return 444; }
Isso descartará todas as solicitações que tentarem acessar esse arquivo. O código 444 fecha a conexão sem resposta.
15. Ative a proteção baseada em sysctl
Ative a proteção baseada em sysctl. Podemos ajustar as variáveis do kernel e do sistema em nosso servidor. Edite o arquivo /etc/sysctl.conf
e defina essas duas linhas como 1 da seguinte forma:
net.ipv4.conf.all.rp_filter = 1 net.ipv4.tcp_syncookies = 1
A primeira configuração habilita a proteção contra falsificação de endereço IP e a segunda configuração habilita a proteção de cookie TCP SYN.
16. Nginx como balanceador de carga
Quando o Nginx é usado como um balanceador de carga, as configurações podem ser definidas para limitar o número de conexões por servidor:
upstream domain { server 111.111.111.4:80 max_conns=100; server 111.111.111.5:80 max_conns=100; queue 20 timeout=10s; }
Aqui, a diretiva max_conns especifica o número de conexões que o Nginx pode abrir para o servidor. A diretiva queue limita o número de solicitações enfileiradas quando todos os servidores desse grupo atingem o limite de conexão.
Por fim, a diretiva de tempo limite especifica por quanto tempo uma solicitação pode ser mantida na fila.
17. Negar certos agentes de usuário
Você pode bloquear facilmente os agentes do usuário, ou seja, rastreadores, bots e spammers que podem estar abusando do seu servidor:
## Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; }
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot|PxBroker) { return 403; }
18. Bloquear spam de referência
O spam de referência é perigoso. Isso pode prejudicar sua classificação de SEO por meio de weblogs (se publicados), pois o campo de referência é vinculado ao site de spam. Com estas linhas, você pode bloquear o acesso a spammers referenciadores:
if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { return 403; }
19. Pare de hotlinking de imagens
Um hotlink de imagem ou HTML significa que alguém vincula seu site a uma de suas imagens, mas a exibe em seu site.
Você acabará pagando pela largura de banda e fazendo com que o conteúdo pareça parte de um site. Isso geralmente é feito em fóruns e blogs. Eu recomendo fortemente que você bloqueie e interrompa o hotlinking de imagens no mesmo nível do seu servidor:
location /images/ { valid_referers none blocked www.domain.com domain.com; if ($invalid_referer) { return 403; } }
20. Limita o número de conexões por endereço IP no nível do firewall
O servidor web deve monitorar as conexões e limitar o número de conexões por segundo. Isso serve 101. Ambos pf e iptables podem bloquear usuários finais antes de acessar seu servidor Nginx.
Linux Iptables: limitando conexões Nginx por segundo.
No exemplo a seguir, as conexões de entrada serão descartadas se o IP fizer mais de 15 tentativas de conexão na porta 80 em 60 segundos:
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set && \ /sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP && \ service iptables save
21. Desative o sniffing de tipo de conteúdo em alguns navegadores
Se uma resposta especificar um tipo de conteúdo incorreto, os navegadores poderão processar a resposta de maneiras inesperadas.
Se o tipo de conteúdo for determinado como um formato baseado em texto renderizável, o navegador geralmente tentará interpretar a resposta como estando nesse formato, independentemente do conteúdo real da resposta.
Além disso, alguns outros tipos de conteúdo especificados podem às vezes ser interpretados como HTML devido a peculiaridades em navegadores específicos. Isso pode levar a conteúdo “seguro”, como imagens sendo renderizadas como HTML, permitindo ataques de script entre sites em determinadas condições. Adicione o seguinte à sua configuração:
add_header X-Content-Type-Options nosniff;
22. Ativar filtro de script entre sites (XSS)
Adicione a seguinte linha ao seu arquivo de configuração para habilitar o cabeçalho X-XSS-Protection em seu servidor web Nginx. Quando terminar, salve suas alterações e recarregue o Nginx:
add_header X-XSS-Protection "1; mode=block";
23. Configurar suporte HTTP/2
HTTP/2 é o sucessor do protocolo de rede HTTP 1.x. O HTTP/2 é amplamente usado para reduzir a latência, minimizar a sobrecarga do protocolo, adicionar suporte para priorização de solicitações e acelerar o carregamento de aplicativos da web.
Portanto, é vital manter-se atualizado com técnicas e estratégias de otimização de desempenho. O foco principal do HTTP/2 é reduzir o tempo de carregamento geral de uma página da Web, o que otimiza o desempenho.
Ele também foca no uso de recursos de rede e servidor, bem como no aumento da segurança, já que a criptografia SSL/TLS é obrigatória ao usar HTTP/2.
Como pré-requisito, certifique-se de que a versão do Nginx seja 1.9.5 ou superior, caso contrário, você terá que adicioná-la manualmente e o servidor deve habilitar SSL/TLS. Seu bloco de servidor HTTPS agora deve ter esta aparência:
server { listen 443 ssl http2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; }
24. Adicionar política de segurança de conteúdo (CSP)
O CSP é uma camada adicional de segurança que ajuda a detectar e mitigar certos tipos de ataques, incluindo cross-site scripting (XSS) e ataques de injeção de dados. Esses ataques são usados para roubo de dados, corrupção de sites e distribuição de malware:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
25. Monitorando o Nginx
O estado do seu servidor deve ser constantemente monitorado. Você pode observar o que o servidor retorna enviando solicitações periodicamente a ele, por exemplo, por meio de serviços pagos de terceiros. Ou você pode ajustar tudo, e há muitas maneiras de fazer isso - mais sobre isso no blog do Nginx .
Em vez de conclusão
É essencial ser flexível e desenvolver uma configuração para cada caso separadamente.