Muy buenas!
Antes de nada: Keep Calm, lo que estamos liberando es la base funcional, algo así como «el producto mínimo viable» que se diría desde la perspectiva de un gestor de proyectos 😉
Es decir, algo con lo que empezar a andar y abrir el proyecto a la comunidad, no es algo production ready ni similar, no lo consideréis como tal please.
¿Otro SBC?
Existen muchos proyectos que permiten construirse uno mismo algo tan genérico como es un SBC, que incluso en el RFC dicen que es algo difuso («relatively non specific») y muchos expertos lo consideran un término más de marketing. Con Kamailio, OpenSIPS, SEMS, FreeSwitch, YATE, … hay muchas opciones para construirse uno entero.
En nuestro caso, las necesidades que teníamos (y sobre todo las que no tenemos – que son casi las más determinantes -) nos han llevado por la vía de construirnos uno propio, que nos permitía:
- Tener un interface web sencillo que pueda ser manejado por técnicos que conocen SIP pero no son expertos Kamailio, OpenSIPS.
- Tener un sistema que nos permita gestionar bien las necesidades de NAT traversal y rtp proxy’ing en entornos diversos en los que solemos estar implicados.
Dicho esto, y cuando lo veáis (por su sencillez) entederéis el porque del nombre 😉
Recomendamos la lectura del README.md para ver las features no soportadas y las que sí.
Show me the code
Actualmente lo tenemos integrado en nuestro GITLAB interno, pero lo pasaremos a Github ASAP, es posible que cuando leáis esto esté ya publicado.
Arquitectura Irontec Tiny SBC (ITSBC)
- La arquitectura es tremendamente sencilla, de ahí su nombre:
- OpenSIPS para toda la gestión del signalling.
- Mención especial al módulo midregistrar.
- RTPEngine para toda la gestión del media.
- Interface web para gestionar todo esto realizado con Symfony (EasyAdmin Bundle).
Ejemplo completo de caso de uso real
Descripción del escenario
De forma sencilla, nos hemos planteado este escenario introductorio, que gestiona registers y requests no registers desde dos tipos de agentes, así que encajaba bien para ilustrar todos los conceptos:
Tareas previas
Antes de seguir los siguientes pasos, lo que tenemos que tener para poder desplegar esto es:
- VM o server físico con Debian 9 64bits instalada.
- Router/Firewall haciendo NAT y con las siguientes redirecciones (port forward)
- [SIP TLS] TCP 4061 en WAN contra TCP 4061 de 192.168.1.2
- [RTP] UDP 17001-19000 en WAN contra UDP 17001-19000 de 192.168.12
- (ver /etc/default/rtpengine)
- Podéis optar sin problemas por Amazon EC2.
Hemos querido poner un ejemplo behind nat porque suele ser lo más habitual o si algun@ probáis esto en Amazon EC2 o cualquier otro cloud será lo que os encontréis como única opción.
Instalación ITSBC
La instalación está totalmente documentada en el fichero README.md, pero la refraseamos por aquí:
Primero añadir el repo de Irontec para Debian 9:
echo 'deb http://packages.irontec.com/debian itsbc main' > /etc/apt/sources.list.d/irontectinysbc.list wget http://packages.irontec.com/public.key -q -O - | apt-key add - apt-get update
Para instalar los paquetes:
apt-get install itsbc
La instalación de la base de datos, optaremos por MariaDB, que es lo que está por defecto en Debian 9, pero debería funcionar con cualquier MySQL Like (Percona, MySQL, ProxySQL …):
apt-get install mariadb-server mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'ROOTPASSWORD' WITH GRANT OPTION"
Acto seguido tenemos que editar y dejar las opciones de MySQL cambiadas: /etc/opensips/opensipsctlrc
DBENGINE=MYSQL ## database port (PostgreSQL=5432 default; MYSQL=3306 default) DBPORT=3306 ## database host DBHOST=localhost ## database name (for ORACLE this is TNS name) DBNAME=opensips ## database read/write user DBRWUSER=opensips ## password for database read/write user DBRWPW="OPENSIPSPASS"
Para finalmente crear la BBDD oficial de OpenSIPS con este comando (nos pedirá la pass de root de MariaDB):
opensipsdbctl create
Y creamos el usuario de acceso para OpenSIPS: [FIXME – IGUAL NO HAY QUE HACERLO]
mysql -uroot -pROOTPASSWORD -e "CREATE USER opensips@localhost IDENTIFIED BY 'OPENSIPSPASS'" mysql -uroot -pROOTPASSWORD -e "GRANT ALL PRIVILEGES ON opensips.* TO opensips@localhost" # Note: This can be done in a better way with more specific privileges :)
Con la contraseña que hayamos decidido para el usuario opensips editamos /opt/irontec/itsbc/config/opensips/opensips_database.cfg y cambiamos los datos de acceso:
modparam("usrloc", "db_url","mysql://opensips:[email protected]/opensips") modparam("avpops","db_url","mysql://opensips:[email protected]/opensips")
El último paso es añadir las tablas necesarias para que funcione la web de administración de ITSBC :
Editamos /opt/irontec/itsbc/app/config/parameters.yml con los datos correctos de acceso
Ejecutamos:
cd /opt/irontec/itsbc/ bin/console doctrine:database:import schema/initial.sql
Tras todo esto recomendamos reiniciar la VM/Máquina entera, para garantizar que arranque OpenSIPS, Apache2, RTPEngine.
Configuraciones a realizar
Una vez ejecutados esos comandos podemos entrar (https://192.168.1.2) con admin / irontec de credenciales.
Para el ejemplo que hemos definido necesitamos definir:
- 2 SIP Listeners
- El primero es el que escucha «hacia/desde WAN» por TLS y tras NAT.
- El segundo es el que está contra la IP PBX enterna, por UDP y sin NAT.
- 2 Media IPs
- La primera está en 192.168.1.2 pero con pública 9.9.9.9 (lo que viajará en los SDP’s).
- La segunda es la misma IP 192.168.1.2 pero sin adverstised address diferente
- 3 Reglas
- Una regla para gestionar los Registers desde fuera.
- Una regla para gestionar los diálogos iniciados desde fuera.
- Una regla para gestionar los diálogos iniciados desde dentro.
Esto a nivel web quedaría tal que:
SIP Listeners
Media IPs
Reglas en Routing Registers
Una única regla:
Reglas en Routing Requests
Requests de la corporate pbx
En este caso tenemos que construir dos reglas, la primera con la métrica menor (para que haga match antes) para todo el tráfico que viene desde la Corporate PBX, especial atención al uso del término «lookup» en la parte de destino:
Como punto especial, comentar únicamente que en Next hop tenemos que poner «lookup», para que OpenSIPS busque en la location table el contact, esto hace que el socket de salida lo coja de la propia tabla de location (y si, tendríamos que ocultar ese campo y hacer que sea un selector 😉 ).
Requests desde el mundo exterior
Por último, nos queda definir una regla con prioridad dos para que las requests que vienen desde la red pública sean encaminadas correctamente hacia la corporate pbx:
Next Hop
Por el momento, no tenemos un roadmap claro, queríamos compartir con tod@s vosotr@s esta pequeña tool, que para muchos casos puede valer. Hay muchísimos puntos que se pueden mejorar y cientos de features implementables, pero vamos poco a poco.
Eso si, seguramente el próximo paso sea hacer que las entidades principales sean elementos gestionables vía web con conceptos usados como: networks, ACL’s, countrys … y que luego se puedan linkar fácilmente en las secciones.
Sentiros libres de hackear el código, de hacer PR en Github o lo que necesitéis 😉
Queremos tu opinión :)