“Possível inundação SYN” no log, apesar do baixo número de conexões SYN_RECV

30

Recentemente, tivemos um servidor apache que estava respondendo muito lentamente devido à inundação de SYN. A solução alternativa para isso foi ativar o tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf).

Eu postei uma pergunta sobre isso aqui, se você quiser mais informações.

Depois de ativar os sincookies, começamos a ver a seguinte mensagem em / var / log / messages aproximadamente a cada 60 segundos:

[84440.731929] possible SYN flooding on port 80. Sending cookies.

Vinko Vrsalovic me informou que isso significa que o backlog de sincronização está ficando cheio, então aumentei tcp_max_syn_backlog para 4096. Em algum momento, também reduzi tcp_synack_retries para 3 (abaixo do padrão de 5) ao emitir sysctl -w net.ipv4.tcp_synack_retries=3. Depois disso, a frequência pareceu diminuir, com o intervalo das mensagens variando entre aproximadamente 60 e 180 segundos.

Em seguida, emiti sysctl -w net.ipv4.tcp_max_syn_backlog=65536, mas ainda estou recebendo a mensagem no log.

Ao longo de tudo isso, observei o número de conexões no estado SYN_RECV (executando watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'), e ele nunca ultrapassa os 240, muito muito menor que o tamanho da lista de pendências. No entanto, eu tenho um servidor Red Hat que fica em torno de 512 (o limite neste servidor é o padrão de 1024).

Existem outras configurações de TCP que limitariam o tamanho da lista de pendências ou estou latindo na árvore errada? O número de conexões SYN_RECV deve estar netstat -tunacorrelacionado com o tamanho da lista de pendências?


Atualizar

O melhor que posso dizer é que estou lidando com conexões legítimas aqui, netstat -tuna|wc -lpairando em torno de 5000. Pesquisei isso hoje e encontrei esta postagem de um funcionário do last.fm, que foi bastante útil.

Também descobri que o tcp_max_syn_backlog não tem efeito quando os sincookies estão ativados (conforme este link )

Assim, na próxima etapa, defino o seguinte no sysctl.conf:

net.ipv4.tcp_syn_retries = 3
        # default=5
net.ipv4.tcp_synack_retries = 3
        # default=5
net.ipv4.tcp_max_syn_backlog = 65536
        # default=1024
net.core.wmem_max = 8388608
        # default=124928
net.core.rmem_max = 8388608
        # default=131071
net.core.somaxconn = 512
        # default = 128
net.core.optmem_max = 81920
        # default = 20480

Em seguida, configurei meu teste de tempo de resposta, executei sysctl -pe desativei as sincookies por sysctl -w net.ipv4.tcp_syncookies=0.

Após fazer isso, o número de conexões no estado SYN_RECV ainda permanecia em torno de 220-250, mas as conexões estavam começando a atrasar novamente. Depois que notei esses atrasos, reativei as sincookies e os atrasos pararam.

Acredito que o que eu estava vendo ainda era uma melhoria em relação ao estado inicial, no entanto, alguns pedidos ainda estavam atrasados, o que é muito pior do que ter sincookies ativadas. Parece que estou preso a eles ativados até conseguirmos mais servidores online para lidar com a carga. Mesmo assim, não tenho certeza se vejo um motivo válido para desativá-los novamente, pois eles são enviados (aparentemente) apenas quando os buffers do servidor ficam cheios.

Mas o backlog syn não parece estar cheio com apenas ~ 250 conexões no estado SYN_RECV! É possível que a mensagem de inundação do SYN seja um arenque vermelho e algo diferente do syn_backlog que está sendo preenchido?

Se alguém tiver outras opções de ajuste, ainda não tentei, ficaria feliz em experimentá-las, mas estou começando a me perguntar se a configuração syn_backlog não está sendo aplicada corretamente por algum motivo.

Alex Forbes
fonte

Respostas:

27

Então, essa é uma pergunta interessante.

Inicialmente, fiquei surpreso ao ver alguma conexão no estado SYN_RECV com os cookies SYN ativados. A beleza dos cookies SYN é que você pode participar sem estado no handshake de 3 vias do TCP como servidor usando criptografia, portanto, espero que o servidor não represente conexões semiabertas, porque esse seria o mesmo estado que isn está sendo mantido.

De fato, uma rápida olhada na fonte (tcp_ipv4.c) mostra informações interessantes sobre como o kernel implementa cookies SYN. Essencialmente, apesar de ativá-los, o kernel se comporta como faria normalmente até que sua fila de conexões pendentes esteja cheia. Isso explica sua lista existente de conexões no estado SYN_RECV.

Somente quando a fila de conexões pendentes está cheia, e outro pacote SYN (tentativa de conexão) é recebido, e faz mais de um minuto desde a última mensagem de aviso, o kernel envia a mensagem de aviso que você viu ("enviando cookies" ) Os cookies SYN são enviados mesmo quando a mensagem de aviso não é; a mensagem de aviso é apenas para informar que o problema não foi resolvido.

Em outras palavras, se você desativar os cookies SYN, a mensagem desaparecerá. Isso só funcionará para você se você não estiver mais sendo inundado pelo SYN.

Para abordar algumas das outras coisas que você fez:

  • net.ipv4.tcp_synack_retries:
    • Aumentar isso não terá nenhum efeito positivo para as conexões de entrada falsificadas, nem para as que recebem um cookie SYN em vez do estado do servidor (nenhuma tentativa para elas também).
    • Para conexões falsas de entrada, aumentar isso aumenta o número de pacotes enviados para um endereço falso e, possivelmente, a quantidade de tempo que esse endereço falsificado permanece na sua tabela de conexões (isso pode ser um efeito negativo significativo).
    • Sob carga / número normal de conexões recebidas, quanto maior for, maior a probabilidade de você concluir com rapidez / êxito as conexões através de links que descartam pacotes. Há retornos decrescentes para aumentar isso.
  • net.ipv4.tcp_syn_retries: Alterar isso não pode afetar as conexões de entrada (afeta apenas as conexões de saída)

As outras variáveis ​​mencionadas ainda não foram pesquisadas, mas suspeito que as respostas para sua pergunta estejam bem aqui.

Se você não está recebendo SYN e a máquina responde a conexões não HTTP (por exemplo, SSH), acho que provavelmente existe um problema de rede, e você deve ter um engenheiro de rede para ajudá-lo a analisar. Se a máquina geralmente não responde, mesmo quando você não está sendo inundado por SYN, isso soa como um sério problema de carga se afetar a criação de conexões TCP (nível e recursos bastante baixos e pouco intensivos)

Slartibartfast
fonte
Obrigado - esta é uma resposta interessante e informativa. Certamente, responde à minha pergunta sobre o relacionamento entre as conexões no estado SYN_RECV e o envio de cookies. A máquina respondeu a não HTTP, incluindo SSH e HTTPS, que recebe muito menos tráfego que HTTP. Assim, decidimos que reduzir o tráfego é o caminho a percorrer.
Alex Forbes
No que diz respeito a obter um engenheiro de rede para dar uma olhada - boa sugestão, mas estamos migrando para fora deste centro de dados, por isso provavelmente não vale a pena quando estamos colocando alguns servidores novos online em outro lugar. Eu acho que você pode estar certo sobre se tratar de um problema de rede - talvez um problema com o balanceador de carga ou o firewall. Mais uma vez obrigado pelas suas ideias!
Alex Forbes
13

Eu enfrentei exatamente o mesmo problema em uma nova instalação do Ubuntu Oneiric 11.10 executando um servidor da web (apache2) com um site carregado. No Ubuntu Oneiric 11.10, as sincookies foram ativadas por padrão.

Eu tinha as mesmas mensagens do kernel informando um possível ataque de inundação SYN na porta do servidor da web:

kernel: [739408.882650] TCP: possível inundação de SYN na porta 80. Enviando cookies.

Ao mesmo tempo, eu tinha certeza de que não havia nenhum ataque acontecendo. Recebi essas mensagens retornando no intervalo de 5 minutos. Isso parecia uma espiada na carga, porque um invasor mantinha a carga alta o tempo todo, enquanto tentava fazer o servidor parar de responder às solicitações.

Ajustar o net.ipv4.tcp_max_syn_backlogparâmetro não levou a nenhuma melhoria - as mensagens continuaram na mesma taxa. o fato de o número de conexões SYN_RECV sempre ter sido realmente muito baixo (no meu caso abaixo de 250) foi um indicador de que deve haver algum outro parâmetro, responsável por esta mensagem.

Encontrei esta mensagem de erro https://bugzilla.redhat.com/show_bug.cgi?id=734991 no site da red hat informando que a mensagem do kernel pode ser resultado de um bug (ou configuração incorreta) no lado do aplicativo . Obviamente, a mensagem de log é muito enganadora! Como esse não é o parâmetro do kernel responsável nesse caso, mas o parâmetro do seu aplicativo, sendo passado para o kernel.

Portanto, também devemos dar uma olhada nos parâmetros de configuração do nosso aplicativo de servidor da web. Pegue os documentos do apache e acesse http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog

O valor padrão do ListenBacklogparâmetro é 511. (Isso corresponde ao número de conexões que você observou no seu servidor red hat. Seu outro servidor pode ter um número menor configurado).

O Apache possui um próprio parâmetro de configuração para a fila de pendências para conexões de entrada. se você tiver muitas conexões de entrada e, a qualquer momento (de maneira aleatória), elas chegarem juntas quase ao mesmo tempo, de modo que o servidor da Web não possa atendê-las com rapidez suficiente e de maneira adequada, seu backlog será estar cheio com 511 conexões e o kernel disparará a mensagem acima informando um possível ataque de inundação SYN.

Para resolver isso, adiciono a seguinte linha a /etc/apache2/ports.confou um dos outros arquivos .conf, que serão carregados pelo apache ( /etc/apache2/apache2.conftambém deve estar ok):

ListenBackLog 5000

você também deve definir o net.ipv4.tcp_max_syn_backlogvalor razoável. no meu entendimento, o máximo do kernel limitará o valor que você poderá configurar na configuração do apache. então corra:

sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000

Depois de ajustar a configuração, não se esqueça de reiniciar o seu apache:

sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )

No meu caso, essa alteração na configuração interrompeu imediatamente os avisos do kernel. Consigo reproduzir as mensagens definindo um valor baixo de ListenBackLog na configuração do apache.

Jeff
fonte
2
Ótima resposta. Supondo que o que você diz está correto, eu marcaria isso como a resposta aceita, mas na verdade não posso testá-lo - reduzir a carga resolveu o problema e tenho uma política de não mexer nos servidores de produção sem uma boa causa :)
Alex Forbes
Posso confirmar que isso funciona essencialmente, é um recurso anti-DDOS do kernel, mas quando você recebe, digamos, muito tráfego na Web, ele acaba bloqueando seus usuários legítimos!
Areeb Soo Yasir
5

Após alguns testes com o kernel 3.4.9, o número de conexões SYN_RECV no netstat depende de

  • /proc/sys/net/core/somaxconn arredondado para a próxima potência de 2 (por exemplo, 128 -> 256)
  • 75% de /proc/sys/net/ipv4/tcp_max_syn_backlogse /proc/sys/net/ipv4/tcp_syncookiesestiver definido como 0ou 100% se /proc/sys/net/ipv4/tcp_syncookiesestiver definido como1
  • ListenBackLog na configuração do apache arredondada para a próxima potência de 2 (por exemplo, 128 -> 256)

o mínimo de cada um desses parâmetros é usado. Após alterar o somaxconn ou o ListenBackLog, o apache deve ser reiniciado.

E depois de aumentar o tcp_max_syn_backlog, o apache também deve ser reiniciado.

Sem tcp_syncookies, o apache está bloqueando, por que, neste caso, apenas 75% de tcp_max_syn_backlog é o limite é estranho. e aumentar esse parâmetro aumenta as conexões SYN_RECV para 100% do valor antigo sem reiniciar o apache.

usoft
fonte
E também a chamada /bin/echo m >/proc/sysrq-triggergeralmente leva a uma possível inundação de SYN na porta 80. Enviando mensagem de cookies .
usoft 11/11/12