Introducción
Asterisk (al menos en las ramas 1.4 y 1.6) carece de un mecanismo 'built-in' que bloquee ataques 'por fuerza bruta' o 'por diccionario' y lo proteja de recibir numerosos intentos de registro fallidos, en sus módulos SIP e IAX2.
Tomando como base teórica el artículo "Limitando conexiones con el módulo 'recent' de Netfilter/iptables", utilizaremos iptables para identificar y bloquear eficazmente este tipo de tráfico.
Teoría
El proceso de registro en el protocolo SIP, segun el estandar RFC3261 es como se ilustra a continuación:
El primer paso en el proceso de registro es el envio a la PBX del mensaje SIP REGISTER:
REGISTER sip:192.168.0.1:5060 SIP/2.0 Content-Length: 0 Contact: ;events="message-summary" Call-ID: 1DBDA84B-37E9-4F05-BE8B-E3A0F6BBEE91@192.168.0.2 Max-Forwards: 70 From: ;tag=220587183498 CSeq: 3 REGISTER To: Via: SIP/2.0/UDP 192.168.0.2;rport;branch=z9hG4bK805d2fa50131c9b1434671010000391200000013
A lo que la central Asterisk respondera:
SIP/2.0 401 Unauthorized Via: SIP/2.0/UDP 192.168.0.2;rport;branch=z9hG4bK805d2fa50131c9b1434671010000391200000013;received=192.168.0.2 From: ;tag=220587183498 To: ;tag=as6d76ba1b Call-ID: 1DBDA84B-37E9-4F05-BE8B-E3A0F6BBEE91@192.168.0.2 CSeq: 3 REGISTER User-Agent: Asterisk PBX Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Contact: WWW-Authenticate: Digest realm="asterisk", nonce="4f87b95d" Content-Length: 0
La PBX le está informando a la extension que intenta registrarse que para hacerlo correctamente, deberá enviar sus credenciales (nombre de usuario y clave). Entonces, la extensión vuelve a enviar otro mensaje REGISTER, esta vez con el nombre de usuario y clave en forma de digest, utilizando para su armado el dato realm
y nonce
:
REGISTER sip:192.168.0.1:5060 SIP/2.0 Content-Length: 0 Contact: ;events="message-summary" Call-ID: 1DBDA84B-37E9-4F05-BE8B-E3A0F6BBEE91@192.168.0.2 Max-Forwards: 70 From: ;tag=2205872822811 CSeq: 4 REGISTER To: Via: SIP/2.0/UDP 192.168.0.2;rport;branch=z9hG4bK805d2fa50131c9b14346710100004e6d00000016 Authorization: Digest username="sultan",realm="asterisk",nonce="4f87b95d",uri="sip:192.168.0.1:5060",response="fed6890f44712fbaef17c704e6e30eac"
Finalmente la PBX acpeta la petición e indica su resultado:
SIP/2.0 200 OK Via: SIP/2.0/UDP 192.168.0.2;rport;branch=z9hG4bK805d2fa50131c9b14346710100004e6d00000016;received=192.168.0.2 From: ;tag=2205872822811 To: ;tag=as6d76ba1b Call-ID: 1DBDA84B-37E9-4F05-BE8B-E3A0F6BBEE91@192.168.0.2 CSeq: 4 REGISTER User-Agent: Asterisk PBX Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Expires: 120 Contact: ;expires=120 Date: Fri, 07 Oct 2005 12:57:55 GMT Content-Length: 0
De esta pequeña introducción se deduce que teoricamente podriamos identificar este tipo de paquetes desde iptables buscando el string REGISTER sip:
.
UDP/IP no es un protocolo orientado a conexiones pero aun asi se puede realizar un seguimiento al estado de las mismas desde el Kernel. Por esta razon es importante tener presente el hecho que solo el primer paquete SIP REGISTER es marcado como una conexión nueva o NEW
. Todos los subsiguientes mensajes SIP de este host se marcaran como ESTABLISHED
o RELATED
.
Materiales & Procedimientos
Para esta prueba utilizaremos un sistema GNU/Linux Debian Etch 4.0 base, corriendo un Asterisk 1.4.38.1 e iptables, con IP 192.168.10.50.
Las reglas en cuestion son:
iptables --new-chain BLACKLISTADD iptables --append BLACKLISTADD --match recent --name BLACKLIST --set --jump DROP iptables --append INPUT --match recent --name BLACKLIST --rcheck --seconds 300 --jump DROP iptables --append INPUT --match recent --name BLACKLIST --remove iptables --append INPUT --protocol udp --dport 5060 --in-interface eth2 --match recent --name SIP --set iptables --append INPUT --protocol udp --dport 5060 --in-interface eth2 --match string --string "REGISTER sip:" --algo bm --match recent --update --seconds 5 --hitcount 10 --name SIP --jump BLACKLISTADD
Los cuatro primeros comandos ya son familiares por nuestro articulo anterior.
El quinto comando agrega cualquier paquete del tipo UDP/IP con destino al puerto 5060 y que haya ingresado por la interfaz de red eth2
a la lista SIP del modulo recent
.
El sexto comando matchea los paquetes anteriores buscando en su interior, el string REGISTER sip:
. De encontrarlo, incrementa el numero de apariciones de este en la lista SIP y acto seguida lo pone en BLACKLIST
en caso que ya existan otros 9 paquetes mas iguales al anterior en los utimos 5 segundo.
Diagamos entonces que con estas reglas, la PBX llevara la cuenta de cuantos paquetes SIP REGISTER
recibe y en caso de detectar mas de 10 en los ultimos 5 segs, bloqueara la IP de origen durante 15mins.
Veamos como funciona esto en la práctica...
Pruebas
Para las pruebas necesitaremos enviar a nuestra PBX de testing, 10 o mas paquetes SIP REGISTER. Para esto utilizaremos la excelente suite SIPsak. Esta herramienta nos permite, entre otras muchas cosas, la utilizacion de varios metodos SIP, entre ellos el REGISTER
.
Simplemente ejecutamos desde otra maquina, el siguiente comando:
sipsak -U -P 10 -C empty -a password -s sip:8120@192.168.10.50 -vv
Veremos que luego de 10 intentos, la PBX deja de responder (en realidad, lo que pasa es que el IPTABLES comienza a DROPear nuestras peticiones).
Conclusión
Utilizando las herramientas y modulos de IPTABLES pudimos limitar los intentos de registro SIP hacia nuestra central.
Consideraciones finales
Tener en cuenta que esta medida de seguridad puede afectar a usuarios legitimos que quieran iniciar sesion en nuestro servidor Asterisk, si no se configura adecuadamente.
Es decir, si Juancito (que es un usuario legitimo en la empresa) desea conectar con nuestro Asterisk utilizando X-Lite desde su notebook, pero no recuerda la clave o la introdujo mal en dicho programa; luego de varios intentos fallidos, quedara imposibilitado de loguearse por 15mins. En lo personal recomiendo no ser tan estricto con los parametros que pongamos en IPTABLES.
Imagen y ejemplos SIP REGISTER tomados de aqui.
Un buen post pero ¿conoces fail2ban? Funciona de la manera que describes y es muy completo.
Hola Manolo, gracias por tu comentario.
Si, conozco Fail2Ban. La diferencia es que este script provee seguridad 'reactiva' debido entre otras cosas a que parsee los logs de los servicios que se desean securizar para luego generar reglas en IPTABLES que baneen las IP's maliciosas.
En cambio, el metodo descripto en este post esta pensado para proveer seguridad 'proactiva', denegando en casi en 'tiempo real' conexiones provenientes de IP's con comportamiento anormal, sin generar carga adicional al servidor en cuestion.
Desde ya, nos mantenemos en contacto y gracias por leer este blog.