Está en la página 1de 12

Proteccin DDoS mediante iptables

PUBLICADO POR VICENTE MOTOS ON MIRCOLES, 20 DE ABRIL DE


2016 ETIQUETAS: FORTIFICACIN , LINUX , REDES

Cuando me inici en el mundo de Linux hace ya ms de 15 aos (joder que


viejo soy) una de las las caractersticas que ms me enganch desde el
principio fueron sus capacidades para usarlo como cortafuegos de red. Primero
con ipfwadm, luego ipchains y despus y sobretodo iptables/Netfilter, fueron
muchos los firewalls Linux que desplegu durante aos. Y despus de tanto
tiempo y an a la espera de la inminente (y tarda) adopcin de nftables, me
siguen maravillando sus posibilidades y capacidades de defensa antes las
ltimas amenazas de nuestra era...

Y precisamente una de las amenazas ms tangibles de esta dcada son


los famosos ataques de denegacin de servicio distribuidos (DDoS) que
vemos tanto en los medios y que provocan a las empresas prdidas
millonarias con slo afectar a la disponibilidad de sus sistemas durante un
breve (o no) periodo de tiempo.

Para contrarrestar estos ataques, iptables y en general el kernel de Linux nos


ofrece ciertas protecciones que debemos tener en cuenta. El genial artculo de
Constantin Oesterling en Javapipe da buena cuenta de ello, as que
repasaremos algunas de sus medidas para mitigar DDoS.

Tuneando el kernel

Lo primero que tenemos que hacer antes de abordar las reglas como tal es
optimizar el kernel para mitigar los efectos de los ataques DDoS. El siguiente
ejemplo se basa en CentOS 7 ya que esta distro incluye una versin reciente
de iptables y soporta synproxy. Slo hay que ponerla en /etc/sysctl.conf y
aplicar la configuracin con sysctl -p:

kernel.printk = 4 4 1 7
kernel.panic = 10
kernel.sysrq = 0
kernel.shmmax = 4294967296
kernel.shmall = 4194304
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
vm.swappiness = 20
vm.dirty_ratio = 80
vm.dirty_background_ratio = 5
fs.file-max = 2097152
net.core.netdev_max_backlog = 262144
net.core.rmem_default = 31457280
net.core.rmem_max = 67108864
net.core.wmem_default = 31457280
net.core.wmem_max = 67108864
net.core.somaxconn = 65535
net.core.optmem_max = 25165824
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
net.ipv4.neigh.default.gc_interval = 5
net.ipv4.neigh.default.gc_stale_time = 120
net.netfilter.nf_conntrack_max = 10000000
net.netfilter.nf_conntrack_tcp_loose = 0
net.netfilter.nf_conntrack_tcp_timeout_established = 1800
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 20
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 20
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_no_pmtu_disc = 1
net.ipv4.route.flush = 1
net.ipv4.route.max_size = 8048576
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 4096 87380 33554432
net.ipv4.udp_rmem_min = 16384
net.ipv4.tcp_wmem = 4096 87380 33554432
net.ipv4.udp_wmem_min = 16384
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 400000
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_fack = 1
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 10
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.rp_filter = 1

Estos ajustes en sysctl.conf ayudan a maximizar el rendimiento de un servidor


bajo un ataque DDoS, as como la eficacia de las reglas de iptables que
veremos a continuacin.

Filtrar lo mximo posible en la tabla mangle y la cadena PREROUTING


Lo segundo que hay que tener en cuenta que el
rendimiento de las reglas de iptables es extremadamente importante. La
mayora de los ataques DDoS basados en TCP se realizan con una alta tasa de
transferencia de paquetes, es decir, con un gran nmero de paquetes por
segundo lo que hace que el servidor se caiga. Es por eso que hay que
asegurarse de que se pueda procesar y bloquear la mayor cantidad de
paquetes por segundo como sea posible.

Muchas guas sobre cmo bloquear los ataques DDoS usando iptables utilizan
la tabla de filtros y la cadena INPUT para las reglas anti-DDoS. El problema con
este enfoque es que la cadena de INPUT slo se procesa despus de las
cadenas PREROUTING y FORWARD y, por lo tanto, slo se aplica si el paquete
no coincide con ninguna de estas dos cadenas. Esto provoca un retraso en el
filtrado de los paquetes que consume recursos.

Por ello, para hacer las reglas ms eficaces, tenemos que hacer que nuestro
anti-DDoS utilice el menor nmero de cadenas posible. La primera cadena que
puede aplicarse a un paquete es la cadena PREROUTING, por lo que lo ideal es
filtrar el mximo de paquetes en esa cadena. Sin embargo, la tabla de filtros o
filter no es compatible con la cadena PREROUTING. Para solucionar este
problema, podemos simplemente utilizar la tabla mangle en lugar de la tabla
de filtros para nuestras reglas de iptables anti-DDoS ya que es compatible con
la mayora, si no todas, las reglas.

En resumen, la mejor solucin para aumentar drsticamente el rendimiento de


las reglas de iptables y por lo tanto la cantidad de ataques DDoS (TCP) que
pueden filtrar es utilizar la tabla mangle y la cadena PREROUTING.

Siguiendo las conexiones

Ahora bien, los ataques DDoS son complejos. Hay muchos tipos diferentes de
DDoS y es casi imposible mantener reglas basadas en firmas contra todos
ellos. Pero por suerte hay algo llamado seguimiento de conexiones (el mdulo
del kernel nf_conntrack) que nos puede ayudar a mitigar casi cualquier ataque
DDoS basado en TCP que no utilizan paquetes SYN que parecen legtimos. Esto
incluye todos los tipos de ataques DDoS ACK y SYN-ACK, as como ataques
DDoS que utilizan flags TCP falsos.

Vamos a empezar slo con cinco reglas de iptables sencillas que detendrn
muchos ataques DDoS basados en TCP.

1.- Bloquear paquetes no vlidos: Esta regla bloquea todos los paquetes que
no son un paquete SYN y no pertenecen a una conexin TCP establecida.

iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j


DROP

2.- Bloquear nuevos paquetes que no son SYN: Esto bloquea todos los
paquetes que son nuevos (no pertenecen a una conexin establecida) y no
utilizan el indicador SYN, complementa la regla anterior.

iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --


ctstate NEW -j DROP
3.- Bloquear valores MSS poco frecuentes: bloquea nuevos paquetes (despus
de aplicar las dos reglas anteriores slo podrn ser SYN) que utilizan un valor
TCP MSS que no es comn. Esto ayuda a bloquear inundaciones SYN sencillas.

iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW


-m tcpmss ! --mss 536:65535 -j DROP

4.- Bloquear paquetes con flags TCP falsos: el siguiente conjunto de reglas
bloquea paquetes que utilizan indicadores TCP falsos, es decir, flags TCP que
los paquetes legtimos no usaran.

iptables -t mangle -A PREROUTING -p tcp --tcp-flags


FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN
FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST
SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN
SYN,FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST
FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j
DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
SYN,FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
SYN,RST,ACK,FIN,URG -j DROP

5.- Bloquear paquetes desde subredes privadas (spoofing): estas


reglas bloquean los paquetes falsificados procedentes de subredes privadas
(locales). En un interfaz de red pblico por lo general no debemos recibir
paquetes IP de origen privado. Estas reglas asumen que el interfaz de
loopback utiliza el espacio IP 127.0.0.0/8.

iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP


iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP

Reglas adicionales

1.- Bloquear de ICMP: Esto descarta todos los paquetes ICMP. ICMP se utiliza
sobretodo para hacer ping a un host para averiguar si todava est vivo. Se
suele utilizar para troubleshooting pero representa una vulnerabilidad que los
atacantes pueden explotar, as que es recomendable bloquear todos los
paquetes ICMP para mitigar Ping de la Muerte (ping flood), ICMP flood y ICMP
fragmentation flood.

iptables -t mangle -A PREROUTING -p icmp -j DROP

2.- Bloquear ataques de conexiones masivas: esta regla rechaza las


conexiones desde equipos que tienen ms de 80 conexiones establecidas. Se
puede elevar el lmite ya que podra causar problemas con los clientes
legtimos que establecen un gran nmero de conexiones TCP.

iptables -A INPUT -p tcp -m connlimit --connlimit-above 80 -j


REJECT --reject-with tcp-reset

3.- Limitar las nuevas conexiones TCP que un cliente puede establecer por
segundo: esto puede ser til contra los ataques de conexin, pero no tanto
contra inundaciones SYN porque suelen usar un sinfn de direcciones IP
diferentes.

iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --


limit 60/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP

4.- Bloquear paquetes fragmentados: esto podra mitigar la inundacin UDP


pero la mayora de las veces utilizan una gran cantidad de ancho de banda que
agota la capacidad de la tarjeta de red, por lo que hace que esta regla sea
opcional y probablemente no la ms til.

iptables -t mangle -A PREROUTING -f -j DROP

5.- Limitar los paquetes TCP RST entrantes: podra mitigar este tipo de
inundaciones pero su efectividad es cuestionable.

iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s


--limit-burst 2 -j ACCEPT
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP

Mitigando SYN floods con SYNPROXY

Synproxy es un nuevo target de iptables que se ha aadido en Linux en la


versin 3.12 de kernel y en la 1.4.21 de iptables. CentOS 7 lo incluye incluso
antes, por defecto desde la versin 3.10 del kernel.

El propsito de synproxy es comprobar si el host que envi el paquete SYN en


realidad establece una conexin TCP completa o, simplemente, no hace nada
despus de que enviara el paquete SYN. Si no hace nada, se descarta el
paquete con un impacto mnimo en el rendimiento.

Mientras que las reglas de iptables que se proporcionan ms arriba bloquean la


mayora de los ataques basados en TCP, el tipo de ataque que todava puede
evadirlos, si es lo suficientemente sofisticado, es un SYN flood. Es importante
tener en cuenta que el rendimiento de las reglas siempre ser mejor si nos
encontramos con un cierto patrn o la firma de bloqueo, tales como la longitud
del paquete (-m length), TOS (-m tos), TTL (-m ttl) o cadenas y valores
hexadecimales (-m string y -m u32 para los usuarios ms avanzados). Sin
embargo, en algunos casos raros sto no es posible o al menos no es fcil de
conseguir. Por lo tanto, en estos casos, se puede hacer uso de synproxy.

Aqu estn las reglas de iptables synproxy que ayudan a mitigar las
inundaciones SYN que omiten las otras reglas:

iptables -t raw -D PREROUTING -p tcp -m tcp --syn -j CT --notrack


iptables -D INPUT -p tcp -m tcp -m conntrack --ctstate
INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 -
-mss 1460
iptables -D INPUT -m conntrack --ctstate INVALID -j DROP

Estas reglas se aplican a todos los puertos. Si deseas utilizar synproxy slo en
determinados puertos TCP (es recomendable tambin bloquear todos los
puertos TCP que no estn en uso utilizando la tabla mangle y la cadena
PREROUTING), puedes por ejemplo simplemente aadir --dport 80 a cada una
de las reglas si quieres utilizar synproxy en el puerto 80 solamente.

Para verificar que synproxy est funcionando puedes hacer 'watch -n1 cat
/proc/net/stat/synproxy'. Si los valores cambian cuando se establece una
nueva conexin TCP con el puerto que utiliza el synproxy, funciona.

El conjunto de reglas IPtables completo

Si no quieres copiar y pegar cada regla expuesta en esta entrada, puedes


utilizar el conjunto de reglas de a continuacin para una proteccin bsica
DDoS de tu servidor Linux.

### 1: Drop invalid packets ###


/sbin/iptables -t mangle -A PREROUTING -m conntrack --ctstate
INVALID -j DROP
### 2: Drop TCP packets that are new and are not SYN ###
/sbin/iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack
--ctstate NEW -j DROP

### 3: Drop SYN packets with suspicious MSS value ###


/sbin/iptables -t mangle -A PREROUTING -p tcp -m conntrack --
ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP

### 4: Block packets with bogus TCP flags ###


/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags
FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN
FIN,SYN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST
SYN,RST -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN
SYN,FIN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST
FIN,RST -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK
FIN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG
URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN
FIN -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH
PSH -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL
-j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE
-j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
FIN,PSH,URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
SYN,FIN,PSH,URG -j DROP
/sbin/iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL
SYN,RST,ACK,FIN,URG -j DROP

### 5: Block spoofed packets ###


/sbin/iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
/sbin/iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j
DROP

### 6: Drop ICMP (useless protocol) ###


/sbin/iptables -t mangle -A PREROUTING -p icmp -j DROP

### 7: Drop fragments in all chains ###


/sbin/iptables -t mangle -A PREROUTING -f -j DROP

### 8: Limit connections per source IP ###


/sbin/iptables -A INPUT -p tcp -m connlimit --connlimit-above 111
-j REJECT --reject-with tcp-reset

### 9: Limit RST packets ###


/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --
limit 2/s --limit-burst 2 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP

### 10: Limit new TCP connections per second per source IP ###
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit
--limit 60/s --limit-burst 20 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP

### 11: Use SYNPROXY on all ports (disables connection limiting


rule) ###
#/sbin/iptables -t raw -D PREROUTING -p tcp -m tcp --syn -j CT --
notrack
#/sbin/iptables -D INPUT -p tcp -m tcp -m conntrack --ctstate
INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 -
-mss 1460
#/sbin/iptables -D INPUT -m conntrack --ctstate INVALID -j DROP

Bonus: reglas adicionales

Las siguientes reglas de iptables son tiles para aumentar la seguridad global
de un servidor Linux.

### SSH brute-force protection ###


/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate
NEW -m recent --set
/sbin/iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate
NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

### Protection against port scanning ###


/sbin/iptables -N port-scanning
/sbin/iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST
RST -m limit --limit 1/s --limit-burst 2 -j RETURN
/sbin/iptables -A port-scanning -j DROP

Conclusin
Las gua de Constantin Oesterling muestra algunos de los mtodos ms
eficaces para detener los ataques DDoS usando iptables. De hecho, dicen
haber mitigado con xito ataques de DDoS que han alcanzado incluso varios
millones de paquetes por segundo utilizando estas reglas de iptables.

Como bien dicen, si se utiliza correctamente, iptables es una herramienta


extremadamente poderosa que es capaz de bloquear diferentes tipos de
ataques DDoS hacia una tarjeta de 1 GbE, e incluso casi de 10 GbE.

No hay que subestimar el poder de iptables!

También podría gustarte