Comunicaciones unificadas con Elastix es una obra destinada a los usuarios y entusiastas de esta distribución. Sirve también como material de referencia para aquellos que quieren entrar en el mundo de Voz sobre IP.

Desde su primera edición, este libro ha sido material de capacitación para la certificación oficial de Elastix y también ha servido como punto de partida en la carrera profesional de muchos integradores que eligieron Elastix como principal solución de las Comunicaciones Unificadas.

En un lenguaje simple, el autor lleva al lector hacia la implementación de configuraciones complejas. Recomendado para aquellos que desean potenciar su conocimiento en telecomunicaciones.

Edgar Landívar

Comunicaciones unificadas con Elastix

Volumen 2

ePub r1.1

Titivillus 12.01.17

Título original: Comunicaciones unificadas con Elastix (Volumen 2)

Edgar Landívar, 2008

Presente edición: 2.ª edición, 2011

Editor digital: Titivillus

ePub base r1.2

Copyright (c) 2008-2011 Edgar Landívar

La presente obra se encuentra licenciada bajo los términos de la licencia Creative Commons que se encuentra a continuación http://creativecommons.org/licenses/by-nc-nd/3.0/. Si luego de leerla todavía tiene alguna duda acerca de esta licencia, envíe una carta a Creative Commons, 171 2nd Street, Suite 300, San Francisco, California, 94105, USA.

Segunda Edición

A Danielita, por su sonrisa…

Reconocimiento

La elaboración de este libro involucró un enorme trabajo que fue facilitado gracias a la generosa colaboración de algunas personas con las cuales me encuentro enormemente agradecido. Mis agradecimientos más especiales a:

José Landívar y Alfredo Salas de ElastixDepot LLC, por la prolija revisión del volumen 1, párrafo a párrafo.

A mi Esposa, por la comprensión durante el tiempo que le tuve que dedicar a la escritura del presente libro.

A Paul Estrella, por ejercer la presión necesaria para que esta obra se termine a tiempo.

A Bob Fryer por su importante ayuda revisando la versión en Inglés.

El libro online

A partir de esta segunda edición el libro contará con su propio sitio Web en http://www.elastixbook.com. Desde aquí el lector podrá acceder al libro en formato HTML.

¿Dónde adquirir este libro?

La versión impresa, tanto como la versión digital, pueden ser adquiridas a través de Lulu.com. Un hipervínculo está disponible en http://www.elastixbook.com.

Feedback

Como siempre, cualquier sugerencia será bien recibida. Que el lector no dude en escribir un email a elastixbook@palosanto.com

17

Plan de marcado avanzado

Olvidar lo malo también es tener memoria

-- José Hernandez en su obra -Martín Fierro-

17.1 Introducción

Aunque la mayoría de configuraciones telefónicas en Elastix pueden realizarse a través de la interfaz Web y no es necesario tocar los archivos de texto donde reside el plan de marcado, a nivel del ingeniero de soporte es necesario conocer las entrañas de nuestro sistema para realizar configuraciones complejas.

En el volumen 1 exploramos brevemente el plan de marcado (dialplan) de Asterisk explicando conceptos básicos como contextos, aplicaciones y variables. En este capítulo avanzaremos más y explicaremos conceptos adicionales que nos permitirán leer y escribir plan de marcado con más facilidad.

17.2 Manipulación de variables

Eliminación de dígitos al inicio y final de una variable

En ocasiones necesitaremos modificar una variable como ${EXTEN} y eliminar algunos dígitos al principio del número ya que estos muchas veces son prefijos telefónicos. Por ejemplo, si queremos marcar a través de un proveedor VoIP que termina llamadas exclusivamente en USA puede ser que sea necesario que el número telefónico deba ser enviado sin el prefijo 001 con el que fue marcado desde un teléfono interno.

Este tipo de cosas se logran de manera sencilla usando la sintaxis apropiada que nos permite eliminar estos dígitos iniciales.

La sintaxis usada para eliminar dígitos al inicio y/o al final de una variable es ${NOMBRE_VARIABLE:x:y}

Donde -x- representa el número de dígitos que se eliminarán al principio de la variable y -y- representa el número de dígitos que se extraerán de dicha variable.

Por ejemplo, supongamos que originalmente la variable ${EXTEN} contiene el número telefónico 123456789. Por lo tanto la expresión ${EXTEN:2:4} nos devolverá el número 3456. Es decir que se eliminaron 2 (x) dígitos al principio y el número devuelto debe contener 4 (y) dígitos.

Si se omite -y- en la expresión (lo cual es el caso más común) entonces se asume que se devolverán todos los restantes dígitos contenidos en la variable. En el ejemplo del número telefónico anterior con la expresión ${EXTEN:2} obtendríamos 3456789.

Concatenación de variables

Para concatenar dos o mas variables simplemente debemos escribirlas juntas. Por ejemplo, para concatenar las variables VAR1, VAR2 y VAR3 podríamos hacer algo como lo siguiente.

exten => s,n,SetVar(VAR_CONCAT=${VAR1}${VAR2}${VAR3})

Expresiones

Una expresión es una combinación de variables y operadores que producen un resultado. Un uso común de una expresión es el de realizar operaciones matemáticas como por ejemplo sumar dos valores. Una expresión tiene la siguiente sintaxis.

$[expresión]

Por ejemplo, para sumar dos variables llamadas VAR1 Y VAR2 podemos utilizar la expresión $[${VAR1} + ${VAR2}]

Operadores

Existen operadores de diferentes tipos como booleanos, matemáticos, de comparación y para manipulación de expresiones regulares.

Operador | Descripción
Booleanos
expr1 | expr2 | Operador OR. Retorna expr1 en caso de que expr1 contenga una cadena no-vacía o diferente de cero. Caso contrario retorna expr2.
expr1 & expr2 | Operador AND. Retorna expr1 siempre y cuando tanto expr1 como expr2 contengan cadenas no-vacías o diferentes de cero. Caso contrario retorna cero.
!expr | Operador de complemento.
Para comparar
expr1 = expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
expr1 != expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
expr1 < expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
expr1 > expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
expr1 <= expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
expr1 >= expr2 | Devuelve 1 si la comparación es cierta y 0 si es falsa
Matemáticos
expr1 + expr2 | Suma dos valores
expr1 - expr2 | Resta dos valores
- expr | Niega un valor
expr1 * expr2 | Multiplica dos valores
expr1 / expr2 | Divide un valor para otro
expr1 % expr2 | Devuelve el módulo de un valor para otro
Para manipular expresiones regulares
expr1 : regexp | Compara expr1 contra una expresión regular contenida en regexp. La comparación asume un carácter de inicio de cadena ^ implícito al inicio de regexp.
expr1 =~ expr2 | Similar al operador anterior excepto que no se asume un carácter de inicio de cadena implícito.

Sintaxis condicional

Cuando se necesita evaluar una expresión y tomar una decisión dependiendo del resultado de dicha evaluación, podemos usar lo que se llama sintaxis condicional y que mostraremos a continuación.

expresión?destino1:destino2

Es decir que si la expresión es verdadera se retorna destino1 y si es falsa se retorna destino2.

Esta sintaxis es la usada por aplicaciones como GotoIf.

17.3 Macros

Las macros no son otra cosa que aplicaciones definidas por el usuario. Una de las grandes ventajas de esto es que nos permiten reutilizar código de plan de marcado.

Para definir una macro simplemente escribimos el código de plan de marcado como si fuera un contexto cualquiera con el cuidado de que el nombre de este contexto debe empezar con la palabra -macro- seguida de un guión y del nombre de nuestra macro. Por ejemplo:

[macro-nohacenada]

exten => s,1,NoOp(No se hace nada)

Para invocar la macro lo hacemos a través de una aplicación especial llamada también Macro, la cual tiene la siguiente sintaxis.

Macro(nombremacro,arg1,arg2…)

Como vemos, la aplicación Macro toma como primer parámetro el nombre de la macro y luego los argumentos que la macro pueda tener.

Si queremos que nuestra macro manipule argumentos podemos acceder a ellos automáticamente a través de las variables ${ARG1}, ${ARG2}, ${ARG3}, etc

Por ejemplo, para invocar la macro que creamos antes podemos proceder de la siguiente manera.

exten => s,n,Macro(nohacenada)

Veamos a continuación la definición de una macro muy usada en el plan de marcado propuesto por FreePBX y que sirve para colgar una llamada.

; What to do on hangup.

[macro-hangupcall]

exten => s,1,ResetCDR(w)

exten => s,n,NoCDR()

Nota: La macro anterior es incluida en una versión vieja de FreePBX, pero se ha decidido dejarla aquí por razones didácticas. La actual macro-hangupcall es mucho más compleja que la mostrada aquí.

Variables disponibles en la macro

Aparte de los argumentos del tipo ${ARGn} existen otras variables disponibles en el contexto de una macro. Estas variables son las siguientes.

Nombre variable | Descripción
${MACRO_CONTEXT} | El contexto de la extensión desde donde se llamó a la macro
${MACRO_EXTEN} | La extensión desde donde se llamó a la macro
${MACRO_PRIORITY} | La prioridad en la extensión donde se llamó a la macro

Otro ejemplo de macro

Un ejemplo de macro muy didáctico y sencillo, aunque probablemente poco útil en la vida práctica, es el de un sumador que nos permita reproducir en audio la suma de dos números. A continuación la macro.

[macro-suma]

exten => s,1,SetVar(TOTAL=$[ ${ARG1} + ${ARG2} ])

exten => s,n,SayNumber(${TOTAL})

17.4 AstDB

Asterisk cuenta con una pequeña base de datos a la que se puede acceder desde el plan de marcado a través de algunas aplicaciones destinadas para este fin. Esta base de datos, llamada AstDB, está basada en el motor Berkeley DB versión 1, que básicamente es una implementación muy sencilla de una base de datos con reducida funcionalidad, pero muy útil para almacenar y recuperar valores desde el plan de marcado.

Nota: En versiones futuras de Asterisk se prevee que se utilice SQLite como motor de base de datos.

AstDB reside en /var/lib/asterisk/astdb.

En esencia AstDB permite agrupar información en -familias-, que no son otra cosa que contenedores (o categorías), que nos servirán para agrupar la información. En cada familia tendremos pares conformados por dos elementos llamados clave y valor; donde cada clave es un nombre único dentro de cada familia. Dos familias importantes que son mantenidas por FreePBX son AMPUSER y DEVICE.

Aplicaciones para administrar AstDB

A continuación algunas aplicaciones que nos servirán para administrar AstDB desde el plan de marcado.

Aplicación | Descripción
DBdel | Elimina una clave de la base de datos
DBdeltree | Elimina una familia de la base de datos
DBget | Obtiene un valor de la base de datos. Para esto debemos proporcionarle la clave correspondiente.
DBput | Almacena un valor en la base de datos

17.5 El plan de marcado de FreePBX

El plan de marcado escrito por FreePBX reside principalmente en los archivos extensions.conf y extensions_additional.conf. El primero contiene información fija que no cambia cuando se hacen cambios desde la interfaz Web de FreePBX y el segundo contiene información variable que sí cambia cuando se hacen cambios desde la interfaz Web.

extensions.conf

El archivo extensions.conf es donde Asterisk buscará primero el plan de marcado. Este archivo a su vez incluye el extensions_additional.conf.

Podríamos decir a nivel general que este archivo se encuentra dividido en dos tipos de contextos: macros y puntos de acceso.

Macros de apoyo

El primer tipo constituye un conjunto de macros que sirven de apoyo en la codificación del plan de marcado y que permiten la reutilización de código y organización del mismo. Algunas de las macros más importantes que podemos encontrar aquí son:

Macro | Descripción
[macro-dial] | Se usa para timbrar a una o más extensiones. Toma como argumentos las variables $DIAL_TIMER, $DIAL_OPTIONS, $EXT1, $EXT2, $EXT3, etc.
[macro-exten-vm] | Timbra a una extensión y si dicha extensión está ocupada o no contesta envía la llamada al casillero de voz (voicemail).
[macro-vm] | Llama sistema de casillero de voz y permite acceder a un IVR personal.
[macro-rg-group] | Timbra grupos de teléfonos (ring groups).
[macro-outisbusy] | Informa al cliente que los canales de salida están ocupados.
[macro-hangupcall] | Cuelga una llamada.
[macro-dialout] | Permite marcar hacia afuera y elimina el prefijo.
[macro-record-enable] | Revisa si una llamada tiene habilitada la grabación de llamadas y procede a la grabación de ser el caso.

Puntos de acceso al dialplan

El segundo tipo de contextos está constituido por lo que podríamos llamar puntos de acceso al plan de marcado o contextos -from-. Es decir los lugares por donde la comunicación se inicia, ya que una llamada podría originarse en diferentes lugares, como extensiones internas, troncales SIP, dispositivos DAHDI, entre otros.

Contexto -from- | Descripción
[from-pstn] | Por aquí ingresan las llamadas desde la PSTN o también desde una troncal VoIP. Este contexto es equivalente a from-trunk; de hecho este último es un alias de from-pstn.
[from-sip-external] | Responde a usuarios SIP externos un mensaje de congestión y luego cuelga
[from-internal] | Por aquí ingresan las llamadas realizadas desde extensiones internas
[from-zaptel] | Para llamadas que ingresan desde dispositivos DAHDI

extensions_additional.conf

Prácticamente cada entidad o característica configurable desde la interfaz Web de FreePBX está especificada aquí. Por ejemplo, en este archivo se definen los servicios, las salas de conferencia, las extensiones mismas, los IVRs, los accesos DISA, las rutas salientes, las rutas entrantes, las colas, los ring-groups, entre otros.

En conclusión se podría decir que este archivo contiene los parámetros configurables por el usuario. Es el archivo donde FreePBX hace su mayor trabajo.

Trataremos de dar una idea al lector de qué significan los diferentes contextos que aquí se pueden encontrar. En ocasiones especificaremos sólo el prefijo con el que empieza el nombre del contexto para agrupar mejor y utilizaremos el carácter * como comodín.

Contexto
Descripción

Globals
En el contexto globals (recordemos que se trata de un contexto de nombre reservado) se enlistan algunas variables que define internamente FreePBX para su correcto funcionamiento.

app-*
Este tipo de contextos corresponde a un servicio o aplicación como por ejemplo el servicio de dictado, el servicio de directorio telefónico, el servicio de acceso al voicemail, entre otros. Se encuentra en este archivo ya que el usuario en cualquier momento puede cambiar el número de acceso al servicio desde el menú -Feature Codes- de la interfaz Web del FreePBX.

ivr-*
Contiene la definición de un IVR. Al prefijo -ivr-- se le agrega un número que identifica internamente al IVR.

macro-*
Las macros de apoyo necesarias para simplificar el código. Una macro muy importante es la macro dialout-trunk que es donde se decide por cuál ruta saldrá una llamada.

ext-*

En estos contextos encontraremos cualquier cosa que pueda ser considerada un número de extensión. Tanto extensiones que correspondan a teléfonos o endpoints, como extensiones que podríamos denominar virtuales ya que no corresponden a teléfonos directamente relacionados con un usuario; como es el caso de cuartos de conferencia, colas, grupos de paging, entre otros, que son accesibles como si fueran números de extensión.

Un contexto de especial interés es ext-local que es donde se encuentran las extensiones internas o locales.

from-internal-additional
Este contexto es referenciado desde el contexto from-internal, que es un punto de acceso para extensiones locales definido en el archivo extensions.conf.

from-trunk-*
Aquí se definen las rutas entrantes.

outrt-*
Aquí se definen las rutas salientes.

outbound-allroutes
Aquí se enlistan todos los contextos que corresponden a rutas salientes. Es decir los que empiezan con -outrt--

17.6 Identificación de patrones de marcado

Si manipulamos el plan de marcado de Asterisk eventualmente necesitaremos identificar un patrón de marcado en lugar de una extensión o número telefónico específico.

Por ejemplo, supongamos que queremos identificar todos los números que inician con 00 (debido a que este es el prefijo arbitrario que usamos para marcar números internacionales) con el objeto de limitar la duración de las llamadas a estos destinos.

Nota: Algunas empresas suelen tener requerimientos similares al del ejemplo anterior como medida para controlar el consumo telefónico.

Por fortuna identificar patrones de marcado es una tarea sencilla debido a que Asterisk soporta identificación de patrones. Para identificar un patrón basta escribirlo en lugar del número de la extensión, precedido por el carácter guión bajo -_-. Veamos un ejemplo.

exten => _00.,1,NoOp(Esta es una llamada internacional)

Como podemos observar hemos escrito el patrón -_00.- en el lugar donde normalmente se escribe el número de extensión o número telefónico marcado. De este modo estamos identificando todos los números que inician con el prefijo 00.

Seguramente el lector habrá notado el punto al final del patrón de marcado. Este punto no es otra cosa que un carácter comodín que significa -uno o más caracteres-. Es decir, que luego del prefijo 00 pueden venir uno o más dígitos adicionales.

Existen también otros comodines que se pueden utilizar como parte de un patrón de marcado. En la siguiente tabla se enumeran los comodines y otras cadenas de caracteres que pueden ser utilizado como parte de un patrón de marcado.

Patrón | Descripción
X | Representa cualquier dígito de 0-9
Z | Representa cualquier dígito de 1-9
N | Representa cualquier dígito de 2-9
[a-z] | Representa una letra minúscula cualquiera
[A-Z] | Representa una letra mayúscula cualquiera
. | Representa uno o más caracteres

A continuación algunos ejemplos de patrones de marcado.

Identificación de número 1800:

exten => _1800.,1,NoOp(Ejemplo de 1800)

Identificación de número NANP (North American Numbering Plan) local o de 7 dígitos. Por ejemplo 235 5678.

exten => _NXXXXXX,1,NoOp(Ejemplo de NANP de 7 digitos)

Ejemplo de limitación de duración de llamada usando patrones de marcado

Al principio de este apartado mencionamos como ejemplo la limitación de la duración de llamadas internacionales, que en nuestro caso contenían el prefijo 00. A continuación el plan de marcado necesario para llevar a cabo este fin.

[custom-internacionales-salientes]

exten => _00.,1,Answer

exten => _00.,n,Set(TRUNK_OPTIONS=${TRUNK_OPTIONS}L(900000:720000:60000))

exten => _00.,n,Set(LIMIT_PLAYAUDIO_CALLEE=yes)

exten => _00.,n,Set(LIMIT_TIMEOUT_FILE=beep)

exten => _00.,n,Set(LIMIT_WARNING_FILE=beep)

exten => _00.,n,Goto(outbound-allroutes,${EXTEN},1)

Como podemos ver hemos creado un contexto llamado custom-internacionales-salientes para organizar mejor el plan de marcado. Este contexto se debe crear en el archivo /etc/asterisk/extensions_custom.conf, que es un archivo que no es sobre-escrito por FreePBX.

Si analizamos el plan de marcado anterior notaremos que todas las líneas inician con el patrón -_00.- lo que identifica a las llamadas internacionales en nuestro caso.

Para limitar la llamada modificaremos ciertas variables globales. La más importante es la variable TRUNK_OPTIONS. Esta variable contiene las opciones del comando Dial que se utilizarán al colocar una llamada.

La opción del comando Dial que nos interesa modificar es la opción L, que es la que sirve para limitar el tiempo de una llamada. La opción L recibe 3 argumentos separados por el carácter dos puntos -:-. La sintaxis del parámetro L es la siguiente.

L(tiempo_limite:tiempo_warning:tiempo_intervalo_recordatorio)

Donde,

tiempo_limite es el tiempo máximo de la llamada en milisegundos. Una vez alcanzado este tiempo la llamada se colgará.

tiempo_warning es el tiempo en que se alertará de manera audible al usuario para que sepa que pronto se colgará la llamada. Como resulta lógico suponer este tiempo debe ser menor al especificado en el argumento tiempo_limite. Este argumento también se encuentra en milisegundos.

tiempo_intervalo_recordatorio indica cada cuántos milisegundos, luego del tiempo_warning se volverá a repetir la alerta audible para que el usuario conozca que la llamada se colgará.

En nuestro ejemplo hemos usado 15 minutos (900000 milisegundos) como tiempo_limite, 12 minutos (720000 milisegundos) como tiempo_warning y luego de los 12 minutos alertamos al usuario cada minuto (60000 milisegundos).

Nota: Para que el ejemplo anterior funcione el lector debe recordar incluir el contexto custom-internacionales-salientes dentro del contexto from-internal-custom. De otro modo nuestro contexto quedará desconectado del flujo principal del plan de marcado.

17.7 Etiquetas de prioridad

Las etiquetas nos permitirán marcar (o etiquetar) ubicaciones dentro del plan de marcado. De este modo podemos organizar mejor nuestro código y utilizar estas marcas como referencias desde aplicaciones como Goto() o GotoIf().

Una etiqueta no es más que una palabra entre paréntesis escrita a la derecha de una prioridad. Para entender mejor veamos el siguiente ejemplo.

exten => 444,n(etiqueta),NoOp(Esta línea contiene una etiqueta)

Como se puede apreciar en el ejemplo anterior, hemos marcado dicha línea con la etiqueta llamada -etiqueta-.

Las etiquetas son muy útiles dentro del plan de marcado, para ilustrarlo veamos el siguiente código.

exten => s,1,GotoIf($["${CALLERID(num)}" = "2222"]?prohibited)

exten => s,n,Answer

exten => s,n,Playback(hello-you-are-welcome)

exten => s,n(prohibited),Hangup()

El ejemplo anterior cuelga inmediatamente cualquier llamada que provenga del número 2222, caso contrario le reproduce un audio de bienvenida. Como se puede observar se ha utilizado la etiqueta -prohibited- como destino en caso de que la aplicación GotoIf determine que se trata del numero 2222.

17.8 Algunos tips útiles

A continuación algunas preguntas comunes y trucos son de mucha ayuda al momento de manipular el plan de marcado.

Cómo verificar si una variable se encuentra vacía?

No existe en el plan de marcado una función como isNull, isEmpty o cosa por el estilo que nos permita verificar si una variable se encuentra vacía, pero podemos valernos de la aplicación LEN para este fin y comparar su salida contra cero. Veamos un ejemplo de esto.

exten => s,1,GotoIf($[${LEN(${VARIABLE_TEST})} > 0]?destino)

Cómo obtener la fecha actual en el plan de marcado?

Para obtener la fecha actual podemos hacer uso de la variable ${EPOCH} que contiene un timestamp del instante actual. Para traducir este timestamp a una fecha más humanamente legible podemos utilizar la función STRFTIME. Veamos un ejemplo de esto tomado del archivo extensions.conf

[macro-record-enable]

exten => s,1,GotoIf($[${LEN(${BLINDTRANSFER})} > 0]?2:4)

exten => s,2,ResetCDR(w)

exten => s,3,StopMonitor()

exten => s,4,AGI(recordingcheck,${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)},${UNIQUEID})

exten => s,5,Noop(No recording needed)

exten => s,999,MixMonitor(${CALLFILENAME}.wav)

Cómo proceder si quiero realizar cambios en el extensions.conf?

No es recomendado cambiar el archivo extensions.conf debido a que FreePBX lo sobre-escribirá durante una operación de actualización. ¿Qué hacer entonces?

Existe un archivo llamado extensions_override_freepbx.conf que puede ser utilizado para este fin. Si un nombre de contexto dentro de este archivo coincide con uno definido en el extensions.conf entonces dicho contexto será sobrescrito por el contenido en extensions_override_freepbx.conf.

Por lo tanto si se quiere modificar un determinado contexto del archivo extensions.conf lo recomendable es escribir nuestra nueva versión de dicho contexto en el extensions_override_freepbx.conf.

Cómo hacer que los cambios realizados en el plan de marcado tomen efecto?

Luego de modificar manualmente el plan de marcado seguramente vamos a querer que nuestros cambios tomen efecto. Para que Asterisk recargue el plan de marcado debemos ejecutar el siguiente comando desde el CLI.

pbx*CLI> dialplan reload

18

Correo electrónico en Elastix

Todo derecho que no lleve consigo un deber, no merece que se luche por defenderlo

-- Mahatma Gandhi

18.1 Arquitectura del sistema de email

Un sistema de correo electrónico está conformado por varios componentes. Los principales son el MUA (Mail User Agent), el MTA (Mail Transfer Agent) y el MDA (Mail Delivery Agent).

Componentes de un sistema de correo electrónico

El MUA no es otra cosa que el programa que utiliza el usuario para gestionar su correo electrónico y generalmente reside en el computador del cliente, por ejemplo el Microsoft Outlook, el Mozilla Thunderbird, entre otros. También existen situaciones en las que el MUA reside en el mismo servidor, como es el caso del servicio de Webmail.

El MTA es quién, mediante protocolo SMTP, recibe los correos electrónicos procedentes de los MUAs y se encarga de hacerlos llegar a los servidores de destino. También recibe correos electrónicos de otros servidores MTA. Hay que tener en cuenta que la principal función de un MTA es -hablar- protocolo SMTP con el objetivo de transferir mensajes de correo electrónico desde y hacia otros servidores MTA de una manera confiable.

Una vez que el MTA recibe por SMTP un correo electrónico de otro servidor MTA su tarea está prácticamente concluida. El MTA no se encarga de los pormenores relacionados con los buzones de los usuarios; es más, el MTA no sabe ni en qué lugar del disco duro del servidor debe almacenar los correos electrónicos; tampoco sabe nada acerca de las credenciales de acceso de los usuarios. Es por esto que luego de recibido el correo electrónico procedente de otro servidor, el MTA se lo entrega al MDA para que realice el resto del trabajo de entrega local.

El MDA es el software encargado de administrar los buzones locales de correo electrónico de los usuarios y de -hablar- otros protocolos como POP e IMAP. Estos protocolos están diseñados para entregar el correo electrónico a los MUAs. El MDA muchas veces reside en el mismo servidor que el MTA y en su conjunto ambos componentes son denominados como -servidor de correo electrónico-.

Hasta aquí es importante notar que un MUA envía el correo electrónico a través de protocolo SMTP, pero recibe correo electrónico a través de POP o IMAP según se haya escogido en la configuración.

Una vez explicada la arquitectura básica de un sistema de correo electrónico, aterrizaremos estos conceptos para Elastix. Elastix incluye un potente sistema de correo electrónico basado en componentes de código abierto.

Elastix utiliza como MTA al software denominado Postfix y como MDA a Cyrus IMAP. Este último provee de los servicios de POP e IMAP. Así mismo, Elastix incluye una interfaz de Webmail llamada RoundCube, la misma que puede ser usada como MUA.

18.2 Configurando el sistema de correo electrónico de Elastix

Elastix facilita y simplifica las tareas de configuración de un servidor de correos. Utilizando la interfaz Web administrativa se puede tener el servicio de correo electrónico completamente funcional en unos cuantos minutos siguiendo el procedimiento detallado a continuación.

Primero se debe elegir el menú -Email- y luego la opción -Domains-. A continuación aparecerá un listado de los dominios locales configurados. En Elastix el servicio de correo electrónico es multi-dominio, por lo que se lo puede utilizar para recibir mensajes para varios dominios diferentes. Inicialmente la lista estará en blanco.

Listado de dominios

Para crear un nuevo dominio se utiliza el botón -Create Domain-, con lo cual aparece una nueva pantalla en la que se debe ingresar el nombre del nuevo dominio.

Creando un nuevo dominio

Luego se guarda la acción utilizando el botón -Save- y se retornará al listado de dominios donde aparecerá el nuevo dominio que se acaba de crear.

El listado de dominios muestra ahora el dominio creado

El siguiente paso es crear las cuentas de correo electrónico. Para ello, en el mismo menú -Email- se debe elegir la opción -Accounts-. En esta sección aparecerá una lista desplegable donde se debe seleccionar el dominio con cuyas cuentas se trabajará y se debe presionar el botón -Show- para mostrar las cuentas existentes en dicho dominio.

Listado de cuentas de email. Aún no se selecciona un dominio de la lista.

Para crear una cuenta nueva, se debe seleccionar el dominio en la lista desplegable y luego utilizar el botón -Create Account-. Aparecerá una pantalla donde se deben ingresar los datos básicos de la cuenta de correo.

Creando una nueva cuenta de correo electrónico

Una vez llenados todos los campos se procede a guardar la cuenta con el botón -Save- e inmediatamente se retornará al listado de las cuentas creadas para el dominio seleccionado anteriormente. Se debe repetir este procedimiento para crear todas las cuentas de correo necesarias.

Cuentas de email para el dominio creado

Es importante resaltar el verdadero nombre de la cuenta creada. En el ejemplo anterior se creó la dirección de correo -example@elastixbook.com- y como es lógico, el lector puede suponer que el nombre de usuario es la parte que antecede al carácter arroba. Es decir la palabra -example-. Sin embargo esto no es así ya que como se puede ver en el listado de cuentas, el nombre real es toda la cadena de texto -example@elastixbook.com-. No se trata de un error, en Elastix el nombre de usuario incluye también el nombre de dominio y luce como una dirección de correo electrónico. Esto es debido a que al tratarse de un sistema con soporte multi-dominio pueden existir varias cuentas llamadas -example- pertenecientes a los diferentes dominios. De esta manera pueden existir sin problema direcciones como -example@elastixbook.com- y -example@example.com-.

Si alguna de las cuentas de correo que han sido creadas será utilizada en un cliente de correo como Microsoft Outlook, Mozilla Thunderbird u otro similar, se le deberá indicar al servidor cuales son las direcciones de red a las que se les permitirá enviar correos hacia dominios que no han sido configurados como locales. Este comportamiento de permitir a un equipo enviar vía SMTP correos electrónicos a dominios externos se conoce como RELAY. Por tanto es necesario que agreguemos nuestra red al listado de redes que están permitidas de hacer RELAY. Esto se configura en el menú -Email -> Relay-.

Configuración de las redes que pueden hacer RELAY

En esta lista se puede agregar las nuevas direcciones de red, una por línea, asegurándose de que se especifique la respectiva máscara de red. También es importante recordar que la dirección de localhost (127.0.0.1/32) deberá estar siempre listada, de lo contrario se pueden presentar problemas con ciertas funcionalidades de Elastix como voicemail, fax-to-email, entre otras.

El siguiente paso es comprobar el funcionamiento del servicio, para ello se puede utilizar una de las cuentas creadas y configurarla en un cliente de correo electrónico. Sin una manera sencilla de hacerlo es utilizar la interface de Webmail que viene incluida con Elastix y se llama RoundCube. Para acceder a este servicio debemos dirigirnos al menú -Email -> Webmail- e ingresar los datos de acceso de una de las cuentas creadas anteriormente.

Ingreso al Webmail provisto a través de RoundCube

Si el ingreso es exitoso veremos una pantalla como la siguiente.

Pantalla principal del Webmail

Para redactar un mensaje nuevo, se debe utilizar el ícono de una hoja de papel con un lápiz amarillo.

Para redactar un nuevo mensaje

El formulario para escribir un mensaje es bastante sencillo e intuitivo. Luego de redactar el correo, se lo envía con el botón -Enviar ahora el mensaje-.

Escribiendo un nuevo email

Los mensajes nuevos en la bandeja de entrada lucen así:

Nuevo mensaje en la bandeja de entrada

18.3 Configuraciones a bajo nivel

Como se mencionó anteriormente, Elastix usa como MTA a Postfix que es un sistema de correo electrónico sumamente potente, seguro y por sobre todo flexible para permitir innumerables configuraciones avanzadas. Se puede obtener más información acerca de Postfix en el sitio Web oficial www.postfix.com, así mismo es común utilizar un buscador de Internet para encontrar documentación respecto a configuraciones específicas.

Una necesidad recurrente en sistemas de correo electrónico es la configuración de un Smart Relay, que consiste en indicarle al MTA (Postfix) que todos los mensajes que no están destinados a dominios locales se los envíe a un servidor específico que se encargará a su vez de transferirlo a los servidores de destino. Esto es de gran utilidad cuando el ISP (Proveedor de Servicios de Internet) ha restringido las conexiones SMTP salientes y solo permite envíos a traves de su propio servidor SMTP, algunas veces llamado SMTP Gateway. En Postfix esta opción se llama -relayhost-.

Postfix posee un archivo de configuración principal llamado -/etc/postfix/main.cf-, en el cual se especifican las diferentes opciones del mismo. Este archivo no muestra todas las opciones, sino solamente las más usuales y aquellas que han sido modificadas de su valor por defecto. Para ver todas las opciones de configuración actuales de Postfix se debe utilizar el comando postconf, sin embargo, la salida es muy larga puesto que tiene cerca de 525 opciones, por lo que se recomienda utilizarlo en conjunto con el comando grep. Por ejemplo, para el caso del Smart Relay, se quiere verificar cual es el valor actual de la opción -relayhost-:

Ejecución del comando postconf

Para cambiar una opción del Postfix se debe editar el archivo -/etc/postfix/main.cf- y buscar la opción requerida, en caso de que no exista se la puede agregar. Se recomienda que cuando se agrega una línea se lo haga en la parte final del archivo pero antes de los comentarios que dicen:

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

#Ingresado por yb-webadmin

En el caso del ejemplo del Smart Relay, se configurará la opción -relayhost- para que tenga el valor -smtp-gw.myisp.net-, para ello se agregará la línea:

relayhost = [smtp-gw.myisp.net]

Archivo /etc/postfix/main.cf

Luego de editado el archivo -/etc/postfix/main.cf- se debe aplicar los cambios utilizando uno de los siguientes comandos:

# service postfix reload

# service postfix restart

18.4 Luchando contra el SPAM

Elastix también provee un filtro contra SPAM que, cuando está activado, verifica todos los mensajes que ingresan al servidor de correos y les asigna un puntaje dependiendo de ciertas características. Si el mensaje obtiene un puntaje superior a lo que se conoce como -Nivel de Rigurosidad-, entonces el mensaje es marcado, es decir que se agregan cabeceras indicando que es SPAM y también se le agrega en el asunto la palabra -[SPAM]-

Es muy fácil configurar los clientes de correo para aplicar filtros y reglas que redireccionen los SPAM a otras carpetas o incluso los eliminen.

Para activar esta característica en el Elastix se debe elegir la opción -Antispam- en el menú -Email- y seleccionar -Active-. En esta pantalla también se puede cambiar el nivel de rigurosidad, se debe recordar que mientras más bajo es el número escogido, más alta es la rigurosidad del filtro.

Configuración del filtro AntiSPAM

Configuración del filtro AntiSPAM

No es recomendables especificar un nivel de rigurosidad menor a 3, puesto que se incrementarían los casos de falsos positivos, que no son otra cosa que mensajes válidos que han sido catalogados como SPAM de manera errónea.

18.5 Instalando antivirus

En Elastix se podría instalar cualquier antivirus que trabaje con Postfix, para lo cual habrá que seguir las instrucciones provistas por el respectivo fabricante. A continuación se detalla el procedimiento para instala ClamAV que es un antivirus gratuito. Se utilizará el paquete ClamSMTP para integrarlo con el Postfix.

Lo primero que hay que hacer es instalar el paquete rpm-build que permitirá generar el RPM del clamsmtp:

# yum install rpm-build

Luego de debe descargar la versión más reciente del SRPM del clamsmtp desde el sitio web http://www.inet.lt/clamsmtp/

# wget http://www.inet.lt/clamsmtp/clamsmtp-1.10-1.src.rpm

Generar el respectivo RPM, el paquete resultante será almacenado en la carpeta /usr/src/redhat/RPMS/i386/.

# rpmbuild --rebuild clamsmtp-1.10-1.src.rpm

Desde el sitio Web http://dag.wieers.com/rpm/packages/clamav/ se debe descargar las versiones más recientes de clamav, clamd y clamav-db para CentOS 5:

# wget http://dag.wieers.com/rpm/packages/clamav/clamav-0.92.1-1.el5.rf.i386.rpm

# wget http://dag.wieers.com/rpm/packages/clamav/clamd-0.92.1-1.el5.rf.i386.rpm

# wget http://dag.wieers.com/rpm/packages/clamav/clamav-db-0.92.1-1.el5.rf.i386.rpm

Finalmente se deben instalar los 3 paquetes:

rpm -Uvh clamav-0.92.1-1.el5.rf.i386.rpm clamav-db-0.92.1-1.el5.rf.i386.rpm /usr/src/redhat/RPMS/i386/clamsmtp-1.10-1.i386.rpm

Se debe crear manualmente la carpeta -/var/run/clamav/-:

mkdir /var/run/clamav/

Editar el archivo de configuración de -/etc/clamsmtpd.conf- y cambiar las siguientes líneas:

ClamAddress: /var/run/clamav/clamd.sock

#User: clamav

Por estas dos:

ClamAddress: /tmp/clamd.sock et

User: clamav

Una vez instalado se debe iniciar los servicios del clamsmtp y clamd:

# service clamd start

# service clamsmtp start

# chkconfig -level 3 clamd off

# chkconfig -level 3 clamsmtp off

Luego hay que configurar el Postfix para que utilice el paquete instalado. Se debe editar el archivo -/etc/postfix/main.cf- y agregar la siguiente línea:

content_filter = scan:[127.0.0.1]:10025

También se debe editar el archivo -/etc/postfix/master.cf- y agregar las siguientes líneas:

# AV scan filter (used by content_filter)

scan unix - - n - 16 smtp

-o smtp_send_xforward_command=yes

-o smtp_enforce_tls=no

# For injecting mail back into postfix from the filter

127.0.0.1:10026 inet n - n - 16 smtpd

-o content_filter=

-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks

-o smtpd_helo_restrictions=

-o smtpd_client_restrictions=

-o smtpd_sender_restrictions=

-o smtpd_recipient_restrictions=permit_mynetworks,reject

-o mynetworks_style=host

-o smtpd_authorized_xforward_hosts=127.0.0.0/8

Y finalmente se debe reiniciar el servicio del Postfix:

# service postfix restart

19

Mensajería Instantánea

Nunca he encontrado una persona tan ignorante que no se pueda aprender algo de ella

-- Galileo Galilei

Elastix basa su funcionalidad de mensajería instantánea en el software Openfire que funciona en base al protocolo XMPP (originalmente conocido como Jabber).

19.1 Protocolo XMPP (Jabber)

El hecho de que se utilice XMPP en Elasix nos da una gran ventaja, debido a que XMPP es un estándar y actualmente existen muchas aplicaciones cliente compatibles con este protocolo. En resumen, tenemos muchas opciones al momento de escoger un cliente de mensajería interna.

XMPP es un protocolo probado, abierto, extensible, generalmente aceptado, seguro y basado en XML. Estas son algunas de las razones por las que fue escogido para formar parte de Elastix.

No es el objetivo de este libro explicar el protocolo XMPP. Sin embargo, es recomendable conocer un poco más de él por lo que dejamos al lector con algunos vínculos interesantes.

http://www.jabber.org (Sitio Web oficial del protocolo XMPP)

http://en.wikipedia.org/wiki/Jabber (Página de Jabber en Wikipedia)

http://www.jabberes.org (Sitio Web en español)

19.2 Openfire

Openfire es un completo sistema de mensajería instantánea que nos permite disponer de un servicio de mensajería instantánea rico en características como transferencia de archivos, mensajes broadcast, integración con telefonía, integración con otros gateways IM, entre otras.

Openfire se encuentra escrito en Java y su funcionalidad puede ser extendida en base a plugins, los cuales pueden ser descargados del sitio Web del fabricante (www.igniterealtime.org). Además cuenta con una amigable interfaz Web de administración que nos permite realizar las tareas administrativas de una manera intuitiva.

Características destacables

A continuación algunas de las características más interesantes.

Interfaz amigable de administración Web

Funcionalidad expandible a través de plugins

Posibilidad de integración con Asterisk

Interacción con otras redes de mensajería instantánea como Gtalk, Yahoo Messenger, ICQ, entre otros

Soporte para mensajes broadcast

Transferencia de archivos

Puede guardar histórico de conversaciones

Soporte para clustering

Los usuarios pueden ser obtenidos de una base de datos LDAP

Permite crear diferentes grupos de trabajo

19.3 Usando Openfire en Elastix

Openfire viene por omisión desactivado en Elastix. Esto se hace así debido a que si el usuario no lo necesita activar explícitamente es preferible que quede apagado para que no consuma recursos innecesariamente.

Activación de Openfire

Si lo queremos activar debemos dar clic en el vínculo que se muestra en la siguiente figura.

Pantalla de activación de Openfire

Lo primero que veremos es una pantalla donde se nos pide escoger un idioma.

Pantalla de selección de idioma en configurador de Openfire

Luego debemos especificar el nombre de dominio del servidor. Esto debería ser lo mismo que se configuró en los parámetros de red.

Configuración de nombre de dominio en el configurador de Openfire

A continuación escogemos la base de datos donde Openfire almacenará la configuración y la información que debe ir almacenando conforme su funcionamiento. Podemos usar un motor de base de datos Standard (Ej. MySQL) o podemos usar una base de datos embebida que trae Openfire y que nos facilita las tareas de configuración si es que no vemos ninguna ventaja en usar un motor Standard.

En la mayoría de los casos es conveniente elegir la base de datos embebida debido a que esto simplifica el proceso de configuración sin perder funcionalidad.

A continuación configuramos el lugar donde se almacenarán los usuarios de Openfire. Una opción muy interesante aquí es el soporte LDAP.

Configuración del sistema de almacenamiento de usuarios de Openfire

Para terminar configuramos la cuenta de administración de Openfire. Con esta cuenta podremos ingresar a la interfaz Web de Openfire y administrar sus parámetros de funcionamiento.

Configuración de cuenta de administrador

Interfaz Web de administración de Openfire

Una vez activado Openfire ya podemos ingresar a la interfaz de administración, crear algunos usuarios y comenzar a usar mensajería instantánea en Elastix. Lo primero que haremos será ingresar a la interfaz como administrador usando la clave configurada previamente.

Ingreso a la consola de administración de Openfire

Una vez que ingresamos como administrador veremos una pantalla similar a la siguiente.

Pantalla inicial en la interfaz Web de administración de Openfire

Lo primero que vamos a hacer será crear un nuevo usuario de mensajería instantánea. Esto lo podemos hacer en el menú -Users/Groups -> Create New User-. Los parámetros a ingresar son bastante intuitivos y se muestra un ejemplo en la siguiente figura.

Creando un nuevo usuario de mensajería instantánea

Una vez creado el usuario ya éste se puede registrar desde su cliente de IM.

Integración de Openfire con Asterisk

Openfire cuenta con un plugin que nos permite integración con Asterisk.

Gracias a este plugin podemos efectuar algunas tareas de interacción telefónica desde el cliente de mensajería como por ejemplo generar una llamada, ser notificado cuando una llamada llega al teléfono o incluso poder ver si otro contacto se encuentra en medio de una llamada telefónica. Es por esto que el cliente de mensajería no puede ser cualquiera, para que la integración sea visible por el usuario. El plug-in funciona con el software cliente de mensajería llamado Spark, el cual también puede ser descargado gratuitamente desde el sitio Web de Openfire.

El plugin para integración con Asterisk recibe el nombre de Asterisk-IM y su instalación es muy sencilla. Nos dirigimos al menú -Plugins -> Available Plugins- y damos clic sobre el botón verde a la derecha de la fila correspondiente al plugin Asterisk-IM. En unos segundos estará activo.

Instalación del plugin Asterisk-IM desde la interfaz de administración de Openfire

Si el plugin se instaló correctamente veremos aparecer automáticamente un nuevo menú llamado Asterisk-IM. Desde aquí podremos configurar la integración de Openfire con Asterisk.

Configuración del plugin Asterisk-IM

Openfire se integra con Asterisk a través de AMI. Por lo tanto, antes de configurar el plugin Asterisk-IM tendremos que crear un usuario AMI para este fin, pues en algún momento de la configuración vamos a necesitar ingresar estos datos. Recordemos que los usuarios AMI se crean en el archivo /etc/asterisk/manager.conf. También podríamos utilizar el usuario que viene creado por omisión en Elastix. Es decir, el usuario admin, con clave elastix456

En todo caso para crear un nuevo usuario AMI podríamos agregar las siguientes líneas al manager.conf

[openfire]

secret = clavesecreta

displayconnects = yes

read = system,call,log,verbose,agent,user,config,dtmf

write = system,call,agent,user,config,command

Bueno, dicho lo anterior, iniciemos la configuración del plugin. Comencemos por habilitar el plugin seleccionando la opción -Enabled-.

En la sección -Configure Phone Manager- encontraremos algunos campos para configurar. No es necesario llenarlos todos, sin embargo es importante llenar el campo -Asterisk Context- con la palabra -default-. Este campo indica el contexto desde el cual se generarán las llamadas telefónicas desde el cliente de mensajería instantánea.

Hasta ahora nuestra configuración debe estar como la mostrada en la siguiente figura.

Avance de la configuración del plugin Asterisk-IM

Ahora damos clic donde dice -Add Server- para añadir a nuestro servidor Asterisk.

Aquí es donde ingresamos los datos de la cuenta AMI de la que hablamos anteriormente, es decir usuario y clave.

El parámetro Port debe llenarse con 5038, el cual es el puerto AMI por omisión. Supongo que se acordaban, ¿verdad? En Server Name podemos poner cualquier nombre que nos sirva para recordar al servidor, mientras que el Username será admin y el Password será la contraseña de administrador de Asterisk (la que se encuentra en el archivo /etc/asterisk/manager.conf).

Configuración de servidor AMI

Finalmente nuestra configuración debe lucir similar a la de la siguiente figura.

Final de la configuración general del plugin Asterisk-IM

En ocasiones, si se utiliza la opción de Base de datos interna, nuestro servidor recién añadido no aparecerá listado como se muestra en la figura anterior (a pesar de sí mostrarse el mensaje -Server created succesfully-). Esto puede corregirse simplemente ejecutando los siguientes dos comandos (dentro del shell Linux como usuario root):

perl -pi.bak -e 's/(.*serverName.*)/ serverName varchar(255) not null,/' /opt/openfire/plugins/asterisk-im/database/asterisk-im_hsqldb.sql

service openfire restart

Hemos terminado de realizar la configuración general del plugin pero nuestro trabajo no ha terminado aquí. Aun debemos asociar los usuarios de Openfire con las extensiones telefónicas creadas en Elastix.

Esto es lógico porque no existe manera de que Openfire sepa qué usuario de mensajería instantánea usa una extensión telefónica determinada. Por esto se lo debemos decir explícitamente en el menú -Asterisk IM -> Phone Mappings-.

Mapeo de usuarios de Openfire a extensiones de telefonía

¡Listo, una vez mapeadas las cuentas necesarias ya tendremos mensajería instantánea integrada con telefonía!

20

Fax en Elastix

El aspecto más triste de la vida actual es que la ciencia gana en conocimiento más rápidamente que la sociedad en sabiduría

-- Isaac Asimov

20.1 HylaFAX e IAXModem

Elastix usa una particular combinación de software para el manejo de documentos de fax. En esta combinación hay dos paquetes de software que destacan; estos son HylaFAX e IAXModem. Los dos interactúan entre sí de tal manera que Asterisk pueda recibir un documento de FAX y enviarlo a una extensión IAX virtual donde reside IAXModem, quien a su vez lo remite a HylaFAX quien finalmente convierte el audio correspondiente al FAX en una imagen.

Elastix añade a esta combinación una intuitiva interfaz Web de administración donde es posible configurar la característica fax-a-email que nos permite que los documentos de fax lleguen a direcciones de correo electrónico en formato PDF.

HylaFAX

HylaFAX es un popular servidor de fax que funciona sobre Linux. Según su propio sitio Web -HylaFAX is an enterprise-class system for sending and receiving facsimiles as well as for sending alpha-numeric pages.-

Con HylaFAX podemos recibir un alto volumen de documentos de fax sin problemas.

La arquitectura del software es cliente-servidor. Es decir que HylaFAX abre un puerto de red por donde escucha peticiones de clientes. Estos clientes pueden residir en máquinas remotas desde donde pueden enviar faxes. ¿Suena bien no?

Quiere decir que desde una aplicación cliente remota se puede establecer una conexión con el servidor Elastix y enviar como fax un documento de texto, PDF, imagen, entre otros.

Hay algunas aplicaciones cliente interesantes entre ellas se encuentra Winprint HylaFAX que añade soporte para enviar faxes a través del cuadro de diálogo de impresión que usan las aplicaciones Windows. De esta manera enviar un fax es tan sencillo como imprimir un documento.

IAXModem

Debido a que HylaFax se puede comunicar con modems y Asterisk con extensiones IAX, necesitamos algún -pegamento- para unir ambas cosas y que puedan funcionar juntas. Ese pegamento es IAXModem.

IAXModem es un paquete de software que simula ser una extensión IAX por el lado de Asterisk y por el lado de HylaFax simula ser un modem serial. Es decir que incluso se registra como una extensión IAX con su respectivo usuario y clave.

Como es de suponer, este teléfono virtual, que simula ser el IAXModem, se ejecuta en el mismo servidor Elastix y por tanto se conectará desde localhost (la dirección IP 127.0.0.1). Es fácil verificar si tenemos una extensión IAXModem conectada desde la consola del CLI pues basta con examinar si existe alguna extensión IAX ejecutándose desde localhost.

elastix*CLI> iax2 show peers

Name/Username    Host                 Mask             Port          Status

620              127.0.0.1       (D)  255.255.255.255  40001         OK (2 ms)

660              (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

661              192.168.1.136   (D)  255.255.255.255  4569          OK (2 ms)

662              127.0.0.1       (D)  255.255.255.255  40000         OK (3 ms)

709              (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

712              192.168.1.126   (D)  255.255.255.255  4569          OK (5 ms)

7214             (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

7213             (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

723              (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

869              (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

966              (Unspecified)   (D)  255.255.255.255  0             OK (9 ms)

964              (Unspecified)   (D)  255.255.255.255  0             UNKNOWN

863              192.168.1.233   (D)  255.255.255.255  4569          OK (9 ms)

De la salida anterior podríamos concluir que las extensiones 620 y 662 son extensiones de FAX manejadas por IAXModem.

20.2 Configuración de Fax en la interfaz Web de Elastix

Listado de Fax Virtual

La opción -Listado de Fax Virtual- del Menú -FAX- del Elastix nos permite verificar el listado de todos los faxes virtuales, donde se muestra el estado de cada uno.

Listado de faxes virtuales

Además al dar clic sobre el nombre del fax virtual podemos ver los datos del mismo:

Visualización de nueva extensión virtual de fax

En la parte superior se encuentran dos botones, el primer botón -Editar- nos permite editar los datos del fax virtual.

Y el segundo botón -Eliminar- nos permite eliminar el fax virtual.

Si procedemos a editar veremos el siguiente formulario.

Edición de fax virtual

Luego de modificar los valores, damos clic sobre el botón -Aplicar Cambios- para guardar los cambios o sobre -Cancelar- para regresar sin guardar.

Nuevo Fax Virtual

La opción -Nuevo Fax Virtual- del Menú -FAX- de Elastix nos permite crear un nuevo fax virtual. Previamente debe haberse creado la extensión de fax de tipo IAX. Para mayor información acerca de como crear una extensión diríjase a -Creación de Nueva Extensión-.

Formulario de creación de una nueva extensión de fax virtual

Para crear un nuevo fax virtual ingrese nombre, correo electrónico, extensión y clave secreta para el fax virtual; estos son campos requeridos. Además de esto existen dos campos adicionales que son el nombre y número del Caller ID. Una vez ingresados estos datos debemos dar clic en el botón -Guardar- para ingresar el nuevo fax virtual o -Cancelar- para salir sin guardar.

Note que la extensión del fax virtual será usada para recibir un fax.

Los datos a ingresar se describen a continuación:

Nombre | Descripción
Nombre de Fax Virtual | Nombre para identificar el fax virtual
Extensión Fax (IAX) | Extensión usada como servicio de fax. Esta extensión debe haber sido previamente creada como tipo IAX en el módulo -Extensiones- del Menú -Configuración PBX-
Email Destino | Email al cual se enviarán notificaciones por parte de la central de los faxes recibidos y de los errores en caso de haberlos
Secreto (IAX) | Debe ser la misma que la ingresada al crear la extensión de fax en el menú de -Configuración PBX-
Nombre Caller ID | El nombre de quien llama. Este campo no es obligatorio. Si no se llena quien reciba un fax de esta extensión no podrá ver el nombre
Número Caller ID | Número de quien llama. Al igual que el anterior no es obligatorio, y si no se llena quien reciba el fax no podrá ver el número.

Fax Master

La opción -Fax Master- del Menú -FAX- de Elastix nos permite ingresar la dirección de correo electrónico del administrador del Fax al cual le llegarán las notificaciones de los mensajes recibidos, errores y la actividad del Servidor de Fax.

Configuración del Fax Master

Proceda a ingresar el correo electrónico del administrador de fax y luego de clic en el botón -Aplicar Cambios-.

Clientes de Fax

La opción -Clientes de Fax- del Menú -FAX- de Elastix nos permite ingresar las IPs que tendrán permiso para enviar faxes por medio de Elastix.

Configuración de IPs de clientes de fax

Proceda a ingresar las IPs, una IP por fila y luego de clic en el botón -Aplicar Cambios-.

Se recomienda ingresar la IP 127.0.0.1 y localhost en la configuración debido a que algunos procesos pueden necesitarlas.

Estos son los clientes que se comunican con HylaFAX a través del puerto de red TCP 4559. Este por ejemplo es el caso del software Winprint HylaFAX.

Visor de Fax

La opción -Visor de Fax- del Menú -Fax- del Elastix nos permite visualizar un listado con el detalle de las faxes recibidos.

Visor de faxes. Si se da clic en alguno se lo visualiza en formato PDF.

Además tenemos la opción de descargar el fax en formato PDF, dando clic sobre el archivo deseado de la lista de faxes recibidos.

A continuación el significado de algunos de los campos que aparecen en el listado anterior.

Nombre | Descripción
Nombre de Compañía | Nombre de la compañía que envía el fax
Fax de Compañía | Número de Fax de la compañía que envía el fax
Fecha de Fax | Fecha de envío del fax

20.3 Envío de FAX desde una estación de trabajo

Una gran ventaja del esquema de FAX de Elastix es que permite a los usuarios enviar documentos de FAX desde la misma computadora, eliminando la necesidad de imprimir el documento y pasarlo a través de la maquinita de FAX.

Lo anterior es posible hacerlo incluso desde la misma aplicación en la que se genera el documento, como el software de procesador de texto u hoja de cálculo. Para esto usaremos un programa que simulará ser una impresora. Es decir que podemos enviar a imprimir a esta impresora virtual cualquier documento y este en lugar de imprimirse se enviará por FAX. Sin duda esto añadirá mucha comodidad a los usuarios y nos proporcionará un inherente ahorro de papel que siempre viene bien, tanto para el ahorro como para el medio ambiente.

Veamos qué hacer para estaciones de trabajo con sistema operativo Windows que suele ser el caso más común.

Lo primero que debemos hacer es descargar el software llamado WinPrint HylaFAX y esto lo podemos hacer desde la página del proyecto ubicada en http://winprinthylafax.sourceforge.net

Configurar WinPrint HylaFAX es una tarea que podríamos dividir en dos partes. La primera es añadir una nueva impresora y la segunda es configurar los parámetros del servidor HylaFAX.

Comencemos por añadir la nueva impresora. Para esto debemos seguir una serie de pasos que se relatan a continuación.

1) Debemos ir al panel de control y añadir una nueva impresora. En el primer cuadro de diálogo hay que escoger que se trata de una impresora local pero des-seleccionar donde dice que se detecte la impresora con plug-n-play ya que no se trata de una impresora real.

2) Luego aparecerá una nueva ventana que nos preguntará a qué puerto se encuentra conectada la impresora y debemos crear un nuevo puerto del tipo -Winprint HylaFAX-

Configurando WinPrint HylaFAX

3) A continuación se nos preguntará el nombre del puerto. Podemos poner cualquier identificador aquí, pero el nombre por omisión está bien.

4) Una ventana aparecerá pidiéndonos especificar el tipo de impresora. Podemos escoger aquí cualquier impresora Postscript. El fabricante recomienda escoger -Apple LaserWriter 12/640 PS-

5) El resto de pasos son triviales y terminaremos con la configuración de la nueva impresora. Lo único importante es no elegir compartir esta impresora pues ya sabemos que no se trata de una impresora.

Hemos terminado con la primera parte, ahora configuremos los parámetros del servidor HylaFAX que reside en nuestro Elastix.

1) En el panel de control damos clic derecho en la impresora que acabamos de crear y escogemos -Propiedades-. Allí nos aparecerá una ventana con varias pestañas, debemos elegir la que dice -Puertos-.

2) En esta nueva ventana debemos configurar el puerto que aparece señalado por omisión. Aparecerá un cuadro de diálogo donde debemos ingresar los datos de nuestro servidor HylaFAX. Debemos configurar aquí la dirección IP del servidor Elastix.

Configuración de los parámetros del servidor HylaFAX

3) No debemos olvidar que para que HylaFAX permita a este computador enviar un FAX el IP del computador debe estar autorizada por HylaFAX y esto lo podemos configurar desde la interfaz Web del Elastix en el menú -FAX -> Clientes de FAX-. Ya vimos cómo configurar esto antes, en este mismo capítulo.

Finalmente nos encontramos listos para enviar un FAX desde cualquier aplicación como si enviáramos el documento a imprimir. Al enviar el trabajo a la impresora virtual nos aparecerá un cuadro de diálogo donde debemos ingresar el número de teléfono al que queremos enviar el FAX.

20.4 Interfaz Web para envío de FAX

Elastix incluye una muy interesante interfaz Web para el envío de documentos de fax de manera sencilla. Esta interfaz está ubicada en el menú -Fax -> Virtual Fax -> Send Fax-.

A través de esta interfaz es posible enviar un documento de fax en formato PDF o TIFF; o simplemente podemos escribir un mensaje de texto y este será convertido en un documento de fax y enviado a su destino.

Interfaz Web para envío de Fax con la opción para envío de mensaje de texto seleccionada

Interfaz Web para envío de Fax con la opción para subir archivo seleccionada

La interfaz es muy intuitiva de usar y también puede resultar muy útil para realizar pruebas de envío y recepción de documentos.

20.5 Procesamiento interno de un documento de FAX en Elastix

Algunas cosas interesantes suceden internamente en Elastix desde el momento en que llega una transmisión de FAX. El esquema de manejo de FAX en Elastix ha demostrado ser una solución robusta y escalable pero que involucra algunos componentes y es importante conocer como se relacionan entre sí.

Desde el momento en que un usuario marca al servidor Elastix con la intención de enviar un documento de FAX sucede más o menos lo siguiente.

Asterisk contesta como si fuera una llamada normal y el usuario selecciona la extensión de FAX

El usuario sin saberlo está marcando una extensión IAX controlada por el software IAXmodem que simula ser un teléfono IAX y contesta la llamada

IAXmodem mantiene la llamada y todo el stream de FAX lo escribe en un dispositivo virtual ubicado en /var/spool/hylafax/FIFO.tty* que simula ser un MODEM

Por otro lado HylaFAX se encuentra escuchando el mismo dispositivo pensando que en realidad se trata de un MODEM y de esta manera recibe la señal de FAX

Internamente HylaFAX transforma este stream a un formato humanamente legible llamado PostScript

Este archivo PostScript es pasado a una aplicación que llamaremos Emailer Script quien a su vez transforma este archivo a un formato más legible, como el formato PDF. Luego construye un mensaje de correo electrónico y envía el PDF adjunto.

Antes de enviar el correo electrónico, el Emailer Script consulta una base de datos interna de Elastix para recabar información del cuerpo del mensaje y el destinatario del correo, ya que como recordaremos esto fue configurado desde la interfaz Web y fue almacenado en esta base de datos interna.

Para hacer más gráfico el procesamiento interno del FAX observemos la siguiente figura.

Comunicación entre los componentes del sistema de FAX en Elastix

20.6 Protocolo T.38

Si vamos a trabajar con tecnologías de FAX en algún momento nos toparemos con el término T.38. El protocolo T.38 es un protocolo recomendado por la ITU que sirve para transportar FAX sobre redes IP.

Si nos ponemos a pensar, una manera de transportar fax sobre redes IP sería transportar la señal de FAX como si fuera audio o voz a través de los protocolos de Voz sobre IP ya existentes en la actualidad, y en efecto esta es una manera de hacerlo. Sin embargo, esta no es la manera más adecuada en muchos casos pues, a diferencia de la voz, el FAX es mucho más sensible a errores de transmisión y por ejemplo una red con un nivel de pérdida de paquetes que pueda sonar aceptable para la transmisión de voz es probable que resulte en inaceptable para la transmisión de FAX pues el documento podría llegar ilegible o simplemente no llegar.

El protocolo T.38 es quien resuelve estos problemas usando algunas técnicas interesantes como la redundancia de paquetes. Es decir que por cada paquete enviado a través de la red es probable que se envíen algunas copias por si alguno se pierde en el camino.

No entraremos en más detalles acerca de T.38 sino más bien nos dedicaremos a explicar el soporte actual que existe de T.38 en Asterisk ya que es un tema frecuente de discusión. En caso de que el lector sienta curiosidad por conocer más detalles de este protocolo le recomendamos visitar http://en.wikipedia.org/wiki/T.38

A partir de Asterisk 1.4 se introdujo soporte limitado para el protocolo T.38. Decimos limitado porque Asterisk no es capaz de terminar una transmisión T.38, es más no esta en capacidad de entender el protocolo. Lo único que puede hacer Asterisk con T.38 es pasar la comunicación de un lado a otro. O sea que T.38 puede pasar a través de Asterisk y a esta modalidad de funcionamiento se le llama passthrough.

En su versión 1.6, Asterisk añade más soporte para T.38 y está en la capacidad de entender el protocolo un poco más y por lo tanto hacer algunas cosas interesantes. Sin embargo el soporte no está 100% completo todavía.

Hay que recordar que Asterisk 1.6 viene incluido a partir de Elastix 2.0.

Para aquellos que requieren soporte T.38 y no pueden esperar a nuevas versiones de Asterisk les dejamos con la noticia de que existen soluciones comerciales para añadir soporte T.38, inclusive una alternativa comercial de Digium llamada -Fax for Asterisk-.

21

Sintetización y reconocimiento de voz

Si he logrado ver más lejos, ha sido porque he subido a hombros de gigantes

-- Isaac Newton

Las tecnologías de sintetización y reconocimiento de voz han sido ideas algo futuristas hasta hace relativamente poco tiempo. En la actualidad es posible usar estas tecnologías en la práctica con resultados muy interesantes.

En Elastix se puede habilitar el soporte para ambos conceptos permitiéndonos con esto obtener un Servidor de Comunicaciones de vanguardia.

21.1 Sintetización de voz

Sintetización de voz es la tecnología que permite convertir el texto a audio. También se conoce como TTS debido al término Text-To-Speech (texto-a-habla en español).

Aunque parezca insólito su historia se remonta a algunos siglos atrás cuando se intentó sintetizar voz mecánicamente con aparatos que simulaban el aparato vocal humano. En ese entonces no fueron más que juguetes. Ya en la década de los 30 laboratorios Bell desarrollaron el famoso VOCODER, que era al mismo tiempo un aparato de reconocimiento de voz que utilizaba electrónica y que podía producir sonido inteligible. Su finalidad original era la de reconocer voz para luego poder transmitirla de manera codificada por un medio y sintetizarla en el otro extremo.

El uso de la computación de allí en adelante hizo que fuera posible desarrollar tecnología de sintetización de voz que fuera práctica y que pudiera estar al alcance de cualquiera que pudiera pagar por ella. Debido a que en un principio muchas de estas tecnologías desarrolladas fueron propietarias y su oferta limitada, sus precios fueron elevados y orientados a grandes empresas o bancos.

Actualmente ya existen alternativas de sintetización de voz de relativo bajo costo e inclusive de libre uso como Festival o FreeTTS. En breve explicaremos cómo hacer uso del motor de sintetización de voz Festival desde nuestro servidor Elastix.

Veamos un poco de cómo funciona la técnica de sintetización de voz moderna como la usada por Festival.

Podemos dividir al proceso de convertir el texto a voz en 3 partes: análisis de texto, análisis lingüístico y generación de audio.

Análisis de texto

Esta etapa es la que se encarga de normalizar el texto, es decir traducirlo a un formato de palabras estándar y por lo tanto más entendible para ser manipulado en la siguiente etapa. El texto -crudo- o sin manipular puede contener palabras mezcladas con números o abreviaciones que no son aptas para la conversión a audio. Por ejemplo, una frase como -Me debes $100 mil dólares y debes pagarme el 10% ahora- se podría escribir como -Me debes cien mil dólares y debes pagarme el diez por ciento ahora- para fines de sintetizarla a voz.

Nota: El ejemplo anterior tiene la finalidad de ilustrar el concepto de normalización del texto. No necesariamente muestra el lenguaje real de un texto normalizado.

Análisis lingüístico

Esta etapa es la que se encarga de convertir el texto normalizado en fonemas. Los fonemas son las unidades fonéticas que componen un lenguaje hablado. Son sonidos únicos y diferentes entre sí.

Una palabra está compuesta por uno o varios fonemas.

Para traducir el texto normalizado en fonemas hace falta bastante trabajo pues se requiere entre otras cosas conocer la entonación de la palabra pues no es lo mismo si se trata de un contexto de pregunta o exclamación.

Nota: En el caso de Festival se trabaja con difonos más que con fonemas.

Generación de audio

Una vez que tenemos el texto en una representación de fonemas nos falta traducir esos fonemas a audio. Habrá que unir o concatenar el audio correspondiente a cada fonema e intercalarlo con los silencios que van entre las palabras.

Sin embargo, no es tan sencillo como suena pues el simple hecho de unir los fonemas audibles puede resultar en un audio de baja calidad que suene robótico o inhumano.

Existen algunas técnicas o algoritmos que se pueden usar para resolver este problema y hacer que la transición entre fonemas sea lo más suave posible. El algoritmo por omisión usado por Festival se llama Residual Excited Linear Prediction o simplemente RELP o RE-LPC. Sin embargo existen otros algoritmos que pueden ser utilizados por Festival como es el caso de MBROLA.

Nota: La técnica de concatenar fonemas no es la única para generar audio a partir de fonemas pero es la que usa Festival. Para ser más específicos Festival usa una técnica de concatenación de difonos.

Conversión de texto a voz con Festival

Festival

Ya hemos visto algo del funcionamiento de Festival, pues ha sido tomada como ejemplo para ilustrar el proceso de conversión de texto a voz en el apartado pasado.

Festival es un sistema de sintetización de voz desarrollado por la Universidad de Edimburgo utilizando lenguaje de programación C++.

Festival soporta varios idiomas, viene instalado por omisión en Elastix y podemos utilizarlo desde Asterisk; lo que lo convierte en una alternativa atractiva si estamos pensando en hacer sintetización de voz.

Festival puede trabajar como cliente y como servidor. Como cliente puede trabajar en dos modos: línea de comandos y tts (text-to-speech).

Modo línea de comandos

En el modo línea de comandos Festival ejecutará un intérprete de comandos. Para entrar a este modo basta ejecutar el comando festival sin opciones.

[root@elastix ~]# festival

Festival Speech Synthesis System 1.95:beta July 2004

Copyright (C) University of Edinburgh, 1996-2004. All rights reserved.

For details type `(festival_warranty)'

festival>

Como vemos obtenemos un prompt que dice festival> y desde el cual se pueden ejecutar comandos de Festival en formato similar al del editor de texto Emacs. Para más información se puede tipear la palabra help.

Ya que estamos en la línea de comandos vamos a aprovechar para sintetizar nuestra primera frase de texto en la tarjeta de sonido de nuestro servidor Elastix. Obviamente tendremos que conectar unos audífonos allí para escuchar algo.

festival> (SayText "Hola Mundo")

#<Utterance 0xb7132578>

También podríamos sintetizar el contenido entero de un archivo de texto desde la línea de comandos.

festival> (tts "content.txt" nil)

nil

festival> (quit)

Finalmente salimos de la línea de comandos con el comando (quit). También podemos salir con la combinación de teclas Ctrl+D.

Modo tts

En el modo tts podemos sintetizar texto a audio sin entrar en la línea de comandos. Para activar el modo tts simplemente hay que pasar el parámetro --tts cuando se ejecuta el comando festival.

Por ejemplo, para sintetizar un archivo de texto podemos ejecutar el siguiente comando en modo tts:

[root@elastix ~]#festival --tts archivo1.txt

Si queremos ejecutar un texto arbitrario sin utilizar un archivo de por medio podemos hacerlo mediante una invocación con una tubería (pipe).

[root@elastix ~]# echo -Hola Mundo, este es un ejemplo- | festival --tts

Por omisión Festival tratará de enviar el audio al dispositivo o tarjeta de sonido, pero muchas veces no es práctico hacerlo de esta manera por lo que veremos cómo enviar la salida de audio a un archivo para escucharlo después.

Para realizar lo anterior Festival nos proporciona un comando para facilitar las cosas llamado text2wave. El uso del comando text2wave es sumamente sencillo.

[root@elastix ~]# text2wave archivo.txt -o archivo.wav

Donde archivo.txt contiene el texto a ser sintetizado y archivo.wav representa el archivo de audio donde se guardará la salida.

Cómo interactuar con Festival desde el plan de marcado

Asterisk nos provee de una aplicación de plan de marcado llamada Festival. Esta aplicación funciona internamente conectándose a un servidor Festival a través de la red y reproduciendo la salida de audio en el canal en uso (o corriente) en el plan de marcado.

Esto nos brinda la flexibilidad de ejecutar un servidor Festival inclusive en un equipo diferente al servidor Elastix. En algunos casos esto es conveniente si nos encontramos en un ambiente con alto volumen de llamadas y queremos descongestionar la carga del servidor. Explicaremos más adelante cómo ejecutar Festival como servidor de red.

La sintaxis de plan de marcado de la aplicación Festival es la siguiente.

Festival(text[|intkeys])

Donde text es el texto que se desea sintetizar (y reproducir) e intkeys es un parámetro opcional que especifica las teclas telefónicas que pueden interrumpir la ejecución del comando. Si el parámetro intkeys toma el valor de -any- quiere decir que el usuario puede interrumpir la ejecución del comando con cualquier tecla.

Veamos un ejemplo de utilización de la aplicación Festival en el plan de marcado.

exten => 5333,1,Answer

exten => 5333,n,Festival('Hola, esto es un ejemplo de conversión de texto a audio','any');

exten => 5333,n,Hangup()

Con el ejemplo anterior hemos creado una extensión 5333. Si se llama a esa extensión escucharemos el mensaje tipeado.

Ejecutando Festival como servidor de red

Festival viene con un script llamado festival_server que sirve para arrancar Festival como servidor de red. Por omisión levantará un servicio de red en el puerto 1314.

Para arrancar el servidor Festival debemos ejecutar el siguiente comando.

[root@elastix ~]# festival_server &

Nota: Una manera sencilla de hacer que este comando se ejecute cada vez que el servidor Elastix se reinicie es incluyéndolo en el archivo /etc/rc.local

Sin embargo, antes de iniciar el servidor Festival debemos hacer unas modificaciones a la configuración de Festival pues Asterisk necesita que el servidor Festival entienda cierto comando y que le envíe audio en un formato particular.

Para configurar Festival para que funcione adecuadamente con Asterisk debemos editar el archivo festival.scm ubicado en /usr/share/festival/

(define (tts_textasterisk string mode)

"(tts_textasterisk STRING MODE)

Apply tts to STRING. This function is specifically designed for

use in server mode so a single function call may synthesize the string.

This function name may be added to the server safe functions."

   (let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string)))))

      (utt.wave.resample wholeutt 8000)

      (utt.wave.rescale wholeutt 5)

      (utt.send.wave.client wholeutt)))

Las podemos añadir cerca del inicio del archivo luego de los comentarios iniciales.

Luego de esto podemos arrancar Festival como servidor (como ya explicamos antes) y reiniciar Asterisk. ¡Finalmente marcamos la extensión 5333 y listo!

En caso de que el archivo festival.scm no haya sido modificado veremos un error como el siguiente en la salida del CLI.

elastix*CLI> SIOD ERROR: unbound variable : tts_textasterisk

Por omisión todo debe funcionar bien. Sin embargo, es necesario explicar que los parámetros de conexión de Asterisk con el servidor Festival se pueden modificar en el archivo /etc/asterisk/festival.conf. Un cambio común en este archivo es cuando se desea ejecutar el servidor Festival en un servidor separado. Para esto deberemos cambiar el parámetro -host- por el IP del equipo donde se encuentra ejecutándose el servidor Festival.

Sintetizando voz desde la interfaz Web de Elastix

Elastix viene equipado con una bonita interfaz Web que nos permite sintetizar texto a voz. Está basada en Festival y se puede encontrar en el menú de -Extras -> Texto a Wav-.

La salida puede obtenerse en formato wav o gsm y podría incluso servir para crear prompts de voz que podemos usar en el plan de marcado.

Interfaz Web para conversión de texto a wav

21.2 Reconocimiento de voz

Existes algunas definiciones de lo que es el reconocimiento de voz. Por ejemplo se puede definir como el proceso en el que un sistema computacional reconoce lo que un ser humano le dice. Generalmente, este reconocimiento representa una orden que deberá ejecutar el computador.

El reconocimiento de voz, hoy en día tiene muchas aplicaciones que las vemos en los teléfonos celulares, en la domótica (o control de artefactos domésticos por medio de la voz), procesadores de texto que reciben -dictado-, en los ámbito de la salud existen aplicaciones más específicas para personas discapacitadas que le permiten abrir y cerrar puertas, así como también en el mundo de la telefonía hay implementaciones en las que cuando se llama a una empresa, el sistema telefónico le pedirá decir el nombre de la persona con la que se desea hablar y el sistema reconocerá el nombre que usted ha dicho y lo redireccionará a la extensión deseada.

El término reconocimiento de voz es muchas veces utilizado para referirse al reconocimiento del habla. El reconocimiento de voz también se puede emplear para identificar la voz de un individuo en particular. Esto se aplica a sistemas de seguridad que asocian la voz con una persona.

En un sistema telefónico lo que se usa es el reconocimiento del habla. Un sistema muy utilizado para sistemas telefónicos IP basados en Asterisk es LUMENVOX.

Lumenvox

LUMENVOX aunque usa algunos de los fundamentos del reconocimiento de voz, es diferente ya que no trata de identificar a individuos, más bien trata de identificar lo que éste dice. La mayoría de los sistemas de reconocimiento de frases o palabras siguen el siguiente procedimiento:

Cargar una lista de palabras para ser reconocidas. Esta lista de palabras se llama -gramática-.

El SRH (Sistema de Reconocimiento del Habla) carga el audio del altavoz. Este audio se representa como una forma de onda, esencialmente la representación matemática del sonido.

El SRH compara la forma de onda a sus propios modelos acústicos. Estas son las bases de datos que contienen información sobre las formas de onda de cada uno de los sonidos y es lo que permite al sistema reconocer del habla.

El SRH comparan las palabras en la gramática a los resultados obtenidos a partir de su búsqueda de modelos acústicos.

Por último, determina qué palabras en la gramática de audio concuerda y devuelve un resultado.

Instalando LumenVox en Elastix

Dividiremos el proceso de instalación en algunas etapas.

Descargar e instalar LumenVox

El primer paso en el proceso de instalación es bajar la llave GPG desde:

http://www.lumenvox.com/packages/FC6/i386/RPM-GPG-KEY-LumenVox.gpg

Crear el archivo llamado LumenVox.repo en /etc/yum.repos.d/

Editar el archivo e ingresar la siguiente información:

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

[LumenVox]

name=LumenVox Products $basearch

baseurl=http://www.LumenVox.com/packages/EL5/i386/

#baseurl=http://www.LumenVox.com/packages/EL4/i386/

enabled=1

gpgcheck=0

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

Grabar y cerrar el archivo

Desde la línea de comandos tipear -yum install LumenVoxLicenseServer-

Luego tipear -yum install LumenVoxSRE-

Instalar la licencia

Lo primero que hay que hacer es generar un archivo llamado Info.bts que guarda información acerca de su sistema. Para realizar esto es necesario ejecutar el siguiente comando:

/usr/bin/lv_license_manager -g path donde path es la ruta completa del archivo server ID. Por ejemplo, si deseo crear el archivo server ID en el directorio root/LumenVox, debería tipear: /usr/bin/lv_license_manager -g /root/LumenVox/Info.bts

Cargar el archivo Info.bts y descargar la licencia

Para esto es necesario visitar http://www.lumenvox.com/customers/. Ingresar con el usuario y clave respectivo.

Luego nos dirigimos al vínculo -View Licenses- y veremos un listado de las licencias disponibles inicialmente en estado -Upload License-. Hay que hacer clic en -Upload License- y cargar el archivo Info.bts que generamos.

Una vez hecho esto el estado de licencia cambiará a -Download License-. Hacemos clic allí y obtenemos la licencia que será un archivo con nombre LicenseXXXX.bts donde XXXX corresponden a cuatro dígitos.

Instalar la licencia.

Para esto hay que tipear el comando /usr/bin/lv_license_manager -m Licensefile donde Licensefile es el archivo de la licencia que nos descargamos en el paso anterior.

Verificar que la instalación fue exitosa

Para verificar que la instalación fue exitosa es necesario ejecutar el comando ps ax|grep -i -lv-. La salida de este comando nos debe mostrar si los procesos lv_license_server y lv_sre_server está ejecutándose tal como se muestra a continuación:

[root@elastix yum.repos.d]# ps ax|grep -i "lv"

 2023 ?        Ssl    0:07 lv_license_server -console

 2118 ?        Ssl    0:35 lv_sre_server -console

13956 pts/5    S+     0:00 grep -i lv

[root@elastix yum.repos.d]#

Descargar e instalar el asterisk/lumenvox connection

Visitar http://www.lumenvox.com/customers/ e ingresar con el usuario y clave respectivo.

Hacer click en -Download-.

Descargar el archivo etiquetado como Asterisk 1.4 Connector (Si usamos Elastix 1.6).

Descomprimir el archivo ejecutando tar -xzvf y el nombre del archivo descargado. Esto crea un nuevo directorio.

Ingresar en el directorio anterior y copiar el archivo llamado res_speech_lumenvox.so en /usr/lib/asterisk/modules/.

Copiar el archivo llamado lumenvox.conf en /etc/asterisk/

Modificar /etc/asterisk/modules.conf y asegurarse de que la línea de preload => res_speech.so esté allí y añadir la línea de load => res_speech_lumenvox.so

Probando LumenVox en Asterisk

Editar el archivo extensions_custom.conf y adicionar el siguiente contexto.

     [lumenvox-test]

     exten => 1234,1,Answer

     exten => 1234,n,Wait(1)

     exten => 1234,n,SpeechCreate

     exten => 1234,n,SpeechActivateGrammar(llamar_extension)

     exten => 1234,n,Set(TIMEOUT(response)=8)

     exten => 1234,n,Background(custom/ivrventas3)

     exten => 1234,n,SpeechBackground(beep)

     exten => 1234,n,Verbose(1|Result was ${SPEECH_TEXT(0)})

     exten => 1234,n,Macro(user-callerid,)

     exten => 1234,n,Dial(SIP/${SPEECH_TEXT(0)})

     exten => 1234,n,Hangup()

Adicionar la línea include => lumenvox-test debajo del contexto from-internal-custom.

Conectarse a Asterisk con el comando asterisk -r

Tipear el comando reload

Probar marcando la extensión 1234 configurada en el plan de marcado de ejemplo

22

Desempeño y dimensionamiento

Yo no hablo de venganzas ni perdones, el olvido es la única venganza y el único perdón

-- Jorge Luis Borges

22.1 Desempeño de Elastix

El desempeño de un servidor Elastix es un asunto complejo de analizar. En muchos casos interesa conocer los resultados y recomendaciones principalmente desde el punto de vista de una PBX, es decir de desempeño de Asterisk, puesto que es uno de los componentes más sensibles, debido a que las comunicaciones por voz deben ser en tiempo real.

En este capítulo no haremos recomendaciones de hardware a utilizar pues esto haría que la presente obra quedara desactualizada en muy corto tiempo ya que el hardware evoluciona rápidamente. Más bien explicaremos los factores que afectan el desempeño en un servidor Elastix a nivel general.

Factores que afectan el desempeño de Elastix

Hay muchos factores que pueden afectar el desempeño de Elastix de alguna manera. Aquí explicaremos los más comunes.

Número de llamadas concurrentes

Sin duda este es un parámetro muy importante, el número de llamadas concurrentes afecta directamente el consumo de CPU del servidor.

El siguiente es un gráfico de pruebas realizadas (sin transcoding) en un computador con un CPU de 2.2 GHz con 512 MB de RAM. Vemos que se han superado las 200 llamadas concurrentes con menos del 50% de CPU. En el computador se usó Elastix 1.3.

Gráfico CPU vs. Llamadas concurrentes

Transcoding

El transcoding ocurre cuando por un lado una llamada ingresa con un codec determinado y la misma llamada tiene que llegar a un destino donde se utiliza otro codec distinto. Por lo tanto, Asterisk que está en el medio tiene que hacer las veces de traductor para que los dos puntos se entiendan. Esto es lo que se denomina transcoding. Como resulta obvio si el origen y el destino utilizan el mismo codec no se necesita hacer transcoding.

El transcoding requiere de muchos cálculos matemáticos pues se está decodificando y codificando información con algoritmos complejos y por lo tanto esta operación requiere mucho CPU.

Una llamada con transcoding puede tomar 4, 5, 10 o incluso más consumo de CPU que una llamada regular, por lo que en escenarios con transcoding el desempeño se reduce significativamente. Por lo tanto, siempre que se pueda se debe evitar usar codecs distintos.

En caso de que no podamos evitar el escenario de transcoding y el desempeño de nuestro servidor Elastix se encuentre comprometido, una opción es el uso de hardware especial dedicado exclusivamente a esta tarea. Es así como en el mercado existen productos de transcoding por hardware, los más populares son las tarjetas de transcoding que se conectan al bus PCI. Estos productos descongestionan al CPU de nuestro servidor de la tarea de hacer transcoding y permiten que un mismo servidor Elastix pueda traficar un número mayor de llamadas.

Las diferentes tarjetas de transcoding que existen en el mercado usualmente publican el número máximo de llamadas concurrentes de transcoding (algunos las llaman sesiones) que son capaces de procesar. Este parámetro es muy útil al momento de elegir el hardware de transcoding correcto.

Interrupciones de hardware

Una interrupción de hardware ocurre cuando un dispositivo requiere la atención del CPU. En este momento el CPU guarda lo que haya estado haciendo y comienza a ejecutar las tareas relacionadas con esa interrupción. Por lo tanto el CPU se demorará más en terminar la ejecución de una tarea determinada (por ejemplo transcoding) si tiene que detenerse frecuentemente a atender interrupciones de hardware.

Estas interrupciones normalmente ocurren en un volumen que no afecta la operación normal del CPU, pues los procesadores de hoy en día son lo suficientemente rápidos; pero existen ciertos escenarios en los que podrían perjudicar el desempeño de nuestro equipo.

Una tarjeta de interfaz telefónica genera aproximadamente unas mil interrupciones por segundo y cada vez que esto ocurre el procesador detiene lo que haya estado haciendo y se dedica a procesar la interrupción. A veces el procesador se encuentra muy ocupado y opta por -perder- la interrupción. Esto no es muy grave en la mayoría de dispositivos, pero si es un problema en una tarjeta de interfaz telefónica pues significa que se pueden perder paquetes de voz y por lo tanto la calidad de voz se verá afectada.

También es importante entender que una tarjeta de interfaz telefónica es diferente a muchos otros dispositivos desde el punto de vista de las interrupciones. Por ejemplo, si una interrupción de una tarjeta de red se pierde usualmente no es un problema pues esa información perdida será transmitida nuevamente por la red. Por otro lado un disco duro tiene prioridad en cuanto a interrupciones de hardware y el CPU intentará no perder ninguna interrupción de este tipo de dispositivo.

Existen casos en los que tenemos muchos dispositivos de hardware conectados a nuestro servidor y todos ellos enviando interrupciones al CPU. En estos casos podemos tener problemas en el desempeño. Un síntoma evidente es la pérdida en la calidad del audio, el cual podría sonar como robotizado. Para hacer un diagnóstico más preciso podemos hacer uso del comando top para verificar si el tiempo que el CPU empeña en procesar las interrupciones de hardware es significativo.

Para esto debemos analizar la cabecera de la salida del comando top. Prestemos especial atención a la tercera línea. Allí encontraremos un parámetro abreviado como hi. Esta es la abreviación de Hardware Interrupts. El valor a la izquierda de este -hi- representa el porcentaje de tiempo que el CPU ha ocupado en atender interrupciones de hardware.

Si este valor se encuentra siempre elevado puede revelarnos un problema.

Si nuestro servidor cuenta con algunos procesadores o núcleos es importante que desglosemos la cabecera para analizar si un procesador se encuentra más atareado que otro atendiendo interrupciones. Para realizar esto tipeamos -1-.

En el caso anterior podemos observar que el procesador Cpu0 se encuentra más ocupado atendiendo interrupciones que el procesador Cpu1. Si queremos analizar más a fondo cómo se encuentran balanceadas las interrupciones de los dispositivos de hardware entre los diferentes núcleos disponibles podemos desplegar la información del archivo /proc/interrupts. A continuación un ejemplo.

En el ejemplo anterior cada fila representa uno o más dispositivos asociados a un número IRQ. La primera columna representa dicho número IRQ. Luego de esto, inmediatamente a la derecha, vemos dos columnas, una para cada CPU. Cada una de estas columnas contiene el valor de un contador de interrupciones que se incrementa cada vez que el dispositivo solicita una interrupción al CPU. La última columna contiene el nombre del driver utilizado.

En este ejemplo podemos identificar la tarjeta de interfaz de telefonía a través del nombre del driver opvxa1200, vemos que esta tarjeta está enviando interrupciones sólo al CPU0.

Situaciones como la anterior pueden derivar en que un CPU se encuentre sobrecargado atendiendo interrupciones de hardware y si este fuera el caso lo recomendable es balancear las interrupciones entre los diferentes CPUs o núcleos de los cuales disponemos.

Para balancear interrupciones se usa un archivo dentro de /proc/irq llamado smp_affinity. Existe un archivo para cada IRQ. Por ejemplo, en el caso anterior el archivo se encuentra en /proc/irq/82/smp_affinity. Si observamos detenidamente el número 82 es el número de IRQ del dispositivo. Veamos el contenido del archivo.

La salida anterior 00000001 se denomina máscara y realmente se trata de un número hexadecimal. En nuestro caso significa que el dispositivo está enviando sus interrupciones únicamente al CPU0. En el caso de dos núcleos existen sólo 3 combinaciones posibles: 00000001, 00000002 y 00000003. La primera ya vimos que significa que el dispositivo está enviando interrupciones únicamente al CPU0, la segunda significa que el dispositivo está enviando interrupciones al CPU1 y la tercera máscara significa que el dispositivo está enviando interrupciones tanto al CPU0 como al CPU1.

Para más núcleos existen más máscaras posibles y se recomienda al lector leer más información acerca de smp_affinity en estos casos.

En todo caso, si queremos que las interrupciones del dispositivo opvxa1200 envíe sus interrupciones al CPU1 en lugar del CPU0 debemos escribir 00000002 en el archivo /proc/irq/82/smp_affinity. Si queremos que envíe interrupciones a ambos CPUs debemos escribir 00000003 en lugar de lo anterior.

En realidad no es necesario escribir todos los ceros que se encuentran al inicio del número debido a que los archivos del /proc en realidad no son archivos reales sino representaciones de la configuración del kernel. Por lo tanto para que la tarjeta de nuestro ejemplo envíe interrupciones a ambos CPUs basta con escribir lo siguiente.

Con lo anterior hemos logrado que las interrupciones del dispositivo opvxa1200 sean enviadas tanto al CPU0 como al CPU1.

Como nota a este ejemplo se puede agregar que si bien el método anterior es muy útil en muchos casos, en otros una solución más sencilla y eficaz es utilizar la menor cantidad de dispositivos conectados al servidor Elastix. Muchas veces se observan servidores con varias tarjetas PCI innecesarias (Ej. tarjetas de sonido o de red de las que se pueden prescindir) y varios dispositivos USB conectados. El único slot PCI ocupado debe ser el de la tarjeta de interfaz telefónica. Mientras más dispositivos soliciten interrupciones más probabilidad existe de degradar el desempeño de nuestro CPU.

Finalmente no está demás comentar que en la actualidad han salido al mercado algunas tarjetas de interfaz telefónica que permiten configurar la frecuencia con la que solicitan interrupciones al CPU. En algunos casos podría hacer la diferencia.

Componentes prescindibles de software que afectan el desempeño

Estrictamente hablando cualquier componente de software afecta el desempeño en cierta medida, pero hay algunos de los que podríamos prescindir en el peor de los casos evitando así que nuestro servidor colapse.

Openfire

Openfire es un software escrito en Java que hace un muy buen trabajo como un servidor de Mensajería Instantánea. Sin embargo también es un gran consumidor de memoria RAM. Por lo tanto si no es realmente necesario o el servidor está limitado de recursos es mejor dejarlo apagado.

Por omisión Openfire inicia apagado en Elastix.

Flash Operator Panel

En instalaciones grandes, cuando existe mucha actividad telefónica el FOP puede comenzar a consumir recursos fuera de los niveles deseados. Esto es porque el FOP se comunica con Asterisk a través de ARI y por lo tanto se encuentra escuchando toda la actividad telefónica a través del puerto de red que levanta Asterisk para este fin. Cuanto más actividad, más información tiene que procesar el FOP.

En instalaciones grandes, en caso de que el uso del FOP no sea requerido es mejor apagarlo.

Addon WebConference

Este addon sin duda es un aditamento lujoso para nuestro servidor Elastix. Los usuarios estarán contentos haciendo conferencias basadas en Web y el Gerente será la envidia de sus amigos. Pero no todo es maravilloso, para brindar toda su interesante funcionalidad el addon WebConference necesita consumir valiosos recursos del sistema como memoria RAM.

Por lo tanto, si contamos con hardware modesto o nuestro equipo ya se encuentra al límite de su funcionamiento, es preferible dejar este lujo para la próxima renovación de servidores.

Herramientas

Hay algunas herramientas que nos permitirán analizar el rendimiento de nuestro servidor Elastix.

top

Para hacer un análisis breve de los servicios que nos están consumiendo recursos basta con ejecutar un comando top y ordenar su salida por consumo de memoria o por consumo de CPU. Para hacer lo primero debemos topear la letra M (Mayúscula) y para lo segundo la letra P.

En algunas ocasiones podemos observar el proceso java liderando las estadísticas de consumo. Normalmente esto tiene que ver con Openfire.

sipp

Sipp es una herramienta de código abierto que sirve para generar tráfico SIP. En otras palabras nos servirá para generar llamadas SIP hacia nuestro servidor Elastix mientras tomamos muestras para entender cómo reaccionan los recursos del sistema (CPU, memoria) en un escenario de un alto volumen de llamadas.

22.2 Dimensionamiento telefónico

Determinando el número de líneas telefónicas necesarias

Cuando a un ingeniero le encomiendan la tarea de planificar un nuevo proyecto telefónico casi siempre el primer parámetro que necesita calcular es ¿cuántas líneas se necesitarán para satisfacer la demanda prevista?

En instalaciones grandes esto es importante puesto que no se quiere tener muchas más líneas de las necesarias pues esto podría significar un desperdicio de recursos y por otro lado no se quiere solicitar a la compañía telefónica tan pocas líneas que quedemos cortos y los usuarios consigan tono de ocupado frecuentemente.

El cálculo por tanto debe basarse en criterios técnicos y no ser tomado a la ligera.

En este apartado estudiaremos una aproximación estadística llamada modelo Erlang para calcular cuántas líneas telefónicas necesitaremos en una instalación determinada para satisfacer una demanda prevista con cierta calidad.

Agner Krarup Erlang

Erlang fue un ingeniero y matemático danés quien desarrolló a principios del siglo 20 las técnicas de Ingeniería de Tráfico y Teoría de Colas. No estudiaremos estos conceptos aquí en detalle pero los exploraremos vagamente para darle al lector cierto conocimiento básico y práctico de estas técnicas sin llegar al rigor matemático que ellas demandan. Estas importantes técnicas nos permitirán dimensionar cuántas líneas telefónicas necesitaremos en una instalación.

La unidad Erlang

Antes de ir a las fórmulas es necesario introducir un nuevo término llamado la unidad Erlang. Un Erlang es una unidad adimensional comúnmente utilizada para medir el tráfico telefónico por hora.

También se puede decir que un Erlang representa la utilización continua de un circuito. Es decir que 1 Erlang equivaldría a la utilización de un circuito continuamente durante una hora en un lapso de una hora de tiempo o lo que es lo mismo que el circuito estuvo siempre en uso. Así mismo 0.5 Erlangs quiere decir que en el lapso de una hora el circuito se utilizó solo 30 minutos.

Para calcular el tráfico en Erlangs se puede proceder de la siguiente manera:

Encontrar el tráfico total en horas: Es decir, sumar el tiempo de todas las llamadas durante un lapso de tiempo cualquiera y convertir este valor a horas

Encontrar el tráfico por unidad de tiempo (en horas): Es decir, dividir el total anterior para el lapso de tiempo en horas

¿Algo confundido? Veamos un ejemplo para clarificar un poco más las cosas:

Supongamos que en una empresa cualquiera entre las 9H00 y 12H00 de un día determinado se realizaron 300 llamadas con un promedio de 6 minutos por llamada y se quiere medir el tráfico en Erlangs.

Tráfico Total = Tráfico en 3 horas = 300 x 6 = 1800 minutos = 1800 minutos / 60 minutos = 30 horas (quiere decir que se hablaron 30 horas en ese lapso de tiempo)

Tráfico por hora = Tráfico Total / Lapso de Tiempo = 30 horas / 3 horas = 10 Erlangs

Hemos obtenido una medida de tráfico de 10 Erlangs.

Modelos Erlang

Ahora sí vamos a lo que nos interesa, o sea el cálculo del dimensionamiento telefónico.

En esencia existen dos modelos en las teorías de Erlang que se utilizan mucho en telefonía y son el modelo B y el modelo C. En la presente obra estudiaremos el modelo B pero recomendamos al lector recabar información del modelo C. El modelo C se utiliza para calcular probabilidades en llamadas que entran a colas así que si el lector está pensando en administrar un call center sería útil que indagara en el modelo Erlang C.

Erlang B

El modelo Erlang B es el más común y es el que usaremos en la mayoría de escenarios pues es el que se usa para determinar el número de líneas necesario. Básicamente necesitamos alimentar a la fórmula con un par de parámetros y podemos obtener el número de líneas que necesitamos. Estos parámetros son: el tráfico pico (el tráfico en la hora de mayor actividad) y el Grado de Servicio (o GOS por sus siglas en inglés).

Nota: La fórmula Erlang B asume que una llamada bloqueada es realmente bloqueada, es decir que no entra a una cola. O sea que si todas las líneas se encuentran ocupadas el llamante obtendrá tono de ocupado en lugar de ingresar a una cola. Esto es verdad para la mayoría de PBXs.

El Tráfico pico se obtiene sumando todo el tráfico en la hora de más actividad telefónica. Es útil tomar muestras no solo de un día sino de algunos días o semanas para que la información sea más exacta.

El Grado de Servicio representa la probabilidad de que una llamada sea rechazada. Su valor va de 0 a 1. Donde 1 significa el 100% de rechazo de llamadas. Algunos criterios comunes que he observado en la práctica son.

GoS | Percepción del servicio por parte del llamante
De 0 a 0.02 | De excelente a muy bueno, casi no se rechazan llamadas. El valor 0 no es posible.
De 0.03 a 0.06 | De normal a aceptable. Un valor de 0.03 a 0.04 es el más comúnmente usado.
De 0.07 a 0.10 | Malo
De 0.10 en adelante | Pésimo, Terrible. Quiere decir que el 10% de llamadas obtendrán ocupado.

Los valores anteriores de ninguna manera constituyen una regla sino más bien una guía aproximada basada en la mayoría de los casos. El Grado de Servicio va en función de la importancia de perder una llamada y esto muchas veces va en función del tipo de negocio. Por ejemplo, la importancia de perder una llamada es diferente en un hospital que en una compañía promedio.

También podría depender del departamento o unidad de negocios de una empresa. En general, el cliente, que conoce muy bien su negocio será el termómetro que nos permitirá determinar este parámetro.

A continuación la fórmula propuesta por el modelo Erlang B.

Donde,

E es el valor del tráfico pico (en Erlangs)

N es el número de líneas telefónicas

Como vemos no es algo precisamente sencillo calcular el valor de GoS y peor aún despejar N que es lo que realmente buscamos para calcular el número de líneas necesarias. Pero no hay por qué preocuparnos porque actualmente hay muchas herramientas que nos permiten calcular el valor de N de manera sencilla, desde hojas de cálculo hasta calculadoras gratuitas online. La idea de presentar la fórmula aquí es para que el lector sepa los fundamentos del cálculo de la misma lo cual siempre es útil.

Veamos algunas de estas herramientas que se encuentran disponibles de manera gratuita a través del Web.

http://www.erlang.com/calculator/erlb/

http://personal.telefonica.terra.es/web/vr/erlang/

http://www.cs.usyd.edu.au/~dcorbett/erlang.cgi

22.3 Cuando un sólo servidor no alcanza

Muchas veces una instalación es tan grande que rebasa la capacidad de un solo equipo. Para estos casos también existe una solución que nos permite dividir un Elastix en uno o más servidores. Es lo que se llama balanceo de carga.

Existen dos esquemas que se usan en la práctica.

Distribuir el trabajo en equipos especializados

Este podría ser un primer acercamiento para liberar de carga al servidor Elastix. Este esquema funciona siempre y cuando la carga no sea excesiva puesto que si lo es entonces vamos a tener que irremediablemente dividir el plan de marcado en otros equipos.

La idea consiste en migrar ciertos servicios a otros servidores. Algunos de los servicios que se pueden migrar son los siguientes.

MySQL: Esto incluye los CDRs ya que estos se almacenan también en MySQL

Antispam: Se puede levantar el servidor antispam en otro equipo y dejar el servidor de correo en el servidor Elastix principal si el volumen de emails es tolerable

Postfix: Si el volumen de correos electrónicos es elevado incluso se puede mover Postfix

Openfire: Incluso con Openfire en otro equipo es posible integrarlo con Asterisk con el plugin Asterisk-IM

La migración de estos servicios a otros equipos requiere trabajo y entendimiento de los componentes utilizados. Por ejemplo, para migrar el antispam deberemos hacer cambios al archivo master.cf que es el archivo de configuración de Postfix y migrar MySQL requerirá incluso modificar algunos archivos PHP usados por la interfaz Web de Elastix. En caso de que se decida por este esquema asegúrese de entender bien el funcionamiento de los componentes o servicios involucrados.

Distribuir el plan de marcado

En ocasiones, cuando la instalación es bastante grande, es deseable dividir el plan de marcado en más de un servidor. Más adelante en este libro explicaremos cómo distribuir el plan de marcado utilizando un adddon de Elastix llamado -Plan de Marcado Distribuido-.

23

Seguridad

Las revoluciones se producen, generalmente, en los callejones sin salida

-- Bertolt Brecht

La disponibilidad del servidor Elastix así como la privacidad de la información que maneja, como llamadas, emails, documentos de fax, entre otros, son aspectos cruciales para su correcto funcionamiento. Estos aspectos pueden ser afectados por personajes inescrupulosos con fines contrarios a los nuestros.

Por estas razones la seguridad se vuelve un aspecto fundamental que debemos estudiar en detalle. En este capítulo revisaremos los tópicos más importantes.

23.1 Algo de historia

Allá por los años sesentas unas cuantas personas, entre ellas algunos famosos hackers, se dieron cuenta que si reproducían una señal audible de 2,600 Hertz a través del auricular de un teléfono, la llamada telefónica activa se colgaba.

Se cuenta que uno de ellos, conocido bajo el pseudónimo de Joybubbles, descubrió el hecho a la edad de siete años mientras silbaba, y era capaz de reproducir esta frecuencia a su antojo solo silbando con la boca.

Años después se conoció que esta frecuencia era parte de la señalización que usaba la empresa telefónica para reiniciar una llamada telefónica. Algunos hackers se pusieron a estudiar y entender la señalización telefónica y no pasó mucho tiempo antes de que alguien se diera cuenta que podía utilizar algunos de estos -tonos- para realizar llamadas de larga distancia de manera gratuita, lo cual era como haber descubierto oro pues en ese entonces las llamadas de larga distancia eran mucho más caras que en la actualidad.

Una de estas personas fue conocida como -John Capitán Crunch- pues descubrió que un silbato que venía como obsequio dentro de una caja de cereal de una conocida marca llamada Captain Crunch producía coincidentalmente la dichosa frecuencia de 2,600 Hz.

El truco consistía en soplar el silbato para reiniciar la llamada y luego reproducir silbidos cortos para marcar el número telefónico. Así un silbido corto significaba uno, dos silbidos el número dos y así. De repente muchas personas conocían como realizar este fraude telefónico y no tuvo que pasar mucho para que algunos fabricaran cajas electrónicas que producían las señales audibles con solo marcar un teclado.

A estas cajas electrónicas se las denominó Bluebox en relación al color de la primera caja encontrada.

El hecho cobró tanto vuelo que en algún momento se comenta que Steve Wozniak y Steve Jobs, quienes después fundaran Apple Computers, se dieron a la tarea de fabricar Blueboxes. ¡Vaya detalle! En la siguiente figura se muestra el modelo de Wozniak, el cual se encuentra en exposición en el Museo de Ciencias de la Computación en USA.

Bluebox fabricado por Steve Wozniak expuesto en el Computer History Museum

Incluso existe una leyenda que cuenta que Wozniak en una ocasión llamó al Vaticano haciéndose pasar por Henry Kissinger y pidió hablar con el Papa.

¿Sucedió o no? Habría que preguntarle a Wozniak. En todo caso así fue como comenzaron los primeros trucos para burlar los sistemas telefónicos. No es de extrañarse que en la actualidad existan miles de maneras de burlar un sistema de comunicaciones y por lo tanto debemos estar muy entrenados para cuidarnos de que esto no suceda.

23.2 Tipos de amenazas de seguridad

Antes de continuar es necesario aclarar que el presente capítulo trata las amenazas de seguridad desde el punto de vista de un acto voluntario, donde existe previamente la intención de una persona, que podríamos llamar hacker, cracker, espía, atacante, intruso, o con el término adecuado según el tipo de amenaza. Este capítulo no considera amenazas de seguridad a los acontecimientos fortuitos o involuntarios como accidentes, desastres naturales, fallos espontáneos en hardware, entre otros. Si bien estos hechos pueden afectar la disponibilidad del equipo y es mejor estar preparado para afrontarlos, no es el objetivo del presente capítulo estudiarlos.

Elastix es un sistema conformado por muchos componentes de software, incluido el sistema operativo Linux. No resultaría práctico escribir un apartado de seguridad para cada uno de estos componentes, pero sí vale la pena mencionar que sólo acerca de Linux ya se han escrito muchos libros que desarrollan a fondo el tema de la seguridad. Esto nos puede dar una idea de que se trata de un tema bastante amplio y el reto será resumirlo en un solo capítulo del presente libro.

También hay que tener presente que no será posible describir todas las amenazas existentes, por lo que en el presente capítulo nos limitaremos a las más comunes.

Existen muchos enfoques bajo los cuales podríamos categorizar las amenazas de seguridad, pero en virtud de resumir, he decidido categorizar las amenazas de seguridad en dos grandes grupos:

Acceso no autorizado: En esta categoría encontramos problemas como la captura de conversaciones, muchos tipos de fraude telefónico, accesos no autorizados a cuentas de email, obtención no autorizada de privilegios de administrador, entre otros.

Pérdida de disponibilidad: Aquí encontraremos problemas como la denegación de servicio (Denial of Service o DoS), apagado físico intencional del equipo, corrupción del sistema de archivos, entre otros.

Estas tretas pueden ocasionarnos graves consecuencias como pérdida irrecuperable de información valiosa, personal incomunicado por varias horas o días, cientos o miles de dólares en consumo telefónico debido a fraude, revelación de información confidencial (información personal o secretos comerciales de la compañía usuario), entre otras.

A continuación describiremos las amenazas más comunes. Al final de la descripción de cada amenaza incluiremos las medidas preventivas que se pueden implementar para evitar que dicha amenaza ocurra.

Acceso no autorizado

El acceso no autorizado es un concepto muy amplio. No solo se refiere al acceso al servidor Elastix propiamente dicho sino también a su entorno. Por ejemplo, si no se toman las precauciones debidas alguien podría obtener acceso a la red y capturar los paquetes de voz para luego decodificarlos y escuchar las llamadas de las extensiones locales conectadas al servidor o, usando un método de captura similar, interceptar los mensajes de correo electrónico que circulan hacia o desde el servidor.

Hay que aclarar que el acontecimiento antes mencionado es un problema que puede suceder en cualquier red de datos si los administradores de la red no son precavidos.

Para ilustrar mejor lo antes dicho revisemos el siguiente caso hipotético donde se tiene un servidor Elastix muy seguro dentro de una red muy insegura.

Ejemplo hipotético de acceso no autorizado

Supongamos que usted es el administrador del servidor Elastix de una compañía de 200 empleados.

El servidor Elastix se encuentra bien protegido y usted, como administrador del servidor, está obsesionado con la seguridad del mismo: nadie, excepto usted, conoce la clave de administración del servidor, tanto la del usuario -root- como la del usuario -admin- de la interfaz Web. Al final de cada día revisa si hay actualizaciones de software para mantener al servidor actualizado y estar prevenido de cualquier -hueco- de seguridad. Adicionalmente ha instalado un firewall muy restrictivo de cara al Internet para que posibles intrusos no puedan acceder al servidor Elastix y como si esto fuera poco ha instalado el servidor en un cuarto con acceso restringido por huella dactilar.

Un buen día llega una persona a la empresa y toma asiento en la recepción de la compañía. Aprovecha sus primeros minutos para anunciarse y congeniar con la recepcionista. Está esperando que lo atiendan para una entrevista laboral, pero como llegó 30 minutos más temprano tendrá que esperar sentado en la recepción. Mientras espera, -para no aburrirse-, abre su laptop y le pregunta a la recepcionista si puede conectarse unos minutos a la red wireless de la empresa para revisar su correo electrónico. La recepcionista le facilita su clave personal de acceso. Justo antes de la entrevista le solicita a la recepcionista que por favor le imprima su currículum desde su pen drive ya que olvidó llevarlo.

Al final del día, como siempre, usted revisa el servidor y encuentra todo en orden. Se va a su casa y duerme tranquilo. Pero a la semana recibe un email burlesco de la persona que estuvo sentada en recepción, claro está ocultando su identidad a través de una cuenta de correo electrónico recién creada en algún proveedor de cuentas de correo electrónico gratuito. En el email le cuenta, que grabó todas las llamadas de la empresa en el periodo de 10 minutos y como muestra le envía una de las grabaciones adjunta en el email. No quiere nada, solo burlarse de usted y la empresa, que a propósito no lo contrató para el cargo que aspiraba.

¿Qué pudo haber ocurrido si usted revisó el servidor y no encontró ninguna pista de que alguien hubiera accedido? Es más, ¿qué pudo haber ocurrido si usted, como administrador del servidor Elastix, es obsesionado con las medidas de seguridad?

Lo que ocurrió fue que el intruso utilizó su red wireless para -oler- la red y capturó algunas llamadas cuyos paquetes estaban circulando por el dispositivo al que tuvo acceso. Luego decodificó los paquetes RTP con un decodificador g.711 y posteriormente grabó los archivos en su disco duro con formato mp3.

Finalmente, con el pretexto de querer imprimir algo, intentó instalar un software troyano en la computadora de la recepcionista. Por suerte esto último no le funcionó debido a que el antivirus en la máquina local se lo impidió, caso contrario habría recibido reportes periódicos de claves digitadas por la recepcionista y el problema hubiera podido ser mayor al que la empresa se enfrenta ahora.

Como vemos en el ejemplo anterior no solo es cuestión de preocuparnos por el servidor Elastix sino también por su entorno. El ejemplo anterior ilustra el caso de captura de llamadas telefónicas a través de la red interna de datos, pero pensemos en lo sencillo que podría resultar para un individuo inescrupuloso, disfrazado de técnico de la empresa telefónica, instalar un grabador de llamadas en las líneas análogas de la PSTN. Ni siquiera tendría que ingresar a su empresa sino que probablemente lo encontraríamos subido a un poste telefónico cercano (en caso de que se use ese tipo de infraestructura de distribución en la ciudad donde se encuentra la empresa). Si queremos ponernos más nerviosos todavía pensemos que, de contar con las herramientas adecuadas, ni siquiera es necesario que el intruso tenga que acudir a la recepción y solicitar las credenciales de acceso al dispositivo wireless. Le hubiera tomado algo más de tiempo pero podría haberlo hecho (crackeando el protocolo WEP) desde el asiento de su auto en el estacionamiento de la empresa.

A continuación explicaremos esta y otras amenazas comunes relacionadas con acceso no autorizado.

Captura de llamadas a nivel de VoIP

En algunos casos es posible escuchar tráfico VoIP que circula por la red con las herramientas adecuadas. Después de todo, los paquetes RTP se encuentran codificados con codecs conocidos y por lo tanto la decodificación de los mismos no es una tarea que complique la vida a un hacker experimentado. Además, los codecs de audio no fueron concebidos con el objetivo de encriptar la comunicación sino más bien de comprimir la voz y evitar errores de transmisión.

Si podemos capturar los paquetes RTP de una llamada podemos utilizar herramientas para convertir estos paquetes en audio que podamos escuchar.

Adicionalmente recordemos que el protocolo SIP es un protocolo de texto o sea que si logramos capturar paquetes SIP de la red podremos además tener acceso a información como Caller IDs, comandos y respuestas SIP.

Existen aplicaciones especializadas que facilitan la vida de los hackers cuando se pretenden hacer escuchas de llamadas VoIP desde equipos intrusos. Citaremos tres de las más conocidas.

VoIPong

Wireshark (con el plugin para análisis VoIP)

Oreka

VoIPong rastrea la red en busca de llamadas VoIP y una vez detectadas permite guardar las llamadas en formato wav. VoIPong soporta g.711. El sitio oficial de VoIPong es http://www.enderunix.org/voipong

Wireshark (el antiguo proyecto Ethereal) ahora trae soporte para análisis de llamadas VoIP y nos permite grabar el payload (la voz) de los paquetes RTP en formato de audio crudo. Vale decir que Wireshark también constituye una herramienta de análisis poderosa y muy útil que no debe faltar en el maletín del ingeniero de VoIP.

Finalmente Oreka es un proyecto algo más complejo pero que nos permite incluso decodificar codecs como GSM e iLBC. Oreka nos puede proveer incluso de una interfaz Web para administrar las llamadas. Para más información el sitio de Oreka se encuentra en http://oreka.sourceforge.net/

En todos estos casos estamos suponiendo que se quieren capturar llamadas de un equipo remoto. Muchas veces esto es posible debido a que, para conectar los equipos de voz, se utilizan hubs en lugar de Switches, malas configuraciones en el Switch (port mirroring) o redes inalámbricas inseguras.

Medidas preventivas recomendadas: no utilizar hubs o redes inalámbricas inseguras, encriptar la VoIP, usar VPNs.

Fraude telefónico

Cada vez se vuelve más común este tipo de amenaza y existen muchas técnicas utilizadas por los hackers para traficar sus llamadas telefónicas a costa nuestra.

En algunas ocasiones inclusive la treta podría originarse de dentro de la misma compañía usuaria de Elastix por un empleado no tan hacker. Imaginémonos el siguiente ejemplo hipotético.

Un empleado de una compañía usuaria de Elastix ha conseguido novia por Internet en un país remoto y la llama frecuentemente. El consumo de su número de teléfono celular ha subido producto de estas llamadas pues le cuestan $0.50 por minuto y pronto descubre que desde el softphone instalado en la laptop de su jefe puede tener acceso a llamadas internacionales sin restricciones.

Le dice entonces a su jefe que el siguiente sábado acudirá a la oficina para trabajar en algunos proyectos atrasados, lo cual su jefe toma con beneplácito.

El sábado acude a la empresa pero no a trabajar en los proyectos atrasados. En lugar de esto copia el softphone de su jefe a su computador, incluidos todos los archivos de configuración que contienen las credenciales de la cuenta SIP de su jefe. Como su jefe no va a trabajar los sábados no ocurrirán conflictos con el softphone de su jefe pues su laptop no estará encendida.

Luego se da cuenta que no hace falta acudir los sábados pues tiene acceso a la red de la empresa a través de una VPN así que también enciende el softphone todos los días por las noches para conversar con su novia.

Hasta ser descubierto, luego de casi dos meses, consumió más de $1,000 dólares en llamadas telefónicas. En un primer momento para los directivos de la compañía no resulta obvio quién es el empleado detrás de estas llamadas, pues recordemos que se encuentra enmascarado con la extensión del softphone de su jefe, por lo que detener al culpable toma más tiempo de lo normal.

El caso anterior puede considerarse no tan grave si consideramos que se trata del consumo telefónico personal de un solo usuario. Pero ¿qué pasa cuando se tratan de muchos usuarios y miles de llamadas? Veamos este otro ejemplo.

Un lunes el administrador de un servidor Elastix acude a trabajar y pronto le reportan que no se pueden realizar llamadas internacionales. Aparentemente el gerente necesita realizar una llamada importante así que el asunto es de prioridad. Inmediatamente ingresa al servidor Elastix por consola y activa la depuración de SIP desde el CLI. No le toma mucho darse cuenta de que la troncal SIP que tiene configurada con su proveedor de llamadas vía Internet retorna un mensaje de llamada no autorizada. En seguida llama al proveedor y la persona que lo atiende le dice que durante el fin de semana se realizaron un número inusual de llamadas telefónicas desde su equipo y si quiere recuperar el servicio debe autorizarlos, previo pago de la deuda pendiente.

Hasta allí no se alarma mucho. Entonces acude a revisar el reporte de detalle de llamadas (CDRs) para confirmar lo que le dijeron del proveedor. Hay miles de llamadas a Cuba y Rusia realizadas durante el fin de semana. ¡El total de la factura supera los $16,000!

Le dan casi las 6 de la mañana del siguiente día revisando los logs de Asterisk y finalmente averigua lo que ocurrió. La extensión 1234 con clave 1234 que había usado la semana anterior en unas pruebas internas fue el hueco por donde ingresó el intruso. Al revisar los logs se da cuenta de que, dado que su equipo se encontraba expuesto al Internet, el intruso utilizó algún tipo de software para tratar de autenticarse vía SIP buscando al azar cuentas con claves débiles. Luego de cientos de intentos dio con la obvia extensión y clave que él mismo había configurado.

El ejemplo anterior es un caso grave pero que puede suceder si no se tiene cuidado al momento de crear extensiones expuestas a Internet.

Medidas preventivas recomendadas: No usar claves débiles, utilizar firewall para proteger el equipo desde Internet, mantener actualizado el equipo.

Sniffing

Sniffing es una práctica que consiste en -olfatear- o capturar los paquetes que circulan por la red. Se trata del mismo caso que fue ilustrado en -captura de llamadas a nivel de VoIP- solo que sniffing es el término más general y no solo se refiere a llamadas telefónicas sino a cualquier tipo de paquete de red que contenga información. De este modo se pueden capturar correos electrónicos, conversaciones de chat, entre otros.

Para poder capturar el tráfico se utiliza una aplicación llamada Sniffer y existen algunas alternativas disponibles en Internet por lo que esta práctica se ha convertido en una tarea no tan difícil de llevar a cabo por hackers.

Luego de capturar el tráfico el atacando lo analizará dependiendo de lo que quiera hacer. Por ejemplo si el tráfico corresponde a una llamada telefónica SIP es probable que el atacante analice la información de señalización para recabar información de Caller IDs principalmente. También es posible que decodifique las tramas RTP y con esto logre inclusive reproducir la llamada y escucharla.

Nota: Una manera de verificar si existe un sniffer ejecutándose en nuestro servidor Elastix es verificar si la tarjeta de red se encuentra en modo -promiscuo-. Esto se puede hacer de manera sencilla analizando la salida del comando ifconfig. Sin embargo, muchas veces el atacante instala el sniffer en un equipo diferente al servidor Elastix.

Obtención de privilegios de -root-

Algunos paquetes de software pueden presentar vulnerabilidades que permitan a otros obtener privilegios de -root-. Esto es algo relativamente difícil de conseguir, más todavía si se realiza por un hacker inexperto. Sin embargo, si llega a suceder es en extremo peligroso, puesto que el hacker ha obtenido los privilegios máximos sobre el equipo.

Luego de esto el intruso podría apagar el equipo (algo no muy inteligente pero que nos dejaría fuera de servicio) o inclusive eliminar archivos.

Pérdida de disponibilidad

Como dijimos antes, los ataques de pérdida de disponibilidad que describiremos aquí no están relacionados con casos fortuitos o involuntarios sino más bien actos premeditados realizados por personas inescrupulosas.

Denegación de servicio

En seguridad informática, un ataque de denegación de servicio, también llamado ataque DoS (de las siglas en inglés Denial of Service), es un ataque que causa que un servicio o recurso sea inaccesible a los usuarios legítimos. Normalmente provoca la pérdida de la conectividad de la red por el consumo del ancho de banda de la red de la víctima o sobrecarga de los recursos computacionales del sistema.

Se genera mediante la saturación de los puertos con flujo de información, haciendo que el servidor se sobrecargue (normalmente el CPU) y no pueda seguir prestando servicios, por eso se le dice "denegación", pues hace que el servidor no de abasto a la cantidad de conexiones.

Realizar un ataque de denegación de servicio no es una misión complicada. Existen algunas herramientas gratuitas en Internet que permiten iniciar ataques de este tipo.

Un problema con este tipo de ataques es que algunas veces es difícil detectarlos pues pueden confundirse con tráfico normal.

Ataques de inundación SIP (SIP Flooding)

SIP Flooding o inundación de SIP es un tipo de ataque de denegación de servicio que consiste en bombardear un servidor SIP como Asterisk de paquetes INVITE. Como ya vimos antes estos paquetes sirven para iniciar una llamada y por lo tanto el servidor SIP, al recibir uno de estos paquetes, se quedará esperando respuesta del supuesto usuario. Mientras el servidor espera recibir una respuesta que nunca llegará muchas más falsas llamadas intentan hacer más conexiones.

Si un alto volumen de estas falsas llamadas ingresa al equipo pueden ocasionar una Denegación de Servicio.

Hay que tener mucho cuidado con esto pues generar un ataque de SIP flooding no es tan difícil. Existen herramientas que fueron creadas con buenas intenciones (ej. generadores de tráfico para pruebas o para hacer análisis de carga) que pueden ser utilizadas con fines equivocados. Una de estas herramientas es SIPP que se encuentra disponible gratuitamente desde el sitio http://sipp.sourceforge.net y normalmente se usa para generar tráfico SIP para pruebas.

SIPP puede configurarse para generar miles de llamadas hacia un servidor SIP.

Aplicación SIPP en acción

23.3 Medidas preventivas

Seguridad física

La seguridad física tiene que ver con aspectos tangibles como por ejemplo si alguien desconecta el cable de poder del servidor o alguien derrama agua sobre el equipo de manera deliberada.

Muchos pensarán que esto es algo obvio a lo cual no hay que dedicarle un apartado especial, pero es importante recordar que muchos de los problemas de seguridad caen en esta categoría ya que no se necesita ser un experto para vulnerar el equipo, basta con acceso físico al equipo y, ya sea mala intención o el error humano involuntario.

Limitación del acceso físico al servidor

Para evitar en gran medida los problemas de seguridad física es muy importante limitar el acceso físico al servidor Elastix. Normalmente esto se logra mediante llave o un sistema de autenticación electrónico con acceso a pocas personas.

Es muy importante complementar esto con un procedimiento riguroso de uso del acceso pues de nada sirve que la llave la tenga una sola persona si esta persona deja la llave siempre olvidada en el comedor de la empresa.

NO dejar sesiones de consola abiertas

Es muy común ver que hasta los mismos administradores de sistemas suelen dejar las sesiones de consola abiertas incluso durante días. En ocasiones hasta con información crítica visible en la pantalla del computador (por ejemplo el comando top ejecutándose) o con una consola del CLI abierta. Esto es análogo a dejar las puertas del automóvil abiertas de par en par.

Por más confiado que uno se encuentre en principio nunca debe dejar una consola abierta si se va a alejar del computador, peor si se ha accedido como -root- porque le estamos dando total acceso a cualquiera que se siente frente al computador.

Bloquear el reinicio

Algunos BIOS nos permiten configurar una contraseña de arranque. En muchas ocasiones esto puede frenar intentos de hackers que podrían querer reiniciar el computador para usar nuevos kernels, entre otras cosas.

Nota: Esta medida puede ser útil en la mayoría de los casos, pero hay que tener en cuenta que esto también nos impedirá reiniciar el equipo remotamente a nosotros también. Claro está, a menos que tengamos un equipo KVM sobre IP que nos permita ingresar la contraseña del BIOS remotamente.

Seguridad a través de la red

Apagando los servicios que no vamos a usar

Elastix es una distro rica en funcionalidad. Para proveer toda esta funcionalidad muchos paquetes de software son empaquetados juntos con la distro.

Sin embargo, en muchos casos no necesitamos de todos ellos para lograr lo que queremos con Elastix. Es por esto que una de las primeras tareas luego de instalar Elastix consiste en apagar o inclusive desinstalar los servicios que no vamos a usar.

Si no se va a usar servidor de Email se pueden apagar los siguientes servicios.

postfix

cyrus-imapd

spamassassin

mailman

saslauthd

Si no se va a usar mensajería instantánea se puede apagar el servidor de mensajería Openfire.

Otros servicios que pueden apagarse.

vsftpd (Servidor FTP)

tftp (este servicio trabaja bajo xinetd y es necesario en caso de utilizar provisionamiento en algunos modelos de teléfonos como Polycom)

xinetd

Firewalls

Un firewall básicamente es un componente de software que nos permite establecer ciertas políticas de bloqueo a puertos de red que no queremos que sean visibles del otro lado, normalmente desde Internet. Como algunos lectores estarán pensando, realmente un firewall es mucho más que eso, pero lo vamos a mantener simple aquí.

Elastix trae incorporado un poderoso firewall llamado iptables. Iptables se ha vuelto el firewall de facto en la mayoría de distribuciones Linux ya que se encuentra incorporado en el kernel mismo.

En el presente apartado configuraremos un firewall básico residente en el mismo servidor Elastix. En realidad siempre es recomendable que el firewall sea un componente externo al servidor Elastix, pero si no tenemos esa opción instalarlo en el propio Elastix es un excelente plan B.

Ejecutando reglas de Iptables

No entraremos en detalles del uso del comando Iptables. Dejamos al lector la importante tarea de adquirir esos conocimientos adicionales. Lo que sí haremos es copiar algunas reglas básicas que se pueden usar para proteger nuestro servidor de comunicaciones. Recordar que el orden de las reglas es importante así como también ejecutar todas las reglas, en especial la última que es la regla que bloquea todos los demás puertos.

Nota: Si no hemos configurado un firewall a través de Iptables antes es recomendable que nos encontremos frente al servidor. Si lo hacemos remotamente y ejecutamos las reglas de manera incorrecta podríamos perder conexión con el equipo.

En fin, vamos a mostrar las reglas. En los siguientes ejemplos se ha supuesto que la tarjeta de red pública es la eth0. Si esto no es así en el caso del lector se deberá modificar este parámetro.

Aceptando el tráfico SIP:

# iptables -A INPUT -p udp -m udp -i eth0 --dport 5060 -j ACCEPT

Aceptando el tráfico IAX2:

# iptables -A INPUT -p udp -m udp -i eth0 --dport 4569 -j ACCEPT

Aceptando el tráfico RTP (Suponiendo que no se ha alterado el archivo rtp.conf):

# iptables -A INPUT -p udp -m udp -i eth0 --dport 10000:20000 -j ACCEPT

Aceptando tráfico MGCP (solo aplicar si es que se va a usar. En la mayoría de los casos no es necesario):

# iptables -A INPUT -p udp -m udp -i eth0 --dport 2727 -j ACCEPT

Aceptando el tráfico de mensajería instantánea (si es que se va a acceder desde fuera):

# iptables -A INPUT -p tcp -i eth0 --dport 9090 -j ACCEPT

Aceptando el tráfico del servidor de correo y POP/IMAP:

# iptables -A INPUT -p tcp -i eth0 --dport 25 -j ACCEPT

# iptables -A INPUT -p tcp -i eth0 --dport 110 -j ACCEPT

# iptables -A INPUT -p tcp -i eth0 --dport 143 -j ACCEPT

Aceptando tráfico Web (HTTP y HTTPS) para poder visitar la interfase administrativa de Elastix:

# iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT

# iptables -A INPUT -p tcp -i eth0 --dport 443 -j ACCEPT

Finalmente denegando el acceso a todo lo demás:

iptables -A INPUT -p all -i eth0 -j DROP

Ya habiendo visto el patrón de las reglas de Iptables dejamos al lector la tarea de predecir cómo abrir otros puertos como SSH (puerto 22), MySQL (puerto 3306), entre otros servicios que podrían ser útiles. Claro está, la premisa es que mientras menos puertos expuestos a los hackers mejor.

Al final es deseable verificar si las reglas se aplicaron bien. Para hacer esto podemos ejecutar el comando iptables con la opción -L.

[root@localhost ~]# iptables -L

Chain INPUT (policy ACCEPT)

target prot opt source destination

ACCEPT udp -- anywhere anywhere udp dpt:sip

ACCEPT udp -- anywhere anywhere udp dpt:iax

ACCEPT udp -- anywhere anywhere udp dpts:ndmp:dnp

ACCEPT tcp -- anywhere anywhere tcp dpt:websm

ACCEPT tcp -- anywhere anywhere tcp dpt:smtp

ACCEPT tcp -- anywhere anywhere tcp dpt:pop3

ACCEPT tcp -- anywhere anywhere tcp dpt:imap

ACCEPT tcp -- anywhere anywhere tcp dpt:http

ACCEPT tcp -- anywhere anywhere tcp dpt:https

DROP all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)

target prot opt source destination

Chain OUTPUT (policy ACCEPT)

target prot opt source destination

La salida que obtengamos debería verse algo similar a la anterior. Si vemos que algo anda mal podemos evacuar todas las reglas con el comando iptables -F y empezar de nuevo.

IDSs e IPSs

Un tipo más avanzado de estrategia para bloquear ataques de hackers es lo que se llama IDS o Intrusión Detection System. Un concepto similar es el de IPS o Intrusión Prevention System. La diferencia entre los dos es que mientras el IDS solo detecta intrusos el segundo toma medidas para evitar que el ataque continúe.

Básicamente estas tecnologías tratan de ir más allá de un simple bloqueo de puertos como vimos en el apartado de firewalls y se dedican a observar la actividad de red en busca de patrones de ataques conocidos. Estos patrones han sido almacenados previamente en lo que se conoce como bases de datos de patrones (fingerprint databases). Como los patrones cambian día a día se deben actualizar de cuando en cuando para que estas aplicaciones estén al tanto de patrones nuevos.

Un IDS nos notificará cuando encuentre un patrón de ataque conocido mientras que un IPS irá más allá y podría ejecutar automáticamente una regla de firewall específica para el ataque recibido con el objetivo de bloquear al posible intruso.

A partir de Elastix 2.2 se incluye en la distro un conocido IPS llamado fail2ban. Todavía no existe una interfaz gráfica en Elastix para configurarlo por lo que habrá que configurar fail2ban de manera manual a través de un terminal de consola. Recomendamos al lector investigar acerca del uso de fail2ban.

Cambiar las claves por omisión en Elastix (aplica para versiones anteriores a 2.0)

Realmente esto NO es necesario a partir de Elastix 2.0 debido a que no existen claves por omisión. Todas las claves son generadas por el usuario la primera vez que el servidor Elastix se inicia.

En versiones anteriores a 2.0 es muy importante cambiar las claves por, pues en caso de no hacerlo cualquiera puede acceder a nuestro equipo libremente y eso sin duda es muy peligroso.

Algunas claves importantes de cambiar son las siguientes.

Sistema | Valor por omisión usuario/clave | Dónde cambiar
Interfaz Web Elastix | admin/palosanto | Interfaz Web, menú Sistema ->Usuarios
FreePBX | admin/admin | Interfaz Web de FreePBX
FOP | admin/eLaStIx.2oo7 | /etc/amportal.conf
MySQL | root/eLaStIx.2oo7 | Comando mysqladmin
SugarCRM | admin/password | Interfase Web de SugarCRM
vTiger | admin/admin | Interfase Web de vTiger

Usar switches en lugar de hubs

A simple vista un hub y un switch son dispositivos bastante parecidos pero esa no es la realidad.

Un hub es un dispositivo de red bastante sencillo cuya misión es repetir cada paquete de datos que llega por un puerto determinado en todos los demás puertos. Por esta razón muchas personas también lo llaman repetidor. Como es de esperar este comportamiento genera muchas colisiones por lo que adicionalmente un hub es capaz de enviar una señal de colisión a sus puertos para indicarles que dejen de transmitir por un momento.

Un switch en cambio es un dispositivo un poco más inteligente y cuando un equipo conectado en uno de sus puertos trata de enviar paquetes a otro, en lugar de repetir el paquete en todos los demás puertos crea una conexión únicamente entre los dos equipos involucrados en la comunicación. Esto parece algo simple pero es una gran ventaja pues mejora enormemente el rendimiento de la red pues ya no es necesario enviar información innecesaria. Evidentemente se consigue una reducción en el consumo de ancho de banda de la red.

Foto de hub marca NETGEAR de 4 puertos

Sin embargo la ventaja de usar un Switch no solo radica en el ahorro de ancho de banda. Por su naturaleza un HUB envía información adicional no necesaria a todos los equipos de la red, o sea comunicaciones de otros equipos de red que no deberían caer en manos de otros equipos no involucrados en la conversación. Normalmente un equipo determinado desecha o filtra esa información innecesaria y allí acaba el problema PERO cuando los hackers entran en escena esa información que antes era indeseable se vuelve valiosa información en manos de estas personas ya que de allí pueden tratar de obtener textos de email, mensajes de IM e incluso pueden grabar llamadas telefónicas de terceros.

Por suerte en la actualidad cada vez se encuentran menos hubs en el mercado, pero nunca está demás hacer la recomendación de no utilizar hubs en implantaciones de VoIP.

Encriptación de la VoIP

Para evitar escuchas o -pinchazos- telefónicos a nivel de VoIP tenemos la alternativa de encriptar la comunicación. Existen algunas opciones que explicaremos a continuación.

SRTP

El protocolo SRTP (Secure RTP) se encuentra oficialmente soportado en Asterisk a partir de la versión 1.8. Elastix incluye esta versión de Asterisk con soporte para SRTP a partir de su la versión 2.2.

Para más información de este protocolo se puede consultar el volumen 1 de la presente obra.

VPNs

Al momento esta es mi manera preferida de encriptar la comunicación IP. Las VPNs son ampliamente usadas y existe un proyecto de código abierto muy bueno llamado OpenVPN que funciona sobre Linux y por ende sobre Elastix.

Una VPN (Virtual Private Network) o Red Privada Virtual es un concepto que nos permite simular una red privada sobre una red pública como el Internet. Para poner un ejemplo una Empresa X tiene oficinas en varias ciudades llamadas A, B y C, y estas ciudades se encuentran conectadas entre sí a través de Internet. Sucede que esta empresa desea que todos los computadores y equipos de red de todas estas ciudades se encuentren dentro del mismo segmento de red privada 192.168.100.X. De esta manera se podrán compartir impresoras entre ciudades pues VIRTUALMENTE estas impresoras se encontrarían en la misma ubicación o segmento de red. Adicionalmente las ciudades B y C podrán alcanzar el servidor Elastix que se encuentra en la ciudad A desde un IP interna (no pública).

Todo suena muy bonito pero enviar las comunicaciones internas o privadas a través de un medio público como el Internet suena algo riesgoso ¿verdad? Bueno, para que esto sea posible de manera segura existe un concepto llamado tunneling que nos permite que estas comunicaciones transiten por la red pública de manera encriptada de tal forma que se asocia esta tecnología con un túnel virtual ya que se encuentra aislado del exterior. Para establecer el túnel virtual se utilizan protocolos seguros.

En concreto se puede establecer una VPN para meter en dicha red todos los dispositivos de voz y de esta manera hacer que las comunicaciones de voz viajen seguras. Existen en la actualidad algunos modelos de teléfono que soportan incluso VPNs por lo que los podríamos conectar directamente con el servidor Elastix. Por ejemplo:

Snom 370

ATCOM 530

En caso de que usemos softphones podemos establecer una VPN entre el PC donde se encuentra el softphone y el servidor Elastix.

Encriptación IAX

Esta es muy probablemente la manera más sencilla de encriptar la comunicación entre dos servidores Asterisk.

Cuando IAX fue concebido se pensó en estos problemas de violación a la privacidad y se añadió soporte nativo para encriptación de llamadas. Habilitar este soporte es sumamente sencillo pues consiste en añadir un parámetro en la configuración IAX.

; El siguiente parámetro habilita encriptación IAX.

; También se puede usar el parámetro encryption=yes

encryption=aes128

Nota: Pese a que este método activa encriptación IAX y por ende puede ser útil en comunicaciones entre 2 o más servidores Asterisk; no conozco aún de teléfonos que implementen esta características. Si el lector conoce de alguno le agradecería que me lo haga saber para actualizar esta información.

Actualizaciones

Cuando una nueva versión de un paquete de software es lanzada al público se pone al análisis de personas que tratan de vulnerarla. Más aún si se trata de una aplicación que puede ser alcanzable a nivel de red como es el caso de Asterisk, Postfix, Cyrus, etc.

Cuando se descubre una de estas vulnerabilidades los desarrolladores sacan nuevas versiones y recomiendan la actualización del software. Por lo general los bugs que comprometen la seguridad del equipo se marcan como críticos y conllevan a que se disponga de la corrección de manera expedita.

Es por esta razón que es muy importante actualizar los servicios de red de cuando en cuando y de esta manera estar prevenido de posibles fallos de seguridad que puedan contener los paquetes de software. También es muy útil estar al tanto de las alertas de seguridad que publican los distintos fabricantes de software. Por ejemplo, Asterisk publica las suyas en http://www.asterisk.org/security

No entraremos en mucho detalle aquí de cómo proceder con las actualizaciones pero les recomendamos utilizar la interfaz Web para actualización de paquetes que viene con Elastix o en su defecto utilizar el comando yum explicado en el capítulo 3 de la presente obra.

23.4 Monitoreo y auditorías de seguridad

Las auditorías de seguridad se suelen realizar cuando se sospecha que un servidor ha sido hacheado o también puede ser considerada como una práctica preventiva. Como resulta obvio lo recomendable es que se realice periódicamente para detectar a tiempo problemas de seguridad que podrían poner en riesgo nuestros equipos.

Existen algunas prácticas comunes indispensables en una auditoría de seguridad. Explicaremos algunas de ellas que considero importantes.

Exploración (scanning) de puertos de red

En muchas ocasiones sobre el equipo atacado, el atacante instala software que utiliza servicios de red. Es relativamente sencillo verificar esto desde el mismo equipo atacado mediante el comando netstat. Sin embargo en algunos casos este comando no nos ayudará mucho pues el atacante puede haber modificado el comando para que nos muestre lo que a él le interesa que pensemos o sea -que el equipo está limpio-. Por lo tanto es necesario también inspeccionar el equipo desde fuera y para esto podemos usar el comando nmap ejecutado desde un equipo remoto.

Un puerto sospechoso en equipos vulnerados suele ser el 6666 o 6667 que son puertos relacionados con servidores IRC pues sucede que una costumbre de los hackers es instalar un servidor IRC para, a través de una simple aplicación de chat IRC, controlar el servidor mediante comandos.

Veamos cómo luce la salidas de un nmap en un equipo Elastix sano desde la red interna y no protegido por firewall.

[root@remote ~]# nmap elastix34.example.com

Starting nmap 3.81 ( http://www.insecure.org/nmap/ ) at 2008-11-16 23:18 ECT

Interesting ports on elastix34.example.com:

(The 1647 ports scanned but not shown below are in state: closed)

PORT STATE SERVICE

21/tcp open ftp

22/tcp open ssh

25/tcp open smtp

80/tcp open http

110/tcp open pop3

143/tcp open imap

443/tcp open https

993/tcp open imaps

995/tcp open pop3s

2000/tcp open callbook

3306/tcp open mysql

4559/tcp open hylafax

7070/tcp open realserver

9090/tcp open zeus-admin

Nmap finished: 1 IP address (1 host up) scanned in 4.556 seconds

Revisión de logs del sistema

Revisar los logs del sistema siempre es útil aunque en muchas ocasiones el hacker tratará de borrarlos para que no veamos su actividad. En todo caso ver un log borrado también puede ser útil pues puede confirmar nuestras sospechas de que el equipo ha sido vulnerado.

Algunos logs que son interesantes de revisar:

/var/log/messages - Por información general como nuevos usuarios creados por el hacker o mensajes de ERROR inusuales

/var/log/maillog - Por si el hacker intentó ingresar por el servidor de correos

/var/log/httpd/error_log* - Por si el hacker intentó ingresar por el servidor Apache

La salida del comando dmesg

El historial de comandos ejecutados. Para el usuario actual se puede ejecutar el comando history

Revisión de rootkits

Muchas veces es difícil darnos cuenta si un hacker ha ingresado al equipo pues estas personas suelen instalar un conjunto de herramientas solo con el fin de hacerlos más invisibles a nuestras inspecciones. Entre esas herramientas constan versiones alteradas de comandos del sistema que muestran salidas modificadas para que los procesos ejecutados por el hacker queden ocultos a nuestra vista.

También suelen instalar programas para inspeccionar nuestro equipo o para controlarlo (como los servidores IRC de los que hablamos antes).

En general a este conjunto de utilerías y herramientas que el hacker instala en nuestro servidor se le denomina rootkit.

Por suerte existe un antídoto para este mal y se llaman buscadores de rootkits.

Un buscador de rootkits es un paquete de software que ejecuta una serie de revisiones por rootkits conocidos o patrones típicos de incursiones de hackers, permitiéndonos descubrir el tipo de ataque realizado y en ocasiones hasta la manera de eliminar al hacker del sistema.

Normalmente un buscador de rootkit contiene su propio set de comandos de sistema para no utilizar los comandos disponibles en el servidor porque estos pueden estar adulterados.

A continuación un par de buscadores de rootkits conocidos y de libre uso:

Chkrootkit (http://www.chkrootkit.org)

Rkhunter (http://www.rootkit.nl)

Auditoría avanzada con Nessus

Nessus es un scanner que rastrea un equipo en busca de vulnerabilidades. Existen listas públicas de vulnerabilidades mantenidas por algunas organizaciones y Nessus se basa en ellas.

Primero trata de determinar a través de la red los servicios que ejecuta el equipo examinado abriendo conexiones a sus puertos (de manera similar a nmap) y si encuentra uno trata de determinar el software que se encuentra corriendo detrás y su versión. Para esto usa una base de datos interna de lo que llama -huellas- puesto que la manera como un software responde por la red puede darnos información de la versión del mismo. Por ejemplo tratemos de iniciar una sesión al puerto 25 de un servidor Elastix.

[root@apps ~]# telnet elastix.example.com 25

Trying elastix.example.com…

Connected to elastix.example.com.

Escape character is '^]'.

220 elastix.example.com ESMTP Postfix

Como podemos ver solo con el simple hecho de abrir una conexión ya nos hemos enterado de que Postfix se encuentra allí. Sin embargo, esto es algo evidente. Nessus conoce hechos menos obvios que le permite conocer en muchos de los casos la versión que estamos ejecutando.

Finalmente, conociendo el software y su versión, Nessus tratará de buscar en su base de datos de vulnerabilidades si existen vulnerabilidades para estas versiones de software. En caso de encontrarlas nos alertará.

Este proceso toma su tiempo pero al final Nessus nos preparará de manera automática un reporte de los paquetes de software que presentan problemas y que deberíamos actualizar. Tener a Nessus trabajando para nosotros es como haber contratado un experto de seguridad en nuestra organización.

Para más información de Nessus el lector puede seguir este link http://www.nessus.org

Monitoreo avanzado con Nagios

El monitoreo constante de un servidor Elastix puede marcar la diferencia en cuanto a seguridad. Es una acción preventiva que nos puede ahorrar un dolor de cabeza.

Existe una aplicación bastante útil para automatizar este proceso y su nombre es Nagios. Nagios es un proyecto de código abierto que puede configurarse para monitorear diversos parámetros como uso de ancho de banda, uso de memoria, carga de CPU, temperatura del CPU, uso de disco duro, carga de la cola de emails e inclusive, con la configuración adecuada, parámetros de Asterisk como número de llamadas concurrentes, etc.

¿De qué me sirve esto?

Bueno, muchas veces los ataques de hackers van acompañados del uso excesivo de recursos como por ejemplo el ancho de banda.

En ocasiones a los hackers no les interesa si el equipo es un servidor de VoIP, base de datos o cualquier otra cosa. Basta con que tenga un buen acceso Internet para que el fulano lo vea atractivo pues lo puede utilizar de plataforma para vulnerar a su vez a otros equipos. Recordemos que muchos ataques DoS se consiguen enviando grandes cantidades de información.

Por lo dicho, en muchos casos resulta útil monitorear algunos recursos del servidor y en caso de que el uso de estos recursos crezca de manera inusual se puede configurar Nagios para que nos envíe una alerta vía email y poder tomar medidas correctivas para evitar daños mayores.

23.5 Menú de seguridad en Elastix 2.0

El Menú de seguridad se encuentra disponible en Elastix 2.0 y consta de 3 módulos que nos ayudarán en nuestra tarea de mantener seguro nuestro servidor Elastix.

Los módulos que forman parte del menú de seguridad en Elastix son los siguientes:

Firewall

Auditoría de Accesos

Claves débiles

Configuraciones de Seguridad Avanzada (Disponible a partir de Elastix 2.2)

Firewall

Contiene un firewall sencillo basado internamente en iptables que nos permite añadir reglas de manera gráfica e intuitiva. Por omisión se incluye un conjunto de reglas de firewall básicas. Sin embargo, estas reglas se encuentran inicialmente inactivas, debemos habilitar el firewall dando clic en el botón -Activar Cortafuegos-.

Módulo de firewall incluido en Elastix

Auditoría de Accesos

Básicamente se trata de un log que nos permite conocer los qué usuario ingresó a la interfaz Web y a qué hora.

Claves Débiles

Este módulo nos alerta cuando se detecta que la contraseña de una extensión es débil. Esto puede significar que la clave es muy corta o basada en diccionario.

Configuraciones de Seguridad Avanzada

Este módulo se incluye a partir de Elastix 2.2 y aquí se pueden configurar algunos parámetros de seguridad como la habilitación del acceso a la interfaz no embebida de FreePBX y también se puede administrar la contraseña para accederlo.

Nota: A partir de Elastix 2.2 la interfaz no embebida de FreePBX se incluye deshabilitada por omisión. Esto se hace así luego de conocerse de un par de problemas de seguridad a través de esta útil herramienta.

Módulo de configuraciones de seguridad avanzada

24

Depuración Avanzada

Yo he preferido hablar de cosas imposibles, porque de lo posible se sabe demasiado

-- Silvio Rodriguez

24.1 Introducción

Muchas veces encontramos un bug o comportamiento poco usual en Asterisk (o cualquier otro paquete de software) y luego de rastrear el problema por mucho tiempo sin encontrar la respuesta caemos en la desazón.

En ese momento tal vez quisiéramos meternos dentro del software y entender qué está ocurriendo. La buena noticia es que en cierto modo eso es posible ya que existen herramientas que nos permiten lograr en parte ese cometido. En el presente capítulo estudiaremos estas herramientas llamadas depuradores.

Un depurador es un programa que nos permite examinar la ejecución de un programa a un nivel de detalle mayor que el habitual, permitiéndonos con esto encontrar errores que de otro modo resultarían difíciles de hallar. Inclusive nos brindan la posibilidad de examinar qué estuvo ocurriendo en el momento en que un programa se -colgó-.

En el presente capítulo presentaremos dos alternativas de herramientas de depuración como lo son strace y gdb. La primera es una herramienta ligera de uso relativamente fácil que puede ser usada en primera instancia mientras que la segunda es una herramienta mucho más completa cuyo uso requiere un poco más de estudio.

A pesar de que el objetivo primario de este capítulo es la depuración de Asterisk los conceptos aquí descritos pueden ser aplicados a cualquier programa.

¿Qué hacer cuando Asterisk se comporta mal?

Cuando ocurren problemas con un servidor Elastix en producción podemos caer en la desesperación pues se trata de una aplicación crítica en una empresa. Trataremos de explicar aquí una serie de pasos para que los podamos seguir en esos momentos en los que la adrenalina corre por nuestras venas.

Identificar el componente que está causando problemas

Es probable que muchas veces no sea un problema de Asterisk sino de sistema operativo o de otros componentes de software o hardware, así que es importante diferenciar si lo que tenemos es un bug de Asterisk. Este apartado se enfocará en explicar un procedimiento para tratar de solucionar un bug de Asterisk.

También es importante notar que un bug es un error en el código de un programa. Muchas personas creen haber encontrado un bug de Asterisk para luego darse cuenta que borraron sin querer un archivo importante de configuración o cosa por el estilo y por esa ocasión Asterisk no se iniciaba.

Reproducir el bug

Imagínense que un cliente nos llama y nos dice que Asterisk se colgó durante la noche y amaneció apagado. El problema dice que se presenta un par de veces a la semana y ha ocurrido incluso durante el día.

¿Qué hacer en estos casos donde inicialmente no hay pistas de qué pueda estar ocurriendo?

Bueno, no hay una solución ideal pero la siguiente guía puede resultar útil en la mayoría de los casos.

Examinar los logs en busca de la actividad minutos antes de que ocurriera el problema y tratar de reproducir la misma actividad o al menos la inusual para ver si así gatillamos el bug. En ocasiones cosas como la simple recepción de un fax podría gatillar un bug.

Consultar a los usuarios telefónicos si tienen alguna idea de lo que podría estar ocasionando el problema. Nunca hay que subestimar el poder de los usuarios pues se encuentran viviendo la situación telefónica muy de cerca.

Monitorear el equipo capturando la mayor cantidad de parámetros posibles. Existen algunas herramientas que nos pueden ayudar en este propósito.

Una vez encontrado el escenario en el cual el bug es reproductible, lo siguiente es encontrar cómo solucionar el problema.

Hay tantos usuarios alrededor del mundo utilizando Asterisk que es probable que si encontramos un bug no seamos los únicos que lo hayamos notado.

Por lo tanto si encontramos la situación que gatilla el bug lo siguiente que podemos hacer son dos cosas:

Verificar si ya fue solucionado en recientes versiones de Asterisk. Esto lo podemos hacer examinando el archivo Changelog (o log de cambios) que se incluye con cada lanzamiento de Asterisk. Podemos descargar la versión más reciente de Asterisk para ver el log de cambios más actualizado o podemos consultarlo en el repositorio SVN.

Verificar si al menos ha sido reportado en la interfaz de seguimiento de bugs de Asterisk. La cual se encuentra disponible en http://bugs.digium.com. Tomémonos un buen tiempo para buscar.

Errores de programación que provocan caídas, colgados o comportamientos indeseados

Es útil conocer estos conceptos para hacer una mejor depuración e inclusive estar más capacitados para corregir el código de ser necesario.

Un programa se puede caer, colgar o funcionar erráticamente por diversas causas, aquí les dejamos con algunas de las más comunes.

Falla de segmentación

Esto sucede cuando un programa utiliza mal la memoria y pretende ocupar un segmento de memoria que no le corresponde o lo pretende utilizar de una manera no permitida.

En ese momento el kernel, que está vigilante, se da cuenta de ello y para preservar la estabilidad del sistema remueve al programa de memoria y termina su ejecución.

Si no existiera este control de parte del kernel el programa mal escrito podría sobrescribir el espacio de memoria de otras aplicaciones o inclusive del sistema operativo.

Deadlock

Un deadlock o bloqueo mutuo ocurre cuando dos procesos (o hilos) de un programa pretenden utilizar un mismo recurso. El primer proceso adquiere permisos sobre el recurso y lo bloquea de tal manera que el segundo proceso no puede accederlo y queda esperando a que se libere. Del mismo modo el segundo proceso ha bloqueado un recurso que necesita el primer proceso de tal modo que los dos procesos quedan bloqueados esperando que los recursos se liberen, cosa que no sucederá.

Esto provoca que estos procesos queden en un estado de espera sin poder ejecutar más acciones.

Fuga de memoria

Ocurre cuando un programa falla al momento de liberar de la memoria los recursos que está utilizando, de tal modo que a medida que el tiempo pasa el consumo de la memoria se incrementa, pudiendo inclusive provocar que el sistema se torne excesivamente lento o se detenga.

División para cero

Este es un error común. Cuando esto ocurre se puede observar un error del tipo -Floating exception-. El programa se detiene.

Buffer overflow

Ocurre cuando el programa trata de escribir en espacios de memoria adyacentes. Esto provoca un comportamiento errático de la aplicación.

Cuando se encuentra un problema de buffer overflow los fabricantes tienden a solucionarlo rápidamente pues aparte de los problemas obvios de inestabilidad que esto representa existen hackers que se encuentran en busca de estos errores para explotarlos en busca de poder ejecutar código propio malicioso en el equipo atacado mediante varias técnicas.

24.2 strace

strace es un depurador para Linux muy fácil de usar que monitorea las llamadas a sistema que realiza un programa determinado y todas las señales que este recibe.

Una llamada a sistema es una petición que realiza un programa al kernel para que éste realice una tarea. Esto funciona así porque existen algunas tareas que por cuestión de privilegios una aplicación no puede realizar directamente, entonces tiene que solicitarle dicha tarea al kernel. Un ejemplo es el uso de dispositivos de sistema como la tarjeta de red o manipulación de archivos.

Algunas llamadas a sistema comunes en Linux son open, read, write, close, wait, exec, fork, exit, kill, entre otras.

El trabajo de strace es posible gracias a una característica del kernel llamada ptrace que le permite a un programa cualquiera monitorear las llamadas a sistema de cualquier programa hijo. Para más información se puede ejecutar el comando -man ptrace- en el servidor Elastix.

La manera más sencilla de usar strace es ejecutar el comando seguido por el programa que se desea monitorear. Veamos el siguiente ejemplo sencillo monitoreando el comando -cat /proc/cpuinfo-

[root@elastix ~]# strace cat /proc/cpuinfo

execve("/bin/cat", ["cat", "/proc/cpuinfo"], [/* 20 vars */]) = 0

brk(0) = 0x975c000

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=37776, ...}) = 0

mmap2(NULL, 37776, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fe9000

close(3) = 0

open("/lib/libc.so.6", O_RDONLY) = 3

[…]

open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=56417648, ...}) = 0

mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7de7000

close(3) = 0

fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0

open("/proc/cpuinfo", O_RDONLY|O_LARGEFILE) = 3

fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0

read(3, "processor\t: 0\nvendor_id\t: Genuin"..., 4096) = 1076

write(1, "processor\t: 0\nvendor_id\t: Genuin"..., 1076) = 1076

read(3, "", 4096) = 0

close(3) = 0

close(1) = 0

exit_group(0) = ?

La salida anterior puede confundirnos un poco al principio pero si prestamos atención veremos que cada línea representa una llamada de sistema. Podemos ver entre otras cosas que se está tratando de abrir el archivo /proc/cpuinfo en modo -sólo lectura-.

open("/proc/cpuinfo", O_RDONLY|O_LARGEFILE)= 3

El número tres al final significa el código de salida de la llamada de sistema. Salidas negativas como -1 generalmente corresponden a errores. Se puede observar esto en el ejemplo anterior cuando se trata de acceder al archivo /etc/ld.so.preload.

En general la sintaxis de uso de strace es sencilla.

strace [opciones] programa [argumentos]

Algunas opciones interesantes son las siguientes.

Parámetro | Descripción
-o | Escribe la salida a un archivo
-p | Monitorea un proceso especificado por su PID. De esta manera se puede monitorear un programa en ejecución
-c | Muestra un reporte donde se puede observar un resumen del número de apariciones de las diversas llamadas de sistema
-e | Nos permite filtrar la salida por tipo de llamada de sistema o señal

Un ejemplo sencillo de depuración de Asterisk

Hay ocasiones donde es importante monitorear un proceso de Asterisk en ejecución. Por ejemplo en el caso de que nos demos cuenta que nuestro servidor se encuentra tomando mucho CPU y queramos averiguar qué está ocurriendo.

Nota: En el caso anterior es probable que GDB sea una mejor opción para averiguar qué está ocurriendo.

Para depurar un programa en ejecución con strace primero debemos averiguar el PID del proceso que queremos monitorear. En nuestro caso monitorearemos Asterisk así que primero enlistaremos los procesos que contengan la palabra Asterisk y tomaremos el menor PID.

[root@elastix ~]# ps aux | grep asterisk

asterisk 1619 0.5 1.9 290568 19564 ? Sl Dec10 3:13 /usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c

asterisk 4298 0.0 1.4 297492 15024 ? S Dec09 0:00 /usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c

root 8656 0.0 0.0 4472 700 ? S Nov07 0:00 /bin/sh /usr/sbin/safe_asterisk -U asterisk -G asterisk

asterisk 17198 0.0 1.4 297332 14864 ? S Dec09 0:00 /usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c

[…]

En el ejemplo anterior el menor PID es el 1619.

Nota: Una manera alternativa de averiguar este PID es usando el comando -pstree -p | grep asterisk-

Ahora que sabemos el PID podemos monitorearlo con strace de manera sencilla.

[root@elastix ~]# strace -p 1619

Process 1619 attached - interrupt to quit

En caso de que estemos experimentando con strace sobre un Asterisk que no posea actividad podemos ejecutar el siguiente comando para probar la salida de strace.

[root@elastix ~]# asterisk -rx "module reload"

Veremos ahora lo siguiente.

[root@elastix ~]# strace -p 1619

Process 1619 attached - interrupt to quit

read(0, 0xbf83cc3b, 1) = ? ERESTARTSYS (To be restarted)

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

read(0, 0xbf83cc3b, 1) = ? ERESTARTSYS (To be restarted)

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

--- SIGURG (Urgent I/O condition) @ 0 (0) ---

rt_sigaction(SIGURG, {0x80652e0, [URG], SA_RESTART}, {0x80652e0, [URG], SA_RESTART}, 8) = 0

sigreturn() = ? (mask now [])

[…]

Para salir basta con ejecutar Ctrl+C

24.3 GDB

GDB es un completo depurador desarrollado y mantenido por la Free Software Foundation.

GDB nos permite hacer seguimiento de la ejecución de un programa insertando pausas cuando creamos necesario; también nos permite observar lo que un programa estaba haciendo cuando se colgó. Inclusive nos permite cambiar ciertas cosas dentro del programa para ver los efectos que se producen con dichos cambios.

GDB es una opción más completa que strace pero también su uso requiere un tanto más de conocimiento.

Con GDB podemos depurar programas escritos en C o C++ como es el caso de Asterisk. Sin embargo, GDB también soporta otros lenguajes.

Ejemplos simples de uso de GDB

GDB puede utilizarse para deputar un programa de tres maneras diferentes: desde el propio GDB, depurar un programa que ya se encuentra en ejecución o para hacer depuración de un archivo core dejado por una aplicación caída.

Depurando un programa desde el depurador

El depurador GDB puede encargarse de arrancar el programa y ejecutarlo. Para esto podemos utilizar la sintaxis.

gdb programa

Depuración sobre Asterisk en plena ejecución

Podemos depurar un programa en plena ejecución si conocemos su PID. Encontrar el PID no es muy difícil y podemos usar el comando ps para ello. Ya vimos esto anteriormente en este mismo capítulo.

A continuación la sintaxis para depurar un programa conociendo su PID.

gdb programa PID

Depuración haciendo backtrace sobre un archivo core

También es posible depurar un programa después de caído siempre y cuando éste haya dejado un archivo core. Para depurar un archivo core debemos especificar el nombre del programa que generó dicho archivo y la ubicación del archivo core.

gdb programa core

Comandos básicos

A continuación una lista con los comandos más básicos de GDB.

run

Ejecuta un programa

bt

Hace un backtrace, es decir muestra la pila de memoria del programa

list

Enlista la fuente del programa en las cercanías de donde se encuentra detenido.

step

Ejecuta el programa línea por línea, después de que ha sido detenido.

next

Igual que step pero no ingresa a las funciones.

status

Imprime una lista de las paradas (breakpoints)

delete

Elimina una parada (breakpoint)

quit

Nos permite salir de GDB

24.4 Archivos core y backtraces

Muchas aplicaciones dejan archivos core cuando terminan inesperadamente, lo que nos permite hacer una depuración post-mortem del software.

En el caso de Asterisk esto es posible cuando se lo inicia con la opción -g. En el caso de Elastix, Asterisk se inicia por defecto con dicha opción.

Si no se está seguro que Asterisk haya sido iniciado con la opción -g se puede verificar con el siguiente comando.

[root@elastix ~]# ps aux | grep asterisk

root 8656 0.0 0.0 4472 696 ? S Nov07 0:00 /bin/sh /usr/sbin/safe_asterisk -U asterisk -G asterisk

asterisk 8715 0.6 2.4 297488 25412 ? Sl Nov19 188:55 /usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c

asterisk 17198 0.0 1.4 297332 14864 ? S Dec09 0:00 /usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c

[…]

Nota: Por omisión el sistema operativo que viene con Elastix no permite la escritura de archivos core, de tal modo que a pesar de que Asterisk haya sido iniciado con la opción correcta, los archivos core no se escribirán. Para habilitar su escritura debemos hacer uso del comando -ulimit -c unlimited-. Una vez encontrado el problema es preferible deshabilitar nuevamente la escritura de archivos core pues podrían generarse de tal modo que comprometan el espacio en disco duro del equipo. Esto lo hacemos con el comando -ulimit -c 0-.

Un archivo core no es otra cosa que el contenido de memoria del programa en el momento en que se detuvo. Es el sistema operativo quien guarda ese contenido de memoria pues la aplicación no está en capacidad de hacerlo puesto se encuentra detenida.

Este contenido de memoria, combinado con la tabla de símbolos que se genera cuando el programa es compilado hacen que GDB nos pueda mostrar información más legible.

Un backtrace (o seguimiento hacia atrás) es un reporte de las llamadas a funciones que se encontraban en memoria en un momento dado.

Desde GDB es posible realizar backtraces sobre un archivo core. Es decir obtener un reporte de las llamadas a funciones en el momento en que el programa se cayó. Para hacerlo existen dos comandos, el bt y el bt full.

El -bt full- es un backtrace más detallado y muestra además parámetros y variables locales usados por las funciones que están siendo invocadas.

Veamos un ejemplo de esto. Primero identificamos el archivo core que necesitamos examinar, por lo general se trata del último.

[root@elastixtest ~]# ll /tmp/ | grep core

-rw------- 1 asterisk asterisk 301694976 Oct 17 14:02 core.34543

-rw------- 1 asterisk asterisk 280817664 Oct 23 10:07 core.45433

-rw------- 1 asterisk asterisk 323821568 Nov 7 16:44 core.54333

-rw------- 1 asterisk asterisk 323416064 Nov 14 10:30 core.54654

-rw------- 1 asterisk asterisk 292384768 Nov 19 16:28 core.63222

En nuestro caso examinaremos el archivo llamado core.63222. Iniciamos el depurador y realizamos un backtrace.

[root@elastix ~]# gdb asterisk /tmp/core.63222

[…]

Reading symbols from /usr/lib/asterisk/modules/chan_mgcp.so...done.

Loaded symbols for /usr/lib/asterisk/modules/chan_mgcp.so

Reading symbols from /usr/lib/asterisk/modules/format_gsm.so...done.

Loaded symbols for /usr/lib/asterisk/modules/format_gsm.so

Core was generated by `/usr/sbin/asterisk -f -U asterisk -G asterisk -vvvg -c'.

Program terminated with signal 11, Segmentation fault.

#0 0x080ecfd7 in c_hmatch ()

(gdb) set logging on

Copying output to gdb.txt.

(gdb) bt

#0 0x080ecfd7 in c_hmatch ()

#1 0x00000001 in ?? ()

#2 0x00000064 in ?? ()

#3 0xbfab4b80 in ?? ()

#4 0xa9610c08 in ?? ()

#5 0x09989cf0 in ?? ()

#6 0xbfab4b78 in ?? ()

#7 0x080ed371 in parse_line ()

Previous frame inner to this frame (corrupt stack?)

(gdb) bt full

#0 0x080ecfd7 in c_hmatch ()

No symbol table info available.

#1 0x00000001 in ?? ()

No symbol table info available.

#2 0x00000064 in ?? ()

No symbol table info available.

#3 0xbfab4b80 in ?? ()

No symbol table info available.

#4 0xa9610c08 in ?? ()

No symbol table info available.

#5 0x09989cf0 in ?? ()

No symbol table info available.

#6 0xbfab4b78 in ?? ()

No symbol table info available.

#7 0x080ed371 in parse_line ()

No symbol table info available.

(gdb) thread apply all bt

[…]

¿Cómo reportar un backtrace a Digium?

Si determinamos que tenemos un bug de Asterisk el siguiente paso lógico es reportar ese bug al fabricante, a menos que sepamos cómo resolverlo.

Digium dispone de una interfaz Web para esta finalidad ubicada en:

http://issues.asterisk.org

Cuando se reporta un bug es de mucha ayuda para los desarrolladores de Asterisk contar un backtrace para poder entender mejor lo que ocurrió a nivel interno.

Los lineamientos generales para reportar backtraces se encuentran en el siguiente sitio:

http://www.asterisk.org/doxygen/trunk/AstDebug.html

Básicamente se pide no subir archivos core sino solo la salida de los comandos bt y bt full conseguidos con GDB.

Adicionalmente es importante al reportar un bug de Asterisk mencionar que se está utilizando Elastix porque esto permitirá a los desarrolladores de Digium conocer que se trata de un Asterisk compilado con parches y funcionalidad adicional.

25

Plan de marcado distribuido

Afirmaciones extraordinarias requieren siempre de evidencia extraordinaria

-- Carl Sagan

25.1 Introducción

DUNDi (Distributed Universal Number Discovery) es un sistema de localización de gateways para el acceso a los servicios de telefonía. Utiliza un esquema punto a punto y, a diferencia de ENUM, que es estrictamente jerárquico por que se basa en DNS, no requiere ninguna arquitectura de red en particular ni un esquema jerárquico cliente-servidor.

En otras palabras DUNDi es capaz de consultar los contextos de otros equipos para encontrar una ruta hacia determinado número.

DUNDi en realidad no realiza una llamada como tal, ya que no es un protocolo de señalización VoIP; mas bien el recibe y proporciona la información necesaria para poder contactar a los equipos independientemente del protocolo VoIP que sea usado.

DUNDi fue inventado por Mark Spencer, quien también desarrolló Asterisk, por lo tanto es de esperar que la integración con este ultimo sea completamente transparente así como su compatibilidad impecable.

Para que DUNDi funcione se debe conocer al menos un peer quien a su vez, si no puede responder al requerimiento, puede delegar la consulta a un peer conocido por él, y así hasta que se encuentre a un peer que tenga una respuesta al numero consultado.

Un ejemplo típico de la utilidad de DUNDi es en una empresa multi-sede, en la cual cada sede tiene su propio equipo con Elastix. Cada equipo puede publicar sus extensiones y si uno de los equipos pregunta, por ejemplo, ¿dónde está el numero 456? la consulta se enviara directa o indirectamente a todos los servidores, y el servidor que tenga esa extensión responderá algo como IAX2/usuario:clave@1.2.3.4/456.

25.2 Ejemplo de configuración

La mejor manera de explicar DUNDi es ilustrando con un ejemplo, así que eso es lo que haremos a continuación. Mostraremos un ejemplo de cómo distribuir el plan de marcado en 3 equipos utilizando DUNDi.

Escenario

En el presente ejemplo se configurarán tres equipos con los siguientes datos.

Nombre de equipo | Dirección IP | MAC
SRV01 | 192.168.255.201 | 00:21:5A:49:24:98
SRV02 | 192.168.255.202 | 00:21:5A:49:7E:9E
SRV02 | 192.168.255.203 | 00:22:64:08:F4:FE

Certificados de encriptación

DUNDi usa certificados de encriptación RSA para compartir los planes de marcado. Esto es importante ya que las respuestas a una consulta incluyen las contraseñas de las troncales.

Usaremos la misma clave para la comunicación entre todos los servidores, así que el primer paso es generar los certificados de encriptación en uno de los equipos (en este ejemplo en SRV01):

SRV01:

cd /var/lib/asterisk/keys

astgenkey -n SERVERS-DUNDI

Ahora necesitamos compartir los certificados entre los dos servidores; esto es para que cada uno pueda des-encriptar al otro.

Copiar de SRV01 hacia SRV02:

[root@elastix ~]# scp /var/lib/asterisk/keys/SERVERS-DUNDI.* \

 192.168.255.202:/var/lib/asterisk/keys

Copiar de SRV01 hacia SRV03:

[root@elastix ~]# scp /var/lib/asterisk/keys/SERVERS-DUNDI.* \

 192.168.255.203:/var/lib/asterisk/keys

dundi.conf

Vamos a generar este archivo desde el principio, sección por sección:

Sección [general]

En esta sección del archivo definimos nuestra propia identificación en la nube DUNDi, así como las opciones globales, debemos rellenar los campos con los datos reales de nuestros equipos (MAC, etc.):

Para SRV01:

[general]

;

department=SERVER01

organization=AlgunaOrganizacion

locality=Quito

stateprov=Pichincha

country=EC

email=info[at]example.com

phone=+593-0000000

;

; Aqui podemos definir en que red va a escuchar dundi

;bindaddr=0.0.0.0

; El puerto en el que va a escuchar, por defecto 4520

port=4520

; Aqui nos identificamos con nuestra MAC address

entityid=00:21:5A:49:24:98

; El numero de consultas que hará DUNDI hasta alcanzar una extensión

ttl=12

; Finaliza las conexiones fallidas

autokill=yes

Para SRV02:

[general]

department=SERVER02

organization=AlgunaOrganizacion

locality=Quito

stateprov=Pichincha

country=EC

email=info[at]example.com

phone=+593-0000000

port=4520

entityid=00:21:5A:49:7E:9E

ttl=12;

autokill=yes

Para SRV03:

[general]

department=SERVER03

organization=AlgunaOrganizacion

locality=Quito

stateprov=Pichincha

country=EC

email=info[at]example.com

phone=+593-0000000

port=4520

entityid=00:22:64:08:F4:FE

ttl=12;

autokill=yes

Sección [mappings]

Aquí definimos nuestra respuesta a una consulta hacia determinado número que tengamos localmente.

Para SRV01:

[mappings]

priv => dundi-priv-canonical,0,IAX2,dundi:${SECRET}@192.168.251.251/${NUMBER},nopartial

priv => dundi-priv-customers,100,IAX2,dundi:${SECRET}@192.168.251.251/${NUMBER},nopartial

priv => dundi-priv-via-pstn,400,IAX2,dundi:${SECRET}@192.168.251.251/${NUMBER},nopartial

Para SRV02:

[mappings]

priv => dundi-priv-canonical,0,IAX2,dundi:${SECRET}@192.168.251.252/${NUMBER},nopartial

priv => dundi-priv-customers,100,IAX2,dundi:${SECRET}@192.168.251.252/${NUMBER},nopartial

priv => dundi-priv-via-pstn,400,IAX2,dundi:${SECRET}@192.168.251.252/${NUMBER},nopartial

Para SRV03:

[mappings]

priv => dundi-priv-canonical,0,IAX2,dundi:${SECRET}@192.168.251.253/${NUMBER},nopartial

priv => dundi-priv-customers,100,IAX2,dundi:${SECRET}@192.168.251.253/${NUMBER},nopartial

priv => dundi-priv-via-pstn,400,IAX2,dundi:${SECRET}@192.168.251.253/${NUMBER},nopartial

Los valores de ${NUMBER} y ${SECRET} se reemplazaran automáticamente, según el numero que se consulte y la clave aleatoria que se haya generado en ese momento.

Peers

Adicionalmente debemos definir los PEERS que consultaran y serán consultados (con la opción symmetric), esto lo hacemos así:

Para SRV01:

; Identificamos al servidor 2 (SRV02) por su entityid

[00:21:5A:49:7E:9E]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV02

host=192.168.255.202

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

; Identificamos al servidor 3 (SRV03) por su entityid

[00:22:64:08:F4:FE]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV03

host=192.168.255.203

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

Para SRV02:

; Identificamos al servidor 1 (SRV01) por su entityid

[00:21:5A:49:24:98]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV01

host=192.168.255.201

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

; Identificamos al servidor 3 (SRV03) por su entityid

[00:22:64:08:F4:FE]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV03

host=192.168.255.203

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

Para SRV03:

; Identificamos al servidor 1 (SRV01) por su entityid

[00:21:5A:49:24:98]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV01

host=192.168.255.201

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

; Identificamos al servidor 1 (SRV01) por su entityid

[00:21:5A:49:24:98]

;permitir y realizar conexiones

model=symmetric

; IP ser servidor SRV01

host=192.168.255.201

inkey=SERVERS-DUNDI

outkey=SERVERS-DUNDI

; Incluimos el contexto antes definido en la sección mappings

include=priv

permit=priv

qualify=yes

order=primary

iax_custom.conf

Aquí debemos definir la configuración de la troncal; como DUNDi va a hacer todo el trabajo de enviar la cadena exacta para contactar cada extensión, solo es necesario crear un usuario que reciba las llamadas autenticadas de la nube DUNDi:

En SRV01 y en SRV02

[dundi]

type=user

dbsecret=dundi/secret

context=ext-local

extensions.conf

Para lograr la integración con FreePBX debemos modificar un poco el contexto "from-internal" que es el contexto que usa FreePBX para las extensiones.

Teniendo en cuenta que cuando un número no es encontrado en el plan de marcado local se usa el contexto [bad-number] es allí donde debemos modificar y la configuración debe ser exactamente la misma en los tres servidores:

En el archivo extensions.conf buscamos la sección:

[from-internal]

include => from-internal-xfer

include => bad-number

Comentamos la última línea (poniendo un punto y coma adelante) y agregamos otra que diga include => dundi-priv-lookupque es un contexto que crearemos luego en el archivo extensions_custom.conf, quedando así:

[from-internal]

include => from-internal-xfer

;include => bad-number

include => dundi-priv-lookup

extensions_custom.conf

Aquí definimos los contextos personalizados para que DUNDI relacione nuestras extensiones, así como una macro para hacer las búsquedas en otros equipos y la sentencia para redirigir las llamadas (switch).

Debemos añadir las siguientes líneas al final del archivo extensions_custom.conf en los dos servidores:

; ********************************************

; CONFIGURACION PARA DUNDi

[dundi-priv-canonical]

; Aqui incluimos el contexto que contiene las extensiones.

include => ext-local

; Aqui incluimos el contexto que contiene las colas de atención

include => ext-queues

[dundi-priv-customers]

; Si tenemos clientes (o revendemos servicios) podemos listarlos aqui

[dundi-priv-via-pstn]

; Aquí podemos incluir contexto con nuestras troncales hacia la PSTN,

; si queremos que los demás equipos puedan usar nuestras troncales

; include => outbound-allroutes

[dundi-priv-local]

; En este contexto unificamos los tres contextos, este lo podemos

; usar como contexto de la troncal iax de dundi

include => dundi-priv-canonical

include => dundi-priv-customers

include => dundi-priv-via-pstn

[dundi-priv-lookup]

; Este contexto se encarga de hacer la busqueda de un numero por dundi

; Antes de hacer la busqueda definimos apropiadamente nuestro

; caller id. ya que si no tendremos un caller id como "device<0000>".

exten => _X.,1,Macro(user-callerid)

exten => _X.,n,Macro(dundi-priv,${EXTEN})

exten => _X.,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?100)

exten => _X.,n,Goto(bad-number,${EXTEN},1)

exten => _X.,100,Playtones(congestion)

exten => _X.,101,Congestion(10)

[macro-dundi-priv]

; Esta es la macro que llamamos desde el contexto [dundi-priv-lookup]

; Tambien evita que hayan loops en las consultas dundi.

exten => s,1,Goto(${ARG1},1)

switch => DUNDi/priv

; ********************************************

Aplicar la configuración

Para que los cambios se hagan efectivos ejecutamos el siguiente comando:

asterisk -rx "restart when convenient"

O si no queremos esperar:

asterisk -rx "restart now"

Conclusión

Ahora cada extensión que creemos desde FreePBX se añadirá al contexto [ext-local] el cual esta incluido en dundi-priv-canonical que va a usar DUNDi para indicar qué extensiones poseemos localmente.

Si un servidor tiene la extensión responderá con los datos para la comunicación hacia esa extensión; esos datos a su ves los interpreta el servidor que esta preguntando y usa la función switch que colocamos en el archivo extensions_custom.conf para comunicarse con la extensión local.

25.3 Integrando IVRs con DUNDi

Cuando tenemos varios equipos y troncales de la PSTN que ingresan a uno de ellos, es muy posible que queramos que el IVR que recibe esas líneas pueda llamar directamente a las extensiones de la red DUNDi.

Para lograrlo, lo primero que hay que hacer es localizar el contexto de IVR que hemos creado desde FreePBX. Este último los crea con una nomenclatura [ivr-N], donde N es un numero incremental que asigna automáticamente.

Tenemos que revisar en el archivo /etc/asterisk/extensions_additional.conf y buscar el contexto adecuado.

Suponiendo que el contexto del IVR es [ivr-2] tendríamos que definir la siguiente configuración en el archivo /etc/asterisk/extensions_additional.conf:

[dundi-priv-lookup-ivr]

exten => _XXXX,1,Macro(dundi-priv,${EXTEN})

exten => _XXXX,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?100)

exten => _XXXX,n,Goto(ivr-2,i,1)

exten => _XXXX,n,Hangup()

exten => _XXXX,100,Playtones(congestion)

exten => _XXXX,101,Congestion(10)

exten => _XXXX,102,Hangup()

[ivr-2-custom]

include => ext-local

include => ext-queues

include => dundi-priv-lookup-ivr

Esto teniendo en cuenta que nuestras extensiones internas tienen 4 dígitos, si no debemos modificar el contexto [dundi-priv-lookup-ivr] y en vez de _XXXX poner el numero de dígitos que usamos.

26

Addon para Call Centers

Hace más ruido un sólo hombre gritando que cien mil callados

-- José de San Martín

26.1 Introducción

El addon para call centers de Elastix es un addon diseñado para administrar -campañas- de llamadas atendidas por operadores humanos en centros de llamadas. A estos operadores se los conoce como -agentes-.

Para optimizar el tiempo de trabajo de un agente, este addon incluye un componente interesante llamado marcador predictivo, que se encarga de marcar de manera automática a los números -objetivo-. Esta marcación la realiza (en base a cálculos estadísticos) incluso antes de que el agente que va a atender la llamada haya colgado la llamada anterior; debido a que pasa cierto tiempo desde que se marca hasta que el destinatario contesta. De esta forma cuando el agente está disponible la siguiente llamada está muy probablemente lista para ser atendida.

Este addon también incluye otros dos componentes muy interesantes como son: una útil consola de agente basada en Web y una interfaz de administración de campañas.

Cabe mencionar además que en la versión más reciente de este addon (2.0.0-15 al momento de escribir la presente obra) se incluye soporte para el nuevo protocolo ECCP (Elastix Call Center Protocol). Con este protocolo es posible integrar aplicaciones externas con el marcador predictivo, como por ejemplo consolas de agente. Los detalle relacionados con este protocolo no serán cubiertos en el presente capítulo.

26.2 Funcionalidad básica

Modelo de funcionamiento

El addon para call centers (en su versión actual) está implementado alrededor del soporte de colas de Asterisk. El diseño del módulo asume que cada una de las colas alberga a uno o más agentes, los cuales pueden estar "registrados" como presentes en una cola, o ausentes. Además se asume que cada campaña utiliza exactamente una cola de Asterisk. Actualmente se reconocen dos modos principales de funcionamiento: campañas salientes, y campañas entrantes. Estos dos modos de funcionamiento se diferencian en quién origina las llamadas.

En una campaña saliente, al sistema se lo alimenta con un archivo que contiene los números telefónicos a marcar. Al activarse la campaña, y si hay agentes registrados como presentes en la cola asignada, el sistema marca los números telefónicos, tantos como agentes libres se encuentren en la cola. El método por medio del cual se coloca una llamada, une la cola (no un agente específico) con el número del abonado al cual se llama, y por lo tanto la llamada realizada, si es exitosa, entra a la cola y es atendida por el siguiente agente libre (según la política de asignación). Al conectarse la llamada, el sistema registra el agente que el Asterisk ha elegido para atender la llamada, y escribe esta información en una base de datos, para que sea recogida por la porción Web. Esta información también permite asociar una llamada con una respuesta a un formulario asociado a la campaña. Al terminar la llamada, el agente pasa al estado ocioso, y está de nuevo disponible para recibir la siguiente llamada. Este proceso continúa hasta recorrer toda la lista de números. Según el parámetro de reintentos especificado por la campaña, se vuelven a intentar marcar números que fallaron en ser contactados, hasta terminar con el número de reintentos o cuando cada número haya sido correctamente contactado.

En una campaña entrante, se define una cola a la cual ingresan los agentes, pero el marcador no inicia llamada alguna. En lugar de ello, se debe organizar que los abonados llamen al sistema, y que resulten encaminados a la cola configurada para la campaña. Como en el caso de la campaña saliente, se registra a qué agente fue asignada la llamada. Opcionalmente se puede alimentar al sistema con datos sobre números específicos, de forma que cuando este número llama, el agente tenga la información correspondiente al abonado disponible en su pantalla de información.

Funcionalidad implementada

La versión 2.0 del addon para call centers tiene las siguientes funcionalidades implementadas:

Llamado automático a partir de una lista de números

Ejecución de múltiples campañas simultáneas, cada una con su propia cola asignada

Seguimiento de agente asignado para atender una llamada

Marcador predictivo. Esta característica intenta predecir, en base a la duración observada de las llamadas realizadas durante una campaña, la probabilidad de que una llamada actualmente en curso sea terminada en un intervalo determinado. Si la llamada se considera a punto de terminarse, se colocan llamadas adicionales con la esperanza de que el agente está disponible cuando la llamada llegue a conectarse.

Almacenamiento de guión de atención. Esta característica permite asociar la campaña con un guión del discurso que el agente debe seguir para atender al abonado. Este discurso está disponible en la cejilla que aparece en la consola de agente.

Ingreso de formulario. Si la campaña saliente es realizada para hacer una encuesta, el sistema puede almacenar un formulario que el agente llena con las respuestas del abonado. Las respuestas de todos los números marcados en una campaña son recuperables como un archivo CSV a través de la interfaz Web.

Auditoría de tiempos de descanso

Capacidad de poner una llamada en "hold"

Reportes de actividad de llamadas

Limitaciones conocidas

El marcador del addon para call centers no controla cuál agente termina atendiendo un número específico que ha sido marcado, o que ha sido recibido. Esto es una limitación fundamental del modelo de agentes de Asterisk como miembros de una cola de atención. Debido a que las llamadas son colocadas entre la cola y el número marcado, el marcador no puede decidir a cuál agente se le asignará la llamada colocada. Esto excluye el marcador para su uso en situaciones en las que un agente debe atender a un subconjunto definido de números.

El marcador del addon para call centers no está diseñado para reproducir mensajes grabados en llamadas no atendidas. Esto no es exactamente una limitación, sino una consecuencia del objetivo para el cual fue escrito este addon, el cual está pensado para mediar llamadas que luego son atendidas por agentes humanos. Por lo tanto, no coloca llamadas en una cola sin agentes. Es posible que se implemente esta característica en una versión futura, como un tipo especial de campaña que no requiere de agentes.

26.3 Componentes del addon para call centers

Marcador predictivo

El marcador predictivo es la porción que interactúa directamente con las llamadas. El marcador está implementado como un servicio residente (daemon) escrito en PHP, e iniciable como un servicio a través del comando 'service elastixdialer start'. Para las campañas salientes, el marcador tiene la tarea de iniciar cada una de las llamadas hacia los abonados, mediante el uso del comando Originate de Asterisk. El marcador lleva la cuenta de las llamadas que han sido colocadas, pero no han sido informadas de éxito o fracaso a través de un evento OriginateResponse enviado por Asterisk. Cuando una llamada es respondida, el marcador recibe eventos OriginateResponse, Join y Link que informan características de la llamada colocada, en particular el agente al cual terminó siendo asignada. Al recibir estos eventos, el marcador escribe la información de la llamada en la base de datos para su uso por parte de la porción Web del módulo.

El marcador interroga regularmente el estado de la cola (para las campañas salientes), para averiguar cuántos agentes se encuentran registrados y libres. El número de agentes libres regula cuántas llamadas son iniciadas simultáneamente cada vez que se revisa el estado de la campaña. Si el número de llamadas colocadas en la historia de la campaña es suficientemente grande, el marcador intenta usar las estadísticas de duración media de la llamada, para intentar predecir si una llamada en curso está a punto de terminar, para colocar proactivamente llamadas adicionales. El modelo para predicción es una distribución Erlang acumulada.

Distribución Erlang acumulada

La interfaz Web permite iniciar y detener el servicio de marcador, y además permite activar y desactivar la depuración de problemas en el marcador, incluso si el marcador está corriendo. La ruta por omisión del log del marcador, donde aparecen las operaciones realizadas por éste, es el archivo /opt/elastix/dialer/dialerd.log. Cuando la depuración está desactivada, sólo los errores se escriben a este log. Al activar la depuración, también se escriben reportes regulares sobre el estado interno del marcador, así como los parámetros que se usan para generar llamadas, los eventos que recibe el marcador, y la interpretación de cuántos agentes están libres.

Consola de agente

La consola de agente es el componente del addon para call centers que administra la interacción del agente con el sistema. Esta consola de agente es esencialmente una página Web que revisa regularmente el estado de llamadas asignadas al agente, y consulta la información relevante a esta llamada para ser mostrada. Por medio de la consola de agente se informa cuál número telefónico está siendo atendido, la información de contacto para el número marcado (si está disponible), y además se interactúa con el formulario para la encuesta asociada al agente (si existiese alguna). La consola de agente tiene integrados comandos para iniciar y finalizar una pausa (break), para poner a la llamada en espera, y para realizar transferencias de llamadas.

Administrador de campañas

La administración de campañas permite crear nuevas campañas, para su ejecución cuando los agentes se registran. Aquí se implementa también la creación de formularios, y la administración de breaks. Adicionalmente se proporciona una interfaz para la creación de agentes en el sistema que son capaces de recibir llamadas de campañas, y una pantalla de configuración que permite iniciar, detener y configurar el marcador predictivo, incluyendo la activación de depuración.

Reportes

Los reportes implementados incluyen:

Reporte de los descansos tomados por los agentes

Detalle de las llamadas colocadas, filtrable por periodo de tiempo, cola y agentes

Histograma de las llamadas colocadas en cada hora, por fecha y estado

Reporte de las llamadas contestadas por cada agente, filtrable por periodo

Histograma de tiempo de espera para las llamadas

Intervalo total que cada agente pasa registrado en el sistema

Eficiencia de colas de llamadas entrantes, como porcentaje de llamadas entrantes que son abandonadas

Uso de troncales por hora

Tiempo de conexión de agentes

26.4 Usando el administrador de campañas

Vamos a explicar brevemente cómo se usa la interfaz Web de administración de campañas. Desde esta interfaz podremos administrar agentes, formularios, campañas y breaks.

Administración de agentes

La administración de agentes se realiza desde el menú Call Center -> Agents. Aquí se nos permite ingresar los datos de las personas que se desempeñarán como agentes. Cada agente debe tener un número y clave asignado, para que por medio de esta se registre y reciba o realice llamadas.

Dentro del menú de agentes tenemos las siguientes pantallas y funcionalidad.

Listado de Agentes

Muestra la lista de los agentes que han sido creados previamente.

Pantalla de listado de agentes

Para cada agente se muestra la siguiente información.

Nombre
Descripción

Desconectar

Desconecta a un agente, que posee la sesión activa en la consola de agente.

Configuración

Si hay un visto:

El agente se encuentra registrado en la base de datos y en el archivo de configuración de Asterisk

Si hay una equis:

Indica que hay un error con este agente y los errores pueden ser los siguientes:

Registrado en la base de datos pero no en el archivo de configuración de Asterisk

Registrado en el archivo de configuración de Asterisk pero no en la base de datos

Número

Número asignado al agente. Es con este número que deberá ingresar a la consola de agente.

Nombre

Nombre del Agente

Estado

Puede ser: Conectado o Desconectado

Opciones

Ver:

Muestra la información del agente, el agente podrá ser Modificado o Eliminado.

Reparar:

Un agente será reparado si se encuentra en la siguientes situaciones:

No se registró en el archivo de configuración de Asterisk, así que será tomado de la base de datos y agregado.

No se registró en la Base de Datos en tal caso se elimina del archivo de configuración de Asterisk

Ingreso de Agentes

Para agregar un nuevo Agente, debemos dar clic en el botón -Nuevo Agente-. Se mostrará un formulario en cual se ingresarán los siguientes campos:

Formulario para la creación de nuevo agente

A continuación el significado de los campos mostrados en el formulario anterior.

Nombre del campo
Descripción

Número de Agente

Número asignado a un agente. Tener en cuenta que este número es la identificación para ingresar a consola de agente

Nombre

Nombre del Agente

Contraseña

Confirmar Contraseña

Contraseña del Agente

Visualizar, Editar y Eliminar

Al dar clic sobre la palabra View se nos conducirá a una pantalla donde se mostrará los datos del agente.

Viendo los datos de un agente

Para eliminar un agente debemos dar clic en el botón -Eliminar-. Se puede además modificar los datos del agente en el botón -Editar-. Los datos que puede cambiar son: Nombre y Contraseña.

Editando un agente

Administración de Formularios

Esta pantalla, ubicada en Call Center -> Form, nos permite crear formularios, los cuales se crean con el objetivo de recolectar datos al momento de atender una llamada.

En este menú tenemos dos opciones Listado de Formularios y Diseño de Formularios.

Listado de Formularios

Muestra la lista de formularios existentes, con el objetivo de hacer una vista preliminar de estos, antes de que sean usados en una campaña.

Listado de formularios

A continuación el significado de los campos observados en la figura anterior.

Nombre del campo
Descripción

Nombre

Nombre del Formulario.

Descripción

Descripción del Formulario.

Estado

Estado del Formulario, que puede ser Activo  o Inactivo.

Opciones

Vista Previa:

Visualización de los campos que posee el formulario de forma Gráfica.

Para hacer una vista preliminar de los formularios se debe hacer clic sobre la palabra preview. Esto nos conducirá a una pantalla donde se mostrará: el Nombre, Descripción y los campos que contiene un formulario en forma gráfica.

Es importante tomar en cuenta que desde esta opción no se puede ingresar ningún dato.

Vista preliminar del formulario

Diseño de Formularios

Al igual que la opción anterior se muestra el listado de formularios existentes y las columnas que se muestran están explicadas en la tabla de más abajo:

Diseñador de formularios

Nombre del campo
Descripción

Nombre

Nombre del Formulario

Descripción

Descripción del Formulario

Estado

Estado del Formulario, puede ser Activo o Inactivo

Opciones

Ver:

Visualización de los campos que posee el formulario de forma Textual. El formulario podrá ser: Editado, Desactivado, Eliminado.

Activar:

Activa los formularios, cuyo estado es Inactivo.

Para agregar un nuevo Formulario se debe dar clic en el botón Crear Nuevo Formulario. Se mostrará una pantalla que se encuentra dividida en dos secciones. La sección superior o cabecera sirve para ingresar información general del formulario como el nombre del mismo y una descripción.

Creación de nuevo formulario

La sección inferior sirve para definir los campos que conformarán el formulario. Se puede añadir un número arbitrario de campos.

Estos campos son agregados desde la sección que dice Nuevo Campo. La información que se debe ingresar para cada campo es la siguiente.

Nombre
Descripción

Nombre del Campo

Nombre del campo

Orden

El orden con que se presentará el campo en el formulario Web

Tipo

Los tipos de campos soportados hasta el momento son los siguientes:

Label: Etiqueta

Text: Caja de Texto

List: ComboBox

Date: Campo tipo fecha

Text Area: Ingreso de Texto extenso

Nota: Si se selecciona el tipo List se deben indicar las posibles opciones separadas por coma en el cuadro de texto Opciones.

Visualizar, Editar y Eliminar formularios

Al dar clic sobre en la palabra View, se nos conducirá a una pantalla donde se mostrará los campos que contiene un formulario en forma textual.

Visualización de formulario

Para Desactivar o Eliminar un formulario haga uso de los botones que se encuentran en la parte superior.

Puede además modificar el nombre, descripción del formulario así como también se puede añadir, editar y eliminar sus campos definidos.

Edición de formulario

Administración de campañas salientes

En esta pantalla se puede crear lo que se conoce como campañas salientes, que son información de cuándo y cómo se va a generar una serie de llamadas de manera automática a números telefónicos que se deben subir en un archivo CSV desde esta misma opción.

Listado de Campañas Salientes.

En esta opción se muestran todas las campañas salientes que se han creado en el sistema. Los datos que se visualizan en forma de columnas son:

Listado de campañas salientes

Nombre
Descripción

Nombre

Nombre de la Campaña

Fecha Inicio

Fecha de inicio en que se va a encontrar vigente la Campaña

Hora Inicio

Hora de inicio en que se va a encontrar vigente la Campaña

Fecha Fin

Fecha de fin de la Campaña. Luego de esta fecha no se realizarán más llamadas aunque hayan quedado números telefónicos pendientes.

Hora Fin

Hora de fin de la Campaña. Luego de esta hora no se realizarán más llamadas aunque hayan quedado números telefónicos pendientes.

Intentos

Número de Intentos de las llamadas a realizar

Troncal

Salida de la llamadas de una campaña

Cola

Cola asignada para realizar la campaña

Llamadas Completadas

Número de llamadas completadas.

Promedio

Promedio de duración de las llamadas realizadas en una campaña

Estado

Estado de una campaña, puede estar Activa o Inactiva

Opciones

Ver:

Datos de la Campaña. Además la campaña saliente podrá ser: Editada, Desactivada, Eliminada.

Activar:

Cuando la campaña está desactivada.

Datos CSV:

Datos en formato CSV de los formularios recolectados en las respectivas campañas.

Ingreso de Campañas Salientes

Desde esta pantalla se van a especificar todos los datos necesarios para la creación de una campaña. Hay que tomar en cuenta que estos datos son importantes al momento que se generan las llamadas. A continuación se describe cada uno de ellos:

Formulario de ingreso de nueva campaña

Nombre
Descripción

Nombre

Nombre de la Campaña

Fecha Inicio

Fecha de inicio en que se va a encontrar vigente la Campaña

Fecha Fin

Fecha de fin de la Campaña. Luego de esta fecha no se realizarán más llamadas aunque hayan quedado números telefónicos pendientes.

Formulario

Seleccionar los formularios de los cuales se va a hacer uso durante la campaña telefónica, para recolectar datos.

Troncal

Troncal por la que las llamadas telefónicas salen.

Contexto

Nombre del contexto a utilizar en una campaña. Por defecto se utiliza: frominternal

Cola

Cola que se ha creado en el IVR con los agentes que van a realizar las llamadas y que es asignada para realizar la campaña

Intentos

Número de veces que se reintenta ejecutar una llamada que no se ha ejecutado con éxito.

Archivo de Llamadas

Archivo formato CSV que contiene los números de teléfonos de las personas a las cuales se realizará las llamadas. A más de los teléfonos también se pueden cargar más datos.

Script

Script o Guión es un mensaje de guía para los agentes en el momento que están realizando las llamadas, es decir, que este podría servir en el momento que una llamada es realizada y el agente tiene un saludo cargado en este script

Archivo de Llamadas

En el archivo de llamadas se colocarán los números de teléfonos, los cuales serán llamados por el marcador al efectuar una campaña. También es posible especificar en el archivo más columnas que contengan datos como Nombre, Dirección, Cédula, etc. Estas columnas se pueden definir arbitrariamente y pueden ser referenciadas luego desde el guión.

Existen algunas restricciones de formato del archivo de llamadas:

Debe estar en formato CSV

La primera columna debe ser el número telefónico.

Si se especifica en la primera fila las cabeceras, esta debe iniciar con una coma (,).

En general un archivo de llamadas puede estar constituido únicamente por los números telefónicos a los que van a llamar.

Formato básico del archivo de llamadas

Como explicamos antes también se puede incluir un número arbitrario de columnas separadas por comas conteniendo cualquier información que se necesite mostrar en el guión.

Archivo de llamadas con columnas arbitrarias

Nota: El número de teléfono, no tendrá cabecera alguna, los demás campos se colocarán separados por (,) comas.

Visualizar, Editar y Eliminar campañas

Al dar clic sobre la palabra View, se nos conducirá a una pantalla donde se mostrará los datos de la campaña.

Visualización de los datos de una campaña

Para editar, desactivar o eliminar una campaña haga uso de los botones que se encuentran en la parte de arriba de la información.

Los datos que puede cambiar son: Nombre, Fecha Inicial, Fecha Final, Formularios, Troncal, Contexto, Cola, Número de Intentos y Script.

Editando una campaña

Administración de llamadas entrantes

Aquí se nos permite asignar aquellas colas que serán destinadas para recepción de llamadas, facilitando realizar un monitoreo de la llamadas recibidas por un agente, para determinar cuales se realizaron con éxito y cuales no lograron contestación.

Listado de Colas

Muestra la lista de las llamadas entrantes, con los siguientes datos.

Listado de colas para manejar llamadas entrantes

Nombre
Descripción

Nombre de cola

Número de la Cola

Estado

Puede ser Activa o Inactiva

Opciones

Ver:

Muestra información de la cola, tal como:

Script detallado, cuál es el mensaje observado por los agentes.

La cola seleccionada podrá ser: Editada o

Desactivada.

Activar:

Activa una cola posee el estado de Inactiva

Seleccionar una Cola

Para seleccionar una cola, dar clic en el botón de Seleccionar una cola. Se mostrará un formulario en cual se ingresarán los siguientes campos:

Formulario para seleccionar una cola y asociarle un guión

Nombre
Descripción

Seleccionar una cola

Selecciona de un combo una cola previamente creada

Script

Guión o mensaje visualizado por Agente

Visualizar, Editar y Eliminar

Al dar clic sobre la palabra View, se nos llevará a una pantalla donde se mostrará los datos de la cola.

Visualización de una cola

Para eliminar una cola de clic en el botón Eliminar. Se puede además modificar los datos de la cola clic en el botón Editar. El dato que puede cambiar es: el Script.

Edición de una cola

Administración de pausas o breaks

La opción para administrar breaks se encuentra en el menú Call Center -> Breaks y nos permite crear las pausas durante las cuales los agentes no receptarán o realizarán llamadas. Un ejemplo de Break es el tiempo de lunch de un agente.

Listado de breaks

Muestra la lista de breaks, con los siguientes datos:

Pantalla de listado de breaks

Nombre
Descripción

Nombre

Nombre del Break

Descripción

Descripción del Break

Estado

Puede ser Activo o Inactivo

Opciones

Ver:

Muestra información del break.

El break podrá ser: Editado o Desactivado.

Activar:

Activa un break cuyo estado es Inactivo

Insertar nuevo break

Para crear un break, dar clic en el botón de -Crear Nuevo Break-. Se mostrará un formulario como el de la siguiente figura.

Formulario de creación de nuevo break

Visualizar, Editar y Eliminar

Al dar clic sobre la palabra View, se nos llevará a una pantalla donde se mostrará los datos del break.

Visualización de los datos de un break

Para desactivar un break de clic en el botón desactivar.

Puede además modificar los datos del break clic en el botón Editar. Los datos que se pueden cambiar son: Nombre y Descripción.

Editando un break

26.5 La consola de agente

Todo agente debe tener a mano un teléfono IP configurado para que se conecte a la central Elastix usada para las campañas. Para esto se puede usar cualquier teléfono VoIP físico, o un programa de softphone que se ejecute en la PC del agente.

Para empezar a atender llamadas, el agente debe ingresar a la página Web de Elastix con su usuario, y luego elegir la opción Call Center ->Agent Console. Esto muestra una segunda petición de ingreso a la interfaz (login), que muestra una lista desplegable con los agentes creados, y otra lista desplegable con las extensiones disponibles. El agente debe elegir de las listas su propio código y extensión, y pulsar el botón de Aceptar. Entonces la interfaz Web ordena al Asterisk que inicie una llamada de ingreso (login) hacia la extensión del agente. El agente debe de contestar el teléfono, y escuchará una grabación que indica que ingrese la clave de acceso del agente. El agente debe usar el teclado numérico del teléfono para ingresar la clave, y si es correcta, el sistema admite al agente como registrado y disponible para recibir llamadas.

Si hay una campaña activa en la cola donde el agente está registrado, el agente eventualmente recibirá una llamada a través de dicha cola. Entonces la interfaz Web muestra la información del número marcado, y posiblemente la información ingresada según la campaña. El agente debe entonces hablar con el abonado, usando si es necesario el guión disponible en la cejilla marcada como Script. Si la campaña se realiza para encuesta y se tiene un formulario, el formulario aparece en otra cejilla para que el agente lo llene con la información proporcionada con el abonado. Si el abonado cierra la llamada, la información de la llamada desaparece, y el agente queda disponible para atender la siguiente llamada.

26.6 Resolución de problemas

A continuación se detallan algunos problemas que podrían ocurrir durante el funcionamiento del marcador, junto con sugerencias sobre posibles soluciones a tales problemas. Para cualquier problema relacionado con el marcador, es de suma utilidad examinar el archivo de log del marcador ubicado en /opt/elastix/dialer/dialerd.log. Se puede activar la emisión de mensajes de depuración al archivo de log, a través de la interfaz Web desde CallCenter -> Configuration.

Marcador no marca (ningún agente recibe llamadas):

Si ningún agente de una campaña recibe llamadas, pueden haber dos escenarios principales: el que no se estén generando llamadas en primer lugar, o el que todas las llamadas estén fallando en ser colocadas. Si ninguna llamada está siendo generada, puede ocurrir que

la campaña está en estado inactivo (verificable a través del listado de campañas en la página Web)

la campaña está fuera de horario. Se puede verificar esto con la opción Ver (View) del listado de campañas. Versiones viejas de la interfaz Web tenían un problema de usabilidad en el cual la fecha de inicio de la campaña y la hora de inicio de la campaña en cada día se introducían con el mismo control, así como con la fecha final y la hora de fin de actividad diaria. Resultaba frecuente que se eligiera la hora igual para inicio y fin de la banda diaria de actividad por error, lo cual conducía a que la campaña nunca se activara. Aunque la interfaz actual fue rediseñada para evitar este error, hay que tenerlo en cuenta, especialmente con campañas creadas con versiones antiguas de la interfaz.

Si todas las llamadas fallan en ser colocadas (lo cual se puede averiguar examinando el log detallado), se debe verificar si se pueden colocar llamadas a través de un teléfono ordinario o un softphone, a través de la troncal que se debe usar para la campaña. Si se puede hacer esto, se debe verificar que la troncal está correctamente especificada. Las versiones recientes del marcador corrigen un problema con troncales que requieren prefijos antes del número marcado, cuando tal prefijo se guarda en el FreePBX. Si su central usa una troncal personalizada, verifique que la plantilla de marcado especifica un $OUTNUM$ (todo en mayúsculas) para que el marcador sepa cómo construir la cadena de marcado.

2008/10/03 13:14 : (DialerProcess) DEBUG: generando llamada

        Destino..... 9832855147

        Cola........ 3000

        Contexto.... from-internal

        Trunk....... SIP/IPCOM

        Plantilla... SIP/IPCOM/84162352$OUTNUM$

        Caller ID... (no definido)

        Cadena de marcado SIP/IPCOM/841623529832855147

En el ejemplo de arriba, el programa de marcado emite (con depuración activada) el trunk usado, la plantilla que usa para marcar, y la cadena que se usa para especificar el marcado al Asterisk.

Marcador sólo marca a un número pequeño de agentes (subutilización):

La causa más frecuente de la subutilización de agentes es que se haya dejado en su valor por omisión al máximo número de canales a usar para la campaña. Por omisión se usan 3 canales como máximo para el trunk de la campaña. Si usted tiene más agentes, y la troncal admite una capacidad mayor, se debe aumentar el valor a un número consistente con la naturaleza de la troncal. La interfaz ISDN soporta 23 canales de voz en T1 y 30 en E1, y las troncales VoIP como IAX y SIP no tienen límite superior, excepto por ancho de banda.

Si usted usa una troncal VoIP como SIP o IAX, y luego de aumentar el máximo número de canales los agentes siguen subutilizados, es posible que las llamadas estén tardando demasiado en ser colocadas. Esto puede deberse a congestión de la red o del proveedor del otro lado de la troncal SIP. La depuración en versiones recientes del addon para call centers indica cuánto tiempo tardan las llamadas en ser colocadas:

2008/10/02 04:32 : (DialerProcess) DEBUG: (cola 501) todavia quedan 1 llamadas pendientes de OriginateResponse!

2008/10/02 04:32 : (DialerProcess) DEBUG:       llamada 32065-14-18429 espera respuesta desde hace 28 segundos.

Otro motivo frecuente por el que los agentes están subutilizados es que un porcentaje muy alto de las llamadas está fallando en la colocación. Esto también se puede revisar en el log del marcador.

27

Extendiendo la interfaz Web de Elastix

Aunque supiera que el mundo se desintegrará mañana, igual plantaría mi manzano

-- Martin Luther King

La interfaz Web de Elastix es uno de sus componentes más importantes, pues una de las premisas de diseño del producto es su facilidad de uso. A pesar de que Elastix posee una interfaz muy completa, siempre existirán requerimientos de personalización por parte de los usuarios. Por lo tanto, conocer los detalles de funcionamiento de este componente nos dará la habilitad de extender el funcionamiento de Elastix hasta nuevas fronteras.

Elastix provee un mecanismo para extender su funcionalidad basado en lo que llamaremos -módulos-. Estos módulos constituyen piezas de código que se integran a la interfaz Web de una manera sencilla.

En el presente capítulo comenzaremos explicando de manera muy general cómo se encuentra organizada la interfaz Web de Elastix y luego abordaremos el fascinante tema de cómo construir un nuevo módulo para Elastix.

Cabe destacar que no es el objetivo de la presente obra que el lector se convierta en un hábil programador, sino más bien explicar los fundamentos estructurales del funcionamiento de la interfaz Web en virtud de proporcionarle al lector las herramientas necesarias para extender de manera sencilla el producto o estar en la capacidad de solucionar problemas básicos. Es por esta razón de que en lo posible se tratará de abstraer del presente capítulo detalles relacionados con el código, a pesar de que, como resulta obvio al menos un conocimiento mínimo será necesario para llevar a cabo con éxito la tarea de extender la interfaz Web de Elastix.

27.1 El framework Neo

Un framework es un conjunto de código que sirve como base para desarrollar programas más complejos. Un framework resuelve tareas repetitivas que no queremos volver a escribir cuando nos encontramos programando. Por ejemplo, en el caso del framework utilizado en Elastix para codificar la interfaz Web, éste resuelve la manera como se dibujan los menús y la manera como se muestran los formularios o listados de información.

El framework utilizado en Elastix se denomina Neo y se encuentra escrito en el lenguaje de programación PHP. Desde sus inicios ha estado en constantes mejoras tanto en estándares de desarrollo Web, como en codificación y arquitectura, con la finalidad de proporcionar la mejor experiencia tanto a usuarios como a desarrolladores.

Entre las características del framework Neo tenemos:

Arquitectura Web basada en patrón MVC2 (Modelo Vista Controlador versión 2)

Programación Orientada a Objetos (PPO)

Implementación modular (Permite integrar nuevo código en forma de módulos)

Soporte multi-idioma

Ayuda embebida

Uso de plantillas

Soporte ACLs. Esto permite que el manejo de usuarios así como la jerarquía de permisos sean manejados directamente por el framework.

Organización del framework Neo

El framework Neo reside en el directorio raíz (o DocumentRoot) del servidor Web incluido en Elastix, es decir en la ruta /var/www/html. Dentro de este directorio se encuentran algunos archivos y carpetas, los más importantes los explicaremos a continuación.

Carpeta | Descripción
themes/ | Aquí residen los archivos de plantilla, los cuales se encuentran clasificados por temas. Existe una carpeta por cada tema disponible en Elastix. Los archivos de plantilla tienen extensión .tpl. También se pueden encontrar aquí archivos de estilo CSS.
index.php | El punto de entrada común para todas las pantallas de la interface de Elastix. Es quien decide qué pantalla mostrar dependiendo de los parámetros recibidos por el usuario.
libs/ | Aquí se encuentran las librerías y clases que contienen el modelo de la aplicación (código reciclable)
configs/ | Archivos de configuración
langs/ | Definición de los lenguajes, actualmente se soportan 22 idiomas
images/ | Lugar común para almacenar las imágenes que se usarán en la interfaz Web
help/ | Aquí residen los archivos de ayuda contextual embebida en la interfaz Web

27.2 Manipulación del menú de Elastix

El menú de Elastix es dibujado automáticamente por el framework Neo. Un módulo de Elastix no tiene que preocuparse por los detalles inherentes a la visualización del menú, así como tampoco de los permisos de los usuarios que intentarán accederlo. Esto simplifica el trabajo de codificación de un módulo y otorga robustez a la interfaz Web.

Para dibujar el menú, el framework Neo consulta una base de datos interna donde reside la información que debe ser desplegada. Adicionalmente cada vez que un usuario visita la interfaz Web el framework tiene que decidir si mostrar o no dicho menú al usuario. Para decidir esto consulta otras bases de datos donde se almacena la información de control de acceso.

Estas bases de datos internas se encuentran basadas en SQLite, un motor de base de datos muy veloz. La manipulación de estas bases es bastante sencilla pues cada base de datos se encuentra contenida en un solo archivo. Estos archivos se encuentran en la ruta /var/www/db y podemos manipularlos directamente con el comando sqlite3 que viene incluido en Elastix.

A continuación mostraremos cómo manipular estos archivos.

Creación y visualización de una pestaña de menú

Antes de crear el módulo de Elastix propiamente dicho vamos a crear una pestaña de menú para que cuando se de clic en ella nos conduzca hasta el módulo que vamos a elaborar. Esta tarea la vamos a dividir en dos partes: la creación del menú propiamente dicho y la asignación de permisos para que este menú sea visible para los usuarios.

Creación de un menú en Elastix

Los menús en Elastix se dibujan automáticamente de la información extraída de la base de datos de menús. Por lo tanto, para crear un nuevo menú debemos ingresar una nueva fila en la tabla -menú- de la base de datos menu.db. Emplearemos el comando sqlite3 para administrar esta base de datos.

Nota: Se recomienda al lector investigar acerca de los comandos básicos de sqlite3, así como también acerca las sentencias básicas de SQL. Si bien en la presente obra se dan algunos ejemplos de sentencias SQL, siempre resulta útil poder manipular las bases de datos a nuestro antojo; aparte de que esto hasta cierto punto evita que cometamos errores que pueden dejar inutilizable nuestra interfaz Web.

Una vez abierta la base de datos menu.db obtendremos un prompt etiquetado como -sqlite>- y allí podemos introducir la sentencia SQL para insertar una nueva fila en la base de datos. Esto equivale a crear un nuevo menú. A continuación la sintaxis.

$ sqlite3 /var/www/db/menu.db

sqlite> insert into menu values ('module_id', 'id_parent', 'link', 'module_name', 'module_type', 'module_position');

Donde,

Nombre Etiqueta | Descripción
module_id | Es el identificador del módulo. Se trata de un identificador de tipo texto y se recomienda usar minúsculas y utilizar solo caracteres alfanuméricos.
id_parent | El identificador del menú padre, es decir el contenedor del menú que se está creando. En caso de que sea un menú de primer nivel se usa 0.
link | Si el menú es de tipo framed (ver module_type) este campo se llena con un vínculo o URL de la aplicación que se quiere vincular. Si el menú es de tipo module se deja vacío.
module_name | Nombre del módulo. Por ejemplo -Hardware Detector-
module_type | Un módulo puede ser de dos tipos: framed y module. El primero se usa cuando se quiere embeber en un frame otra aplicación. Por ejemplo este es el caso de VTigerCRM.
module_position | La posición donde quedará ubicado el módulo. Un valor 0 lo ubicará en la primera posición de izquierda a derecha, un valor 1 lo ubicará en la segunda posición y así sucesivamente

A continuación un ejemplo de creación de nuevo menú.

$ sqlite3 /var/www/db/menu.db

sqlite> insert into menu values ('example', 'extras','', 'Example', 'module', 2);

En el ejemplo anterior vemos que hemos creado un nuevo menú debajo del menú -extras-. Es decir que el menú -extras- será el menú -padre- del nuevo menú creado.

Es importante notar que el campo module_id o identificador del módulo, que en el ejemplo anterior toma el valor de -example-, debe ser único. Es decir que su nombre no debe ser igual al de ningún otro módulo en la interfaz Web de Elastix.

Hasta aquí ya hemos creado un nuevo menú. Sin embargo, no todo es celebración, crear un nuevo menú de Elastix no es suficiente para que sea visible desde la interfaz Web debido a que por omisión ningún menú es visible a menos que le demos los permisos de acceso adecuados al usuario.

Asignación de permisos para visualizar un menú

Elastix maneja un sistema de ACLs (Access Control List) o Lista de Control de Acceso, lo que permite manejar permisos de acceso de una manera más organizada.

Antes de continuar es importante definir dos conceptos importantes para de este modo entender mejor cómo se encuentran organizados los ACLs.

Recursos: Son las entidades para las cuales se establecen los permisos. En nuestro caso los menús.

Acciones: Son las acciones que pueden ser autorizadas sobre los recursos. Por ejemplo, una acción puede ser -visualizar-, otra acción puede ser -editar- y así, dependiendo de lo que queramos hacer sobre el recurso. En el caso de los menús existe solo una acción posible y esta se llama -access-.

Toda la información de ACLs se almacena en otra base de datos SQLite llamada acl.db. Esta base de datos contiene algunas tablas que se enlistan a continuación.

[root@elastix ~]# sqlite3 /var/www/db/acl.db

sqlite> .tables

acl_action acl_membership acl_user

acl_group acl_profile_properties acl_user_permission

acl_group_permission acl_resource acl_user_profile

Nota: La base de datos acl.db contiene algunas tablas a diferencia de la base de datos menu.db que solo contenía la tabla -menu-.

A continuación explicaremos para qué sirven las tablas más importantes.

Tabla | Descripción
acl_action | Esta tabla almacena las acciones posibles sobre un recurso.
acl_group | Los usuarios se pueden asociar en grupos para facilitar la asignación de permisos. De esta manera es más fácil modificar los permisos de un grupo de usuarios en lugar de estar cambiando permisos a cada usuario.
acl_group_permission | Matriz de permisos de un grupo dado. Básicamente aquí se almacenan qué acciones puede realizar un determinado grupo sobre un determinado recurso.
acl_membership | Esta tabla (cuyo nombre se traduce como membresía) almacena la relación usuario vs grupo. Es decir que nos dice qué usuarios pertenecen a qué grupos.
acl_resource | En el caso de Elastix un recurso significa un menú. Un recurso es la entidad que es objeto de los permisos.
acl_user | Aquí se almacenan los usuarios de Elastix. Por omisión se encuentra aquí el usuario admin, caso contrario no se podría ingresar a la interfaz de Elastix por primera vez.
acl_user_permission | Esta tabla contiene la matriz de permisos para cada usuario

Del listado anterior podemos notar que existen dos lugares que contienen información de permisos para un usuario dado: la tabla de permisos del usuario y la tabla de permisos del grupo al cual pertenece dicho usuario. El framework Neo une estos dos conjuntos de permisos para calcular los permisos totales del usuario. De este modo si un usuario NO tiene permiso para acceder al menú -shutdown-, pero el grupo al cual pertenece SI tiene permiso, entonces el resultado es que el usuario PODRA acceder al menú -shutdown- debido a que los permisos del grupo al cual pertenece se lo permiten.

Veamos ahora cómo manipular las tablas de ACLs para otorgarle a nuestro nuevo menú los permisos necesarios para poderlo visualizar.

Lo primero que haremos será examinar la tabla acl_resource que como explicamos antes almacena la información de menús. En cierto modo el lector puede pensar que es una tabla innecesaria debido a que ya definimos los menús en la base de datos menu.db. Sin embargo, es importante recordar que el concepto de -recurso- es más general que el de menú, aunque en nuestro caso venga a ser lo mismo.

Nota: La salida de la siguiente tabla ha sido truncada pues no es necesario mostrar toda la salida. Elastix contiene actualmente más de 100 menús y el número crece cuando instalamos addons.

[root@elastix ~]# sqlite3 /var/www/db/acl.db

sqlite> select * from acl_resource;

2|network|Network

3|network_parameters|Network Parameters

4|dhcp_server|DHCP Server

5|usermgr|User Management

6|grouplist|Group List

7|userlist|User List

8|group_permission|Group Permission

10|shutdown|Shutdown

11|hardware_detection|Hardware Detection

12|updates|Updates

13|packages|Packages

14|repositories|Repositories

15|backup_restore|Backup/Restore

16|preferences|Preferences

17|language|Language

En la tabla anterior vemos que existen 3 campos: el identificador del menú (un entero secuencial automático), el nombre del menú y una descripción corta del mismo.

El siguiente paso será ingresar nuestro menú -example- en la tabla acl_resource. Solo interesa ingresar el nombre del menú y la descripción debido a que el identificador se ingresará de manera automática.

$ sqlite3 /var/www/db/acl.db

sqlite> insert into acl_resource (name, description) values ('example', 'Example');

Ahora debemos ir a Sistema -> Administrar Usuarios -> Permisos de Grupo y seleccionamos el nuevo menú para el grupo -Administrador-. Presionamos -Guardar selección como accesible- y el nuevo menú será accesible desde la interfaz Web para el grupo -Administrador-.

Nota: Para que los cambios sean visibles es necesario salir desde la interfaz Web y volver a iniciar sesión.

En este punto nuestro nuevo menú ya es visible por el administrador. Veamos ahora cómo cambiar el idioma de los elementos listados en los Permisos de Grupo.

Definición del menú en los archivos de idioma

Los archivos donde se encuentran las traducciones a los diferentes idiomas soportados por Elastix residen en la carpeta /var/www/html/lang.

Esta carpeta contiene algunos archivos, uno por cada idioma. Las dos primeras letras del nombre del archivo identifican el idioma. Por ejemplo, el archivo en.lang se usa para el idioma inglés (english) mientras que el archivo es.lang se usa para el idioma español.

Estos archivos son archivos de texto que podemos editar con el editor vim. Sin embargo, es importante notar que se encuentran en lenguaje PHP por lo que debemos tener cuidado de no eliminar caracteres especiales como el punto y coma o los paréntesis.

Editemos el archivo es.lang para que al acceder a los Permisos de Grupo, estando el idioma de la interfaz web configurado a español, nuestro nuevo módulo se muestre apropiadamente listado en dicho idioma.

Nota: Si su Elastix se encuentra configurado en otro idioma debe editar el archivo correspondiente.

Al final de este archivo y antes del símbolo -);- agregue una nueva línea que contenga la traducción del nombre del menú. Las 3 últimas líneas del archivo deben lucir como a continuación.

La primera palabra a la izquierda de los símbolos => es lo que se conoce como clave. Usualmente está inglés y se corresponde con la descripción que ingresamos en la tabla acl_resource.

Grabe el archivo y listo, ya podremos ver el nombre de nuestro módulo apropiadamente en español al acceder aSistema -> Administrar Usuarios -> Permisos de Grupo.

Visualizando el nuevo menú

Ahora en Sistema -> Administrar Usuarios -> Permisos de Grupo, verá que el nombre de su modulo se visualiza en el idioma correcto, si no está marcado, márquelo y aplique los cambios.

Listado de permisos de grupo. Ahora sí se muestra el nombre del nuevo módulo

Visitemos ahora nuestro nuevo menú que se encuentra dentro del menú padre -Extras- y veamos qué sucede.

Visitando por primera vez nuestra nueva entrada en el menú

El mensaje de error anterior es solo una indicación de que el framework Neo no ha encontrado el código del módulo asociado con el nuevo menú creado. Por ahora no hay mayor drama debido a que no hemos codificado el módulo todavía. Resolveremos esto en breve, lo importante aquí es que hemos creado un nuevo menú en Elastix y lo hemos asociado a una estructura de permisos.

27.3 Programación del Módulo -Hola Mundo-

Hasta este punto ya hemos aprendido que un menú de Elastix está atado a un módulo, el cual se encarga de mostrar el contenido. Un módulo no es otra cosa que código PHP que es relativamente sencillo de integrar dentro de la interfaz Web de Elastix. En las siguientes líneas mostraremos cómo codificar un módulo de ejemplo muy sencillo: el famoso -Hola Mundo-.

Ubicación de un módulo de Elastix

Cada módulo reside dentro de una carpeta dentro de la ruta /var/www/html/modules y el nombre de esta carpeta tiene que ser igual al module_id que se ingresó en la tabla -menú-. En nuestro caso el module_id era -example- por lo que debemos crear una nueva carpeta llamada -example- donde residirá el código de nuestro módulo.

$ mkdir -p /var/www/html/modules/example/

También es importante mantener los permisos de la carpeta creada bajo el usuario -asterisk- ya que el servidor Web de Elastix se ejecuta bajo este usuario.

$ chown -R asterisk:asterisk /var/www/html/modules/example/

Como pudimos ver la última vez que tratamos de acceder al nuevo menú, el framework Neo trató de buscar un archivo en la ruta /var/www/html/modules/example/index.php y no lo encontró. Este archivo es el punto de acceso al módulo, es decir, lo primero que el framework Neo tratará de invocar como parte del módulo. Veremos a continuación cómo crear este archivo y llenarlo con algo de código.

Archivo index.php

Como ya vimos, el archivo index.php dentro de la carpeta de un módulo es el punto de entrada al módulo.

Este archivo debe contener como mínimo una función llamada _moduleContent. Esta función debe retornar el contenido HTML que será mostrado por el módulo.

Nota: En programación la función _moduleContent es lo que se conoce como callback.

Para que nuestro módulo muestre la famosa frase -Hola Mundo- debemos crear un archivo llamado index.php en la ruta /var/www/html/modules/example. El archivo debe contener lo siguiente.

<?php

function _moduleContent($smarty, $module_name)

{

return (-Hola Mundo-);

}

?>

Eso es todo. Si visitamos nuevamente nuestro menú de ejemplo veremos en la pantalla que nuestro módulo nos saluda con un cordial -Hola Mundo-.

27.4 El addon para desarrolladores al rescate

Elastix cuenta con un addon muy útil llamado -Developer-, que nos permitirá construir un módulo más complejo que nuestro anterior -Hola Mundo- y todo desde la misma interfaz Web de Elastix.

El addon Developer nos permitirá crear de manera transparente para nosotros el esqueleto inicial de código necesario para elaborar un módulo de Elastix, lo que puede constituir un ahorro de horas en muchos casos.

Existen tres tipos de módulos que este addon puede construir y son: Formulario, Reporte y Enmarcado. Ya veremos más adelante en qué consisten estos tipos de módulos, por ahora vamos a comenzar instalando el addon.

Instalación del addon para desarrolladores

La instalación de este addon es sumamente sencilla gracias al nuevo soporte de addons disponible a partir de Elastix 2.0.

Para instalarlo debemos ingresar a la interfaz de Elastix como administrador y luego acudir al menú -Addons-. Esperamos a que el listado de addons verifique dependencias locales y damos clic en el botón que dice -Instalar- junto al addon etiquetado como -Developer-.

Luego de esto salimos de la interfaz y volvemos a ingresar como administrador. Debemos ver una nueva pestaña de menú con el nombre -Developer-.

Construcción de un módulo con el addon para desarrolladores

El addon para desarrolladores tiene tres submenús pero el que nos interesa se llama -Constructor de Módulos- o -Build Module- y es el primer submenú.

La función del constructor de módulos es generar el esqueleto de código del nuevo módulo que estamos creando, para que luego podamos continuar con el desarrollo extendiendo este código inicial.

Al crear un modulo desde aquí, se generará lo siguiente:

El menú (o los menús) dentro de la interfaz Web de Elastix. Es decir que ya no tendremos que modificar manualmente la base de datos menu.db!

El código esqueleto, el cual se encontrará dentro de una carpeta cuyo nombre será igual al ID del módulo. Esta carpeta será ubicada a su vez dentro de la carpeta /var/www/html/modules que es donde residen todos los módulos de Elastix. Es decir que ya no tenemos que crear manualmente esta carpeta!

Pantallas prototipo. Como dijimos antes, estas pantallas pueden ser de tres tipos: formulario, reporte y enmarcado.

Veamos ahora cómo luce el constructor de módulos.

El constructor de módulos incluido en el addon Developer

Como podemos observar, el constructor de módulos se encuentra dividido en tres partes:

Información General

Localización

Descripción del módulo

Información General

Esta sección nos permite definir el nombre e identificador único del módulo, así como también los datos de la persona que crea el modulo para comentarlas en las cabeceras de cada archivo de programación en PHP. También nos permite configurar el nivel de accesibilidad que tendrá el módulo a través del parámetro -Permisos de Grupo

Sección de información general dentro del constructor de módulos

Localización

En esta sección se configura el lugar, dentro del menú, donde vamos a ubicar el nuevo módulo. Por omisión esta sección luce como la siguiente figura.

Sección donde se configura la ubicación del módulo

Si decimos que el módulo es de nivel 3 entonces aparecerán automáticamente nuevos campos para ingresar los identificadores de los menús padres de nivel 1 y nivel 2.

Aparecen nuevos campos si se dice que el módulo será de nivel 3

Para clarificar el significado de los campos mostrados en esta sección veamos la siguiente tabla.

Nombre campo
Descripción

Nivel del Módulo

Aquí definimos el nivel de jerarquía del modulo.

¿Existe Padre Nivel 1?

Aquí definimos si vamos a colocar el nuevo módulo bajo un menú de nivel 1 existente o se tendrá que crear uno nuevo. Para colocar el nuevo módulo bajo un menú previamente existente escogemos -Sí- y de manera automática se desplegará un listado con los módulos de nivel 1 existentes.

Si escogemos -No- crearemos un nuevo menú de nivel 1 sobre la marcha. Por esta razón aparecerán dos campos adicionales para especificar el nombre y el identificador.

Nombre Padre Nivel 1

Definimos el nombre del módulo padre. La primera letra con mayúscula.

Id Padre Nivel 1

Definimos el identificador del módulo padre. Todo con minúsculas y no se permiten espacios.

¿Existe Padre Nivel 2?

Esta opción aparecerá si escogimos un nivel 3 en el campo -Nivel del Módulo-.

De manera similar a lo que ocurre con el campo -Existe Padre Nivel 1-, si se escoge -No- aparecerán dos campos más.

Nombre Padre Nivel 2

Definimos el nombre del módulo padre de nivel 2. La primera letra con letra mayúscula.

Id Padre Nivel 1

Definimos el identificador del módulo padre de nivel 2. Todo con minúsculas y no se permiten espacios.

Descripción del módulo

Esta última sección es la más interesante pues es aquí donde se crea el contenido mismo del módulo.

A continuación se explica qué significan los tres tipos de módulos que se pueden crear.

Formulario: Sirve para recolectar datos del usuario. El constructor de módulos cuenta con soporte para los tipos de campos HTML más comunes como son: texto, selección, fecha, área de texto, casilla de verificación, radio, contraseña, oculto y archivo.

Reporte: Un reporte muestra datos organizados en forma de una tabla donde se incluyen automáticamente algunos controles útiles como botones para navegación. Luego de generar el código necesario con el constructor de módulos ya es más sencillo enlazar el reporte con una base de datos para mostrar información útil.

Enmarcado: Embebe un URL arbitrario en la pantalla. Muy útil cuando queremos integrar aplicaciones externas en la interfaz Web de Elastix. Un ejemplo de esto es la integración de vtigerCRM.

Creación de una pantalla tipo Formulario

Con los botones ">>", "<<" podemos añadir o quitar los campos a insertar en nuestro formulario.

Eliminación de un módulo a través del addon para desarrolladores

Otra opción interesante del addon para desarrolladores es que nos permite eliminar módulos. Esto es útil si estamos desarrollando un nuevo módulo y estamos haciendo pruebas.

El submenú "Delete Module" del addon para desarrolladores nos permite eliminar módulos en todos sus niveles. Primero se tendrán que eliminar los submódulos que existan en el módulo padre para poder eliminarlo por completo.

Eliminación de un módulo

Nota: >Es muy importante estar seguro antes de seleccionar la opción -Delete Files- pues esto eliminará todos los archivos relacionados con el módulo en el disco duro.

Administración de lenguajes desde el addon para desarrolladores

El submenú "Language Admin" del addon para desarrolladores nos permite administrar los diferentes archivos de idioma de los módulos en Elastix.

Aquí podemos consultar si existe un idioma definido para un módulo, también para el framework Neo y observar una lista de palabras con su respectiva traducción como lo podemos observar en la figura de abajo. Estos valores pueden ser modificados de acuerdo al idioma que desee traducir y guardar los cambios presionando el botón "Save all".

Administración de idiomas desde el addon para desarrolladores

27.5 Diferencia entre un módulo y un addon

Es común confundirse y pensar que un módulo y un addon son la misma cosa, al final de cuentas los dos por lo general terminan siendo un nuevo menú de Elastix. Sin embargo un addon es algo mucho más complejo que un módulo.

Un addon es un paquete de software certificado por PaloSanto Solutions y que se encuentra disponible en formato RPM a través de un repositorio oficial. Un addon puede contener un módulo, pero además también puede contener otros componentes de software, escritos en cualquier lenguaje soportado por Elastix. La instalación de un addon se realiza de manera sencilla e intuitiva a través del menú -Addons- desde la interfaz Web de Elastix.

Dicho lo anterior es importante aclarar que un módulo de Elastix sí se puede convertir en un addon. Para hacer esto es necesario empaquetar el módulo en formato RPM e iniciar un proceso de certificación de software interoperable con Elastix.

Para más información acerca de este proceso de certificación es necesario escribir un email a certification@palosanto.com

28

Virtualización

El hombre nunca debe avergonzarse de reconocer que se ha equivocado, puesto que hacerlo corresponde a decir que hoy sabe más que lo que sabía ayer

-- Alexander Pope

Existen situaciones donde resulta interesante virtualizar Elastix. Una de ellas, que se ha vuelto algo popular en los últimos tiempos, es la de permitir a los proveedores de servicios de centros de datos (datacenters) el incluir un producto más a su lista: Hosted PBX.

Sin duda resulta más rentable ofrecer este servicio si se puede virtualizar Elastix en lugar de disponer de un servidor por cliente, pues así se optimizan recursos.

Sin embargo, esta no es la única situación interesante. Existen algunos otros escenarios donde el cliente puede encontrar productivo dividir un mismo hardware entre varias máquinas virtuales, entre ellas Elastix.

28.1 Opciones de virtualización

En la actualidad existen algunas opciones de virtualización en el mercado como VMWare, VirtualBox, XEN, entre otras. En el presente capítulo nos limitaremos a explicar la herramienta VirtualBox debido a su popularidad y madurez.

28.2 Elastix sobre VirtualBox

VirtualBox es una herramienta de virtualización que permite ejecutar diversos sistemas operativos en máquinas virtuales. De esta manera la podemos utilizar para instalar un servidor virtual con Elastix.

Existen 2 versiones de VirtualBox que podemos utilizar par virtualizar Elastix:

La versión libre que viene incorporada en la mayoría de distribuciones Linux

La no libre pero que se puede descargar sin costo de su página Web y funciona también para algunas plataformas, inclusive para Windows y Mac OS

La principal diferencia entre la versión libre y la no libre es el soporte para dispositivos USB en las máquinas virtuales. Esto es algo que no vamos a necesitar para propósitos didácticos en la presente obra, por lo que la versión libre funcionará de excelente manera.

Por ejemplo en caso de utilizar una distribución basada en Debian como por ejemplo Ubuntu se debe ejecutar el siguiente comando:

sudo aptitude install virtualbox-ose virtualbox-ose-modules-`uname -r`

Para el caso de Windows o Mac OS o distribuciones Linux que no tengan VirtualBox en sus repositorios se puede descargar el instalador desde http://virtualbox.org y seguir el wizard para instalación

VirtualBox y Redes

Antes de poder utilizar VirtualBox para crear nuestra máquina virtual debemos configurar la forma en la que VirtualBox manejará las redes. VirtualBox puede manejar hasta cuatro interfaces de red virtuales por cada máquina virtual. Cada una de estas tarjetas de red puede tener una de las siguientes configuraciones:

No Conectada: en este caso la máquina virtual tiene una tarjeta de red pero funcionará como si no tiene un cable de red conectado. Esta modalidad no será útil para instalar Elastix ya que Elastix no tiene mayor uso si no esta conectado a una red.

NAT: Esta es la configuración por defecto y permite que nuestra máquina virtual pueda ver nuestra red o salir a Internet, pero no puede ser vista por otras máquinas en la red. Esta función tampoco nos sirve para Elastix ya que necesitamos que nuestra máquina virtual sea vista por toda la red

Red Local: La configuración de red local crea una red virtual entre nuestras máquinas virtuales. De esta forma las máquinas virtuales solo podrán ver a máquinas virtuales dentro de esta red virtual. Esto es útil si se quiere colocar a servidores virtuales atrás de un firewall virtual. En el caso de Elastix se podría utilizar pero para este caso particular queremos que nuestra máquina virtual sea una más en la red.

Interfaz Anfitrión: Esta opción permite que nuestra máquina virtual sea vista por toda la red como si fuera una máquina real. Esta es la opción que utilizaremos para instalar la máquina virtual de Elastix.

Nota: La máquina virtual puede tener hasta 4 interfaces virtuales por lo que se podría tener una interfaz de red interna y otra interfaz anfitrión en una sola máquina virtual.

Configuración de la interfaz anfitrión

Configuración de Red Sistema Operativo MS Windows

Para crear una interfaz de red virtual en Windows es necesario ejecutar el siguiente comando:

VBoxManage createhostif "VM1 external"

Configuración de Red en Sistema Operativo Linux

Para configurar la tarjeta de red de nuestra máquina virtual debemos crear un bridge a nivel del sistema operativo anfitrión. Este bridge se podría decir que será nuestro switch virtual a donde se conectarán las máquinas virtuales.

Para crear el bridge se requiere instalar el paquete bridge-utils. Para distribuciones basadas en Debian se debe ejecutar el siguiente comando para instalar:

sudo aptitude install bridge-utils

Ahora podremos crear nuestro bridge y utilizaremos la interfaz eth0 para esto.

1. Configuramos la interfaz eth0 para que funcione en modo promiscuo

sudo ifconfig eth0 0.0.0.0 promisc

2. Creamos el bridge y añadimos la interfaz eth0 al mismo

sudo brctl addbr br0

sudo brctl addif br0 eth0

3. Asignamos la dirección IP de nuestra máquina al bridge y ya no será utilizado más por la interfaz eth0

Con dirección IP dinámica

sudo dhclient br0

Con dirección IP estática

sudo ifconfig br0 <mi ip> netmask <mascara de red>

sudo route add default gw <ip de mi gateway>

Con esto hemos creado el bridge y nos hace falta crear las interfaces virtuales para las instalaciones de Elastix. Para esto vamos a utilizar el utilitario que trae VirtualBox.

sudo VBoxAddIF vbox0 rafael br0

Con este comando hemos creado la interfaz vbox0 que ha sido añadida al brige br0. Si quisiéramos añadir más interfaces ejecutamos el mismo comando pero cambiamos vbox0 por vbox1, vbox2, etc.

Mantener la configuración de manera permanente

De lo antes visto, lo único que se conserva de manera permanente es la creación de la interfaz vbox0, la configuración del bridge y la tarjeta de red se perderán por lo que sería muy útil crear un script para esto que contenga la siguiente información

#!/bin/bash

sudo ifconfig eth0 0.0.0.0 promisc

sudo brctl addbr br0

sudo brctl addif br0 eth0

Para que el script sea accesible desde cualquier ruta es recomendable guardarlo en /usr/local/sbin y darle permisos de ejecución. Si vamos a crear máquinas virtuales cada vez que arrancamos nuestro PC podríamos pensar en ejecutar este script de manera automática cada vez que iniciamos nuestro computador.

Creación de la máquina virtual

Tenemos todo el ambiente listo para crear nuestra máquina virtual y poder ejecutarla. Para hacer la instalación se pude usar un CD de Elastix o simplemente el archivo con la imagen ISO. En este caso utilizaremos la imagen ISO.

Ejecutamos VirtualBox y seleccionamos la opción de crear una nueva máquina virtual. Aquí usted deberá contestar algunas preguntas.

En la primera ventana se pedirá el nombre de la máquina virtual y el sistema operativo que se instalará en este. Ponga el nombre que usted desee y seleccione Red Hat como sistema operativo.

En la segunda ventana se debe seleccionar la cantidad de memoria RAM que nuestra máquina virtual utilizará. Para motivos de aprendizaje seleccionaremos 256 Mb pero si estuviéramos creando un servidor que utilizaremos deberíamos seleccionar más memoria dependiendo de las necesidades.

En la tercera ventana se nos solicita seleccionar el disco duro. Lo más probable es que se tenga que crear un disco duro virtual.

Al crear el disco duro virtual se nos dará 2 posibilidades. Utilizar una imagen de tamaño fijo o utilizar una de tamaño dinámico. La diferencia es que la de tamaño fijo ocupará todo el espacio asignado en la máquina real mientras que la dinámica ira creciendo en el tiempo. En este caso seleccionaremos tamaño fijo.

Se asigna el nombre del disco duro y el tamaño deseado. Para fines didácticos 4 GB puede ser un buen tamaño, pero para producción necesitaremos mucho más. Damos aceptar y hemos creado el disco duro virtual para nuestra máquina.

Con esta información ya estamos listos para terminar la creación de nuestra máquina virtual.

Configuración Previa de la Máquina Virtual

Antes de encender nuestra máquina virtual, debemos decir a nuestro a VirtualBox qué configuración de red utilizar. Para esto seleccionamos la máquina virtual creada y seleccionamos configuración. En la ventana de configuración se debe seleccionar la configuración red.

Una vez en la ventana de configuración de red configuraremos el adaptador 1 de red para que funcione como interfaz de anfitrión. Para esto se deben modificar 2 cosas:

Donde dice -attached to- se debe seleccionar Interfaz Anfitrión.

Donde dice -Interface Name- debemos escribir vbox0 en el caso de Linux o seleccionar de la lista desplegable la interfaz en el caso de Windows.

Nota: pusimos el nombre vbox0 ya que anteriormente creamos esta interfaz de red. Si creáramos más máquinas virtuales deberíamos crear vbox1, vbox3, etc.

Arrancar la Máquina Virtual por Primera Vez

La primera vez que arrancamos la máquina virtual se solicitará seleccionar el medio de arranque. En el presente ejemplo se utilizará una imagen ISO guardada en el disco duro. Para esto seleccionamos utilizar CDROM y utilizar archivo de imagen ISO. Se selecciona el archivo y damos siguiente. A continuación seguiremos el procedimiento normal de instalación de Elastix.

Instalación de Elastix en VirtualBox

Una vez terminada la instalación podremos acceder a la interfaz Web administrativa de Elastix desde cualquier PC en nuestra red, añadir teléfonos IP, conectar troncales SIP o IAX, entre otras cosas; tal como lo haríamos en una máquina real. Lo único que no podremos hacer es acceder a las tarjetas de red PCI.

Opciones Avanzadas

Clonar Máquinas Virtuales

Una de las ventajas de la virtualización es que se puede clonar un disco duro de una máquina virtual y tener un respaldo completo de todo el sistema operativo. Si alguna vez la máquina que esta en producción deja de funcionar bastaría con reiniciar nuestra máquina virtual desde el último respaldo. Otro caso útil ocurre si tenemos un servidor pre-configurado que necesitamos replicar en varias instalaciones. Entonces se puede clonar varias veces esta máquina virtual.

Los discos duros de las máquinas virtuales de VirtualBox se almacenan en archivos con extensión .vdi. En el caso particular de Linux estos archivos se guardan en la siguiente ruta:

/home/<usuario>/.VirtualBox/VDI

Donde <usuario> debe ser remplazado con el nombre de mi usuario.

Para clonar una imagen de disco duro se debe apagar la máquina virtual y ejecutar el siguiente comando en la ruta donde se encuentran los archivos VDI:

VBoxManage clonevdi Elastix_Virtual.vdi Elastix_Virtual-clone.vdi

En este ejemplo se ha clonado la imagen Elastix_Virtual.vdi al archivo Elastix_Virtual-clone.vdi. Si queremos utilizar el nuevo disco duro bastara con crear una nueva máquina virtual y seleccionar este archivo como disco duro.

Arrancar Máquina Virtual sin Interfaz Gráfica

Podría darse el caso de que necesitemos iniciar VirtualBox sin Interfaz Gráfica, esto puede ser útil si se desea tener servidores cuya única función es la de correr máquinas virtuales por lo que no necesitan una interfaz gráfica. Al ejecutar Elastix sin interfaz gráfica solo será accesible a través de la interfaz Web o SSH. Existen casos en lo que esto suele ser muy útil para compañías de hosting que venden servidores virtuales de VoIP con Elastix.

Para arrancar la máquina virtual sin interfaz gráfica basta con ejecutar el siguiente comando:

VBoxHeadless --startvm "Elastix Virtual"

Donde -Elastix Virtual- es el nombre que hemos puesto a nuestra máquina virtual, si deseáramos arrancar una o varias máquinas virtuales al encender nuestro servidor, bastaría con ejecutar este comando cuando la computadora arranca.

29

Compilando Asterisk

La vida no es la que uno vivió, sino la que uno recuerda

-- Gabriel García Márquez

Son muchas las situaciones en las que es útil recompilar Asterisk. Por ejemplo si se quiere parchar el código para agregar funcionalidad o si se quiere optimizar Asterisk para eliminar funcionalidad no necesaria y mejorar el rendimiento.

Como en cualquier compilación de un paquete de software complejo esta es una tarea que requiere relativo conocimiento para resolver cualquier posible problema que se pueda presentar. Aquí trataremos de explicar brevemente los conocimientos básicos.

29.1 Recompilando los SRPMs

La manera relativamente más fácil de recompilar Asterisk si se está usando Elastix es utilizando los SRPMs provistos por el proyecto Elastix. Estos se pueden descargar de las siguientes rutas:

http://repo.elastix.org/elastix/2/updates/SRPMS/

http://repo.elastix.org/elastix/2/base/SRPMS/

Si se requiere probar una versión de prueba de Asterisk para Elastix, se puede buscar en el repositorio elastix-beta, cuya ruta es la siguiente.

http://repo.elastix.org/elastix/2/beta/SRPMS/

Un SRPM (o Source RPM) es un paquete que contiene la información necesaria para construir un RPM, como el código fuente del paquete y las directrices usadas para compilarlo e instalarlo en el sistema.

Estas directrices se especifican en un archivo llamado SPEC, que usualmente se distingue por su extensión .spec.

No explicaremos aquí todos los detalles relacionados con la construcción de RPMs pero explicaremos los pasos básicos a continuación.

Instalar un Elastix con los requisitos para construir el RPM

Para llevar a cabo esta tarea lo recomendable es usar un equipo con Elastix instalado. Vamos a necesitar algunos RPMs necesarios para poder construir el RPM de Asterisk a partir del SRPM.

Requerimientos

Según el último archivo asterisk.spec los siguientes RPMs son requeridos para construir el RPM de Asterisk. Por lo tanto asegurémonos que tenemos esos paquetes instalados antes de empezar.

gcc-c++

m4

openssl-devel

newt-devel

libtermcap-devel, ncurses-devel

postgresql-devel, zlib-devel

libpri-devel >= 1.4.12

dahdi-devel >= 2.4.1.2

libtiff-devel >= 3.5.7

libogg-devel, libvorbis-devel

unixODBC-devel, libtool, sqlite-devel

alsa-lib-devel

gsm-devel

net-snmp-devel

spandsp-devel >= 0.0.6

curl-devel, wget

speex-devel >= 1.2

libxml2-devel

mISDNuser-devel, mISDN-devel

libopenr2-devel

autoconf >= 2.60

mysql-devel, zlib-devel

/usr/bin/soxmix (parte del paquete sox)

iksemel-devel

libsrtp

libgsmat

Algunos de ellos ya vienen instalados en una instalación de Elasix normal, otros habrá que instalarlos. Se pueden instalar a través del comando yum.

Instalar el SRPM de Asterisk y modificar el SPEC de acuerdo a nuestras necesidades

Luego de descargar el SRPM de Asterisk lo instalamos en la máquina concebida para este fin. Esto se hace de manera sencilla con el comando rpm.

[root@elastix ~]# rpm -ivh asterisk-1.8*.src.rpm

Esta instalación no instalará Asterisk como pudiera parecer sino que más bien instalará el código fuente de Asterisk y otros archivos necesarios para generar el RPM de Asterisk. Todos estos archivos se extraerán en el directorio /usr/src/redhat que es donde se copiará el código fuente de Asterisk, el archivo SPEC y cualquier otra información nacida del SRPM.

A continuación deberemos hacer los cambios en el archivo SPEC para personalizar nuestro Asterisk. Aquí podremos hacer casi cualquier cosa como por ejemplo:

Eliminar parches para conseguir un Asterisk mínimo

Añadir funcionalidad nueva a Asterisk

Parchar contra bugs

Actualizar la versión de Asterisk

En este libro no explicaremos el formato del archivo SPEC y cómo se encuentra este dividido. Si el lector se encuentra interesado le recomendamos el siguiente vínculo http://www.rpm.org/max-rpm/

Nota: Es muy importante que la versión del RPM que generemos siempre sea mayor que la que tenemos instalada en el sistema donde queremos instalar dicho RPM puesto que si el RPM generado posee una versión menor o igual se rehusará a instalarse.

Construir el RPM de Asterisk

Una vez realizados los cambios en el SPEC nos encontramos listos para recompilar Asterisk o, siendo exactos, construir un nuevo RPM para Asterisk. Para lograr esto nos valemos del comando rpmbuild, pasándole como parámetro la ruta del archivo SPEC que hemos modificado.

[root@elastix ~]# rpmbuild -ba /usr/src/redhat/SPECS/asterisk.spec

Al final del proceso, que puede tardar un poco, obtendremos los siguientes RPMs en la carpeta /usr/src/redhat/RPMS/

asterisk

asterisk-devel

asterisk-sounds-es

asterisk-sounds-fr

Además obtendremos un nuevo SRPM en la carpeta /usr/src/redhat/SRPMS/

30

La Certificación Elastix

Aprender sin pensar es esfuerzo perdido; pensar sin aprender, peligroso.

-- Confusio

30.1 Introducción

Con la difusión de Elastix como plataforma de comunicaciones y su uso en empresas alrededor del mundo, surgió el negocio de soporte técnico relacionado con esta distribución. Hoy en día muchas empresas o personas brindan soporte relacionado con Elastix a sus clientes y junto con esto ha crecido el interés de validar esos conocimientos técnicos de manera oficial.

Con el fin de proveer esta necesaria validación nació el Programa de Certificación Elastix, el mismo que tiene como eje central el Examen de Certificación Elastix. Este examen certifica a la persona que lo aprueba que tiene los conocimientos necesarios para implementar soluciones basadas en Elastix así como también resolver problemas técnicos relacionados con la distro.

30.2 El Curso de Certificación Elastix

El Curso de Certificación Elastix no es otra cosa que un programa de entrenamiento oficial de preparación para quien esté interesado en rendir el Examen de Certificación Elastix.

La capacitación dura 40 horas y es impartida durante 5 días, al final de los cuales el alumno debería estar apto para rendir el Examen de Certificación.

30.3 El Examen de Certificación Elastix

El Examen de Certificación Elastix es un examen objetivo, es su mayoría de alternativas múltiples, que tiene como objetivo calificar la idoneidad de un profesional Elastix.

El Examen se rinde a través de un sistema especializado y únicamente puede ser tomado en un Testing Center Elastix oficial.

La duración del examen es de 2 horas y contiene 100 preguntas.

Tópicos y Pesos

Se han dividido los tópicos en tres grandes grupos. Cada grupo tiene un peso equivalente a la tercera parte del peso total. Dentro de cada grupo se enlistan los tópicos del examen ordenados de mayor a menor peso.

Linux, VoIP y Redes: Peso de 33.33%

Introducción a la VoIP

Protocolos SIP y RTP

Introducción a la telefonía

Calidad de voz

Linux para administradores de Elastix

Configuración de Hardware

Configuración de teléfono IP

Virtualización

Asterisk: Peso de 33.33%

Fundamentos de Asterisk

Plan de marcado avanzado

Diagnóstico de problemas

AMI y AGI

Depuración

Seguridad

Desempeño

DUNDi

Compilación de Asterisk

Sintetización y reconocimiento de voz

Elastix: Peso de 33.33%

Configuración Básica de Elastix (Extensiones, colas, IVR, conferencias, FOP)

Ruteo de llamadas

funcionamiento interno de FreePBX

Interconexión con Elastix remotos

Elastix overview

Fax

Instalación de Elastix

Tarifación y Reportación en Elastix

Servidor de correo electrónico

Addon para call centers

Mensajería instantánea

Extendiendo Elastix

30.4 Preguntas típicas de examen

A continuación algunas preguntas típicas de examen.

¿Para qué se utiliza el cable MOLEX de suministro de poder en algunas tarjetas analógicas?

a) No es necesario conectar las tarjetas a un cable de poder adicional. La tarjeta ya se alimenta de poder a través del bus PCI.

b) Para suministrar energía eléctrica adicional a los módulos FXS

c) Para suministrar energía eléctrica adicional a los módulos FXO

d) Esto sólo es necesario en antiguas tarjetas ISA

e) Ninguna de las anteriores

¿En qué carpeta se almacenan los voicemails?

a) /usr/lib/asterisk/voicemail

b) /var/lib/asterisk/voicemails

c) /var/spool/asterisk/voicemail

d) En ninguna carpeta, los voicemails se almacenan en una base de datos interna de Asterisk para facilitar su acceso

e) Ninguna de las anteriores

¿Cuál es el rango de la escala MOS?

a) 1-5

b) 1-10

c) 0-100%

d) Empieza en el 0 pero no tiene tope

e) Ninguna de las anteriores

¿A través de que comando inicializamos el marcador predictivo?

a) service elastix start

b) service dialer start

c) service dialerelastix start

d) service elastixdialer start

e) Ninguna de las anteriores

¿En qué se diferencian el módulo -PBX -> Conferencias- que provee directamente Elastix del módulo -PBX -> PBX Configuration -> Conferences- provisto a través de freePBX?

a) No existen dos módulos para administrar conferencias, sólo uno

b) Existen dos módulos pero en realidad son la misma cosa, ya que el módulo provisto por Elastix es solo un wrapper del módulo de FreePBX

c) El módulo de FreePBX administra cuartos de conferencia permanentes mientras que el provisto por Elastix administra cuartos temporales

d) Los dos hacen prácticamente lo mismo pero son dos implementaciones diferentes

e) Ninguna de las anteriores

¿Cuáles contextos se encuentran reservados en el plan de marcado de Asterisk? Puede seleccionar más de uno.

a) globals

b) general

c) default

d) reserved

e) Todos los anteriores

¿Cuál de las siguientes NO es una estrategia de colas válida? Puede elegir más de una respuesta.

a) ringall

b) roundrobin

c) leastrecent

d) random

e) leastactive

¿Cuál es la extensión de los archivos de temas que se encuentran dentro de la carpeta -themes- y que sirven para dar el aspecto o look a la interfaz Web de Elastix?

a) .ini

b) .tpl

c) .htm

d) .conf

e) Ninguna de las anteriores

EDGAR LANDÍVAR. Edgar Landívar ha venido trabajando en el desarrollo y la promoción de soluciones de Código Abierto durante más de 10 años.

Junto a PaloSanto Solutions ha sido uno de los pioneros de implementaciones basadas en Linux en el Ecuador.

Actualmente dirige el proyecto de telefonía IP y Comunicaciones Unificadas “Elastix”, con un impacto de más de un millón de descargas a nivel mundial.