IPTABLES Asterisk

Comparto esto ya he visto muchas consultas en distintos foros en
donde las respuestas no son o no han sido muy claras, las veo incompletas o
dejan mucho entre líneas, lo que las hace aún más confusa para quien busca una
ayuda.

Hice una mezcla de varias ideas tratando de ser lo más explicativo
posible para ayudarle a quien pueda, quien reconozca su trabajo dentro de lo
que mezcle, por supuesto, el mérito es suyo...

Objetivo del documento, crear un script para correr iptables en
servidor Asterisk expuesto a directamente a Internet.
Asterisk está instalado sobre una plataforma Linux Centos 6.X de
64 bits con dos interfaces de red y actúa de Gateway entre la LAN y la
INTERNET, teniendo usuarios de ambos mundos.
 
Las herramientas utilizadas en el servidor son:

    
Algunos
Howto bastante buenos de las últimas herramientas comentadas:
 
Fail2ban:
https://www.voztovoice.org/?q=node/135
http://www.voip-info.org/wiki/view/Fail2Ban+(with+iptables)+And+Asterisk
http://www.fail2ban.org/wiki/index.php/Asterisk
 
Xtables:
https://www.howtoforge.com/xtables-addons-on-centos-6-and-iptables-geoip-filtering
http://phenobarbital.wordpress.com/2014/06/24/iptables-usar-geoip-y-shorewall-para-
bloquear-paises/

http://sharing.jorgesuarezdelis.name/2010/asrii4/trabajo.pdf
 
Módulos Xtables: 
http://xtables-addons.sourceforge.net/modules.php
 
Entonces partir recordando que IPTABLES actúa secuencialmente las
instrucciones se le vayan ingresando o hayan sido cargadas, por tanto si nos
basamos en un script como es el caso, hay que poner atención en el orden de las
reglas ya unas pueden inhabilitar otras si están en un orden que no
corresponde.
También considerar que si identifico un “riesgo” y
este no lo descarto o rechazo hasta la última regla del cortafuegos, a éste lo
hago trabajar más de cuenta lo que puede llevarme a una degradación he incluso
a una denegación de servicio, por lo tanto primero descarto lo obvio, luego
aplico las reglas de filtrado que requiero y por último cierro todo acceso
adicional por lo que pude haber obviado.
En adelante un copy paste de un script.
 

#################################################################

#!/bin/sh

 

# Asignación de variables

 

SRV_LAN="192.168.200.10"

RLAN="192.168.200.0/24"

SRV_WAN="90.4.52.4"

LAN="eth1"

WAN="eth0"

PROV_1="xxx.xxx.xxx.xxx"

PROV_2="xxx.yyy.xxx.yyy"

 

# Borro reglas y contadores previos

 

iptables -F

iptables -X

iptables -Z

 

# Establezco reglas por defecto

# INPUT negado por defecto

# resta solo decirle que SI puede pasar.

 

iptables -P INPUT DROP

iptables -P FORWARD DROP

iptables -P OUTPUT ACCEPT

 

# Acepto conexiones nuevas relacionadas y otras
previamente establecidas, así

# no evalúo por cada paquete todas las reglas sino
solo las nuevas conexiones.

iptables -A INPUT -m state --state RELATED,ESTABLISHED
-j ACCEPT

 

# Acepto las conexiones loopback

iptables -A INPUT -i lo -j ACCEPT

 

# Creo cualquier cadena nueva a utilizar. En este
caso, cualquier paquete caiga

# en la cadena BLACKLIST se descartará por 1200
segundos, luego se restaurará.

iptables --new-chain BLACKLIST

iptables -A BLACKLIST -m limit --limit 5/m
--limit-burst 7 -j LOG --log-prefix "**BLACKLIST A:" --log-level 7

iptables -A BLACKLIST -m recent --name BLACKLIST --set
-j DROP

iptables -A INPUT -m recent --name BLACKLIST --rcheck
--seconds 1200 -j LOG --log-prefix "**BLACKLIST A:" --log-level 7

iptables -A INPUT -m recent --name BLACKLIST --rcheck
--seconds 1200 -j DROP

iptables -A INPUT -m recent --name BLACKLIST --remove

 

# Partí indicando que es solo necesario indicar las
políticas

# que si tendrán acceso, por otra parte, se entiende que
los protocolos

# en Asterisk por defecto trabajan sobre UDP, pero me
es necesario tomar algunas

# medidas de seguridad que actúan sobre TCP, éstas
acciones permitirán

# rechazar algnos ataques ya identificados lo que nos
ahorrara tiempo y $$$.

 

# Según TCP/IP todo establecimiento de conexión
comienza con un paquete tipo SYN,

# por lo tanto como anteriormente ya permito
conexiones nuevas relacionadas y otras

# previamente establecidas, descarto nuevas conexiones
que no comiencen según la norma.

iptables -A INPUT -i $WAN -p tcp ! --syn -m state
--state NEW -j DROP

 

# Descarto todos los paquetes fragmentados

iptables -A INPUT -i $WAN -f -j DROP

 

# Descarto paquetes XMAS

iptables -A INPUT -i $WAN -p tcp –-tcp-flags ALL ALL
-j DROP

 

# Descarto paquetes vacíos

 

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL NONE
-j DROP

 

# Descarto paquetes inválidos

iptables -A INPUT -i $WAN -m state --state INVALID -j
DROP

 

# Algunos ataques envían XXX cantidad de solicitudes
erróneas para

# llenar la cola de requerimientos del server y/o la
red involucrada,

# así éste quedar fuera de línea, para posterior
suplantación

# u otro caso, entonces si los requerimientos no
vienen en el 

# orden de banderas esperado, simplemente descarto la
conexión

iptables -A INPUT -i $WAN -p tcp --tcp-flags ACK,FIN
FIN -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ACK,PSH
PSH -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ACK,URG
URG -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags FIN,RST
FIN,RST -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags
FIN,SYN,RST,PSH,ACK,URG NONE -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags FIN,SYN
FIN,SYN -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags FIN,ACK
FIN -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags SYN,FIN
SYN,FIN -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags SYN,RST
SYN,RST -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL ALL
-j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL NONE
-j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL
FIN,PSH,URG -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL
SYN,FIN,PSH,URG -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL
SYN,RST,ACK,FIN,URG -j DROP

iptables -A INPUT -i $WAN -p tcp --tcp-flags ALL
ACK,RST,SYN,FIN -j DROP

 

# Descarto el spoofing RFC1918

# Solo respondo consultas de IP Privadas por la
interface conectada a la LAN

iptables -A INPUT -i $WAN -s 10.0.0.0/8 -j DROP

iptables -A INPUT -i $WAN -s 172.16.0.0/12 -j DROP

iptables -A INPUT -i $WAN -s 192.168.0.0/16 -j DROP

 

# Descarto el otro spoofing

# Multicast, IPs reservadas o calquier otra que por
definición

# no debe llegar a nuestro servidor, se descartan.

iptables -A INPUT -i $WAN -s 169.254.0.0/16 -j DROP

iptables -A INPUT -i !lo -s 127.0.0.0/8 -j DROP

iptables -A INPUT -i $WAN -s 224.0.0.0/4 -j DROP

iptables -A INPUT -i $WAN -d 224.0.0.0/4 -j DROP

iptables -A INPUT -i $WAN -s 240.0.0.0/5 -j DROP

iptables -A INPUT -i $WAN -d 240.0.0.0/5 -j DROP

iptables -A INPUT -i $WAN -s 0.0.0.0/8 -j DROP

iptables -A INPUT -i $WAN -d 0.0.0.0/8 -j DROP

iptables -A INPUT -i $WAN -d 239.255.255.0/24 -j DROP

iptables -A INPUT -i $WAN -d 255.255.255.255 -j DROP

iptables -A INPUT -i $WAN -s 248.0.0.0/5 -j DROP

iptables -A INPUT -i $WAN -d 248.0.0.0/5 -j DROP

iptables -A INPUT -i $WAN -s 239.255.255.0/24 -j DROP

iptables -A INPUT -i $WAN -s 255.255.255.255 -j DROP

iptables -A INPUT -i $WAN -s 192.0.2.0/24 -j DROP

iptables -A INPUT -i $WAN -d 192.0.2.0/24 -j DROP

 

# Descarto el ataque ICMP SMURF

iptables -A INPUT -i $WAN -p icmp --icmp-type
address-mask-request -j DROP

iptables -A INPUT -i $WAN -p icmp --icmp-type
timestamp-request -j DROP

iptables -A INPUT -i $WAN -p icmp --icmp-type
router-solicitation -j DROP

 

# Ahora, algo un poco interesante:

# ¿Mis clientes todos cuentan con IP pública fija la
cual yo pueda filtrar y

# así asegurarme de que solo ellos tengan acceso a mis
servicios o además

# existen clientes con IP dinámica?

 

# Si todos cuentan con IP fija, pues solo aplicar las
reglas de filtrado con

# dichas IPs y santo remedio, si por el contrario
existen algunos con IP dinámica

# y peor, están repartidos por distintos ISP, lo mejor
es tomar una decisión en

# función de las preguntas: ¿Doy servicio al extranjero?

# ¿Necesito que Tangamandapio acceda a mi servicio?

 

# Si doy servicio al extranjero, nada, pues
encomendarse y a tener una buena

# política de administración del firewall, a lo mejor
hasta crear VPNs.

 

# Si solo doy servicios dentro de mi País puedo hacer
uso de xtables-addons

# Xtables me permite entre otras cosas, contar con una
base de datos actualizables

# con el direccionamiento IP por zona geográfica.

# Una regla como la siguiente descartaría por completo
todo el tráfico internacional

#

# iptables -A INPUT -i $WAN -m state --state NEW -m
geoip ! --src-cc CL -j DROP

#

# Pero como tengo un cortafuegos con DROP por defecto,
solo requiero habilitar el 

# tráfico donde lo requiero, en este caso este modulo
se aplica como condicionante

# en las reglas que permiten tráfico

 

# Me cuido del escaneo de puertos con el mismo xtables

# He aquí algo por depurar, fíjense de los paquetes
que caen al LOG.

iptables -A INPUT -i $WAN -m psd
--psd-weight-threshold 5 --psd-hi-ports-weight 3 -j LOG --log-prefix
"**PORTSCAN A:" --log-level 7

iptables -A INPUT -i $WAN -m psd
--psd-weight-threshold 5 --psd-hi-ports-weight 3 -j DROP

 

# Limito/Descarto los ataques por excesivas paquetes
rst

iptables -A INPUT -i $WAN -p tcp --tcp-flags RST RST
-m limit --limit 2/second --limit-burst 2 -j ACCEPT

 

# Puertos y conexiones habilitados desde INTERNET

 

# Proveedores del extranjero

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m multiport --dport 5060,10000:20000 -s $PROV_1 -j ACCEPT

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m multiport --dport 5060,10000:20000 -s $PROV_2 -j ACCEPT

 

# Nacional, solo -m geoip --src-cc CL

# Con restricciones de trafico por segundo

# Y analizando string en el paquete de datos

 

# Ping

iptables -A INPUT -i $WAN -d $SRV_WAN -p icmp -m icmp
--icmp-type 8 -m state --state NEW -m geoip --src-cc CL -m recent --set --name
ICMP

iptables -A INPUT -i $WAN -d $SRV_WAN -p icmp -m icmp
--icmp-type 8 -m state --state NEW -m geoip --src-cc CL -m recent --update
--seconds 1 --hitcount 1 --name ICMP -j LOG  --log-prefix "**PING
A:"

iptables -A INPUT -i $WAN -d $SRV_WAN -p icmp -m icmp
--icmp-type 8 -m state --state NEW -m geoip --src-cc CL -m recent --update
--seconds 1 --hitcount 1 --name ICMP -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -p icmp -m icmp
--icmp-type 8 -m state --state NEW -m geoip --src-cc CL -j ACCEPT

 

# Traceroute

iptables -A INPUT -i $WAN -d $SRV_WAN -p udp -m udp
--dport 33434 -m state --state NEW -m geoip --src-cc CL -m recent --set --name
TRACE

iptables -A INPUT -i $WAN -d $SRV_WAN -p udp -m udp
--dport 33434 -m state --state NEW -m geoip --src-cc CL -m recent --update
--seconds 10 --hitcount 2 --name TRACE -j LOG  --log-prefix "**TRACE
A:"

iptables -A INPUT -i $WAN -d $SRV_WAN -p udp -m udp
--dport 33434 -m state --state NEW -m geoip --src-cc CL -m recent --update
--seconds 10 --hitcount 2 --name TRACE -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -p udp -m udp
--dport 33434 -m state --state NEW -m geoip --src-cc CL -j ACCEPT

 

# SSH

iptables -A INPUT -i $WAN -d $SRV_WAN -p tcp -m state
--state NEW -m tcp --dport 22 -m geoip --src-cc CL -m recent --set --name SSH

iptables -A INPUT -i $WAN -d $SRV_WAN -p tcp -m state
--state NEW -m tcp --dport 22 -m geoip --src-cc CL -m recent --update --seconds
30 --hitcount 5 --rttl --name SSH -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -p tcp -m state
--state NEW -m tcp --dport 22 -m geoip --src-cc CL -j ACCEPT

 

# SIP

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"sundayddr" --algo bm --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"sipsak" --algo bm --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"sipvicious" --algo bm --icase --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"friendly-scanner" --algo bm --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"iWar" --algo bm --to 65535 --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"sip-scan" --algo bm --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"sipcli" --algo bm --to 1500 -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"VaxSIPUserAgent" --algo bm --to 1500 -j BLACKLIST

 

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"REGISTER sip:" --algo bm -m recent --set --name SIP_R --rsource

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"REGISTER sip:" --algo bm -m recent --update --seconds 5 --hitcount
10 --rttl --name SIP_R --rsource -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"INVITE sip:" --algo bm -m recent --set --name SIP_I --rsource

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m string --string
"INVITE sip:" --algo bm -m recent --update --seconds 60 --hitcount 12
--rttl --name SIP_I --rsource -j BLACKLIST

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -m hashlimit --hashlimit
6/sec --hashlimit-mode srcip,dstport --hashlimit-name tunnel_limit -j ACCEPT

#iptables -A INPUT -i $WAN -d $SRV_WAN -m state
--state NEW -p udp -m udp --dport 5060 -m geoip --src-cc CL -j ACCEPT

 

# RTP

iptables -A INPUT -i $WAN -d $SRV_WAN -m state --state
NEW -p udp -m udp --dport 10000:20000 -m geoip --src-cc CL -j ACCEPT

 

# Puertos y conexiones habilitados desde la RED LOCAL

 

# Ping

iptables -A INPUT -i $LAN -d $SRV_LAN -m state --state
NEW -p icmp -m icmp --icmp-type 8 -s $RLAN -j ACCEPT

 

# Trceroute

iptables -A INPUT -i $LAN -d $SRV_LAN -m state --state
NEW -p udp -m udp --dport 33434 -s $RLAN -j ACCEPT

 

# SSH

iptables -A INPUT -i $LAN -d $SRV_LAN -m state --state
NEW -p tcp -m tcp --dport 22 -s $RLAN -j ACCEPT

 

# SIP y RTP

iptables -A INPUT -i $LAN -d $SRV_LAN -m state --state
NEW -p udp -m multiport --dport 5060,10000:20000 -s $RLAN -j ACCEPT

 

# Para ver lo que se nos esté pasando podemos
habilitar el LOG de todo lo que no cae en estas reglas

# pero cuidado porque el log puede crecer muy rápido y
ocuparnos la partición de log

#iptables -A INPUT -j LOG --log-prefix
"**OTRO_INPUT A:"

 

iptables -A INPUT -j DROP

iptables -A OUTPUT -j ACCEPT

 

service iptables save

 

# Al final listo las reglas para ver como quedaron

iptables -nvxL --line-numbers

 

#################################################################

 
Luego guardar el
script donde les acomode, volverlo ejecutable, ponerlo junto al inicio del
sistema y monitorear a el comportamiento de los logs.
 
Para los logs con
rsyslog + logrotate, pueden seguir los enlaces: 
http://blog.desdelinux.net/logueando-toda-actividad-con-iptables/
https://blog.shadypixel.com/log-iptables-messages-to-a-separate-file-with-rsyslog/
 

Para aumentar la
seguridad, fail2ban, verán que éste casi no aplicará con las restricciones que
ya hemos puesto en el firewall, pero no está demás, la carga que genera es
mínima.