Asterisk es una herramienta fantástica de software libre usada para la comunicación voz ip que funciona perfectamente en Linux. Evidentemente no todo es gratis, si queremos hacer llamadas al exterior, se necesita contratar un proveedor SIP cuyo precio es bastante asequible pero que no deja de ser un coste. Aún así, yo la considero una excelente herramienta tanto cómo aprendizaje tanto cómo herramienta profesional (centralita de llamadas hecha por uno mismo). Hace poco monté una pequeña centralita muy simple, contratando un proveedor SIP gratuito que tenía la limitación de realizar o recibir llamadas de miembros de dicho proveedor. No es algo practico en la vida real, pero sí útil.
La centralita voz ip es muy útil, pero si no tenemos cuidado puede salirnos caro. Un recurso indispensable es la configuración de varios filtros para que nadie que nosotros no queramos pueda entrar por el router. Pero nunca está de más tener una protección extra en el servidor linux donde está instalado Asterisk. Hace poco estaba mirando los logs y grande fue mi sopresa al ver más de mil intentos de registro en mi centralita con diferentes nombres y contraseñas. Por suerte mi contraseña es sólida y no ha podido hacer nada (aunque si hubiese entrado no habría podido hacer gran cosa), pero nunca es agradable ver cómo te saturan de ataques o ver que tu servidor no es tan seguro. En mi caso solo he tenido que filtrar todo aquello que entrase por el puerto 5060 menos mi proveedor SIP, pero imaginemos que queremos algo abierto en un caso real. No es aconsejable impedir todos los accesos por el puerto(imaginemos que tenemos varios proveedores o que tenemos una centralita con constantes cambios), pero tampoco hay que dejarlo abierto para todos ya que pueden pasar cosas cómo esta. Por ello vi la necesidad de bloquear solo las ip que me intentasen invadir.
Hay varias herramientas por ahí, pero ninguna se adaptaba a mis necesidades o era defectuosa y por ello, he creado un script para sea ejecutado automáticamente (gracias a la herramienta crontab) cada cierto tiempo, en mi caso particular cada 30 minutos, y me proteja de aquello que me acosa constantemente.
En mi caso he llamado al script asterisk_filter.sh
- #!/bin/bash
- ##############################################Filtrador de Asterisk################################
- #Variables necesarias
- tabla[1]=0
- i=1
- count[1]=0
- aux=1
- rev=0
- marca=0
- #Registramos en el fichero /tmp/fichero.txt las ultimas las lineas que incluyen: NOTICE y failed for. Solo guardamos la ip y el puerto.
- #Esta puesto para que lea las ultimas 500 lineas
- tail -n 500 /var/log/asterisk/messages |grep 'failed for' |grep 'NOTICE' |cut -d "'" -f4 > /tmp/fichero.txt
- #Lectura del fichero
- while read linea;
- do
- #Inicializamos la variable auxiliar
- aux=1
- while [ ${aux} -le ${i} ];
- do
- if [ ${tabla[$aux]} != ${linea} ];
- then
- #Con esto evaluamos si lo que no coincide con el contenido ya existe en nuestra tabla
- while [ ${rev} -le ${i} ];
- do
- rev=$((${rev} + 1))
- if [ "${tabla[$rev]}" == "${linea}" ]; #Si coincide hacemos una marca que dice que existe
- then
- marca=1
- fi
- done
- if [ ${marca} -eq 0 ]; #Si la marca dice que no existe, sumamos una entrada a la tabla
- then
- i=$((${i}+1))
- tabla[${i}]=${linea}
- fi
- else
- count[${aux}]=$((${count[aux]} + 1)) #Si la cadena existe en la tabla, la sumamos al contador
- fi
- #Reinicializamos las variables de revision
- marca=0
- rev=0
- #Sumamos uno al auxiliar
- aux=$((${aux} + 1))
- done #Fin de bucle de comparaciones de cadenas
- done < /tmp/fichero.txt #Fin de lectura de fichero
- aux=1 #Aprovechamos la variable auxiliar para la evaluacion final
- limite=180 #Limite de intentos
- while [ ${aux} -le $i ]; #Mientras que aux sea
- do
- marca=0 #Siempre que iniciamos el bucle la marca es 0
- aux=$((${aux}+1))
- #Si el numero de intentos de entrada desde una ip concreta es mayor que 180, entonces la bloqueamos
- if [ ${count[${aux}]} -gt ${limite} ];
- then
- #Miramos si esta regla ya existe en nuestro iptables por para evitar duplicidades
- #Esto se hace para evitar que nuestro equipo se llene de reglas iguales
- #ya que se puede leer algo del log que ya ha sido tratado antes pero que sigue en dicho
- if [ -f /etc/init.d/iptables.sh ]; #si existe iptables...
- then
- echo "nada" >/dev/null
- else
- touch /etc/init.d/iptables.sh
- echo "### BEGIN INIT INFO" > /etc/init.d/iptables.sh
- echo "# Provides: iptables.sh" >> /etc/init.d/iptables.sh
- echo "# Required-Start: " >> /etc/init.d/iptables.sh
- echo "# Required-Stop: " >> /etc/init.d/iptables.sh
- echo "# Should-Start: " >> /etc/init.d/iptables.sh
- echo "# Should-Stop: " >> /etc/init.d/iptables.sh
- echo "# Default-Start: 2 3 4 5" >> /etc/init.d/iptables.sh
- echo "# Default-Stop: 0 1 6" >> /etc/init.d/iptables.sh
- echo "# Short-Description: iptables.sh" >> /etc/init.d/iptables.sh
- echo "# Description: iptables script" >> /etc/init.d/iptables.sh
- echo "### END INIT INFO" >> /etc/init.d/iptables.sh
- chmod 755 /etc/init.d/iptables.sh
- $(insserv iptables.sh)
- fi
- while read line;
- do
- ##Aqui dividimos la ip del atacante y el puerto por el que intenta acceder
- ip=${tabla[${aux}]} |cut -d ":" -f1
- port=${tabla[${aux}]} |cut -d ":" -f2
- #Esto es para que funcioe en algunas versiones antiguas que no incluyen el puerto en el log
- if [ ${#ip} == 0 ];
- then
- ip=${tabla[${aux}]}
- fi
- if [ ${#port} == 0 ]
- then
- port=5060 #Aqui ponemos el standard sip porque suele ser el mas atacado
- fi
- #Fin de proteccion
- #Comprobamos si existe la regla
- if [ "${line}" == "iptables -A INPUT -s ${ip} -p tcp --dport ${port} -j DROP" ];
- then
- marca=1 #si existe, lo marcamos para no crear duplicidades
- fi
- done < /etc/init.d/iptables.sh
- #Si no hay marca, es decir si no existe, agregamos una regla
- if [ ${marca} == 0 ];
- then
- #Bloqueamo los protocolos, tcp y udp y agregamos las reglas a nuestro script de inicio
- $(iptables -A INPUT -s ${ip} -p tcp --dport ${port} -j DROP)
- $(iptables -A INPUT -s ${ip} -p udp --dport ${port} -j DROP)
- echo "iptables -A INPUT -s ${ip} -p tcp --dport ${port} -j DROP" >> /etc/init.d/iptables.sh
- echo "iptables -A INPUT -s ${ip} -p udp --dport ${port} -j DROP" >> /etc/init.d/iptables.sh
- fi
- fi
- done
- rm /tmp/fichero.txt
Esto es el funcionamiento básico del programa. Obviamente puede ser mejorado. Hay multitud de opciones pero para ello he puesto también el código, para que luego cada uno lo vaya mejorando a su gusto. Si tenéis alguna propuesta/mejora comentarla por favor.
Por cierto luego en el crontab pondríamos algo cómo esto:
Un saludo.
No hay comentarios :
Publicar un comentario