Limite o máximo de conexões por endereço IP e novas conexões por segundo com iptables

37

Temos um servidor Ubuntu 12.04 com httpd na porta 80 e queremos limitar:

  • o número máximo de conexões por endereço IP para httpd a 10
  • o máximo de novas conexões por segundo entre httpd e 150

Como podemos fazer isso com o iptables?

evacristina
fonte

Respostas:

48
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

Isso rejeitará conexões acima de 15 de um IP de origem.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

Nestas 160 novas conexões (realmente pacotes) são permitidas antes que o limite de 150 novas conexões (pacotes) por segundo seja aplicado.

totti
fonte
11
O acima pode ser configurado para funcionar em todas as portas, não apenas na porta 80?
EminezArtus
11
Tem certeza de que é por IP?
LatinSuD
2
Para definir esta regra para todas as portas, basta remover o --dport 80.
Dan Pritts
5
A segunda regra NÃO funciona em "novas conexões". Afeta explicitamente as conexões existentes ("ESTABELECIDAS"). Para fazer novas conexões, você desejaria --state NEW. Você também pode considerar usar -m conntrack --ctstateno lugar de -m state --state. O conntrack é novo e aprimorado versus o estado.
Dan Pritts
2
o comentário acima para adicionar a 2ª regra às NEWconexões - não faça isso - efetivamente transforma sua INPUTcadeia em um padrão accept!!!
Stuart Cardall
8

Você deseja que as seguintes regras no iptables respondam aos dois requisitos da sua pergunta:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP

Como estamos usando -I (conforme a solicitação do OP), precisamos fazê-los na ordem inversa, de modo a 'lê-los' de baixo para cima.

Também sugiro considerar a alteração --NN da máscara de limite de 32 a 24. Isso limitará uma rede Classe C completa (máximo de 256 endereços IP no mesmo intervalo) a 10 conexões. Você também pode usar qualquer outro número sem classe, como 22 ou 30, dependendo de como você acha que seu serviço pode ser usado.

Além disso, dependendo de como você deseja que o cliente se comporte, você pode usar "-j REJECT --reject-with tcp-reset" em vez de "-j DROP" nas duas regras acima, ou mesmo apenas no máximo de 150 conexões. regra.

Se você rejeitar a conexão, o navegador ou software usando a porta 80 mostrará um status "não disponível" imediatamente, mas a opção DROP fará com que o cliente espere e tente novamente algumas vezes antes de relatar o site como não disponível. Costumo me apoiar no DROP, pois ele se comporta mais como uma conexão ruim do que como um servidor offline.

Além disso, se o limite de conexão cair abaixo de 150 (ou 10) enquanto ainda estiver tentando novamente, ele finalmente chegará ao seu servidor.

A opção REJECT, no entanto, causará uma fração a menos de tráfego no site, pois o DROP fará com que ele envie pacotes adicionais enquanto tenta novamente. Provavelmente não é tão relevante.

Se, por outro lado, o tráfego da porta 80 fizer parte de um cluster, o REJECT dirá ao controlador de cluster que está inoperante e para de enviar o tráfego para ele durante o tempo limite de nova tentativa.

A regra RELATED, ESTABLISHED existe sob a suposição de que sua regra padrão é bloquear todo o tráfego (iptables -t filter -P INPUT DROP). Isso apenas aceita outros pacotes pertencentes a conexões aceitas.

Também --syn diz para prestar atenção (ou contar) aos pacotes que configuram uma conexão TCP.

Ian Macintosh
fonte
Obrigado por percorrer as minúcias desses comandos.
txyoji
Posso obter --connlimit-mask para bloquear apenas esse endereço IP específico e não um intervalo inteiro?
analógico
A máscara --connlimit-32 é um limite de endereço único. Ou seja, é como uma máscara de rede / 32. Qualquer coisa menos, como 24, é como uma máscara de rede / 24, ignorando os 8 bits inferiores.
Ian Macintosh
5

Você precisa usar os connlimitmódulos que permitem restringir o número de conexões TCP paralelas a um servidor por endereço IP do cliente (ou bloco de endereços).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Raman_Singh
fonte
Atualizei sua resposta, espero que ainda esteja OK (por que o "--syn" é necessário?). + E sobre o "A conexão máxima por segundo (porta 80, tcp) para 150"? Obrigado!
evachristine
--syn significa que a regra olha apenas para pacotes TCP com o sinalizador syn - o que significa novas conexões. Você poderia fazer aproximadamente o mesmo com -m state --state NEW, mas isso provavelmente é mais rápido.
Dan Pritts