Alterando as regras do PF em tempo real para mitigar o dano do DDoS (OpenBSD 6.4)

1

Esta é uma questão de duas partes, na verdade. Tenha em mente que eu sou um desenvolvedor e não um administrador de sistema, mas sendo o único funcionário da empresa, eu uso TODOS os chapéus.

Implantei meu servidor com dois firewalls em execução no CARP para balanceamento de carga / redundância, além de cerca de 40 computadores para banco de dados e outras necessidades de aplicativos de back-end. Como início, quero economizar dinheiro mitigando os danos de um ataque DDoS sem pagar meu ISP por uma empresa dedicada à Internet além da proteção contra DDoS. Eu sei que você não pode proteger totalmente contra DDoS. Eu só quero mitigar os danos até que meu aplicativo comece a ganhar dinheiro e eu possa deixar o ISP lidar com as dores de cabeça.

Nesse espírito, fiquei me perguntando se alguém já implementou uma solução de onde um script (talvez através do cron) mudaria as regras do PF com base no uso atual. Por exemplo, se houver muitas conexões semiabertas de milhões de endereços IP, eu gostaria de dizer ao PF para entrar no modo SYN-Cookies e, em seguida, quando o ataque terminar (ou algum tempo depois) para voltar ao normal. / p>

Não consigo usar o Cloudfare porque estou executando um back-end para um aplicativo e 99% do conteúdo não é estático. Eu poderia fazer cloudfare para o site do aplicativo, mas é sobre isso.

Para reiterar, o dinheiro é uma questão. Atualmente, estou usando o FIOS Business e a Verizon não fornecerá proteção contra DDoS nesse tipo de linha.

Por último, alguém experimentou problemas drásticos depois de ativar o SYN-COOKIES / SYN-PROXYING? Me dê uma história real. Por favor.

PS Eu não quero começar um debate sobre SYN-PROXYING vs SYN-COOKIES!

    
por Miguel 18.11.2018 / 16:19

1 resposta

0

Como ninguém respondeu à minha pergunta, esta é a configuração do pf que acabei. Especificamente, olhe a linha para definir cookies depois que a tabela estiver preenchida com 15% de conexões TCP abertas. Os cookies SYN fornecem um ótimo retorno para seus investimentos quando se trata de evitar muitas conexões semiabertas. Isto não é final, no entanto. Outra coisa que você pode fazer no seu próprio ambiente é limitar a quantidade de icmp na interface externa, por exemplo, 1000 / segundo. Isso é algo que eu ainda tenho que jogar. Apenas não o limite dentro da sua rede, pois isso pode ter efeitos devastadores.

a tabela bogons e as tabelas USA são atualizadas com freqüência. A cada 4 e 24 horas, respectivamente. ESTA É uma obrigação, pois há muitos endereços IP, especialmente o ipv6, que não estão em uso hoje. Então, por que se incomodar em manuseá-los? além disso, não há necessidade de ninguém de fora dos EUA acessar o SSH.

Há também algumas tabelas de tentativas de força bruta que meus aplicativos atualizam de fora e o ssh é atualizado dentro de pf. Apenas no caso de alguém tentar tentar muitas conexões de uma só vez, eles estão obviamente tentando algo obscuro.

Esta não foi minha configuração final, pois fiz o balanceamento de carga dos meus servidores da Web e outras coisas, mas não queria postar muitas informações desnecessárias.

última nota, sempre tente executar carpa para failover / redundância / balanceamento de carga !!

# Macros
udp_services = "{ domain, ntp }"
tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s }"
carpdevs = "carp0"
ext_if = "em0"
int_if = "{ em1, em2, em3, em4, em5 }"
localnet = "{ em1:network, em2:network, em3:network, em4:network, em5:network}"

table <USA_IP_ADDRESSES> persist file "/etc/usa_all_ip.zone"
table <dhcpd_leased_ips> persist
table <dhcpd_abandoned_ips> persist
table <dhcpd_changed_ips> persist
table <bruteforce> persist
table <bogons> persist file "/etc/bogons" # see cron jobs for when this file gets updated (daily) and from where
table <lan> const { 192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24, 192.168.4.0/24, 192.168.5.0 }
table <webservers> persist { 192.168.4.10, 192.168.4.20 }
table <websiteoverload> persist

table <appoverload> persist
table <mysmateservers> persist

# Global settings
set debug warning
set limit { states 10000000, table-entries 1000000}
set optimization aggressive
set syncookies adaptive (start 15%, end 8%)
set timeout tcp.established 1800
set skip on lo
set loginterface em0

# Default everything coming in + antispoof
antispoof for $ext_if inet
antispoof for $int_if inet
antispoof for carp0 inet

block drop all
block drop in quick on $ext_if from { <bogons>, <bruteforce> }

# Allow traffic from all our CARP devices
pass on $carpdevs proto carp

# Allow connections between all of our intrefaces
pass from { self, $localnet }
#block drop in on $ext_if from carp0:network
# block all outgoing traffic through em0 coming from em2-em5 and don't bother testing other rules
block return out on egress proto { tcp, udp} from 192.168.0.0/16

# pass out clock synchronization
pass out on egress proto udp from 192.168.0.0/16 to port ntp

# pass out dns look up
pass out on egress proto { udp, tcp } from 192.168.0.0/16 to port domain

pass out on egress from 192.168.1.0/24
pass out on egress from 192.168.5.0/24
pass out log on egress from 192.168.2.0/24

match out on $ext_if inet from 192.168.0.0/16 nat-to (carp0) # NAT, match IPv4 only

# ICMP related rules -- See The PF Book Chapter 3
icmp_types = "{ echoreq, unreach }"
icmp6_types = "{ echoreq unreach timex paramprob }"
pass inet proto icmp icmp-type $icmp_types #max-pkt-rate 100/1
pass inet6 proto icmp6 icmp6-type $icmp6_types # max-pkt-rate 100/1

# Allow default port range for traceroute(8) 64*3 - Reference: The PF Book Chapter 3
pass out on egress inet proto udp to port 33433:33626 # For IPv4
pass out on egress inet6 proto udp to port 33433:33626 # For IPv6

# Allow incoming SSH connections from US IP addresses only
pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port ssh modulate state \
        (max-src-conn 50, max-src-conn-rate 10/1, overload <bruteforce> flush global)

# Allow incoming traffic on http,https and forward it to our web_server computer
pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port https rdr-to 192.168.5.5 keep state \
        (max-src-conn-rate 100/1, overload <websiteoverload>)

pass in log on $ext_if proto tcp from <USA_IP_ADDRESSES> to port 58777 rdr-to <mysmateservers> least-states modulate state \
        (max-src-conn-rate 1000/1, overload <appoverload>)

# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010

# Port build user does not need network
block return out proto {tcp udp} user _pbuild
    
por 10.12.2018 / 13:49