600
Libro Asterisk 1.8.X v. 1.0 Abril 2012 By VozToVoice www.voztovoice.org

Libro Asterisk 1.8.X - Versión 1.0 (1)

Embed Size (px)

Citation preview

Page 1: Libro Asterisk 1.8.X - Versión 1.0 (1)

Libro Asterisk 1.8.X v. 1.0Abril 2012

By VozToVoicewww.voztovoice.org

Page 2: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 3: Libro Asterisk 1.8.X - Versión 1.0 (1)

Convenciones tipográficas.

Negrita = comandos que el usuario tiene que teclear en la consola de Linux

NegritaCursiva: Lineas que hay que añadir/modificar en los archivos de configuración

Nombreprograma = Indica el nombre de un programa o librería

Cursiva: respuesta del servidor Linux a los comandos

CLI> indica que estamos trabajando en la consola de Asterisk

mysql> indica que estamos trabajando en el cliente MySQL

Si encuentran alguna incorrección o errata pueden escribir al autor:

[email protected]

i

Page 4: Libro Asterisk 1.8.X - Versión 1.0 (1)

Este documento se publica bajo la GNU Free Documentation License, versión 1.3 o sucesivas, publicadas por la Free Software Foundation. Está permitido copiar, distribuir y/o modificar este documento bajo los términos indicados en la licencia. Una copia integral de la licencia es presente en la apéndice H de este libro.

Copyright (C) 2012-2016 Andrea Sannucci Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

ii

Page 5: Libro Asterisk 1.8.X - Versión 1.0 (1)

INDICE

Capitulo I - Instalación de Asterisk ….......................................................................................... 1

1.1 Preparación del VPS Linode 11.2 GRUB, Kernel-XEN y clave RSA 71.3 Utilidades, librerías, dependencias 161.4 Libpri 191.5 DAHDI 191.6 App_fax, GoogleTalk, LibiCAL y SRTP 211.7 Instalación de Asterisk 27

Capitulo II - Configuración inicial de Asterisk ......................................................................... 36

2.1 Instalar y configurar un cortafuego 362.2 Carpetas y archivos 392.3 asterisk.conf 412.4 modules.conf 432.5 Música en espera y MP3 452.6 Preparación del dialplan – extensions.conf 48

Capitulo III – Protocolo SIP y archivo sip.conf.......................................................................... 54

3.1 sip.conf 563.2 Directmedia 693.3 Contraseñas seguras 703.4 Ngrep 713.5 SoftPhone X-Lite y REGISTER 723.6 Softphone 3CX 773.7 Llamadas entre extensiones 793.8 SIP INVITE y CANCEL 80

Capitulo IV – Protocolo IAX2 – iax.conf ................................................................................. 84

4.1 iax.conf 844.2 Softphone Zoiper 89

Capitulo V - GoogleTalk – gtalk.conf jabber.conf................................................................... 95

5.1 jabber.conf y gtalk.conf 955.2 Google Voice 101

iii

Page 6: Libro Asterisk 1.8.X - Versión 1.0 (1)

5.3 Aplicación JabberSend 1025.4 La función JABBER_RECEIVE 104

Capitulo VI - Asterisk y la red PSTN........................................................................................ 107

6.1 Tarjeta Digium TDM410 108 6.1.1 OSLEC 112

6.2 Tarjeta Digium TE120P 1166.2.1 MFG/R2 – Openr2 117

6.4 Wanpipe 1226.5 Linksys SPA3102 – Gateway FXO/FXS 124

Capitulo VII - Dialplan – Configuración avanzada.................................................................. 134

7.1 Las Variables 134 7.2 Pattern Matching 1377.3 La aplicación Echo 1387.4 El contexto Subscribe 1397.5 Las Macro 1437.6 Autenticar las Llamadas Salientes con la aplicación Authenticate 1467.7 Limitar llamadas salientes: funciones GROUP y GROUP_COUNT 149

Capitulo VIII - IVR …................................................................................................................. 156

8.1 Grabación de las locuciones 1568.2 Configuración numero geográfico 1578.3 Creación del IVR 158

Capitulo IX - Funcionalidades avanzadas de Asterisk – features.conf ................................... 164

9.1 features.conf 1649.2 Callgroup y Pickupgroup 1729.3 Aplicación Dial y features.conf 174

Capitulo X - Asterisk y los calendarios ….................................................................................. 180

10.1 calendar.conf 18110.2 CALENDAR_BUSY 19010.3 CALENDAR_EVENT 19210.4 CALENDAR_QUERY y CALENDAR_QUERY_RESULT 19410.5 CALENDAR_WRITE 19710.6 Enviar las notificaciones de los calendarios a números fijos/celulares 201

iv

Page 7: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XI - CCSS (Call Completion Supplementary System) – Rellamada …................... 206

11.1 Configuración del CCSS 20611.2 CCSS 1ª Prueba 20811.3 CCSS 2ª Prueba 20911.4 CCSS 3ª Prueba 210

Capitulo XII – Asterisk Realtime............................................................................................... 213

12.1 Realtime estático 21312.2 Realtime dinámico 220

12.2.1 Extensiones SIP en Realtime 22012.2.2 Extensiones IAX en Realtime 22812.2.3 Dialplan en Realtime dinámico 233

Capitulo XIII – IVR avanzados – func_odbc.conf ........... ....................................................... 237

13.1 Empleados 23713.2 Encuesta 242

Capitulo XIV - Buzón de voz – voicemail.conf........................................................................ 246

14.1 voicemail.conf 24614.2 Mensajes de voz en una base de datos 25814.3 Buzones de voz en una base de datos 261

Capitulo XV - Las conferencias audio ................................................................................... 265

15.1 meetme.conf 26515.2 Aplicación ConfBridge 26915.3 Meetme en Realtime Dinámico 27115.4 Aplicación Page 274

Capitulo XVI - Distribución automática de llamadas – Colas de espera …........................... 278

16.1 Los agentes 27816.2 Las colas de espera – queue.conf 28116.3 Agentes dinámicos 29116.4 Estadísticas de las colas 29416.5 Colas, agentes y estadísticas en Realtime dinámico 297

v

Page 8: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XVII - Asterisk y los FAX …........................................................................................ 309

17.1 IAXmodem 30917.2 Hylafax 31317.3 Protocolo T38 328

17.3.1 Aplicación ReceiveFax 33217.3.2 Applicación SendFax 334

Capitulo XVIII - Conexiones entre servidores Asterisk …....................................................... 339

18.1 Conectar dos servidores Asterisk con el protocolo SIP 33918.2 Conectar dos servidores Asterisk con el protocolo IAX2 34318.3 El protocolo DUNDi 34518.4 Conectar dos servidores Asterisk con OpenVPN 35618.5 Conectar dos Servidores Asterisk con TLS y SRTP 374

Capitulo XIX – AMI y AGI …............................................................................................ 382

19.1 AMI (Asterisk Manager Interface) 38219.2 AGI (Asterisk Gateway Interface) 39119.3 Las variantes AGI 397

19.3.1 EAGI 39719.3.2 FastAGI 39819.3.3 Async AGI 400

Capitulo XX - Los registros en Asterisk …................................................................................. 405

20.1 CDR (Call Detail Record) 40520.1.1 cdr.conf 40720.1.2 cdr_manager.conf 40920.1.3 CDR adaptive 411

20.2 CEL (Channel Event Logging) 41620.3 Logger.conf 423

20.3.1 Debug 426

Capitulo XXI - Seguridad en Asterisk …................................................................................... 429

21.1 Reglas de oro 42921.2 Fail2ban 429

Capitulo XXII - Monitorear Asterisk ….....................................................................................434

vi

Page 9: Libro Asterisk 1.8.X - Versión 1.0 (1)

22.1 Monit 43422.2 SNMP 43922.3 Nagios 442

22.3.1 NDOutils 45322.4 Monitoreo calidad llamadas 455

22.4.1 Monitoreo calidad llamadas desde la consola de Asterisk 45522.4.2 Monitoreo calidad llamadas con VoIPMonitor 456

Capitulo XXIII - Conectar un Softphone (Blink) de forma segura: SIP TLS y SRTP …...... 462

23.1 Creación de los certificados 46223.2 Configuración Softphone Blink 466

Capitulo XXIV - Openfire y Asterisk …..................................................................................... 471

24.1 Instalación de Openfire 47124.2 Instalar el Plugin SIPPhone en Openfire 47924.3 El Plugin Asterisk-IM 48324.4 Asterisk como cliente en Openfire 48724.5 Conectar dos servidores Openfire 49024.6 Openfire Connection Manager 494

Capitulo XXV - Asterisk y alta disponibilidad ......................................................................... 499

25.1 Replicación MySQL Master-Slave 49925.2 Replicación MySQL Master-Master 50525.3 DRBD - Raid1 vía TCP 51525.4 Heartbeat 522

Capitulo XXVI - Asterisk GUI …............................................................................................. 529

Capitulo XXVII – FreePBX …................................................................................................... 535

Apéndice A – Instalar CentOS 5.8 en una maquina virtual con VirtualBox 542

Apéndice B – Archivos de configuración 564

Apéndice C – Licencia GNU FDL 582

vii

Page 10: Libro Asterisk 1.8.X - Versión 1.0 (1)

Introducción

Después de unos cuantos meses de trabajo, toma vida la primera versión del libro dedicado a la versión 1.8.X de Asterisk PBX. Como siempre pasa con los manuales, muchos dirán que no se abordaron algunos temas importantes, otros que la parte descriptiva es muy sucinta. La verdad, todos tienen razón. Iba a añadir una cuantos párrafos más pero pensé que podía dejarlo para “mañana”. Lo que si les puedo decir es que en la próxima versión estarán presentes estos termas:

• Aplicación Chan_spy• Aplicación GotoIfTime (para enrutar las llamadas entrantes según la fecha y la hora)• El funcionamiento de la negociación de los codec audio a lo largo de una llamada

Siempre he sido una persona muy parca con las palabras y la escritura. No me gusta alargarme demasiado cuando escribo y no me gusta que las palabras sobren. Puede ser que en algunas partes del libro me he pasado un poco aplicando esta regla, pero para eso están las primera versiones de un manual. De ellas se aprende para mejorarlas.

La que me gusta de este manual es que parte desde la instalación del sistema operativo (Linux CentOS 5.8) y acompaña quien lo lee hacia la instalación y configuración de Asterisk hasta armar una centralita completamente lista para las funciones básicas e intermedias. Todo esto probando cada nueva configuración como si se estuviera trabajando en un laboratorio de prueba.

Quiero darles las gracias a los viejos y nuevos participantes a mis cursos a distancia que son los que me animaron y me animan a escribir y mejorar este libro. Es gracias a ellos que he ido aprendiendo cada día más y que me inspiran con sus preguntas a la hora de escribir.

viii

Page 11: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 12: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo I

Instalación de Asterisk

Asterisk es el programa Open Source más reconocido para implementar una PBX. Para una lista completa de las funcionalidades brindadas, visiten la página de los desarrolladores. Entre ellas:

• Registro (Log) de llamadas• Grabación de llamadas• Desvío de llamadas• Trasferencia de llamadas• Conferencias audio• Música en espera• Gestión de colas (call center)• Soporte para tarjetas y Gateway FXO, FXS, digitales y celulares• IVR• Buzón de voz

Este libro abarca la instalación de Asterisk en un VPS (Servidor Virtual Privado) remoto y es valida para cualquier Servidor Linux CentOS. Con el VPS remoto la ventaja es tener una PBX siempre activa, independiente de la banda ancha disponible en la casa/oficina y evita tener una computadora dedicada y siempre encendida. En este caso, considerando la relación calidad/precio, se ha optado por los VPS de la empresa Linode. Para aquellos que quieran trabajar con un servidor local, en la apéndice A es presente una guía para la instalación de CentOS en VirtualBox.

1.1 Preparación del VPS

Una vez adquirido el servidor Linode, desde la pagina de administración, se selecciona el enlace que aparece en la imagen que sigue:

Se escoge el centro de datos donde se quiere tener el servidor virtual remoto (en este caso Dallas):

Page 13: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la nueva ventana que aparecerá se configurarán algunos parámetros (distribución Linux, Memoria disco, swap y contraseña del usuario root. Se deja una parte del espacio del disco duro para crear dos particiones que se utilizarán para la configuración de alta disponibilidad.

Terminada la configuración se presiona el botón “Rebuild”. Empezará el proceso de instalación y configuración del sistema operativo. En la sección “Disk Images”, se crean dos nuevas particiones seleccionando el enlace “Create a new disk image”:

2

Page 14: Libro Asterisk 1.8.X - Versión 1.0 (1)

La primera:

La segunda:

Para añadir las dos particiones al perfil del VPS se selecciona el enlace que aparece en la siguiente imagen:

3

Page 15: Libro Asterisk 1.8.X - Versión 1.0 (1)

y en la sección “Block device Assignment”, se añaden las dos particiones como mostrado en la imagen:

Se va al final de la pagina y se presiona el botón “Save Changes”.Ya se puede iniciar el servidor presionando el botón “Boot”.

Como se puede ver en la imagen, el Kernel que se instala es la versión “Latest 3.0 (3.0.18-linode43). De esta versión no hay las fuentes disponibles y eso imposibilita la instalación de DAHDI. Por eso en el próximo párrafo se verá como instalar en el servidor la ultima versión disponible del Kernel-XEN.

Una vez que el servidor esté corriendo, como indicado en la imagen que sigue, que aparece en el lado derecho de la pagina de administración de Linode, se puede acceder al servidor con el programa PuTTy (un cliente SSH):

4

Page 16: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para conocer la dirección IP del servidor Linode, se entra en la siguiente pagina, donde aparecen todos los datos de configuración de la red:

Se descarga el programa PuTTy para Windows desde esta pagina:

http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe

Una vez descargado se ejecuta. Aparecerá la siguiente ventana:

5

Page 17: Libro Asterisk 1.8.X - Versión 1.0 (1)

En “Host Name (or IP address) se pone la dirección IP del servidor Linode, en “Port” 22 y en “Saved Sessions” un nombre que identifique la conexión al VPS. Terminada la configuración se presiona el botón “Save” y luego el botón “Open” que aparece más abajo. Se abrirá una nueva ventana donde en “login as” hay que poner root y en “password” la contraseña que se ha escogido al momento de la instalación del sistema operativo.

Si se está utilizando Linux se abre una ventana terminal y para conectarse al servidor remoto se ejecuta el siguiente comando:

ssh root@IPlinode

en lugar de IPlinode se pone la dirección IP publica del servidor remoto.

El resultado será:

La primera cosa que hay que hacer es actualizar el sistema:

yum -y update

y luego reiniciarlo:

reboot

Se esperan un par de minutos y se vuelve a entrar con el cliente PuTTy.

6

Page 18: Libro Asterisk 1.8.X - Versión 1.0 (1)

1.2 GRUB, Kernel-XEN y clave RSA

En este párrafo se verá como instalar el sistema de arranque GRUB con la ultima versión disponible del Kernel-XEN y como volver más seguro el acceso al servidor remoto a través de la creación y configuración de SSH utilizando una clave RSA. Primero se descarga y se ejecuta el script que sigue que se ocupará de la configuración de GRUB y de la instalación de Selinux:

cd /usr/src

wget http://www.voztovoice.org/tmp/selinux-grub

Como la versión del Kernel-XEN puede cambiar, antes de ejecutar el script, se averigua cual es la ultima versión disponible del kernel-xen

yum info kernel-xen

y se compara con la que aparece en estas lineas del archivo selinux-grub:

title CentOS (2.6.18-274.12.1.el5xen)kernel /boot/vmlinuz-2.6.18-274.12.1.el5xen root=/dev/xvdainitrd /boot/initrd-2.6.18-274.12.1.el5xen.img

Si las versiones son diferentes se modifican las lineas indicando la versión corriente. Si son iguales, se cierra el archivo y se vuelve ejecutable:

chmod +x selinux-grub

y se inicia:

./selinux-grub

Se puede averiguar que efectivamente se ha instalado el sistema de arranque GRUB con este comando:

7

Page 19: Libro Asterisk 1.8.X - Versión 1.0 (1)

ls /boot/grub/

Como el script instala dos servicios relacionados con el protocolo iSCSI que no se necesitan, se desabilitan:

chkconfig iscsi off

chkconfig iscsid off

El paso a seguir es modificar la configuración del servidor Linode. Desde la pagina de administración se selecciona el enlace que aparece en la imagen:

En la nueva pagina se modifican los parámetros como indicado en las dos siguientes imágenes:

En Botton Settings – Kernel escogemos “pv-grub-x86_32

8

Page 20: Libro Asterisk 1.8.X - Versión 1.0 (1)

Casi al final de la pagina se modifican los dos parámetros indicados cambiado la opción de Yes a No. Para terminar se guardan los cambios presionando el botón “Save Changes”. Se regresará a la pagina principal del servidor Linode y de ahí se reinicia:

Para averiguar que efectivamente el sistema se reinicia utilizando el Kernel-XEN y el gestor de arranque GRUB, en la pagina de Linode se entra en el menú “Remote access” y luego se sigue el enlace “Launch Lish Ajax Console” che permite acceder al servidor desde una consola local. Se abrirá una nueva ventana y después de unos segundos aparecerá esta imagen:

Para crear la clave RSA se descarga el programa PuTTygen:

http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe

Se ejecuta:

9

Page 21: Libro Asterisk 1.8.X - Versión 1.0 (1)

En “Number of bits in a generated key” se pone 2048 (se crea una clave de 2048 Byte) y luego se presiona el botón “Generate”. Para la creación de la clave se necesita generar una serie aleatoria de números y se hace moviendo el ratón en el cuadro que aparece bajo la linea “Key”:

Hay que seguir moviendolo hasta que la barra que aparece no llegue al final de la linea. Terminada la

10

Page 22: Libro Asterisk 1.8.X - Versión 1.0 (1)

operación se tendrá disponible la clave RSA (publica y privada):

Se guarda la clave privada en una carpeta del ordenador local presionando el botón “Save private key”(en este caso se nombra claveprivada):

Para continuar se selecciona todo el texto que aparece en la imagen que sigue, se presiona el botón derecho del ratón y se escoge en el menú “copiar”:

11

Page 23: Libro Asterisk 1.8.X - Versión 1.0 (1)

El texto copiado es la clave publica. Se accede nuevamente con PuTTy al servidor remoto y se sigue este procedimiento para utilizar la clave publica; se crea la carpeta ssh:

mkdir .ssh

se permite el acceso a la carpeta creada solamente al usuario root:

chmod 700 .ssh

se entra en la carpeta:

cd .ssh

se crea el archivo authorized_keys que es donde el sistema operativo buscará las claves RSA publicas del sistema (en este caso para el usuario root):

nano authorized_keys

se pega el contenido copiado desde PuTTygen que debe quedar todo en la misma linea:

12

Page 24: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guarda el archivo hundiendo las teclas CTRL-X. Se asigna al archivo recién creado los permisos de lectura y escritura solamente al usuario root:

chmod 600 /root/.ssh/authorized_keys

Terminada esta operación se modifican algunos parámetros del servidor SSH para permitir el acceso al VPS solamente al usuario root si se autentica con la clave RSA; además, para aumentar la seguridad, se cambia el puerto predefinido para el acceso SSH (22 TCP), escogiendo otro (15000 TCP). Esto se hace modificando el archivo de configuración del servidor SSH:

nano /etc/ssh/sshd_config

Se buscan estas lineas (para buscar un texto con el editor nano hay que hundir la tecla CTRL junto a la tecla W):

#Port 22#RSAAuthentication yesPasswordAuthentication yes

y se modifican para que queden:

Port 15000RSAAuthentication yesPasswordAuthentication no

De esta forma se cambia el puerto predefinido para acceder al servidor remoto (de 22 a 15000), se activa el acceso con claves RSA y se desactiva la autentificación con nombre de usuario y contraseña. Se guardan los cambios y se reinicia el servidor SSH:

/etc/init.d/sshd restart

Se abre otra instancia del cliente SSH:

13

Page 25: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pone la IP del servidor Linode, come puerto el 15000 y se asigna un nuevo nombre a esta nueva conexión.

En la barra de la izquierda se busca el menú “SSH”, luego “Auth” y se presiona el botón “Browse”. Se busca la clave privada en la carpeta donde se ha guardado anteriormente y se selecciona. Se vuelve al menú Session (en la izquierda) y se guarda esta nueva configuración hundiendo el botón “Save”. Ahora hay dos sesiones disponibles en el cliente SSH: Linode y Linode2. Para acceder al servidor Linux se escoge la sesión Linode2, botón “Load” y luego botón “Open”. Debe aparecer esta ventana:

14

Page 26: Libro Asterisk 1.8.X - Versión 1.0 (1)

Una vez que se haya escrito el nombre de usuario root en “login as:”, automáticamente el cliente se conectará al servidor autenticándose con la clave RSA creada.

Para terminar la configuración del VPS, se modifica la hora predefinida del servidor y, si se quieres, el idioma del sistema operativo:

rm /etc/localtimerm: remove regular file `/etc/localtime'? Y

En el caso de Colombia, se crea un enlace simbólico a la hora de Bogotá:

ln -s /usr/share/zoneinfo/America/Bogota /etc/localtime

se averigua que la hora sea exacta con el comando:

date

Para que la hora se actualice de manera automática se instala el servidor NTP (Network Time Protocol):

yum install ntp

Se configura para que se inicie automáticamente al arrancar el servidor Linux:

chkconfig ntpd on

y se inicia:

service ntpd startStarting ntpd:

Para modificar el idioma predefinido (ingles) y ponerlo en español (de Colombia):

nano /etc/sysconfig/i18n

se modifica esta linea:

LANG="en_US.UTF-8"

para que quede:

15

Page 27: Libro Asterisk 1.8.X - Versión 1.0 (1)

LANG="es_CO.iso88591"

Para activar el nuevo idioma basta salir y volver a entrar al servidor con PuTTy.

1.3 Utilidades, librerías, dependencias

Antes de la compilación de Asterisk, se instalarán una serie de librerías y dependencias que permitirán obtener la instalación de casi todos los módulos de la PBX. Se empieza con Vorbis que es una librería para la compresión/descompresión audio:

yum install libvorbis libvorbis-devel vorbis-tools libogg libogg-devel

se sigue con CURL que es un cliente que permite recibir o enviar archivos utilizando los protocolos HTTP, HTTPS, FTP, GOPHER, DICT, TELNET:

yum install curl curl-devel libidn-devel

se instalan todas las librerías y dependencias que se necesitan para compilar las fuentes:

yum install gcc ncurses-devel make gcc-c++ libtermcap-devel zlib-devel libtool bison bison-devel

yum install openssl-devel bzip2-devel wget newt-devel subversion flex gtk2-devel

a seguir para crear y gestionar las bases de datos, MySQL:

yum install mysql mysql-server mysql-devel

UNIXODBC que es la implementación Linux de los API ODBC que permiten conectarse a muchos sistemas de gestión de base de datos (ej: MySQL):

yum install unixODBC unixODBC-devel mysql-connector-odbc libtool-ltdl-devel

Se instala FESTIVAL, que es un sistema de text to speech (disponible en español):

yum install festival festival-devel

Una vez terminada esta parte se empieza a instalar una serie de programas desde las fuentes; el primero es SPEEX que es un programa para la compresión audio específicamente diseñado para la voz.

IMPORTANTE: Para todos los programas que se instalan desde las fuentes, antes de descargarlos, averiguar si hay una versión más reciente disponible.

cd /usr/src

wget http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz

16

Page 28: Libro Asterisk 1.8.X - Versión 1.0 (1)

tar -xf speex-1.2rc1.tar.gz

cd speex-1.2rc1

./configure --prefix=/usrmakemake install

Se continua con LAME que es utiliza para codificar archivos audio en formato MP3:

cd /usr/src

wget http://ufpr.dl.sourceforge.net/sourceforge/lame/lame-3.99.5.tar.gz

tar -xf lame-3.99.5.tar.gz

cd lame-3.99.5

./configure --prefix=/usrmakemake install

LIBMAD que es un MPEG audio decodificador de alta calidad:

cd /usr/src

wget http://prdownloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz

tar -xf libmad-0.15.1b.tar.gz

cd libmad-0.15.1b

./configure --prefix=/usrmakemake install

WAVPACK es un compresor audio de alto rendimiento sin perdida de calidad:

cd /usr/src

wget http://www.wavpack.com/wavpack-4.60.1.tar.bz2

tar -xf wavpack-4.60.1.tar.bz2

cd wavpack-4.60.1

17

Page 29: Libro Asterisk 1.8.X - Versión 1.0 (1)

./configure --prefix=/usrmakemake install

Se termina con SOX que es un programa que permite la manipulación de archivos audio y la posibilidad de pasarlos de un formato a otro:

cd /usr/src

wget http://downloads.sourceforge.net/project/sox/sox/14.4.0/sox-14.4.0.tar.gz

tar -xf sox-14.4.0.tar.gz

cd sox-14.4.0

./configure -prefix=/usr

Al finalizar el configure aparecerá esta tabla donde se encontrarán todos los formatos audio que se podrán manipular con SOX:

Se termina con la compilación e instalación:

makemake install

18

Page 30: Libro Asterisk 1.8.X - Versión 1.0 (1)

1.4 LIBPRI

En el caso que se quiera instalar tarjetas digitales en el servidor Asterisk (E1, T1, ISDN), antes de instalar DAHDI, hay que instalar la librería libpri

cd /usr/src

wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-1.4.12.tar.gz

se descomprime:

tar -xf libpri-1.4.12.tar.gz

se entra en la carpeta:

cd libpri-1.4.12

se compila y se instala:

makemake install

1.5 DAHDI

El paquete DADHI (Digium Asterisk Hardware Device Interface) permite cargar los drivers y configurar distintos tipos de tarjetas en Asterisk (analógicas, digitales, RDSI/ISDN, cancelador de ECHO). Asterisk además se apoya en DAHDI para las conferencias audio (modulo app_meetme) y el trunking IAX2 (tema tratado en la configuración del archivo iax.conf). Se instala el paquete de desarrollo del Kernel-Xen:

yum install kernel-xen-devel

IMPORTANTE: La única diferencia con un sistema CentOS local o un servidor dedicado es que se instala el paquete estándar del Kernel: yum install kernel-devel

Se continua con la ultima versión disponible de DAHDI-Linux:

cd /usr/src

wget http://downloads.asterisk.org/pub/telephony/dahdi-linux/dahdi-linux-current.tar.gz

tar -xf dahdi-linux-current.tar.gz

cd dahdi-linux-2.6.0

19

Page 31: Libro Asterisk 1.8.X - Versión 1.0 (1)

makemake install

Se termina con la ultima versión disponible de DAHDI-Tools:

cd /usr/src

wget http://downloads.asterisk.org/pub/telephony/dahdi-tools/dahdi-tools-current.tar.gz

tar -xf dahdi-tools-current.tar.gz

cd dahdi-tools-2.6.0

./configure

make menuselect

en la ventana que aparece se seleccionan todos los módulos disponibles como indicado en la imagen que sigue:

Se guarda la configuración presionando la tecla tabulador hasta posicionarse sobre “Save & Exit”. Se termina con la compilación e instalación:

makemake installmake config

Ya se puede iniciar DAHDI:

/etc/init.d/dahdi startLoading DAHDI hardware modules: wct4xxp: [ OK ] wcte12xp: [ OK ]

20

Page 32: Libro Asterisk 1.8.X - Versión 1.0 (1)

wct1xxp: [ OK ] wcte11xp: [ OK ] wctdm24xxp: [ OK ] wcfxo: [ OK ] wctdm: [ OK ] wcb4xxp: [ OK ] wctc4xxp: [ OK ] xpp_usb: [ OK ]

No hardware timing source found in /proc/dahdi, loading dahdi_dummyRunning dahdi_cfg: [ OK ]

1.6 App_fax, GoogleTalk, LibiCAL y SRTP

En este párrafo se verá como instalar SpanDSP, un procesador de señales digitales que en Asterisk permite la instalación del modulo res_fax para la recepción y envío de FAX, y IKSEMEL que permite implementar el protocolo XMPP en Asterisk y de esta forma conectarse a GoogleTalk y/o a cualquier servidor de tipo XMPP (otro ejemplo es Openfire):

Para SpanDSP se necesita instalar primero las librerías libtiff y libxml2:

yum install libtiff libtiff-devel libxml2 libxml2-devel

se continua con SpanDSP:

cd /usr/src

wget http://www.soft-switch.org/downloads/spandsp/spandsp-0.0.6pre20.tgz

tar -xf spandsp-0.0.6pre20.tgz

cd spandsp-0.0.6

./configure --prefix=/usrmakemake install

El protocolo XMPP permite conexione seguras entre cliente y servidor utilizando el protocolo TLS; para ese efecto se instala, antes de IKSEMEL, las relativas librerías:

yum install gnutls gnutls-devel gnutls-utils

se continua con IKSEMEL:

cd /usr/src

21

Page 33: Libro Asterisk 1.8.X - Versión 1.0 (1)

wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz

tar -xf iksemel-1.4.tar.gz

cd iksemel-1.4

./configure --prefix=/usrmake

antes de la instalación se ejecuta un test para averiguar que la compilación haya tenido éxito:

make checkPASS: tst-ikstackPASS: tst-iksPASS: tst-saxPASS: tst-domPASS: tst-shaPASS: tst-md5PASS: tst-filterPASS: tst-jid==================All 8 tests passed==================

Ya que todo está bien, se puede instalar:

make install

Antes de la instalación de Asterisk, se termina la preparación del sistema con unos programas más. Primero un servidor de correo electrónico, SENDMAIL:

yum install sendmail sendmail-devel sendmail-cf

Se configura para que arranque en automático:

chkconfig sendmail on

Al alquilar el servidor Linode, cada usuario tiene asignado un sub-dominio que se puede utilizar para la configuración del sistema. Este dato aparece en la pagina de administración de Linode, bajo el menú “Remote Access”

22

Page 34: Libro Asterisk 1.8.X - Versión 1.0 (1)

En este caso el sub-dominio asignado es li371-235.members.linode.com. Ese nombre se pone en la configuración de red del servidor de la siguiente forma:

nano /etc/sysconfig/network

al final del archivo se añade la siguiente linea:

HOSTNAME=li371-235.members.linode.com

Se guardan los cambios y se reinicia el servicio de red:

service network restart

El sub-dominio se utilizará también para el envío de los correos electrónicos. Por defecto el servidor de correo electrónico escucha solamente en la puerto TCP 25 local. Para que sea alcanzable también desde remoto hay que abrir el archivo de configuración de Sendmail:

nano /etc/mail/sendmail.mc

buscar esta linea:

DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

y modificarla como sigue:

DAEMON_OPTIONS(`Port=smtp,, Name=MTA')dnl

se guardan los cambios y se vuelve a compilar la configuración de Sendmail:

make -C /etc/mail

23

Page 35: Libro Asterisk 1.8.X - Versión 1.0 (1)

se reinicia el servidor de correo:

/etc/init.d/sendmail restart

para hacer la prueba de conexión al servidor de correo electrónico desde remoto, se abre una ventana terminal en Windows y se escribe:

C:\> telnet -a IPLinode 25

En lugar de IPLinode se pone la IP del servidor Linode. El resultado:

OpenLDAP es la versión open source del protocolo Lightweight Directory Access. Normalmente se utiliza para crear un directorio de usuarios que puede ser consultado y/o modificado desde remoto. Muchos programas implementan la posibilidad de conectarse a un servidor OpenLDAP y Asterisk, desde la versión 1.6.X, presenta esta posibilidad:

yum install compat-openldap openldap openldap-clients openldap-devel openldap-servers

SNMP es el Protocolo Simple de Administración de Red y sirve para controlar y monitorear el desempeño del servidor Linux. En Asterisk permite monitorear, entre otras cosas, los canales y las llamadas. Se utilizará junto a NAGIOS para controlar el servidor Asterisk y enviar avisos cuando se verifique algún tipo de problema:

yum install net-snmp net-snmp-devel net-snmp-libs net-snmp-utils

En Asterisk existe la posibilidad de guardar los registros de las llamadas en un servidor RADIUS a través de un cliente RADIUS que hay que instalar. En este caso se instala desde las fuentes:

cd /usr/src

wget http://download.berlios.de/radiusclient-ng/radiusclient-ng-0.5.6.tar.gz

tar -xf radiusclient-ng-0.5.6.tar.gz

cd radiusclient-ng-0.5.6

./configure --prefix=/usrmakemake install

24

Page 36: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se continua la preparación del servidor con la instalación del lenguaje de programación LUA que permite escribir el dialplan (o plan de marcado) utilizando este lenguaje. Al terminar la instalación de Asterisk se encontrará un archivo de ejemplo en la carpeta /etc/asterisk. En este caso se instala desde las fuentes. Primero unas dependencias:

yum install readline-devel

luego el programa:

cd /usr/src

wget http://www.lua.org/ftp/lua-5.2.0.tar.gz

tar -xf lua-5.2.0.tar.gz

cd lua-5.2.0

Se modifica el archivo Makefile para que el programa se instale por defecto en la carpeta /usr:

nano Makefile

se modifica esta linea:

INSTALL_TOP= /usr/local

para que quede:

INSTALL_TOP= /usr

Se guardan los cambios, se compila e instala:

make linux make install

Para terminar se compilan los paquetes que permiten utilizar las nuevas funcionalidades de Asterisk 1.8.X. Primero LIBICAL que permite la implementación del protocolo iCalendar (RFC5546) en Asterisk a través del modulo res_calendar:

cd /usr/src

wget http://downloads.sourceforge.net/project/freeassociation/libical/libical-0.48/libical-0.48.tar.gz

tar -xf libical-0.48.tar.gz

cd libical-0.48

./configure --prefix=/usr

25

Page 37: Libro Asterisk 1.8.X - Versión 1.0 (1)

makemake install

Luego NEON que es una librería que permite la implementación del protocolo WebDAV en Asterisk:

cd /usr/src

wget http://webdav.org/neon/neon-0.29.6.tar.gz

tar -xf neon-0.29.6.tar.gz

cd neon-0.29.6

./configure --prefix=/usrmakemake install

Por ultimo la librería LIBSRTP que permite implementar en Asterisk el cifrado del flujo media a través del protocolo SRTP (RFC3711):

cd /usr/src

wget http://downloads.sourceforge.net/project/srtp/srtp/1.4.4/srtp-1.4.4.tgz

tar -xf srtp-1.4.4.tgz

cd srtp

./configure --prefix=/usr CFLAGS=-fPIC make

Antes de lanzar el make runtest, para que tenga éxito, hay que modificar una linea en el archivo que ejecuta el test:

nano test/rtpw_test.sh

cambiar esta linea:

RTPW=rtpw

para que quede:

RTPW=./rtpw

Se continua con el test:

make runtest

26

Page 38: Libro Asterisk 1.8.X - Versión 1.0 (1)

make install

1.7 Instalación de Asterisk

Terminada la preparación del servidor, se inicia con la instalación de Asterisk. Se descarga la ultima versión 1.8.X disponible:

cd /usr/src

wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-1.8.11.0.tar.gz

tar -xf asterisk-1.8.11.0.tar.gz

cd asterisk-1.8.11.0

./configuremake menuselect

Desde la versión 1.8.X lo que antes era un paquete a parte (asterisk-addons) ahora es presente en el paquete principal de Asterisk. Como se puede notar, los módulos relacionados con MySQL (menos res_mysql) son “deprecated” y en las versiones futuras de Asterisk serán eliminados. Se entra en el menú “Add-ons” y se activan los paquetes que siguen:

En Asterisk 1.8.X está presente un nuevo menú “Channel Event Logging” que como se verá más adelante, permite complementar el CDR (call detail record) con nuevas informaciones relacionadas con las llamadas:

27

Page 39: Libro Asterisk 1.8.X - Versión 1.0 (1)

En “Resource modules” se controla que los módulos relacionados con las funciones calendario y cifrado del flujo media estén activados:

Se seleccionan todos los módulos en el menú “Utilities” y “AGI Samples”:

En “Core Sound Packages” se seleccionan todos los paquetes disponibles:

28

Page 40: Libro Asterisk 1.8.X - Versión 1.0 (1)

En “Music On Hold File Packages” se hace lo mismo:

Como se hace lo mismo en “Extra Sound Packages”:

29

Page 41: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guarda la configuración presionando la tecla tabulador hasta posicionarse sobre “Save & Exit”. Se termina con la compilación e instalación:

make

Si a lo largo de la compilación aparece este error:

make[1]: *** [format_mp3.o] Error 1make: *** [addons] Error 2

se continua con:

contrib/scripts/get_mp3_source.sh

y luego otra vez el make:

make

se instala Asterisk:

make install

se instalan los archivos de configuración predefinidos:

make samples

30

Page 42: Libro Asterisk 1.8.X - Versión 1.0 (1)

se configura el script de arranque de Asterisk:

make config

Terminada la instalación, se procede a la configuración de MySQL para crear la base de datos y la tabla donde se guardarán los registros de las llamadas.

/etc/init.d/mysqld start

se configura para que arranque en automático:

chkconfig mysqld on

y se crea una contraseña para el usuario root de MySQL (sesamo):

IMPORTANTE: para un sistema en producción utilizar siempre contraseñas fuertes

mysqladmin -u root password sesamo

Para asegurar el servidor MySQL se ejecuta el programa:

mysql_secure_installation

Se contestan las preguntas somo sigue:

Enter current password for root (enter for none): sesamoOK, successfully used password, moving on...

Change the root password? [Y/n] n ... skipping.

Remove anonymous users? [Y/n] y ... Success!

Disallow root login remotely? [Y/n] y ... Success!

Remove test database and access to it? [Y/n] y - Dropping test database...

Reload privilege tables now? [Y/n] y ... Success!

Cleaning up...

31

Page 43: Libro Asterisk 1.8.X - Versión 1.0 (1)

All done! If you've completed all of the above steps, your MySQLinstallation should now be secure.

Thanks for using MySQL!

Se reinicia el servidor MySQL:

service mysqld restart

Se crea la base de datos para guardar los registros de las llamadas. Se entra en el cliente de MySQL:

mysql -u root -psesamo

se crea la base de datos asteriskcdr:

mysql> create database asteriskcdr;

se selecciona:

mysql> use asteriskcdr

se crea la tabla cdr (copiando y pegando las lineas que siguen):

mysql> CREATE TABLE cdr ( id bigint(20) NOT NULL auto_increment, calldate datetime NOT NULL default '0000-00-00 00:00:00', clid varchar(80) NOT NULL default '', src varchar(80) NOT NULL default '', dst varchar(80) NOT NULL default '', dcontext varchar(80) NOT NULL default '', channel varchar(80) NOT NULL default '', dstchannel varchar(80) NOT NULL default '', lastapp varchar(80) NOT NULL default '', lastdata varchar(80) NOT NULL default '', duration int(11) NOT NULL default '0', billsec int(11) NOT NULL default '0', disposition varchar(45) NOT NULL default '', amaflags int(11) NOT NULL default '0', accountcode varchar(20) NOT NULL default '', peeraccount varchar(20) NOT NULL default '', uniqueid varchar(32) NOT NULL default '', linkedid varchar(80) NOT NULL default '', userfield varchar(255) NOT NULL default '', PRIMARY KEY (`id`), KEY callerid (clid));

32

Page 44: Libro Asterisk 1.8.X - Versión 1.0 (1)

Con la versión 1.8 de Asterisk se han añadido dos nuevos campos a la tabla CDR:

• linkedid• peeraccount

que permiten tener informaciones más detalladas de cada llamada.

Se otorgan los permisos de acceso a la base de datos creada al usuario asterisk, desde local

mysql> GRANT ALL PRIVILEGES ON asteriskcdr.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';

desde remoto:

mysql> GRANT ALL PRIVILEGES ON asteriskcdr.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo';

se actualizan los permisos:

mysql> flush privileges;

se sale del cliente:

mysql> quit

En Asterisk la conexión a la base de datos y la tabla de los registros de las llamadas, se configura en el archivo cdr_mysql.conf. Se renombra el predefinido:

mv /etc/asterisk/cdr_mysql.conf /etc/asterisk/cdr_mysql.conf.old

se crea uno nuevo:

nano /etc/asterisk/cdr_mysql.conf

se añaden las siguientes lineas:

[global]hostname=localhostdbname=asteriskcdrtable=cdrpassword=sesamouser=asteriskport=3306sock=/var/lib/mysql/mysql.sock

Los datos:

33

Page 45: Libro Asterisk 1.8.X - Versión 1.0 (1)

1. [global] – etiqueta inicial del bloque2. hostname - nombre de dominio o IP del servidor MySQL3. dbname - nombre de la base de datos4. table - nombre de la tabla5. password - contraseña del usuario que tiene los permisos para acceder a la base de datos6. user - nombre del usuario que tiene los permisos para acceder a la base de datos7. port – puerto donde MySQL recibirá las conexiones (predefinido 3306)8. sock – archivo que se crea cuando se inicia MySQL y que se necesita indicar para una correcta

conexión

Se guardan los cambios y se inicia Asterisk:

/etc/init.d/asterisk start

se averigua que esté corriendo:

/etc/init.d/asterisk statusasterisk (pid 2403) is running...

se entra en la consola:

asterisk -rvvvvvvvvvvvvvvvv

se controla que la conexión a la base de datos esté activa:

CLI> cdr mysql statusConnected to asteriskcdr@localhost, port 3306 using table cdr for 59 seconds. Wrote 0 records since last restart.

Se sale de la consola:

CLI> quitExecuting last minute cleanups

34

Page 46: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 47: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo II

Configuración inicial de Asterisk

2.1 Instalar y configurar un cortafuegos

Para proteger el servidor Linux de accesos no autorizados hay que instalar un firewall (cortafuegos) y abrir los puertos que Asterisk necesita para aceptar conexiones externas. Esta es la parte más delicada de la configuración del servidor porque es donde se definen los puertos y los servicios que son accesibles desde Internet. En el caso del VPS Linode se instalará y Configurará IPtables.

Si Asterisk se encuentra instalado en un computador local conectado a Internet a través de un router hay dos opciones:

• Abrir los puertos desde la pagina de administración del router.• Configurar una DMZ en el router y luego gestionar los puertos directamente con Iptables en el

servidor Linux

Para instalar iptables:

yum install iptables

Iptables se encarga de gestionar todos los paquetes que entren y salgan del servidor Linux. Para eso se utilizan tres tipos de tablas:

• la tabla filter donde pasan todos los paquetes en entrada y salida. La tabla filter acepta tres tipos de opciones (cadenas)

• INPUT para los paquetes en entrada• OUTPUT para los paquetes en salida• FORWARD para redireccionar los paquetes

• la tabla NAT se utiliza para rescribir las direcciones o los puertos de los paquetes• la tabla MANGLE se utiliza para modificar algunos parámetros de los paquetes (un ejemplo es

marcar los paquetes para que sean procesados y enviados con una prioridad más alta)

Las reglas se definen una por linea y serán procesadas por iptables siguiendo la misma secuencia.

Cuando no se especifica diversamente, todas las reglas se aplicarán a la tabla filter:

Se acepta todo el trafico en entrada direccionado a la interfaz lookpack

iptables -A INPUT -i lo -j ACCEPT

Se rechaza (REJECT) todo el trafico entrante direccionado a las IP 127.0.0.0/127.255.255.255 menos los paquetes para la interfaz -lo

Page 48: Libro Asterisk 1.8.X - Versión 1.0 (1)

iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT

Se aceptan todos los paquetes en entrada de conexiones ya establecidas, o relacionados con conexiones establecidas. Véase protocolo TCP

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

Se dejan pasar todos los paquetes salientes.

iptables -A OUTPUT -j ACCEPT

Se deja pasar todo el trafico en entrada para el protocolo SSH (puerto 15000 TCP)

iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 15000 -j ACCEPT

Se deja pasar todo el trafico en entrada destinado al puerto udp 4569 (protocolo IAX2)

iptables -A INPUT -p udp --dport 4569 -j ACCEPT

Se deja pasar todo el trafico en entrada destinado al puerto udp 5060 (protocolo SIP)

iptables -A INPUT -p udp --dport 5060 -j ACCEPT

Se deja pasar todo el trafico en entrada destinado al puerto tcp 5060 (protocolo SIP sobre TCP)

iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT

Se deja pasar todo el trafico en entrada destinado a los puertos udp que van de 10000 a 20000 (protocolo RTP)

iptables -A INPUT -p udp --dport 10000:20000 -j ACCEPT

Se dejan pasar las solicitudes de ping

iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

A este punto, ya que se han definido los puertos base que se necesitan abiertos, se bloquea todo el trafico restante.

iptables -A INPUT -j REJECTiptables -A FORWARD -j REJECT

Se averigua el estado de las reglas definidas con el comando:

iptables -L

Aparecerá:

37

Page 49: Libro Asterisk 1.8.X - Versión 1.0 (1)

Chain INPUT (policy ACCEPT)target prot opt source destinationACCEPT all -- anywhere anywhereREJECT all -- anywhere 127.0.0.0/8 reject-with icmp-port-unreachableACCEPT all -- anywhere anywhere state RELATED,ESTABLISHEDACCEPT tcp -- anywhere anywhere state NEW tcp dpt:hydapACCEPT udp -- anywhere anywhere udp dpt:iaxACCEPT udp -- anywhere anywhere udp dpt:sipACCEPT tcp -- anywhere anywhere state NEW tcp dpt:sipACCEPT udp -- anywhere anywhere udp dpts:ndmp:dnpACCEPT icmp -- anywhere anywhere icmp echo-requestREJECT all -- anywhere anywhere reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)target prot opt source destinationREJECT all -- anywhere anywhere reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)target prot opt source destinationACCEPT all -- anywhere anywhere

Para guardar los cambios:

service iptables saveSaving firewall rules to /etc/sysconfig/iptables: [ OK ]

Se inicia el servicio:

service iptables start

Para iniciar iptables automáticamente:

chkconfig iptables on

Para terminar hay que configurar Asterisk para que use los puertos UDP desde 10000 hasta 20000 para el protocolo RTP (es el que se encarga, una vez establecida la conexión entre dos canales, del flujo audio/video)

Se renombra el archivo predefinido:

mv /etc/asterisk/rtp.conf /etc/asterisk/rtp.conf.old

Se crea uno nuevo:

nano /etc/asterisk/rtp.conf

38

Page 50: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se copian las siguientes lineas:

[general]rtpstart=10000rtpend=20000rtpchecksums=nodtmftimeout=3000rtcpinterval=5000strictrtp=yes

Los datos:

• [general] – etiqueta inicial del archivo de configuración• rtpstart – puerto inicial para el trafico RTP• rtpend – puerto final para el trafico RTP• rtpchecksums – Activar o no la suma de verificación en los paquetes del trafico RTP• dtmftimeout – la cantidad de tiempo (en mili segundos) que un tono DTMF sin marcador de fin

tiene los permisos para continuar en el trafico RTP• mili segundos entre los reportes del protocolo RTCP (protocolo che se utiliza para controlar el

trafico RTP• strictrtp – Lo paquetes que no proceden del mismo flujo RTP utilizado en la conexión serán

eliminados

Se guardan los cambios efectuados y se recarga la configuración de Asterisk:

/etc/init.d/asterisk reload

2.2 Carpetas y archivos

Al terminar la instalación de Asterisk unas cuantas carpetas nuevas serán creadas.

/etc/asterisk

Contiene todos los archivos de configuración de Asterisk.

/usr/lib/asterisk/modules

Contiene todos los módulos compilados y utilizables en Asterisk.

/var/lib/asterisk

Que a su vez contiene las siguientes carpetas:

agi-bin/

39

Page 51: Libro Asterisk 1.8.X - Versión 1.0 (1)

donde se guardan los script AGI.

firmware/

Donde se guardan los firmware de las tarjetas en uso.

images/

Donde las aplicaciones irán a buscar las imágenes cuando se comuniquen con teléfonos que soportan esta función.

keys/

Claves publicas y privadas que Asterisk necesita para autenticarse con otros servidores o servicios (Ej: DUNDi).

sounds/

Contiene todas las locuciones que se pueden utilizar en el plan de marcado (dialplan).

moh/

La música en espera que viene con la instalación de Asterisk (no mp3).

licences/

Las licencias de uso que se han adquirido (Ej: para el codec audio g729).

/var/spool/asterisk

Que contiene:

dictate/

Donde se guardarán los archivos audio creados con la aplicación Dictate().

meetme/

Donde se guardarán las grabaciones de las conferencias.

monitor/

Si se graba una llamada, esta es la carpeta donde se guardarán los archivos audio.

outgoing/

Donde hay que mover los archivo de llamadas (call files). Véase el archivo callfiles.txt en la carpeta

40

Page 52: Libro Asterisk 1.8.X - Versión 1.0 (1)

doc de las fuentes de Asterisk para una explicación del funcionamiento de estos archivos.

system/

Carpeta para archivos temporales creados por la aplicación System().

tmp/

Carpeta donde se guardan los archivos temporales creados por algunas aplicaciones (Ej. buzón de voz).

voicemail/

Donde se guardarán los archivos audio de los mensajes de voz dejados en el buzón de voz y los mensajes audio personalizados de cada usuario.

/var/run/asterisk

Contiene la ID del proceso de Asterisk cuando esté corriendo.

/var/log/asterisk

Donde se guardarán todos los registros de Asterisk (errores, mensajes, llamadas y eventos). De revisar cuando se tengan problemas con Asterisk.

2.3 asterisk.conf

En el archivo asterisk.conf, que se encuentra en la carpeta /etc/asterisk, se puede modificar la configuración general de Asterisk. Se divide en cuatro bloques:

• un bloque donde se definen las carpetas de trabajo de Asterisk• un bloque donde se definen distintas opciones• un bloque donde se definen los permisos para el socket de Asterisk• un bloque donde se define el tipo de comportamiento que debe tener Asterisk para determinadas

aplicaciones (dialplan, AGI, Realtime).

[directories](!)astetcdir => /etc/asteriskastmoddir => /usr/lib/asterisk/modulesastvarlibdir => /var/lib/asteriskastdbdir => /var/lib/asteriskastkeydir => /var/lib/asteriskastdatadir => /var/lib/asteriskastagidir => /var/lib/asterisk/agi-binastspooldir => /var/spool/asteriskastrundir => /var/run/asterisk

41

Page 53: Libro Asterisk 1.8.X - Versión 1.0 (1)

astlogdir => /var/log/asterisk

El Bloque [directories] es donde se pueden cambiar las carpetas de configuración de Asterisk. El valor (!) después de la etiqueta [directories] indica que el bloque esta comentado (no será leído por Asterisk).

[options];verbose = 3;debug = 3;alwaysfork = yes;nofork = yes;quiet = yes;timestamp = yes;execincludes = yes;console = yes;highpriority = ye;initcrypto = yes;nocolor = yes;dontwarn = yes;dumpcore = yes;languageprefix = yes;internal_timing = yes;systemname = my_system_name;autosystemname = yes;maxcalls = 10;maxload = 0.9;maxfiles = 1000;minmemfree = 1;cache_record_files = yes;record_cache_dir = /tmp;transmit_silence_during_record = yes;transmit_silence = yes;transcode_via_sln = yes;sendfullybooted = yes;runuser = asterisk;rungroup = asterisk;lightbackground = yes;documentation_language = en_US;hideconnect = yes

El Bloque [options] permite modificar algunas opciones de Asterisk. Por defecto todas las opciones están comentadas (no aplican). Algunos ejemplos:

• si se quiere quitar los colores en la consola de Asterisk, se quita el punto y coma de la linea nocolors=yes

• Si el sistema donde está instalado Asterisk no puede cursar más de 30 llamadas, se pone maxcalls = 30 y se quita el punto y coma delante de la linea

42

Page 54: Libro Asterisk 1.8.X - Versión 1.0 (1)

• si se quiere que al alcanzar un consumo del 0,9 de la CPU del servidor, no se curse más llamadas, se quita el punto y coma delante de maxload = 0.9

• si en lugar del usuario y grupo root, se quiere que el sistema arranque con usuario y grupo asterisk (que hay que crear) se quita el punto y coma delante de runuser = asterisk y rungroup = asterisk

• si se utiliza un servidor dedicado para la base de datos y todos los registros de llamadas de distintos servidores Asterisk se guardan en ese servidor, no hay forma de saber de cual servidor es un determinado registro. Para que esto sea posible, en cada servidor Asterisk hay que configurar el parámetro systemname con un valor que identifique el servidor Asterisk. De esta forma en los registros de llamadas se podrá saber en cual PBX se originó la llamada.

;[files];astctlpermissions = 0660;astctlowner = root;astctlgroup = apache;astctl = asterisk.ctl

El Bloque [files] es donde se definen permisos, usuarios y nombre del socket de Asterisk.

[compat]pbx_realtime=1.6res_agi=1.6app_set=1.6

El Bloque [compat] es donde se puede cambiar el comportamiento de Asterisk para el dialplan, el AGI y el Realtime (temas que serán abordados en lo próximos capítulos). En las versiones anteriores a la 1.8 y 1.6 cuando se definían las opciones de una aplicación, se separaban con un pipe | Desde la versión 1.6 hay que sostituir el pipe con una coma. Si se quiere que Asterisk interprete correctamente los pipe hay que modificar las tres lineas de la siguiente forma:

[compat]pbx_realtime=1.4res_agi=1.4app_set=1.4

2.4 modules.conf

Cuando se compila Asterisk, todos los módulos se guardan en la carpeta /usr/lib/asterisk/modules. Por defecto cuando se inicia Asterisk, todos los módulos serán cargados. Este comportamiento se debe a la configuración predefinida del archivo modules.conf. Si se abre este archivo, después de la etiqueta [modules] se encontrará el parámetro:

autoload=yes

que significa que todos los módulos compilados se cargarán al iniciar Asterisk. Otra forma de cargar los

43

Page 55: Libro Asterisk 1.8.X - Versión 1.0 (1)

módulos podría ser poner ese parámetro en no y luego en el mismo archivo utilizar el parámetro load para cargar los módulos uno a uno.

En el mismo archivo encontramos el parámetro preload. Este parámetro se utiliza para cargar un modulo antes de todos los demás. Como se verá más adelante, en el caso de los módulos relacionados con ODBC, hay que utilizar este parámetro para cargarlos antes de todos los demás.

Es muy probable que a lo largo de la configuración de Asterisk, no se necesitará utilizar algunos módulos y es una buena practica desactivarlos de forma que no se carguen al iniciar Asterisk. En este modo se reduce la memoria y los recursos utilizados por la PBX.

Un ejemplo puede ser el canal Skinny que se utiliza en los teléfonos de marca CISCO. Si no se va a utilizar este protocolo, es mejor desactivarlo en el archivo modules.conf. Esto se hace utilizando el parámetro noload. Se abre el archivo modules.conf:

nano /etc/asterisk/modules.conf

y al final se añade la siguiente linea:

noload => chan_skinny.so

Se guardan los cambios y se reinicia Asterisk:

service asterisk restart

Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvv

y con el comando:

CLI> module show like chan

se verán todos los canales disponibles:

Module Description Use Countchan_local.so Local Proxy Channel (Note: used internal 0chan_iax2.so Inter Asterisk eXchange (Ver 2) 0chan_sip.so Session Initiation Protocol (SIP) 0chan_dahdi.so DAHDI Telephony Driver w/PRI 0chan_oss.so OSS Console Channel Driver 0app_chanspy.so Listen to the audio of an active channel 0chan_bridge.so Bridge Interaction Channel 0app_dumpchan.so Dump Info About The Calling Channel 0chan_mgcp.so Media Gateway Control Protocol (MGCP) 0chan_gtalk.so Gtalk Channel Driver 0chan_unistim.so UNISTIM Protocol (USTM) 0

44

Page 56: Libro Asterisk 1.8.X - Versión 1.0 (1)

chan_agent.so Agent Proxy Channel 0func_channel.so Channel information dialplan functions 0chan_jingle.so Jingle Channel Driver 0app_channelredirect.so Redirects a given channel to a dialplan 0app_chanisavail.so Check channel availability 0chan_phone.so Linux Telephony API Support 017 modules loaded

El canal chan_skinny no aparece porque se ha configurado para que no se cargue. Si en un determinado momento se quiere cargar un modulo que ha sido configurado para no cargarse al iniciar Asterisk, se utiliza el comando:

CLI> module load chan_skinny.so

[Dec 9 11:09:18] NOTICE[3054]: chan_skinny.c:7144 config_load: Configuring skinny from skinny.conf == Parsing '/etc/asterisk/skinny.conf': == Found == Skinny listening on 0.0.0.0:2000 == Registered channel type 'Skinny' (Skinny Client Control Protocol (Skinny)) == Manager registered action SKINNYdevices == Manager registered action SKINNYshowdevice == Manager registered action SKINNYlines == Manager registered action SKINNYshowline Loaded chan_skinny.so => (Skinny Client Control Protocol (Skinny))

El modulo cargado de esta forma quedará activo hasta el siguiente reinicio de Asterisk.

2.5 Música en espera y MP3

Una de las funcionalidades de Asterisk es la música en espera. En muchos servicios de asistencia al cliente es típico escucharla mientras se espera que algún operador nos atienda. En este párrafo se mostrará la configuración de la música en espera con archivos MP3.

Primero se crea la carpeta donde guardar los archivos MP3:

mkdir /var/lib/asterisk/mohmp3

Ahora se descarga un archivo mp3 en la carpeta creada.

cd /var/lib/asterisk/mohmp3

wget http://www.voztovoice.org/tmp/fresas.mp3

Informaciones sobre el archivo:

sox --i fresas.mp3

45

Page 57: Libro Asterisk 1.8.X - Versión 1.0 (1)

Terminada la descarga del fichero MP3, el paso que sigue es configurar el archivo musiconhold.conf.

Se modifica de la siguiente manera:

nano /etc/asterisk/musiconhold.conf

Se añaden las siguientes líneas al final del archivo:

[mp3]mode=filesdirectory=/var/lib/asterisk/mohmp3random=yes

• [mp3] – Nombre de la nueva clase de música en espera• mode= files – la nueva clase utilizará archivos audio• directory=/var/lib/asterisk/mohmp3 – los archivos se encontrarán en la carpeta indicada en el

parametro directory• random=yes – los archivos audio se utilizarán de forma aleatoria

Se accede a la consola de Asterisk:

asterisk -rvvvvvvvvvvvvv

Se escribe:

CLI> moh reload

para recargar la configuración de la música en espera.

CLI> moh show classes

Para ver las clases de música en espera configuradas. Aparecerá:

Class: default localhosMode: files

46

Page 58: Libro Asterisk 1.8.X - Versión 1.0 (1)

localhosDirectory: /var/lib/asterisk/moh

Class: mp3Mode: filesDirectory: /var/lib/asterisk/mohmp3

CLI> quit

Usando archivos MP3 para la música de espera hay que tener en cuenta que el sistema necesitará utilizar bastante recursos de la CPU. Esto porque los archivo MP3 tendrán que ser convertidos en el formato audio requerido por el canal que está accediendo al servicio.

Considerando que los teléfonos IP no tienen un sistema de audio de alta calidad se puede bajar la frecuencia de sampling de los archivos MP3 sin perder en calidad del audio escuchado. El programa que permite este tipo de operación es el mismo SOX.

sox fresas.mp3 -V -r 22050 -c 1 fresas1.mp3

• -c 1 pasamos el archivo de estéreo a mono (un canal).• -r 22050 frecuencia de sampling de 44100 H/z a 22050 Hz.• archivo1.mp3 - el resultado del sampling.

Usando la opción -V aparecerá en la pantalla todo el proceso:

47

Page 59: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se borra el archivo original:

rm fresas.mp3rm: remove regular file `fresas.mp3'? Y

Para probar la nueva configuración se necesita crear una extensión en el archivo extensions.conf (el dialplan o plan de marcado) que se verá más adelante.

IMPORTANTE: cada vez que se modifican o añaden nuevos archivos en la carpeta hay que recargar la configuración de la música en espera o reiniciar Asterisk:

/etc/init.d/asterisk restart

Para luego averiguar que efectivamente el archivo mp3 esté presente en la lista de archivos para la musica en espera [mp3]

asterisk -rvvvvvvvvvvvvvvv

CLI> moh show filesClass: default File: /var/lib/asterisk/moh/macroform-the_simplicity File: /var/lib/asterisk/moh/manolo_camp-morning_coffee File: /var/lib/asterisk/moh/macroform-robot_dity File: /var/lib/asterisk/moh/reno_project-system File: /var/lib/asterisk/moh/macroform-cold_dayClass: mp3 File: /var/lib/asterisk/mohmp3/fresas1

2.6 Preparación del dialplan – extensions.conf

El archivo de configuración de Asterisk extensions.conf es donde se define el dialplan de la centralita. Todas las llamadas entrantes y salientes se procesan en este archivo. Para que Asterisk sepa come enrutarlas se definen contextos, extensiones y prioridades. Más adelante se verá como se crea un contexto y dentro del contexto las extensiones y las prioridades. Una pequeña paréntesis. En el lenguaje común, la extensión es el numero de teléfono interno de una oficina o de un determinado servicio con el que se quiere comunicar. En el caso de Asterisk, la extensión es una serie de números o letras que definen un bloque del dialplan dentro del cual se ejecutan aplicaciones o funciones de la PBX.

En este párrafo se presentará la configuración base del archivo para luego enriquecerlo a lo largo del libro. Este archivo se divide en tres bloques:

• Parte general• Parte dedicada a las variables globales• el dialplan

48

Page 60: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la columna descripción, en negrita, el valor asociado al parámetro. Al final del modulo, la configuración completa del archivo.

Parámetro Descripción[general] etiqueta que da inicio a la parte generalstatic no=cuando se modifica una extensión en el

dialplan el modulo pbx_config reescribirá este archivo y se perderán todos los comentarios presentes.yes=el modulo pbx_config no actualiza automáticamente el dialplan

writeprotect si writeprotect=no y static=yes y se guarda la configuración del dialplan con el comando “dialplan save” se perderán todos los comentarios presentes en el archivo.si writeprotect=yes no se perderán los comentarios y se desactiva el comando “dialplan save”

autofallthrough yes=si una llamada, por cualquier motivo, se sale del dialplan, la llamada será terminada

extenpatternmatchnew yes=mejora la velocidad de elaboración del dialplan para contextos con un numero elevado de extensiones.

clearglobalvars no=si se recarga el dialplan, las variables globales mantendrán su valor definidoyes=si se recarga el dialplan, las variables globales serán reajustadas y asociadas nuevamente

[globals] desde esta etiqueta empieza la definición de las variables globales.

1000 se asocia a la variable 1000 un valor. En este caso SIP/1000

JUST se asocia a la variable JUST el valor SIP/justvoipmarko se asocia a la variable marko el valor

IAX2/marko

Terminada la configuración general y globals se empieza a construir el dialplan. Para iniciar se crearan dos contexto: internas y externas. En uno se definirá la parte accesible a todas las extensiones y en el otro la parte dedicada a las llamadas salientes. De esta forma se podrá controlar quienes tienen acceso y a que. Cada contexto se compone de extensiones y cada extensión de prioridades. Un primero ejemplo:

[internas]

se define el contexto internas

49

Page 61: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 123,1,Answer

el comando exten => es para definir una extensión. 123 es la extensión, 1 es la prioridad y Answer es la aplicación que se utilizará. En este caso Answer contesta la llamada

La segunda linea:

exten => 123,2,Playback(hello-world)

la extensión es la misma, la prioridad es la numero 2 y en este caso la aplicación es Playback cuya función es enviar el audio de una locución al canal que está llamando

La tercera linea:

exten => 123,3,Hangup

la extensión es siempre la misma, la prioridad es la numero 3 y la aplicación es Hangup que lo que hace es terminar la llamada.

Con este primer ejemplo ya se puede empezar a entender como funciona el dialplan. Desde una extensión conectada a Asterisk se marca 123 y si esa extensión tiene acceso al contexto internas, se ejecutará la primera linea, luego la segunda y por ultimo la tercera. Las prioridades indican el orden en que se procesa el dialplan para una determinada extensión.

Otra forma de escribir esta parte del dialplan es:

exten => 123,1,Answerexten => 123,n,Playback(hello-world)exten => 123,n,Hangup

La n de la segunda y tercera linea está por “next” y añade una prioridad a la que la precede. Desde la versión 1.6.2.X de Asterisk hay una forma mucho más sencilla de escribir el dialplan y es la que se utilizará en este libro:

exten => 123,1,Answersame => n,Playback(hello-world)same => n,Hangup

Ahora se configura otra extensión que permite escuchar la música de espera MP3 creada en el párrafo 2.5:

exten => 200,1,Answersame => n,MusicOnHold(mp3,60)same => n,Hangup

Marcando la extensión 200, Asterisk contestará la llamada (Answer) ejecutará la aplicación

50

Page 62: Libro Asterisk 1.8.X - Versión 1.0 (1)

MusicOnHold que permite escuchar la música de espera de una clase configurada en el archivo musiconhold.conf (es este caso la clase mp3). La segunda opción (60) define el tiempo, en segundos, que se escuchará la música. Pasados los 60 segundos, la llamada terminará (Hangup).

En el dialplan se pueden definir contextos que incluyen otros contextos. De esta forma si un determinado contexto incluye a otro, ese contexto tendrá acceso a las extensiones presentes en el contexto incluido. Por ahora se definen dos de esta forma:

[externas]include => internas

[locales]include => internas

Con estos primeros datos se construye el dialplan. Se renombra el archivo predefinido:

mv /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.old

se crea uno nuevo:

nano /etc/asterisk/extensions.conf

y se copian las siguientes lineas:

[general]static=yeswriteprotect=yseautofallthrough=yseextenpatternmatchnew=yseclearglobalvars=no

[globals]1000=SIP/1000JUST=SIP/justvoipmarko=IAX2/marko

[internas]exten => 123,1,Answersame => n,Playback(hello-world)same => n,Hangup

exten => 200,1,Answersame => n,MusicOnHold(mp3,60)same => n,Hangup

[externas]include => internas

51

Page 63: Libro Asterisk 1.8.X - Versión 1.0 (1)

[locales]include => internas

Se guarda la configuración y se recarga el dialplan desde la consola de Asterisk:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

Para ver el dialplan externas:

CLI> dialplan show externas[ Context 'externas' created by 'pbx_config' ] Include => 'internas' [pbx_config]-= 0 extensions (0 priorities) in 1 context. =-

Para ver el contexto internas:

CLI> dialplan show internas[ Context 'internas' created by 'pbx_config' ] '123' => 1. Answer() [pbx_config] 2. Playback(helloworld) [pbx_config] 3. Hangup() [pbx_config] '200' => 1. Answer() [pbx_config] 2. MusicOnHold(mp3,60) [pbx_config] 3. Hangup() [pbx_config]-= 2 extensions (6 priorities) in 1 context. =-

Para una lista de comandos disponibles:

CLI> help dialplan dialplan add extension Add new extension into context dialplan add ignorepat Add new ignore pattern dialplan add include Include context in other context dialplan debug Show fast extension pattern matching data structures dialplan reload Reload extensions and *only* extensions dialplan remove extension Remove a specified extension dialplan remove ignorepat Remove ignore pattern from context dialplan remove include Remove a specified include from context dialplan save Save current dialplan into a file dialplan set chanvar Set a channel variabledialplan set extenpatternmatch Use the Old extension pattern matching algorithm.dialplan set extenpatternmatch Use the New extension pattern matching algorithm. dialplan set global Set global dialplan variable dialplan show chanvar Show channel variables dialplan show globals Show global dialplan variables

52

Page 64: Libro Asterisk 1.8.X - Versión 1.0 (1)

dialplan show Show dialplan

53

Page 65: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 66: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo III

Protocolo SIP y el archivo sip.conf

El protocolo SIP es un protocolo de señalización que permite:

• localizar un usuario• contactar un usuario para determinar su voluntad de establecer una sesión• Negociación de los media (audio/video) que se utilizarán a lo largo de la sesión• Modificar una sesión establecida• Terminar una sesión establecida

Este protocolo ha sido definido por la IETF (The Internet Engineering Task Force) que es la entidad que se encarga de definir los estándar para la red Internet. En este caso el documento que define el protocolo SIP es el RFC (Request for Comments) 3261. En ese documento se explica como deben funcionar programas y/o dispositivos que quieran implementar el protocolo SIP. Desde un punto de vista del funcionamiento, los mensajes que se envían son una mezcla entre el protocolo HTTP (Hypertext Transfer Protocol) y el protocolo SMTP (Simple Mail Transfer Protocol). Dentro del protocolo SIP existen los métodos, que representan las distintas solicitudes que un dispositivo puede enviar a otro. Los seis métodos principales del protocolo SIP son:

• REGISTER• INVITE• BYE• ACK• CANCEL• OPTIONS

Asterisk PBX es un B2BUA (back-to-back user agent) y su función es la de hacer de “intermediario” entre los usuarios. Un usuario (o User Agent como definido en el protocolo SIP) enviará todas sus peticiones a Asterisk que se encargará de procesarlas y de esta forma permitir establecer sesiones media. Como Asterisk implementa distintos tipos de protocolos (SIP, IAX2, H323), él mismo se encargará de establecer llamadas entre usuarios que están utilizando diferentes protocolos.

En Asterisk, el archivo sip.conf es donde se definen las extensiones SIP, los proveedores SIP y, en general, todo lo relacionado con el protocolo SIP. El archivo sip.conf está estructurado en tres bloques:

• Una parte general donde se define la configuración global del protocolo SIP. Al momento de configurar una extensión o una troncal, si no se definen algunos parámetros, estos serán tomados desde la parte general del archivo. Un ejemplo son los codecs audio.

• Un bloque central donde se configura el registro a los proveedores VoIP y/o otros servidores Asterisk

• Una parte final donde se configuran las extensiones internas, las troncales y las conexiones a otros servidores Asterisk.

Hay que pensar en Asterisk como un conmutador que quizás algún día hemos visto en la recepción de

Page 67: Libro Asterisk 1.8.X - Versión 1.0 (1)

un Hotel o una empresa. Asterisk tiene las mismas funcionalidades. Con las extensiones configuradas se podrán llamar entre ellas, se podrán enrutar las llamadas a teléfonos fijos y/o celulares, utilizar proveedores SIP, Gateway PSTN, y aprovechar los típicos servicios de una PBX como llamada en espera, desvío de llamadas, llamada a tres, contestador automático, buzón de voz, etc.

En los VPS Linode hay la posibilidad de activar una dirección IP local. Normalmente se utiliza para la creación de una red local entre distintos VPS que estén en el mismo Datacenter. Para volver la configuración del sip.conf lo más real posible, se activará esta IP local. Para hacerlo se entra en la pagina de administración del VPS y en la pestaña “Remote Access” se escoge el enlace evidenciado en la imagen que sigue:

Aparecerá la dirección IP local:

Se anota el valor y se configura una nueva tarjeta de red virtual:

nano /etc/sysconfig/network-scripts/ifcfg-eth0:1

Se añaden estas lineas:

DEVICE=eth0:1BOOTPROTO=noneONBOOT=yesIPADDR=192.168.181.15NETMASK=255.255.128.0

En IPADDR hay que poner la IP local creada en su VPS Linode. Se guardan las modificaciones y se reinicia la red del servidor:

service network restart

Con el comando:

ifconfig

56

Page 68: Libro Asterisk 1.8.X - Versión 1.0 (1)

veremos la nueva tarjeta de red configurada:

3.1 sip.conf

La configuración que sigue abarca los parámetros más importantes del sip.conf; cada línea de la tabla viene acompañada por una breve explicación Si es presente un asterisco antes del nombre del parámetro, significa que es una nueva funcionalidad añadida con la versión 1.8 de Asterisk o que han habido cambios en su configuración. En negrita la opción que se utilizará para cada parámetro. Al final de la tabla, la configuración completa del archivo.

Parámetro Descripción

[general] etiqueta que introduce la parte general de la configuraciónallowguest No = no se permiten llamadas entrantes (INVITE) de usuarios

no autenticados (aumenta la seguridad de Asterisk)Yes = se permiten llamadas entrantes (INVITE de usuarios no autenticados

context default = el contexto donde llegarán las llamadas no autenticadas si allowguest=yes

allowtransfer En casi todos los teléfonos SIP, a lo largo de una llamada, es posible hundir un botón para transferirla a otra extensión. Este parámetro define si Asterisk aceptará este tipo de solicitudes. Posibles opciones: No y Yes

realm si al servidor es asociado un dominio registrado, se puede definir este parámetro para que la autentificación se haga utilizando ese nombre de dominio (digest authentication RFC2617). Se deja comentado

*udpbindaddr Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha para las señalización SIP utilizando el protocolo UDP. Como desde la versión 1.8, Asterisk soporta el protocolo IPv6 es posible configurar cuatro escenarios distintos:

1. 192.168.1.0 – Asterisk aceptará conexiones solamente si enviadas a la dirección IPv4 indicada

2. 2600:3c00::f03c:91ff:fedf:a455 - Asterisk aceptará conexiones solamente si enviadas a la dirección IPv6 indicada

3. 0.0.0.0 – Asterisk aceptará conexiones en todas las direcciones IPv4 presentes en el servidor Linux

57

Page 69: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

4. :: - Asterisk aceptará conexiones en todas las direcciones IPv4 y IPv6 dando prioridad a la primera IP que encuentra. En el caso de Linode será IPv6

Como se va a trabajar con Ipv4, para que Asterisk escuche en todas las direcciones IPv4 puerto 5060 (el predefinido) el Valor es: 0.0.0.0:5060

tcpenable Desde la versión 1.6 es posible configurar Asterisk para que permita la señalización SIP sobre el protocolo TCP Valor yes

*tcpbindaddr Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha para las señalización SIP utilizando el protocolo TCP. Como para el protocolo UDP es posible utilizar cuatro escenarios distintos para indicar IP y puerto de escucha. En este caso se configurará para que escuche en todas las direcciones Ipv4 puerto 5060. Valor: 0.0.0.0:560

tcpauthtimeout Representa el números de segundos que tiene a disposición un cliente para registrarse utilizando el protocolo TCP. Si no lo hace antes del tiempo indicado, sera desconectado. Valor: 30

tcpauthlimit Numero máximo de conexiones no autenticadas permitidas utilizando el protocolo TCP. Valor:100

srvlookup Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas SIP salientes del tipo: SIP/usuario@dominio. Asterisk hace esta búsqueda limitándose al primer valor encontrado. Valor: Yes

maxexpiry Tiempo máximo, en segundos, permitido para REGISTER y SUBSCRIBE entrantes. Valor 3600

minexpiry Tiempo mínimo, en segundos, permitido para REGISTER y SUBSCRIBE entrantes. Valor: 60

defaultexpiry Cuando un cliente se registra a Asterisk, envía el tiempo de duración de su registro. En el caso que no lo haga, Asterisk considerará que el registro durará el tiempo indicado en este parámetro expresado en segundos. Valor: 120

mwiexpiry La mayoría de los teléfonos SIP, cuando la extensión registrada recibe un nuevo mensaje en el buzón de voz, lo señalan a través de un icono en la pantalla o un indicador luminoso. Esto porque se “suscribe” a este tipo de servicio en el servidor Asterisk. Este parámetro indica cada cuantos segundos las suscripción tendrá que ser renovada. Valor 3600

maxforwards Cada vez que un “mensaje” Sip se envía puede atravesar distintos servidores antes de llegar al destinatario. Con este parámetro se limita el numero de veces que se puede reenviar. Se utiliza también para evitar que se creen bucles. Valor. 70

58

Page 70: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

qualifyfreq Cada cuantos segundos enviar un paquete OPTIONS a la extensión registrada en Asterisk. Esto permite saber si la extensión misma es alcanzable. El método OPTIONS del protocolo SIP se utiliza también para conocer los métodos disponible en un determinado cliente. Valor 60

*preferred_codec_only Asterisk contesta a un INVITE entrante con un solo codec audio en lugar de enviar toda la lista de codecs configurados. Esto permite que el llamante envíe el flujo audio con el codec que se ha establecido. Valor: no

disallow all – Se desactivan todos los codec audio y videoallow Se indican los codec audio y video utilizables. Pueden ser

indicados uno por linea o en la misma linea separados por una coma:allow=alawallow=ulawoallow=alaw,ulawulaw: se utiliza en Estados Unidos, Canadá y Australiaalaw = se utiliza en Asia, Europa, África y América Latina

mohinterpret clase de música de espera predefinida – default mohsuggest Clase de música de espera cuando un canal de tipo peer se pone

en espera – default parkinglot Asterisk, entre sus funcionalidades, permite parquear una

llamada. Como desde la versión 1.6.X es posible configurar más de un “contexto” de parqueo, en este parámetro se indica el predefinido. Valor: default

language el idioma predefinido para las locuciones . Valor es (Español)sendrpid Como se verá más adelante cada “mensaje” SIP se compone de

diferentes lineas. Cada linea se llama HEADER o cabecera. Este parámetro define se entre los distintos HEADER se envía también el Remote-Party-ID. Este parámetro es muy útil para las transferencias atendida de las llamadas entre extensiones Valor: yes

rpid_update En algunos casos, la única forma de actualizar los datos de una sesión es enviando un SIP UPDATE. Con este parámetro se activa o desactiva. Valor: yes

prematuremedia En Asterisk es posible enviar audio aunque la llamada no ha sido contestada. Un ejemplo es cuando llamamos un numero celular (en Colombia) y si nadie contesta escuchamos la voz que dice "Sistema correo de voz. Tendrá cobro a partir de este momento". Si colgamos, no pagamos nada porque la llamada realmente no

59

Page 71: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

ha sido contestada. Esta funcionalidad se llama "Early Media". Durante el Early Media, los tonos DTMF no funcionan y no se pueden utilizar. Este comportamiento se obtiene poniendo como valor no

useragent Asterisk se presentará con este nombre al momento de comunicarse con otros servidores o proveedores SIP. Valor: VozToVoice v. 1.0 Personalizar

sdpsession asterisksdpowner asterisk dtmfmode protocolo para el envío de los DTMF (Dual-Tone Multi-

Frequency). Serían los tonos que se generan cuando se hunden las teclas del teléfono. Valor: rfc2833 Otro valor bastante común es inband. Con inband los tonos se envían en el flujo audio (protocolo RTP). Inband no funciona con el codec audio G729

videosupport no=no se activa el soporte para video llamadasyes=se activa el soporte para video llamadas

maxcallbitrate Banda máxima utilizable para video llamadas (predefinida 384 kb/s)

callevents yes=cuando el estado de una extensión cambia, el Asterisk Manager Interface (AMI) genera el correspondiente evento

authfailureevents yes=el AMI generará un evento cuando una peer no se pueda autenticar con la PBX

alwaysauthreject yes=cuando un INVITE o un REGISTER es rechazado por Asterisk, en lugar de enviar el verdadero motivo del rechazo contestará siempre con un 401 Unauthorized no permitiendo dar pistas a los que están intentando acceder al sistema

use_q850_reason Yes Permite el envío de los códigos Q850 en el Header Reason que normalmente se utiliza para conocer el motivo porque una llamada SIP ha sido terminada. Esta serie de códigos, es utilizado por algunos Gateway para mejorar la compatibilidad con el protocolo SIP

rtptimeout 60=si en una llamada establecida no hay flujo audio por 60 segundos la llamada será terminada

rtpholdtimeout 300=si en una llamada en espera no hay flujo audio por 300 segundos, la llamada será terminada

rtpkeepalive 0=no envía un paquete UDP utilizando el protocolo RPT para mantener abierto el NAT

allowsubscribe yes=permite suscribirse al estado de una extensiónsubscribecontext subscribe=Este parámetro define el contexto que se utilizará

60

Page 72: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

para permitir a las extensiones acceder al estado de otras.notifyringing yes=Notifica si la extensión está timbrandonotifyhold yes= Notifica si la extensión está en esperacallcounter yes=cuenta el numero de canales utilizados por una extensión.

Este parámetro junto a las funciones GROUP y GROUP_COUNT permite limitar el numero de llamadas simultaneas que una extensión puede hacer.

*t38pt_udptl Permite el uso del protocolo T38 (fax sobre IP). Desde la versión 1.8.X, la aplicación para enviar y recibir fax ha sido reescrita totalmente. El nuevo modulo se llama res_fax que sustituye el viejo app_fax ahora “deprecated” Valor: yes,fec,maxdatagram=400

faxdetect Permite diferenciar el tratamiento de las llamadas entrantes según sea un fax o una llamada de voz. Los valores permitidos son:

• yes = Habilita la detección de FAX T30 y T38• no = dehabilitado• cng = Habilita la detección de FAX T30• t38 = Habilita la detección de FAX T38

localnet En el caso que Asterisk esté instalado en una red local que se encuentra detrás de un NAT, hay que indicar el rango de direcciones IP de la red local. En el caso del VPS Linode se pone la dirección IP local creada (personalizar con la IP local de su VPS) Ejemplo: 192.168.128.0/255.255.128.0

externaddr Si Asterisk está instalado detrás de un NAT, con este parámetro se indica la dirección IP publica de la red. En el VPS Linode se pone la IP del servidor. Ejemplo 96.126.121.135 Personalizar

;externhost Si la dirección IP publica es dinámica o está asociada a un nombre de dominio, en lugar de externaddr se utiliza este parámetro. Si no se posee un nombre de dominio, se puede utilizar el servicio de dyndns. En el VPS Linode se deja comentado

;externrefresh Cada cuantos segundos actualizar la asociación dirección IP – nombre de dominio. En el VPS Linode se deja comentado

*nat Define el tipo de comportamiento que debe tener Asterisk al conectarse con otras extensiones/dispositivos. Los distintos valores son:no = usa el parámetro rport (RFC3581) solamente si el cliente remoto lo requiere

61

Page 73: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

force_rport = impone siempre el uso del parámetro rportyes = impone siempre el uso del parámetro rport y envía el flujo audio/video por el mismo puerto utilizado por el dispositivo remoto.comedia = usa el parámetro rport solamente si requerido por el dispositivo remoto

directmedia no=no se permite el flujo media directo (protocolo RPT) entre las extensiones. El flujo directo solo es posible cuando las extensiones no se encuentran detrás de un NAT

;media_address Si se quiere que el trafico RTP (audio/video) viaje sobre una IP distinta a la de la señalización SIP, se puede definir en este parámetro. Se deja comentado

rtcachefriends Este parámetro aplica cuando las extensiones están configuradas en una base de datos (se verá más adelante). Valor no

rtupdate este parámetro también aplica cuando las extensiones están configuradas en una base de datos. Cuando una de estas extensiones se registre a Asteirsk, en la base de datos se guardará la dirección IP, el puerto, el tiempo de registro y el nombre de usuario. Valor yes

register => Con esta linea empieza el segundo bloque del archivo sip.conf y se utiliza para registrarse a servidores externos; normalmente proveedores SIP o otro servidores Asterisk. El parámetro se deja comentado y a seguir se presentan algunos ejemplos:

• register => fulano:[email protected] el registro con el proveedor el username será fulano, la contraseña sesamo y el dominio sip.provider1.com. Si el proveedor usa un puerto que no es el 5060 hay que especificarlo al final de la línea de esta forma:

• register => fulano:[email protected]:5061En los dos casos las llamadas entrantes llegaran a la extensión s y al contexto que se define en la configuración de la extensión. Si queremos que las llamadas entre a una extensión definida, tenemos que añadir al final de la linea el numero. Este numero puede ser arbitrario siempre y cuando los proveedores SIP no especifiquen diversamente:

• register => fulano:contraseñ[email protected]/1234registertimeout Si Asterisk pierde el registro, este parámetro representa el

numero de segundos que Asterisk esperará antes de volver a intentar registrarse. Valor 20

registerattempts este parámetro representa el numero de intentos que Asterisk hará para registrarse. Si ponemos 0, los intentos serán infinitos. Valor 10

62

Page 74: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

mwi => Desde la versión 1.6.2.X se puede subscribir el estado de un buzón de voz de un servidor remoto. En este ejemplo el buzón 1234 y contexto SIP_remote. Para subscribirse en la configuración de la extensión se indicará: mailbox=1234@SIP_Remote. Valor: 1234:[email protected]/1234

La ultima parte es dedicada a la configuración de las extensiones. En el caso del VPS Linode todas las extensiones se conectarán detrás de un NAT (router banda ancha y/o otro tipo de conexión Internet).

Parámetro Descripción[1000] Numero de la extensiónaccountcode Código que aparecerá en el registro de llamadas

para esta extensión. Valor 1000language es=esta extensión utilizará las locuciones en

españoltype friend=es un user y peer al mismo tiempo

• user: una extensión que se autentica al servidor Asterisk usando el campo From para hacer llamadas.

• peer una extensión que se autentica para las llamadas entrantes utilizando la dirección IP y el puerto

secret La contraseña para la extensión. Personalizar Valor predefinido: pbx909090

qualify Este parámetro se utiliza para mantener activa la conexión de una extensión que se conecta al servidor Asterisk detrás de una NAT. Valor Yes

mailbox Si este parámetro es configurado, cuando la extensión se conecte al servidor Asterisk, éste controlará si hay mensajes de voz pendientes y en caso positivo se lo comunicará usando MWI = Message Waiting Indicator. que es una señal audio o vídeo que puede ser recibida por la mayoría de los teléfonos IP o Softphone Valor 1000@default

host Si la extensión se conecta remotamente con un IP dinámico se pone dynamic. En caso contrario se pone la dirección IP

dtmfmode Protocolo para los tonos DTMF Valor rfc2833context El contexto a que tendrá acceso la extensión.

63

Page 75: Libro Asterisk 1.8.X - Versión 1.0 (1)

Valor externas como se ha creado en el dialplandirectmedia Si las extensiones, como es el caso de una VPS

Linode, están detrás de un NAT, el valor es nocallerid el nombre y el numero que identifica la extensión

cuando llama. valor Fulano <1000> Personalizarcallgrouppickupgroup

estos dos parámetros definen una de las funcionalidades avanzadas de Asterisk, es decir la posibilidad de capturar la llamada de una extensión que está timbrando, desde otra extensión. Valor 1 para ambos

disallow all=se deshabilita todos los codec (audio/video)allow alaw=se habilita el codec audio alawallow g722=se habilita el codec audio g722allow g729=se habilita el codec audio g729allow h263=se habilita el codec video H263

Se configura una segunda extensión:

[1001]type=friendaccountcode=1001language=essecret=pbx9091qualify=yesmailbox=1001@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=zutano <1001>callgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

Cuando se deben configurar muchas extensiones, se pueden crear templates (plantillas) donde se definen todos los parámetros compartidos por todas las extensiones. Luego por cada una de ellas, se configuran solamente los parámetros que la diferencian de las demás. Para crear un template la primera linea debe tener esta sintaxis:

64

Page 76: Libro Asterisk 1.8.X - Versión 1.0 (1)

[int-locales](!)

[int-locales] es la descripción del template (en este ejemplo se utilizará para configurar todas las extensiones que tienen acceso solo a llamadas locales). (!) es las sintaxis que indica que se trata de un template. Luego se añaden todas las lineas comunes a todas las extensiones:

type=friendlanguage=esqualify=yeshost=dynamicdtmfmode=rfc2833context=localesdirectmedia=nocallgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

Ahora para configurar una nueva extensión se puede utilizar ese template de la siguiente forma:

[1002](int-locales)accountcode=1002secret=pbx9092mailbox=1002@defaultcallerid=Mengano <1002>

Terminada la configuración de las extensiones, se pasa a la troncal SIP utilizando el proveedor JustVoIP:

Parámetro Descripción[justvoip] nombre que se le asigna a la troncaltype la troncal es de tipo peerhost sip.justvoip.com=dominio del proveedor SIPfromdomain sip.justvoip.com=Este parámetro permite definir

el nombre de dominio que aparecerá en la campo From: de la cabecera SIP. Mucho proveedores lo exigen para autenticar las llamadas

fromuser nombre de usuario. Este parámetro permite definir el nombre de usuario que aparecerá en el campo

65

Page 77: Libro Asterisk 1.8.X - Versión 1.0 (1)

From de la cabecera SIP. Muchos proveedores lo exigen para autenticar las llamadas.

defaultuser el mismo valor del parametro fromusersecret la contraseña.qualify yesdtmfmode rfc2833context from-justvoip=el contexto donde llegarán las

llamadas si se utiliza el proveedor también para las llamadas entrantes

directmedia nolanguage esnat no=no hay NAT entre el servidor Asterisk y el

proveedor SIPdisallow allallow alawallow g729

Ahora se puede copiar toda la configuración en el archivo sip.conf. Antes que nada se renombra el archivo sip.conf predefinido y se crea uno nuevo:

mv /etc/asterisk/sip.conf /etc/asterisk/sip.conf.old

nano /etc/asterisk/sip.conf

Se pegan las lineas que siguen:

[general]allowguest=nocontext=defaultallowtransfer=yes;realm=mydomain.tldudpbindaddr=0.0.0.0:5060tcpenable=yestcpbindaddr=0.0.0.0:5060tcpauthtimeout=30tcpauthlimit=100srvlookup=yesmaxexpiry=3600minexpiry=60defaultexpiry=120mwiexpiry=3600maxforwards=70

66

Page 78: Libro Asterisk 1.8.X - Versión 1.0 (1)

qualifyfreq=60preferred_codec_only=nodisallow=allallow=ulawallow=alawmohinterpret=defaultmohsuggest=defaultparkinglot=defaultlanguage=essendrpid=yerpid_update=yesprematuremedia=nouseragent=VozToVoice v. 1.0sdpsession=asterisksdpowner=asteriskdtmfmode=rfc2833videosupport=yesmaxcallbitrate=384callevents=yesauthfailureevents=yesalwaysauthreject=yesuse_q850_reason=yesrtptimeout=60rtpholdtimeout=300rtpkeepalive=0allowsubscribe=yessubscribecontext=subscribenotifyringing=yesnotifyhold=yescallcounter=yest38pt_udptl=yes,fec,maxdatagram=400 faxdetect=yeslocalnet=externaddr=;externhost=prueba.dyndns.org;externrefresh=180nat=force_rportdirectmedia=no;media_address=0.0.0.0rtcachefriends=nortupdate=yes

;register => fulano:[email protected];register => fulano:[email protected]:5061;register => fulano:contraseñ[email protected]/1234registertimeout=20registerattempts=10

67

Page 79: Libro Asterisk 1.8.X - Versión 1.0 (1)

;mwi => 1234:[email protected]/1234

[1000]accountcode=1000language=estype=friendsecret=pbx9090qualify=yesmailbox=1000@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=callerid=Fulano <1000>callgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

[1001]type=friendaccountcode=1001language=essecret=pbx9091qualify=yesmailbox=1001@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=zutano <1001>callgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

[int-locales](!)type=friendlanguage=esqualify=yeshost=dynamic

68

Page 80: Libro Asterisk 1.8.X - Versión 1.0 (1)

dtmfmode=rfc2833context=localesdirectmedia=nocallgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

[1002](int-locales)accountcode=1002secret=pbx9092mailbox=1002@defaultcallerid=Mengano <1002>

[justvoip] type=peerhost=sip.justvoip.comfromdomain=sip.justvoip.comfromuser=defaultuser=secret=qualify=yesdtmfmode=rfc2833context=from-justvoipdirectmedia=nolanguage=esnat=nodisallow=allallow=alawallow=g729

Antes de guardar los cambios, hay que personalizar los parámetros localnet y externaddr en el bloque general; en el bloque del proveedor SIP Justvoip se ponen los datos de usuario y contraseña creados al momento de la creación de la cuenta con el proveedor. Cada vez que se modifica la configuración del sip.conf hay que recargarla. Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvv

Se escribe el comando:

CLI> sip reload

Para ver los peer configurados:

69

Page 81: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> sip show peersName/username Host Dyn Nat ACL Port Status1000 (Unspecified) D N 5060 UNKNOWN1001 (Unspecified) D N 5060 UNKNOWN1002 (Unspecified) D N 5060 UNKNOWNjustvoip/pbx2020 77.72.169.129 5060 OK (160 ms)4 sip peers [Monitored: 1 online, 3 offline Unmonitored: 0 online, 0 offline]

Para ver los users configurados:

CLI> sip show usersUsername Secret Accountcode Def.Context ACL NAT1000 pbx9090 1000 phones No Always1001 pbx9091 1001 phones No Always1002 pbx9092 1002 phones No Always

Para una lista de los comandos disponibles para el protocolo SIP en Asterisk:

CLI> help sip sip notify Send a notify packet to a SIP peer sip prune realtime [peer|all] Prune cached Realtime users/peers sip qualify peer Send an OPTIONS packet to a peer sip reload Reload SIP configurationsip set debug {on|off|ip|peer} Enable/Disable SIP debugging sip set history {on|off} Enable/Disable SIP historysip show {channels|subscriptio List active SIP channels or subscriptions sip show channelstats List statistics for active SIP channels sip show channel Show detailed SIP channel info sip show domains List our local SIP domains sip show history Show SIP dialog history sip show inuse List all inuse/limits sip show mwi Show MWI subscriptions sip show objects List all SIP object allocations sip show peers List defined SIP peers sip show peer Show details on specific SIP peer sip show registry List SIP registration status sip show sched Present a report on the status of the sched queue sip show settings Show SIP global settings sip show tcp List TCP Connections sip show users List defined SIP users sip show user Show details on specific SIP user sip unregister Unregister (force expiration) a SIP peer from the registry

3.2 Directmedia

Como se ha dicho anteriormente, este parámetro permite definir si el flujo audio es directo entre los

70

Page 82: Libro Asterisk 1.8.X - Versión 1.0 (1)

dispositivos o pasa por Asterisk que se encarga de enrutarlo de una extensión a otra. Para poder entender un poco mejor este comportamiento, se puede ver el gráfico que sigue:

SIP SIP RPT RPT

En este escenario directmedia=no. El trafico SIP y RTP pasa completamente por Asterisk. En el caso que directmedia= yes el gráfico cambiaría de la siguiente forma:

SIP SIP

La señalización SIP sigue pasando por Asterisk, mientras que el flujo media va directo de una extensión a otra. Este escenario funciona solamente si las extensiones no están detrás de un NAT. Un típico ejemplo es cuando se instala el servidor Asterisk dentro de una red local y los teléfonos SIP están conectados en la misma red. La ventaja es que de esta forma se ahorran recursos del servidor Linux. Si en el sip.conf el parámetro dtmfmode=inband, como los tonos viajan en el flujo audio y Asterisk no recibe ese flujo, no se podrán utilizar funcionalidades avanzadas configuradas en Asterisk que utilizan los tonos para ser activadas.

3.3 Contraseñas seguras

En el archivo sip.conf las contraseñas de las extensiones aparecen en texto plano. Si alguien lograra entrar en el servidor Linux, con solo abrir el archivo, podría conocer todas las contraseñas de las

71

RPT

Page 83: Libro Asterisk 1.8.X - Versión 1.0 (1)

extensiones. Para evitar esto y volver más seguro el sistema, es posible cifrarlas con el algoritmo MD5.Tomamos como ejemplo la primera extensión cuya contraseña es pbx9090. Para cifrarla la sintaxis es:

echo -n "<extensión>:<realm>:<secret>" | md5sum

Como el parámetro real presente en la parte general del sip.conf se ha dejado comentado, el valor predefinido es asterisk; pues el comando sería:

echo -n "1000:asterisk:pbx9090" | md5sum

cuyo resultado será:

5b09185bfc9148923c47cdf60c3a1681

Para utilizar la contraseña cifrada en la configuración de una extensión, en el sip.conf en el bloque de la extensión se quita el parámetro secret y se añade el parámetro md5secret asignándole el valor creado.

3.4 Ngrep

Como se quiere tener la traza de los mensajes SIP entre Asterisk y las extensiones, se instala en el servidor Linux el programa NGREP que permite capturar cualquier tipo de paquete que entre o salga del sistema:

cd /usr/src

primero se instalan unas dependencias:

yum install libpcap-devel

luego se descarga el paquete:

wget http://downloads.sourceforge.net/project/ngrep/ngrep/1.45/ngrep-1.45.tar.bz2

se descomprime:

tar -xf ngrep-1.45.tar.bz2

se entra en la carpeta creada

cd ngrep-1.45

se compila y se instala:

./configure --prefix=/usrmakemake install

72

Page 84: Libro Asterisk 1.8.X - Versión 1.0 (1)

3.5 SoftPhone X-Lite y REGISTER

X-lite es un softphone gratuito desarrollado por la empresa CounterPath que a pesar de sus limitaciones, puede ser utilizado para las pruebas presentes en este libro. Se descarga, se instala y se inicia. Primero se configura la cuenta 1000 creada en Asterisk:

Account name: una descripción de la cuentaUserID: el numero de la extensiónDomain: la dirección IP o el nombre de dominio del servidor Asterisk (la IP del VPS Linode)

73

Page 85: Libro Asterisk 1.8.X - Versión 1.0 (1)

Password: la contraseña de la extensión 1000 (pbx9090)Display name: el numero de la extensiónAuthorization name: el numero de la extensión

En la pestaña Voicemail:

Se selecciona la casilla “check for voicemail” y en “Number to dial for checking voicemail” se pone 97. Este será el numero que hay que marcar para entrar al buzón de voz y que se configurará posteriormente en el dialplan.

74

Page 86: Libro Asterisk 1.8.X - Versión 1.0 (1)

En Topology, como la extensión está detrás de un NAT, se selecciona la casilla “Auto-detect firewall trasversal method using ICE. Interactive Connectivity Establishment es un protocolo (RFC5245) que permite a los dispositivos que lo utilizan, lograr atravesar el NAT. Si la conexión es contra un servidor local, hay que seleccionar la casilla “None (use local IP address).

75

Page 87: Libro Asterisk 1.8.X - Versión 1.0 (1)

En Advanced se configura cada cuantos segundos X-lite volverá a registrarse a Asterisk (3600). Como el softphone se encuentra detrás de un NAT, se selecciona “Send SIP keep-alives para mantener la conexión abierta, y rport. Si la conexión es a un servidor local se pueden desactivar las dos casillas.

Antes de presionar el botón Ok para guardar la configuración, se vuelve a la consola de Linux y se escribe el siguiente comando:

ngrep 1000 -W byline port 5060 > /tmp/register

De esta forma se capturan todos los paquetes enviados y recibidos por la extensión 1000 y se guardan en el archivo register. Se vuelve al X-Lite y se presiona el botón OK. Después de unos segundos el softphone debería estar registrado a Asterisk. Se regresa a la consola Linux y se hunden las teclas CTRL-C para terminar la captura de paquetes por parte de Ngrep.

Ahora se abre el archivo register:

nano /tmp/register

76

Page 88: Libro Asterisk 1.8.X - Versión 1.0 (1)

Encontraremos esta secuencia:

X-Lite ------------------Register---------------> AsteriskX-Lite <-------401 Unauthorized-------------- Asterisk

En el mensaje 401 Unauthorized, Asterisk indica a X-Lite que se requiere una autentificación basada en el protocolo http digest y envía los datos necesarios para que el softphone pueda autenticarse de esta forma. X-Lite responde enviando una nueva petición de REGISTER añadiendo los datos de autentificación

X-Lite ------------------Register---------------> AsteriskX-Lite <------------------200 Ok---------------- Asterisk

Ahora el X-Llite está registrado y Asterisk puede localizarlo en el caso entre una llamada para la extensión 1000. De hecho el método REGISTER del protocolo SIP sirve para esto. Se recomienda la lectura del RFC3261 para entender como funciona la señalización SIP.

Si se continua a mirar el archivo register se notará que aparece otro bloque que utiliza el método SUBSCRIBE (RFC4235). Todo este bloque está relacionado con el buzón de voz de la extensión 1000 y es el que permite a la misma extensión suscribirse a Asterisk para recibir notificaciones cuando sea presente un nuevo mensaje en el buzón de voz.

La secuencia es:

X-Lite ------------------Subscribe-------------> Asterisk X-Lite <-------401 Unauthorized-------------- Asterisk

X-Lite ------------------Subscribe-------------> Asterisk X-Lite <------------------200 Ok---------------- Asterisk

X-Lite <-----------------NOTIFY---------------- AsteriskX-Lite ------------------200 Ok-----------------> Asterisk

Una vez que Asterisk acepte el SUBSCRIBE enviado por X-Lite, le enviará un NOTIFY para que el softphone sepa si hay mensajes en el buzón de voz. Claramente todavía no hay ninguno (ultima parte del mensaje NOTIFY enviado por Asterisk):

Messages-Waiting: no.Message-Account: sip:[email protected]: 0/0 (0/0).

En la consola de Asterisk aparecerá la extensión conectada:

asterisk -rvvvvvvvvvvvvvvvvv

CLI> sip show peersName/username Host Dyn Nat ACL Port Status1000/1000 190.255.234.54 D N 10527 OK (135 ms)

77

Page 89: Libro Asterisk 1.8.X - Versión 1.0 (1)

Otra forma de ver los mensajes SIP es activar el sip debug en Asterisk. Se puede hacer de forma general:

CLI> sip set debug onSIP Debugging re-enabled

o solamente para una extensión/troncal especifica:

CLI> sip set debug peer 1000SIP Debugging Enabled for IP: 190.255.234.54:10527

CLI> sip set debug peer justvoipSIP Debugging Enabled for IP: 77.72.169.129:5060

3.6 Softphone 3CX

Se instalará un segundo softphone para las pruebas. En este caso 3CX. Se descarga, se instala y se inicia:

Se presiona el botón evidenciado y, en la pantalla que sigue, se selecciona el icono Conexión:

78

Page 90: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la nueva ventana se presiona el botón New y se configura la extensión 1001:

Terminada la configuración se presiona el botón OK y nuevamente OK. La extensión se registrará a Asterisk:

CLI> sip show peersName/username Host Dyn Nat ACL Port Status1000/1000 190.255.234.54 D N 10527 OK (134 ms)

79

Page 91: Libro Asterisk 1.8.X - Versión 1.0 (1)

1001/1001 190.255.234.54 D N 10870 OK (220 ms)

3.7 Llamadas entre extensiones

Si desde la extensión 1000 se llama la extensión 1001, en la consola de Asterisk aparecerá:

NOTICE[29214]: chan_sip.c:20785 handle_request_invite: Call from '1000' to extension '1001' rejected because extension not found in context 'externas'

Esto porque no se ha configurado todavía el Dialplan para permitir las llamadas entre las extensiones.

nano /etc/asterisk/extensions.conf

y al final del contexto internas se añaden las siguientes lineas:

exten => _100[0-2],1,Dial(SIP/${EXTEN},30)same => n,Hangup

En la primera linea, después del comando exten => la “_” indica que se está utilizando un Pattern-matching. En el párrafo 7.2 se explicará cosa son y como se utilizan los Pattern-matching. En este ejemplo [0-2] significa que la cuarta cifra puede ser uno 0 un 1 o un 2. De esta formas si marcamos 1000 1001 o 1002 todas las llamadas entrarán en esta parte del dialplan. 1 es la prioridad y Dial es la aplicación que se utiliza para iniciar una llamada. La sintaxis es:

Dial(Technology/Resource[&Technology2/Resource2[&...]][,timeout[,options[,URL]]])

En este caso Technology es SIP, resource es ${EXTEN} y timeout es 30 segundos. La variable ${EXTEN} es una variable de canal (los distintos tipos de variables se presentarán en el párrafo 7.1) y contendrá el numero marcado. Si nadie contesta dentro de 30 segundos la llamada terminará (Hangup).

El proveedor Justvoip requiere que la sintaxis para marcar cualquier numero sea: 00 + código país + numero. Para poder utilizar el proveedor para las llamadas salientes, después del contexto internas se crea el contexto internacio y se añaden las siguientes lineas:

[internacio]exten => _00.,1,Dial(SIP/justvoip/${EXTEN},30)same => n,Hangup

Como se quiere que solamente las extensiones configuradas con el contexto externas tengan acceso a este contexto se añade esta linea al contexto externas:

include => internacio

para que el bloque quede:

[externas]

80

Page 92: Libro Asterisk 1.8.X - Versión 1.0 (1)

include => internasinclude => internacio

Se guardan los cambios y se recarga el dialplan.

asterisk -rvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se marca el numero 1001. El resultado en la consola de Asterisk será:

Executing [1000@externas:1] Dial("SIP/1000-00000001", "SIP/1000,30") in new stack

y en el teléfono 3CX:

3.8 SIP INVITE y CANCEL

El método SIP que se utiliza para iniciar una sesión media, es INVITE. Para ver como funciona se hará la traza de una llamada con ngrep. En la ventana terminal del servidor se escribe:

ngrep 1000 -W byline port 5060 > /tmp/invite

Luego desde la extensión 1000 se llama la extensión 1001. Se contesta la llamada y después de unos segundos se cuelga. Se vuelve a la ventana terminal y se termina la captura de los paquetes con CTRL-C

En el archivo invite estará presente esta secuencia:

X-Lite Asterisk 3CX

----------------INVITE---1001-----> <-------401 Unauthorized-----------

----------------ACK------------------>----------------INVITE---1001-----><------------100 Trying--------------

------------INVITE 1000--------><--------180 Ringing--------------

<------------180 Ringing-------------

81

Page 93: Libro Asterisk 1.8.X - Versión 1.0 (1)

<------------200 OK---------------------------------ACK--------------->

<---------------200 OK---------------------------------ACK------------------>

<----------------BYE--------------------------------200 OK------------->

<----------------BYE------------------------------------200 OK------------------->

El X-LIte envía un INVITE para la extensión 1001 a Asterisk. Asterisk contesta diciendo que para aceptar el INVITE, X-Lite tiene que autenticarse. X-Lite contesta con ACK confirmando que ha recibido la respuesta de Asterisk; luego envía otro INVITE con sus datos de autentificación. Asterisk contesta con un Trying (probando) y envía el INVITE al 3CX que contesta con un 180 Ringing (timbrando). Asterisk devuelve el 180 Ringing a X-Lite. Cuando la extensión 1001 contesta la llamada genera un 200 OK y Asterisk un ACK confirmando que ha recibido el 200 OK. Asterisk envía el 200 OK a X-Lite y cuando este confirma la recepción del mensaje con un ACK inicia la sesión media (en este caso solo audio) entre las dos extensiones. Cuando la extensión 1001 cuelga se genera un BYE que es recibido por Asterisk que contesta con un 200 OK. Asterisk envía el BYE al X-Lite que contesta con un 200 OK. A partir de este momento termina realmente la llamada.

Una segunda prueba es que la extensión 1000 cuelgue antes que la extensión 1001 conteste. En la ventana terminal de linux se escribe:

ngrep 1000 -W byline port 5060 > /tmp/cancel

Luego desde la extensión 1000 se llama la extensión 1001 y después de unos segundos se cuelga. Se vuelve a la ventana terminal y se termina la captura de los paquetes con CTRL-C. Analizando el archivo cancel, esta es la secuencia:

X-Lite Asterisk 3CX

----------------INVITE---1001-----> <-------401 Unauthorized-----------

----------------ACK------------------>----------------INVITE---1001-----><------------100 Trying--------------

------------INVITE 1000--------><--------180 Ringing--------------

<------------180 Ringing-----------------------------BYE-------------------><--------------200 OK-----------------<-------487 Request Terminated---------------------ACK----------------->

--------------CANCEL----------->

82

Sesion Media

Page 94: Libro Asterisk 1.8.X - Versión 1.0 (1)

<-------------200 OK--------------<----- 487 Request Terminated-------------------ACK---------------->

Ahora para probar el proveedor SIP se marca, desde la extensión 1000, un numero internacional (por ejemplo la linea de atención al cliente de Avianca):

005714013434

Si se intenta marcar el mismo numero, como se verá más adelante, desde la extensión 1002 no funcionará ya que esa extensión no tiene acceso al contexto internacio:

NOTICE[10455]: chan_sip.c:20785 handle_request_invite: Call from '1002' to extension '005714013434' rejected because extension not found in context 'locales'.

De esta forma podemos controlar las extensiones que tienen acceso a las llamadas salientes.

83

Page 95: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 96: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO IV

Protocolo IAX2 – iax.conf

El protocolo IAX (ahora IAX2) ha sido desarrollado por Mark Spencer, quien empezó a escribir el código de Asterisk PBX y actual gerente de la empresa Digium. La idea detrás de IAX era crear un protocolo que pudiera utilizar el mismo puerto para la señalización y la sesión media, eliminando, de esta forma, los problemas relacionados con el NAT que padece el protocolo SIP. De hecho IAX2 utiliza el puerto estándar 4569 UDP para la señalización y el transporte de la sesión media. A pesar de haber sido aceptado por la IETF y haberse vuelto un estándar de hecho (RFC5456) son muy pocos los proveedores que ofrecen este tipo de conexión y los teléfonos que lo soportan.

Una funcionalidad interesante de este protocolo y que quizás puede ser útil implementar en una instalación de Asterisk, es la del trunking, que permite utilizar un único “trunk” para distintos flujos media, reduciendo de hecho, el ancho de banda necesario. Para que el trunking sea utilizable en Asterisk, DAHDI tiene que ser instalado porque es la fuente de sincronización que IAX2 necesita para funcionar en esta modalidad.

4.1 iax.conf

Este archivo, como el sip.conf, se divide en tres bloques:

• Una parte general donde se configuran los parámetros del protocolo• Un bloque central donde se configuran los registros a proveedores IAX2 o otro servidores

Asterisk• Un bloque final dedicado a la configuración de las extensiones

En la columna descripción aparecerá en negrita el valor del parámetro. Al final del modulo, toda la configuración del archivo.

Parámetro Descripción[general] Esta etiqueta define el inicio de la parte general de la configuración del

protocolo IAX2bindport El puerto UDP usado por este protocolo. Este parámetro va

configurado antes del bindaddr. Valor 4569bindaddr Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha

para las señalización IAX2 utilizando el protocolo UDP. Si se indica 0.0.0.0 Asterisk escuchará en todas la direcciones IP presentes en el servidor Linux. Valor: 0.0.0.0

nochecksums no=no se realiza la suma de verificación de los paquetes UDPdelayreject yes=mejora la seguridad contra “brute force password attacks”

retrasando el envío de los rechazos de autentificaciónamaflags Automated Message Accounting. Con este parámetro se configura un

Page 97: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripcióncampo del CDR (call data records) univoco para todas las llamadas. Este campo se puede personalizar en cada extensión. Valor: documentation

srvlookup yes=Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas SIP salientes del tipo: IAX2/usuario@dominio.

language es=el idioma predefinido para las locucionesmohinterpret clase de música de espera predefinida – defaultmohsuggest Clase de música de espera cuando un canal de tipo peer se pone en

espera – defaultbandwidth Con este parámetro se define el ancho de banda disponible para las

llamadas y en base a este se escogerán los codecs audio a utilizar entre los configurados. Este parámetro acepta como valores: low, medium, high

disallow all – Se desactivan todos los codec audio y videoallow Se indican los codec audio y video utilizables. Pueden ser indicados

uno por linea o en la misma linea separados por una coma:allow=alawallow=ulawoallow=alaw,ulaw

minregexpire 60=tiempo mínimo de espiración del registro de las troncales IAX2maxregexpire 60=tiempo máximo de espiración del registro de las troncales IAX2encryption yes=se habilita el cifrado de la señalización y del flujo mediaforceencryption no=no se fuerza el uso del cifradotrunkmaxsize define el tamaño máximo de los datos (bytes) que pueden pasar por una

troncal IAX2 cuando se configura el parámetro trunk=yes. Con 128000 bytes pasarán por la troncal 800 llamadas con codec alaw y paquetes audio de 20ms

trunkmtu cuando el trafico que pasa por una troncal IAX2 es bastante alto, si los paquetes UDP los fragmenta el sistema operativo Linux, hay la posibilidad que se verifique una mala calidad del audio. Configurando este parámetro con el valor 1240, significa que será el mismo Asterisk el que se encargará de fragmentar los paquetes audio más grandes de 1240 byte, mejorando la calidad del audio en las conversaciones

autokill yes=si no se recibe un ACK después de una NEW enviado dentro de 2000ms, para evitar que el servidor Asterisk se estanque, se anula la solicitud

codecpriority Controla quien tiene la prioridad en la negociación de los codec audio.

86

Page 98: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro DescripciónPuede ser:

• caller• host• disabel

rtcachefriends Este parámetro aplica cuando las extensiones están configuradas en una base de datos (se verá más adelante). Valor no

rtupdate este parámetro también aplica cuando las extensiones están configuradas en una base de datos. Cuando una de estas extensiones se registre a Asteirsk, en la base de datos se guardará la dirección IP, el puerto, el tiempo de registro y el nombre de usuario. Valor yes

parkinglot Asterisk, entre sus funcionalidades, permite parquear una llamada. Como desde la versión 1.6.X es posible configurar más de un “contexto” de parqueo, en este parámetro se indica el predefinido. Valor: default

calltokenoptional En septiembre del 2009 hubo una actualización del protocolo IAX2 para mejorar la seguridad. Este parámetro con el que sigue hace referencia a esa nueva implementación. Como la mayoría de los teléfonos IAX no la soportan se indica que es opcional para todas las direcciones IP. 0.0.0.0/0.0.0.0

requirecalltoken auto=se requiere el calltoken solo si el teléfono lo soportaregister => El segundo bloque empieza con las lineas de register. Algunos

ejemplos:• register => marko:[email protected]

Registro con nombre usuario, contraseña y dominio• register => joe@remotehost:5656

Registo con nombre, dominio y puerto remoto (sin contraseña)• register => marko:[key]@tormenta.linux-support.net

Registro con nombre, clave RSA (key) y dominio

En en tercero y ultimo bloque se configuran las troncales/extensiones IAX2. Por ahora se configurará solamente una extensión. Más adelante se verá como configurar una troncal y utilizar IAX2 para el envío de FAX utilizando IAXmodem y Hylafax.

Parametro Descripción[marko] Nombre de la extensióntype friend Puede ser peer y userhost Si la extensión se conecta remotamente con un IP

dinámico se pone dynamic. En caso contrario se pone la dirección IP

87

Page 99: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parametro Descripciónsecret La contraseña para la extensión. Valor

predefinido: pbx9094context El contexto a que tendrá acceso la extensión.

Valor externasmailbox Si este parámetro es configurado, cuando la

extensión se conecte al servidor Asterisk, éste controlará si hay mensajes de voz pendientes y en caso positivo se lo comunicará usando MWI = Message Waiting Indicator. que es una señal audio o vídeo que puede ser recibida por la mayoría de los teléfonos IP o Softphone Valor 1234@default

qualify Este parámetro se utiliza para mantener activa la conexión de una extensión que se conecta al servidor Asterisk detrás de una NAT. Valor Yes

callerid markorequirecalltoken Véase parte general. Valor auto

Para crear el archivo de configuración de iax.conf, se renombra el predefinido y se crea uno nuevo:

mv /etc/asterisk/iax.conf /etc/asterisk/iax.conf.old

nano /etc/asterisk/iax.conf

Se copian las siguientes lineas:

[general]bindport=4569bindaddr=0.0.0.0nochecksums=nodelayreject=yesamaflags=documentationsrvlookup=yeslanguage=esmohinterpret=defaultmohsuggest=defautlbandwidth=highdisallow=allallow=alawallow=alawminregexpire=60maxregexpire=60encryption=yesforceencryption=no

88

Page 100: Libro Asterisk 1.8.X - Versión 1.0 (1)

trunkmaxsize=128000trunkmtu=1240autokill=yescodecpriority=hostrtcachefriends=nortupdate=yesparkinglot=defaultcalltokenoptional=0.0.0.0/0.0.0.0requirecalltoken=auto

;register => marko:[email protected];register => joe@remotehost:5656 ;register => marko:[key]@tormenta.linux-support.net

[marko]type=friendhost=dynamicsecret=pbx9094context=externasmailbox=1234@defaultqualify=yescallerid=markorequirecalltoken=auto

Se guardan los cambios y se actualiza la configuración de IAX2:

asterisk -rvvvvvvvvvvvvvvv

CLI> iax2 reload

Para ver la configuración de la extensión recién creada:

CLI> IAX2 show peer marko

* Name : marko Secret : <Set> Context : externas Parking lot : Mailbox : 1234@default Dynamic : Yes Callnum limit: 0 Calltoken req: Auto Trunk : No Encryption : (aes128,keyrotate) Callerid : "marko" <> Expire : -1 ACL : No

89

Page 101: Libro Asterisk 1.8.X - Versión 1.0 (1)

Addr->IP : (Unspecified) Port 0 Defaddr->IP : 0.0.0.0 Port 4569 Username : Codecs : 0x8 (alaw) Codec Order : (alaw) Status : UNKNOWN Qualify : every 60000ms when OK, every 10000ms when UNREACHABLE (sample smoothing Off)

Para una lista de los comandos disponibles para el protocolo IAX2:

CLI> help IAX2

4.2 Softphone Zoiper

Para conectarse a la extensión recién creada en el archivo iax.conf, se utilizará el softphone Zoiper. Se descarga y se instala. Una vez instalado se escoge el menú Settings -> Preferences

en la ventana que aparece se elige "Create New IAX account"

90

Page 102: Libro Asterisk 1.8.X - Versión 1.0 (1)

se pone el nombre de la cuenta (marko) y se hunde el botón OK:

Se ponen los datos come definidos en el archivo di configuración iax.conf y se hunde el botón Register. Luego el botón OK que aparece al fondo de la ventana. Se entra nuevamente en el Menú "Settings -> Preferences":

Se escoge el usuario marko:

En alto a la derecha, aparecerá la voz "Registered". También en la consola de Asterisk el usuario aparecerá registrado:

CLI> IAX2 show peersName/Username Host Mask Port Status

91

Page 103: Libro Asterisk 1.8.X - Versión 1.0 (1)

marko 190.254.129.133 (D) 255.255.255.255 26599 (E) OK (127 ms)1 iax2 peers [1 online, 0 offline, 0 unmonitored]

CLI> quit

Ya que en Zoiper se pueden configurar también extensiones SIP, se configura la extensión 1002:

Se presiona el botón o ok y en la nueva ventana se ponen los datos de conexión:

Se presiona el botón register y el botón ok que aparece al fondo de la pagina. Se averigua que la extensión esté conectada:

asterisk -rvvvvvvvvvvvvvvv

CLI> sip show peersName/username Host Dyn Nat ACL Port Status1000/1000 190.254.129.133 D N 27174 OK (125 ms)1001/1001 190.254.129.133 D N 27256 OK (250 ms)1002/1002 190.254.129.133 D N 5060 OK (137 ms)justvoip/pbx2020 77.72.169.129 5060 OK (161 ms)4 sip peers [Monitored: 4 online, 0 offline Unmonitored: 0 online, 0 offline]

CLI> quit

92

Page 104: Libro Asterisk 1.8.X - Versión 1.0 (1)

A partir de este momento, todas las extensiones SIP y IAX2 están conectadas al servidor Asterisk. Los iconos de los tres softphone:

Ahora la pregunta: ¿Cómo se configura el dialplan para que se pueda llamar el usuario marko ya que la extensión no es un numero sino un nombre?

Se hace de la siguiente manera:

nano /etc/asterisk/extensions.conf

al final del contexto internas se añade:

exten => 1234,1,Dial(IAX2/marko,30)same => n,Hangup

Se guardan los datos y se recarga el dialplan

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se marca 1234. El resultado en la consola de Asterisk:

Executing [1234@externas:1] Dial("SIP/1000-00000007", "IAX2/marko,30") in new stack

El resultado en Zoiper:

De esta forma se ha hecho la prueba de una llamada entre dos teléfonos con distintos protocolos.

93

Page 105: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 106: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO V

GoogleTalk – gtalk.conf jabber.conf

Como se ha visto a lo largo de la instalación de Asterisk, la centralita soporta el protocolo XMMP que permite conectarla a servidores que utilizan ese protocolo. En Asterisk el modulo relacionado es el res_jabber.so.

Para ver si efectivamente este modulo ha sido compilado y instalado correctamente, se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvv

Primero se controla que el modulo exista:

CLI> module show like res_jabberModule Description Use Countres_jabber.so AJI - Asterisk Jabber Interface 01 modules loaded

luego se quita y se vuelve a cargar para controlar eventuales errores:

CLI> module unload res_jabber.so == Unregistered application 'JabberSend' == Unregistered application 'JabberSendGroup' == Unregistered application 'JabberStatus' == Unregistered application 'JabberJoin' == Unregistered application 'JabberLeave' == Manager unregistered action JabberSend == Unregistered custom function JABBER_STATUS == Unregistered custom function JABBER_RECEIVE > JABBER: Disconnecting

CLI> module load res_jabber.so == Parsing '/etc/asterisk/jabber.conf': == Found == Manager registered action JabberSend == Registered application 'JabberSend' == Registered application 'JabberSendGroup' == Registered application 'JabberStatus' == Registered application 'JabberJoin' == Registered application 'JabberLeave' == Registered custom function 'JABBER_STATUS' == Registered custom function 'JABBER_RECEIVE' Loaded res_jabber.so => (AJI - Asterisk Jabber Interface)

Al cargar un modulo aparecen las aplicaciones y las funciones que ese modulo activa.

Page 107: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se sale de la consola:

CLI> quit

Para la configuración de un usuario GoogleTalk en Asterisk además del modulo res_jabber.so, hay que configurar el modulo chan_gtalk que es el que permite llamadas de este tipo:

• Asterisk → GoogleTalk• GoogleTalk → Asterisk• Asterisk → GoogleVoice

Esto significa que se podrán recibir llamadas de usuarios GoogleTalk en Asterisk y luego, a través de la configuración del dialplan, enrutarlas a cualquier extensión configurada en la PBX. Siempre configurando adecuadamente el dialplan será posible, desde una extensión, llamar usuarios GoogleTalk y efectuar llamadas utilizando el servicio GoogleVoice. Para la configuración se aconseja crear una nueva cuenta en Google.

5.1 jabber.conf y gtalk.conf

Se empieza con el archivo de configuración jabber.conf. Como siempre en la columna descripción, en negrita, aparecen los valores que hay que configurar. Al final de las tablas, la configuración de los dos archivos.

Parámetro Descripción[general] etiqueta que define el inicio de la parte generaldebug no=no se activa el debug en la consola de Asterisk

yes=se activa el debug en la consola de Asteriskautoprune yes=elimina automáticamente los usuario de la lista de amigos

no=no elimina automáticamente los usuarios de la lista de amigos

autoregister yes=si un usuario añade el usuario configurado en este archivo a su lista de amigos, Asterisk automáticamente lo añadirá a la lista de amigosno=no lo añade automáticamente

;collection_nodes=yes A partir de la versión 1.8 de Asterisk es posible monitorear el estado de las extensiones remotas utilizando el protocolo XMPP. Este parámetro indica si se habilita el soporte para la especificación XEP-048 del protocolo XMPP. Se deja comentado

;pubsub_autocreate=yes Este parámetro especifica si los nodos para el monitoreo de las extensiones remotas se crean en automático o no. Se deja comentado.

96

Page 108: Libro Asterisk 1.8.X - Versión 1.0 (1)

;auth_policy=accept=yes La especificación XEP-048 se basa en un sistema de suscripciones que los usuarios activan para recibir actualizaciones. Con este parámetro en yes las suscripciones de los usuarios se aceptan en automático. Se deja comentado

[campus.voztovoice] A partir de esta etiqueta, la configuración del usuario GoogleTalk. Suponiendo que el usuario creado es [email protected], en la etiqueta se pone el nombre de usuario. Personalizar con el nombre del usuario google creado.

type puede ser client o componentserverhost dominio del servidor GoogleTalk. Valor: talk.google.com;pubsub_node=pubsub.dominio.com Nombre del nodo para publicar los eventos para la

configuración del monitoreo de extensiones remotas. Se deja comentado

username El nombre del usuario creado en Google. En este ejemplo [email protected]. Personalizar

secret la contraseña asociada al usuario creado en Google. Personalizarport 5222 Es el puerto que utiliza GoogleTalk para aceptar

conexionesusetls yes=se activa el protocolo TLS. De esta forma todos los

paquetes intercambiados entre cliente y servidor serán cifradosusesasl yes=se activa el protocolo sasl. Sasl es un protocolo de

autentificación y autorización que permite la negociación de protocolos de cifrado entre cliente y servidor.

buddy si se quiere añadir un amigo a la lista de amigos directamente desde la configuración del archivo se indica en este parámetro. Si los amigos que se quieren añadir son distintos, se pone una linea con este parámetro para cada amigo. Para este ejemplo se pone [email protected] en esta linea.

;distribute_events=yes Se especifica si esta conexión se utilizará o no para la generación de eventos en la configuración del monitoreo de las extensiones remotas. Se deja comentado

statusmessage Mensaje de estado que aparecerá junto al nombre de usuario. Valor: Asterisk Server

timeout 100=tiempo máximo para la entrega de un mensaje (en segundos)

Terminada la configuración del archivo jabber.conf, se continua con el archivo gtalk.conf. En la columna descripción, en negrita, aparecen los valores que hay que configurar.

97

Page 109: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Desc[general] inicia la parte general del archivocontext contexto del dialplan donde entrarán las llamadas

de los usuarios GoogleTalk. Valor: google-inbindaddr dirección ip para la escucha de peticiones

GoogleTalk. Se configura para que escuche en todas las direcciones presentes en el servidor. Valor: 0.0.0.0

externip A partir de la versión 1.8 de Asterisk se ha añadido este parámetro, que permite definir la IP publica del servidor. Se pone la IP de Linode

allowguest no=no se permiten llamadas de usuarios GoogleTalk que no estén en la lista de amigosyes=se permiten

[guest] a partir de esta etiqueta empieza la configuración para los usuarios huéspedes (que no están en la lista de amigos).

disallow all=se desactivan todos los codec audioallow alaw=se activa el codec audio alawcontext google-in=nombre del contexto del dialplan donde

llegarán las llamadas de usuarios huéspedesconnection se pone la etiqueta definida en el jabber.conf para

el usuario GoogleTalk configurado en Asterisk. en este ejemplo es campus.voztovoice. Personalizar

[voztovoicenet] a partir de esta linea, se definen todos los amigos que se quiere tener en la lista. Para un ejemplo real el usuario es voztovoicenet.

username nombre del usuario: [email protected] all=se desactivan todos los codec audioallow alaw=se activa el codec audio alawconnection se pone la etiqueta definida en el jabber.conf para

el usuario GoogleTalk configurado en Asterisk. en este ejemplo es campus.voztovoice. Personalizar

context el contexto del dialplan donde llegarán las llamadas del usuario google-in

Una vez definidos todos los parámetros de jabber.conf y gtalk.conf, se crean los respectivos archivos. Primero se renombran los predefinidos:

mv /etc/asterisk/jabber.conf /etc/asterisk/jabber.conf.old

98

Page 110: Libro Asterisk 1.8.X - Versión 1.0 (1)

mv /etc/asterisk/gtalk.conf /etc/asterisk/gtalk.conf.old

Luego se crea el archivo jabber.conf:

nano /etc/asterisk/jabber.conf

se pegan las siguientes lineas:

[general]debug=yesautoprune=noautoregister=yes;collection_nodes=yes;pubsub_autocreate=yes;pubsub_autocreate=yes

[campus.voztovoice]type=clientserverhost=talk.google.com;pubsub_node=pubsub.dominio.comusername=campus.voztovoice@gmail.comsecret=passwordport=5222usetls=yesusesasl=yesbuddy=voztovoicenet@gmail.com;distribute_events=yesstatusmessage=Asterisk Servertimeout=100

IMPORTANTE: antes de guardar la configuración, hay que personalizar los parámetros username, secret y la etiqueta [campus.voztovoice], con los datos de su cuenta Google.

Se pasa al archivo gtalk.conf

nano /etc/asterisk/gtalk.conf

[general]context=google-inbindaddr=0.0.0.0externip=IPasteriskallowguest=yes

99

Page 111: Libro Asterisk 1.8.X - Versión 1.0 (1)

[guest]disallow=allallow=alawcontext=google-inconnection=campus.voztovoice

[voztovoicenet][email protected]=allallow=alawconnection=campus.voztovoicecontext=google-in

IMPORTANTE: antes de guardar la configuración, hay que personalizar el parámetro connection con la etiqueta inicial de la configuración del usuario GoogleTalk en el archivo jabber.conf (en este ejemplo campus.voztovoice) y el parámetro externip.

Terminada la configuración de los dos archivos se entra en la consola de Asterisk y se recargan los dos módulos; primero res_jabber.so y luego chan_gtalk.so:

asterisk -rvvvvvvvvvvvvv

CLI> module unload res_jabber.so

CLI> module unload chan_gtalk.so

CLI> module load res_jabber.so

CLI> module load chan_gtalk.so

Después de algunos segundos, el usuario debería estar conectado:

CLI> jabber show connectionsJabber Users and their status: User: [email protected] - Connected---- Number of users: 1

Para ver la lista de amigos conectados ([email protected])

CLI> jabber show buddiesJabber buddy listsClient: [email protected] Buddy: [email protected] Resource: talk5D9E1034 node: http://www.asterisk.org/xmpp/client/caps version: asterisk-xmpp

100

Page 112: Libro Asterisk 1.8.X - Versión 1.0 (1)

Jingle capable: yes Status: 1 Priority: 10

Para una lista de comandos disponibles en los dos módulos

CLI> help jabber jabber create collection Creates a PubSub node collection. jabber create leaf Creates a PubSub leaf node jabber delete node Deletes a PubSub node jabber list nodes Lists PubSub nodes jabber purge nodes Purges PubSub nodes jabber reload Reload Jabber configuration jabber set debug {on|off} Enable/Disable Jabber debug jabber show buddies Show buddy lists of our clients jabber show connections Show state of clients and components jabber test Shows roster, but is generally used for mog's debugging.

CLI> help gtalk gtalk show channels Show GoogleTalk channels

Por ultimo si se entra en GoogleTalk con otro nombre de usuario y se añade a la lista de amigos el usuario configurado en Asterisk (en este ejemplo [email protected]), el resultado será:

El icono del teléfono que aparece, indica que se puede tener una conversación audio con ese usuario.

Ahora se pasa al dialplan. Como contexto para las llamadas entrantes de usuarios GoogleTalk, se ha definido google-in. Este contexto va creado en el dialplan:

nano /etc/asterisk/extensions.conf

Después del bloque internas se añaden estas lineas.

[google-in]exten => s,1,NoOp( Call from Gtalk )same => n,Dial(SIP/1000,30)same => n,Hangup()

Todas las llamadas que entren desde GoogleTalk se desvían a la extensión 1000. Si dentro de treinta segundos la extensión 1000 no contesta, la llamadas terminará

Para las llamadas salientes se pone al final del contexto internas:

101

Page 113: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => _[a-z].,1,Dial(gtalk/campus.voztovoice/${EXTEN},30)same => n,Hangup

Una explicación de las dos lineas: Se dice a Asterisk de llamar a través del canal gtalk, usando la conexión campus.voztovoice que es la etiqueta que inicia el bloque de configuración del usuario [email protected]. Con _[a-z]. se puede marcar a cualquier usuario GoogleTalk cuyo nombre empieza con una letra del alfabeto (de a a z). Si después de 30 segundos, nadie contesta, se termina la llamada.

Para que esto funcione, hay que añadir un bloque nuevo en el archivo gtalk.conf para cada nuevo usuario siguiendo las mismas pautas utilizadas para configurar el usuario [email protected]. En el caso que se quiera llamar un usuario no configurado en gtalk.conf, hay que añadirlo de esta forma en el dialplan (contexto internas):

exten => 10000,1,Dial(gtalk/campus.voztovoice/[email protected],30)same => n,Hangup

suponiendo que [email protected] es el usuario que se quiera llamar. Se guardan los cambios. Otra forma de actualizar el dialplan sin entrar en la consola de Asterisk es:

asterisk -rx "dialplan reload"Dialplan reloaded.

Se puede hacer una primera prueba llamando el usuario [email protected] desde el X-LIte

Se marca de esta manera:

Se presiona el botón “Call”. El resultado:

Para llamar al usuario [email protected] se marcará la extensión 10000 desde X-Lite. Como nota utilizando el cliente GoogleTalk en un celular Android, es posible efectuar llamadas al usuario configurado en Asterisk pero no es posible (hasta el momento) recibirlas.

5.2 Google Voice

Google Voice es el servicio de Google que permite efectuar llamadas a cualquier parte del mundo. Esta

102

Page 114: Libro Asterisk 1.8.X - Versión 1.0 (1)

funcionalidad es disponible en la pagina personal de la cuenta Google:

Desde la versión 1.8.X de Asterisk, es posible efectuar llamadas utilizando una cuenta Google Voice. Para llamar, por ejemplo, a Estados Unidos, la sintaxis es +1 más el numero a llamar. En el contexto internacio del dialplan:

nano /etc/asterisk/extensions.conf

se añade:

exten => _1XXXXXXXXXX,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

Como se puede ver el + se pone delante de la variable ${EXTEN} (+${EXTEN}). De esta forma no hace falta marcarlo.

Para las llamadas a cualquier otro país la sintaxis es + código país numero. En el mismo contexto internacio se añade:

exten => _NNXX.,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

5.3 Aplicación JabberSend

Una aplicación que se activa con el modulo res_jabber.conf es “JabberSend” que permite enviar mensajes instantáneos a usuarios GoogleTalk.

La sintaxis de la aplicación es:

103

Page 115: Libro Asterisk 1.8.X - Versión 1.0 (1)

JabberSend(Jabber,JID,Message)

Un ejemplo. Cada vez que una extensión llame la extensión de la música en espera, queremos enviar un mensaje a un usuario GoogleTalk para que se entere. Se modifica el dialplan:

nano /etc/asterisk/extensions.conf

se cambia este bloque:

exten => 200,1,Answersame => n,MusicOnHold(mp3,60)same => n,Hangup

para que quede:

exten => 200,1,Answersame => n,Jabbersend(campus.voztovoice,[email protected],Estamos escuchando MP3)same => n,MusicOnHold(mp3,60)same => n,Hangup

Cambiar “campus.voztovoice” con la etiqueta que define el usuario configurado en el archivo jabber.conf; cambiar el usuario [email protected] con el usuario Gmail al que se quiere enviar el mensaje. Se guardan los cambios y se recarga el dialplan:

asterisk -rx "dialplan reload"

Desde la extensión 1000 se marca la extensión 200. El resultado:

5.4 La función JABBER_RECEIVE

La función JABBER_RECEIVE ha sido añadida en la versión 1.8 de Asterisk. Esta función permite interactuar con un usuario Google Talk a través del envío y recepción de mensajes de textos. Para el envío de mensajes de texto se utiliza la aplicación SendText que permite, cuando un canal ya está conectado, enviar texto a ese canal.

104

Page 116: Libro Asterisk 1.8.X - Versión 1.0 (1)

La sintaxis de la función es:

asterisk -rvvvvvvvvvvvvvv

CLI> core show function JABBER_RECEIVE

JABBER_RECEIVE(account,jid[,timeout])

• account, es la etiqueta definida para el usuario Google Talk configurado en el archivo jabber.conf (en este caso campus.voztovoice)

• jid, es el nombre del usuario Google Talk con el que se quiere interactuar• timeout, es el tiempo, en segundos, que tendrá el usuario Google Talk para escribir una

respuesta

Un ejemplo sencillo, para que se vea como funciona, es enviar un mensaje de texto a un usuario Google Talk para pedirle su nombre y luego almacenar su respuesta en una variable.

Para efectuar la prueba, se modifica el dialplan:

nano /etc/asterisk/extensions.conf

este bloque:

[google-in]exten => s,1,NoOp( Call from Gtalk )same => n,Dial(SIP/1000,30)same => n,Hangup()

para que quede:

[google-in]exten => s,1,NoOp( Call from Gtalk )same => n,SendText(Hola,Como te llamas?)same => n,Set(nombre=${JABBER_RECEIVE(campus.voztovoice,${CALLERID(name)},20)})same => n,SendText(Hola ${nombre}, bienvenido en VozToVoice)same => n,Set(CALLERID(name)=${nombre})same => n,Wait(2)same => n,SendText(Espera un momento mientras te comunicamos con un operador)same => n,Dial(SIP/1000,30)same => n,Hangup()

La variable ${CALLERID(name)} contendrá el nombre del usuario Google Talk.

Se guardan los cambios y se recarga el dialplan:

asterisk -rx "dialplan reload"

105

Page 117: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora desde un usuario GoogleTalk, se llama el usuario configurado en Asterisk. En la ventana de chat de Google Talk:

En el X-Lite:

Aparecerá como callerid, el nombre que el usuario ha digitado en la ventana de chat de Google Talk. Este es un ejemplo muy sencillo. Posibles aplicaciones de esta función:

• Brindar a los usuarios Google Talk, la posibilidad de crear una extensión en Asterisk digitando todos los parámetros relacionados

• crear un IVR textual que permita al usuario GoogleTalk escoger una opción que, por ejemplo, lo ponga en comunicación con un determinado departamento de la empresa

• Solicitar al usuario Google Talk dos números a llamar y luego desde Asterisk comunicarlos entre ellos.

106

Page 118: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 119: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO VI

Asterisk y la red PSTN

Asterisk puede ser conectado a la red telefónica tradicional a través de tarjetas telefónica o Gateway. Estos dispositivos pueden ser de distintos tipos:

• Tarjetas o Gateway FXO• Tarjetas o Gateway FXS• Tarjetas o Gateway mixtos (FXO-FXS)• Tarjetas o Gateway BRI (ISDN)• Tarjetas o Gateway PRI (primarios E1, T1, J1)• Tarjetas o Gateway GSM/UMTS

FXO (Foreign Exchange Office) es un dispositivo de computador que permite conectar éste a la RTB, y mediante un software especial, realizar y recibir llamadas de teléfono.

FXS (Foreign Exchange Station) es un dispositivo de computador que permite conectar éste a un teléfono analógico.

Los dispositivos Mixtos FXO/FXS combinan los dos tipos de conexiones según las necesidades del adquirente. Un ejemplo de dispositivo FXO/FXS es la tarjeta Digium TDM410 que permite instalar un total de 4 módulos, sean FXO o FXS.

Los dispositivos BRI (Basic rate interface) permiten conectar una linea ISDN (Integrated Services Digital Network) al servidor Asterisk.. Las lineas ISDN están compuestas por dos canales audio (de 64Kbit/s cada uno) y un canal (D) para la señalización con la central telefónica (de 16 Kbit/s).

Los dispositivos E1, T1, J1, que también se pueden denominar primarios, son lineas digitales que según el tipo brindan de 23 (T1) o 30 (E1) canales de voz. En la T1 los canales 0 y 24 son reservados para la señalización. En la E1 los canales de señalización son los 0 y 16. La diversa nomenclatura de estas lineas está relacionada con los países donde se usan. T1 son la lineas disponibles en Estados Unidos, E1 en Europa y gran parte de latino américa, J1 en Japón.

En este capitulo se verá como instalar las siguientes tarjetas:

• Digium TDM410 con 4 puertos FXO• Digium TE120 (E1)

y los siguientes programas:

• OSLEC para la cancelación de eco• El driver Wanpipe para tarjetas Sangoma• La librería open2r para la señalización de primarios que se utiliza en algunos países de latino

américa (entre ellos México, Brasil y Argentina).

Page 120: Libro Asterisk 1.8.X - Versión 1.0 (1)

6.1 Tarjeta Digium TDM410

La tarjeta Digium TDM410 puede hospedar 4 módulos de tipo FXO y FXS. En este caso se instalará con 4 módulos FXO para cuatro lineas telefónicas analógicas.

Los pasos a seguir son:

1. Apagar el computador2. Desconectar el cable de alimentación3. Abrir el chasis del Computador4. Insertar la tarjeta en una ranura PCI disponible5. Volver a poner el chasis del computador6. Conectar el cable de alimentación al computador7. Conectar las lineas telefónicas a los puertos FXO de la tarjeta a través de un normal cable

telefónico8. Encender el computador

Normalmente CentOS reconoce automáticamente la nueva tarjeta instalada y le asigna un IRQ para que pueda comunicar con el procesador del computador. Se comprueba que la tarjeta ha sido reconocida:

lspci -n

debe aparecer:

0000:01:00.0 0200:d161:8005

Ahora se puede configurar. Antes de iniciar con la configuración se para Asterisk y luego DAHDI:

/etc/init.d/asterisk stop

/etc/init.d/dahdi stop

El primer archivo que hay que modificar es el /etc/dahdi/system.conf

109

Page 121: Libro Asterisk 1.8.X - Versión 1.0 (1)

En ese archivo se define, entre otras cosas, la zona geográfica donde se va a utilizar la tarjeta. Esto sirve para la generación de los tonos de la linea (timbrando, ocupado, congestión, etc..). Los países cuya configuración está disponibles son:

• Estados Unidos (us)• Australia (au)• Francia (fr)• Holanda (nl)• Inglaterra (uk)• Finlandia (fi)• España (es)• Japon (jp)• Noruega (no)• Austria (at)• Nueva Zelanda (nz)• Italia (it)• Grecia (gr)• Taiwan (tw)• Chile (cl)• Suecia (se)• Bélgica (be)• Singapur (sg)• Israel (il)• Brasil (br)• Hungría (hu)• Lituania (lt)• Polonia (pl)• Sudáfrica (za)• Portugal (pt)• Estonia (ee)• México (mx)• India (in)• Alemania (de)• Suiza (ch)• Dinamarca (dk)• Republica Checa (cz)• China (ch)• Argentina (ar)• Malasia (my)• Tailandia (th)• Bulgaria (bg)• Venezuela (ve)• Filipinas (ph)

110

Page 122: Libro Asterisk 1.8.X - Versión 1.0 (1)

• Rusia (ru)• Turquía (tr)• Panamá (pa)• Macao China (mo)• Costa Rica (cr)• Emiratos Árabes (ae)

Para Colombia esta configuración no está presente y para activarla hay que modificar un archivo de la fuentes de dahdi-tools:

cd /usr/src/dahdi-tools-2.6.0

nano zonedata.c

al final del archivo, antes de esta linea:

{ .zone = -1 }

se añaden las siguientes lineas:

{ .zone = 46, .country = "co", .description = "Colombia", .ringcadence = { 1500, 4000 }, .tones = { /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/250,0/250" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4500" }, { DAHDI_TONE_CONGESTION, "425/100,0/250,425/350,0/250,425/650,0/250" }, { DAHDI_TONE_CALLWAIT, "400+450/300,0/6000" }, { DAHDI_TONE_DIALRECALL, "425" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0/1000" },

{ DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/10,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, },

IMPORTANTE: El contenido de la linea DAHDI_TONE_SHUTTER tiene que estar en el mismo renglón.

111

Page 123: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se vuelve a compilar dahdi-tools:

make distclean./configuremake manuselectmakemake installmake config

se renombra el archivo predefinido:

mv /etc/dahdi/system.conf /etc/dahdi/system.conf.old

y se crea uno nuevo:

nano /etc/dahdi/system.conf

Se añaden las primeras dos lineas relacionadas con la zona geográfica:

loadzone = codefaultzone = co

Se define el tipo de señalización (fxsks para FXO y fxoks para FXS); en este caso se configuran 4 modulos FXO:

fxsks=1-4

que se puede escribir también:

fxsks=1,2,3,4

para terminar se define la cancelación de eco. Predefinida es mg2:

echocanceller = mg2,1-4

El archivo final será:

loadzone = codefaultzone = cofxsks=1-4echocanceller = mg2,1-4

Se guardan los cambios.

Para mejorar la cancelación de eco se instala OSLEC

112

Page 124: Libro Asterisk 1.8.X - Versión 1.0 (1)

6.1.1 OSLEC

El eco es generado por la reflexión del audio trasmitido que se devuelve a quien lo ha originado con un retraso que puede variar de algunos mili segundos a centenares de mili segundos. Más alto el tiempo de retraso, más fastidioso el eco. Las librerías DAHDI vienen con un cancelador de eco software que a veces no logra solucionar este tipo de problema. En estos casos la mejor solución es instalar el cancelador de eco OSLEC. OSLEC ha sido desarrollado por David Rowe, un ingeniero electrónico australiano.

¿Por qué OSLEC logra solucionar con mayor eficacia los problemas de eco?

Porque a pesar que sea un cancelador de eco de 32ms, actúa justo en los casos en que se produce este tipo de retraso. Cuando las llamadas son locales o de larga distancia, las compañías telefónicas no aplican ningún tipo de cancelación de eco y es propio en estos casos que los 32ms de OSLEC son suficientes para cancelar el eco de manera satisfactoria. Cuando las llamadas son internacionales y el eco producido considerable (centenares de ms), son las mismas compañías telefónicas que normalmente se encargan (a nivel de centrales) de eliminar el eco que se produce.

OSLEC está disponible en la fuentes del Kernel a partir de la versión 2.28

Para instalarlo se siguen estos pasos:

cd /usr/src

se descargan las fuentes del Kernel 2.6.28

wget http://www.voztovoice.org/campus/pbx05/linux-2.6.28.tar.bz2

se descomprimen:

tar -xf linux-2.6.28.tar.bz2

Se preparan las fuentes de DAHDI para la compilación de OSLEC:

mkdir /usr/src/dahdi-linux-2.6.0/drivers/staging

cp -fR /usr/src/linux-2.6.28/drivers/staging/echo /usr/src/dahdi-linux-2.6.0/drivers/staging

sed -i "s|#obj-m += dahdi_echocan_oslec.o|obj-m += dahdi_echocan_oslec.o|" /usr/src/dahdi-linux-2.6.0/drivers/dahdi/Kbuild

sed -i "s|#obj-m += ../staging/echo/|obj-m += ../staging/echo/|" /usr/src/dahdi-linux-2.6.0/drivers/dahdi/Kbuild

echo 'obj-m += echo.o' > /usr/src/dahdi-linux-2.6.0/drivers/staging/echo/Kbuild

113

Page 125: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora se recompilan DAHDI-linux y DAHDI-tools:

cd /usr/src/dahdi-linux-2.6.0

make distcleanmakemake install

DAHDI-Tools:

cd /usr/src/dahdi-tools-2.6.0

make distclean./configuremake menuselectmakemake installmake config

Se modifica el system.conf

nano /etc/dahdi/system.conf

se cambia esta linea

echocanceller=mg2,1-4

para que quede:

echocanceller=oslec,1-4

Para terminar la configuración de la tarjeta hay que modificar el archivo chan_dahdi.conf

se renombra el predefinido:

mv /etc/asterisk/chan_dahdi.conf /etc/asterisk/chan_dahdi.conf.old

y se crea uno nuevo:

nano /etc/asterisk/chan_dahdi.conf

Se añaden las siguientes lineas:

[trunkgroups]

[channels]language=es

114

Page 126: Libro Asterisk 1.8.X - Versión 1.0 (1)

context=from-pstnoverlapdial=yessignalling=fxs_kstoneduration=100usecallerid=yescidsignalling=v23cidstart=polarityhidecallerid=nocallwaiting=yescallwaitingcallerid=yesthreewaycalling=yestransfer=yescanpark=yescancallforward=yescallreturn=yesechocancel=yesrelaxdtmf=yesrxgain=2.0txgain=3.0callerid = asreceivedamaflags=documentationaccountcode=pstnbusydetect=yesbusycount=6mohinterpret=defaultmohsuggest=default

group=1channel => 1-4

En el bloque channels se configuran los parámetros validos para todos los canales. A partir de la linea channel => se configuran los canales. En este caso los cuatro canales FXO pertenecen todos al grupo 1

Reiniciamos primero DAHDI y luego Asterisk

/etc/init.d/dahdi start

/etc/init.d/asterisk start

Se controla que efectivamente la cancelación de echo configurada sea OSLEC:

dahdi_cfg -vvv

DAHDI Tools Version - 2.4.1DAHDI Version: 2.5.0.1 Echo Canceller(s): OSLEC Configuration

115

Page 127: Libro Asterisk 1.8.X - Versión 1.0 (1)

======================

El en servidor Linode, se recibirán solamente una serie de errores ya que la tarjeta no está realmente instalada.

Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvv

se mira la configuración del canal 1:

CLI> dahdi show channel 1

Se sale de la consola:

CLI> quit

Si se decide utilizar las 4 lineas telefónicas para las llamadas locales y nacionales hay cuatro forma de escribir el dialplan (para Colombia). Se antepone el numero 9 para indicar que marcando 9 más el numero de destino se está saliendo por las lineas analógicas. Este dialplan no se utilizará para llamadas a celulares.

exten => _9[12456789]XXXXXXX!,1Dial(DAHDI/g1/${EXTEN:1},45)same => n,Hangup

g1= Usa las líneas del grupo X de menor a Mayor

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/G1/${EXTEN:1},45)same => n,Hangup

G1= Usa las líneas del grupo X de Mayor a menor

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/r1/${EXTEN:1},45)same => n,Hangup

r1= Usa las líneas del grupo X de menor a Mayor pero de manera aleatoria

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/R1/${EXTEN:1},45)same => n,Hangup

R1= Usa las líneas del grupo X de Mayor a menor pero de manera aleatoria

Se usará este ultimo bloque.

nano /etc/asterisk/extensions.conf

al final del contexto internas se pone:

116

Page 128: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/R1/${EXTEN:1},45)same => n,Hangup

Para llamadas entrantes después del contexto google-in:

[from-pstn]exten => s,1,Dial(SIP/1000,45)exten => s,n,Hangup

El contexto from-pstn es el que se ha definido en el archivo chan_dahdi.conf

Se recarga el dialplan:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

se sale de la consola:

CLI> quit

6.2 Tarjeta Digium TE120P

La tarjeta TE120P es una tarjeta con una conexión T1, E1 o J1. El tipo de conexión se configura a través de un jumper presente en la tarjeta:

Los pasos a seguir son:

1. Apagar el computador

117

Page 129: Libro Asterisk 1.8.X - Versión 1.0 (1)

2. Desconectar el cable de alimentación3. Abrir el chasis del Computador4. Insertar la tarjeta en una ranura PCI disponible5. Volver a poner el chasis del computador6. Conectar el cable de alimentación al computador7. Conectar el cable RJ45 de la linea E1 a la tarjeta8. Encender el computador

Se paran los servicios Asterisk y DAHDI:

service asterisk stop

service dahdi stop

6.2.1 MFG/R2 - Openr2

Como en algunos países de latino américa, se utiliza la señalización MFG/R2 para que DAHDI la pueda implementar hay que instalar la librería Openr2:

se descarga:

cd /usr/src

wget http://openr2.googlecode.com/files/openr2-1.3.1.tar.gz

se descomprime:

tar -xf openr2-1.3.1.tar.gz

se entra en la carpeta:

cd openr2-1.3.1

y se compila:

./configure --prefix=/usrmakemake install

Luego hay que volver a compilar Asterisk:

cd /usr/src/asterisk-1.8.11.0

make distclean./configuremake

118

Page 130: Libro Asterisk 1.8.X - Versión 1.0 (1)

make install

Si aparece este WARNING (advertencia):

WARNING WARNING WARNING

Your Asterisk modules directory, located at /usr/lib/asterisk/modules contains modules that were not installed by this version of Asterisk. Please ensure that these modules are compatible with this version before attempting to run Asterisk.

app_mysql.so app_saycountpl.so cdr_mysql.so format_mp3.so res_config_mysql.so

WARNING WARNING WARNING

no hay problema ya que esos módulos se han anteriormente compilado con la misma versión de Asterisk.

make config

Para averiguar que la librería ha sido englobada en el el modulo chan_dahdi.so:

ldd channels/chan_dahdi.so | grep openr2libopenr2.so.3 => /usr/lib/libopenr2.so.3 (0x004bf000)

Para ver las distintas versiones de la señalización MFG/R2 soportadas por la librería:

r2test -lVariant Code CountryAR ArgentinaBR BrazilCN ChinaCZ Czech RepublicCO ColombiaEC EcuadorID IndonesiaITU International Telecommunication UnionMX MexicoPH PhilippinesVE Venezuela

119

Page 131: Libro Asterisk 1.8.X - Versión 1.0 (1)

Terminada la instalación de la librería se averigua si la tarjeta ha sido reconocida por CentOS:

lspci -n

el resultado debe ser:

0000:01:00.0 0200: ISDN controller: Unknown device d161:0120

Cuando se configura una linea E1 la sintaxis en el archivo system.conf es:

span => <Number>,<Timing>,<Line Build Out>,<Framing>,<Coding>[,Yellow]

Number: el puerto donde está conectado el cable de la linea E1. En este caso 1Timing: determina la fuente de sincronización para la tarjeta. Posibles valores:

0 = la fuente la genera la misma tarjeta1 = la fuente es remota

Line Build Out: 0 predefinidoFraming: en las lineas E1 puede ser CAS (Channel Associated Signaling) o CSS (Common Channel Signaling )Coding: puede ser AMI o HBD3. En algunos casos al final de la linea se pone CRC4 para el control de los paquetes.

Estos datos normalmente los facilita el proveedor de la linea. Algunos ejemplos podrían ser:

span => 1,0,0,cas,hdb3,crc4

o

span => 1,0,0,css,hdb3

Luego se configuran los canales:

bchan = 1-15,17-31dchan = 16

bchan son los canales audio y dchan el canal para la señalización.

y la cancelación de eco:

echocanceller => oslec,1-15,17-31

se termina con:

loadzone = codefaultzone = co

Por ultimo se configura el chan_dahdi.conf

120

Page 132: Libro Asterisk 1.8.X - Versión 1.0 (1)

los dos valores más importantes son:

switchtypesignaling

que también facilita el proveedor. Lo más común es:

switchtype=euroisdnsignaling=pri_cpe

Un ejemplo de archivo de configuración es:

[trunkgroups]

[channels]usecallerid=yeshidecallerid=nocallwaiting=yesusecallingpres=yescallwaitingcallerid=yesthreewaycalling=yestransfer=yescanpark=yescancallforward=yescallreturn=yesechocancel=yesechocancelwhenbridged=yesrelaxdtmf=yesrxgain=2.0txgain=3.0immediate=nocontext=from-pstngroup=1switchtype=euroisdnsignaling=pri_cpechannel => 1-15,17-31

Para la señalización MFC/R2 sería:

system.conf

span=1,1,0,cas,hdb3cas=1-15:1101dchan=16cas=17-31:1101loadzone = co

121

Page 133: Libro Asterisk 1.8.X - Versión 1.0 (1)

defaultzone = co

chan_dahdi.conf

[trunkgroups]

[channels]usecallerid=yeshidecallerid=nocallwaiting=yesusecallingpres=yescallwaitingcallerid=yesthreewaycalling=yestransfer=yescanpark=yescancallforward=yescallreturn=yesechocancel=yesechocancelwhenbridged=yesrelaxdtmf=yesrxgain=2.0txgain=3.0immediate=nocontext=from-pstngroup=1signalling = mfcr2mfcr2_variant = comfcr2_get_ani_first = nomfcr2_max_ani = 10mfcr2_max_dnis = 4mfcr2_category = national_subscribermfcr2_mfback_timeout = -1mfcr2_metering_pulse_timeout = -1mfcr2_logdir = logmfcr2_logging = allchannel => 1-15,17-31

Terminada la configuración se reinician los servicios:

service dahdi startservice asterisk start

y se averigua en la consola si todos los canales están configurados:

CLI> dahdi show channels

122

Page 134: Libro Asterisk 1.8.X - Versión 1.0 (1)

6.3 Wanpipe

Se termina esta parte del capitulo con la instalación del driver Wanpipe necesario para tarjetas SANGOMA. Primero se instala la tarjeta:

Los pasos a seguir son:

1. Apagar el computador2. Desconectar el cable de alimentación3. Abrir el chasis del Computador4. Insertar la tarjeta en una ranura PCI disponible5. Volver a poner el chasis del computador6. Conectar el cable de alimentación al computador7. Conectar el cable RJ45 de la linea E1 a la tarjeta8. Encender el computador

se para Asterisk y DAHDI:

service asterisk stopservice dahdi stop

Se descarga el driver:

cd /usr/src

wget ftp://ftp.sangoma.com/linux/current_wanpipe/wanpipe-3.5.23.tgz

se descomprime:

tar -xf wanpipe-3.5.23.tgz

se entra en la carpeta:

cd wanpipe-3.5.23

y se instala:

./Setup dahdi

se escribe y y se continua con envío:

123

Page 135: Libro Asterisk 1.8.X - Versión 1.0 (1)

se selecciona 1 más envío. Empieza la compilación del driver y de las utilidades. Al finalizar aparecerá:

Ahora se ejecuta:

wancfg_dahdi

que creará todos los datos de configuración para la tarjeta instalada. Luego se inicia wanpipe:

wanrouter start

DAHDI

service dahdi start

Asterisk:

service asterisk start

Para terminar se personalizan los parámetros creados por wancfg.

Al terminar este párrafo, y para volver a la configuración anterior, se vuelven a poner los archivos predefinidos:

mv /etc/dahdi/system.conf.old /etc/dahdi/system.conf

mv /etc/asterisk/chan_dahdi.conf.old /etc/asterisk/chan_dahdi.conf

y se reinician los dos servicios:

service dahdi start

124

Page 136: Libro Asterisk 1.8.X - Versión 1.0 (1)

service asterisk start

6.4 Linksys SPA3102 – Gateway FXO/FXS

El SPA3102 es un Gateway que soporta una linea FXO, una linea FXS y cada linea se puede configurar como si fuera una extensión SIP. La configuración que sigue abarca solamente la parte FXO ya que todas las llamadas entrantes se contestarán desde una extensión SIP. Por defecto el SPA3102 no permite conectarse a la pagina de administración desde remoto, así que lo primero que hay que hacer es activarla.

En Line se conecta el cable del teléfono que viene de la línea telefónica. En Ethernet se conecta un cable de red que luego se conectará al toma de red del computador. Para finalizar, en Internet se conecta un cable de red que luego se conecta al Router. Se abre una pestaña nueva del navegador y se pone la siguiente dirección: http://192.168.0.1 Aparecerá la pagina de administración del SPA3102:

125

Page 137: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se averigua la versión del Firmware instalada y la dirección IP asignada por el Router. Se da click en el enlace “advanced” y luego en la pestaña “Wan Setup”. Se activa la conexión desde remoto:

Para guardar cada cambio, al final de la pagina se presiona el botón “Submit All Changes”. Ya se puede desconectar el cable del puerto Ethernet del ATA y volver a conectar el computador al router. Ahora se puede acceder al SPA3102 indicando la dirección IP asignada por el Router. En este caso 192.168.100.100 El segundo paso es configurar una clave para el administrador y una para el usuario. Esto se hace en la pestaña Voice y luego System:

Se presiona el botón Submit All Changes. Si la versión del firmware no es la 5.1.10 se actualiza. Los firware para el SPA3102, se pueden descargar desde esta pagina. Se descomprime el archivo en el escritorio del computador. Entre los nuevo iconos:

Se da click dos veces. Aparecerá:

126

Page 138: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para aceptar la advertencia se presiona el botón “Continue”:

Se pone la dirección IP local del SPA3102 y la del computador donde se ha descargado el Firmware. Se continua con el botón “OK”:

127

Page 139: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pone el usuario admin y la clave que se acaba de crear. Se presiona el botón “OK”:

Se revisan todos los datos y para iniciar la actualización se presiona el botón “Upgrade”. La operación tarda unos minutos. Cuando termine, se vuelve a entrar en la pagina de administración del ATA y se configura la cuenta SIP para la línea FXO. Se va a la pestaña Voice y luego en PSTN Line donde se configura solamente la parte que interesa:

128

Page 140: Libro Asterisk 1.8.X - Versión 1.0 (1)

Line Enable = yesNAT Keep Alive Enable = yes (si el Asterisk es remoto y el ATA se encuentra detrás de un NAT)NAT Keep Alive Msg = viene por defecto con la opción $NOTIFY que envía un paquete de tipo SIP NOTYFY para tener abierta la conexión. Se puede dejar la linea en blanco. De esta forma se envía a Asterisk solamente un paquete UDP vacío como hacen la mayoría de los teléfonos SIP:

Proxy = dirección IP o nombre de dominio del servidor Asterisk remotoRegister = yesDisplay Name = poner el numero de teléfono de la línea telefónica (por ejemplo)UserID = el nombre de la extensión que luego se configurará en AsteriskUse Auth ID =yesAuth ID = lo mismo que User ID

129

Page 141: Libro Asterisk 1.8.X - Versión 1.0 (1)

Como codec predefinido se activa alaw y como segundo G729:

Se definen dos Dialplan: El primero para las llamadas salientes y el segundo para las llamadas entrantes. Todas las llamadas entrantes se enrutan a la extensión s de Asterisk:

En la configuración del Gateway VoIP –> PSTN se pone:

VoIP-To-PSTN Gateway Enable =yesVoIP Caller Auth Method = none (ninguna autentificación)One Stage Dialing = yesLine 1 VoIP Caller DP = para las llamadas salientes se utilizará el dialplan 1

En la configuración del Gateway PSTN – > VoIP se pone:

PSTN-To-VoIP Gateway Enable =yesPSTN Calles Auth Method = none (de esta forma cuando el ATA conteste no solicitará ningún PIN para acceder al Gateway VoIP)PSTN Ring Thru Line 1 = no (ya que no se va a conectar un teléfono analógico al ATA)PSTN Caller Default DP = 2 (Para este Gateway se utilizará el diaplan 2)

130

Page 142: Libro Asterisk 1.8.X - Versión 1.0 (1)

Cuando entre una llamada desde la red PSTN el Gateway VoIP del ATA contestará después de 2 segundos y pasará la llamada también a las extensión s de Asterisk:

Detect Polarity Reversal = no (para Colombia)Detect PSTN Long silence = yes (si no hay flujo audio del lado PSTN por 30 segundos (parámetro que sigue) la llamada terminaráPSTN Long Silence Duration = 30Detect VoIP Long Silence = yes Lo mismo para lado VoIPVoIP Long Silence Duration = 30Detect Disconnect Tone = YesDisconnect Tone = el valor de su país. Esto valores, para muchos países, aparecen en la guía de administrador del SPA3102.Se termina presionando el botón “Submit All Changes”.

Ahora el ATA intentará conectarse a Asterisk sin éxito ya que la extensión no ha sido creada. Se abre el archivo sip.conf y al final del archivo, se añade el siguiente bloque:

nano /etc/asterisk/sip.conf

[spa3102]type=friendsecret=passwordqualify=yesnat=yeshost=dynamicdirectmedia=no

131

Page 143: Libro Asterisk 1.8.X - Versión 1.0 (1)

context=from-spa3102dtmfmode=rfc2833language=escallerid=LineaTel <NumTel>allowtransfer=yesallowsubscribe=yessubscribecontext=subscribecallcounter=yesdisallow=allallow=alawallow=g729

Se guardan los cambios y se recarga la configuración SIP:

asterisk -rx "sip reload"

Después de unos segundos en la pagina del SPA3102 (Menú Voice, pestaña Info, debería aparecer):

El dialplan:

nano /etc/asterisk/extensions.conf

para las llamadas salientes al final del contexto internas se pone:

exten => _8.,1,Dial(SIP/spa3102,45,D(${EXTEN:1}))same => n,Busy(3)same => n,Hangup

De esta forma marcando 8 + el numero a llamar, todas las llamadas pasarán para el SPA3102. En cuanto el ATA conteste, se le envía los dígitos del numero a marcar quitando el 8 (opción D de la aplicación Dial). Para las llamadas entrantes, después del contexto google-in, se configura el contexto from-spa3102 (como definido en la configuración de la extensión en el sip.conf) y se pone:

132

Page 144: Libro Asterisk 1.8.X - Versión 1.0 (1)

[from-spa3102]exten => s,1,NoOpsame => n,Dial(SIP/1000)same => n,Hangup

De esta forma cuando alguien llamará el numero de la línea telefónica, después de dos segundos empezará a timbrar también la extensión 1000. Claramente la llamada entrante se puede enviar a un IVR o configurar para que timbre más de una extensión.

Se guardan los cambios y se recarga el dialplan:

asterisk –rvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde cualquier teléfono SIP conectado a Asterisk se marca un numero anteponiendo el 8. La llamada saldrá por el SPA3102. Otra prueba: se marca desde un celular al numero de la línea telefónica y se espera que empiece a timbrar la extensión 1000.

133

Page 145: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 146: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO VII

Dialplan – Configuración avanzada

Para poder entender mejor como funciona y como se construye un dialplan en Asterisk, hay que aclarar algunos conceptos claves. En el párrafo 2.6, se ha explicado la división del dialplan en contextos, extensiones y prioridades. En esta parte se ilustrarán:

• las variables• los pattern matching• la aplicación ECHO• el contexto subscribe• las Macro• la aplicación Authenticate• Limitar llamadas salientes• Enrutamiento llamadas entrantes según fecha hora

7.1 Las variables

Una variable es un objeto al que se asocia un valor. Se utilizan mucho en matemática y su función en Asterisk es reducir la complexidad del dialplan, simplificar su construcción y añadirle una lógica más comprensible. En Asterisk existen tres tipos de variables:

• variables globales• variables de canal• variables de ambiente

Las variables globales son aquellas cuyo valor no cambia a lo largo del dialplan. En la preparación del dialplan se ha visto el bloque dedicado a las variables globales y se han configurado tres, entre ellas:

marko=IAX2/marko

De esta forma se asocia al nombre de variable marko el valor IAX2/marko. ¿Cual es su función en el dialplan? En este caso simplificarlo. Si se retoma el bloque de dialplan:

exten => 1234,1,Dial(IAX2/marko,30)same => n,Hangup

que se ha creado para llamar la extensión IAX2 marko, esta parte puede ser escrita también de la siguiente forma:

exten => 1234,1,Dial(${marko},30)same => n,Hangup

Cuando se utiliza una variable en el dialplan la sintaxis es: carácter dolar $ seguido por el nombre de la

Page 147: Libro Asterisk 1.8.X - Versión 1.0 (1)

variable entre dos llaves {}. Las variables son case sensitive, es decir que hay diferencia si se escriben en mayúsculas y minúsculas. En el caso de la variable ${marko} que está escrita toda en minúsculo, no es lo mismo si en el dialplan se pone:

exten => 1234,1,Dial(${MARKO},30)same => n,Hangup

La variable ${MARKO} estará totalmente vacía. Algunas aplicaciones y funciones de Asterisk al ejecutarse generan variables. Todas las variables generadas son en mayúsculo, como, por ejemplo, la que ya se ha visto ${EXTEN}. Es una buena practica, cuando se crean variables, utilizar nombres en minúsculo para diferenciarlas de las variables generadas por Asterisk.

Las variables de canal tienen validez solamente para la llamada corriente. Para crearlas se utiliza la aplicación Set. Un ejemplo:

Set(numero=1)

Para toda la duración de la llamada el valor de la variable ${numero} será 1. Cuando la llamada termine, el valor asociado a la variable volverá a ser nulo. Este tipo de variables se utilizan mucho en el dialplan para modificar valores del canal y/o para guardar algunos datos de las llamadas para luego utilizarlos. A lo largo de la construcción del dialplan se presentarán distintos ejemplos.

Hay muchas variables predefinidas que se crean durante una llamada. Para saber cuales son y que valor tienen en un determinado canal, se utiliza la aplicación Dumpchan.

Para verla en acción se abre el archivo del dialplan:

nano /etc/asterisk/extensions.conf

se modifica este bloque:

exten => 123,1,Answersame => n,Playback(hello-world)same => n,Hangup

para que quede:

exten => 123,1,Answersame => n,Dumpchansame => n,Playback(hello-world)same => n,Hangup

Se guardan las modificaciones y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvv

CLI> dialplan reload

136

Page 148: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora desde la extensión 1000 se marca el numero 123. El resultado en la consola de Asterisk será:

Dumping Info For Channel: SIP/1000-00000001:===========================================================Info:Name= SIP/1000-00000001Type= SIPUniqueID= 1318352043.1CallerIDNum= 1000CallerIDName= callerid=FulanoDNIDDigits= 123RDNIS= (N/A)Parkinglot=Language= esState= Up (6)Rings= 0NativeFormat= 0x8 (alaw)WriteFormat= 0x8 (alaw)ReadFormat= 0x8 (alaw)RawWriteFormat= 0x8 (alaw)RawReadFormat= 0x8 (alaw)1stFileDescriptor= 29Framesin= 1Framesout= 0TimetoHangup= 0ElapsedTime= 0h0m0sContext= externasExtension= 123Priority= 2CallGroup= 1PickupGroup= 1Application= DumpChanData= (Empty)Blocking_in= (Not Blocking)

Variables:SIPCALLID=YzBkYjQ1MjYyOWYxMzllYjU5Y2RhNmM3MDM3MjFkYTU.SIPDOMAIN=96.126.121.135SIPURI=sip:[email protected]:15480

CLI> quit

Para una lista completa de las variables predefinidas se puede consultar la Wiki de Asterisk. Una variable muy peculiar es la variable ${EXTEN}, que contiene el numero marcado. Esta variable tiene la siguiente sintaxis ${EXTEN:x:y) donde x es la posición inicial e y el numero de dígitos que se

137

Page 149: Libro Asterisk 1.8.X - Versión 1.0 (1)

quieren extraer:

Tomando como numero de partida 57300200:

${EXTEN:1} devolverá 7300200

${EXTEN:1:4} devolverá 7300

${EXTEN:2:6} devolverá 300200

${EXTEN:5:3} devolverá 200

Las variables de ambiente se utilizan para leer la variables del sistema (Linux). Para crearlas se utiliza la aplicación SET y la función ENV. Un ejemplo:

Set(PBX=${ENV(LANG)})

En este ejemplo a la variable PBX estará asociado el idioma configurado en el servidor Linux.

para probarla en el dialplan:

nano /etc/asterisk/extensions.conf

en el contexto internas se ánade este bloque:

exten => 50,1,Set(PBX=${ENV(LANG)})same => n,Noop(Idioma Servidor ${PBX})same => n,Hangup

Se guardan los cambios y se recarga el dialplan.

asterisk -rvvvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca el numero 50. En la consola de Asterisk:

Executing [50@externas:1] Set("SIP/1000-0000000b", "PBX=en_US.UTF-8") in new stackExecuting [50@externas:2] NoOp("SIP/1000-0000000b", "Idioma Servidor en_US.UTF-8") in new stackExecuting [50@externas:3] Hangup("SIP/1000-0000000b", "") in new stack

No todas las variables de ambiente se pueden leer desde Asterisk.

7.2 Pattern Matching

138

Page 150: Libro Asterisk 1.8.X - Versión 1.0 (1)

El dialplan se construye de modo que todos los posibles números marcados puedan ser “interceptados” por Asterisk. Sería absurdo indicar todos los números de teléfono de Colombia porque un usuario podría marcar uno de ellos. Para este tipo de situaciones, se utilizan los Pattern Marching o patrones de llamada, que permiten crear extensiones en el dialplan que “intercepten” los números marcados. Estos caracteres se ponen en lugar de uno o más dígitos. La lista es la siguiente:

• X puede ser un numero de 0 a 9• Z puede ser un numero de 1 a 9• N puede ser un numero de 2 a 9• [1-4,6-8] puede ser un numero de 1 a 4 o de 6 a 8• . (punto) puede ser uno o más caracteres• ! puede ser cero o más caracteres.

Algunos ejemplos. Si se quiere crear una extensión donde entren todas las llamadas a los celulares de Colombia (prefijo 3) con el proveedor Justvoip, la primera linea sería:

exten => _00573XXXXXXXXX,1,Dial(SIP/justvoip/${EXTEN})

Si no se conoce exactamente de cuantos dígitos está compuesto un numero de celular la misma linea cambiaría de la siguiente forma:

exten => _00573.,1,Dial(SIP/justvoip/${EXTEN})

El punto después del 00573, indica que lo que sigue puede ser compuesto de uno o más dígitos.

Cuando se pone un pattern matching en la creación de una extensión, siempre hay que anteponer el guion abajo _

Si, por ejemplo, el numero de extensiones configuradas en Asterisk van desde 1000 hasta 1099 el dialplan para las llamadas entre extensiones sería:

exten => _10XX,1,Dial(SIP/${EXTEN})

7.3 La aplicación Echo

La aplicación Echo se utiliza para medir el tiempo de retorno de la voz. Puede ser útil para revisar eventuales retrasos y o problemas en la calidad del audio.

Para configurarla se modifica el dialplan:

nano /etc/asterisk/extensions.conf

y en el contexto internas se añade el siguiente bloque:

exten => 150,1,Answer

139

Page 151: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Playback(demo-echotest)same => n,Echosame => n,Playback(demo-echodone)same => n,Hangup

Se guardan los cambios y se recarga el dialplan:

asterisk -rx "dialplan reload"

Desde cualquier extensión registrada a Asterisk se marca el numero 150 y se hace la prueba.

7.4 El contexto Subscribe

A lo largo de la configuración del archivo sip.conf se ha hablado de la posibilidad de monitorear el estado de una extensión y en la parte general del archivo se han configurados los siguientes parámetros para activar esta funcionalidad:

callcounter=yesallowsubscribe=yessubscribecontext=subscribenotifyringing=yesnotifyhold=yes

Ahora para que el sistema funcione, en el dialplan hay que configurar el contexto subscribe. Se abre el archivo:

nano /etc/asterisk/extensions.conf

y después del contexto internas se añade el siguiente bloque:

[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001exten => 1002,hint,SIP/1002exten => marko,hint,IAX2/marko

La prioridad Hint es una prioridad especial que permite monitorear el estado de las extensiones. En este caso las extensiones SIP 1000,1001 y 1002 y la extensión IAX2 marko.

Otra forma de escribir el bloque es:

[subscribe]exten => _100[0-2],hint,SIP/100[0-2]exten => marko,hint,IAX2/marko

es decir utilizando los Pattern Marching. En este caso se utilizará la primera forma. Se guardan los

140

Page 152: Libro Asterisk 1.8.X - Versión 1.0 (1)

cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Con el comando:

CLI> core show hints

-= Registered Asterisk Dial Plan Hints =- 1000@subscribe : SIP/1000 State:Idle Watchers 0 1001@subscribe : SIP/1001 State:Unavailable Watchers 0 1002@subscribe : SIP/1002 State:Unavailable Watchers 0 marko@subscribe : IAX2/marko State:Unavailable Watchers 0

Se verán los hints configurados y en la ultima columna cuantas extensiones se han subscrito al estado de las demás (en este caso ninguna).

Ahora se abre el Xlite configurado como extensión 1000 y se presiona el icono evidenciado:

En la nueva ventana:

Al lado de la casilla “Softphone” se escribe 1001 y luego se presiona el botón Add. Antes de presionar el botón “OK” para terminar la operación, en la ventana del terminal se sale de la consola de Asterisk:

CLI> quit

y se inicia la captura de los paquetes SIP:

ngrep 1000 -W byline port 5060 > /tmp/subscribe

Se vuelve al Xlite y se presiona el botón OK. Se vuelve a la ventana terminal y se termina la captura de

141

Page 153: Libro Asterisk 1.8.X - Versión 1.0 (1)

los paquetes SIP.

La secuencia de los paquetes será:

X-Lite ------------------Subscribe---------------> Asterisk X-Lite <-------401 Unauthorized-------------- Asterisk

X-Lite ------------------Subscribe---------------> Asterisk X-Lite <-------------------200 Ok---------------- AsteriskX-Lite <-----------------NOTIFY---------------- AsteriskX-Lite -------------------200 OK----------------> Asterisk

Y en el NOTIFY final, estará anexa esta parte:

<?xml version="1.0" encoding="ISO-8859-1"?><presence xmlns="urn:ietf:params:xml:ns:pidf"xmlns:pp="urn:ietf:params:xml:ns:pidf:person"xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status"xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person"entity="sip:[email protected]"><pp:person><status><ep:activities><ep:away/></ep:activities></status></pp:person><note>Not online</note><tuple id="1001"><contact priority="1">sip:[email protected]</contact><status><basic>closed</basic></status></tuple></presence>

Asterisk está comunicando a la extensión 1000 que la extensión 1001 no está en linea (Not online)

Se capturan nuevamente los paquetes con el comando:

ngrep 1000 -W byline port 5060 > /tmp/notify

Se abre el softphone 3CX configurado como extensión 1001 y una vez que esté registrado a Asterisk se termina la captura de los paquetes. En el archivo notify se encontrará la siguiente secuencia:

Asterisk --------NOTIFY--------------> XliteAsterisk <--------200 OK-------------- Xlite

La parte final del paquete de Notify enviado por Asterisk a la extensión 1000 será:

<?xml version="1.0" encoding="ISO-8859-1"?><presence xmlns="urn:ietf:params:xml:ns:pidf"xmlns:pp="urn:ietf:params:xml:ns:pidf:person"xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status"

142

Page 154: Libro Asterisk 1.8.X - Versión 1.0 (1)

xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person"entity="sip:[email protected]"><pp:person><status></status></pp:person><note>Ready</note><tuple id="1001"><contact priority="1">sip:[email protected]</contact><status><basic>open</basic></status></tuple></presence>

Asterisk estará comunicando a la extensión 1000 que la extensión 1001 está en linea ya que la extensión 1000 ha subscrito el estado de esa extensión. Si se vuelve a la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvv

CLI> core show hints -= Registered Asterisk Dial Plan Hints =- 1000@subscribe : SIP/1000 State:Idle Watchers 0 1001@subscribe : SIP/1001 State:Idle Watchers 1 1002@subscribe : SIP/1002 State:Unavailable Watchers 0 marko@subscribe : IAX2/marko State:Unavailable Watchers 0

En la columna Watchers de la extensión 1001 hay un 1 que indica que hay una extensión que está monitoreando su estado.

Se abre Zoiper (configurado con las cuentas SIP 1002 y IAX2 marko) y en el Xlite se subscribe el estado de ambas. El resultado será:

Desde la extensión 1001 se marca el numero 150 (test de echo). En el Xlite aparecerá:

143

Page 155: Libro Asterisk 1.8.X - Versión 1.0 (1)

Por ultimo, desde la extensión 1002 se llama la extensión 1001:

La misma cosa se puede hacer en los Teléfonos SIP de mesa que soportan los BLF (Busy Lamp Field).

7.5 Las Macro

Si en el dialplan algunas acciones se repiten a menudo, Asterisk brinda la posibilidad de crear una Macro que permite simplificar este tipo de operaciones. La sintaxis de la aplicación Macro:

asterisk -rvvvvvvvvvvvv

CLI> core show application Macro -= Info about application 'Macro' =-

[Synopsis]Macro Implementation.

[Description]Executes a macro using the context macro-<name>, jumping to the 's' extensionof that context and executing each step, then returning when the steps end.The calling extension, context, and priority are stored in ${MACRO_EXTEN}, ${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become${ARG1}, ${ARG2}, etc in the macro context.If you Goto out of the Macro context, the Macro will terminate and controlwill be returned at the location of the Goto.

144

Page 156: Libro Asterisk 1.8.X - Versión 1.0 (1)

If ${MACRO_OFFSET} is set at termination, Macro will attempt to continueat priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.WARNING!!!: Because of the way Macro is implemented (it executes thepriorities contained within it via sub-engine), and a fixed per-thread memorystack allowance, macros are limited to 7 levels of nesting (macro callingmacro calling macro, etc.); It may be possible that stack-intensiveapplications in deeply nested macros could cause asterisk to crash earlierthan this limit. It is advised that if you need to deeply nest macro calls,that you use the Gosub application (now allows arguments like a Macro) withexplict Return() calls instead.WARNING!!!: Use of the application 'WaitExten' within a macro will notfunction as expected. Please use the 'Read' application in order to read DTMFfrom a channel currently executing a macro.

[Syntax]Macro(name[,arg1[,arg2[,...]]])

[Arguments]name The name of the macro

El comando seria:

Macro(nombre_de_la_macro, argumento1,argumento2,argumentoN)

ArgumentoN es un valor o una variable que se pasa a la macro al momento de llamarla desde el plan de llamadas.

La aplicación macro crea las siguientes variables de canal:

• ${MACRO_EXTEN} contendrá el numero marcado• ${MACRO_CONTEXT} contendrá el contexto de donde se ha llamado la Macro• ${MACRO_PRIORITY} contendrá la prioridad de la línea de donde se ha llamado la Macro• ${ARG1}, ${ARG2}, ${ARGN) son las variables que contienen los argumentos que se han

enviado a la Macro.

Para empezar a utilizar la aplicación Macro se creará una muy sencilla que antes de marcar una extensión controle su estado y, en base a éste, envíe la llamada a una determinada parte del dialplan.

Primero hay que salir de la consola y modificar el plan de llamadas:

CLI> quit

nano /etc/asterisk/extensions.conf

Al final del archivo se añaden estas líneas:

145

Page 157: Libro Asterisk 1.8.X - Versión 1.0 (1)

[macro-disponible]exten => s,1,Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})})exten => s,n,Gotoif($["${estado}" = "NOT_INUSE"]?5)exten => s,n,Busyexten => s,n,Hangupexten => s,n,MacroExit

Una explicación de las aplicaciones y funciones nuevas que aparecen en las lineas de la Macro:

La función DEVICE_STATE: controla si una extensión está disponible y retorna un valor que se asignará a la variable “estado”. Los posibles valores son:

• UNKNOWN – El canal es valido pero su estado no es conocido • NOT_INUSE - No se está usando• INUSE - El canal está en uso• BUSY - El canal está ocupado• INVALID - El canal no es valido• UNAVAILABLE - El canal no está disponible (no está registrado a Asterisk)• RINGING - El canal está timbrando• RINGINGUSE - El canal está timbrando y en uso• ONHOLD - El canal está en espera

La aplicación Gotoif: literalmente es: ve a la prioridad indicada si se presenta una determinada condición (verdadero), sino ve a otra prioridad indicada (falso). Si la segunda prioridad no se especifica, el dialplan continua con la prioridad que sigue.

La aplicación Busy: si la extensión no se encuentra libre se envía al llamante una señal de ocupado

La aplicación MacroExit: sale de la macro y vuelve al mismo contexto, extensión, prioridad + 1 de donde se llamó.

Para insertar la Macro en el dialplan creado, se modifica el bloque configurado para las llamadas entre extensiones.

exten => _100[0-2],1,Dial(SIP/${EXTEN},30)same => n,Hangup

Para que quede:

exten => _100[0-2],1,Macro(disponible)same => n,Dial(SIP/${EXTEN},45)same => n,Hangup

Se guardan los cambios y se actualiza el plan de llamadas:

146

Page 158: Libro Asterisk 1.8.X - Versión 1.0 (1)

asterisk -rvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora se marca desde la extensión 1000 la extensión 1001 (ambas conectadas a Asteirsk) y se controla lo que aparece en la consola de Asterisk:

Executing [1001@externas:1] Macro("SIP/1000-00000011", "disponible") in new stackExecuting [s@macro-disponible:1] Set("SIP/1000-00000011", "estado=NOT_INUSE") in new stackExecuting [s@macro-disponible:2] GotoIf("SIP/1000-00000011", "1?5") in new stackGoto (macro-disponible,s,5)Executing [s@macro-disponible:5] MacroExit("SIP/1000-00000011", "") in new stackExecuting [1001@externas:2] Dial("SIP/1000-00000011", "SIP/1001,45") in new stack

Se cierra el 3CX Softphone (extensión 1001) y se marca otra vez desde la extensión 1000 la extensión 1001:

Executing [1001@externas:1] Macro("SIP/1000-00000013", "disponible") in new stackExecuting [s@macro-disponible:1] Set("SIP/1000-00000013", "estado=UNAVAILABLE") in new stackExecuting [s@macro-disponible:2] GotoIf("SIP/1000-00000013", "0?5") in new stackExecuting [s@macro-disponible:3] Busy("SIP/1000-00000013", "") in new stack

Como el estado de la extensión 1001 es “UNAVAILABLE” (en negrita) se procesa la prioridad 3 (el Busy) y se termina la llamada.

7.6 Autenticar las Llamadas Salientes con la aplicación Authenticate

Al momento de crear las extensiones en el archivo sip.conf, a la extensión 1002 se ha asociado el contexto locales. Ese contexto no tiene acceso al contexto internacio, pues la extensión 1002 no puede efectuar llamadas salientes utilizando el proveedor SIP Justvoip. Este es un caso típico en la configuración de Asterisk. Algunas extensiones tienen acceso a la lineas salientes y otras no. Para comprobarlo, si se marca el numero 00573126814740 desde las extensión 1002, el resultado será:

[Feb 2 10:29:18] NOTICE[31745]: chan_sip.c:22147 handle_request_invite: Call from '1002' (186.112.195.81:10000) to extension '00573126814740' rejected because extension not found in context 'locales'.

Otra forma de configurar Asterisk es que las extensiones que no tienen acceso a las lineas salientes, para tenerlo, tengan que autenticarse. De esta forma hay un control sobre la llamadas salientes y se puede tener un registro de los usuarios que han utilizado el servicio. Este tipo de configuración se hará utilizando la aplicación Authenticate.

Para conocer la sintaxis de la aplicación:

asterisk -rvvvvvvvvvvvvvv

147

Page 159: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> core show application authenticate

[Syntax]Authenticate(password[,options[,maxdigits[,prompt]]])

[Arguments]password Password the user should knowoptions a: Set the channels' account code to the password that is entered d: Interpret the given path as database key, not a literal file m: Interpret the given path as a file which contains a list of account codes and password hashes delimited with ':', listed one per line in the file. When one of the passwords is matched, the channel will have its account code set to the corresponding account code in the file. r: Remove the database key upon successful entry (valid with 'd' only)maxdigits maximum acceptable number of digits. Stops reading after maxdigits have been entered (without requiring the user to press the '#' key). Defaults to 0 - no limit - wait for the user press the '#' key.prompt Override the agent-pass prompt file.

La opción password puede contener un valor o referirse a un archivo de texto que contenga una lista de nombres con las respectivas contraseñas separada por el carácter “:”. Las contraseñas se pueden escribir en claro o cifradas con MD5. En este caso se cifrarán. Si el PIN para la extensión 1002 (Mengano) es 4488, su valor cifrado será:

echo -n "4488" | md5sum

c4819d06b0ca810d38506453cfaae9d8

Luego se crea el archivo de texto con el nombre del usuario de la extensión y la respectiva contraseña cifrada:

nano /tmp/pin.txt

se añade la siguiente linea:

Mengano:c4819d06b0ca810d38506453cfaae9d8

Se guardan los cambios.

Ahora se crea un nuevo contexto al cual tenga acceso la extensión 1002. Se llamará este contexto “auten”

148

Page 160: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/extensions.conf

después del contexto internas se añade el siguiente bloque:

[auten]exten => _00.,1,NoOPsame => n,Authenticate(/tmp/pin.txt,am,4)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

Los parámetros utilizados en la aplicación Authenticate:

• El primero define la carpeta y el nombre del archivo que contiene las contraseñas.• La Opción a define que en el registro de las llamadas el campo Accountcode contendrá el

nombre del usuario independientemente de la extensión que haya utilizado para efectuar la llamada

• La opción m define que el archivo de texto contendrá las contraseñas cifradas con MD5.• El ultimo parámetro indica que los dígitos del PIN son 4 evitando de tener que utilizar la tecla

numero para terminar el envío de los dígitos.

Si la contraseña digitada está en el archivo de texto creado, el dialplan pasará a la línea que sigue donde se iniciará la llamada.

En el contexto locales se añade el contexto auten para que la extensión 1002 tenga acceso al bloque recién creado (en negrita los cambios):

[locales]include => internasinclude => auten

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1002 se marca el numero 005714013434. Cuando Asterisk lo pide, se ingresará la contraseña 4488. Empezará la llamada al numero marcado.

Se sale de la consola de Asterisk:

CLI> quit

Para averiguar que efectivamente la llamada ha sido cargada a la cuenta del usuario Mengano se entra en el cliente MySQL:

149

Page 161: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql -u root -psesamo

Se selecciona la base de datos asteriskcdr (donde se ha creado la tabal CDR):

mysql> use asteriskcdr

y se hace una consulta en la tabal CDR (que contiene todos los registros de las llamadas):

mysql> select src,dst,channel,billsec,accountcode from cdr where accountcode='Mengano';

El resultado será:

+------+--------------+-------------------+---------+-------------+| src | dst | channel | billsec | accountcode +------+--------------+-------------------+---------+-------------+| 1002 | 005714013434 | SIP/1002-00000014 | 15 | Mengano+------+--------------+-------------------+---------+-------------+1 row in set (0.00 sec)

Se sale del cliente MySQL:

mysql> quit

7.7 Limitar llamadas salientes: funciones GROUP y GROUP_COUNT

Hasta la versión 1.4.X si se quería limitar el numero de llamadas salientes/entrantes para una extensión, se utilizaba el parámetro call-limit que había que añadir en la configuración de la extensión en el sip.conf. A partir de la versión 1.6.X de Asterisk y por consecuencia en la versión 1.8.X, este parámetro ha sido marcado como “deprecated”; esto quiere decir que no se recomienda su uso en las nuevas versiones. En su lugar se han introducido dos funciones:

• GROUP• GROUP_COUNT

A través de estas dos funciones, es posible limitar el numero de canales utilizados en las llamadas entrantes y salientes.

Un ejemplo practico. Se quiere limitar a 2 el numero de llamadas salientes para cada extensión configurada y al mismo tiempo se quieres limitar a 2 las llamadas salientes por la troncal Justvoip.

Lo que hay que hacer es construir un dialplan donde si una extensión intenta sacar la tercera llamada simultanea, se le avise que no puede y al mismo tiempo si los 2 canales de la troncal se están utilizando, se le avise al usuario que no hay más canales disponibles para las llamadas salientes.

Si se quiere conocer en cualquier momento los canales utilizados por cada extensión/troncal

150

Page 162: Libro Asterisk 1.8.X - Versión 1.0 (1)

configurada en Asterisk, el comando es:

asterisk -rvvvvvvvvvvvvvvvvv

CLI> sip show inuse* Peer name In use Limit1000 0/0/0 21474836471001 0/0/0 21474836471002 0/0/0 2147483647justvoip 0/0/0 2147483647

Bajo la columna In use, los significados de las tres columnas (de la izquierda a la derecha) son:

• Canales in uso• Canales timbrando• Canales en espera

Bajo la columna Limit se puede notar que prácticamente no existe ningún limite. Retomando el dialplan hasta ahora creado, se va a aplicar la regla definida a las llamadas salientes. Se abre el archivo del dialplan:

nano /etc/asterisk/extensions.conf

En el contexto internacio se modifican estas lineas:

exten => _00.,1,Dial(SIP/justvoip/${EXTEN},30)same => n,Hangup

Para que queden:

exten => _00X.,1,NoOpsame => n,Set(GROUP(voip)=justvoip)same => n,Set(GROUP(salida)=${CALLERID(num)})same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)})same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)})same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip)same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangupsame => n(busy),Playback(all-outgoing-lines-unavailable)same => n,Hangup

Una explicación del dialplan creado:

• En la segunda linea se se asigna al grupo voip la troncal justvoip• En la tercera linea se asigna al grupo salida la variable ${CALLERID(num)} que contiene el

151

Page 163: Libro Asterisk 1.8.X - Versión 1.0 (1)

numero de la extensión que está llamando• En la cuarta linea se aumenta de una unidad el valor del grupo voip y se asigna el nuevo valor a

la variable trunksal• En la quinta linea se aumenta de una unidad el valor del grupo salida y se asigna el nuevo valor

a la variable extsal• En la sexta linea se envía el valor de las llamadas totales de las extensiones y de la troncal a la

consola de Asterisk• En la séptima linea se define este comportamiento. Si las llamadas desde las extensiones son

mayores a dos o las llamadas de la troncal son mayores a dos, ir a la etiqueta (busy), sino seguir con el dialplan. El operador lógico | está en lugar de la palabra inglés OR.

• En la linea que empieza con la etiqueta busy, se comunica a la extensión que no hay lineas disponibles para las llamadas salientes.

Ahora para hacer una primera prueba, desde la extensión 1001 (el softphone 3CX) se marca el numero 005714013434 y al mismo tiempo desde la extensión 1000 se marca dos veces al mismo numero. En la consola de Asterisk aparecerá:

Primera llamda == Extension Changed 1001[subscribe] new state InUse for Notify User 1000 -- Executing [005714013434@externas:1] NoOp("SIP/1001-00000020", "") in new stack -- Executing [005714013434@externas:2] Set("SIP/1001-00000020", "GROUP(voip)=justvoip") in new stack -- Executing [005714013434@externas:3] Set("SIP/1001-00000020", "GROUP(salida)=1001") in new stack -- Executing [005714013434@externas:4] Set("SIP/1001-00000020", "trunksal=1") in new stack -- Executing [005714013434@externas:5] Set("SIP/1001-00000020", "extsal=1") in new stack -- Executing [005714013434@externas:6] NoOp("SIP/1001-00000020", "Hay 1 llamadas desde la extension 1001 y 1 con el proveedor Justvoip") in new stack -- Executing [005714013434@externas:7] GotoIf("SIP/1001-00000020", "0?busy") in new stack -- Executing [005714013434@externas:8] Dial("SIP/1001-00000020", "SIP/justvoip/005714013434") in new stack Segunda Llamada == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -- Called SIP/justvoip/005714013434 -- SIP/justvoip-00000021 is making progress passing it to SIP/1001-00000020 == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -- Executing [005714013434@externas:1] NoOp("SIP/1000-00000022", "") in new stack -- Executing [005714013434@externas:2] Set("SIP/1000-00000022", "GROUP(voip)=justvoip") in new stack -- Executing [005714013434@externas:3] Set("SIP/1000-00000022", "GROUP(salida)=1000") in new stack -- Executing [005714013434@externas:4] Set("SIP/1000-00000022", "trunksal=2") in new stack -- Executing [005714013434@externas:5] Set("SIP/1000-00000022", "extsal=1") in new stack

152

Page 164: Libro Asterisk 1.8.X - Versión 1.0 (1)

-- Executing [005714013434@externas:6] NoOp("SIP/1000-00000022", "Hay 1 llamadas desde la extension 1000 y 2 con el proveedor Justvoip") in new stack -- Executing [005714013434@externas:7] GotoIf("SIP/1000-00000022", "0?busy") in new stack -- Executing [005714013434@externas:8] Dial("SIP/1000-00000022", "SIP/justvoip/005714013434") in new stack

Tercera Llamada == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -- Called SIP/justvoip/005714013434 -- SIP/justvoip-00000023 is making progress passing it to SIP/1000-00000022 -- SIP/justvoip-00000021 answered SIP/1001-00000020 == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -- Executing [005714013434@externas:1] NoOp("SIP/1000-00000024", "") in new stack -- Executing [005714013434@externas:2] Set("SIP/1000-00000024", "GROUP(voip)=justvoip") in new stack -- Executing [005714013434@externas:3] Set("SIP/1000-00000024", "GROUP(salida)=1000") in new stack -- Executing [005714013434@externas:4] Set("SIP/1000-00000024", "trunksal=3") in new stack -- Executing [005714013434@externas:5] Set("SIP/1000-00000024", "extsal=2") in new stack -- Executing [005714013434@externas:6] NoOp("SIP/1000-00000024", "Hay 2 llamadas desde la extension 1000 y 3 con el proveedor Justvoip") in new stack -- Executing [005714013434@externas:7] GotoIf("SIP/1000-00000024", "1?busy") in new stack -- Goto (externas,005714013434,10) -- Executing [005714013434@externas:10] Playback("SIP/1000-00000024", "all-outgoing-lines-unavailable") in new stack -- <SIP/1000-00000024> Playing 'all-outgoing-lines-unavailable.ulaw' (language 'es')[Feb 6 11:52:16] NOTICE[3578]: channel.c:4148 __ast_read: Dropping incompatible voice frame on SIP/1000-00000024 of format alaw since our native format has changed to 0x4 (ulaw) -- SIP/justvoip-00000023 answered SIP/1000-00000022 -- Started music on hold, class 'default', on SIP/justvoip-00000023 -- Executing [005714013434@externas:11] Hangup("SIP/1000-00000024", "") in new stack

Con el comando sip show inuse, a lo largo de la segunda llamada, aparecerá:

CLI> sip show inuse* Peer name In use Limit1000 1/0/0 21474836471001 1/0/0 21474836471002 0/0/0 2147483647justvoip 2/0/0 2147483647

Cuando la extensión 1000 intenta sacar la tercera llamada, el Gotoif es verdadero y el dialplan sigue desde la prioridad con la etiqueta busy anunciando que no hay más linea salientes disponibles.

153

Page 165: Libro Asterisk 1.8.X - Versión 1.0 (1)

154

Page 166: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 167: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO VIII

IVR

IVR es la sigla de Interactive Voice Response, que se traduce del inglés como Respuesta de Voz Interactiva. Consiste en un central telefónica (en este caso Asterisk) que es capaz de recibir una llamada e interactuar con el usuario a través de grabaciones de voz y el reconocimiento de respuestas a través del uso de las teclas del teléfono. Algunos ejemplos: el menú que se escucha cuando se llama un centro de atención al cliente; los bancos que permiten hacer consultas o pagos a través de un menú vocal. En el lenguaje técnico habría que diferenciar dos tipos de sistemas:

• El IVR permite hacer consulta a base de datos, devolver los resultados y, en general, interactuar de forma activa con el usuario.

• la contestadora automática permite navegar entre menús vocales permitiendo elegir entre distintos menús hasta llegar a la información que se está buscando

En este capitulo se presentará la configuración de una contestadora automática.

8.1 Grabación de las locuciones

En Asterisk con la aplicación Record se pueden grabar archivos audios para luego utilizarlos en la creación de un IVR. Para implementarla hay que modificar el dialplan.

nano /etc/asterisk/extensions.conf

En el contexto internas se pone el siguiente bloque:

exten => _66XX,1,Answer()same => n,Wait(2)same => n,Record(/tmp/prompt${EXTEN:2}:wav)same => n,Wait(2)same => n,Playback(/tmp/prompt${EXTEN:2})same => n,Wait(2)same => n,Hangup()

• Línea 1: contesta la llamada• Línea 2: espera 2 segundos• Línea 3: Graba el archivo audio en la carpeta /tmp con nombre promptXX donde XX son los

últimos dos dígitos de la extensión que se ha marcado desde el Softphone. Ejemplo: Si se llama la extensión 6650 el archivo audio tendrá el nombre prompt50.waw

• Línea 4: espera 2 segundos• Línea 5: devuelve el archivo recién grabado• Línea 6: espera 2 segundos• Línea 7: cuelga la llamada

Page 168: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si la grabación no es satisfactoria, se vuelve a grabar marcando el mismo numero. La nueva grabación remplazará la vieja.

IMPORTANTE: para terminar la grabación hay que presionar la tecla numero #

Se actualiza el dialplan:

asterisk -rvvvvvvvvvvvvvvvv

CLI> dialplan reload

CLI> quit

Esta solución permite grabar hasta 99 archivos audio. Para el ejemplo a seguir hay que grabar tres archivos de audio que contengan las siguientes frases:

• prompt01.wav - “for english press one, para español marque dos”• prompt02.wav - “para efectuar un test de eco marque 1, para escuchar la música en espera

marque 2, para la oficina de ventas marque 3”• prompt03.wav - “for echo test press 1, for music on hold press 2, for sales office, press 3”

Desde la extensión 1000 se marca 6601 y se graba la primera frase; luego 6602 y se graba la segunda; se termina con 6603 y se graba la tercera. Una vez terminadas las grabaciones se crea un nueva carpeta:

mkdir /var/lib/asterisk/sounds/custom

y se mueven los tres archivos (prompt01.wav prompt02.wav y prompt03.wav) a la carpeta creada

cd /tmp

mv prompt* /var/lib/asterisk/sounds/custom

El formato audio de las locuciones es Wav. A veces es útil y aconsejable crear las mismas locuciones en otros formatos audio; esto para que Asterisk no tenga que decodificar y codificar las locuciones a otro formato audio según el codec configurado en el teléfono IP o softphone de quien está llamando. Este proceso se llama transcoding y utiliza bastantes recursos del servidor. Para crear las locuciones en otros formatos audio hay un comando disponible en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvv

Asterisk de manera predefinida busca las locuciones en la carpeta /var/lib/asterisk/sounds. Como han sido copiadas en la carpeta custom, el comando será:

CLI> file convert custom/prompt01.wav custom/prompt01.ulaw

157

Page 169: Libro Asterisk 1.8.X - Versión 1.0 (1)

De esta forma se convierte la locución al formato audio ulaw

CLI> file convert custom/prompt01.wav custom/prompt01.alaw

para el formato alaw.

Para conocer la sinopsis del comando record:

CLI> core show application record

CLI> quit

8.2 Configuración numero geográfico

Cuando se adquiere un numero geográfico, la empresa que lo vende, facilita siempre el rango de IP de donde ella envía los INVITE para las llamadas entrantes. Esta lista de IP hay que incluirla en el sip.conf sino las llamadas no serán autenticadas pues serán rechazadas.

Otra cosa que el proveedor permite, es configurar el “Mapping”, es decir definir que dirección SIP o numero de teléfono hay que llamar cuando entre una llamada al numero geográfico. Esto normalmente se hace desde el panel de control que cada cliente tiene a disposición. Para una idea de como funciona y de como se configuran los números geográficos, puede visitar la pagina de la empresa VozToVoice.

El el caso que se adquiera un numero geográfico, al momento de configurarlo, en “Ingresar Nombre Dominio o Dirección IP “ se pone la dirección IP del servidor y en “Usuario o Extensión” la letra s. Con ese numero ya se puede hacer una primera prueba. Desde la extensión 1000 se marca el numero. La sintaxis es 00 + código país + numero geográfico. El resultado en la consola de Asterisk será:

NOTICE[7577]: chan_sip.c:20701 handle_request_invite: Sending fake auth rejection for device "6620016037" <sip:[email protected]>;tag=as4dbd19b8

Asterisk no puede autenticar el INVITE en entrada

Para solucionar el problema hay que añadir en el sip.conf de Asterisk todas las direcciones IP de donde puede llegar una llamada. Estas direcciones están configuradas en un archivo que se descargará:

cd /etc/asterisk

wget http://www.voztovoice.org/tmp/didvoztovoice

Ahora se incluye el archivo didvoztovoice en el sip.conf aprovechando el comando include:

nano sip.conf

al final del archivo se añade:

158

Page 170: Libro Asterisk 1.8.X - Versión 1.0 (1)

#include didvoztovoice

El comando #include toma un archivo de texto y lo engloba en la configuración. Se guardan los cambios, se entra en la consola de Asterisk y se recarga la configuración SIP:

asterisk -rvvvvvvvvvvvvvvvvvv

CLI> sip reload

Segunda prueba: se marca nuevamente el numero se mira que pasa en la consola de Asterisk:

NOTICE[7577]: chan_sip.c:20785 handle_request_invite: Call from '46.19.209.78' to extension 's' rejected because extension not found in context 'from-voztovoice'

Ya la llamada no viene rechazada sino que no se puede enviar a ninguna parte del dialplan porque no Asterisk no encuentra el contexto from-voztooice. Más adelante se creará ese contexto

8.3 Creación del IVR

Con la locuciones grabadas, ya se puede configurar el IVR. Para hacerlo se crea un nuevo archivo que luego se incluirá en el dialplan.

nano /etc/asterisk/IVR

se copian los tres bloques que siguen:

[IVR]exten => s,1,Wait(1)exten => s,2,Set(CHANNEL(language)=es)exten => s,3,Set(TIMEOUT(digit)=7)exten => s,4,Set(TIMEOUT(response)=10)exten => s,5,BackGround(custom/prompt01)exten => s,6,WaitExten()exten => 1,1,goto(IVR1,s,1)exten => 2,1,goto(IVR2,s,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR,s,2)exten => i,3,Hangupexten => t,1,goto(IVR,s,2)exten => h,1,Hangup

[IVR1]exten => s,1,Set(TIMEOUT(digit)=7)exten => s,2,Set(TIMEOUT(response)=10)exten => s,3,Set(CHANNEL(language)=en)exten => s,4,BackGround(custom/prompt03)

159

Page 171: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => s,5,WaitExten()exten => 1,1,Playback(demo-echotest)exten => 1,2,Echo()exten => 2,1,MusicOnHoldexten => 3,1,Playback(pls-wait-connect-call)exten => 3,2,Goto(internas,100,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR1,s,1)exten => i,3,hangupexten => t,1,goto(IVR1,s,1)exten => h,1,Hangup

[IVR2]exten => s,1,Set(TIMEOUT(digit)=7)exten => s,2,Set(TIMEOUT(response)=10)exten => s,3,Set(CHANNEL(language)=es)exten => s,4,BackGround(custom/prompt02)exten => s,5,WaitExten()exten => 1,1,Playback(demo-echotest)exten => 1,2,Echo()exten => 2,1,MusicOnHoldexten => 3,1,Playback(pls-wait-connect-call)exten => 3,2,Goto(internas,100,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR2,s,1)exten => i,3,hangupexten => t,1,goto(IVR2,s,1)exten => h,1,Hangup

Se guardan los cambios. Una explicación de las nueva funciones y aplicaciones que aparecen en el IVR:

• Wait(1) – Espera un segundo• Set(CHANNEL(language)=es) – Se pone como idioma predefinido para las locuciones el

español• Set(TIMEOUT(digit)=7) – numero de segundos máximo (7) entre el primer dígito y los

siguientes• Set(TIMEOUT(response)=10) – numero de segundos que el sistema esperará para que el

llamante presione una tecla del teléfono.• BackGround(custom/prompt01) – presenta la locución prompt01 y al mismo tiempo se pone a

la escucha de los dígitos que pueda presionar el llamante.• WaitExten() - Espera que el llamante presione una tecla• 1,1,goto(IVR1,s,1) – si el llamante presiona 1 va (goto) al contexto IVR1, extensión s, prioridad

1• 2,1,goto(IVR2,s,1) – si el llamante presiona 2, va (goto) al contexto IVR2, extensión s,

prioridad 1

160

Page 172: Libro Asterisk 1.8.X - Versión 1.0 (1)

• i,1,Playback(invalid) – si la tecla presionada no es valida (ni 1 ni 2) comunica el error• i,2,Goto(IVR,s,2) – y devuelve el llamante al contexto IVR, extensión s, prioridad 2 (presenta

nuevamente el menú inicial)• t,1,goto(IVR,s,2) – si dentro de 10 segundos (TIMEOUT(response)), el llamante no presiona

ninguna tecla, vuelve a presentar el menú inicial• h,1,Hangup – si el llamante cuelga, se ejecuta la extensión h

La extensión i se utiliza para capturar dentro del dialplan, dígitos errados.La extensión t se utiliza cuando la función TIMEOUT está presente en el dialplanLa extensión h se utiliza para añadir nuevas lineas de dialplan cuando se cuelga la llamada

El segundo bloque del IVR es bastante parecido y envía el llamante a la extensión que haya digitado. La parte interesante es que si se digita el numero tres, la llamada se enviará al contexto internas, extensión 100, prioridad 1

Como esa extensión todavía no existe, hay que crearla:

nano /etc/asterisk/extensions.conf

en el contexto internas se añade el siguiente bloque:

exten => 100,1,Noopsame => n,Dial(SIP/1000&SIP/1001&SIP/1002,30)same => n,Hangup

Lo que se hará es marcar a las extensiones 1000, 1001 y 1002 simultáneamente hasta que una de las tres conteste la llamada. Este tipo de configuración se llama Ring Group.

Para que todas las llamadas externas sean atendidas por el IVR, antes del contexto internas, se añade este bloque:

[from-didvoztovoice]exten => s,1,Answersame => n,Goto(IVR,s,2)same => n,Hangup

from-didvoztovoice es el contexto donde llegarán las llamadas al numero geográficos (configurado para cada troncal IP presente en el archivo didvoztovoice).

Para probar el IVR en local se añaden estas lineas en el contexto internas:

exten => 75,1,Answersame => n,Wait(1)same => n,Goto(IVR,s,1)

y para incluir el archivo IVR al dialplan, al final del archivo se añade esta linea

161

Page 173: Libro Asterisk 1.8.X - Versión 1.0 (1)

#include IVR

Se guardan los cambios y desde la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000, se marca la extensión 75 para probar el IVR desde local.

Al momento de crear un IVR, las posibilidades son prácticamente infinitas. Ejemplos:

• un IVR que gestione colas de espera diferenciadas por departamento (ventas, compras, asistencia técnica, etc.)

• un IVR que permita marcar directamente una extensión o, en el caso que no se marque ninguna, envíe la llamada a una operadora.

• un IVR que avise el llamante que las oficinas están cerradas y que envíe la llamada al buzón de voz

162

Page 174: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 175: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO IX

Funcionalidades avanzadas de Asterisk – features.conf

El archivo features.conf es donde se configuran las funcionalidades avanzadas de Asterisk que luego se pueden utilizar a lo largo de una llamada.. Estas son:

• Parqueo de las llamadas• Transferencia ciega y asistida• Captura de las llamadas (Pickup)• Grabación de las llamadas

9.1 features.conf

A seguir la tabla con los parámetros del archivo y la descripción. En negrita la opción que se utilizará para cada parámetro. Al final de tabla, la configuración completa del archivo.

Parámetro Descripción[general] Inicia la parte general del archivoparkext => 700 = numero de extensión donde transferir una llamada para

parquearlaparkpos => 701-709 = numero de extensiones reservadas para parquear las

llamadasparkinghints no = las prioridades Hint para monitorear el estado de las

extensiones dedicadas al parqueo hay que configurarlas manualmente en el dialplan. Con yes se crean de forma automática

parkingtime => Numero de segundos que quedará parqueada una llamadas. Pasado ese tiempo la llamada se transfiere a la extensión definida en el próximo parámetro. Valor 45

comebacktoorigin yes = la llamada parqueada se transfiere a la extensión que la parqueó. Con no se envía al contexto parkedcallstimeout, extensión s, prioridad 1. En ese caso hay que crear el contexto en el dialplan

courtesytone Locución que se enviará al canal parqueado cuando alguien lo llama o cuando se activa/desactiva la grabación de la llamada Valor beep

parkedplay Define a quien hay que enviar el courtesytone. Puede ser:• parked (canal parqueado)• caller (quien llama un canal parqueado)• both (ambos)

parkedcalltransfers Activa o desactiva la secuencia de tonos para transferir la llamada cuando es una llamada parqueada. Puede ser:

• callee (llamado)• caller (llamante)

Page 176: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

• both (ambos)• no (no permitido)

parkedcallreparking Activa o desactiva la secuencia de tonos para parquear la llamada cuando es una llamada parqueada. Puede ser:

• callee (llamado)• caller (llamante)• both (ambos)• no (no permitido)

parkedcallhangup Activa o desactiva la secuencia de tonos para terminar una llamada cuando es una llamada parqueada. Puede ser:

• callee (llamado)• caller (llamante)• both (ambos)• no (no permitido)

parkedcallrecording Activa o desactiva la secuencia de tonos para grabar una llamada cuando es una llamada parqueada. Puede ser:

• callee (llamado)• caller (llamante)• both (ambos)• no (no permitido)

parkedmusicclass La clase de música en espera que escuchará el canal que ha sido parqueado. Valor default

transferdigittimeout => Numero de segundos de espera entre los dígitos cuando se está transfiriendo una llamada. Valor 5

xfersound La locución que avisará que la transferencia de llamada asistida ha tenido éxito. Valor beep

xferfailsound La locución que avisará que la transferencia de llamada no ha tenido éxito. Valor beeperr

pickupexten Secuencia de tonos para capturar la llamada de una extensión que está timbrando. Depende de la configuración de los parámetros callgroup y pickupgroup de cada extensión. Valor *8

pickupsound La locución que avisará que la captura de llamada ha tenido éxito. Valor beep

pickupfailsound La locución que avisará que la captura de llamada no ha tenido éxito. Valor beeperr

featuredigittimeout Tiempo máximo de espera entre los dígitos para activar las funcionalidades definidas después de la etiqueta [featuremap] (en mili segundos) Valor 2000

atxfernoanswertimeout Tiempo máximo disponible para contestar una transferencia asistida

165

Page 177: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción(en segundos). Valor 15

atxferdropcall Si quien transfiere una llamada con el método “asistido” cuelga antes que la llamada sea transferida completamente, Asterisk devuelve la llamada a quien la estaba transfiriendo. Si está en yes la llamada no se devuelve y se considera terminada. Valor no

atxferloopdelay Numero de segundos de espera antes de intentar nuevamente devolver la llamada (si atxferdropcall = no). Valor 10

atxfercallbackretries Numero de veces que se intentará devolver una llamada transferida a quien la transfirió sin éxito. Valor 2

;[parkinglot_empresa2] Se puede crear más de un bloque de extensiones para parquear las llamadas. Un ejemplo es si quiere diferenciar las llamadas parqueadas por el departamento de ventas, de las llamadas parqueadas por el departamento de compras. La etiqueta define el nuevo bloque y los tres parámetros que siguen el contexto, el numero de las extensiones reservadas y como se van utilizando las extensiones. Para asignar una extensión a un determinado “slot” de parqueo, en la configuración de la extensión en el sip.conf, parámetro parkinglot, se pone el nombre del contexto presente en la linea que sigue. Se dejan las cuatro lineas comentadas.

;context => empresa2;parkpos => 801-810;findslot => next[featuremap] A partir de esta etiqueta empieza la configuración de las

funcionalidadesblindxfer => # = tecla para activar la transferencia ciegadisconnect => *0 = secuencia de dígitos para terminar una llamadaautomon => *1 = secuencia de dígitos para iniciar la grabación de la llamada (en

dos archivos audio, uno para cada canal)atxfer => *2 = secuencia de dígitos para activar la transferencia asistidaparkcall => *7 = secuencia de dígitos para parquear una llamada (se puede usar

esta secuencia o #700)automixmon => *3 = secuencia de dígitos para iniciar la grabación de una llamada

(en un único archivo audio donde se mezclarán los dos canales audio)

[applicationmap] A partir de esta etiqueta se pueden configurar funcionalidades personalizadas. La sintaxis es: <FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>[,MOH_Class]]

166

Page 178: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

• FeatureName: El nombre de la funcionalidad;• DTMF_sequence: la secuencia de dígitos para activar la

funcionalidad;• ActivateOn: aquí se define para quien activar la

funcionalidad. Los valores son self y peer. Con self la funcionalidad se activa para quien la activa, con peer para el otro canal;

• ActivatedBy: Este parámetro define quien tiene acceso a la funcionalidad. Las opciones son: caller (llamante), callee (llamado), both (ambos);

• Application: La aplicación que se va a ejecutar;• AppArguments: Las opciones asociadas a la aplicación;• MOH_Class: la clase de música en espera que escuchará el

canal libre mientras se ejecuta la funcionalidad en el otro canal.

test1 => *9,peer,Playback,tt-monkeys,default = Digitando la secuencia *9 desde un canal, el otro escuchará la locución tt-monkeys mientras el canal que activó la funcionalidad, escuchará la música en espera

Antes de crear el archivo una pequeña explicación de la diferencia entre transferencia ciega y transferencia asistida:

• blinxfer: A lo largo de una conversación se quiere transferir la llamada a otra extensión. Hay que presionar la tecla # y luego el numero de la extensión. La llamada será transferida y el el canal de quien la transfirió será colgado

• atxfer: A lo largo de una conversación se quiere transferir la llamada a otra extensión. Se presiona la secuencia *2 y luego el numero de la extensión donde se quiere transferir la llamada. Se escuchará timbrar la extensión y una vez que el interlocutor conteste, se podrá hablar con él (por ejemplo para anunciar la llamada que se va a transferir). Solamente cuando se colgará la llamada será efectivamente transferida.

Ahora se crea el archivo de configuración features.conf. Se renombra el predefinido:

mv /etc/asterisk/features.conf /etc/asterisk/features.conf.old

se crea uno nuevo

nano /etc/asterisk/features.conf

y se copian las lineas que siguen:

[general]parkext => 700parkpos => 701-709

167

Page 179: Libro Asterisk 1.8.X - Versión 1.0 (1)

parkinghints=noparkingtime => 45comebacktoorigin=yescourtesytone=beepparkedplay=bohtparkedcalltransfers=callerparkedcallreparking=callerparkedcallhangup=callerparkedcallrecording=callerparkedmusicclass=defaulttransferdigittimeout => 5xfersound=beepxferfailsound=beeperrpickupexten=*8pickupsound=beeppickupfailsound=beeperrfeaturedigittimeout=2000atxfernoanswertimeout=15atxferdropcall=noatxferloopdelay=10atxfercallbackretries=2

;[parkinglot_empresa2];context => empresa2;parkpos => 801-810;findslot => next

[featuremap]blindxfer => #disconnect => *0automon => *1atxfer => *2parkcall => *7automixmon => *3

[applicationmap]test1 => *9,peer,Playback,tt-monkeys,default

Se guardan los cambios. Para volver disponibles estas funcionalidades hay que modificar el plan de llamadas. Se va a recoger la configuración del archivo así como se dejó en el modulo anterior. En negrita aparecen las modificaciones:

nano /etc/asterisk/extensions.conf

[general]static=yeswriteprotect=yse

168

Page 180: Libro Asterisk 1.8.X - Versión 1.0 (1)

autofallthrough=yseextenpatternmatchnew=yseclearglobalvars=no

[globals]1000=SIP/1000JUST=SIP/justvoipmarko=IAX2/markoDYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon

[from-didvoztovoice]exten => s,1,Answersame => n,Goto(IVR,s,2)same => n,Hangup

[internas]exten => 50,1,Set(PBX=${ENV(LANG)})same => n,Noop(Idioma Servidor ${PBX})same => n,Hangup

exten => 75,1,Answersame => n,Wait(1)same => n,Goto(IVR,s,2)

exten => 100,1,Noopsame => n,Dial(SIP/1000&SIP/1001&SIP/1002,30)same => n,Hangup

exten => 123,1,Answersame => n,Dumpchansame => n,Playback(hello-world)same => n,Hangup

exten => 150,1,Answersame => n,Playback(demo-echotest)same => n,Echosame => n,Playback(demo-echodone)same => n,Hangup

exten => 200,1,Answersame => n,Jabbersend(campus.voztovoice,[email protected],Estamos escuchando MP3)same => n,MusicOnHold(mp3,60)same => n,Hangup

exten => _100[0-2],1,Macro(disponible)same => n,Dial(SIP/${EXTEN},45)same => n,Hangup

169

Page 181: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 1234,1,Dial(IAX2/marko,30)same => n,Hangup

exten => _66XX,1,Answer()same => n,Wait(2)same => n,Record(/tmp/prompt${EXTEN:2}:wav)same => n,Wait(2)same => n,Playback(/tmp/prompt${EXTEN:2})same => n,Wait(2)same => n,Hangup()

exten => _[a-z].,1,Dial(gtalk/campus.voztovoice/${EXTEN},30)same => n,Hangup

exten => 10000,1,Dial(gtalk/campus.voztovoice/[email protected],30)same => n,Hangup

exten => _8.,1,Dial(SIP/spa3102,45,D(${EXTEN:1}))same => n,Busy(3)same => n,Hangup

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/R1/${EXTEN:1},45)same => n,Hangup [auten]exten => _00.,1,NoOPsame => n,Authenticate(/tmp/pin.txt,am,4)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001exten => 1002,hint,SIP/1002exten => marko,hint,IAX2/markoexten => 701,hint,park:701@parkedcallsexten => 702,hint,park:702@parkedcallsexten => 703,hint,park:703@parkedcallsexten => 704,hint,park:704@parkedcallsexten => 705,hint,park:705@parkedcallsexten => 706,hint,park:706@parkedcallsexten => 707,hint,park:707@parkedcallsexten => 708,hint,park:708@parkedcallsexten => 709,hint,park:709@parkedcalls

[google-in]

170

Page 182: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => s,1,NoOp( Call from Gtalk )same => n,SendText(Hola,Como te llamas?)same => n,Set(nombre=${JABBER_RECEIVE(campus.voztovoice,${CALLERID(name)},20)})same => n,SendText(Hola ${nombre}, bienvenido en VozToVoice)same => n,Set(CALLERID(name)=${nombre})same => n,Wait(2)same => n,SendText(Espera un momento mientras te comunicamos con un operador)same => n,Dial(SIP/1000,30)same => n,Hangup()

[from-spa3102]exten => s,1,NoOpsame => n,Dial(SIP/1000)same => n,Hangup

[from-pstn]exten => s,1,Dial(SIP/1000,45)exten => s,n,Hangup

[internacio]exten => _00X.,1,NoOpsame => n,Set(GROUP(voip)=justvoip)same => n,Set(GROUP(salida)=${CALLERID(num)})same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)})same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)})same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip)same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangupsame => n(busy),Playback(all-outgoing-lines-unavailable)same => n,Hangup

exten => _1XXXXXXXXXX,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

exten => _NNXX.,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

[externas]include => internasinclude => internacioinclude => parkedcalls

[locales]include => internasinclude => auten

171

Page 183: Libro Asterisk 1.8.X - Versión 1.0 (1)

include => parkedcalls

[macro-disponible]exten => s,1,Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})})exten => s,n,Gotoif($["${estado}" = "NOT_INUSE"]?5)exten => s,n,Busyexten => s,n,Hangupexten => s,n,MacroExit

#include IVR

Para que las funcionalidades configuradas en features.conf sean activas hay que definir la variable DYNAMIC_FEAUTURES y añadirle todas las funcionalidades que se han configurado. Después de la etiqueta [subscribe] se han añadido nueve líneas para poder monitorear el estado de las extensiones utilizadas para parquear las llamadas. De esta forma siempre se podrá saber cuantas llamadas están parqueadas (en los teléfonos IP software y hardware que soportan esta funcionalidad).

Para terminar en las etiquetas [externas] y [locales] se ha añadido el contexto parkedcalls. Todas las extensiones que tengan acceso al contexto externas, además de tener acceso al contexto internas y internacio, tendrán acceso al contexto parkedcalls es decir podrán llamar una extensión parqueada. Lo mismo para las extensiones que tienen acceso al contexto [locales].

Hay tres aplicaciones relacionadas con el parqueo de llamadas que se pueden utilizar en el dialplan:

• Park• ParkAndAnnounce• ParkedCall

Se guardan los cambios y se reinicia Asterisk:

/etc/init.d/asterisk restart

Desde la consola de Asterisk podemos ver las funcionalidades activadas.

asterisk -rvvvvvvvvvvvv

CLI> features show

Builtin Feature Default Current--------------- ------- -------Pickup *8 *8Blind Transfer # #Attended Transfer *2One Touch Monitor *1Disconnect Call * *0Park Call *7

172

Page 184: Libro Asterisk 1.8.X - Versión 1.0 (1)

One Touch MixMonitor *3

Dynamic Feature Default Current--------------- ------- -------test1 no def *9

Feature Groups:---------------(none)

Call parking (Parking lot: default)------------Parking extension : 700Parking context : parkedcallsParked call extensions: 701-709

9.2 Callgroup y Pickupgroup

En todas las extensiones SIP configuradas se han definido los siguientes parámetros:

callgroup=1pickupgroup=1

¿Qué significa?

Significa que todas las extensiones pertenecen al grupo de llamadas 1 y pueden capturar las llamadas del grupo de llamadas 1. La secuencia de dígitos para capturar una llamada se acaba de configurar el el archivo features.conf y es *8.

Una configuración un poco más compleja podría ser:

Extensiones ventas:

1000 - 1001 - 1002

Extensiones soporte:

2000 - 2001 - 2002

Extensiones compras:

3000 - 3001 - 3002

Extensión oficina dirección:

4000

173

Page 185: Libro Asterisk 1.8.X - Versión 1.0 (1)

El escenario es que cada trabajador de cada departamento pueda capturar las llamadas de los teléfonos del departamento en que trabaja y que desde la oficina de dirección se pueda capturar las llamadas de cualquier extensión de cualquier departamento. Para que esto sea posible, en la configuración de cada extensión se pone:

[1000]callgroup=1pickupgroup=1

[1001]callgroup=1pickupgroup=1

[1002]callgroup=1pickupgroup=1

[2000]callgroup=2pickupgroup=2

[2001]callgroup=2pickupgroup=2

[2002]callgroup=2pickupgroup=2

[3000]callgroup=3pickupgroup=3

[3001]callgroup=3pickupgroup=3

[3000]callgroup=3pickupgroup=3

[4000]callgroup=4pickupgroup=1,2,3

La extensión 4000, con el parámetro pickupgroup configurado con 1,2,3 podrá capturar las llamadas de

174

Page 186: Libro Asterisk 1.8.X - Versión 1.0 (1)

las extensiones que perteneces a uno de los grupos configurados, es decir:

• grupo 1 – 1000,1001,1002• grupo 2 – 2000,2001.2002• grupo 3 – 3000,3001,3002

9.3 Aplicación Dial y features.conf

En este párrafo se ilustrará como integrar en el dialplan las funcionalidades configuradas en el archivo features.conf utilizando la aplicación Dial.

La sintaxis de la aplicación Dial:

Dial(Technology/resource[&Tech2/resource2...][,timeout][,options][,URL]):

• Dial: el nombre de la aplicación que nos permite efectuar una llamada• Technology: el protocolo o la tecnología usada para efectuar la llamada (ej: SIP, IAX2)• resource: el recurso utilizado para hacer la llamada o el numero de extensión a llamar• timeout: define los segundos dentro de los cuales la llamada tiene que ser contestada• options: son las opciones que podemos añadir a la aplicación• URL: para enviar una dirección Web a la extensión llamada (si el teléfono soporta la

funcionalida)

Algunos ejemplos:

exten => 1000,1,Dial(SIP/1000,45)same => n,,Hangup

Si se marca la extensión 1000 Asterisk llamará dicha extensión usando el protocolo SIP, esperará 30 segundos. Si la extensión 1000 no contesta dentro de los treinta segundos, Asterisk procesará la línea siguiente del dialplan, es decir terminará la llamada.

exten => 00573001000000,1,Dial(SIP/justvoip/00573001000000,45)same => n,,Hangup

En este caso si desde un SoftPhone o IP Phone conectados a la centralita se marca el numero 0057300100000, Asterisk llamará dicho numero usando un proveedor VoIP (en este caso especifico Justvoip). Esperará una respuesta por 45 segundos y si nadie contesta terminará la llamada. Como tecnología se ha indicado SIP porque justvoip usa solo este tipo de protocolo. En el caso de proveedores que utilicen el protocolo IAX2 sería:

exten => 00573001000000,1,Dial(IAX2/justvoip/00573001000000,45)same => n,,Hangup

Para configurar las funcionalidades definidas en el archivo features.conf se tendrá que utilizar unas

175

Page 187: Libro Asterisk 1.8.X - Versión 1.0 (1)

opciones de la aplicación Dial.

exten => 100X,1,Dial(SIP/${EXTEN},45,hH)

Las opciones presentes:

• h: permite al llamado colgar la llamada presionando la secuencia de dígitos definida en features.conf

• H: permite al llamante colgar la llamada presionando la secuencia de dígitos definida en features.conf

exten => 100X,1,Dial(SIP/${EXTEN},45,kK)

• k: permite al llamado parquear la llamada presionando la secuencia de dígitos definida en features.conf

• K: permite al llamante parquear la llamada presionando la secuencia de dígitos definida en features.conf

exten => 100X,1,Dial(SIP/${EXTEN},45,tT)

• t: permite al llamado transferir la llamada presionando la secuencia de dígitos definida en features.conf

• T: permite al llamante transferir la llamada presionando la secuencia de dígitos definida en features.conf

exten => 100X,1,Dial(SIP/${EXTEN},45,wW)

• w: permite al llamado empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf. Asterisk, en este caso, creará dos archivos audio, uno por cada canal

• W: permite al llamante empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf. Asterisk, en este caso, creará dos archivos audio, uno por cada canal.

exten => 100X,1,Dial(SIP/${EXTEN},45,xX)

• x: permite al llamado empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf. La diferencia con las opciones w y W es que en este caso los dos canales (llamante y llamado) se grabaran en un único archivo audio

• X: permite al llamante empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf. La diferencia con las opciones w y W es que en este caso los dos canales (llamante y llamado) se grabaran en un único archivo audio

Si se quiere, por ejemplo, activar todas estas opciones a la vez, la aplicación Dial aparecerá de esta forma:

exten => _100X,1,Dial(SIP/ ${EXTEN},45,hHkKtTwWxX)

176

Page 188: Libro Asterisk 1.8.X - Versión 1.0 (1)

A seguir se presentarán algunos registros como aparecen en la consola de Asterisk al activar o desactivar las funcionalidades descritas.

Para terminar se modifica el dialplan para incluir estas funcionalidades en las llamadas entre extensiones. (en negrita los cambios):

nano /etc/asterisk/extensions.conf

exten => _100[0-2],1,Macro(disponible)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

Se actualiza el dialplan:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

En el X-Lite se añaden todas las extensiones reservadas para el parqueo de las llamadas. El resultado tienes que ser:

Ahora desde la extensión 1001 se marca la extensión 1002 y cuando esta conteste se parquea la llamada (con la secuencia de dígitos *7 o #700).

El resultado será:

177

Page 189: Libro Asterisk 1.8.X - Versión 1.0 (1)

La extensión 1002 esta parqueada en la extensión 701. Desde el X-Lite, presionando el botón derecho del ratón sobre la linea de la extensión 701 se podrá llamar la extensión parqueada es decir la extensión 1002.

Otra prueba que se puede hacer es grabar la llamada utilizando la secuencia de dígitos *3 para tener un solo archivo audio de toda la conversación.

Desde la extensión 1001 se marca nuevamente a las 1002 y cuando esta conteste, se activa la grabación de la llamada digitando *3. En la consola de Asterisk aparecerá:

-- <SIP/1001-00000009> Playing 'beep.ulaw' (language 'es') -- User hit '*3' to record call. filename: auto-1318460210-1001-1002 == Begin MixMonitor Recording SIP/1002-0000000a -- <SIP/1001-00000009> Playing 'beep.ulaw' (language 'es')

Digitando nuevamente la secuencia *3 terminará la grabación de la llamada:

-- User hit '*3' to stop recording call. == MixMonitor close filestream == End MixMonitor Recording SIP/1002-0000000a

Se sale de la consola de Asterisk:

CLI> quit

Se averigua que se haya creado el archivo:

ls -l /var/spool/asterisk/monitor/-rw-r--r-- 1 root root 233964 Oct 12 17:57 auto-1318460210-1001-1002.wav

178

Page 190: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para probar la captura de llamada, se llama desde la extensión 1001 a la extensión 1002 y cuando ésta timbre, desde la extensión 1000 (X-Lite) se digita *8.

Si todo funciona bien, la llamada será capturada por la extensión 1000 que podrá hablar con la extensión 1001.

179

Page 191: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 192: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo X

Asterisk y los calendarios

Asterisk puede ser integrado con distintos formatos de calendarios. Esta nueva funcionalidad ha sido incluida desde la versión 1.8.X. Los formatos soportados son:

• iCalendar: es un estándar Internet (RFC5546) que ha sido utilizado por primera vez por Apple con su aplicación iCal

• CalDAV: es un estándar Internet (RFC4791) que permite a un cliente acceder a la información de eventos programados presentes en un servidor. Es una extensión del estándar Internet WebDAV (RCF 4918). Para el formato de los datos se apoya a iCalendar. Actualmente es utilizado por muchas aplicaciones, entre ellas, Google Calendar, Zimbra, Yahoo! Calendar y Thunderbird de Mozilla Fundation.

• MS Exchange: utilizado por Microsoft Exchange 2003• Ms Exchange Web Services: utilizado por Exchange 2007 y superiores.

Esto significa que Asterisk, oportunamente configurado, puede interactuar con estos formatos de Calendario. Los módulos que se encargan de esta integración son:

asterisk -rvvvvvvvvvvvvv

CLI> module show like res_calendarModule Description Use Countres_calendar.so Asterisk Calendar integration 1res_calendar_caldav.so Asterisk CalDAV Calendar Integration 0res_calendar_ews.so Asterisk MS Exchange Web Service Calenda 0res_calendar_icalendar.so Asterisk iCalendar .ics file integration 0res_calendar_exchange.so Asterisk MS Exchange Calendar Integratio 0

Para que estén activados en Asterisk, hay que compilar las siguientes dos librerías:

• Neon• libical

Al momento de ejecutar, desde la carpeta de las fuentes de Asterisk, el comando make menuselect, se averigua que los módulos estén habilitados:

Page 193: Libro Asterisk 1.8.X - Versión 1.0 (1)

10.1 calendar.conf

El archivo para la configuración de los calendarios es calendar.conf y se encuentra en la carpeta /etc/asterisk. En este archivo se puede configurar más de un calendario y cada uno será identificado por una etiqueta inicial. Para crear un entorno real, se simulará la conexión al calendario de Google, que se puede activar utilizando una cuenta Gmail registrada. A seguir la tabla con los parámetros de configuración. En negrita, la opción que se utilizará para cada parámetro. Al final de la tabla, la configuración completa del archivo.

Parámetro Descripción

[campusvoztovoice] Etiqueta que permite identificar el calendario que se está configurando. Personalizar

type Puede ser:• iCal• caldav• exchange (Microsoft Exhange 2003)• ews ( Microsoft Exchange 2007 y superiores)

Para Google Calendar el tipo es caldavurl La URL para conectarse al calendario. En el caso de GoogleCalendar la

sintaxis es:https://www.google.com/calendar/dav/[email protected]/events/Personalizar username@gmail con su cuenta de Google

user Nombre usuario gmail. En este ejemplo: [email protected] Personalizar

secret la contraseña del usuario Googlerefresh Cada cuantos minutos consultar el Calendario de Google para actualizar

los datos en Asterisk. Valor: 10timeframe Por cada consulta extraer los eventos que tendrán lugar en los próximos

N minutos. Este valor tiene que ser mayor del parámetro refresh. Valor: 180 (3 horas)

autoreminder Este parámetro anula cualquiera notificación configurada para un evento y la cambia por el valor indicado en minutos. Valor 10

channel Cuando falten los N minutos definidos en el parámetro autoreminder, es posible enviar una llamada a la extensión indicada en este parámetro. La sintaxis es: Tecnología/numero. Suponiendo que este calendario es asociado a la extensión 1000, se pone SIP/1000. A partir de los próximos parámetros podemos definir dos comportamientos distintos cuando la extensión 1000 conteste la llamada:

• enviar la llamada a un contexto, extensión definida• ejecutar una aplicación y definir sus parámetros.

context nombre del contexto: calendario

182

Page 194: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

extension numero de extensión: calappappdata

aplicación a ejecutar cuando la extensión conteste: Playbackopciones para la aplicación: demo-congrats

waittime este ultimo parámetro define el tiempo (en segundos) que tendrá la extensión 1000 para contestar la llamada. Valor 45

Con estos parámetros se configura el primer calendario. Como configuración predefinida, cuando la extensión 1000 conteste, se utilizarán los dos parámetros context/extension. Primero se crea una copia del archivo predefinido:

mv /etc/asterisk/calendar.conf /etc/asterisk/calendar.conf.old

y se crea uno nuevo:

nano /etc/asterisk/calendar.conf

[campusvoztovoice]type=caldavurl=https://www.google.com/calendar/dav/[email protected]/events/[email protected]=passwordrefresh=10timeframe=180autoreminder=10channel=SIP/1000context=calendarioextension=calwaittime=45;app= Playback;appdata=demo-conrats

IMPORTANTE: Personalizar los datos de la etiqueta inicial, el parámetro url, el parámetro user y el parámetro secret con los datos de su cuenta Google.

Se guardan los cambios

Ahora se entra en la pagina del calendario de Google y se van añadiendo una serie de eventos para el día en que se está configurando este modulo. En este ejemplo se han creado tres:

183

Page 195: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvvv

Se recarga el modulo calendario:

CLI> module reload res_calendar.so

Si aparece esta advertencia:

[Feb 7 16:20:09] WARNING[27477]: res_calendar_caldav.c:157 caldav_request: Unknown response to CalDAV calendar campusvoztovoice, request REPORT to /calendar/dav/[email protected]/events/: Could not read status line: connection was closed by server

significa que la configuración no está funcionando. ¿Por qué? Primero se descarta que sea un problema de la configuración de los datos en el archivo calendar.conf.

Se abre una ventana del navegador y se pega la url que aparece en el archivo calendar.conf. En este caso:

https://www.google.com/calendar/dav/[email protected]/events/

Aparecerá:

184

Page 196: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pone el nombre de usuario de Google y la contraseña. Se termina presionando el botón “Iniciar sesión”. Si la conexión tiene éxito aparecerá una ventana de descarga que pedirá de guardar un archivo de texto:

El archivo descargado contendrá todos los datos del calendario. Esto significa que los datos de configuración del archivo calendar.conf son correctos. Si se mira el parametro url del archivo, se notará que empieza con https, esto quiere decir que se basa en una conexión segura y que la librería que permite la conexión CalDAV (neon) debe implementar el protocolo SSL. ¿Será que Neon no se ha compilado con el soporte SSL?

Se entra en la carpeta de las fuentes de neon:

cd /usr/src/neon-0.29.6

y se lanza nuevamente un configure:

./configure

Cuando el comando termine:

Por defecto neon no se compila con el soporte SSL, pues para solucionar el problema hay que volver a compilar neon y luego Asterisk:

185

Page 197: Libro Asterisk 1.8.X - Versión 1.0 (1)

make distclean

./configure --prefix=/usr --with-ssl=openssl

Ahora si se compiló con el soporte SSL. Se termina la compilación e instalación:

makemake install

Ahora hay que volver a compilar Asterisk. Primero se para el servicio:

service asterisk stop

Se entra en la carpeta de las fuentes:

cd /usr/src/asterisk-1.8.11.0

se borra la compilación anterior:

make distclean

se vuelve a compilar:

./configure

Se necesita volver a entrar en la interfaz gráfica para seleccionar los módulos Add-ons ya que por defecto no están seleccionados:

make menuselect

186

Page 198: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se vuelve a compilar:

makemake install

Terminada esta operación, se inicia nuevamente Asterisk:

service asterisk start

Se entra en la consola y se recarga nuevamente el modulo Calendario:

asterisk -rvvvvvvvvvvvvv

CLI> module reload res_calendar.so

Si no aparecen errores y/o advertencias significa que esta vez la conexión al calendario de Google ha tenido éxito y se debería poder ver algunos eventos programados.

CLI> calendar show calendars

Con este comando aparecerá la lista de calendarios configurados y el estados de cada uno:

Calendar Type Status-------- ---- ------campusvoztovoice caldav free

Con este comando:

CLI> calendar show calendar campusvoztovoice

se pueden ver los eventos programados en los próximos 180 minutos (parámetro timeframe=180). Si no aparecen es porque todavía Asterisk no ha actualizado la información ya que lo hace cada 10 minutos (parametro refresh=10). Modificar campusvoztovoice con el nombre de su calendario.

187

Page 199: Libro Asterisk 1.8.X - Versión 1.0 (1)

Aparece el evento de las 7:30 y el evento de las 9:30. El evento programado a las 11 no aparece porque el modulo está configurado para que lea los eventos de los próximos 180 minutos. Ahora para que la llamada llegue a la extensión 1000 hay que crear el contexto calendario y la extensión cal (como configurado en el archivo calendar.conf). ¿Cómo se construye el dialplan para que la extensión 1000 pueda saber que cita está para iniciar?. Hay que instalar un sistema de texto a voz que lea un texto y lo transforme en audio.

Lefteris Zafiris, ha desarrolado un AGI que se conecta al sistema de texto a voz de Google y transforma un texto en audio. Aunque la parte de los AGI se verá de manera más detallada en el ultimo modulo del curso, en este caso se implementará esta solución. Para que el AGI funcione, los requisitos son:

• Paquete Perl• Paquete perl-libwww• sox

188

Page 200: Libro Asterisk 1.8.X - Versión 1.0 (1)

• mpg123• el servidor donde está instalado Asterisk debe tener acceso a Internet

Como sox ya está instalado, se instalan los paquetes de perl:

yum install perl perl-libwww-perl

se descarga, compila e instala mpg123:

cd /usr/srcwget http://downloads.sourceforge.net/project/mpg123/mpg123/1.13.4/mpg123-1.13.4.tar.bz2tar -xf mpg123-1.13.4.tar.bz2cd mpg123-1.13.4./configure --prefix=/usrmakemake install

Ya se puede descargar el archivo que contiene el AGI:

cd /usr/src

wget http://www.voztovoice.org/campus/pbx18/asterisk-googletts-0.5.tar.gz

Se descomprime:

tar -xf asterisk-googletts-0.5.tar.gz

Se entra en la carpeta creada:

cd asterisk-googletts-0.5

Por defecto Asterisk busca los AGI en la carpeta /var/lib/asterisk/agi-bin. Por eso se copia el AGI en esa carpeta y se vuelve ejecutable:

cp googletts.agi /var/lib/asterisk/agi-bin/chmod +x /var/lib/asterisk/agi-bin/googletts.agi

Por ultimo se modifica el dialplan:

nano /etc/asterisk/extensions.conf

y antes del contexto internas se crea el nuevo contexto:

[calendario]exten => cal,1,NoOp(Llamada desde el calendario)same => n,Agi(googletts.agi,"${CALENDAR_EVENT(summary)}.",es)

189

Page 201: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Agi(googletts.agi,"a las ${STRFTIME(${CALENDAR_EVENT(start)},,%H:%M)}.",es)same => n,Wait(1)same => n,Playback(goodbye)same => n,Hangup

En la segunda y tercera linea se inicia el AGI y se leen las variables ${CALENDAR_EVENT(summary)} y ${CALENDAR_EVENT(start)} que contienen el titulo del evento y la hora de inicio respectivamente. Como la hora se lee en el formato EPOCH, hay que transformarla en el formato de hora y minutos a través de la función STRFTIME

Se recarga el dialplan:

asterisk -rx "dialplan reload"

10 minutos antes del inicio del evento, Asterisk llamará la extensión 1000 y cuando esta conteste, le anunciará el tipo de evento y la hora en que va a iniciar. La llamada llegará siempre con este CALLERID:

Cuando el evento iniciará en el calendario aparecerá el estado ocupado:

asterisk -rvvvvvvvvvvvvvv

CLI> calendar show calendarsCalendar Type Status-------- ---- ------campusvoztovoice caldav busy

Esto es así siempre y cuando en la configuración del evento en el Calendario se haya configurado la opción:

Para saber que tipo de informaciones se pueden conocer acerca de un evento programado el comando

190

Page 202: Libro Asterisk 1.8.X - Versión 1.0 (1)

es:

asterisk -rvvvvvvvvvvvvvv

CLI> core show function CALENDAR_EVENT -= Info about function 'CALENDAR_EVENT' =-

[Synopsis]Get calendar event notification data from a notification call.

[Description]Whenever a calendar event notification call is made, the event data may beaccessed with this function.

[Syntax]CALENDAR_EVENT(field)

[Arguments]field summary - The VEVENT SUMMARY property or Exchange event 'subject' description - The text description of the event organizer - The organizer of the event location - The location of the eventt categories - The categories of the event priority - The priority of the event calendar - The name of the calendar associated with the event uid - The unique identifier for this event start - The start time of the event end - The end time of the event busystate - The busy state of the event 0=FREE, 1=TENTATIVE, 2=BUSY

Todos los parámetros bajo la etiqueta [Arguments] se pueden extraer del calendario y utilizar en el dialplan.

Para conocer todas las funciones disponibles en Asterisk para trabajar con los calendarios:

CLI> core show function calendar + tecla tabuladorCALENDAR_BUSY CALENDAR_EVENT CALENDAR_QUERY CALENDAR_QUERY_RESULT CALENDAR_WRITE

10.2 CALENDAR_BUSY

Es una función que permite consultar un calendario para ver si su estado es libre o ocupado. Este tipo de respuesta se puede utilizar en el dialplan asociando el calendario a una determinada extensión y en base al estado del calendario procesar la llamada de diferentes formas. Un ejemplo: el calendario

191

Page 203: Libro Asterisk 1.8.X - Versión 1.0 (1)

configurado en Asterisk está asociado a la extensión 1000. Si el estado del calendario es ocupado, se anuncia al llamante de llamar más tarde, sino se pasa la llamada a la extensión 1000.

Se abre el dialplan

nano /etc/asterisk/extensions.conf

se modifica este bloque:

exten => _100[0-2],1,Macro(disponible)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

para que quede:

exten => _100[0-2],1,Macro(disponible)same => n,Macro(calendario)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

y al final del archivo, antes de esta linea:

#include IVR

se añade la nueva macro:

[macro-calendario]exten => s,1,Noop(${MACRO_EXTEN})same => n,GotoIf($[${MACRO_EXTEN} = 1000]?calendario)same => n,MacroExitsame => n(calendario),Set(estado=${CALENDAR_BUSY(campusvoztovoice)})same => n,Noop(Estado = ${estado})same => n,Gotoif($[${estado} = 1]?ocupado)same => n,MacroExitsame => n(ocupado),Agi(googletts.agi,"la extensión se encuentra ocupada, llame mas tarde. Gracias",es)same => n,Hangup

Esta nueva macro controla primero si la extensión que se está llamando es la 1000. Si es así continua desde la etiqueta calendario donde revisa si el calendario asociado a la extensión 1000 (en este caso campusvoztovoice) resulta libre o ocupado. Si resulta ocupado, Asterisk devuelve el valor 1, si resulta libre Asterisk devuelve el valor 0). En el caso que el resultado sea 1, se le anuncia al llamante (con el AGI de google) que la extensión se encuentra ocupada y que llame más tarde). Si el resultado es 0 se sale de la Macro y se vuelve al contexto, extensión, prioridad +1 de donde la Macro se ha llamado.

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvvvvvvvv

192

Page 204: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> dialplan reload

se averigua el estado del calendario:

CLI> calendar show calendarsCalendar Type Status-------- ---- ------campusvoztovoice caldav busy

Como en este caso resulta el ocupado, si desde la extensión 1001 se marca a la extensión 1000, se debería escuchar el anuncio que la extensión se encuentra ocupada.

El resultado de la llamada en la consola:

Extension Changed 1001[subscribe] new state InUse for Notify User 1000 -- Executing [1000@externas:1] Macro("SIP/1001-0000000f", "disponible") in new stack -- Executing [s@macro-disponible:1] Set("SIP/1001-0000000f", "estado=NOT_INUSE") in new stack -- Executing [s@macro-disponible:2] GotoIf("SIP/1001-0000000f", "1?5") in new stack -- Goto (macro-disponible,s,5) -- Executing [s@macro-disponible:5] MacroExit("SIP/1001-0000000f", "") in new stack -- Executing [1000@externas:2] Macro("SIP/1001-0000000f", "calendario") in new stack -- Executing [s@macro-calendario:1] NoOp("SIP/1001-0000000f", "1000") in new stack -- Executing [s@macro-calendario:2] GotoIf("SIP/1001-0000000f", "1?calendario") in new stack -- Goto (macro-calendario,s,4) -- Executing [s@macro-calendario:4] Set("SIP/1001-0000000f", "estado=1") in new stack -- Executing [s@macro-calendario:5] NoOp("SIP/1001-0000000f", "Estado = 1") in new stack -- Executing [s@macro-calendario:6] GotoIf("SIP/1001-0000000f", "1?ocupado") in new stack -- Goto (macro-calendario,s,8) -- Executing [s@macro-calendario:8] AGI("SIP/1001-0000000f", "googletts.agi,"la extension se encuentra ocupada, llame mas tarde. Gracias",es") in new stack -- Launched AGI Script /var/lib/asterisk/agi-bin/googletts.agi -- Playing '/tmp/80eb1469553d3ab98b95661fbf6a2f1c' (escape_digits=) (sample_offset 0) -- <SIP/1001-0000000f>AGI Script googletts.agi completed, returning 0 -- Executing [s@macro-calendario:9] Hangup("SIP/1001-0000000f", "") in new stack

10.3 CALENDAR_EVENT

Como ya se ha visto más arriba, esta función permite extraer todas las informaciones relacionadas con un evento. Más en detalle:

• summary – El titulo del evento.• description – La descripción del evento• organizer – El organizador del evento• location – Sitio donde tiene lugar el evento

193

Page 205: Libro Asterisk 1.8.X - Versión 1.0 (1)

• categories – Categoría del evento• priority – Prioridad asignada al evento• calendar – Nombre del calendario asociado con el evento• uid – numero único que identifica el evento• start – Fecha y hora de inicio de un evento• end – Fecha y hora en que termina el evento• busystate – El estado configurado para el evento

Con estos datos, se pueden construir diferentes bloques de dialplan. Un ejemplo es configurar un evento de Conferencia y en la casilla lugar indicar un numero de cuarto de conferencia.

En Google calendar sería:

¿Parece complicado? La verdad no. Lo importante es que cada persona que tiene o quiere participar a la conferencia ponga en su calendario personal la misma información en los campos Titulo y lugar.

En en dialplan:

194

Page 206: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/extensions.conf

Se modifica este bloque:

[calendario]exten => cal,1,NoOp(Llamada desde el calendario)same => n,Agi(googletts.agi,"${CALENDAR_EVENT(summary)}.",es)same => n,Agi(googletts.agi,"a las ${STRFTIME(${CALENDAR_EVENT(start)},,%H:%M)}.",es)same => n,Wait(1)same => n,Playback(goodbye)same => n,Hangup

Para que quede:

[calendario]exten => cal,1,NoOp(Llamada desde el calendario)same => n,Gotoif($[${ISNULL(${CALENDAR_EVENT(location)})} = 0 & "${CALENDAR_EVENT(summary)}" = "Conferencia"]?conf)same => n,Agi(googletts.agi,"${CALENDAR_EVENT(summary)} a las ${STRFTIME(${CALENDAR_EVENT(start)},,%H:%M)}.",es)same => n,Wait(1)same => n,Playback(goodbye)same => n,Hangupsame => n(conf),Agi(googletts.agi,"${CALENDAR_EVENT(description)}",es)same => n,Confbridge(${CALENDAR_EVENT(location)},cM(default))same => n,Hangup

En la linea dos se utiliza la función ISNULL que permite averiguar si una variable está vacía. Si la variable está vacía devuelve 1 sino 0. La lógica de la linea funciona de la siguiente manera: Si la variable ${CALENDAR_EVENT(location)} no está vacía “y” (el carácter &) la variable ${CALENDAR_EVENT(summary) contiene el valor Conferencia ir a la etiqueta conf sino continuar con la linea que sigue.

En la linea con la etiqueta conf se utiliza el AGI de texto a voz de Google y se le anuncia a la extensión la descripción del evento.

En la linea siguiente se utiliza la aplicación ConfBridge para crear una conferencia dinámica cuyo numero es el que aparece en el campo lugar (location) del calendario y se envía la extensión a esa conferencia. Se profundizará el tema de las conferencias en el Capitulo XV.

10.4 CALENDAR_QUERY y CALENDAR_QUERY_RESULT

Esta dos funciones sirven para hacer consultas en los calendarios configurados en Asterisk y sacar los datos de interés. Para saber que datos se pueden extraer, desde la consola de Asterisk:

195

Page 207: Libro Asterisk 1.8.X - Versión 1.0 (1)

asterisk -rvvvvvvvvvvvvvv

CLI> core show function CALENDAR_QUERY_RESULT

• getnum – numero de eventos que tendrán lugar en el rango de tiempo indicado en la consulta (en este caso 180 minutos)

• summary – Titulo del evento• description – Descripción del evento• organizer – Organizador del evento• location – Lugar del evento• categories – Categoría del evento• priority – Prioridad del evento• calendar – Nombre del calendario• uid – Numero que identifica univocamente el evento• start – Hora de inicio del evento• end – Hora en que termina el evento• busystate – El estado del calendario

La sintaxis de la función es:

CALENDAR_QUERY_RESULT(id,field[,entry])

• id – el valor obtenido con la función CALENDAR_QUERY• field – El campos que se quiere extraer de un determinado evento• entry – en el caso que la función CALENDAR_QUERY haya almacenado en su id más de un

evento, con esta opción se define a que evento hace referencia el campo que se quiere extraer

Para ver como funcionan, se crean dos nuevos eventos:

Se averigua que los eventos aparecen en Asterisk:

196

Page 208: Libro Asterisk 1.8.X - Versión 1.0 (1)

Perfecto! Ahora se crea el dialplan para hacer una consulta al calendario:

nano /etc/asterisk/extensions.conf

En el contexto internas se añade este bloque:

exten => 51,1,Noop(Consulta en el calendario)same => n,Set(fin=$[${EPOCH}+10800])same => n,Set(id=${CALENDAR_QUERY(campusvoztovoice,${EPOCH},${fin})})same => n,Set(numeve=${CALENDAR_QUERY_RESULT(${id},getnum)})same => n,Set(num=1)same => n,While($[${numeve} > 0])same => n,Agi(googletts.agi,"${CALENDAR_QUERY_RESULT(${id},summary,${num})}",es)same => n,Agi(googletts.agi,"a las ${STRFTIME(${CALENDAR_QUERY_RESULT(${id},start,${num})},,%H:%M)}",es)same => n,Set(numeve=$[${numeve}-1])same => n,Set(num=$[${num}+1])same => n,Endwhilesame => n,Hangup

• Linea 2 – Como en la configuración de los calendarios se ha puesto como limite de consulta los 180 minutos, se añade a la variable ${EPOCH} el valor 10800 segundos que corresponden a 180 minutos. No se puede hacer consultas más allá de este tiempo sin cambiar la configuración del parámetro timeframe en calendar.conf

• Linea 3 – se asigna a la variable id el resultado de la consulta en el calendario campusvoztovoice indicando la ora de inicio y la hora final de la consulta, es decir los eventos

197

Page 209: Libro Asterisk 1.8.X - Versión 1.0 (1)

que tendrán lugar en lo próximos 180 minutos• Linea 4 – se asigna a la variable numeve el numero de eventos que tendrán lugar en los

próximos 180 minutos• Linea 5 – se asigna a la variable num el valor 1• Linea 6 – la aplicación While se usa para crear un ciclo y este ciclo se ejecutará hasta que la

variable ${numeve} sea mayor a 0• Linea 7 – con el AGI del TTS de Google se anuncia el titulo del evento (summary) de la entrada

cuyo numero es el contenido en la variable ${num}• Linea 8 - con el AGI del TTS de Google se anuncia la hora (start) de la entrada cuyo numero es

el contenido en la variable ${num}• Linea 9 – se asigna a la variable ${numeve} el valor de la misma variable menos 1. Ejemplo: si

el calendario contiene dos eventos en los próximos 180 minutos, la variable ${numeve} contiene el valor 2. Después de esta linea contendrá el valor 1

• Linea 10 – Se asigna a la variable ${num} el valor de la variable ${num} + 1. Como inicialmente la variable contenía el valor 1, después de esta linea contendrá el valor 2

• Llinea 11 – Con la aplicación EndWhile se cierra el ciclo y el dialplan vuelve a la linea con la aplicación While. Ahora, como la variable ${numeve} es todavía mayor que 0, el ciclo se repite y se leerá el titulo y la hora del segundo evento.

La siguiente vez que se vuelve a la aplicación While, la variable ${numeve} contendrá el valor cero pues se saldrá del ciclo “While - Endwhile” y se ejecutará la linea que sigue la aplicación EndWhile, es decir same => n,Hangup

De esta forma si llegando a la oficina, se quiere conocer los eventos programados en las próximas 3 horas, basta marcar la extensión 51. Claramente cada persona de la empresa puede tener su calendario personal.

10.5 CALENDAR_WRITE

Con la función CALENDAR_WRITE, es posible crear nuevos eventos en el calendario desde Asterisk. En este ejemplo se mostrará como grabar las llamadas salientes con el proveedor Justvoip en un calendario. Para este ejemplo se utilizará un nuevo calendario.

Desde la pagina de administración del calendario principal, se entra en la pagina de configuración y se crea un nuevo calendario:

198

Page 210: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se presiona el botón “Crear un calendario nuevo” y en la nueva pagina se rellenas los campos:

Se concluye la creación presionando el botón “Crear calendario”. Se entra en la configuración del nuevo calendario y se anota el siguiente dato:

Con el valor del ID del nuevo calendario se configura Asterisk:

nano /etc/asterisk/calendar.conf

al final del archivo se añade:

[llamadas]type=caldavurl=https://www.google.com/calendar/dav/[email protected]/events/[email protected]=passwordrefresh=10timeframe=180autoreminder=10channel=SIP/1000context=calendarioextension=calwaittime=45

199

Page 211: Libro Asterisk 1.8.X - Versión 1.0 (1)

IMPORTANTE: Personalizar los datos de la etiqueta inicial, el parámetro url, el parámetro user y el parámetro secret con los datos de su cuenta Google.

Se guardan los cambios y se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvv

Se recarga el modulo:

CLI> module reload res_calendar.so

Si no aparecen errores y/o advertencias, todo debería estar bien configurado. Con el comando:

CLI> calendar show calendarsCalendar Type Status-------- ---- ------campusvoztovoice caldav freellamadas caldav free

Se puede comprobar que efectivamente los dos calendarios están conectados.

Los datos de las llamadas que se guardarán en el calendario son:

• extensión que ha iniciado la llamada• IP de la extensión• numero marcado• Fecha de la llamada

Para implementar está solución se abre el dialplan:

nano /etc/asterisk/extensions.conf

se modifica este bloque:

[internacio]exten => _00X.,1,NoOpsame => n,Set(GROUP(voip)=justvoip)same => n,Set(GROUP(salida)=${CALLERID(num)})same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)})same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)})same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip)same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

200

Page 212: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n(busy),Playback(all-outgoing-lines-unavailable)same => n,Hangup

Para que quede:

[internacio]exten => _00X.,1,NoOpsame => n,Set(CALENDAR_WRITE(llamadas,summary,description,location,start)=Llamada de ${CALLERID(num)} a ${EXTEN},Llamada desde la extension ${CALLERID(num)} al numero ${EXTEN},IP = ${CHANNEL(peerip)},${EPOCH})same => n,Set(GROUP(voip)=justvoip)same => n,Set(GROUP(salida)=${CALLERID(num)})same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)})same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)})same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip)same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangupsame => n(busy),Playback(all-outgoing-lines-unavailable)same => n,Hangup

Se ha añadido la linea 2 (en amarillo). El contenido de esa linea tiene que quedar en la mismo renglón. Con esa linea se le dice a Asterisk que guarde en el calendario “llamadas” los campos:

• summary• description• location• start

En la segunda parte de la linea se le asigna a cada campo un valor y más en detalle:

• Summary = Llamada de ${CALLERID(num)} a ${EXTEN}• Description = Llamada desde la extension ${CALLERID(num)} al numero ${EXTEN}• Location = IP = ${CHANNEL(peerip)}• Start = ${EPOCH}

Las variables presentes:

• ${CALLERID(num)} – Contiene el numero de la extensión que ha llamado• ${EXTEN} – Contiene el numero marcado• ${CHANNEL(peerip)} = Contiene la IP de donde la extensión ha iniciado la llamada• ${EPOCH} = Contiene la fecha de inicio de la llamada en formato EPOCH que es el requerido

por Google Calendar

El resultado en Google Calendar será:

201

Page 213: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si tenemos sincronizado el calendario en un sistema Android:

Claramente este es ejemplo muy sencillo. Se puede elaborar más para sacar más datos de la llamada.

Otro ejemplo para utilizar esta función podría ser programar una conferencia a través de un IVR indicando las extensiones que deben participar y guardar los datos en el Calendario.

10.6 Enviar las notificaciones de los calendarios a números fijos/celulares

En la configuración que se ha visto hasta el momento, es posible asociar el calendario a una extensión y llamar la extensión configurada para notificarle el comienzo de un evento. Una forma más elaborada de configurar el calendario y de consecuencia el dialplan, es modificar el CALLERID antes de marcar a la extensión y en el caso que no conteste, desviar la llamada a un numero fijo/celular. Para este tipo de configuración se utilizará el chan_local.

202

Page 214: Libro Asterisk 1.8.X - Versión 1.0 (1)

Primero se modifica la configuración del calendario:

nano /etc/asterisk/calendar.conf

Se modifica esta linea:

channel=SIP/1000

para que quede:

Local/6500@internas

Se guardan los cambios. De esta forma cuando se acerca un evento y Asterisk envía la notificación, llamará el canal Local, extensión 6000, contexto internas; esa extensión hay que crearla en el dialplan:

nano /etc/asterisk/extensions.conf

En el contesto internas se añaden las siguientes lineas:

exten => 6500,1,Set(CALLERID(name)=Calendario)same => n,Set(CALLERID(num)=CampusVozToVoice)same => n,Dial(SIP/1000,15)same => n,Gotoif($[${DIALSTATUS} = ANSWER)]?contestada)same => n,Dial(SIP/justvoip/0057XXXXXXXXXX)same => n,hangupsame => n(contestada),Hangup

• En la primera linea se asigna al la variable CALLERID(name) la palabra Calendario• En la segunda linea se asigna a la variable CALLERID(num) el nombre del calendario (en este

caso CampusVozToVoice)• En la tercera linea se marca a la extensión 1000 por 15 segundos• Si la extensión contesta (GotoIF verdadero), se va a la etiqueta (contestada) y se termina la

llamada• Si la extensión no contesta dentro de 15 segundos, se marca al un numero fijo o celular.

Se guardan los cambios y se crea un nuevo evento en el calendario para probar la configuración. Se reinicia Asterisk:

service asterisk restart

Se espera la llamada del calendario. Primero timbrará la extensión 1000:

203

Page 215: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si no se contesta dentro de 15 segundos, la llamada se enviará al numero fijo/celular configurado:

En este caso el CALLERID no es el que se ha configurado en el dialplan ya que su envío/recepción depende del Proveedor VoIP utilizado.

204

Page 216: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 217: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XI

CCSS (Call Completion Supplementary System) – Rellamada

El CCSS es una nueva funcionalidad de Asterisk 1.8.X que permite solicitar el servicio de rellamada cuando el llamado no ha contestado y/o su extensión se encuentra ocupada. El sistema se basa en el Internet Draft “draft-ietf-bliss-call-completion-04”. Un Internet Draft es una propuesta de estandarización presentada a la IETF (Internet Engineering Task Force) para que sea analizada y, si el caso, aprobada y transformada en un RFC (Request for Comment), es decir, un estándar de hecho.

En este caso los desarrolladores de Asterisk han optado por implementar un sistema que todavía no es un estándar de hecho. Esto explica porque muchas veces no hay interoperabilidad entre dispositivos SIP de distintos productores aunque, supuestamente, todos utilizan el protocolo SIP.

Actualmente la única PBX que utiliza este Draft es Asterisk y no hay sofphone ni teléfonos SIP que lo implementen. Es por este motivo que al momento de configurar esta funcionalidad, se podrá utilizar su configuración nativa solamente entre servidores Asterisk (desde la versión 1.8.X). Para su utilizo entre Asterisk y los teléfonos SIP o softphone hay que optar por su configuración genérica que realmente no se basa en el Draft mencionado, sino en un sub-sistema que se apoya a la función DEVICE_STATE.

¿Cómo funciona el sistema?

El sistema aplica a llamadas no contestadas CCNR (Call Completion on No Response) o cuando la extensión llamada se encuentra ocupada CCBR (Call Completion on Busy Subscriber) y solamente para canales SIP. Si se utiliza el agente genérico para solicitar la rellamada, habrá que utilizar la aplicación CallCompletion. Si se utiliza el agente nativo, el mismo productor del dispositivo que implementa el Draft, indicará como activarla. Normalmente es a través de una tecla del teléfono o presionando un botón ya programado para esta función.

Un ejemplo. La extensión 1000 llama la extensión 1001. Si la extensión 1001 no contesta, la extensión 1000 tendrá un tiempo predefinido para solicitar una rellamada. La solicitud se hace utilizando la aplicación CallCompletion en el dialplan. Una vez solicitada la rellamada, se activará un temporizador que definirá por cuanto tiempo la solicitud quedará activa. Si dentro de este tiempo la extensión 1001 efectúa una llamada, Asterisk la considerará nuevamente activa y en cuanto termine la llamada, marcará primero la extensión 1000 y luego la extensión 1001. Si la rellamada tiene éxito, la solicitud sera eliminada. Si la rellamada no tiene éxito (la extensión 1001 no contesta nuevamente o está hablando), habrá que solicitar una nueva rellamada. En cualquier momento se puede anular una solicitud de rellamada utilizando la aplicación CallCompletionCancel en el dialplan.

11.1 Configuración del CCSS

¿Cómo se configura el sistema de rellamada en Asterisk?

Primero hay que configurar el archivo ccss.conf. En este archivo se define un único parámetro que es el numero máximo de solicitudes que pueden estar activas en la PBX. Los demás datos que se encuentran el el archivo son para la configuración de las extensiones.

Page 218: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se renombra el archivo predefinido:

mv /etc/asterisk/ccss.conf /etc/asterisk/ccss.conf.old

Se crea uno nuevo:

nano /etc/asterisk/ccss.conf

y se pone, después de la etiqueta general, el parámetro cc_max_requests:

[general[cc_max_request=20

De esta forma se limita a veinte el numero máximo de solicitudes activas en el sistema.

Se guardan los cambios.

Ahora la parte de las extensiones, donde se pueden configurar una serie de parámetros. Los parámetros que no se configuran, tomarán como valor el predefinido:

Parámetro Descripcióncc_offer_timer Tiempo máximo, en segundos, para solicitar una

rellamada cuando una llamada no ha tenido éxito. Valor 20

ccbs_available_timer Tiempo de vida, en segundos, de una solicitud de rellamada cuando le extensión llamada estaba ocupada. Valor 4800

ccnr_available_timer Tiempo de vida, en segundos, de una solicitud de rellamada cuando la extensión llamada no ha contestado. Valor 7200

cc_recall_timer Cuando la extensión que ha solicitado la rellamada, recibe la llamada del sistema tendrá el numero de segundos indicados en este parámetro para contestar. Si no lo hace la rellamada será anulada. Valor: 20

cc_agent_policy Este parámetro describe el tipo de comportamiento de Asterisk cuando se comunicará con el llamante para una rellamada. Puede ser:

• never: deshabilita la posibilidad de solicitar una rellamada para el llamante

• generic: cuando no se utiliza el Draft sino el sub-sistema basado en el

207

Page 219: Libro Asterisk 1.8.X - Versión 1.0 (1)

DEVICE_STATE• native: cuando se utiliza el Draft para el

sistema de rellamada (el teléfono del llamante lo soporta)

cc_monitor_policy Este parámetro describe el tipo de comportamiento de Asterisk cuando se comunicará con el llamado para una rellamada. Puede ser:

• never: deshabilita la posibilidad de recibir una rellamada

• generic: activará el monitorep del llamado utilizando el sub-sistema basado en el DEVICE_STATE

• native: cuando se utiliza el Draft para el sistema de rellamada (el teléfono del llamado lo soporta)

• always: cuando no se sabe si el teléfono soporta el Draft. De esta forma Asterisk intentará utilizar el sistema nativo y si no funciona, el genérico

cc_max_agents Limita el numero de rellamadas activas para el llamante. Si cc_agent_policy=generic, este valor no será tomado en consideración. Valor: 5

cc_max_monitors = 5 Limita el numero de rellamadas que un dispositivo puede aceptar. Valor: 5

Para poder hacer una prueba se configurará en las extensiones 1000,1001 y 1002 solamente dos parámetros:

• cc_agent_policy=generic• cc_monitor_policy=generic

Se abre el archivo sip.conf

nano /etc/asterisk/sip.conf

y al final del bloque de configuración de cada extensión se pone:

cc_agent_policy=genericcc_monitor_policy=generic

Se guardan los cambios. Como se va a utilizar el sistema genérico, en el dialplan hay que configurar una extensión para la aplicación CallCompletion y otra para la aplicación CallCompletionCancel

208

Page 220: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/extensions.conf

en el contexto internas se añaden las siguientes lineas:

exten => *30,1,CallCompletionRequestsame => n,Agi(googletts.agi,"Rellamada activada",es)same => n,Hangup

exten => *31,1,CallCompletionCancelsame => n,Agi(googletts.agi,"Rellamada anulada",es)same => n,Hangup

Se guardan los cambios y se recarga toda la configuración de Asterisk:

service asterisk reload

11.2 CCSS 1ª Prueba

Desde la extensión 1000 se llama la extensión 1001. Cuando esta esté timbrando, se rechaza la llamada:

A partir de ese momento, la extensión 1000 tendrá 20 segundos para solicitar la rellamada. Se puede ver, desde la consola de Asterisk, que la rellamada ha sido ofrecida por la extensión 1000

CLI> cc report status

Ahora para solicitarla desde la extensión 1000 se marca *30.

CLI> cc report status

209

Page 221: Libro Asterisk 1.8.X - Versión 1.0 (1)

Siendo el tipo de solicitud CCNR, tendrá un tiempo de vigencia de 7200 segundo (dos horas), como indicado en ccnr_available_timer como valor predefinido. Para que la rellamada se efectúe, el sistema esperará que la extensión 1001 haga una llamada y de esta forma saber que ya está activa nuevamente. Para averiguarlo, desde la extensión 1001 se marca 150 (test de echo) y después de unos segundos de cuelga. Casi en seguida entrará una llamada a la extensión 1000:

Como se puede ver el CallerID es la misma extensión 1000 y esto indica que se trata de una rellamada.Cuando la extensión 1000 contesta se pueden presentar dos escenarios:

• la extensión 1001 no contesta nuevamente. La rellamada corriente se anula y la extensión 1001 ofrece nuevamente a la extensión 1000 la posibilidad de solicitar una rellamada.

• la extensión 1001 contesta. La rellamada solicitada se anula.

La extensión 1000 tiene 20 segundos para contestar la llamada entrante (valor predefinido del parámetro cc_recall_timer). Si no lo hace, la rellamada se considerará terminada.

11.3 CCSS 2ª Prueba

Desde la extensión 1000 se llama la extensión 1001. La extensión 1001 rechaza la llamada. La extensión 1000 solicita la rellamada marcando *30. Después de unos minutos, decide que ya no la necesita. Marcando *31 la anula. Las distintas secuencias desde la consola de Asterisk:

210

Page 222: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si la solicitud de CC es anulada, no se puede solicitar nuevamente.

11.4 CCSS 3ª Prueba

Desde la extensión 1000 se llama la extensión 1001. La extensión 1001 contesta la llamada. Cuando la conversación termine, la extensión 1000, a pesar que la extensión 1001 ha contestado, podrá solicitar una rellamada. Este tipo de comportamiento tiene su lógica ya que el hecho que la llamada ha sido contestada, no significa que el llamante ha podido hablar con el llamado (como en este caso). Esto porque si en el dialplan se configura que si la extensión 1001 no contesta dentro de un tiempo, la llamada se pasa a un buzón de voz o a un IVR, realmente la extensión 1000 no ha podido hablar con la extensión 1001. Si se mira la consola, efectivamente la rellamada se está ofreciendo:

211

Page 223: Libro Asterisk 1.8.X - Versión 1.0 (1)

Consejos:

1. El sistema de rellamada consuma bastante recursos del sistema. Para limitar este consumo es buena practica:

• configurar el parámetro cc_max_requests con un valor bajo• configurar el parámetro cc_offer_time con un valor bajo• En el sip.conf, por cada extensión, configurar el parámetro cc_agent_policy con never y

activar el agente desde el dialplan utilizando la función CALLCOMPLETETION. Para el bloque de las llamadas entre extensiones seria algo como:exten => _100[0-2],1,Macro(disponible)same => n,Macro(calendario)same => n,Set(CALLCOMPLETION(cc_agent_policy)=generic)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

2. la rellamada nativa funciona solamente si el paquete libxml2-devel ha sido instalado en el servidor Linux antes de compilar Asterisk. Esto porque el Draft se basa en un sistema de SUBSCRIBE, NOTIFY y PUBLISH donde el cuerpo del paquete SIP contiene la información en ese formato (XML).

212

Page 224: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 225: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XII

Asterisk Realtime

ARA (The Asterisk Realtime Architecture) es un método para almacenar los archivos de configuración de Asterisk y/o objetos en una base de datos. Existen dos tipos de Realtime:

• Estático• Dinámico

12.1 Realtime estático

Con el Realtime estático es posible guardar los archivos de configuración de Asterisk en una base de datos. Se dice estático porque cuando se hagan cambios en la base de datos, hay que recargar la configuración de Asterisk. Si las configuraciones se guardan en la base de datos, ya no se podrán utilizar los archivos de texto, es decir que si por ejemplo, se guarda la configuración del dialplan en Realtime estático, la PBX no leerá el archivo extensions.conf. El archivo donde se configura el Realtime estático es extconfig.conf y la sintaxis es:

file.conf => driver,database[,table]

• file.conf: archivo de configuración que se quiere guardar en la base de datos• driver: que motor de base de datos se va a utilizar (MySQL, ODBC, Postgres, SQLite3)• database: el nombre de la base de datos• table: el nombre de la tabla en la base de datos

Los únicos archivos de configuración que no se pueden guardar con el Realtime estático son:

• asterisk.conf• logger.conf• extconfig.conf

Otros tres archivos se pueden guardar en la base de datos solamente si el modulo del motor que se va a utilizar se carga en el modules.conf antes de los demás módulos. Esto se hace con la declaración preload. Como se va a utilizar ODBC, la modifica que hay que hacer es:

nano /etc/asterisk/modules.conf

se buscan estas dos lineas:

;preload => res_odbc.so;preload => res_config_odbc.so

y se modifican para que queden:

Page 226: Libro Asterisk 1.8.X - Versión 1.0 (1)

preload => res_odbc.sopreload => res_config_odbc.so

Los dos módulos (que se utilizan para el Realtime con ODBC), se cargarán antes de los demás módulos y de esta formas se podrán guardar en Realtime también estos archivos:

• manager.conf• cdr.conf• rtp.conf

¿Cual es el procedimiento para configurar el Realtime estático en Asterisk con ODBC?

1. Se crea una nueva base de datos2. Se crea la tabla para el Realtime estático3. Se configurar el conector ODBC4. Se configura el archivo de configuración de Asterisk res_odbc.conf5. Se configura el archivo extconfig.conf

Visto gráficamente sería:

Se inicia creado una nueva base de datos:

mysql -u root -psesamo

mysql> create database asterisk;

Se otorgan los permisos de acceso a la base de datos creada al usuario asterisk, desde local:

215

Page 227: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';

desde remoto:

mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo';

se crea la tabla para el Realtime estático:

mysql> use asterisk

mysql> CREATE TABLE `ast_config` ( `id` int(11) NOT NULL auto_increment, `cat_metric` int(11) NOT NULL default '0', `var_metric` int(11) NOT NULL default '0', `filename` varchar(128) NOT NULL default '', `category` varchar(128) NOT NULL default 'default', `var_name` varchar(128) NOT NULL default '', `var_val` varchar(128) NOT NULL default '', `commented` int(11) NOT NULL default '0', PRIMARY KEY (`id`), KEY `filename_comment` (`filename`,`commented`));

El nombre de la tabla es totalmente arbitrario y se puede personalizar para volverlo más amigable. Una explicación de los parámetros que aparecen en la tabla:

• ID – es un numero progresivo que se crea automáticamente• cat_metric – el peso de la categoría o bloque dentro del archivo. Un valor bajo significa que la

categoría aparecerá más arriba en el archivo de configuración• var_metric – el peso de un objeto o parámetro dentro de la categoría. Un valor bajo significa

que el objeto aparecerá más arriba en la categoría• filename – el nombre del archivo de configuración de Asterisk que se quiere guardar en la base

de datos• category – la categoría o bloque del archivo de configuración• var_name – el nombre del objeto o del parámetro que se está configurando• var_val – el valor del objeto o parámetro• commented – si es cualquier valor diferente a cero, la entrada en la base de datos aparecerá

como comentada.

Para entender mejor como funciona, se guardará el archivo musiconhold.conf en Realtime estático.

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('0','0','musiconhold.conf','default','mode','files');

216

Page 228: Libro Asterisk 1.8.X - Versión 1.0 (1)

Con esta primera linea se crea la clase default y se define que el modo es files.

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('0','1','musiconhold.conf','default','directory','/var/lib/asterisk/moh');

Con esta segunda linea se define que la carpeta que contiene los archivos audio para la clase default es /var/lib/asterisk/moh

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('0','2','musiconhold.conf','default','random','yes');

En la ultima linea se define que los archivos audio de la música de espera de la clase default se reproducirán aleatoriamente. Se repiten las tres lineas para la música de espera MP3 (como se había configurado en el párrafo 2.5):

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('1','0','musiconhold.conf','mp3','mode','files');

Como se puede notar en esta primera linea el cat_metric es 1 e indica que estamos creando un segundo bloque en el archivo de configuración.

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('1','1','musiconhold.conf','mp3','directory','/var/lib/asterisk/mohmp3');

Con esta segunda linea se define que la carpeta que contiene los archivos audio para la clase mp3 es /var/lib/asterisk/mohmp3

mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('1','2','musiconhold.conf','mp3','random','yes');

En la ultima linea se define que los archivos audio de la música de espera de la clase mp3 se reproducirán aleatoriamente.

Se sale del cliente MySQL:

mysql> quit

Creada la base de datos y la tabla, se configura el conector ODBC. Esto se hace en dos archivos de configuración:

• odbcinst.ini• odbc.ini

En el primero se configuran las conexiones ODBC → librerías base de datos. En el segundo se configuran las base de datos. Para iniciar se borra el archivo predefinido odbcinst.ini

217

Page 229: Libro Asterisk 1.8.X - Versión 1.0 (1)

rm /etc/odbcinst.ini

se crea uno nuevo:

nano /etc/odbcinst.ini

y para ODBC → MySQL se ponen las siguientes lineas:

[MySQL]Description = ODBC para MySQLDriver = /usr/lib/libmyodbc3.soSetup = /usr/lib/libodbcmyS.soFileUsage = 1

Para una versión 64 bit de CentOS sería:

[MySQL]Description = ODBC para MySQLDriver = /usr/lib64/libmyodbc3.soSetup = /usr/lib64/libodbcmyS.soFileUsage = 1

Se continua con odbc.ini

nano /etc/odbc.ini

se copian las siguientes lineas que crean una conexión a la base de datos MySQL asterisk:

[asterisk]Description = MySQL AsteriskDriver = MySQLDatabase = asteriskServer = localhostUser = asteriskPassword = sesamoPort = 3306Option = 3

Se guardan los cambios. Para probar la conexión entre ODBC y la base de datos asterisk se usa el comando:

isql asterisk asterisk sesamo

• asterisk – etiqueta que da inicio al bloque configurado en odbc.ini• asterisk – nombre del usuario que tiene acceso a la base de datos creada

218

Page 230: Libro Asterisk 1.8.X - Versión 1.0 (1)

• sesamo – la contraseña del usuario asterisk creado en MySQL

El resultado:

+---------------------------------------+| Connected! || || sql-statement || help [tablename] || quit || |+---------------------------------------+

La conexión entre ODBC y la base de datos MySQL asterisk funciona perfectamente. Para salir:

SQL> quit

El siguiente paso es configurar res_odbc.conf. Se renombra el archivo predefinido y se crea uno nuevo:

mv /etc/asterisk/res_odbc.conf /etc/asterisk/res_odbc.conf.old

nano /etc/asterisk/res_odbc.conf

Se copian las siguientes lineas:

[ENV]

[asterisk]enabled => yesdsn => asteriskusername => asteriskpassword => sesamopre-connect => yessanitysql => select 1idlecheck => 3600connect_timeout => 10

La linea más importante es dsn => asterisk. El valor asterisk es el que se ha configurado en el bloque que se acaba de crear en el archivo odbc.ini

Se guardan los cambios y se modifica el ultimo archivo:

nano /etc/asterisk/extconfig.conf

después de esta linea:

;extensions.conf => sqlite,asterisk,ast_config

219

Page 231: Libro Asterisk 1.8.X - Versión 1.0 (1)

se pone:

musiconhold.conf => odbc,asterisk,ast_config

Se guardan los cambios. El nombre asterisk que aparece en la linea se refiere al nombre de la etiqueta con que inicia la configuración de la conexión en res_odbc.conf. Gráficamente:

Ahora que se ha configurado la música de espera en Realtime se renombra el archivo de texto:

mv /etc/asterisk/musiconhold.conf /etc/asterisk/musiconhold.conf.old

Se reinicia Asterisk:

service asterisk restart

Se entra en la consola:

asterisk -rvvvvvvvvvvvvvv

se averigua que la conexión en Realtime esté activa (desde el lado Asterisk):

CLI> odbc show allODBC DSN Settings-----------------

Name: asterisk DSN: asterisk Last connection attempt: 1969-12-31 19:00:00 Pooled: No

220

odbc.ini res_odbc.conf

extconfig.conf

Page 232: Libro Asterisk 1.8.X - Versión 1.0 (1)

Connected: Yes

se mira la configuración de la música de espera:

CLI> moh show classesClass: default Mode: files Directory: /var/lib/asterisk/mohClass: mp3 Mode: files Directory: /var/lib/asterisk/mohmp3

Parece que todo está bien. Desde la extensión 1000 se marca el numero 200 para probar la música de espera MP3 en Realtime.

12.2 Realtime Dinamico

El Realtime dinámico permite guardar objetos en una base de datos. Estos objetos pueden ser: extensiones, colas de espera, agentes, buzones de voz, etc. Cuando se hace un cambio en la base de datos, Asterisk actualizará la configuración en tiempo real. A diferencia del Realtime estático, los objetos creados en la base de datos “conviven” con los presentes en los archivos de configuración. Ejemplo: se pueden configurar las extensiones en el sip.conf y al mismo tiempo en la base de datos. Al recargar la configuración SIP, funcionarán ambas.

12.2.1 Extensiones SIP en Realtime

La parte más complicada de la configuración de SIP en Realtime, es la creación de la tabla donde almacenar los parámetros de las extensiones SIP. Algunos campos de la tabla son opcionales mientras otros son obligatorios. Una tabla base debe contener por lo menos estos parámetro:

• type• name• secret• context• host• ipaddr• port• regseconds• defaultuser• fulcontact• regserver• useragent• lastms

221

Page 233: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para crear una tabla más completa, se puede tomar como referencia el resultado de este comando:

CLI> sip show peer 1000

* Name : 1000 Secret : <Set> MD5Secret : <Not set> Remote Secret: <Not set> Context : externas Subscr.Cont. : subscribe Language : es Accountcode : 1000 AMA flags : Unknown Transfer mode: open CallingPres : Presentation Allowed, Not Screened Callgroup : 1 Pickupgroup : 1 Mailbox : 1000@default VM Extension : asterisk LastMsgsSent : 32767/65535 Call limit : 2147483647 Dynamic : Yes Callerid : "callerid=Fulano" <1000> MaxCallBR : 384 kbps Expire : 2917 Insecure : no Nat : Always ACL : No T.38 support : Yes T.38 EC mode : FEC T.38 MaxDtgrm: 400 DirectMedia : No PromiscRedir : No User=Phone : No Video Support: Yes Text Support : No Ign SDP ver : No Trust RPID : No Send RPID : Yes Subscriptions: Yes Overlap dial : Yes Forward Loop : Yes DTMFmode : rfc2833 Timer T1 : 500 Timer B : 32000 ToHost : Addr->IP : 190.253.175.156 Port 22840

222

Page 234: Libro Asterisk 1.8.X - Versión 1.0 (1)

Defaddr->IP : 0.0.0.0 Port 5060 Prim.Transp. : UDP Allowed.Trsp : UDP Def. Username: 1000 SIP Options : replaces replace Codecs : 0x8010c (ulaw|alaw|g729|h263) Codec Order : (alaw:20,ulaw:20,g729:20) Auto-Framing : No 100 on REG : Yes Status : OK (129 ms) Useragent : Reg. Contact : sip:[email protected]:22840;rinstance=3201f90c0a78b7d0 Qualify Freq : 60000 ms Sess-Timers : Accept Sess-Refresh : uas Sess-Expires : 1800 secs Min-Sess : 90 secs Parkinglot :

Todos los parámetros que aparecen en la lista, se pueden configurar en la tabla.

CLI> quit

Para empezar se crea la tabla en la base de datos asterisk:

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `sipexten` (`name` varchar(40) NOT NULL default ' ',`secret` varchar(40) default NULL,`md5secret` varchar(40) default NULL,`remotesecret` varchar(40) default NULL,`type` varchar(10) NOT NULL default ' ',`defaultuser` varchar(40) default NULL,`fromuser` varchar(40) default NULL,`fromdomain` varchar(40) default NULL,`auth` varchar(10) default NULL,`mailbox` varchar(20) default NULL,`subscribemwi` varchar(10) default NULL,`vmexten` varchar(20) default NULL,`callerid` varchar(40) default NULL,`cid_number` varchar(40) default NULL,`callingpres` varchar(20) default NULL,`usereqphone` varchar(10) default NULL,`language` varchar(10) default NULL,

223

Page 235: Libro Asterisk 1.8.X - Versión 1.0 (1)

`context` varchar(40) NOT NULL default ' ',`subscribecontext` varchar(40) default NULL,`amaflags` varchar(20) default NULL,`accountcode` varchar(20) default NULL,`allowtransfer` varchar(20) default NULL,`callgroup` varchar(20) default NULL,`pickupgroup` varchar(20) default NULL,`autoframing` varchar(10) default NULL,`disallow` varchar(20) default 'all',`allow` varchar(20) default NULL,`maxcallbitrate` varchar(15) default NULL,`host` varchar(40) default 'dynamic',`outboundproxy` varchar(40) default NULL,`ipaddr` varchar(45) NOT NULL default ' ',`defaultip` varchar(20) NOT NULL default '0.0.0.0',`port` int(6) NOT NULL default '0',`fullcontact` varchar(60) default NULL,`insecure` varchar(20) default NULL,`qualify` varchar(15) default NULL,`regseconds` int(11) NOT NULL default '0',`regexten` varchar(20) default NULL,`regserver` varchar(20) default NULL,`rtptimeout` varchar(15) default NULL,`rtpholdtimeout` varchar(15) default NULL,`rtpkeepalive` varchar(15) default NULL,`lastms` int(11) NOT NULL default '-1',`setvar` varchar(200) default NULL,`nat` varchar(3) NOT NULL,`useragent` varchar(40) default NULL,`Directmedia` varchar(3) default 'no',`Deny` varchar(31) default '',`Permit` varchar(31) default NULL,PRIMARY KEY (`name`),KEY `host` (`host`,`port`),KEY `ipaddr` (`ipaddr`,`port`)) ;Query OK, 0 rows affected (0.01 sec)

Se sale del cliente MySQL

mysql> quitBye

En este caso como la base de datos es la misma del Realtime estático, no hay que modificar ni el odbc.ini, ni el res_odbc.ini. El único archivo que hay que modificar es el extconfig.conf

nano /etc/asterisk/extconfig.conf

224

Page 236: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se modifican esta linea:

;sippeers => odbc,asterisk

para que queden:

sippeers => odbc,asterisk,sipexten

Se guardan los cambios y se actualiza la configuración de Asterisk:

/etc/init.d/asterisk reload

Ahora se puede configurar la primera extensión SIP en Realtime. Para volver más sencillo el trabajo con las bases de datos, se pueden utilizar distintos programas, entre otros: webmin e phpadmin. En este caso se ha optado por Webmin. Se instalan unas dependencias (para conexiones seguras):

yum install perl-Net-SSLeay

Se descarga el paquete:

cd /usr/src

wget http://downloads.sourceforge.net/project/webadmin/webmin/1.580/webmin-1.580-1.noarch.rpm

y se instala

rpm -ivh webmin-1.580-1.noarch.rpmwarning: webmin-1.570-1.noarch.rpm: Header V3 DSA signature: NOKEY, key ID 11f63c51Preparing... ########################################### [100%]Operating system is CentOS Linux 1:webmin ########################################### [100%]Webmin install complete.

Antes de entrar en la pagina de administración de Webmin hay que abrir el puerto 10000 en el firewall:

nano /etc/sysconfig/iptables

Después de esta linea:

-A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT

se pone:

# Webmin-A INPUT -p tcp -m state --state NEW -m tcp --dport 10000 -j ACCEPT

225

Page 237: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se reinicia iptables:

service iptables restart

Ahora desde un navegador Web se pone la dirección para entrar en Webmin. Si es un servidor Linode se pone el nombre de dominio del Linode sino la IP:

https://IPservidor:10000

En Username se pone root y en Password la contraseña del usuario root de Linux. En la pagina que aparece, en la derecha se escoge el menú “Servers” y luego “MySQL Database Server”:

En Login se pone root (el usuario MySQL) y como contraseña sesamo:

Se selecciona la base de datos Asterisk y luego la tabla Sipexten. Al fondo de la nueva pagina se presiona el botón “View Data” y luego “Add Row”. Se puede empezar a crear la primera extensión en Realtime:

226

Page 238: Libro Asterisk 1.8.X - Versión 1.0 (1)

227

Page 239: Libro Asterisk 1.8.X - Versión 1.0 (1)

228

Page 240: Libro Asterisk 1.8.X - Versión 1.0 (1)

Al terminar se presiona el botón "Save". Si desde la consola de Asterisk se escribe el comando:

asterisk -rvvvvvvvvvvvv

CLI> sip show peers

la nueva extensión configurada no aparecerá. Para ver la configuración de la nueva extensión hay que utilizar el siguiente comando:

CLI> sip show peer 1004 load

Para la parte user:

CLI> sip show user 1004 load

Se configura el X-lite para conectarse a la extensión 1004. En la consola de Asterisk aparecerá:

Si se quiere ver el estado de la extensión en la consola de Asterisk como si fuera configurada en el archivo sip.conf y conocer su estado hay que modificar dos parámetros:

• qualify=yes en la configuración de la extensión• rtcachefriends=yes en la parte general del archivo sip.conf

Se recarga la configuració sip:

CLI> sip reload

y se mira si aparece:

CLI> sip show peers like 1004

En la columna Realtime aparece “Cached RT” que significa que la extensión está configurada en Realtime y que se activó el parámetro rtcachefriends. Desde la extensión 1004 se marca 123 para probarla.

12.2.2 Extensiones IAX en Realtime

La configuración de las extensiones IAX en realtime es bastante similar a la que se ha mostrado para las extensiones SIP. Primero hay que crear la tabla

229

Page 241: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `iaxexten` ( `name` varchar(40) NOT NULL default '', `type` varchar(10) NOT NULL default 'friend', `username` varchar(40) NULL, `mailbox` varchar(40) NULL, `secret` varchar(40) NULL, `dbsecret` varchar(40) NULL, `context` varchar(40) NULL, `regcontext` varchar(40) NULL, `host` varchar(40) NULL default 'dynamic', `ipaddr` varchar(20) NULL, `port` int(5) NULL, `defaultip` varchar(20) NULL, `sourceaddress` varchar(20) NULL, `mask` varchar(20) NULL, `regexten` varchar(40) NULL, `regseconds` int(11) NULL, `accountcode` varchar(20) NULL, `mohinterpret` varchar(20) NULL, `mohsuggest` varchar(20) NULL, `inkeys` varchar(40) NULL, `outkey` varchar(40) NULL, `language` varchar(10) NULL, `callerid` varchar(100) NULL, `cid_number` varchar(40) NULL, `sendani` varchar(10) NULL, `fullname` varchar(40) NULL, `trunk` varchar(3) NULL, `auth` varchar(20) NULL, `maxauthreq` varchar(5) NULL, `requirecalltoken` varchar(4) NULL, `encryption` varchar(20) NULL, `transfer` varchar(10) NULL, `jitterbuffer` varchar(3) NULL, `forcejitterbuffer` varchar(3) NULL, `disallow` varchar(40) NULL, `allow` varchar(40) NULL, `codecpriority` varchar(40) NULL, `qualify` varchar(10) NULL, `qualifysmoothing` varchar(10) NULL, `qualifyfreqok` varchar(10) NULL, `qualifyfreqnotok` varchar(10) NULL,

230

Page 242: Libro Asterisk 1.8.X - Versión 1.0 (1)

`timezone` varchar(20) NULL, `adsi` varchar(10) NULL, `amaflags` varchar(20) NULL, `setvar` varchar(200) NULL, PRIMARY KEY (`name`), INDEX name (name, host), INDEX name2 (name, ipaddr, port), INDEX ipaddr (ipaddr, port), INDEX host (host, port));

mysql> quit

Luego se modifica el archivo extconfig.conf:

nano /etc/asterisk/extconfig.conf

se cambian estas dos lineas:

;iaxusers => odbc,asterisk;iaxpeers => odbc,asterisk

para que queden:

iaxusers => odbc,asterisk,iaxexteniaxpeers => odbc,asterisk,iaxexten

se guarda la configuración y se crea una extensión IAX en Realtime desde Webmin entrando en la tabla iaxexten:

231

Page 243: Libro Asterisk 1.8.X - Versión 1.0 (1)

232

Page 244: Libro Asterisk 1.8.X - Versión 1.0 (1)

Al terminar se presiona el botón “Save”. Como para el protocolo SIP se cambia el parámetro rtcachefriends en el iax.conf:

nano /etc/asterisk/iax.conf

rtcachefriends=no

para que quede:

rtcachefriends=yes

Se guarda la configuración y se actualiza Asterisk:

service asterisk reload

En el cliente Zoiper se configura el usuario marko2 y se mira en la consola de Asterisk si está registrado:

asterisk -rvvvvvvvvvvvvvv

CLI> iax2 show peers

Para terminar hay que modificar el dialplan para que se pueda marcar a la extensiones creadas en Realtime:

233

Page 245: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> quit

nano /etc/asterisk/extensions.conf

Se modifica este bloque:

exten => _100[0-2],1,Macro(disponible)same => n,Macro(calendario)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

para que quede:

exten => _100[0-2,4],1,Macro(disponible)same => n,Macro(calendario)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

siempre en el contexto internas se pone:

exten => 1235,1,Dial(IAX2/marko2,30)same => n,Hangup

para terminar en el contexto subscribe se añade:

exten => 1004,hint,SIP/1004exten => marko2,hint,IAX2/marko2

Se guarda los cambios y se recarga el dialplan:

asterisk -rx "dialplan reload"

10.2.3 Dialplan en Realtime dinamico

Entre los objetos que se pueden guardar en Realtime dinámico, está el dialplan. De esta forma se pueden crear distintos dialplan para distintos servidores Asterisk conectados en Realtime a la base de datos. Esta puede ser una optima solución cuando se quieren compartir partes de dialplan entre distintos servidores Asterisk o cuando se quiere tener el motor de la base de datos en otro servidor.

Para iniciar se crea la tabla para guardar el dialplan en la base de datos:

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `dialplan` (

234

Page 246: Libro Asterisk 1.8.X - Versión 1.0 (1)

`id` int(11) NOT NULL auto_increment,`context` varchar(20) NOT NULL default '',`exten` varchar(20) NOT NULL default '',`priority` tinyint(4) NOT NULL default '0',`app` varchar(20) NOT NULL default '',`appdata` varchar(128) NOT NULL default '',PRIMARY KEY (`context`,`exten`,`priority`),KEY `id` (`id`));

ahora se crea una extensión muy sencilla en la tabla:

mysql> INSERT INTO dialplan (context,exten,priority,app,appdata) VALUES ('test','70','1','Answer','0');

mysql> INSERT INTO dialplan (context,exten,priority,app,appdata) VALUES ('test','70','2','Playback','demo-congrats');

mysql> INSERT INTO dialplan (context,exten,priority,app,appdata) VALUES ('test','70','3','Hangup','0');

el resultado será:

mysql> select * from dialplan;

Se sale del cliente MySQL y se modifica el archivo extconfig.conf:

mysql> quit

nano /etc/asterisk/extconfig.conf

Se busca esta linea:

;extensions => odbc,asterisk

y se modifica para que quede:

extensions => odbc,asterisk,dialplan

235

Page 247: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se pasa al dialplan

nano /etc/asterisk/extensions.conf

Antes del contexto internas se añade este bloque que configura Asterisk para que busque el contexto test en la base de datos:

[test]switch => Realtime

y se añade las lineas en negrita en los dos bloques que siguen:

[externas]include => internasinclude => internacioinclude => parkedcallsinclude => test

[locales]include => internasinclude => auteninclude => parkedcallsinclude => test

De esta forma las extensiones que tengan acceso al contexto externas o locales, tendrán acceso también al contexto test. Se guardan los cambios y se reinicia Asterisk:

service asterisk restart

Desde la extensión 1000 se marca el numero 70 y se prueba el nuevo contexto creado en Realtime.

236

Page 248: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 249: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XIII

IVR avanzados – func_odbc.conf

La función func_odbc permite hacer consultas en base de datos directamente desde el dialplan. Al mismo tiempo es posible actualizar o modificar entradas de la base de datos. El archivo que se utiliza para este tipo de configuración es el func_odbc.conf. En este modulo, se ilustrarán dos diferentes escenarios:

• Buscar el nombre de un empleado en base a su numero de matricula• Guardar los resultados de una encuesta telefónica en una base de datos

13.1 Empleados

La tabla de los empleados contendrá solamente dos campos:

1. numero de matricula2. nombre

Se crea la tabla en la base de datos Asterisk:

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `empleados` (`id` int(11) NOT NULL auto_increment,`nombre` varchar(20) NOT NULL,`matricula` int(4) NOT NULL,PRIMARY KEY (`nombre`),KEY `id` (`id`));

Se añaden a la tablas cuatro empleados:

mysql> INSERT INTO empleados (nombre,matricula) VALUES ('fulano','1234'),('zutano','1235'),('mengano','1236'),('perengano','1237');

el resultado:

mysql> select * from empleados;

Page 250: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora se crea el archivo func_odbc.conf. Primero se renombra el predefinido:

mv /etc/asterisk/func_odbc.conf /etc/asterisk/func_odbc.conf.old

se crea el nuevo

nano /etc/asterisk/func_odbc.conf

y se copian las siguientes lineas:

[Empleados]dsn=asteriskreadsql=SELECT nombre FROM empleados WHERE matricula='${SQL_ESC(${ARG1})}'

• [Empleados] – El nombre de la función que se está creando• dsn – el nombre de la etiqueta definida al inicio del bloque configurado en el archivo odbc.ini

para la base de datos asterisk• readsql=SELECT nombre FROM empleados WHERE matricula='${SQL_ESC(${ARG1})}' –

la sentencia SQL para hacer consultas en la base de datos asterisk (en este caso la tabla empleados)

Para interactuar con el usuario que llame para consultar la base de datos, se utilizará otro sistema de TTS (text to Speech), en este caso Festival. En Asterisk hay un modulo dedicado a la conexión con un servidor Festival. Lo único que hace falta es configurarlo. Primero se averigua si le modulo está compilado y funcionando:

asterisk -rvvvvvvvvvvvvvvv

CLI> module unload app_festival.so

CLI> module load app_festival.so == Parsing '/etc/asterisk/festival.conf': == Found == Registered application 'Festival' Loaded app_festival.so => (Simple Festival Interface)

CLI> quit

Festival viene con el inglés como idioma predefinido. Para configurarlo para el español se siguen estos

239

Page 251: Libro Asterisk 1.8.X - Versión 1.0 (1)

pasos:

cd /usr/share/festival/voices

wget http://www.voztovoice.org/tmp/festival-spanish.zip

unzip festival-spanish.zip

Ahora se modifica el archivo de configuración de festival

nano /usr/share/festival/festival.scm

se añaden estas líneas antes de la ultima linea del archivo

;(language__spanish)(set! voice_default 'voice_el_diphone)(define (tts_textasterisk string mode)"(tts_textasterisk STRING MODE)Apply tts to STRING. This function is specifically designed foruse 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)))

Se guardan los cambios y se modifica el archivo de configuración de festival en Asterisk:

mv /etc/asterisk/festival.conf /etc/asterisk/festival.conf.old

nano /etc/asterisk/festival.conf

estas son la líneas que hay que añadir:

[general]host=localhostport=1314festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n

Se guardan las modificaciones. Se actualiza la configuración de Asterisk:

/etc/init.d/asterisk reload

Para arrancar el servidor Festival en automático:

nano /etc/rc.local

240

Page 252: Libro Asterisk 1.8.X - Versión 1.0 (1)

al final del archivo se añade esta linea:

/usr/bin/festival_server > /dev/null &

Se inicia el servidor festival;

/usr/bin/festival_server > /dev/null &

Se controla que esté corriendo:

ps aux | grep festivalroot 24071 0.0 0.2 4600 1096 pts/1 S 13:36 0:00 /bin/sh /usr/bin/festival_serverroot 24077 0.4 3.6 23464 19324 pts/1 S 13:36 0:00 festival --server ./festival_server.scmroot 24081 0.0 0.1 4028 688 pts/1 S+ 13:36 0:00 grep festival

Se modifica el Dialplan para crear una extensión que permita hacer una prueba del servidor Festival:

nano /etc/asterisk/extensions.conf

en el contexto internas se pone:

exten => 650,1,Answer()same => n,Festival(Asterisk y Festival trabajan junto. Chevere!!!)same => n,Hangup()

Se actualiza el dialplan desde la consola

asterisk -rvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca la extensión 650 para escuchar la frase que se acaba de configurar en el dialplan.

CLI> quit

Terminada la configuración y la prueba de Festival se construye el dialplan para hacer consultas a la tabla empleados:

nano /etc/asterisk/extensions.conf

en el contexto internas se pone:

exten => 660,1,Answersame => n,Wait(2)same => n,Festival(Por favor ingrese los 4 digitos de la matricula del empleado.)same => n,Read(EMPNUM,beep,4)

241

Page 253: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Set(EMPNAME=${ODBC_Empleados(${EMPNUM})})same => n,GotoIf($[${EXISTS(${EMPNAME})}]?nombre)same => n,Festival(Ningun empleado encontrado. Hasta luego.)same => n,Hangupsame => n(nombre),Festival(El nombre del empleado es ${EMPNAME}. Hasta luego.)same => n,Hangup

Una explicación de las lineas:

• Linea1 – se contesta la llamada• Linea2 – se esperan dos segundos• Linea3 – Se usa Festival para leer el texto y enviarlo como audio• Linea 4 – Con la aplicación Read se espera que el llamante digite 4 números y se guardan en la

variable EMPNUM• Linea 5 – Se hace la consulta en la tabla Empleados como configurado en el archivo func_odbc.

Desde la lógica de MySQL sería: select nombre from empleados where matricula='${EMPNUM}';

• Linea6 – Si la consulta devuelve un valor se va a la etiqueta (nombre), si la consulta no devuelve ningún valor se continua en el dialplan (la función EXIST permite averiguar si una determinada variable contiene un valor o está vacía)

• Linea7 – En el caso la consulta no haya tenido éxito, se anuncia al llamante que no se ha encontrado ningún empleado que tenga ese numero de matricula

• Linea8 – se termina la llamada• Linea9 – Si la consulta ha tenido éxito, se anuncia al llamante el nombre del empleado• Linea10 – se termina la llamada

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca 660 y se hacen diferentes pruebas. En la consola:

Executing [660@externas:1] Answer("SIP/1000-00000010", "") in new stack -- Executing [660@externas:2] Wait("SIP/1000-00000010", "2") in new stack -- Executing [660@externas:3] Festival("SIP/1000-00000010", "Por favor ingrese los 4 digitos de la matricula del empleado.") in new stack == Parsing '/etc/asterisk/festival.conf': == Found -- Executing [660@externas:4] Read("SIP/1000-00000010", "EMPNUM,beep,4") in new stack -- Accepting a maximum of 4 digits. -- <SIP/1000-00000010> Playing 'beep.alaw' (language 'es') -- User entered '1234' -- Executing [660@externas:5] Set("SIP/1000-00000010", "EMPNAME=fulano") in new stack -- Executing [660@externas:6] GotoIf("SIP/1000-00000010", "1?nombre") in new stack -- Goto (externas,660,9)

242

Page 254: Libro Asterisk 1.8.X - Versión 1.0 (1)

-- Executing [660@externas:9] Festival("SIP/1000-00000010", "El nombre del empleado es fulano. Hasta luego.") in new stack == Parsing '/etc/asterisk/festival.conf': == Found -- Executing [660@externas:10] Hangup("SIP/1000-00000010", "") in new stack == Spawn extension (externas, 660, 10) exited non-zero on 'SIP/1000-00000010'

13.2 Encuesta

Se quiere suministrar una encuesta a los clientes de la empresa para medir el grado de satisfacción de los mismos. La encuesta está compuesta por 4 preguntas. Las preguntas se pueden pregrabar o, como en este caso, se utilizará Festival. Los pasos a seguir son:

• crear la tabla para la encuesta• crear un nuevo bloque en el archivo func_odbc.conf• crear un nuevo bloque de dialplan

Se inicia creando la tabla:

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `encuesta` ( `id` bigint(20) NOT NULL auto_increment, `fecha` datetime default NULL, `resp1` int(1) default NULL, `resp2` int(1) default NULL, `resp3` int(1) default NULL, `resp4` int(1) default NULL, PRIMARY KEY (`id`));

se sale del cliente mysql:

mysql> quit

se abre el archivo func_odbc.conf

nano /etc/asterisk/func_odbc.conf

al final del archivo se añade el siguiente bloque:

[Encuesta]dsn=asteriskwritesql=insert into encuesta (Fecha,resp1,resp2,resp3,resp4) values ("${SQL_ESC(${VAL1})}","$

243

Page 255: Libro Asterisk 1.8.X - Versión 1.0 (1)

{SQL_ESC(${VAL2})}","${SQL_ESC(${VAL3})}","${SQL_ESC(${VAL4})}","${SQL_ESC(${VAL5})}")

IMPORTANTE: El contenido de la sentencia writesql tiene que estar en la misma linea.

Para terminar se modifica el dialplan:

nano /etc/asterisk/extensions.conf

en el contexto internas se pone:

exten => 670,1,Goto(encuesta,s,1)same => n,Hangup

y después del contexto internas se pone el siguiente bloque:

[encuesta]exten => s,1,Answersame => n,Wait(2)same => n,Festival(Pregunta uno)same => n,Read(var1,,1,,10)same => n,Festival(Pregunta dos)same => n,Read(var2,,1,,10)same => n,Festival(Pregunta tres)same => n,Read(var3,,1,,10)same => n,Festival(Pregunta cuatro)same => n,Read(var4,,1,,10)same => n,Set(ODBC_Encuesta()=${STRFTIME(${EPOCH},,%y%m%d%H%M%S)},${var1},${var2},${var3},${var4})same => n,Playback(thank-you-cooperation)same => n,Hangup

El bloque de dialplan es bastante comprensible. Se presentan las cuatros preguntas. Se guardan los dígitos en 4 variables distintas y al terminar la encuesta se guardan los resultados en la tabla encuesta a través de la función ODBC_Encuesta que se acaba de crear en el archivo func_odbc.conf.

Se guardan las modificaciones y se actualiza Asterisk:

service asterisk reload

Desde unas de las extensiones conectadas a Asterisk se marca el 670 y se contestan las preguntas. Se repite la operación 3-4 veces. Para ver los resultados:

mysql -u root -psesamo

mysql> use asterisk

244

Page 256: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql> select * from encuesta;

Los resultados aparecen ordenados por ID y fecha.

245

Page 257: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 258: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XIV

Buzón de voz – voicemail.conf

En el archivo voicemail.conf es donde se configura todo lo relacionado con el buzón de voz. Si se recibe una llamada y no se contesta o la línea está ocupada, siempre y cuando se configure el dialplan oportunamente, entrará en función el buzón de voz, grabará el mensaje de voz dejado por quien llama y enviará una notificación por correo electrónico al llamado. Anexo al correo electrónico es posible enviar el mensaje de voz en distintos formatos audio. A través de la configuración de este archivo es posible, además, crear distintos grupos de buzones de voz (distintas empresa) y configurar distintas zonas horarias.

14.1 voicemail.conf

Como por lo demás archivos de configuración, en la tabla a seguir se indicarán los parámetros que se van a configurar con una breve descripción. En negrita los valores de cada parámetro. Al final de la tabla, la configuración completa del archivo.

Parámetro Descripción[general] Inicia la parte generalformat Los formatos audio en que se grabará cada mensaje de voz.

Valor wav49|gsm|wavserveremail Correo electrónico del remitente en la notificaciones de la

presencia de un nuevo mensaje de voz. Valor [email protected]. Un ejemplo para Linode: [email protected] Personalizar

attach yes = se anexa al correo electrónico el archivo audio que contiene el mensaje de voz.

maxmsg Numero máximo de mensajes de voz guardados para cada buzón de voz. Valor 100

maxsecs Numero máximo de segundos que puede durar un mensaje de voz. Valor 500

minsecs Numero mínimo de segundos para que un mensaje de voz sea reconocido como tal y enviado al buzón de voz del destinatario. Valor 5

maxgreet Duración máxima, en segundos, del mensaje de bienvenida que cada propietario de un buzón de voz puede grabar para presentarse. Valor 180

skipms Cuando se escuchan los mensaje de voz, se puede usar el teclado numérico del teléfono para adelantar o devolver el mensaje. Se expresa en mili segundos. Valor 3000

Page 259: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónmaxsilence Si mientras se deja un mensaje en el buzón de voz hay un

silencio mayor al numero de segundos indicados en este parámetro, se termina la grabación. Valor 4 Tienes que ser un valor menor del parámetro minsecs

silencethreshold El numero indicado en este parámetro indica el nivel de ruido y sirve para definir que se considera silencio. Más bajo el número, más sensible al ruido. Valor 128

maxlogins Numero máximo de intentos para marcar la clave asociada al buzón de voz personal. Valor 3

moveheard yes = una vez escuchados los nuevos mensajes de voz, se mueven a la carpeta OLD (viejos) en automático; si se configura en no, hay que hacerlo desde el menú del buzón de voz

forward_urgent_auto yes = cada mensaje de voz reenviado se considerará urgente. Valor no

;externnotify=/usr/bin/myapp si se quiere ejecutar una aplicación cada vez que llega un nuevo mensaje de voz, hay que definirla en este parámetro. Se deja comentado

;externpass=/usr/bin/myapp cada vez que se cambie la contraseña de un buzón de voz, es posible ejecutar un script externo. Se deja comentado

;externpassnotify=/usr/bin/myapp Cada vez que se cambie la contraseña de un buzón de voz y se configure el nombre de un script en este parámetro, las variables contexto, mailbox y nueva contraseña se pasarán al script; si el parámetro anterior se ha configurado, este no será tomado en cuenta.

directoryintro La locución de introducción de la aplicación directory. Se explicará más adelante. Valor dir-intro

charset El estándar ISO para los correo electrónicos que se enviarán para notificar la llegada de un nuevo mensaje de voz. Valor ISO-8859-1

pbxskip yes = quita la sigla [PBX] en el asunto de los correos electrónicos

fromstring Nombre del remitente del los correos electrónicos. Valor Buzón de Voz

usedirectory yes = los mensajes de voz que se reciben se pueden reenviar a otros usuarios/extensiones del servidor Asterisk. También se pueden dejar directamente mensajes de voz a otros buzones. Este parámetro permite buscar en el directorio la persona a la que se quiere dejar o reenviar el mensaje de voz

;odbcstorage Se pueden guardar los mensajes de voz en un base de datos

248

Page 260: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónusando el conector ODBC. En este parámetro se define el nombre de la base de datos. Valor asterisk (se deja comentado)

;odbctable El nombre de la tabla de la base de datos donde guardar los mensaje de voz. Valor: mensajes (se deja comentado)

emailsubject Asunto del correo electrónico de notificación. Valor. Nuevo mensaje de voz ${VM_MSGNUM} en el buzon de voz ${VM_MAILBOX}

emailbody Contenido del correo electrónico. Tiene que estar todo en la misma linea. Valor: Estimando ${VM_NAME}:\n\n\t le estamos enviando este correo para avisarle que ha recibido un nuevo mensajede voz de ${VM_DUR} segundos (numero ${VM_MSGNUM})\n\n buzon de voz ${VM_MAILBOX} del numero ${VM_CALLERID}, el${VM_DATE}.\n\n Llame su buzon de voz para escucharlo. Gracias!\n\n\t\t\t\t.Tu Buzon de Voz\n Nombre empresa

emaildateformat Formato de la hora y fecha del correo electrónico. Valor %A, %d %B %Y at %H:%M:%S

mailcmd comando Linux para enviar el correo electrónico. En este caso se utiliza Sendmail. Valor /usr/sbin/sendmail -t

tz zona horaria predefinida para indicar fecha y hora de llegada del mensaje de voz. Valor central A partir de este parámetro inicia la configuración avanzada del archivo.

locale Desde la versión 1.8 de Asterisk es posible configurar el idioma para el formato de la fecha que aparece en el mensaje de notificación. Se pone el mismo valor configurado para el idioma del sistema operativo: es_CO.iso88591

attach yes = se envían los nuevos mensajes de voz anexos al correo electrónico de notificación.

attachfmt de los tres formatos audio en que se grabarán los mensaje de voz (definidos en el parámetro format), se escoge él que se utilizará para anexar el audio al correo electrónico. Valor wav

saycid yes = antes de escuchar el mensaje de voz se anuncia el CallerID del llamante

cidinternalcontexts nombre del contexto del dialplan donde buscar el contexto de los buzones de voz para anunciar en lugar del numero de extensión el nombre de la persona que dejó el mensaje. Valor internas

sayduration yes = anuncia la duración del mensaje de vozsaydurationm define la duración mínima del mensaje de voz para que sea

249

Page 261: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónanunciado (en minutos). Valor 2

dialout nombre del contexto del dialplan para efectuar llamadas salientes desde el menú del buzón de voz (opción 4 del menú avanzado). Valor externas

sendvoicemail Permitir o no enviar el mensaje de voz a otra extensión (opción 5 del menú avanzado). Valor yes

;callback=fromvm Nombre del contexto del dialplan para poder llamar el remitente del mensaje de voz. Se deja comentado

:exitcontext=fromvm Nombre del contexto donde enviar el llamante si presiona una tecla antes de dejar un mensaje. Se deja comentado

review yes = Permite al llamante escuchar el mensaje de voz que ha grabado antes de enviarlo

;operador=yes permite al llamante presionar la tecla 0 para hablar con un operador mientras se encuentra en el buzón de voz. Se deja comentado

envelope yes = antes de reproducir un mensaje de voz, se anuncian todos los datos del mensaje mismo (fecha, hora, CLI, etc.)

delete no = no se borra el mensaje de voz una vez que se ha enviado anexo al correo electrónico de notificación.

volgain permite subir el volumen de grabación de los mensajes de voz. Para que funcione se necesita que SOX sea instalado en el servidor. Valor 0.0

nextaftercmd yes = en el caso de más de un mensaje de voz presente en el buzón de voz, permite pasar al mensaje siguiente sin presionar las teclas 7 o 9 (borrar/guardar el mensaje respectivamente)

forcename yes = obliga cada usuario con un buzón de voz configurado, grabar su nombre la primera vez que acceda. Un usuario se considera nuevo si la contraseña del buzón de voz coincide con el numero de extensión

forcegreeting no = obliga un nuevo usuario a grabar un mensaje de bienvenida para su buzón de voz

hidefromdir no = el usuario aparecerá en el directorio. yes = el usuario no aparecerá en el directorio

tempgreetwarn yes = recuerda al usuario que el mensaje de bienvenida que está usando es temporal hasta que no grabe uno personalizado.

passwordlocation A partir de la versión 1.8.X de Asterisk es posible definir donde se guardarán las contraseñas para cada buzón de voz. Posibles valores:

– voicemail.conf - Se guardarán en este archivo

250

Page 262: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

– spooldir – la contraseñas se guardarán en un archivo de texto (secret.conf) que hay que crear en la carpeta /var/spool/asterisk/voicemail/contexto/usuario donde contexto es el nombre del contexto al que pertenece el buzón de voz y usuario es el numero del buzón de voz de la extensión

messagewrap yes = Mientras se están escuchando los mensajes de voz, permite, presionando 6 desde el ultimo mensaje escuchado volver al primero, presionando 4 del primero mensaje ir al ultimo.

minpassword define una longitud mínima para la contraseña del buzón de voz (en numero de cifras). Valor 4

;vm-password=custom_sound;vm-newpassword=custom_sound ;vm-passchanged=custom_sound ;vm-reenterpassword=custom_sound ;vm-mismatch=custom_sound;vm-invalid-password=custom_sound;vm-pls-try-again=custom_sound

estos parámetros permiten personalizar las locuciones. Se dejan comentadas

listen-control-forward-key # = tecla para el avance rápido del mensajelisten-control-reverse * = tecla para rebobinar el mensajelisten-control-pause-key 0 = tecla numérica para poner en pausa/reanudar el mensajelisten-control-restart-key 2 = tecla numérica para volver a escuchar el mensaje desde el

iniciolisten-control-stop-key 13456789 = teclas numéricas para terminar la escucha de un

mensaje de voz (todas, menos las ya configuradas)backupdeleted 50 = numero máximo de mensajes de voz permitidos en la

carpeta de borrados[zonemessages] a partir de esta etiqueta se configuran las distintas zona

horarias que se podrán configurar para cada buzón de voz. De esta forma el propietario de cada buzón de voz, escuchará la fecha y la hora en que se dejó el mensaje de voz según el país en que se encuentre. Lo mismo pasará con el correo electrónico de notificación. Siguen algunos ejemplos

eastern America/New_York|'vm-received' Q 'digits/at' IMpcentral America/Chicago|'vm-received' Q 'digits/at' IMpeuropean Europe/Copenhagen|'vm-received' a d b 'digits/at' HMcolombia America/Bogota|'vm-received' aebY 'digits/at' HM

251

Page 263: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónmexico America/Mexico_City|'vm-received' aebY 'digits/at' HM[default] a partir de esta etiqueta se configuran los contextos para los

buzones de voz. En el configuración de las extensiones en el sip.conf para el parámetro mailbox se ha puesto como valor “default”. Ese el el contexto que hay que configurar en el voicemail.conf y la etiqueta lo define. Después del contexto, se configuran todos los buzones de voz, uno por linea, siguiendo la sintaxis: Numero extensión => contraseña, nombre apellido, correo electrónico, correo pager,opciones

1000 => 1000,fulano de tal,[email protected],,tz=colombia1001 => 1001,fulano de pascual,[email protected],,tz=colombia1002 => 1002,zutano pelado,[email protected],,tz=european1234 => 1234,marko,[email protected],,tz=mexico1235 => 1235,marko2,[email protected],,tz=central

IMPORTANTE: Todos los datos (nombre, correo electrónico y zona horaria presentes en el archivo, van personalizados.

De esta forma se han definidos los buzones de voz para todas las extensiones configuradas en Asterisk meno la 1004. Como la contraseña es igual al numero de extensión, la primera vez que el usuario entre en su buzón de voz, se le pedirá de cambiar la contraseña y configurar su buzón de voz.

Ahora se puede crear el archivo. Se renombra el predefinido:

mv /etc/asterisk/voicemail.conf /etc/asterisk/voicemail.conf.old

se crea uno nuevo:

nano /etc/asterisk/voicemail.conf

se copian las siguientes lineas:

[general]format=wav49|gsm|[email protected]=yesmaxmsg=100maxsecs=500minsecs=5maxgreet=180skipms=3000maxsilence=4

252

Page 264: Libro Asterisk 1.8.X - Versión 1.0 (1)

silencethreshold=128maxlogins=3moveheard=yesforward_urgent_auto=no;externnotify=/usr/bin/myapp;externpass=/usr/bin/myapp;externpassnotify=/usr/bin/myappdirectoryintro=dir-introcharset=ISO-8859-1pbxskip=yesfromstring=Buzon de Vozusedirectory=yes;odbcstorage=asterisk;odbctable=mensajes

emailsubject=Nuevo mensaje de voz ${VM_MSGNUM} en el buzon de voz ${VM_MAILBOX}emailbody=Estimando ${VM_NAME}:\n\n\t le estamos enviando este correo para avisarle que ha recibido un nuevo mensajede voz de ${VM_DUR} segundos (numero ${VM_MSGNUM})\n\n buzon de voz ${VM_MAILBOX} del numero ${VM_CALLERID}, el${VM_DATE}.\n\n Llame su buzon de voz para escucharlo. Gracias!\n\n\t\t\t\t.Tu Buzon de Voz\n Nombre empresa; todo el texto del parametro "emailbody" tiene que estar en la misma linea

emaildateformat=%A, %d %B %Y at %H:%M:%Smailcmd=/usr/sbin/sendmail -ttz=centrallocale=es_CO.iso88591attach=yesattachfmt=wavsaycid=yescidinternalcontexts=internassayduration=yessaydurationm=2dialout=externassendvoicemail=yes;callback=fromvm:exitcontext=fromvmreview=yes;operador=yesenvelope=yesdelete=novolgain=0.0nextaftercmd=yesforcename=yesforcegreeting=nohidefromdir=no

253

Page 265: Libro Asterisk 1.8.X - Versión 1.0 (1)

tempgreetwarn=yespasswordlocation=voicemail.confmessagewrap=yesminpassword=4;vm-password=custom_sound;vm-newpassword=custom_sound;vm-passchanged=custom_sound;vm-reenterpassword=custom_sound;vm-mismatch=custom_sound;vm-invalid-password=custom_sound;vm-pls-try-again=custom_soundlisten-control-forward-key=#listen-control-reverse=*listen-control-pause-key=0listen-control-restart-key=2listen-control-stop-key=13456789backupdeleted=50

[zonemessages]; Supported values:; 'filename' filename of a soundfile (single ticks around the filename; required); ${VAR} variable substitution; A or a Day of week (Saturday, Sunday, ...); B or b or h Month name (January, February, ...); d or e numeric day of month (first, second, ..., thirty-first); Y Year; I or l Hour, 12 hour clock; H Hour, 24 hour clock (single digit hours preceded by "oh"); k Hour, 24 hour clock (single digit hours NOT preceded by "oh"); M Minute, with 00 pronounced as "o'clock"; N Minute, with 00 pronounced as "hundred" (US military time); P or p AM or PM; Q "today", "yesterday" or ABdY; (*note: not standard strftime value); q "" (for today), "yesterday", weekday, or ABdY; (*note: not standard strftime value); R 24 hour time, including minuteeastern=America/New_York|'vm-received' Q 'digits/at' IMpcentral=America/Chicago|'vm-received' Q 'digits/at' IMpeuropean=Europe/Copenhagen|'vm-received' a d b 'digits/at' HMcolombia=America/Bogota|'vm-received' aebY 'digits/at' HMmexico=America/Bogota|'vm-received' aebY 'digits/at' HM

[default]; personalizar nombres, apellidos, correos electrónicos y zona horaria1000 => 1000,fulano de tal,[email protected],,tz=colombia

254

Page 266: Libro Asterisk 1.8.X - Versión 1.0 (1)

1001 => 1001,fulano de pascual,[email protected],,tz=colombia1002 => 1002,zutano pelado,[email protected],,tz=european1234 => 1234,marko,[email protected],,tz=mexico1235 => 1235,marko2,[email protected],,tz=central

IMPORTANTE: personalizar el parámetro serveremail con su nombre de dominio y los parámetros nombre, correo electrónico y zona horaria de cada buzón de voz.

Se guardan los cambios y se recarga la configuración del voicemail.conf:

asterisk -rvvvvvvvvvvvvvvvv

CLI> voicemail reload

Para ver los usuarios configurados y los mensajes de voz presentes:

CLI> voicemail show usersContext Mbox User Zone NewMsgdefault general New User 0default 1000 fulano de tal colombia 0default 1001 fulano de pascual colombia 0default 1002 zutano de tal european 0default 1234 marko mexico 0default 1235 marko2 central 0

Para ver la zonas horarias configuradas:

CLI> voicemail show zonesZone Timezone Message Formatmexico America/Bogota 'vm-received' aebY 'digits/at' HMcolombia America/Bogota 'vm-received' aebY 'digits/at' HMeuropean Europe/Copenhagen 'vm-received' a d b 'digits/at' HMcentral America/Chicago 'vm-received' Q 'digits/at' IMpeastern America/New_York 'vm-received' Q 'digits/at' IMp

Se sale la consola:

CLI> quit

Para que una llamada si no es contestada o si la extensión está ocupada se envíe al buzón de voz, hay que modificar el dialplan. Como esta parte es igual para todas las extensiones, se creará una Macro.

Se abre el archivo del dialplan:

nano /etc/asterisk/extensions.conf

255

Page 267: Libro Asterisk 1.8.X - Versión 1.0 (1)

Primero se añade la parte para llamar el buzón de voz en el contexto internas:

exten => 97,1,Answersame => n,VoiceMailMain(${CALLERID(num)}@default)same => n,Hangup

• Linea1 – contesta la llamada• Linea2 – envía la llamada al buzón de voz del llamante (CALLERID(num) y al contexto default

(configurado en voicemail.conf)• Linea2 – cuelga la llamada

Para entrar al buzón de voz general y luego digitar numero de buzón y contraseña:

exten => 98,1,VoicemailMainsame => n,Hangup

Para buscar un usuario en el directorio:

exten => 99,1,Directory(default,internas,e)same => n,Hangup

se modifica estos tres bloques para que queden:

exten => _100[0-2,4],1,Macro(disponible)same => n,Macro(calendario)same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Hangup

exten => 1234,1,Dial(IAX2/marko,30)same => n,Hangup

exten => 1235,1,Dial(IAX2/marko2,30)same => n,Hangup

para que queden:

exten => _100[0-2,4],1,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Macro(voicemail)same => n,Hangup

exten => 1234,1,Dial(IAX2/marko,30)same => n,Macro(voicemail)same => n,Hangup

exten => 1235,1,Dial(IAX2/marko2,30)same => n,Macro(voicemail)

256

Page 268: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Hangup

Luego al final del archivo se crea la macro:

[macro-voicemail]exten => s,1,Goto(s-${DIALSTATUS},1)exten => s-BUSY,1,Voicemail(${MACRO_EXTEN}@default,b)same => n,Hangupexten => s-CANCEL,1,Hangupexten => s-CONGESTION,1,Congestionsame => n,Hangupexten => _s-.,1,Voicemail(${MACRO_EXTEN}@default,u)same => n,Hangup

La aplicación dial genera la variable DIALSTATUS que contiene uno de los siguientes valores:

• CHANUNAVAIL• CONGESTION• NOANSWER• BUSY• ANSWER• CANCEL• DONTCALL• TORTURE

En base al valor se enviará la llamada a un determinado punto de la macro, por ejemplo, si el valor es BUSY, la llamada se transferirá al buzón de voz anunciando al llamante que la extensión está hablando.

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvv

CLI> dialplan reload

La primera operación es la de configurar el buzón de voz de la extensión 1000. Desde esa extensión se marca el numero 97 y se siguen los pasos indicados por las locuciones.

Terminada esta operación se marca desde la extensión 1000 el numero 99 para probar el directorio. En el directorio se busca una persona digitando en el teclado del teléfono las primeras tres letras del apellido. Si el apellido existe, se podrá llamar directamente desde esta aplicación. Hacer la prueba marcando el apellido (como configurado en el voicemail.conf) de la extensión 1002.

Como ultima prueba, desde la extensión 1001 se marca la extensión 1000 y no se contesta la llamada. La extensión 1001 será transferida al buzón de voz de la extensión 1000 donde se dejará un mensaje.

En la interfaz de X-Lite (extension 1000), aparecerá:

257

Page 269: Libro Asterisk 1.8.X - Versión 1.0 (1)

La parte evidenciada indica que hay un mensaje en el buzón de voz de la extensión 1000. Se puede comprobar también desde la consola:

CLI> voicemail show usersContext Mbox User Zone NewMsgdefault general New User central 0default 1000 fulano de tal colombia 1default 1001 fulano de pascual colombia 0default 1002 zutano pelado european 0default 1234 marko mexico 0default 1235 marko2 central 07 voicemail users configured.

y con el correo electrónico recibido:

El anexo es el archivo audio con el mensaje de voz. Se puede escuchar el mensaje llamando también el numero 97.

Los tres archivos audio (en los tres formatos definidos en voicemail.conf) se encontrarán en la carpeta:

258

Page 270: Libro Asterisk 1.8.X - Versión 1.0 (1)

ls - /var/spool/asterisk/voicemail/default/1000/INBOX/

-rw-r--r-- 1 root root 17127 Oct 19 20:37 msg0000.gsm-rw-rw-rw- 1 root root 271 Oct 19 20:37 msg0000.txt-rw-r--r-- 1 root root 166124 Oct 19 20:37 msg0000.wav-rw-r--r-- 1 root root 16895 Oct 19 20:37 msg0000.WAV

El archivo msg0000.txt contiene toda la información relacionada con el mensaje de voz:

;; Message Information file;[message]origmailbox=1000context=macro-voicemailmacrocontext=localesexten=s-BUSYpriority=1callerchan=SIP/1002-00000032callerid="Mengano" <1002>origdate=Thu Oct 20 01:37:07 AM UTC 2011origtime=1319074627category=flag=duration=10

14.2 Mensajes de voz en una base de datos

Los mensaje de voz, ademas de guardarse en la carpeta indicada en el párrafo anterior, pueden guardarse en una base de datos. Esto permite implementar aplicaciones que desde la Web permitan escuchar los mensajes de voz y revisar todos los datos de los mismos. Esta configuración se basa en el conector ODBC y una base de datos (en este caso MySQL). Para que funcione, hay que volver a compilar Asterisk con el soporte ODBC para el buzón de voz.

Se entra en la carpeta de las fuentes de Asterisk y se siguen estos pasos:

cd /usr/src/asterisk-1.8.11.0

make distclean

./configure

make menuselect

Cuando se recompila Asterisk, como ya se ha visto anteriormente, hay que volver a seleccionar los

259

Page 271: Libro Asterisk 1.8.X - Versión 1.0 (1)

modulos Add-ons:

Luego en el menú “Voicemail Build Options” seleccionar “ODBC_STORAGE”:

Se guardan los cambios y se compila Asterisk:

make

Antes de instalar nuevamente los modulo de Asterisk, se para el servicio:

service asterisk stop

Luego se instala:

make install

Ahora, para guardar los mensaje de voz en la base de datos, hay que crear la tabla. En algunos casos los datos de las tablas se encuentran en la carpeta contrib/realtime/mysql de las fuentes de Asterisk como es para los mensajes de voz.

mysql -u root -psesamo asterisk < contrib/realtime/mysql/voicemail_messages.sql

Creada la tabla hay que modificar dos parámetros en el archivo voicemail.conf:

nano /etc/asterisk/voicemail.conf

modificar estas dos lineas:

;odbcstorage=asterisk;odbctable=mensajes

260

Page 272: Libro Asterisk 1.8.X - Versión 1.0 (1)

para que queden:

odbcstorage=asteriskodbctable=voicemail_messages

Se guardan los cambios y se inicia Asterisk:

service asterisk start

Se entra en la consola de Asterisk y se averigua que el modulo esté funcionando con ODBC Storage:

asterisk -rvvvvvvvvvvvvvvvvvv

CLI> module unload app_voicemail.so

CLI> module load app_voicemail.soLoaded app_voicemail.so == Parsing '/etc/asterisk/voicemail.conf': == Found == Parsing '/etc/asterisk/users.conf': == Found == Registered application 'VoiceMail' == Registered application 'VoiceMailMain' == Registered application 'MailboxExists' == Registered application 'VMAuthenticate' == Registered application 'VMSayName' == Registered custom function 'MAILBOX_EXISTS' == Manager registered action VoicemailUsersList Loaded app_voicemail.so => (Comedian Mail (Voicemail System) with ODBC Storage)

Por lo que aparece en negrita parece que si. Para probarlo, desde la extensión 1001 o 1002 se llama la extensión 1000 y se deja un mensaje en el buzón de voz.

Para averiguar que el mensaje ha sido guardado en la tabla:

mysql -u root -psesamo

mysql> use asterisk

mysql> select dir,msgnum,context,callerid from voicemail_messages;

+--------------------------------------------------+--------+-----------------+-----------------+| dir | msgnum | context | callerid |+--------------------------------------------------+--------+-----------------+-----------------+| /var/spool/asterisk/voicemail/default/1000/INBOX | 0 | macro-voicemail | "zutano" <1001> |+--------------------------------------------------+--------+-----------------+-----------------+1 row in set (0.00 sec)

Perfecto!!

261

Page 273: Libro Asterisk 1.8.X - Versión 1.0 (1)

14.3 Buzones de voz en una base de datos

Además de los mensajes de voz, también los buzones de voz se pueden guardar en una base de datos. En este caso se utilizará el Realtime dinámico. La ventaja, como ya se ha dicho anteriormente, es que esto permite modificar los valores directamente desde la base de datos o desde una aplicación Web que trabaje con la base de datos..

Los pasos a seguir son:

• crear la tabla en la base de datos• configurar el realtime dinámico• reiniciar asterisk

Como para la tabla de los mensajes de voz, se utilizará la tabla presente en las fuentes de Asterisk:

cd /usr/src/asterisk-1.8.11.0/contrib/realtime/mysql/

mysql -u root -psesamo asterisk < voicemail.sql

Creada la tabla se configura el realtime dinámico:

nano /etc/asterisk/extconfig.conf

Se modifica esta linea:

;voicemail => odbc,asterisk

para que quede:

voicemail => odbc,asterisk,voicemail

Se guardan los cambios y se reinicia Asterisk:

service asterisk restart

Ahora se configura el buzón de voz de la extensión 1004 (la configurada en SIP realtime) en la tabla a través de webmin:

262

Page 274: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la tabla aparecen todas las opciones que se pueden configurar para un buzón de voz. Se termina

263

Page 275: Libro Asterisk 1.8.X - Versión 1.0 (1)

presionando el botón “Save” y desde la extensión 1004 se marca el 97 para probar la configuración. Si todo funciona, ya se ha terminado con la configuración de los buzones de voz.

264

Page 276: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 277: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XV

Las conferencias audio

Cuarta parte - Las conferencias audio – meetme.conf

En Asterisk una funcionalidad bastante interesante es la de las conferencias audio. Para utilizar esta funcionalidad, existen dos aplicaciones:

• meetme• confbridge

La primera es la más conocida y ha sido implementada en Asterisk desde las primeras versiones. Meetme se apoya a DAHDI para generar la sincronización de los canales audios presentes en la conferencia creando una canal pseudo-DAHDI para cada conferencia. Sin DAHDI instalado, meetme no funciona. Confbridge ha sido añadida a Asteirks a partir de la versión 1.6.1.X y no necesita DAHDI para funcionar, pero implementa menos funciones y no es posible configurarla en Realtime dinámico. La configuración de meetme se hace a partir de un archivo dedicado mientras las conferencias creadas con Confbridge no necesitan configuración previa.

15.1 meetme.conf

Como para los demás archivos de configuración de Asterisk, se presentan los parámetros con una breve descripción. En negrita los valores que se asignarán. Al final de la tabla el archivo completo.

Parámetro Descripción[general] Inicia la parte general de configuraciónaudiobuffers Numero de paquetes audio de 20ms que serán

guardados en un buffer de memoria cuando pertenecen a canales que no son DADHI. Esto permite sincronizar el audio de los distintos participantes y evitar retrasos. Puede ser un valor entre 2 y 32. Valor 32

schedule Este parámetro va configurado en yes solamente si se usan las conferencias en realtime (ARA). En caso contrario hay que dejarlo en no

logmembercount Si las conferencias están configuradas en Realtime este parámetro actualiza la tabla cada vez que un usuario entre o salga de la conferencia. Valor yes

fuzzystart Hay una conferencia programada a las 8 de la mañana. Este parámetro se utiliza para definir si un usuario puede o no entrar en la conferencia si eésta no ha empezado. 300 es el número de

Page 278: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónsegundos. Ejemplo. Si el usuario entra a la 7:55 será aceptado porque puede entrar hasta 5 minutos (300 segundos) antes del comienzo de la conferencia. Si entra a las 7:50 será rechazado. Funciona solamente en Realtime

earlyalert Este valor (siempre en segundos) define si al usuario que intenta entrar en una conferencia programada le será anunciado o no que la conferencia todavía no ha empezado. Con el valor en 3600, si entra cuando falta menos de una hora recibirá este aviso. Si entra más de una hora antes se le anunciará que la conferencia no existe.

endalert Cuando falten los segundos indicados en este parámetro para que termine una conferencia programada, a los usuario se les presentará un aviso. Valor 120

[rooms] a partir de esta etiqueta inicia la configuración de las conferencias. La sintaxis es:conf => confno[,pin][,adminpin]

conf => 3500 Se configura la primera sala de conferencia sin PIN de usuario y PIN de administrador

conf => 3501,1234 Se configura la segunda sala de conferencia con PIN de usuario 1234 y sin PIN de administrador

conf => 3502,1234,5678 Se configura una tercera sala de conferencia con PIN de usuario 1234 y PIN de administrador 5678

Se renombra el archivo predefinido:

mv /etc/asterisk/meetme.conf /etc/asterisk/meetme.conf.old

y se crea uno nuevo con los parámetros indicados en la tabla:

nano /etc/asterisk/meetme.conf

[general]audiobuffers=32schedule=nologmembercount=yesfuzzystart=300earlyalert=3600endalert=120

267

Page 279: Libro Asterisk 1.8.X - Versión 1.0 (1)

[rooms]conf => 3500conf => 3501,1234conf => 3502,1234,5678

Se guardan los cambios y se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvvv

se recarga el modulo app_meetme

CLI> module reload app_meetme.so

se revisa la sintaxis de la aplicación meetme:

CLI> core show application meetme

Como se puede ver hay muchos parámetros y opciones que se pueden configurar.

Hay otras aplicaciones relacionadas con las conferencias:

CLI> core show application meetme (más la tecla tabulador)

MeetMe MeetMeAdmin MeetMeChannelAdmin MeetMeCount

Las aplicaciones disponibles son cuatro. La primera es para entrar en una conferencia, la segunda para administrarla, la tercera es para controlar un canal de la conferencia y la tercera para conocer el numero de usuarios presentes en una conferencia.

CLI> quit

Ahora se modifica el dialplan para utilizar las conferencias.

nano /etc/asterisk/extensions.conf

después del contexto internas se añade un nuevo contexto:

[conferencias]exten => _350[012],1,Meetme(${EXTEN},scM(default))same => n,Hangup

Llamando la extensión 3500,3501 o 3502 se entrará en el cuarto de conferencia (como configurado en meetme.conf)

Las tres opciones:

• s - Con esta opción se activa el menú del cuarto de conferencias para usuarios y

268

Page 280: Libro Asterisk 1.8.X - Versión 1.0 (1)

administradores. Marcando la tecla asterisco se escuchará el menú• c - Al entrar en un cuarto de conferencia se le anunciará al usuario el número de personas

presentes• M(default) - Cuando en el cuarto de conferencia está solamente una persona, ésta escuchara la

música de espera de la clase default”

Existe la posibilidad de crear cuartos de conferencias de forma dinámica (sin tener que configurarlos en el archivo meetme.conf). A seguir un ejemplo que se va a añadir al dialplan en el contexto conferencias:

exten => 3510,1,Meetme(,DM(default))same => n,Hangup

Primero no se indica el número del cuarto de conferencias y se usa la opción D que permite definir la extensión 3510 como cuarto de la conferencia y un PIN para entrar. El PIN de la conferencia será el que será digitado por la primera persona que entre en la conferencia. Si en lugar de la opción D se pone la opción d no se necesitará definir un PIN para el cuarto de conferencia.

Otro ejemplo que se puede añadir al dialplan es crear una conferencia y definir como numero máximo de participantes 10. Esto se hace con una Macro. En el contexto conferencias se pone:

exten => 3520,1,Set(confmax=10)same => n,Macro(meetme)same => n,Hangup

y al final del archivo se añade la Macro:

[macro-meetme]exten => s,1,MeetMeCount(${MACRO_EXTEN},count)same => n,Gotoif($[${count} > ${confmax}]?llena)same => n,MeetMe(${MACRO_EXTEN},D)same => n,Hangupsame => n(llena),Playback(conf-invalid)same => n,Hangup

Una explicación. Primero se asocia a la variable confmax el numero 10 (el numero máximo de participantes permitidos en la conferencia) y luego se llama la macro meetme. Con la primera línea de la macro se controla con la aplicación MeetmeCount cuantos usuarios están en la conferencia 3520 y se asocia ese valor a la variable count. Si el numero contenido en la variable count es mayor al numero contenido en la variable confmax (10) se va a la línea con la etiqueta (llena) donde se comunicará que la conferencia no es valida y se colgará la llamada; si es menor el usuario podrá entrar al cuarto de conferencias.

Para terminar la configuración del dialplan, para que las extensiones tengan acceso al contexto conferencias hay que añadir la linea en negrita al contexto externas y locales:

269

Page 281: Libro Asterisk 1.8.X - Versión 1.0 (1)

[externas]include => internasinclude => internacioinclude => parkedcallsinclude => testinclude => conferencias

[locales]include => internasinclude => auteninclude => parkedcallsinclude => testinclude => conferencias

Se guardan los cambios y se actualiza el dialplan:

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde las extensiones 1000 y 1001 se marca el numero 3500 para entrar en la primera conferencia configurada en el archivo meetme.conf.

Para ver las extensiones presentes en la conferencia:

CLI> meetme list 3500User #: 01 1000 callerid=Fulano Channel: SIP/1000-00000003 (unmonitored) 00:02:45User #: 02 1001 zutano Channel: SIP/1001-00000007 (unmonitored) 00:00:532 users in that conference.

Para sacar un usuario de la conferencia:

CLI> meetme kick 3500 1 == Setting global variable 'MEETMEADMINSTATUS' to 'OK' -- <SIP/1000-00000003> Playing 'conf-kicked.alaw' (language 'es') -- Executing [3500@externas:2] Hangup("SIP/1000-00000003", "") in new stack

Quedará:

CLI> meetme list 3500User #: 02 1002 Mengano Channel: SIP/1002-00000005 (unmonitored) 00:04:091 user in that conference.

Para probar la Macro desde la extensión 1000 se marca 3520.

15.2 Aplicación ConfBridge

270

Page 282: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para conocer la sintaxis de la aplicación ConfBridge:

CLI> core show application ConfBridge

-= Info about application 'ConfBridge' =-

[Synopsis]Conference bridge application.

[Description]Enters the user into a specified conference bridge. The user can exit theconference by hangup only.The join sound can be set using the 'CONFBRIDGE_JOIN_SOUND' variable andthe leave sound can be set using the 'CONFBRIDGE_LEAVE_SOUND' variable. Thesecan be unique to the caller.NOTE: This application will not automatically answer the channel.

[Syntax]ConfBridge([confno][,options])

[Arguments]confno The conference numberoptions a: Set admin mode.

A: Set marked mode.

c: Announce user(s) count on joining a conference.

m: Set initially muted.

M[(class)]: Enable music on hold when the conference has a single caller. Optionally, specify a musiconhold class to use. If one is not provided, it will use the channel's currently set music class, or 'default'.

1: Do not play message when first person enters

s: Present menu (user or admin) when '*' is received (send to menu).

w: Wait until the marked user enters the conference.

q: Quiet mode (don't play enter/leave sounds).

271

Page 283: Libro Asterisk 1.8.X - Versión 1.0 (1)

[See Also]Not available

Como esta aplicación no contesta automáticamente el canal, para configurarla en el dialplan hay que iniciar el bloque con un Answer:

CLI> quit

nano /etc/asterisk/extensions.conf

En el contexto conferencias se añade:

exten => 3530,1,Answersame => n,ConfBridge(3530,Mcs)same => n,Hangup

Se guardan los cambios y se actualiza el dialplan:

asterisk -rvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se marca el numero 3530. A diferencia de meetme, con ConfBridge no se puede, desde la consola de Asterisk, controlar los participantes presentes, ni hacer otros tipos de operaciones.

15.3 Meetme en Realtime Dinámico

Como se ha comentado anteriormente, es posible configurar las conferencias en Realtime dinámico. Lo primero es crear la tabla en la base de datos Asterisk:

mysql -u root -psesamo

mysql> use asterisk

mysql> CREATE TABLE `meetme` ( `confno` char(80) NOT NULL default '0', `starttime` datetime NOT NULL default '0000-00-00 00:00:00', `endtime` datetime default NULL, `pin` char(20) default NULL, `opts` char(100) default NULL, `adminpin` char(20) default NULL, `adminopts` char(100) default NULL, `members` int(11) NOT NULL default '0',

272

Page 284: Libro Asterisk 1.8.X - Versión 1.0 (1)

`maxusers` int(11) NOT NULL default '0', PRIMARY KEY (`confno`,`starttime`) );

mysql> quit

Creada la tabla, se modifica el archivo extconfig.conf

nano /etc/asterisk/extconfig.conf

se busca esta linea:

;meetme => mysql,general

y se modifica para que quede:

meetme => odbc,asterisk,meetme

Se guardan los cambios y se modifica el parámetro schedule del archivo meetme.conf para permitir la creación de conferencias programadas en Realtime:

nano /etc/asterisk/meetme.conf

schedule= no

se cambia a:

schedule=yes

Se guardan los cambios y se recarga toda la configuración de Asterisk:

service asterisk reload

Como algunas locuciones para las conferencias programadas no existen en la instalación estándar de Asterisk, hay que descargarlas:

cd /tmp

wget http://www.voztovoice.org/tmp/confprompts.tar

descomprimir el paquete:

tar -xf confprompts.tar

y moverlas en la carpeta de la locuciones en ingles:

mv *.wav /var/lib/asterisk/sounds/en

273

Page 285: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora para la prueba se configuran dos conferencias a través de Webmin. La idea es crear una que inicie dentro de 50 minutos y otra que inicie dentro de 5 minutos y que las dos duren una hora.

Se guardan los datos presionando el botón Save. La segunda:

Las opciones que aparecen en las dos conferencias para los usuarios:

• c – anuncia los usuarios presentes en la conferencia• I – obliga al usuario que entra a la conferencia a grabar su nombre

274

Page 286: Libro Asterisk 1.8.X - Versión 1.0 (1)

• s – se activa la tecla “*” para entrar en un menú que permite modificar algunos parámetros personales (volumen de la conferencia, volumen del micrófono, etcétera).

La única diferencia con las opciones del administrador es la opción a que activa el modo administrador.

Para terminar hay que añadir las dos conferencias en el dialplan

nano /etc/asterisk/extensions.conf

en el contexto conferencias se añade el siguiente bloque:

exten => _500[01],1,Meetme(${EXTEN})same => n,Hangup

Se guardan los cambios y se actualiza la configuración

asterisk -rvvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora se hace una prueba llamando primero la conferencia 5000 y luego la 5001. En el primer caso un anuncio avisará que la conferencia no ha empezado, en el segundo, como faltan menos de 5 minutos para que empiece, deja entrar el usuario (como configurado en el parámetro fuzzystart, 300 segundos).

15.4 Aplicación Page

La aplicación Page se utiliza para crear conferencias instantáneas llamando un grupo de extensiones simultáneamente. Dependiendo del tipo de opciones configuradas, se podrán crear distintos tipos de escenarios:

• solamente quien ha iniciado la llamada podrá hablar• todas las extensiones podrán hablar• como sistema de intercomunicación para comunicar breves mensajes a la persona llamada (el

teléfono del destinatario abrirá la linea en automático)

La sintaxis de la aplicación es:

Page(Technology/Resource[&Technology2/Resource2[&...]][,options[,timeout]])

y las opciones disponibles:

• d – audio en ambas direcciones• i – no se tomarán en cuenta intentos de transferir la llamada• q – modo silencioso, el llamante no escuchará un beep• r – se grabará la conferencia en un archivo audio

275

Page 287: Libro Asterisk 1.8.X - Versión 1.0 (1)

• s – solo se intentará incluir en las conferencias las extensiones cuyo estado sea “NOT_INUSE”• A(x) – envía un anuncio a todos los participantes de la conferencia. x es el nombre del archivo

audio que contiene la locución• n – no envía un anuncio a todos los participantes de la conferencia. Implica que A(x) sea

presente

Una prima forma de probar la aplicación es:

exten => 501,1,Page(SIP/1001&SIP/1002)same => n,Hangup

Una vez que las dos extensiones contesten, solamente la 1000 tendrá activado el audio.

Una variación de este bloque es:

exten => 502,1,Page(SIP/1001&SIP/1002,d)same => n,Hangup

En este caso todas las extensiones tendrán el micrófono activado.

Utilizar Page como sistema de intercomunicación puede ser muy útil, por ejemplo, en una empresa donde se quiera comunicar a todos los empleados un anuncio. En este caso se conecta a Asterisk una ATA tipo el PA1 de SNOM, que a su vez se puede conectar a un sistema de amplificación audio. Llamando la extensión asociada al PA1, este contestará la llamada en automático y el anuncio será difundido por el sistema de parlantes conectados al ATA.

El mismo sistema se utiliza con los teléfonos SIP. Dependiendo de la marca hay que enviar una cabecera especifica en el INVITE para que el teléfono mismo la reconozca y conteste la llamada en automático activando el parlante (alta voz) del teléfono. Las cabeceras se añaden a través de la aplicación Sipaddheader de Asterisk

Estas cabeceras cambian según la marca de los telefonos. Algunos ejemplos:

• Aastra - SIPAddHeader(Alert-Info: info=alert-autoanswer)• Polycom - SIPAddHeader(Alert-Info: Ring Answer)• Snom - SIPAddHeader(Call-Info: sip:domain.com\;answer-after=0)• Cisco SPA - SIPAddHeader(Call-Info:\;answer-after=0) • Yealink - SIPAddHeader (P-Auto-answer: normal)

Ahora in una hipotética oficina donde el gerente quiera hacer una anuncio a la secretaria y ambos están utilizando teléfonos Yealink cuya extensiones son 1000 para el gerente y 1001 para la secretaria, el dialplan sería:

exten => 503,1,SIPAddHeader (P-Auto-answer: normal)same => n,Page(SIP/1001,i)same => hangup

276

Page 288: Libro Asterisk 1.8.X - Versión 1.0 (1)

El gerente marca 503 y hace el anuncio a la secretaria cuyo teléfono habrá contestado en automático activando el parlante.

Para terminar este párrafo se modifica el dialplan:

nano /etc/asterisk/extensions.conf

y en el contexto conferencias se añaden los dos bloques que siguen:

exten => 501,1,Page(SIP/1001&SIP/1002)same => n,Hangup

exten => 502,1,Page(SIP/1001&SIP/1002,d)same => n,Hangup

Se guardan los cambios y se actualiza el dialplan:

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca primero el numero 501 y luego el 502.

277

Page 289: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 290: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XVI

Distribución automática de llamadas – Colas de espera

Cuando se llama un centro de atención al cliente, sin saberlo, se está adentro de un sistema de distribución automática de las llamadas. ¿Cómo funciona? Cada llamada que llega se pone en una cola de espera respetando la prioridad con que ha llegado. Cuando uno de los operadores que atienden las llamadas está libre, la llamada sera transferida a ese operador. A lo largo de la espera, según la configuración, el llamante escuchará distintos anuncios (que posición tiene en la cola, el tiempo estimado de espera y un largo etcétera).

Quizás este es el servicio más importante y estratégico para una empresa. En base a su calidad y el tiempo promedio de espera, los clientes estarán evaluando la misma empresa.

¿Cómo se configura en Asterisk la gestión de las colas? A través de dos archivos:

• agents.conf• queues.conf

En el primero se configuran, definiendo algunas variables y parámetros, los agentes que atenderán las colas. En el queues.conf se configuran las colas (pueden ser una o más), los agentes miembros de cada cola y que tipo de estrategia se utilizará para enrutar las llamadas en la cola.

16.1 Los Agentes

Para configurar los agentes que atenderán las llamadas entrantes a las distintas colas hay que modificar el archivo agents.conf. En la tabla que sigue los distintos parámetros con una breve descripción. En negrita el valor asociado a cada parámetro. Al final del la tabla el archivo completo de configuración.

Parámetro Descripción[general] etiqueta que da inicio a la parte general del

archivomultiplelogin Define si está permitido a una extensión

conectarse como agente múltiple. Valor no[agents] A partir de esta etiqueta inicia la configuración de

los agentesmaxlogintries Numero de intentos permitidos a un agente para

autenticarse. Valor 3autologoff Numero de segundos que un agente tiene para

contestar una llamada entrante. Si no contesta dentro de ese tiempo, será desconectado de la cola. Valor 15

autologoffunavail yes = si la extensión desde la cual el agente se

Page 291: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónconecta se vuelve no disponible, automáticamente el agente será desconectado de la cola

ackcall Para atender una llamada un agente tiene que presionar la tecla configurada en el próximo parámetro. Valor no (no tiene que presionarla)

acceptdtmf #endcall yes = permite al agente terminar una llamada

presionando la tecla configurada en el próximo parámetro

enddtmf *wrapuptime Numero de mili segundos que Asterisk esperará

antes de volver a llamar un agente que acaba de atender una llamada. Valor 5000

musiconhold Música de espera predefinida para el agente. Valor default

;goodbye=vm-goodbye locución que el agente escuchará al terminar una llamada. Si se deja comentado será la predefinida (vm-goodbye)

updatecdr Actualizar o no el CDR con el nombre del agente. Valor no

;group obsoleto. No usarrecordagentcalls grabar o no las llamadas de los agentes. Valor norecordformat Formato audio de las llamadas grabadas. Valor

wav;urlprefix el prefijo del nombre del los archivos grabados.

Puede ser una URL. Ejemplo http://www.voztovoice.org/calls. Se deja comentado

;savecallsin De manera predefinida las llamadas grabadas se guardan en la carpeta: /var/spool/asterisk/monitor Si se quiere personalizar la carpeta se indica en este parámetro. Se deja comentado

custom_beep Avisa al agente que está conectado permanentemente a la cola, de la llegada de una llamada. Valor beep

agent Ahora se configuran los agentes. Las sintaxis es:agent => agentid,agentpassword,nameValor: 2000,1234,Fulano

280

Page 292: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónagent 2001,1235,Zutanoagent 2002,1236 Mengano

Se renombra el archivo predefinido:

mv /etc/asterisk/agents.conf /etc/asterisk/agents.conf.old

se crea uno nuevo:

nano /etc/asterisk/agents.conf

y se añaden los parámetros de la tabla:

[general]multiplelogin=no

[agents]maxlogintries=3autologoff=15autologoffunavail=yesackcall=noacceptdtmf=#endcall=yesenddtmf=*wrapuptime=5000musiconhold=default;goodbye=vm-goodbyeupdatecdr=yes;grouprecordagentcalls=norecordformat=wav;urlprefix=http://dominio.org/calls;savecallsin=/home/callscustom_beep=beep

agent => 2000,1234,Fulanoagent => 2001,1235,Zutanoagent => 2002,1236,Mengano

Se guardan los cambios. Se entra en la consola de Asterisk y se recarga el modulo chan_agent.so:

asterisk -rvvvvvvvvvvvvvv

CLI> module reload chan_agent.so

281

Page 293: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para ver la lista de los agentes configurados:

CLI> agent show2000 (Fulano) not logged in (musiconhold is 'default')2001 (Zutano) not logged in (musiconhold is 'default')2002 (Mengano) not logged in (musiconhold is 'default')3 agents configured [0 online , 3 offline]

CLI> quit

Para que los agentes puedan autenticarse y atender las colas de que son miembros, se utiliza en el dialplan la aplicación Agentlogin:

nano /etc/asterisk/extensions.conf

en el contexto internas, se añade el siguiente bloque:

exten => _200[012],1,Agentlogin(${EXTEN})same => n,Hangup

Se guardan los cambios y se actualiza el dialplan.

asterisk -rvvvvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se marca el numero 2000, y cuando el sistema lo pide, se ingresa la clave del agente 2000 (1234) seguida por la tecla numero #. Una vez autenticado, el agente empezará a escuchar la música de espera predefinida, esperando de atender los clientes.

CLI> agent show2000 (Fulano) logged in on SIP/1000-00000001 is idle (musiconhold is 'default')2001 (Zutano) not logged in (musiconhold is 'default')2002 (Mengano) not logged in (musiconhold is 'default')3 agents configured [1 online , 2 offline]

Este sistema de conectar los agentes a las colas se ha vuelto un poco obsoleto para perqueños CallCenter y se está optando más para aplicaciones que permiten añadir a las colas de espera agentes dinámicos. Es poco productivo tener una agente conectado permanentemente a una cola además utilizando parte de la banda disponible. Es mucho más lógico conectar los agentes de forma dinámica y que mientras esperen las llamadas de los clientes, puedan utilizar el teléfono para otro tipo de actividad. Esta parte se verá en el ultimo párrafo de este capitulo. Es hora de configurar las colas.

16.2 Las colas de espera – queue.conf

282

Page 294: Libro Asterisk 1.8.X - Versión 1.0 (1)

En el archivo queues.conf se configuran las distintas colas de espera. En la tabla que sigue los distintos parámetros con una breve descripción. En negrita el valor asociado a cada parámetro. Al final de la tabla el archivo completo.

Parámetro Descripción[general] Etiqueta que define la parte general del archivopersistentmembers yes = se guardan los datos de los miembros de la cola

activos en la base de datos interna de Asterisk. Si se reinicia la PBX los miembros serán reasignados a las colas correspondientes. Valido solamente para agentes dinámicos

autofill Normalmente una cola funciona de la siguiente manera. Hay unos cuantos usuarios esperando por ser atendidos por los agentes. Cuando el usuario que está de primero en la cola viene atendido el segundo se vuelve primero e será atendido por el primer agente disponible. Este comportamiento no tiene en cuenta que pueden haber muchos agentes disponibles que podrían atender los clientes sin esperar que llegarán a ser los primeros de la cola de espera. Con este parámetro se define otro tipo de comportamiento. Los clientes serán atendidos de manera paralela hasta que haya agentes disponibles. De esta forma se reducen considerablemente los tiempos de espera. Valor yes

monitor-type el tipo de aplicación utilizada para grabar las conversaciones de una cola. Puede ser Mixmonitor o monitor

updatecdr Actualiza o no el valor del campo dstchannel del CDR (el registro de las llamadas) con el nombre del agente. Valor no

shared_lastcall Si un agente hace parte de más de una cola y se ha definido su tiempo de descanso entre una llamada y otra (el parámetro wraptime), con este parámetro se define si ese tiempo va respetado entre las distintas colas de que el agente es miembro. Valor yes

[ventas] con esta etiqueta se define la primera cola de esperamusiclass La música de espera para los clientes en la cola. Valor

default;announce=queue-ventas Este parámetro permite crear un anuncio para que los

agentes que pertenecen a más de una cola sepan, antes de atender una llamada, de que cola proviene el cliente. Se deja comentado

283

Page 295: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónstrategy En este parámetro se define la lógica con que se

enrutarán las llamadas de una cola a los agentes:• Leastrecent: Asigna la siguiente llamada al

agente que más tiempo lleva sin atender una llamada.

• Fewestcalls: Asigna la siguiente llamada al agente que menos llamadas ha atendido.

• Random: Asigna la siguiente llamada aleatoriamente a cualquier agente disponible.

• Ringall: Llama todos los agentes disponibles a la vez hasta que uno conteste.

• RRMemory: Distribuye las llamadas “por turnos” entre los agentes disponibles y “recuerda” el último agente al que intentó llamar.

• Linear: Llama los agentes siguiendo el orden definido en este archivo de configuración. Si son agentes dinámicos según el orden con que se han registrado a la cola

• Wrandom: asigna la llamada aleatoriamente usando una métrica basada en penalidades.

servicelevel Parámetro utilizado para la estadísticas de la cola. En base al numero de segundos configurados en este parámetro, en los reportes aparecerá el numero de llamadas contestadas dentro del tiempo definido. Valor 120

context Si el cliente en la cola antes de ser atendido presiona una tecla del teléfono será enviado al contexto definido en este parámetro y a la prioridad correspondiente al dígito que ha marcado. Valor ventas-exit

timeout En la cola se pueden configurar dos distintos tipos de tiempos de espera. Uno a nivel de aplicación (dialplan) define el tiempo máximo que un cliente podrá quedar en la cola. Pasado ese tiempo sin ser atendido, el cliente saldrá de la cola y se ejecutara la siguiente prioridad presente en el dialplan. El segundo es el tiempo máximo que timbrará la extensión de un agente antes de considerarlo no disponible y pasar al siguiente. Este parámetro y los siguientes dos se utilizan para definir que tipo de tiempo de espera tendrá prioridad. Este primer parámetro define por cuantos segundos timbrará la extensión del agente. Valor: 15

retry numero de segundos de espera antes de llamar otro

284

Page 296: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónagente si el primero no ha contestado dentro de los 15 segundos definidos en el parámetro anterior. Valor: 4

timeoutpriority En este parámetro se define si se toma en consideración el tiempo de espera definido a nivel de aplicación o a nivel de archivo de configuración. Valor app (aplicación)

weight El peso de la cola. Más alto el valor, más prioridad tendrá la cola. Si hay agentes que atienden más de una cola, las colas con peso más alto serán atendidas con prioridad respecto a las colas con peso más bajo. Valor 0

wrapuptime Tiempo de descanso de un agente entre una llamada y otra (en segundos) Valor 15

autofill El mismo parámetro de la parte general del archivo se puede configurar por cada cola separadamente. Valor yes

autopause yes = lo agentes que no atenderán una llamada serán puestos en pausa

maxlen Numero máximo de personas que pueden estar esperando en la cola. Valor 50 Si se pone 0 no se fijará ningún limite

setinterfacevar yes = una serie de variables serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues.conf)

setqueueentryvar yes = otra serie de variables serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues.conf)

setqueuevar yes = otra serie de variables relacionadas con la cola serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues.conf)

;membermacro=macro Antes de conectar el agente con el cliente se puede ejecutar la macro indicada en este parámetro. Se deja comentado

announce-frequency Cada cuanto segundos anunciar al cliente en la cola su posición y tiempo estimado de espera. Valor 90

min-announce-frequency Para evitar que cada vez que la posición y/o el tiempo estimado de espera de un cliente cambie se le presente un anuncio, este parámetro define un tiempo (en segundos) que se esperará antes de comunicarle su

285

Page 297: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónnueva posición/tiempo estimado. Valor 15

;periodic-announce-frequency=60 Cada cuantos segundos presentar un anuncio personalizado al cliente en la cola de espera. Se deja comentado

;random-periodic-announce=no Los anuncios pueden ser presentados según un orden aleatorio? Se deja comentado

announce-holdtime anunciar junto a la posición en la cola el tiempo estimado de espera. Puede ser yes, no, u once (una sola vez)

announce-position Anuncia al cliente su posición en la cola. Valores:• yes – si• no – no se le anuncia• more - si la posición del cliente en la cola de

espera es más alta del numero especificado en el próximo parámetro, se le anunciará que hay más de “valor del próximo parámetro” clientes esperando en la cola

• limit – solo los clientes con una posición en la cola de espera menor o igual al valor del parámetro que sigue, escucharán el anuncio de su posición en la cola de espera

announce-position-limit 5announce-round-seconds Con este parámetro se redondea los minutos y los

segundos de espera anunciados al cliente. Valor 20;queue-youarenext=queue-youarenext A partir de esta linea se pueden personalizar las

locuciones predefinidas de la cola de espera. ;queue-thereare=queue-thereare;queue-callswaiting=queue-callswaiting;queue-holdtime=queue-holdtime;queue-minute=queue-minute;queue-minutes=queue-minutes;queue-seconds=queue-seconds;queue-thankyou=queue-thankyou;queue-reporthold=queue-reporthold;periodic-announce=queue-periodic-announce;periodic-announce=anuncio1,anuncio2 en este parámetro se definen los anuncios periódicos

personalizados separados por una coma. Se deja

286

Page 298: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripcióncomentado

;monitor-format=gsm|wav|wav49 formatos audio en que se grabarán las conversaciones de la cola de espera (si se deja comentado, no se grabaran)

monitor-type Se define la aplicación para grabar la conversaciones. Puede ser monitor y mixmonitor

joinempty Este parámetro con el que sigue, son los más importantes en la configuración de la cola. Aquí se define si un cliente puede o no entrar a una cola de espera si no hay agentes disponibles. Los distintos valores que se pueden utilizar, separados por una coma, son:

• paused – un agente es considerado no disponible si está en pausa

• penalty – un agente es considerado no disponible si el valor de su penalidad es menor al valor asociado a la variable QUEUE_MAX_PENALTY

• inuse – un agente es considerado no disponible si el estado de su extensión es INUSE

• ringing – un agente es considerado no disponible si su extensión está timbrando

• unavailable - un agente es considerado no disponible si el estado de su extensión es UNAVAILABLE

• invalid - un agente es considerado no disponible si el estado de su extensión es INVALID

• unknown – un agente es considerado no disponible si el estado de su extensión es UNKNOWN

• wrapup - un agente es considerado no disponible si está en su tiempo de descanso (wraptime) después de haber atendido una llamada

Valor: paused,unavailable,invalid,unknownleavewhenempty este parámetro aplica a los clientes que ya están en la

cola de espera y en base a los valores indicados, si todos los agentes se vuelven no disponibles, el cliente será sacado de la cola. Valor paused,unavailable,invalid,unknown

287

Page 299: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción;eventwhencalled = yes;eventmemberstatus = yes

Estos dos parámetros configurados en yes, generan una serie de eventos relacionados con la cola en el AMI de Asterisk

reportholdtime yes = Se anuncia al agente, antes de contestar la llamada, cuanto tiempo el cliente ha esperado en la cola

ringinuse no = no se envían las llamadas a agentes cuyo estado de la extensión es INUSE

memberdelay tiempo en segundos que el sistema esperará antes de conectar el agente con el cliente. De esta forma aunque hayan agentes disponibles, el cliente esperará ese tiempo antes de ser conectado con un agente. Valor 5

timeoutrestart yes = el tiempo de espera para que un agente conteste una llamada se resetea si el estado de la extensión es BUSY o CONGESTION

;defaultrule=myrule en el archivo queuerules.conf se configuran distintos escenarios para manejar las colas con el sistema de penalidades. En el caso que se haya configurado un escenario para esta cola, en este parámetro se define el nombre. Se deja comentado

member => Agent/2000member => Agent/2001member => Agent/2002

a partir de esta linea se definen los miembros de la cola. La sintaxis es:member => tecnología/extensión,penalidad,nombre,extensiónSe ponen los tres agentes configurados en el archivo agent.conf

Ahora se guardan los valores de la tabla en el archivo de configuración de las colas. Se renombra el predefinido:

mv /etc/asterisk/queues.conf /etc/asterisk/queues.conf.old

Se crea uno nuevo:

nano /etc/asterisk/queues.conf

se añaden las siguientes lineas:

[general]persistentmembers=yesautofill=yesmonitor-type=mixmonitorupdatecdr=no

288

Page 300: Libro Asterisk 1.8.X - Versión 1.0 (1)

shared_lastcall=yes

[ventas]musicclass=default;announce=queue-ventasstrategy=ringallservicelevel=120context=ventas-exittimeout=15retry=4timeoutpriority=appweight=0wrapuptime=15autofill=yesautopause=yesmaxlen=50setinterfacevar=yessetqueueentryvar=yessetqueuevar=yes;membermacro=macroannounce-frequency=90min-announce-frequency=15;periodic-announce-frequency=60;random-periodic-announce=noannounce-holdtime=onceannounce-position=moreannounce-position-limit=5announce-round-seconds=30;queue-youarenext=queue-youarenext;queue-thereare=queue-thereare;queue-callswaiting=queue-callswaiting;queue-holdtime=queue-holdtime;queue-minute=queue-minute;queue-minutes=queue-minutes;queue-seconds=queue-seconds;queue-thankyou=queue-thankyou;queue-reporthold=queue-reporthold;periodic-announce=anuncio1,anuncio2;monitor-format=gsm|wav|wav49monitor-type=mixmonitorjoinempty=paused,unavailable,invalid,unknownleavewhenempty=paused,unavailable,invalid,unknown;eventwhencalled = yes;eventmemberstatus = yesreportholdtime=yesringinuse=nomemberdelay=5

289

Page 301: Libro Asterisk 1.8.X - Versión 1.0 (1)

timeoutrestart=yes;defaultrule=myrulemember => Agent/2000member => Agent/2001member => Agent/2002

Se guardan los cambios y se recarga el modulo de la aplicación de las colas en espera:

asterisk -rvvvvvvvvvvvvvvvvvvvvv

CLI> module reload app_queue.so

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers

Con queue show ventas se muestran los datos de las colas. Los comandos asociados a la aplicación queue:

CLI> help queuequeue add member Add a channel to a specified queuequeue reload {parameters|membe Reload queues, members, queue rules, or parameters queue remove member Removes a channel from a specified queue queue reset stats Reset statistics for a queue queue set penalty Set penalty for a channel of a specified queue queue show Show status of a specified queue queue {pause|unpause} member Pause or unpause a queue member queue show rules Show the rules defined in queuerules.conf

CLI> quit

Se sale de la consola y se pasa al dialplan:

nano /etc/asterisk/extensions.conf

en el contexto internas se ponen las siguientes lineas

exten => 3000,1,Answersame => n,Queue(ventas,R)same => n,Hangup

Con la opción R, introducida con la versión 1.8.X de Asterisk, cuando la llamada es enviada a un

290

Page 302: Libro Asterisk 1.8.X - Versión 1.0 (1)

agente, dejará de enviar la musca de espera al cliente y en su lugar el cliente escuchará el tono de timbrado.

Se guardan los cambios y se recarga el dialplan:

asterisk -rx "dialplan reload"

Desde la extensión 1000 conectada a Asterisk, se marca la extensión 3000. Como no hay agentes disponibles la llamada terminará.

Ahora desde la extensión 1000 se marca el numero 2000 (para conectarse como agente a las colas de espera). Una vez conectado se entra a la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvv

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Not in use) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers

El agente 2000 está disponible. Desde la extensión 1001 se marca el numero 3000. Cuando el agente (la extensión 1000) reciba la llamada del cliente (la extensión 1001), el estado de la cola de espera será:

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Busy) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers

y al terminar la llamada:

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 28s talktime), W:0, C:1, A:0, SL:100.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Not in use) has taken 1 calls (last was 27 secs ago) Agent/2001 (Unavailable) has taken no calls yet No Callers

291

Page 303: Libro Asterisk 1.8.X - Versión 1.0 (1)

Como se ha visto, si no hay agentes disponibles no se deja entrar el cliente a la cola. Como se ha dicho el llamante se envía a la prioridad que sigue. Se puede crear otro escenario de este tipo:

nano /etc/asterisk/extensions.conf

en el contexto internas se pone

exten => 3001,1,Answersame => n,Queue(ventas)same => n,Voicemail(1000@default)same => n,Hangup

De esta forma el llamante tendrá la oportunidad de dejar un mensaje en el buzón de voz. Se guardan los cambios y se recarga el dialplan.

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca el 3001 (sin agentes conectados).

Executing [3001@externas:1] Answer("SIP/1000-00000017", "") in new stackExecuting [3001@externas:2] Queue("SIP/1000-00000017", "ventas") in new stack[Oct 21 16:58:49] WARNING[15270]: app_queue.c:5160 queue_exec: Unable to join queue 'ventas'Executing [3001@externas:3] VoiceMail("SIP/1000-00000017", "1000@default") in new stack

Como no hay agentes disponibles, la llamada será enviada al buzón de voz.

16.3 Agentes dinámicos

En Asterisk hay dos aplicaciones para añadir y quitar un miembro de una cola. Estas dos aplicaciones son:

• AddQueueMember• RemoveQueueMember

¿Cual es la diferencia con la aplicación Agentlogin?

La aplicación Agentlogin es pensada para call center de grandes dimensiones. En el caso de una pequeña empresa que quiera tener un pequeño call center y no quiera que los empleados estén todo el tiempo conectados como agentes sino que puedan desarrollar su normal actividad y al mismo tiempo atender las llamadas de la cola, la aplicación addQueueMember es mucho más funcional.

En el plan de llamadas, contexto internas, se añaden estos dos bloques:

292

Page 304: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/extensions.conf

exten => *70,1,Addqueuemember(ventas,SIP/${CALLERID(num)})same => n,Playback(agent-loginok)same => n,Hangup

exten => *71,1,Removequeuemember(ventas,SIP/${CALLERID(num)})same => n,Playback(agent-loggedoff)same => n,Hangup

Con el primer bloque las extensiones se añaden a la cola ventas, con el segundo se quitan.

Hay dos aplicaciones más que permiten a los agentes dinámicos ponerse en pausa y no atender las llamadas para luego, después del “descanso” volver a atender la cola. Hay que acordarse que cuando un agente se pone en pausa, por como se ha configurado la cola, el agente será considerado como no disponible. Estas dos aplicaciones se pueden añadir al plan de llamadas de la siguiente forma:

exten => *72,1,PauseQueueMember(ventas,SIP/${CALLERID(num)})same => n,Playback(beep)same => n,Hangup

exten => *73,1,UnpauseQueueMember(ventas,SIP/${CALLERID(num)})same => n,Playback(beep)same => n,Hangup

Todos los datos de las conexiones de los agentes dinámicos se guardan en la base de datos interna de Asterisk.

Se guardan los cambios y se recarga el plan de llamadas:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se llama el numero *70 y se mira lo que aparece en la base de datos de Asterisk:

CLI> database show/Queue/PersistentMembers/ventas : SIP/1000;0;0;SIP/1000;SIP/1000

CLI> quit

Como en el archivos de las colas de espera se ha configurado el parámetro persistentmembers=yes, si se reinicia Asterisk, los datos del agente deben permanecer en la base de datos.

service asterisk restart

293

Page 305: Libro Asterisk 1.8.X - Versión 1.0 (1)

asterisk -rvvvvvvvvvvvvvvvvvvvvvvv

CLI> database show/Queue/PersistentMembers/ventas : SIP/1000;0;0;SIP/1000;SIP/1000

El agente no se ha borrado de la cola de espera. Para probarlo desde la extensión 1001 se marca el numero 3001.

Como el agente dinámico quiere almorzar, se pone en pausa marcando el numero *72

Si se mira el estado de la cola:

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (2s holdtime, 2s talktime), W:0, C:1, A:0, SL:100.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (paused) (Not in use) has taken no calls yet No Callers

Se podrá comprobar que efectivamente el agente dinámico está en pausa. Para volver activo desde la extensión 1000 se marca el numero *73. El resultado:

CLI> queue show ventasventas has 0 calls (max 50) in 'ringall' strategy (2s holdtime, 2s talktime), W:0, C:1, A:0, SL:100.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (Not in use) has taken no calls yet No Callers

Terminada la prueba se quita la extensión 1000 de la cola de espera llamando desde esa extensión el numero: *71

Se averigua en la base de datos de Asterisk que efectivamente el agente ya no está registrado:

CLI> database show

Ya no aparece la linea:

/Queue/PersistentMembers/ventas : SIP/1000;0;0;SIP/1000;SIP/1000

294

Page 306: Libro Asterisk 1.8.X - Versión 1.0 (1)

16.4 Estadísticas de las colas

Por defecto todas las estadísticas de las colas se guardan en el archivo predefinido queue_log presente en la carpeta /var/log/asterisk. La mayoría de los programas que permiten obtener gráficos de estas estadísticas, leen ese archivo. Entre ellos, se pueden citar los dos más reconocidos (el primero con una versión Lite gratuita disponible y el segundo comercial)

• Asternic Call Center Stats• QueueMetrics

¿Cómo se interpretan los datos presentes en este archivo?

Cada linea del archivo puede contener hasta 10 campos distintos separados por un pipe | Estos son:

• fecha y hora en formado EPOCH• identificador único de la llamada• nombre de la cola• nombre del agente• evento que se ha presentado• campos de datos (hasta 5) que contienen los valores devueltos por los eventos de la cola.

En el caso que el evento no incluya todos los campos, en lugar de los datos aparecerá el valor NONE.

Los eventos que se pueden presentar son:

• ABANDON: cuando un cliente abandona la cola sin ser atendido. Junto al evento aparecerá el nombre de la cola, la posición que tenía el cliente cuando abandonó la cola, la posición que tenía al momento de entrar en la cola y el tiempo que esperó antes de colgar.

• ADDMEMBER: cuando se añade un agente dinámico a la cola. Junto al evento aparecerá la variable UNIQUEID de la llamada, el nombre de la cola a la que se registró el agente y la extensión con la que se registró.

Ejemplo: 1323691008|1323691008.7|ventas|SIP/1000|ADDMEMBER|

• AGENTDUMP: el agente ha rechazado la llamada mientra el cliente estaba escuchando el anuncio de la cola

• AGENTLOGIN: cuando un agente se conecta utilizando la aplicación Agentlogin. Junto al evento aparecerá la variable UNIQUEID de la llamada, El numero del agente y el canal utilizado para el registro.

Ejemplo: 1323689794|1323689785.3|NONE|Agent/2000|AGENTLOGIN|SIP/1000-00000003

• AGENTLOGOFF: cuando un agente se desconecta. Junto al evento aparecerá la variable

295

Page 307: Libro Asterisk 1.8.X - Versión 1.0 (1)

UNIQUEID de la llamada, el numero del agente, el canal utilizado cuando se registró y el tiempo en segundos que ha quedado conectado.

Ejemplo: 1323689825|1323689785.3|NONE|Agent/2000|AGENTLOGOFF|SIP/1000-00000003|31

• COMPLETEAGENT: cuando un agente que ha atendido una llamada cuelga. Junto al evento aparecerá la variable UNIQUEID, el nombre de cola, la extensión del agente, el tiempo que esperó el cliente antes de ser atendido, la duración de la llamada y la posición que tenía el cliente al entrar en la cola.

Ejemplo: 1323690712|1323690653.4|ventas|Agent/2000|COMPLETEAGENT|9|50|1

• COMPLETECALLER: cuando un cliente atendido por un agente cuelga la llamada. Junto al evento aparecerá , la variable UNIQUEID, el nombre de la cola, la extensión del agente, el tiempo que esperó el cliente antes de ser atendido, la duración de la llamada y la posición inicial que tenía el cliente al entrar en la cola.

Ejemplo: 1323695800|1323694274.2|ventas|SIP/1000|COMPLETECALLER|16|27|1

• CONFIGRELOAD: cuando se recarga la configuración de Asterisk.

Ejemplo: 1323531449|NONE|NONE|NONE|CONFIGRELOAD|

• CONNECT: cuando un cliente es atendido por un agente. Junto al evento aparecerá, el UNIQUEID de la llamada del cliente, el nombre de la cola, la extensión del agente que ha atendido el cliente, el tiempo que ha esperado el cliente antes de ser atendido, el UNIQUEID de la llamada entre cliente y agente, y el tiempo que timbró la extensión del agente.

Ejemplo: 1323690662|1323690653.4|ventas|Agent/2000|CONNECT|9|1323690653.5|0

• ENTERQUEUE: cuando un cliente entra en la cola. Junto al evento aparecerá, el UNIQUEID de la llamada, el nombre de la cola, la URLsi aplica y el CALLERID del cliente.

Ejemplo: 1323690653|1323690653.4|ventas|NONE|ENTERQUEUE||1001

• EXITEMPTY: cuando un cliente viene desconectado de la cola porque no hay agentes disponibles. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola, posición inicial y final del cliente en la cola, y el tiempo que ha esperado en la cola antes de ser desconectado.

Ejemplo: 1323710320|1323710281.17|ventas|NONE|EXITEMPTY|1|1|38

• EXITWITHKEY: el cliente mientras esperaba en la cola ha presionado una tecla. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola, el numero de la tecla presionada (en este caso 8), y la posición del cliente en la cola antes de presionar la tecla.

296

Page 308: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ejemplo: 1323710850|1323710844.23|ventas|NONE|EXITWITHKEY|8|1

• EXITWITHTIMEOUT: el cliente ha sido desconectado de la cola porque después del tiempo máximo permitido de espera, ningún agente lo ha atendido. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola, la posición final y inicial del cliente en la cola, y el tiempo que éste ha esperado antes de ser desconectado

• PAUSE: cuando un agente se pone en pausa utilizando la aplicación PauseQueueMember de Asterisk. Junto al evento aparecerá el nombre de la cola y la extensión del agente. Si el agente ha sido desconectado de la cola porque no ha atendido una llamada antes del tiempo configurado, aparecerá también el valor Auto-Pause

Ejemplo1: 1323712960|NONE|ventas|SIP/1000|PAUSE|Ejemplo2: 1323710541|NONE|ventas|SIP/1000|PAUSE|Auto-Pause

• QUEUESTART: cuando Asterisk ha sido reiniciado

Ejemplo: 1323447241|NONE|NONE|NONE|QUEUESTART|

• REMOVEMEMBER: cuando una agente se desconecta de la cola con la aplicación Removequeuemember. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola y la extensión del agente.

• RINGNOANSWER: cuando la extensión de un agente timbra y al agente no contesta dentro del tiempo configurado. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola, la extensión del agente que no ha contestado la llamada y el tiempo (en milisegundos) que ha timbrado la extensión del agente:

Ejemplo: 1323711528|1323711480.31|ventas|SIP/1000|RINGNOANSWER|45000

• SYSCOMPAT: la llamada ha sido contestada por un agente pero ha terminado porque los dos canales (cliente y agente) no eran compatibles.

• TRANSFER: cuando el cliente, atendido por un agente, ha sido transferido a otra extensión. Junto al evento aparecerá el UNIQUEID de la llamada, el nombre de la cola, la extensión del agente que ha atendido la llamada, el numero de la extensión donde ha sido transferida la llamada, el contexto utilizado para la transferencia, el tiempo que ha esperado el cliente en la cola, el tiempo de duración de la llamada entes de la transferencia y la posición del cliente al entrar en la cola.

Ejemplo: 1323712663|1323712627.34|ventas|SIP/1000|TRANSFER|1002|externas|12|24|1

• UNPAUSE: cuando un agente vuelve a conectarse a la cola utilizando la aplicación UnpauseQueueMember. Junto al evento aparecerá el nombre de la cola y la extensión del agente.

297

Page 309: Libro Asterisk 1.8.X - Versión 1.0 (1)

16.5 Colas, agentes y estadísticas en Realtime dinámico

Como para las extensiones, las conferencias, los buzones de voz, también para las colas es posible trabajar en Realtime. En este caso se puede guardar en Realtime:

• la configuración de las colas• los agentes• las estadísticas de la cola

Como queda claro por lo arriba mencionado, hay que crear tres tablas distintas, una para cada tipo de objectos que se guardarán. Se inicia con la configuración de las colas. En esta tabla se pueden configurar todos los valores presentes para la definición de la cola, aunque el único obligatorio es el nombre de la cola misma.

se entra en MySQL

mysql -u root -psesamo

se escoge la base de datos asterisk:

mysql> use asterisk

se crea la tabla para las colas:

mysql> CREATE TABLE `queue_table` (`name` varchar(128) NOT NULL,`musiconhold` varchar(128) default NULL,`announce` varchar(128) default NULL,`context` varchar(128) default NULL,`strategy` varchar(128) default NULL,`servicelevel` int(11) default NULL,`penaltymemberslimit` int(11) default NULL,`timeout` int(11) default NULL,`retry` int(11) default NULL,`timeoutpriority` varchar(128) default NULL,`weight` int(11) default NULL,`wrapuptime` int(11) default NULL,`autofill` varchar(128) default NULL,`autopause` varchar(128) default NULL,`maxlen` int(11) default NULL,`setinterfacevar` varchar(3) default NULL,`setqueueentryvar` varchar(3) default NULL,`setqueuevar` varchar(3) default NULL,`membermacro` varchar(128) default NULL,`announce-frequency` int(11) default NULL,

298

Page 310: Libro Asterisk 1.8.X - Versión 1.0 (1)

`min-announce-frequency` int(11) default NULL,`periodic-announce-frequency` int(11) default NULL,`random-periodic-announce` varchar(3) default NULL,`relative-periodic-announce` varchar(3) default NULL,`announce-holdtime` varchar(4) default NULL,`announce-position` varchar(3) default NULL,`announce-position-limit` int(11) default NULL,`announce-round-seconds` int(11) default NULL,`queue-youarenext` varchar(128) default NULL,`queue-thereare` varchar(128) default NULL,`queue-callswaiting` varchar(128) default NULL,`queue-holdtime` varchar(128) default NULL,`queue-minute` varchar(128) default NULL,`queue-minutes` varchar(128) default NULL,`queue-seconds` varchar(128) default NULL,`queue-thankyou` varchar(128) default NULL,`queue-reporthold` varchar(128) default NULL,`periodic-announce` varchar(512) default NULL,`monitor-format` varchar(128) default NULL,`monitor-type` varchar(128) default NULL,`joinempty` varchar(128) default NULL,`leavewhenempty` varchar(128) default NULL,`eventwhencalled` varchar(128) default NULL,`eventmemberstatus` varchar(128) default NULL,`reportholdtime` varchar(128) default NULL,`ringinuse` varchar(3) default NULL,`memberdelay` int(11) default NULL,`timeoutrestart` varchar(128) default NULL,`defaultrule` varchar(128) default NULL,PRIMARY KEY (`name`));

Se crea la tabla para los agentes de las colas:

mysql> CREATE TABLE queue_member_table (uniqueid INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT,membername varchar(40),queue_name varchar(128),interface varchar(128),penalty INT(11),paused INT(11),UNIQUE KEY queue_interface (queue_name, interface));

y por ultimo se crea la tabla para guardar las estadísticas de las colas:

mysql> CREATE TABLE queue_log (

299

Page 311: Libro Asterisk 1.8.X - Versión 1.0 (1)

time datetime,callid char(50),queuename char(50),agent char(50),event char(20),data1 char(50),data2 char(50),data3 char(50),data4 char(50),data5 char(50),index bydate (time),index qname (queuename,time));

Se sale de MySQL y se modifica el archivo del realtime:

mysql> quit

nano /etc/asterisk/extconfig.conf

se modifican estas tres lineas:

;queues => odbc,asterisk;queue_members => odbc,asterisk;queue_log => mysql,genera

para que queden:

queues => odbc,asterisk,queue_tablequeue_members => odbc,asterisk,queue_member_tablequeue_log => odbc,asterisk,queue_log

Se guardan los cambios y se reinicia Asterisk:

service asterisk restart

Ahora para probar el log de las colas en realtime, desde la extensión 1000 se marca *70 para conectarse a la cola ventas como agente dinámico y luego desde las demás extensiones se marca el 3001. El resultado en la base de datos:

mysql -u root -psesamo

mysql> use asterisk

mysql> select time,queuename,agent,event,data1,data2,data3 from queue_log;

El resultado:

300

Page 312: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se sale del cliente MySQL:

mysql> quit

Como segunda prueba se crea otra cola en realtime. Desde Webmin se entra a la tabla queue_table y se rellenan los campos:

301

Page 313: Libro Asterisk 1.8.X - Versión 1.0 (1)

302

Page 314: Libro Asterisk 1.8.X - Versión 1.0 (1)

303

Page 315: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guarda la configuración presionando el botón “Save”. Se vuelve a la consola de Asterisk donde aparecerá la nueva cola:

CLI> queue show comprascompras has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:1, C:0, A:0, SL:0.0% within 120s No Members No Callers

que todavía no tienes agentes configurados. Desde el Webmin se pasa a la tabla queue_member_table y se añaden dos agentes a la cola creada:

304

Page 316: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se vuelve nuevamente a la consola de Asterisk:

CLI> queue show comprascompras has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:1, C:0, A:0, SL:0.0% within 120s Members: Fulamo (Agent/2000) (realtime) (Unavailable) has taken no calls yet Sutano (Agent/2001) (realtime) (Unavailable) has taken no calls yet No Callers

Para terminar si desde la extensión 1000 se marca 2000 para conectarse como agente 2000. Una vez conectado en la consola de Asterisk:

CLI> queue showcompras has 0 calls (max 50) in 'ringall' strategy (0s holdtime, 0s talktime), W:1, C:0, A:0, SL:0.0% within 120s Members: Fulamo (Agent/2000) (realtime) (Not in use) has taken no calls yet Sutano (Agent/2001) (realtime) (Unavailable) has taken no calls yet No Callers

ventas has 0 calls (max 50) in 'ringall' strategy (14s holdtime, 10s talktime), W:0, C:4, A:1, SL:100.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet

305

Page 317: Libro Asterisk 1.8.X - Versión 1.0 (1)

Agent/2000 (Not in use) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (In use) has taken 4 calls (last was 9443 secs ago) No Callers

El agente estará conectado a las dos colas creadas (en negrita).

306

Page 318: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 319: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XVII

Asterisk y los FAX

Hasta la versión 1.6.2.X, Asterisk soportaba la recepción y trasmisión de FAX a través del modulo app_fax. A partir de la versión 1.8.X hay dos nuevos módulos:

• res_fax• res_fax_spandsp

La idea detrás de este cambio es mejorar el soporte del protocolo T38 en Asterisk. Estos dos módulos se apoyan en las librerías SpanDSP y permiten la recepción y envío de FAX a través de dos protocolos: T30 (audio) y T38 (FoIP – Fax over IP). En este capitulo se presentará primero una solución basada en la combinación del programa IAXmodem con el servidor de FAX Hylafax, para luego abordar el tema del protocolo T38.

17.1 IAXmodem

IAXmodem es un módem software, escrito en lenguaje C que utiliza un canal IAX2 en lugar de una línea telefónica y un DSP software (SpanDSP) en lugar de un chip DSP (Digital Signal Processing). Se descargan las fuentes de IAXmodem:

cd /usr/src

wget http://switch.dl.sourceforge.net/sourceforge/iaxmodem/iaxmodem-1.2.0.tar.gz

Se descomprime el archivo

tar -xf iaxmodem-1.2.0.tar.gz

Se entra en la carpeta:

cd iaxmodem-1.2.0

Se compila:

./configure

make

Se copia el programa compilado en la siguiente carpeta:

cp iaxmodem /usr/local/sbin

Como se van a crear dos módem IAX2, se crean algunas carpetas y archivos para el correcto funcionamiento de IAXmodem:

Page 320: Libro Asterisk 1.8.X - Versión 1.0 (1)

mkdir /etc/iaxmodem

mkdir /var/log/iaxmodem

touch /var/log/iaxmodem/ttyIAX1

touch /var/log/iaxmodem/ttyIAX2

touch /var/log/iaxmodem/iaxmodem

En la carpeta de las fuentes de IAXmodem hay un archivo de configuración predefinido para la creación de un módem IAX. Se puede tomar como referencia para la creación de los dos módem IAX que se utilizarán para la recepción y envío de FAX con Asterisk. Se configura el primero

cd /etc/iaxmodem

nano ttyIAX1

La lineas son:

device /dev/ttyIAX1owner uucp:uucpmode 660port 4570refresh 60server 127.0.0.1peername iaxmodem1secret pbx5050cidname VozToVoicecidnumber XXXXXXXXXXcodec alaw

Se guardan los cambios. Esta configuración es valida si IAXmodem está instalado en el mismo servidor donde se instaló Asterisk. En el caso de dos servidores distintos hay que indicar en la línea server la dirección IP del servidor Asterisk. Se pone la contraseña en secret y en cidname y cidnumber nombre y numero telefónico que usará IAXmodem para presentarse a Asterisk. Para configurar distintos IAXmodem hay que modificar en la primera línea el nombre del device, en port el puerto y en peername el nombre de la troncal.

IMPORTANTE: en la linea codec hay que indicar un codec audio que no utilice algoritmos de compresión. Esto porque el protocolo T30 funciona solamente con canales audio no comprimidos.

Para el segundo IAXmodem la configuración será:

nano ttyIAX2

309

Page 321: Libro Asterisk 1.8.X - Versión 1.0 (1)

device /dev/ttyIAX2owner uucp:uucpmode 660port 4571refresh 60server 127.0.0.1peername iaxmodem2secret pbx5051cidname VozToVoicecidnumber XXXXXXXXXXcodec alaw

Se guardan los cambios.

Ahora hay que modificar la configuración de Asterisk para añadir las dos extensiones IAX (iaxmodem1 y iaxmodem2) en el archivo iax.conf

nano /etc/asterisk/iax.conf

Al final del archivo se añaden los dos bloques que siguen:

[iaxmodem1]type=friendcontext=faxdisallow=allallow=alawusername=iaxmodem1secret=pbx5050qualify=yesnotransfer=yeshost=dynamicrequirecalltoken=auto

[iaxmodem2]type=friendcontext=faxdisallow=allallow=alawusername=iaxmodem2secret=pbx5051qualify=yesnotransfer=yeshost=dynamicrequirecalltoken=auto

Se guardan los cambios y se actualiza la configuración de IAX2 en Asterisk

310

Page 322: Libro Asterisk 1.8.X - Versión 1.0 (1)

asterisk -rvvvvvvvvvvvvvvvvvvv

CLI> iax2 reload

Se abre otra ventana terminal o se crea otra sesión de PuTTy y se hace una prueba para ver si la conexión entre IAXmodem y Asterisk funciona:

cd /usr/local/sbin

./iaxmodem ttyIAX1

debe aparecer:

[2011-10-24 09:44:37] Modem started[2011-10-24 09:44:37] Setting device = '/dev/ttyIAX1'[2011-10-24 09:44:37] Setting owner = 'uucp:uucp'[2011-10-24 09:44:37] Setting mode = '660'[2011-10-24 09:44:37] Setting port = 4570[2011-10-24 09:44:37] Setting refresh = 60[2011-10-24 09:44:37] Setting server = '127.0.0.1'[2011-10-24 09:44:37] Setting peername = 'iaxmodem1'[2011-10-24 09:44:37] Setting secret = 'pbx5050'[2011-10-24 09:44:37] Setting cidname = 'VozToVoice'[2011-10-24 09:44:37] Setting cidnumber = 'XXXXXXXX'[2011-10-24 09:44:37] Setting codec = ulaw[2011-10-24 09:44:37] Opened pty, slave device: /dev/pts/4[2011-10-24 09:44:37] Created /dev/ttyIAX1 symbolic linkIgnoring unknown information element 'Unknown IE' (54) of length 0[2011-10-24 09:44:37] Registration completed successfully.

Se controla que en la consola de Asterisk aparezca la conexión de IAXmodem (volviendo a la otra ventana Terminal abierta):

Para iniciar IAXmodem en automático se instala el script presente en la carpeta de las fuentes de IAXmodem:

cd /usr/src/iaxmodem-1.2.0

mv iaxmodem.init.fedora /etc/init.d/iaxmodem

se vuelve ejecutable:

chmod +x /etc/init.d/iaxmodem

311

Page 323: Libro Asterisk 1.8.X - Versión 1.0 (1)

e se configura para el inicio automático:

chkconfig --add iaxmodem

chkconfig iaxmodem on

Se inicia el programa:

/etc/init.d/iaxmodem start

Volviendo a la consola de Asterisk, las dos extensiones deben estar registradas:

CLI> iax2 show peersName/Username Host Mask Port Statusmarko (Unspecified) (D) 255.255.255.255 0 (E) UNKNOWNmarko2/marko2 190.253.162.206 (D) 255.255.255.255 13269 (E) OK (102 ms)iaxmodem1/iaxmo 127.0.0.1 (D) 255.255.255.255 4570 (E) OK (1 ms)iaxmodem2/iaxmo 127.0.0.1 (D) 255.255.255.255 4571 (E) OK (3 ms)4 iax2 peers [3 online, 1 offline, 0 unmonitored]

Ahora que IAXmodem ha sido instalado y configurado, se puede continuar con la instalación y configuración de Hylafax.

17.2 Hylafax

Hylafax es un servidor FAX diseñado para sistemas Linux que se basa en un sistema cliente-servidor. Un cliente (FAX) se conecta al servidor (Hylafax) y a través de el envía el FAX

Hay que empezar instalando algunas (dependencias) requeridas por Hylafax:

yum install ghostscript ghostscript-devel sharutils ghostscript-fonts

En la pagina de Hylafax están presentes los paquetes para las distintas distribuciones de Linux:

Se descargan los paquetes para CentOS 5 (cliente y servidor):

cd /usr/src

wget ftp://ftp.hylafax.org/binary/linux/redhat/6.0.5/hylafax-server-6.0.5-1rhel5.i386.rpm

wget ftp://ftp.hylafax.org/binary/linux/redhat/6.0.5/hylafax-client-6.0.5-1rhel5.i386.rpm

Se instalan:

rpm -ivh hylafax*.rpm

312

Page 324: Libro Asterisk 1.8.X - Versión 1.0 (1)

El paso a seguir es la configuración de de Hylafax. Esto se hace a través de la utilidad faxsetup:

faxsetup

Should an entry be added for the FaxMaster to /etc/aliases [yes]? no

Update /var/spool/hylafax/status/any.info.

HylaFAX configuration parameters are:

[1] Init script starts faxq: yes [2] Init script starts hfaxd yes [3] Start paging protocol: noAre these ok [yes]? yes

Se contesta yes. Luego inicia la configuración de Hylafax. Hay que indicar los parámetros como aparecen personalizando el numero de teléfono y el prefijo del país. En negrita los datos que se van insertando desde el teclado.

Modem support functions written to /var/spool/hylafax/etc/setup.modem.Configuration parameters written to /var/spool/hylafax/etc/setup.cache.

No scheduler config file exists, creating one from scratch.Country code [1]? 57Area code []? 5Long distance dialing prefix [1]? 0International dialing prefix [011]? 00Dial string rules file (relative to /var/spool/hylafax) ["etc/dialrules"]?Tracing during normal server operation [1]?Default tracing during send and receive sessions [0xffffffff]?Continuation cover page (relative to /var/spool/hylafax) []?Timeout when converting PostScript documents (secs) [180]?Maximum number of concurrent jobs to a destination [1]?Define a group of modems []?Time of day restrictions for outbound jobs ["Any"]?Timeout before purging a stale UUCP lock file (secs) [30]?Max number of pages to permit in an outbound job [0xffffffff]?Syslog facility name for ServerTracing messages [daemon]?

The non-default scheduler parameters are:

CountryCode: 57AreaCode: 5LongDistancePrefix: 0InternationalPrefix: 00

313

Page 325: Libro Asterisk 1.8.X - Versión 1.0 (1)

Are these ok [yes]? yes

Creating new configuration file /var/spool/hylafax/etc/config...

Restarting HylaFAX server processes.Should I restart the HylaFAX server processes [yes]? yes

/etc/rc.d/init.d/hylafax startStarting HylaFAX queue manager (faxq): [ OK ]Starting HylaFAX server (hfaxd): [ OK ]Restarting HylaFAX modem manager (faxgetty): [ OK ]

You do not appear to have any modems configured for use. Modems areconfigured for use with HylaFAX with the faxaddmodem(8C) command.

Desde la linea que sigue se configura el primer FAX (ttyIAX1)

Do you want to run faxaddmodem to configure a modem [yes]? yesSerial port that modem is connected to []? ttyIAX1

Ok, time to setup a configuration file for the modem. The manualpage config(5F) may be useful during this process. Also be awarethat at any time you can safely interrupt this procedure.

Reading scheduler config file /var/spool/hylafax/etc/config.

No existing configuration, let's do this from scratch.

Country code [57]?Area code [5]?Phone number of fax modem [+1.999.555.1212]? +5753850962Local identification string (for TSI/CIG) ["NothingSetup"]? CursoAsteriskLong distance dialing prefix [1]? 0International dialing prefix [011]? 00Dial string rules file (relative to /var/spool/hylafax) [etc/dialrules]?Tracing during normal server operation [1]?Tracing during send and receive sessions [11]?Protection mode for received facsimile [0600]?Protection mode for session logs [0600]?Protection mode for ttyIAX1 [0600]?Rings to wait before answering [1]? 2Modem speaker volume [off]?Command line arguments to getty program ["-h %l dx_%s"]?Pathname of TSI access control list file (relative to /var/spool/hylafax) [""]?Pathname of Caller-ID access control list file (relative to /var/spool/hylafax) [""]?

314

Page 326: Libro Asterisk 1.8.X - Versión 1.0 (1)

Tag line font file (relative to /var/spool/hylafax) [etc/lutRS18.pcf]?Tag line format string ["From %%l|%c|Page %%P of %%T"]?Time before purging a stale UUCP lock file (secs) [30]?Hold UUCP lockfile during inbound data calls [Yes]?Hold UUCP lockfile during inbound voice calls [Yes]?Percent good lines to accept during copy quality checking [95]?Max consecutive bad lines to accept during copy quality checking [5]?Max number of pages to accept in a received facsimile [25]?Syslog facility name for ServerTracing messages [daemon]?Set UID to 0 to manipulate CLOCAL [""]?Use available priority job scheduling mechanism [""]?

The non-default server configuration parameters are:

CountryCode: 57AreaCode: 5FAXNumber: +5753850962LongDistancePrefix: 0InternationalPrefix: 00DialStringRules: etc/dialrulesSessionTracing: 11RingsBeforeAnswer: 2SpeakerVolume: offGettyArgs: "-h %l dx_%s"LocalIdentifier: CursoAsteriskTagLineFont: etc/lutRS18.pcfTagLineFormat: "From %%l|%c|Page %%P of %%T"MaxRecvPages: 25

Are these ok [yes]? yes

Now we are going to probe the tty port to figure out the typeof modem that is attached. This takes a few seconds, so be patient.Note that if you do not have the modem cabled to the port, or themodem is turned off, this may hang (just go and cable up the modemor turn it on, or whatever).

Probing for best speed to talk to modem: 38400 OK.

About fax classes:

The difference between fax classes has to do with how HylaFAX interactswith the modem and the fax protocol features that are used when sendingor receiving faxes. One class isn't inherently better than another;however, one probably will suit a user's needs better than others.

315

Page 327: Libro Asterisk 1.8.X - Versión 1.0 (1)

Class 1 relies on HylaFAX to perform the bulk of the fax protocol.Class 2 relies on the modem to perform the bulk of the fax protocol.Class 2.0 is similar to Class 2 but may include more features.Class 1.0 is similar to Class 1 but may add V.34-fax capability.Class 2.1 is similar to Class 2.0 but adds V.34-fax capability.

HylaFAX generally will have more features when using Class 1/1.0 thanwhen using most modems' Class 2 or Class 2.0 implementations. Generallyany problems encountered in Class 1/1.0 can be resolved by modificationsto HylaFAX, but usually any problems encountered in Class 2/2.0/2.1 willrequire the modem manufacturer to resolve it.

Use Class 1 unless you have a good reason not to.

This modem looks to have support for Class 1.0 and 1.How should it be configured [1.0]?

Hmm, this looks like a Class 1.0 modem.Product code (ATI0) is "spandsp".Other information (ATI3) is "www.soft-switch.org".DTE-DCE flow control scheme [default]?Modem manufacturer is "Unknown".Modem model is "Unknown".

Using prototype configuration file class1.0...

There is no prototype configuration file for your modem, so we willhave to fill in the appropriate parameters by hand. You will need themanual for how to program your modem to do this task. In case you areuncertain of the meaning of a configuration parameter you shouldconsult the config(5F) manual page for an explanation.

Note that modem commands must be specified exactly as they are to besent to the modem. Note also that quote marks (") will not be displayedand will automatically be deleted. You can use this facility to supplynull parameters as "".

Finally, beware that the set of parameters is long. If you prefer touse your favorite editor instead of this script you should fill thingsin here as best you can and then edit the configuration file

"/var/spool/hylafax/etc/config.ttyIAX1"

after completing this procedure.

Command to enter Class 1 [AT+FCLASS=1.0]?

316

Page 328: Libro Asterisk 1.8.X - Versión 1.0 (1)

Command to stop and wait prior to sending PPM [AT+FTS=7]?Command to stop and wait prior to sending TCF [AT+FTS=7]?Command to stop and wait prior to sending EOP [AT+FTS=9]?Extra bytes in a received HDLC frame [4]?Maximum time to wait for OK after aborting a receive (ms) [200]?Maximum wait for initial identification frame (ms) [40000]?Command to ensure silence after receiving HDLC and before sending [AT+FRS=7]?

The modem configuration parameters are:

Class1Cmd: AT+FCLASS=1.0Class1PPMWaitCmd: AT+FTS=7Class1TCFWaitCmd: AT+FTS=7Class1EOPWaitCmd: AT+FTS=9Class1FrameOverhead: 4Class1RecvAbortOK: 200Class1RecvIdentTimer: 40000Class1SwitchingCmd: AT+FRS=7Class1TCFMaxNonZero: 10Class1TCFMinRun: 1000

Are these ok [yes]? yes

Creating new configuration file /var/spool/hylafax/etc/config......saving current file as /var/spool/hylafax/etc/config.sav.

Don't forget to run faxmodem(8C) (if you have a send-only environment)or configure init to run faxgetty on ttyIAX1.

Terminada la configuración del primer módem, el servidor Hyalafax preguntará si se quiere instalar otro. Se contesta con yes y se configura el segundo módem (ttyIAX2)

Do you want to run faxaddmodem to configure another modem [yes]? yesSerial port that modem is connected to []? ttyIAX2

Ok, time to setup a configuration file for the modem. The manualpage config(5F) may be useful during this process. Also be awarethat at any time you can safely interrupt this procedure.

Reading scheduler config file /var/spool/hylafax/etc/config.

No existing configuration, let's do this from scratch.

Country code [57]?Area code [5]?Phone number of fax modem [+1.999.555.1212]? +5753850962

317

Page 329: Libro Asterisk 1.8.X - Versión 1.0 (1)

Local identification string (for TSI/CIG) ["NothingSetup"]? CursoAsteriskLong distance dialing prefix [1]? 0International dialing prefix [011]? 00Dial string rules file (relative to /var/spool/hylafax) [etc/dialrules]?Tracing during normal server operation [1]?Tracing during send and receive sessions [11]?Protection mode for received facsimile [0600]?Protection mode for session logs [0600]?Protection mode for ttyIAX2 [0600]?Rings to wait before answering [1]? 2Modem speaker volume [off]?Command line arguments to getty program ["-h %l dx_%s"]?Pathname of TSI access control list file (relative to /var/spool/hylafax) [""]?Pathname of Caller-ID access control list file (relative to /var/spool/hylafax) [""]?Tag line font file (relative to /var/spool/hylafax) [etc/lutRS18.pcf]?Tag line format string ["From %%l|%c|Page %%P of %%T"]?Time before purging a stale UUCP lock file (secs) [30]?Hold UUCP lockfile during inbound data calls [Yes]?Hold UUCP lockfile during inbound voice calls [Yes]?Percent good lines to accept during copy quality checking [95]?Max consecutive bad lines to accept during copy quality checking [5]?Max number of pages to accept in a received facsimile [25]?Syslog facility name for ServerTracing messages [daemon]?Set UID to 0 to manipulate CLOCAL [""]?Use available priority job scheduling mechanism [""]?

The non-default server configuration parameters are:

CountryCode: 57AreaCode: 5FAXNumber: +5753850962LongDistancePrefix: 0InternationalPrefix: 00DialStringRules: etc/dialrulesSessionTracing: 11RingsBeforeAnswer: 2SpeakerVolume: offGettyArgs: "-h %l dx_%s"LocalIdentifier: CursoAsteriskTagLineFont: etc/lutRS18.pcfTagLineFormat: "From %%l|%c|Page %%P of %%T"MaxRecvPages: 25

Are these ok [yes]? yes

Now we are going to probe the tty port to figure out the type

318

Page 330: Libro Asterisk 1.8.X - Versión 1.0 (1)

of modem that is attached. This takes a few seconds, so be patient.Note that if you do not have the modem cabled to the port, or themodem is turned off, this may hang (just go and cable up the modemor turn it on, or whatever).

Probing for best speed to talk to modem: 38400 OK.

About fax classes:

The difference between fax classes has to do with how HylaFAX interactswith the modem and the fax protocol features that are used when sendingor receiving faxes. One class isn't inherently better than another;however, one probably will suit a user's needs better than others.

Class 1 relies on HylaFAX to perform the bulk of the fax protocol.Class 2 relies on the modem to perform the bulk of the fax protocol.Class 2.0 is similar to Class 2 but may include more features.Class 1.0 is similar to Class 1 but may add V.34-fax capability.Class 2.1 is similar to Class 2.0 but adds V.34-fax capability.

HylaFAX generally will have more features when using Class 1/1.0 thanwhen using most modems' Class 2 or Class 2.0 implementations. Generallyany problems encountered in Class 1/1.0 can be resolved by modificationsto HylaFAX, but usually any problems encountered in Class 2/2.0/2.1 willrequire the modem manufacturer to resolve it.

Use Class 1 unless you have a good reason not to.

This modem looks to have support for Class 1.0 and 1.How should it be configured [1.0]?

Hmm, this looks like a Class 1.0 modem.Product code (ATI0) is "spandsp".Other information (ATI3) is "www.soft-switch.org".DTE-DCE flow control scheme [default]?Modem manufacturer is "Unknown".Modem model is "Unknown".

Using prototype configuration file class1.0...

There is no prototype configuration file for your modem, so we willhave to fill in the appropriate parameters by hand. You will need themanual for how to program your modem to do this task. In case you areuncertain of the meaning of a configuration parameter you shouldconsult the config(5F) manual page for an explanation.

319

Page 331: Libro Asterisk 1.8.X - Versión 1.0 (1)

Note that modem commands must be specified exactly as they are to besent to the modem. Note also that quote marks (") will not be displayedand will automatically be deleted. You can use this facility to supplynull parameters as "".

Finally, beware that the set of parameters is long. If you prefer touse your favorite editor instead of this script you should fill thingsin here as best you can and then edit the configuration file

"/var/spool/hylafax/etc/config.ttyIAX2"

after completing this procedure.

Command to enter Class 1 [AT+FCLASS=1.0]?Command to stop and wait prior to sending PPM [AT+FTS=7]?Command to stop and wait prior to sending TCF [AT+FTS=7]?Command to stop and wait prior to sending EOP [AT+FTS=9]?Extra bytes in a received HDLC frame [4]?Maximum time to wait for OK after aborting a receive (ms) [200]?Maximum wait for initial identification frame (ms) [40000]?Command to ensure silence after receiving HDLC and before sending [AT+FRS=7]?

The modem configuration parameters are:

Class1Cmd: AT+FCLASS=1.0Class1PPMWaitCmd: AT+FTS=7Class1TCFWaitCmd: AT+FTS=7Class1EOPWaitCmd: AT+FTS=9Class1FrameOverhead: 4Class1RecvAbortOK: 200Class1RecvIdentTimer: 40000Class1SwitchingCmd: AT+FRS=7Class1TCFMaxNonZero: 10Class1TCFMinRun: 1000

Are these ok [yes]? yes

Creating new configuration file /var/spool/hylafax/etc/config.ttyIAX2...Creating fifo /var/spool/hylafax/FIFO.ttyIAX2 for faxgetty... done.Done setting up the modem configuration.

Checking /var/spool/hylafax/etc/config for consistency......everything looks ok; leaving existing file unchanged.

Don't forget to run faxmodem(8C) (if you have a send-only environment)or configure init to run faxgetty on ttyIAX2.

320

Page 332: Libro Asterisk 1.8.X - Versión 1.0 (1)

Hylafax preguntará si se quiere configurar otro módem:

Do you want to run faxaddmodem to configure another modem [yes]? no

Se contesta no. El servidor de FAX avisará que para que las llamadas sean contestadas en automático hay que configurar faxgetty (la utilidad que se encarga de esta tarea) y si se quiere iniciar faxmodem para los dos FAX configurados (se contesta yes):

You do not appear to be using faxgetty to notify the HylaFAX schedulerabout new modems and/or their status. This means that you must use thefaxmodem program to inform the new faxq process about the modems youwant to have scheduled by HylaFAX. Beware that if you have modems thatrequire non-default capabilities specified to faxmodem then you shouldread faxmodem(8C) manual page and do this work yourself (since thisscript is not intelligent enough to automatically figure out the modemcapabilities and supply the appropriate arguments).

Should I run faxmodem for each configured modem [yes]? yes/usr/sbin/faxmodem ttyIAX1/usr/sbin/faxmodem ttyIAX2

Done verifying system setup.

La configuración de los dos módem ha terminado. Ahora se configura faxgetty en el archivo inittab de forma que la utilidad se inicie al arrancar el servidor Linux:

nano /etc/inittab

después de esta linea:

#6:2345:respawn:/sbin/mingetty tty6

se pone:

fax1:2345:respawn:/usr/sbin/faxgetty ttyIAX1fax2:2345:respawn:/usr/sbin/faxgetty ttyIAX2

Se guardan los cambios y se recarga la configuración de inittab:

init q

Se averigua que faxgetty este corriendo para los dos FAX:

ps aux | grep ttyIAX

321

Page 333: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se reinicia Hylafax

/etc/init.d/hylafax restartShutting down HylaFAX queue manager (faxq): [ OK ]Shutting down HylaFAX server (hfaxd): [ OK ]Starting HylaFAX queue manager (faxq): [ OK ]Starting HylaFAX server (hfaxd): [ OK ]Restarting HylaFAX modem manager (faxgetty): [ OK ]Shutting down HylaFAX queue manager (faxq): [ OK ]

Todos los archivos de configuración que se crearán a lo largo del proceso de configuración de Hylafax se guardaran en las carpeta /var/spool/hylafax/etc y /etc/hylafax

Para controlar el estado de Hylafax y de los FAX configurados se usa este comando:

faxstat

El resultado es:

HylaFAX scheduler on li370-135.members.linode.com: RunningModem ttyIAX2 (+5753850962): Running and idleModem ttyIAX1 (+5753850962): Running and idle

Para mejorar la recepción y envío de los FAX, se añade un pequeño retraso en la configuración de los módem de forma que si se pierde la conexión, se intentará reajustarla:

nano /var/spool/hylafax/etc/config.ttyIAX1

al final del archivo se añade esta linea:

Class1SwitchingCmd: "<delay:7>"

Lo mismo se hace con el módem ttyIAX2:

nano /var/spool/hylafax/etc/config.ttyIAX2

al final del archivo se añade esta linea:

Class1SwitchingCmd: "<delay:7>"

Para recibir una notificación si el fax ha sido enviado hay que modificar el archivo de configuración de Hylafax (la recibirá el usuario root):

nano /etc/hylafax/hyla.conf

322

Page 334: Libro Asterisk 1.8.X - Versión 1.0 (1)

si cambia esta linea:

#Notify: Done

para que quede

Notify: Done

Para recibir los FAX entrantes a una dirección de correo electrónico externa al servidor:

nano /var/spool/hylafax/etc/FaxDispatch

se cambia esta linea:

SENDTO=FaxMaster

para que quede (personalizar la dirección de correo electrónico):

[email protected]

Se reinicia Hylafax:

/etc/init.d/hylafax restart Por ultimo se indica que todos los mensajes de correo electrónico para el usuario Faxmaster se envíen al usuario root:

nano /etc/aliases

después de esta linea:support: postmaster

se pone:

FaxMaster: root

Se guardan los cambios y se recarga la configuración:

newaliases

Prueba envío.

Para el envío de los FAX se crea en extension.conf un contesto [fax] (El mismo que se ha configurado para las dos extensiones iaxmodem en iax.conf) antes del contexto internas, con las siguientes líneas:

323

Page 335: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/extensions.conf

[fax]exten => _X.,1,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

exten => 1234,1,Dial(IAX2/iaxmodem2)same => n,hangup

El primer bloque es para enviar FAX a números externos, el segundo es para probar el fax en local.

En la parte general del archivo sip.conf, se ha configurado el parámetro faxdetect en yes; esto significa que si el sistema detecta que la llamada está llegando desde un FAX, automáticamente “saltará”, si existe, a la extensión fax. Para probarlo, en el mismo contexto fax se añade otro bloque:

exten => 1235,1,Answersame => n,Wait(6)same => n,Dial(SIP/1000,45)exten => fax,1,Dial(IAX2/iaxmodem2)same => n,hangup

El flujo del dialplan es: se contesta la llamada entrante, se esperan 4 segundos para permitir a Asterisk reconocer si la llamada procede de un fax. Si procede de un fax se va a la extensión fax, prioridad 1 donde se contestará con el modem FAX iaxmodem2, sino se llamará la extensión 1000. Se guardan los cambios y actualiza el dialplan:

/etc/init.d/asterisk reload

Para enviar un fax con el cliente Hylafax la sintaxis es:

sendfax -h modem -n -d <faxnumber> <file.txt>

Se crea el archivo de texto que se enviará:

nano /tmp/pruebafax.txt

y se pone:

Libro Asterisk 1.8.X Nombre Apellido

Se guardan los cambios. En este caso con el módem ttyIAX1 se enviará el FAX y con el módem ttyIAX2 se recibirá. Hay que tener en cuenta que cuanto se trabaja con pura lineas VoIP el envío y la recepción de los FAX no siempre funciona bien. Por eso se hace esta prueba.

sendfax -h ttyIAX1@localhost -n -d numerolocal /tmp/pruebafax.txt

324

Page 336: Libro Asterisk 1.8.X - Versión 1.0 (1)

Utilizando el numero local sería:

sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax.txt

En lugar de “numerolocal” se pone el numero definido en el contexto [fax] para la prueba en local. Si sale este error:

Usage: /usr/sbin/textfmt [-1] [-2] [-B] [-c] [-D] [-f fontname] [-F fontdir(s)] [-m N] [-o #] [-p #] [-r] [-U] [-Ml=#,r=#,t=#,b=#] [-V #] files... >out.psDefault options: -f Courier -1 -p 11bp -o 0Se ha producido un error al convertir el documento; el comando fue "/usr/sbin/textfmt -B -f Courier-Bold -Ml=0.4in -p 11 -s default >'/tmp//sndfaxlBau98' <'/tmp/pruebafax.txt'"

es porque hay un problema con los fonts de Ghostscrpt. Para solucionarlo se abre el siguiente archivo:

nano /usr/share/ghostscript/8.70/Resource/Init/Fontmap.GS

y se modifica la linea 92:

/Courier-Bold /NimbusMonL-Bold ;

Para que quede:

/Courier-Bold (n022004l.pfa) ;

Se guardan los cambios y se vuelve a enviar el fax:

sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax.txt

request id is 1 (group id 1) for host localhost (1 file)

Se puede controlar el estado del envío con el siguiente comando:

faxstat -s

HylaFAX scheduler on li374-112.members.linode.com: RunningModem ttyIAX2 (+5753850962): Running and idleModem ttyIAX1 (+5753850962): Initializing serverJID Pri S Owner Number Pages Dials TTS Status1 127 R root 1234 0:1 0:12

Se entra en la consola de Asterisk y se mira que aparece:

asterisk -rvvvvvvvvvvvvv

cuando termine la llamada se sale de la consola:

325

Page 337: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> quit

y se controla que ha pasado:

faxstat -sHylaFAX scheduler on li374-112.members.linode.com: RunningModem ttyIAX2 (+5753850962): Running and idleModem ttyIAX1 (+5753850962): Running and idle

En este caso el fax se ha enviado con éxito ya que los dos FAX configurados están disponibles. ¿Cómo puedo comprobarlo? Abriendo el correo del usuario root (desde terminal o webmin):

y comprobando que el fax enviado ha llegado al correo electrónico definido a lo largo de la configuración de Hylafax:

326

Page 338: Libro Asterisk 1.8.X - Versión 1.0 (1)

Abriendo el PDF:

Si se quiere usar un cliente con interfaz gráfica para el envío de fax, una buena solución es YajHFC (Yet another Java HylaFAX Client) que siendo escrito completamente en JAVA funciona con cualquier sistema operativo. Otra solución más elaborada es AvantFAX.

En el caso que se utilice un cliente remoto en el cortafuegos hay que abrir el puerto 4559 TCP (usado por Hylafax) y los puertos desde el 30000 hasta el 65000 TCP para los datos.

17.3 Protocolo T38

Se pone una hoja en la “maquina”, se marca el numero de teléfono de destino y se espera que salga un OK por algún lado. Esta sencilla operación es la que se hace cuando se quiere enviar un FAX. Todo lo

327

Page 339: Libro Asterisk 1.8.X - Versión 1.0 (1)

que pasa en el “mientras” es totalmente transparente. Las dos maquinas FAX negocian todos los pasajes y para hacerlo utilizan un protocolo. Ese protocolo ha sido definido por la “International Telecommunication Union” y tomó como sigla T.30

En 1998 la misma organización define un nuevo protocolo que permite recibir y enviar fax usando una red a paquetes (Internet). La sigla de este protocolo es T.38.

¿Cómo funciona el protocolo T.38?

Quizás la imagen que sigue ayuda para entender:

El FAX está conectado a la línea telefónica y también a un Gateway con soporte T.38. Este Gateway se encarga de transformar el FAX en el formato requerido para ser enviado a través de la red Internet. En el lado opuesto otro Gateway T.38 se encarga de “decodificar” los paquetes que lleguen para luego pasar el resultado al fax de destinación. Un Gateway T.38 clásico funciona como se muestra en la imagen que sigue:

328

Page 340: Libro Asterisk 1.8.X - Versión 1.0 (1)

Los datos del FAX T.30 vienen analizados y manipulados para luego ser transformados en paquetes (IFP). Los paquetes se pueden enviar usando tres protocolos de transporte: UDPTL, TCP o RTP. Será tarea de los Gateway T.38 negociar el protocolo de trasporte. En el caso de Asterisk el único protocolo de trasporte permitido es UDPTL que funciona de la siguiente forma:

Cada paquete UDPTL contiene encapsulado el paquete IFP (que contiene los datos del fax que se está enviando y un sistema de corrección de errores – FEC [forward error correction]). Para repetir los paquetes perdidos y controlar que lleguen en el justo orden hay disponibles dos sistemas:

• Con el primero se repite el ultimo paquete enviado como FEC para el paquete que se está enviando

• Con el segundo se crea un paquete de paridad para un numero determinado de paquetes IFP y se incluye esta información en el paquete UDPTL corriente.

El paquete UDPTL está encapsulado en un paquete UDP (protocolo de trasporte) que a su vez está encapsulado en un paquete IP (protocolo que permite al paquete llegar a destinación).

Asterisk 1.8.X soporta el protocolo T.38 solamente como pasarela, es decir que no está “en el medio” a

329

Page 341: Libro Asterisk 1.8.X - Versión 1.0 (1)

lo largo del envío del fax. A un lado y al otro de la trasmisión deberán estar dos Gateway T.38 que se hagan cargo de la tarea de enviar/recibir el fax. En Asterisk el envío y recepción de faxes es posible a través de la librería SpanDSP y el modulo res_fax.

Desde la consola:

asterisk -rvvvvvvvvvvvvvvvv

Se controla la sintaxis de las dos aplicaciones contenidas en el modulo app_fax

CLI> core show application ReceiveFax -= Info about application 'ReceiveFAX' =-

[Synopsis]Receive a FAX and save as a TIFF/F file.

[Description]This application is provided by res_fax, which is a FAX technology agnosticmodule that utilizes FAX technology resource modules to complete a FAXtransmission.Session arguments can be set by the FAXOPT function and to check resultsof the ReceiveFax() application.

[Syntax]ReceiveFAX(filename[,options])

[Arguments]options d: Enable FAX debugging.

f: Allow audio fallback FAX transfer on T.38 capable channels.

s: Send progress Manager events (overrides statusevents setting in res_fax.conf).

CLI> core show application SendFax -= Info about application 'SendFAX' =-

[Synopsis]Sends a specified TIFF/F file as a FAX.

[Description]This application is provided by res_fax, which is a FAX technology agnosticmodule that utilizes FAX technology resource modules to complete a FAXtransmission.Session arguments can be set by the FAXOPT function and to check resultsof the SendFax() application.

330

Page 342: Libro Asterisk 1.8.X - Versión 1.0 (1)

[Syntax]SendFAX([filename2[&...]][,options])

[Arguments]filename2 TIFF file to send as a FAX.options d: Enable FAX debugging.

f: Allow audio fallback FAX transfer on T.38 capable channels.

s: Send progress Manager events (overrides statusevents setting in res_fax.conf).

z: Initiate a T.38 reinvite on the channel if the remote end does not.

Algunos ATA comercializados soportan el protocolo T.38. En Voip-info aparece una lista (aunque no muy actualizada).

Para el soporte T.38 en Asterisk hay que modificar este archivo:

mv /etc/asterisk/udptl.conf /etc/asterisk/udptl.con.old

nano /etc/asterisk/udptl.conf

Se pone:

[general]udptlstart=4000udptlend=4099udptlchecksums=yesudptlfecentries = 3udptlfecspan = 3use_even_ports = no

Se guardan los cambios y se vuelve a arrancar Asterisk:

/etc/init.d/asterisk restart

17.3.1 Aplicación ReceiveFax

Para el test que se va a ejecutar hay que modificar el dialplan:

nano /etc/asterisk/extensions.conf

331

Page 343: Libro Asterisk 1.8.X - Versión 1.0 (1)

se modifica este bloque:

exten => 1234,1,Dial(IAX2/iaxmodem2)same => n,hangup

Para que quede:

exten => 1234,1,Answersame => n,Receivefax(/tmp/${UNIQUEID}.tif,df)same => n,Hangupexten => h,1,Noop(FAXSTATUS ${FAXSTATUS}, FAXERROR ${FAXERROR})same => n,Hangup

Se guardan los cambios. Como se ha activado la opción de debug (d), para ver los datos en la consola de Asterisk hay que modificar el archivo logger.conf que es donde se configuran los distintos registros de Asterisk. Se abordará la configuración del archivo de forma más detallada en el capitulo 20.

nano /etc/asterisk/logger.conf

se modifica esta linea:

console => notice,warning,error

para que quede:

console => notice,warning,error,fax

Se guardan los cambios y se actualiza la configuración de Asterisk:

service asterisk reload

Se envía el mismo archivo txt utilizado anteriormente:

sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax.txt

entran en la consola de Asterisk y miran los resultados del envío:

asterisk -rvvvvvvvvvvvvvvvvv

Encontraremos todo el debug de la recepción del fax con el protocolo T30. Las ultimas lineas:

[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW T.30 Send complete in phase T30_PHASE_E, state 2[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW T.30 Changing from state 2 to 32[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW T.30 Changing from phase T30_PHASE_E to T30_PHASE_CALL_FINISHED

332

Page 344: Libro Asterisk 1.8.X - Versión 1.0 (1)

[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW FAX Set rx type 9[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW FAX FAX exchange complete[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW FAX Set tx type 9[Mar 23 07:18:03] FAX[11707]: res_fax.c:655 ast_fax_log: FLOW FAX FAX exchange complete -- Executing [1234@fax:3] Hangup("IAX2/iaxmodem1-3347", "") in new stack == Spawn extension (fax, 1234, 3) exited non-zero on 'IAX2/iaxmodem1-3347' -- Executing [h@fax:1] NoOp("IAX2/iaxmodem1-3347", "FAXSTATUS SUCCESS, FAXERROR ") in new stack -- Executing [h@fax:2] Hangup("IAX2/iaxmodem1-3347", "") in new stack

El fax, como indica la parte en negrita, se ha recibido con éxito. Se entra en la carpeta /tmp y se mira si efectivamente está presente un archivo tiff:

ls /tmp

1332505066.0.tif

17.3.2 Applicación SendFax

Como se ha visto en el párrafo 17.3, la aplicación para enviar FAX en Asterisk es SendFax. La sintaxis es muy sencilla:

SendFAX([filename2[&...]][,options])

El problema es que con esta aplicación no se puede llamar directamente un FAX en cuanto no hay posibilidad de indicar el numero a marcar.

Para solucionar este problema hay que hacer uso de un callfile. Un callfile es un archivo de texto donde se definen unas cuantas acciones que Asterisk ejecuta; una vez preparado se mueve (no se copia) en la carpeta /var/spool/asterisk/outgoing. Asterisk controla periódicamente esta carpeta a través del modulo pbx_spool.so y si hay un archivo de este tipo lo procesa.

En el escenario que se va a presentar se llamará el numero de destino usando el chan_local. Una vez que el destinatario conteste se enviará el archivo Ttiff (la aplicación SendFax solo acepta archivos tiff).

El callfile que se va a utilizar:

Channel: Local/1234@fax;el canal que se va a usar para efectuar la llamada y el numero a llamar. El canal Local es un pseudo canal que permite llamar una extensión y un determinado contexto y, cuando la extensión conteste, pasar el procesamiento del dialplan a esa extensión. En este caso se llamará la extensión 1234, contexto fax que es donde se ha configurado la aplicación para recibir los FAX.

Callerid: "FAX"; el identificativo del llamante

333

Page 345: Libro Asterisk 1.8.X - Versión 1.0 (1)

WaitTime: 30;Se espera un respuesta por 30 segundos

Maxretries:3:se intentará llamar el numero tres veces

RetryTime: 300; entre un intento y otro se esperarán 300 segundos

Account: 1000; en el registro de las llamadas (CDR) se contabilizará la llamada a la extensión 1000

Application: SendFax; una vez que el destinatario conteste se ejecuta la aplicación sendfax

Data: /tmp/1329843102.10.tif;el nombre del archivo que se enviará (cambiar el nombre con el que hay en la carpeta /tmp)

El resultado del archivo sin los comentarios será:

cd /tmp

nano enviofax

Channel: Local/1234@faxCallerid: "FAX"WaitTime: 30Maxretries:3RetryTime: 300Account: 1000Application: SendFaxData: /tmp/1332505066.0.tif,dz

Ahora se mueve el archivo en la carpeta /var/spool/asteisk/outgoning

mv enviofax /var/spool/asterisk/outgoing

Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvv

Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW T.30 Send complete in phase T30_PHASE_E, state 2[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW T.30 Changing from state 2 to 32[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW T.30 Changing from phase T30_PHASE_E to T30_PHASE_CALL_FINISHED[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW FAX Set rx type 9

334

Page 346: Libro Asterisk 1.8.X - Versión 1.0 (1)

[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW FAX FAX exchange complete[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW FAX Set tx type 9[Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW FAX FAX exchange complete -- Executing [1234@fax:3] Hangup("Local/1234@fax-ee6a;2", "") in new stack == Spawn extension (fax, 1234, 3) exited non-zero on 'Local/1234@fax-ee6a;2' -- Executing [h@fax:1] NoOp("Local/1234@fax-ee6a;2", "FAXSTATUS SUCCESS, FAXERROR ") in new stack -- Executing [h@fax:2] Hangup("Local/1234@fax-ee6a;2", "") in new stack

Esto significa que el fax se ha enviado con éxito utilizando el protocolo T30. Si se quiere probar el envío con el protocolo T38, hay que utilizar un proveedor VoIP que lo soporte, cosa que no hace Justvoip como se puede ver con esta prueba:

nano enviofax

Channel: SIP/justvoip/003907331870494Callerid: "FAX"WaitTime: 30Maxretries:3RetryTime: 300Account: 1000Application: SendFaxData: /tmp/1332505066.0.tif,dz

mv enviofax /var/spool/asterisk/outgoing

El resultado en la consola de Asterisk (la parte en negrita):

-- Attempting call on SIP/justvoip/003907331875163 for application SendFax(/tmp/1332505066.0.tif,d) (Retry 1) == Using SIP RTP CoS mark 5 > Channel SIP/justvoip-00000001 was answered. > Launching SendFax(/tmp/1332505066.0.tif,d) on SIP/justvoip-00000001 -- Channel 'SIP/justvoip-00000001' sending FAX: -- /tmp/1332505066.0.tif[Mar 23 07:33:58] WARNING[11945]: res_fax.c:1996 sendfax_t38_init: Audio FAX not allowed on channel 'SIP/justvoip-00000001' and T.38 negotiation failed; aborting.[Mar 23 07:33:58] ERROR[11945]: res_fax.c:2225 sendfax_exec: error initializing channel 'SIP/justvoip-00000001' in T.38 mode[Mar 23 07:33:58] NOTICE[11945]: pbx_spool.c:366 attempt_thread: Call completed to SIP/justvoip/003907331875163

El discurso cambia si para recibir FAX se utilizan las normales lineas telefónicas. La calidad es mucho mejor. En la configuración del chan_dahdi.conf, hay unos parámetro relacionados con los FAX:

; For fax detection, uncomment one of the following lines. The default is *OFF*;

335

Page 347: Libro Asterisk 1.8.X - Versión 1.0 (1)

;faxdetect=both;faxdetect=incoming;faxdetect=outgoing;faxdetect=no

; When 'faxdetect' is used, one could use 'faxbuffers' to configure the DAHDI; transmit buffer policy. The default is *OFF*. When this configuration; option is used, the faxbuffer policy will be used for the life of the call; after a fax tone is detected. The faxbuffer policy is reverted after the; call is torn down. The sample below will result in 6 buffers and a full; buffer policy.;;faxbuffers=>6,full

De esta forma, para cada canal se puede definir si tiene que reconocer los FAX en las llamadas entrantes, salientes o desactivar la opción.

336

Page 348: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 349: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XVIII

Conexiones entre servidores Asterisk

Este capitulo es dedicado a la conexiones entre servidores Asterisk. Un escenario típico de este tipo de configuración es cuando una empresa tiene sedes en distintos lugares y quiere que las extensiones de una sede puedan comunicarse con las extensiones de la otra. Además, si en una de las sedes están instalados Gateway/Tarjetas FXO, desde la otra sede se podrán sacar las

llamadas utilizando esos Gateway/Tarjetas.

Se presentarán cinco tipos de conexiones:

• Conexiones SIP con nombre de usuario y contraseña• Conexiones IAX2 con autentificación sobre IP• Conexiones distribuidas con el protocolo DUNDi• Conexiones sobre OpenVPN• Conexiones SIP con protocolo SIP TLS y audio cifrado (SRTP)

18.1 Conectar dos servidores Asterisk con el protocolo SIP

Hay dos servidores Asterisk, A y B, y se quiere conectarlos entre ellos utilizando el protocolo SIP para llamar desde A las extensiones de B y desde B las extensiones de A. Las extensiones del servidor A son de 4 cifras y empiezan por 1, en el servidor B son de 4 cifras y empiezan por el mismo numero 1.

Servidor A

nano /etc/asterisk/sip.conf

En el bloque register se añade:

register => serverA:pass1@IPserverB/serverB

En lugar del IPserverB se pone la dirección IP del servidor B. Al final del archivo:

[serverB]type=friendremotesecret=pass2context=internasqualify=yeshost=dynamiclanguage=esdisallow=allallow=gsmallow=ulawallow=alaw

Page 350: Libro Asterisk 1.8.X - Versión 1.0 (1)

Con la línea de register, se conecta el servidor serverA al servidor serverB. Con las líneas que están después de la etiqueta [serverB] se define una extensión SIP que será aquella usada por el servidor B para conectarse al servidor A. Con contexto=internas, el servidor B tendrá acceso a todo el dialplan definido en ese contexto. Si se quiere que el servidor B tenga acceso solamente a un determinado contexto, se modifica la linea context poniendo un nombre de contexto y, si no existe, se crea ese contexto en el dialplan.

IMPORTANTE: cuando se conectan dos servidores Asterisk entre ellos, en la configuración de la extensión ya no se utiliza el parámetro secret sino el parámetro remotesecret (esto desde la versión 1.6.1.X de Asterisk)

Se guardan los cambios y se pasa al servidor B.

Servidor B

nano /etc/asterisk/sip.conf

En el bloque register se añade::

register => serverB:pass2@IPserverA/serverA

al final del archivo:

[serverA]type=friendremotesecret=pass1context=internashost=dynamiclanguage=esqualify=yesdisallow=allallow=gsmallow=ulawallow=alaw

Ahora que los dos servidores están configurados hay que reiniciarlos. En los dos se escribe el comando:

/etc/init.d/asterisk restart

Desde la consola se averigua que haya conexión entre los dos servidores:

asterisk -rvvvvvvvvvvvvvv

para el servidor A:

CLI> sip show registry69.164.196.73:5060 N serverA 105 Registered Wed, 26 Oct 2011 10:17:54

339

Page 351: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> sip show peersserverB/serverA 69.164.196.73 D N 5060 OK (1 ms)

para el servidor B:

CLI> sip show registry96.126.121.135:5060 N serverB 105 Registered Wed, 26 Oct 2011 10:18:42

CLI> sip show peersserverA/serverB 96.126.121.135 D 5060 OK (2 ms)

Ahora lo único que hace falta es modificar el archivo extensions.conf de ambos servidores.

Servidor A

nano /etc/asterisk/extensions.conf

En el contexto internas (para las llamadas a extensiones del servidor B) se añade:

exten => _*1XXX,1,NoOp()same => n,Dial(SIP/serverB/${EXTEN:1},30)same => n,Hangup()

Con estas líneas se configura Asterisk para que todas las llamadas con destino las extensiones cuyo numero empiece por 1 y sean de 4 cifras sean redirigidas hacia el servidor B. Para diferenciarlas de las llamadas entre las extensiones locales del servidor A se añade un * delante de las cuatro cifras a marcar. Ejemplo: para marcar a la extensión 1000 del servidor B, hay que digitar el siguiente numero: *1000

Servidor B

nano /etc/asterisk/extensions.conf

En el contexto internas (para las llamadas a extensiones del servidor A) se añade:

exten => _*1XXX,1,NoOp()same => n,Dial(SIP/serverA/${EXTEN:1},30)same => n,Hangup()

Con estas líneas se configura Asterisk para que todas las llamadas con destino las extensiones cuyo numero empiece por 1 y sean de 4 cifras sean redirigidas hacia el servidor B. Para diferenciarlas de las llamadas entre las extensiones locales del servidor A se añade un * delante de las cuatro cifras a marcar.

Se actualiza la configuración en los dos servidores:

asterisk -rvvvvvvvvvvvvvvv

340

Page 352: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> dialplan reload

Prueba

Desde la extensión 1000 del servidor A se marca *1000 para llamar la extensión 1000 del servidor B y se mira lo que pasa en la consola de Asterisk del servidor B:

[2011-01-25 22:42:24] WARNING[14692]: chan_sip.c:12849 check_auth: username mismatch, have <1000>, digest has <serverA>[2011-01-25 22:42:24] NOTICE[14692]: chan_sip.c:20212 handle_request_invite: Failed to authenticate device "Fulano" <sip:[email protected]>;tag=as2e5f74a9

La llamada no funciona.

¿Porqué pasa eso?

Porque el servidor B piensa que la llamada esté llegando desde la extensión 1000 local y no logra distinguir entre extensión 1000 local y extensión 1000 remota. Para solucionar el problema, hay que modificar el plan de llamadas en ambos servidores.

Servidor A

nano /etc/asterisk/extensions.conf

modificar este bloque

exten => _*1XXX,1,NoOp()same => n,Dial(SIP/serverB/${EXTEN:1},30)same => n,Hangup()

para que quede:

exten => _*1XXX,1, Set(CALLERID(num)=serverA)same => n,Dial(SIP/serverB/${EXTEN:1},30)same => n,Hangup()

Servidor B

nano /etc/asterisk/extensions.conf

modificar estas lineas:

exten => _*1XXX,1,NoOp()same => n,Dial(SIP/serverA/${EXTEN:1},30)same => n,Hangup()

341

Page 353: Libro Asterisk 1.8.X - Versión 1.0 (1)

para que queden:

exten => _*1XXX,1, Set(CALLERID(num)=serverB)same => n,Dial(SIP/serverA/${EXTEN:1},30)same => n,Hangup()

Se actualiza el dialplan en ambos servidores y se intenta llamar nuevamente desde el servidor A el numero *1000. En la consola de Asterisk del servidor A aparecerá:

Executing [*1000@externas:1] Set("SIP/1000-00000004", "CALLERID(num)=serverA") in new stack -- Executing [*1000@externas:2] Dial("SIP/1000-00000004", "SIP/serverB/1000,30") in new stack == Using SIP RTP CoS mark 5 == Using SIP VRTP CoS mark 6 == Using UDPTL CoS mark 5 -- Called serverB/1000 -- SIP/serverB-00000005 is ringing

La llamada funciona. Este tipo de configuración se necesita solamente si las extensiones de los dos servidores Asterisk tienen los mismos números asignados. En el caso de servidores Asterisk con números de extensiones distintos, no hace falta modificar el CALLERID antes de marcar.

18.2 Conectar dos servidores Asterisk con el protocolo IAX2

En este párrafo se ilustrará como conectar dos servidor Asterisk a través del protocolo IAX2 y la autentificación con dirección IP. La ventaja de IAX2 está en su característica, llamada trunking, que utiliza el mismo trunk para el envío del audio de todas las llamadas. De esta forma cuando hay un numero considerable de llamadas que estén pasando por la troncal IAX2, hay un notable ahorro de banda. Esta conexión se implementará utilizando las direcciones IP publicas de los Servidores. Suponiendo que la direcciones IP publicas sean:

Servidor A:IP: 96.126.125.112nome trunk: serveraExtensiones: 1000-1001-1002

Servidor B:IP: 66.228.49.216nome trunk: serverbExtensiones: 1000-1001-1002

Servidor A

Si abre el archivo iax.conf

nano /etc/asterisk/iax.conf

342

Page 354: Libro Asterisk 1.8.X - Versión 1.0 (1)

al final del archivo se añaden las siguientes lineas:

[serverb]type=friendhost=66.228.49.216trunk=yescontext=internasqualify=yes

Es importante destacar que la IP que se define es la del servidor B; además se utilizará en la configuración la funcionalidad del trunkink IAX2

El mismo procedimiento se ejecuta en el servidor B.

Servidorr B

nano /etc/asterisk/iax.conf

se añaden las lineas:

[servera]type=friendhost=96.126.125.112trunk=yescontext=internasqualify=yes

Se actualiza la configuración en ambos servidores:

asterisk -rvvvvvvvvv

CLI> iax2 reload

Se averigua que haya conexión entre los servidores (servidor A):

CLI> iax2 show peersserverb 66.228.49.216 (S) 255.255.255.255 4569 (T) (E) OK (1 ms)

Servidor B:

CLI> iax2 show peersservera 96.126.125.112 (S) 255.255.255.255 4569 (T) (E) OK (1 ms)

CLI> quit

En el dialplan se crea un nuevo bloque que permita llamar de un servidor a otro:

343

Page 355: Libro Asterisk 1.8.X - Versión 1.0 (1)

Servidor A

nano /etc/asterisk/extensions.conf

se añaden las siguientes lineas en el contexto internas:

exten => _*1100X,1,Dial(IAX2/serverb/${EXTEN:2})same => n,Hangup

se actualiza el dialplan:

asterisk -rx "dialplan reload"

Servidor B

nano /etc/asterisk/extensions.conf

se añaden las siguientes lineas en el contexto internas:

exten => _*1100X,1,Dial(IAX2/servera/${EXTEN:2})same => n,Hangup

se actualiza el dialplan:

asterisk -rx "dialplan reload"

Ahora se pueden efectuar las pruebas. Desde la extensión 1000 del servidor A, se marca el numero *11000 y se averigua en la consola de Asterisk que la llamada sea cursada correctamente al servidor B..

En la consola Asterisk del servidor A aparecerá:

-- Executing [*11000@externas:1] Dial("SIP/1000-00000000", "IAX2/servera/1000") in new stack -- Called IAX2/servera/1000 -- Call accepted by 96.126.125.112 (format alaw) -- Format for call is alaw -- IAX2/servera-17542 answered SIP/1000-00000000

18.3 El protocolo DUNDi

Cuando hay que conectar un numero considerable de servidores Asterisk y compartir las rutas y las extensiones configuradas en cada uno de ellos, la solución más funcional es el protocolo DUNDi. DUNDi (Distributed Universal Number Discovery) es un protocolo que permite buscar y compartir dialplan entre servidores Asterisk. Esto por medio de una red Peer-to-peer (punto-a-punto) en la cual no existen roles fijos de clientes y servidores, sino que los servidores pueden asumir uno u otro rol según el contexto.

344

Page 356: Libro Asterisk 1.8.X - Versión 1.0 (1)

A lo largo de la configuración se puede decidir si compartir contextos ya configurados en el Dialplan o crear contextos nuevos definiendo las extensiones que se volverán disponibles a los demás servidores.. Aunque la configuración y puesta en marcha pueda parecer algo complicado, con un poco de practica se irán aclarando las ideas y los conceptos claves.

El puerto predefino para el protocolo DUNDi es el 4520 UDP. Hay que abrirlo en el cortafuego de los servidores donde se va a utilizar DUNDi:

nano /etc/sysconfig/iptables

antes de esta linea:

-A INPUT -p udp -m udp --dport 4569 -j ACCEPT

se pone:

# DUNDi-A INPUT -p udp -m udp --dport 4520 -j ACCEPT

Se guardan los cambios y se reinicia Iptables:

service iptables restart

En el escenario que se presenta en este párrafo hay dos servidores Asterisk con estas características:

Servidor A:IP: 192.168.129.142usuario: server1Extensiones: 1000-1001-1002MAC Tarjeta de red: F2:3C:91:DF:5B:3E

Servidor B:IP: 192.168.182.236usuario: server2Extensiones: 1000-1001-1002 MAC Tarjeta de red: FE:FD:45:A4:C4:49

Los dos servidores están en la misma LAN pero pueden estar ubicados en cualquier punto de la red Internet.

El protocolo DUNDi se configura en el archivo dundi.conf. Es en este archivo que se definen los parámetros de conexión entre los servidores Asterisk y los contextos que se van a compartir. En el mismo archivo se define el tipo de protocolo que los dos servidores usarán para efectuar y recibir llamadas(puede ser IAX2, SIP o H323).

345

Page 357: Libro Asterisk 1.8.X - Versión 1.0 (1)

Terminada la configuración de dundi.conf, se modifica el dialplan para definir cuales son las rutas o contextos que se quiere compartir.

Servidor A

En la tabla que sigue se indican los parámetros que se configuran en el archivo dundi.conf con una breve descripción para cada uno de ellos. En la columna descripción, en negrita el valor de cada parámetro.

Parámetro Descripción[general] inicia la configuración general del archivodepartment=EmpresaAorganization=EmpresaAlocality=Santa Martastateprov=Magdalenacountry=Colombiaemail=admin@servidorA.comphone=+57XXXXXXXXXX

En estos parámetros se indican los datos de la empresa.

bindaddr Dirección IP que se quiere utilizar con el protocolo DUNDi. Con 0.0.0.0 todas las direcciones IP disponibles en el servidor Linux

port Puerto para las conexiones DUNDi (4520 predefinido)entityid El MAC address de la tarjeta de red utilizada para las conexiones

DUNDi. Personalizar con el valor real. Un ejemplo: F2:3C:91:DF:5B:3E

cachetime Cuando se envía un solicitud para conocer la disponibilidad de una ruta y se encuentra una disponible, el resultado se guardará por el tiempo definido en este parámetro (en segundos) en la base de datos interna de Asterisk del servidor que envió la solicitud. Valor 3600

ttl Time to Live es un numero que representa el tiempo de vida de la solicitud. Más alto el numero más nodos se alcanzará a consultar. Valor 32

autokill yes = si no se recibe una respuesta dentro de 2000 ms, se anulará la solicitud. Esto permite evitar que las solicitudes queden abiertas por un tiempo indeterminado

secretpath El modulo pbx_dundi crea una clave, con el nombre definido en este parámetro, que rotará de manera automática y que se guardará en la base de datos interna de Asterisk. Valor dundi

storehistory yes = mantiene un registro de las ultimas solicitudes efectuadas con los tiempos de respuesta de cada una. De esta forma es posible averiguar cuales son los nodos lentos dentro de la red DUNDi

[mappings] a partir de esta etiqueta se definen los contextos que se va a compartir con los demás servidores Asterisk. Las sintaxis de un contexto es:

346

Page 358: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripcióndundi_context => local_context,weight,tech,dest[,options]]

• dundi_context - el contexto DUNDi que se quiere compartir con los demás nodos de la red DUNDi

• local_context – el contexto local definido en el dialplan donde se configuran las rutas o extensiones que se quieren compartir

• weight – el peso que se asigna a las rutas que se comparten. Si son extensiones locales se pone 0, si son rutas por las cuales no hay una conexión directa o de alta calidad se pone un numero más alto. Al momento de hacer una solicitud si para el mismo numero requerido existen distintas rutas, se escogerá la ruta con menor peso

• tech – protocolo usado para la conexión entre servidores Asterisk (se usará IAX2)

• dest – cuando se hace una solicitud desde el servidor B y se encuentra una ruta en el Servidor A, el Servidor A utilizará esa destinación para recibir la llamada. Simplificando: se crea un user en el iax.conf del servidor Asterisk A y dest representa los paramentos para conectarse a ese user

• options – son las distintas opciones que se pueden añadir a cada contexto DUNDi:

1. nounsolicited – llamadas de cualquier tipo que no sean solicitadas no son permitidas en esta ruta

2. nocomunsolicit – llamadas comerciales no solicitadas no son permitidas en esta ruta

3. residential – el numero es de una residencia4. commercial – el numero es de una empresa5. mobile – el numero es un celular6. nopartial – no se harán búsquedas por números

incompletos

servera => servera-local,0,IAX2,server1:${SECRET}@192.168.129.142/${NUMBER}

El que aparece arriba es el contexto que se va a definir:

• servera => - el contexto DUNDi que se va a compartir• servera-local - el contexto definido en el dialplan que

contendrá todas las rutas que se van a compartir• IAX2 - la tecnología usada (protocolo) para las llamadas• server1 - usuario que se configurará en el el archivo iax.conf• ${SECRET} - es la variable que contiene la clave que el

modulo DUNDi crea en automático y que se usará para autenticar el usuario server1

• 192.168.129.142 - dirección IP del Servidor A (personalizar)

347

Page 359: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

• ${NUMBER}: la variable que contendrá el numero que ha sido solicitado

Para terminar con la configuración del archivo dundi.conf se definen los servidores Asterisk con los que se va a tener una conexión directa:

[FE:FD:45:A4:C4:49]model = symmetrichost = 192.168.182.236inkey = server2outkey = server1include = allpermit = serveraqualify = yes

• FE:FD:45:A4:C4:49: MAC address de la tarjeta de red del Servidor Asterisk B con el que se crea la conexión (personalizar)

• model: puede ser:1. inbound: recibe solamente solicitudes2. outbound: solo efectúa solicitudes pero no las recibe3. symmetric: recibe y efectúa solicitudes

• host: direccion IP o nombre de dominio del servidor Asterisk B• inkey: clave RSA usada para autenticarse con el servidor Asterisk B• outkey: clave RSA usada por el Servidor Asterisk B para autenticarse con el Servidor

Asterisk A• include: incluye esta conexión para todas las solicitudes efectuadas en el Servidor Asterisk A• permit: se definen los contextos DUNDi a los que tendrá acceso este nodo• qualify: se controlará periódicamente que la conexión con el nodo esté activa

Se crea el archivo dundi.conf. Primero se renombra el predefinido:

mv /etc/asterisk/dundi.conf /etc/asterisk/dundi.conf.old

se crea uno nuevo:

nano /etc/asterisk/dundi.conf

y se copian los datos de configuración:

[general]department=EmpresaAorganization=EmpresaAlocality=Santa Martastateprov=Magdalena

348

Page 360: Libro Asterisk 1.8.X - Versión 1.0 (1)

[email protected]=+57XXXXXXXXXXbindaddr=0.0.0.0port=4520entityid=F2:3C:91:DF:5B:3Ecachetime=3600ttl=32autokill=yessecretpath=dundistorehistory=yes

[mappings]servera => servera-local,0,IAX2,server1:${SECRET}@192.168.129.142/${NUMBER}

[F2:3C:91:96:EC:A3]model = symmetrichost = 192.168.182.236inkey = server2outkey = server1include = allpermit = serveraqualify = yes

IMPORTANTE: Personalizar los siguientes parámetros: entityid, la dirección IP local presente bajo la etiqueta [mappings], el mac address de la tarjeta del servidor B contenido entre corchetes y la dirección ip local del servidor B en host

Se guardan los cambios y se crea la clave RSA para autenticar el Servidor Asterisk B. Para crear la clave se usará una utilidad que viene con la instalación de Asterisk. Primero se entra en la carpeta donde se guardarán las claves:

cd /var/lib/asterisk/keys

Se crea la clave:

astgenkey -n server1

This script generates an RSA private and public key pairin PEM format for use by Asterisk. You will be asked toenter a passcode for your key multiple times. Pleaseenter the same code each time. The resulting files willneed to be moved to /var/lib/asterisk/keys if you wantto use them, and any private keys (.key files) willneed to be initialized at runtime either by runningAsterisk with the '-i' option, or with the 'init keys'command once Asterisk is running.

349

Page 361: Libro Asterisk 1.8.X - Versión 1.0 (1)

Press ENTER to continue or ^C to cancel.

Generating SSL key 'server1':Generating RSA private key, 1024 bit long modulus...............++++++....++++++e is 65537 (0x10001)writing RSA keyKey creation successful.Public key: server1.pubPrivate key: server1.key

Se crearán dos archivos, uno contiene la clave publica y uno la clave privada. La publica se copia en el Servidor Asterisk B:

scp server1.pub [email protected]:/var/lib/asterisk/keys

Personalizar la dirección IP local del servidor B. Ahora se puede añadir el usuario server1 al archivo iax.conf

nano /etc/asterisk/iax.conf

Se añaden las siguientes lineas al final del archivo:

[server1]type=userdbsecret=dundi/secretcontext=servera-localqualify=yesdisallow=allallow=ulawallow=alaw

Importante definir el parámetro context con el valor del contexto que se ha definido en nuestra ruta (servera-local)

El ultimo archivo que hay que modificar es el dialplan:

nano /etc/asterisk/extensions.conf

Antes del contexto internas se define el contexto servera-local y se incluyen las rutas/extensiones que se quiere compartir con el servidor B

[servera-local]exten => 20,1,Answer()exten => 20,n,Playback(hello-world)

350

Page 362: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 20,n,Hangup()

Para las solicitudes remotas se crea otro contexto:

[dundi-remoto]switch => DUNDi/serverb

De esta forma cuando se marca un numero y ese numero no está presente en ningún contexto del dialplan, Asterisk consultará el servidor remoto con que tiene una conexión DUNDi. El nombre serverb es el contexto DUNDi que luego se creará en el archivo dundi.conf del Servidor Asterisk B

Añadimos el contexto dundi-remoto a la lista de contextos disponibles para la extensiones configuradas en el Servidor Asterisk A (en negrita los cambios):

[externas]include => internasinclude => internacioinclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

[locales]include => internas

include => auteninclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

Se guardan los cambios y se continúa con la configuración del Servidor Asterisk B

Servidor B

mv /etc/asterisk/dundi.conf /etc/asterisk/dundi.conf.old

nano /etc/asterisk/dundi.conf

Con los oportunos cambios, la configuración del servidor B será:

[general]department=EmpresaBorganization=EmpresaBlocality=Santa Martastateprov=Magdalenacountry=Colombiaemail=admin@servidorB.com

351

Page 363: Libro Asterisk 1.8.X - Versión 1.0 (1)

phone=+57XXXXXXXXbindaddr=0.0.0.0port=4520entityid=F2:3C:91:96:EC:A3cachetime=3600ttl=32autokill=yessecretpath=dundistorehistory=yes

[mappings]serverb => serverb-local,0,IAX2,server2:${SECRET}@192.168.182.236/${NUMBER}

[F2:3C:91:DF:5B:3E]model = symmetrichost = 192.168.129.142inkey = server1outkey = server2include = allpermit = serverbqualify = yes

IMPORTANTE: Personalizar los siguientes parámetros: entityid, la dirección IP local presente bajo la etiqueta [mappings],el mac address de la tarjeta del servidor B contenido entre corchetes y la dirección ip local del servidor B en host

Se crea la clave RSA para el servidor B:

cd /var/lib/asterisk/keys

astgenkey -n server2

This script generates an RSA private and public key pairin PEM format for use by Asterisk. You will be asked toenter a passcode for your key multiple times. Pleaseenter the same code each time. The resulting files willneed to be moved to /var/lib/asterisk/keys if you wantto use them, and any private keys (.key files) willneed to be initialized at runtime either by runningAsterisk with the '-i' option, or with the 'init keys'command once Asterisk is running.

Press ENTER to continue or ^C to cancel.

Generating SSL key 'server2':Generating RSA private key, 1024 bit long modulus............++++++

352

Page 364: Libro Asterisk 1.8.X - Versión 1.0 (1)

..........................++++++e is 65537 (0x10001)writing RSA keyKey creation successful.Public key: server2.pubPrivate key: server2.key

Se copia la clave publica en el Servidor Asterisk A

scp server2.pub [email protected]:/var/lib/asterisk/keys

Personalizar la dirección IP local del servidor A. Se crea el usuario IAX2

nano /etc/asterisk/iax.conf

[server2]type=userqualify=yesdbsecret=dundi/secretcontext=serverb-localdisallow=allallow=ulawallow=alaw

Para terminar se modifica el plan de llamadas:

nano /etc/asterisk/extensions.conf

[serverb-local]exten => 40,1,Answer()exten => 40,n,Playback(hello-world)exten => 40,n,Hangup()

[dundi-remoto]switch => DUNDi/servera

Se incluye el contexto dundi-remoto de forma que sea accesible a las extensiones:

[externas]include => internasinclude => internacioinclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

[locales]

353

Page 365: Libro Asterisk 1.8.X - Versión 1.0 (1)

include => internasinclude => auteninclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

Una vez terminada la configuración del Servidor Asterisk B en ambos se reinicia la PBX:

/etc/init.d/asterisk restart

Se entra en la consola del servidor Asterisk A:

asterisk -rvvvvvvvvvvvv

se mira la lista de comandos disponibles para DUNDi

CLI> help dundidundi flush [stats] Flush DUNDi cachedundi lookup Lookup a number in DUNDidundi precache Precache a number in DUNDidundi query Query a DUNDi EIDdundi set debug {on|off} Enable/Disable DUNDi debuggingdundi show entityid Display Global Entity IDdundi show mappings Show DUNDi mappingsdundi show peers [registered|i Show defined DUNDi peersdundi show peer Show info on a specific DUNDi peerdundi show precache Show DUNDi precachedundi show requests Show DUNDi requestsdundi show trans Show active DUNDi transactionsdundi store history {on|off} Enable/Disable DUNDi historic records

Se controla que haya conexión entre los dos servidores:

CLI> dundi show peersEID Host Port Model AvgTime Statusf2:3c:91:96:ec:a3 192.168.182.236 (S) 4520 Symmetric Unavail OK (1 ms)1 dundi peers [1 online, 0 offline, 0 unmonitored]

Con el comando:

CLI> database show/dundi/secret : qotQe+Vp1B2G7S9yoizlPA==;3obGb1QtvkUeciZs7rH5CA==/dundi/secretexpiry : 1259212403

aparecerá la clave creada por el modulo pbx_dundi y el tiempo que falta para que caduque.

354

Page 366: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora se puede hacer la primera consulta para controlar que efectivamente las rutas se están compartiendo:

CLI> dundi lookup 40@serverb 1. 0 IAX2/server2:[email protected]/40 (EXISTS|CANMATCH) from f2:3c:91:96:ec:a3, expires in 3600 sDUNDi lookup completed in 45 ms

En el servidor Asterisk B las extensión compartidas es la 40 y efectivamente enviando la solicitud, la respuesta es que la extensión existe. En el comando ademas de la extensión va indicado el contexto como se ha definido en el bloque mappings del dundi.conf del servidor Asterisk B.

Si se envía una solicitud para una ruta que no existe la respuesta será:

CLI> dundi lookup 20@serverbDUNDi lookup returned no results.DUNDi lookup completed in 3 ms

Se hace otra solicitud de prueba desde el Servidor Asterisk B

CLI> dundi lookup 20@servera 1. 0 IAX2/server1:[email protected]/20 (EXISTS|CANMATCH) from f2:3c:91:df:5b:3e, expires in 3600 sDUNDi lookup completed in 7 ms

Para terminar las pruebas se conecta un softphone al servidor Asterisk B y se intenta llamar la extensión 20 (que es presente en el servidor Asterisk A); luego desde una extensión del servidor A se marca el numero 40.

Como se ha podido ver, las potencialidades del protocolo DUNDi son realmente grandes. Este párrafo es una pequeña guía para que se pueda empezar a implementarlas.

18.4 Conectar dos servidores Asterisk con OpenVPN

Desde la versión 1.8.X es posible cifrar la señalización SIP y el flujo media. A pesar de la nueva implementación, todavía hay muchos problemas de compatibilidad entre Asterisk y las distintas marcas/modelos de teléfonos actualmente en el mercado. Por este motivo, en algunos casos, puede ser más funcional crear una red VPN entre servidores Linux y luego utilizarla para configurar troncales en Asterisk. En este párrafo se verá como instalar y configurar OpenVPN en dos servidores Asterisk y como crear una conexión VPN entre los dos.

Servidor A

Primero se instala LZO, una librería de compresión datos requerida por OpenVPN:

355

Page 367: Libro Asterisk 1.8.X - Versión 1.0 (1)

cd /usr/src

Se descarga:

wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz

Se descomprime y se instala:

tar -xf lzo-2.06.tar.gzcd lzo-2.06./configure --prefix=/usrmakemake install

Ahora se puede instalar la ultima versión disponible de OpenVPN:

cd /usr/src

se descarga:

wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz

se descomprime:

tar -xf openvpn-2.2.2.tar.gz

se entra en la carpeta creada:

cd openvpn-2.2.2

se compila:

./configuremakemake install

Se prepara el servidor Linux para crear las distintas claves (CA, servidor, cliente):

cd easy-rsa/2.0

Se crea la carpeta donde se guardarán las distintas claves:

mkdir /usr/local/sbin/keys

nano vars

356

Page 368: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se modifican las líneas que siguen. Esto datos serán los predefinidos que se usaran al momento de la generación de las claves. Personalizar los datos de los parametros que siguen:

export KEY_DIR=/usr/local/sbin/keys export KEY_COUNTRY="CO"export KEY_PROVINCE="MAG"export KEY_CITY="SantaMarta"export KEY_ORG="VozToVoice"export KEY_EMAIL="[email protected]"export [email protected]

Se guardan los cambios y se prepara el programa para la generación de las claves:

. ./vars

IMPORTANTE: entre el primer punto y el segundo hay un espacio

./clean-all

Ahora se puede empezar a generar las claves empezando con la CA (Certificate Authority):

./build-ca

Generating a 1024 bit RSA private key..++++++......++++++writing new private key to 'ca.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXACommon Name (eg, your name or your server's hostname) [changeme]:li44-242.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

En “Common Name” se pone el nombre de dominio de Linode o del servidor Linux que se está

357

Page 369: Libro Asterisk 1.8.X - Versión 1.0 (1)

utilizando. Se continua con la clave del servidor:

./build-key-server server

Generating a 1024 bit RSA private key..............++++++..............++++++writing new private key to 'server.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXACommon Name (eg, your name or your server's hostname) [server]:li44-242.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:Using configuration from /root/openvpn-2.2.1/easy-rsa/2.0/openssl-0.9.8.cnfCheck that the request matches the signatureSignature okThe Subject's Distinguished Name is as followscountryName :PRINTABLE:'CO'stateOrProvinceName :PRINTABLE:'Magdalena'localityName :PRINTABLE:'SantaMarta'organizationName :PRINTABLE:'VozToVoice'organizationalUnitName:PRINTABLE:'PBXA'commonName :PRINTABLE:'li44-242.members.linode.com'name :PRINTABLE:'voztovoice'emailAddress :IA5STRING:'[email protected]'Certificate is to be certified until Dec 10 14:16:09 2021 GMT (3650 days)Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entries

358

Page 370: Libro Asterisk 1.8.X - Versión 1.0 (1)

Data Base Updated

Para terminar se crea una clave para el cliente (el servidor Asterisk B):

./build-key clienteb

Generating a 1024 bit RSA private key.......++++++................................................++++++writing new private key to 'clienteb.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXACommon Name (eg, your name or your server's hostname) [clienteb]:li44-242.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:Using configuration from /root/openvpn-2.2.1/easy-rsa/2.0/openssl-0.9.8.cnfCheck that the request matches the signatureSignature okThe Subject's Distinguished Name is as followscountryName :PRINTABLE:'CO'stateOrProvinceName :PRINTABLE:'Magdalena'localityName :PRINTABLE:'SantaMarta'organizationName :PRINTABLE:'VozToVoice'organizationalUnitName:PRINTABLE:'PBXA'commonName :PRINTABLE:'li44-242.members.linode.com'name :PRINTABLE:'voztovoice'emailAddress :IA5STRING:'[email protected]'Certificate is to be certified until Dec 10 14:19:20 2021 GMT (3650 days)Sign the certificate? [y/n]:y

359

Page 371: Libro Asterisk 1.8.X - Versión 1.0 (1)

1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesData Base Updated

Si se tiene planeado utilizar la conexión para conectar telefonos IP y/o Softphone, se crean otras claves cliente. Se termina con la generación del parámetro Diffie Hellman

./build-dhGenerating DH parameters, 1024 bit long safe prime, generator 2This is going to take a long time

OpenVPN utiliza como puerto predefinido el 1194 (puede ser UDP o TCP según la configuración). Hay que abrirlo en Iptables solamente para la IP del servidor B. Suponiendo que la IP del servidor B es 66.228.49.216, se añaden las siguientes lineas en la configuración:

nano /etc/sysconfig/iptables

después de esta linea:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 15000 -j ACCEPT

se pone:

# OpenVPN-A INPUT -p tcp -m state --state NEW -m tcp -s 66.228.49.216 --dport 1194 -j ACCEPT-A INPUT -p udp -m udp -s 66.228.49.216 --dport 1194 -j ACCEPT

Se guardan los cambios y se reinicia iptables:

service iptables restart

Lo siguiente es instalar el script de arranque presente en las fuentes de OpenVPN:

cd /usr/src/openvpn-2.2.2/sample-scripts/

cp openvpn.init /etc/rc.d/init.d/openvpn

chkconfig --add openvpn

chkconfig openvpn on

Se crea la carpeta donde se guardarán los archivos de configuración de OpenVPN:

mkdir /etc/openvpn

Se crea el archivo de configuración para el servidor:

360

Page 372: Libro Asterisk 1.8.X - Versión 1.0 (1)

cd /etc/openvpn

nano server.conf

Se copian las siguientes lineas:

port 1194proto udpdev tunca /usr/local/sbin/keys/ca.crtcert /usr/local/sbin/keys/server.crtkey /usr/local/sbin/keys/server.keydh /usr/local/sbin/keys/dh1024.pemserver 10.8.0.0 255.255.255.0ifconfig-pool-persist ipp.txtkeepalive 10 120comp-lzomax-clients 30persist-keypersist-tunlog openvpn.loglog-append openvpn.logverb 3management localhost 7505

Para más informaciones sobre estos parámetros:

http://openvpn.net/index.php/open-source/documentation/howto.html#examples

Se guardan los cambios y se inicia OpenVPN

/etc/init.d/openvpn start

En la configuración de red del servidor aparecerá un nuevo dispositivo:

ifconfig

Servidor B

361

Page 373: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se sigue el mismo procedimiento para el servidor B:

cd /usr/src

Se descarga:

wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz

Se descomprime y se instala:

tar -xf lzo-2.06.tar.gzcd lzo-2.06./configure –prefix=/usrmakemake install

Ahora se puede instalar la ultima versión disponible de OpenVPN:

cd /usr/src

se descarga:

wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz

se descomprime:

tar -xf openvpn-2.2.2.tar.gz

se entra en la carpeta creada:

cd openvpn-2.2.2

se compila:

./configuremakemake install

Se prepara el servidor Linux para crear las distintas claves (CA, servidor, cliente):

cd easy-rsa/2.0

Se crea la carpeta donde se guardarán las distintas claves:

mkdir /usr/local/sbin/keys

nano vars

362

Page 374: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se modifican las líneas que siguen. Esto datos serán los que se usaran como predefinidos al momento de la generación de las claves. Personalizar los datos desde la segunda linea en adelante:

export KEY_DIR=/usr/local/sbin/keys export KEY_COUNTRY="CO"export KEY_PROVINCE="MAG"export KEY_CITY="SantaMarta"export KEY_ORG="VozToVoice"export KEY_EMAIL="[email protected]"export [email protected]

Se guardan los cambios y se prepara el programa para la generación de las claves:

. ./vars

IMPORTANTE: entre el primer punto y el segundo hay un espacio

./clean-all

Ahora se puede empezar a generar las claves empezando con la CA (Certificate Authority):

./build-ca

Generating a 1024 bit RSA private key.++++++....++++++writing new private key to 'ca.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXBCommon Name (eg, your name or your server's hostname) [changeme]:li212-33.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

363

Page 375: Libro Asterisk 1.8.X - Versión 1.0 (1)

En “Common Name” se pone el nombre de dominio de Linode o del servidor Linux que se está utilizando. Se continua con la clave del servidor:

./build-key-server server

Generating a 1024 bit RSA private key.++++++..++++++writing new private key to 'server.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXBCommon Name (eg, your name or your server's hostname) [server]:li212-33.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:Using configuration from /usr/src/openvpn-2.2.1/easy-rsa/2.0/openssl-0.9.8.cnfCheck that the request matches the signatureSignature okThe Subject's Distinguished Name is as followscountryName :PRINTABLE:'CO'stateOrProvinceName :PRINTABLE:'Magdalena'localityName :PRINTABLE:'SantaMarta'organizationName :PRINTABLE:'VozToVoice'organizationalUnitName:PRINTABLE:'PBXB'commonName :PRINTABLE:'li212-33.members.linode.com 'name :PRINTABLE:'voztovoice'emailAddress :IA5STRING:'[email protected]'Certificate is to be certified until Dec 10 15:13:18 2021 GMT (3650 days)Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

364

Page 376: Libro Asterisk 1.8.X - Versión 1.0 (1)

Write out database with 1 new entriesData Base Updated

Para terminar se crea una clave para el cliente (el servidor Asterisk B):

./build-key clientea

Generating a 1024 bit RSA private key..........++++++....++++++writing new private key to 'clientea.key'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [CO]:State or Province Name (full name) [Magdalena]:Locality Name (eg, city) [SantaMarta]:Organization Name (eg, company) [VozToVoice]:Organizational Unit Name (eg, section) [changeme]:PBXBCommon Name (eg, your name or your server's hostname) [clientea]:li212-33.members.linode.comName [changeme]:voztovoiceEmail Address [[email protected]]:

Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:Using configuration from /usr/src/openvpn-2.2.1/easy-rsa/2.0/openssl-0.9.8.cnfCheck that the request matches the signatureSignature okThe Subject's Distinguished Name is as followscountryName :PRINTABLE:'CO'stateOrProvinceName :PRINTABLE:'Magdalena'localityName :PRINTABLE:'SantaMarta'organizationName :PRINTABLE:'VozToVoice'organizationalUnitName:PRINTABLE:'PBXB'commonName :PRINTABLE:'li212-33.members.linode.com 'name :PRINTABLE:'voztovoice'emailAddress :IA5STRING:'[email protected]'Certificate is to be certified until Dec 10 15:15:37 2021 GMT (3650 days)Sign the certificate? [y/n]:y

365

Page 377: Libro Asterisk 1.8.X - Versión 1.0 (1)

1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesData Base Updated

Se termina con la generación del parámetro Diffie Hellman

./build-dhGenerating DH parameters, 1024 bit long safe prime, generator 2This is going to take a long time

Como para el servidor A, se abren los puertos en iptables para la IP del servidor A

nano /etc/sysconfig/iptables

# OpenVPN-A INPUT -p tcp -m state --state NEW -m tcp -s 69.164.201.178 --dport 1194 -j ACCEPT-A INPUT -p udp -m udp -s 69.164.201.178 --dport 1194 -j ACCEPT

Se guardan los cambios y se reinicia iptables:

service iptables restart

Lo siguiente es instalar el script de arranque presente en las fuentes de OpenVPN:

cd /usr/src/openvpn-2.2.2/sample-scripts/

cp openvpn.init /etc/rc.d/init.d/openvpn

chkconfig --add openvpn

chkconfig openvpn on

Se crea la carpeta donde se guardarán los archivos de configuración de OpenVPN:

mkdir /etc/openvpn

Se crea el archivo de configuración para el servidor:

cd /etc/openvpn

nano server.conf

Se copian las siguientes lineas:

port 1194proto udp

366

Page 378: Libro Asterisk 1.8.X - Versión 1.0 (1)

dev tunca /usr/local/sbin/keys/ca.crtcert /usr/local/sbin/keys/server.crtkey /usr/local/sbin/keys/server.keydh /usr/local/sbin/keys/dh1024.pemserver 10.10.0.0 255.255.255.0ifconfig-pool-persist ipp.txtkeepalive 10 120comp-lzomax-clients 30persist-keypersist-tunlog openvpn.loglog-append openvpn.logverb 3management localhost 7505

Se guardan los cambios. La diferencia con el archivo del Servidor A es que se utiliza otro rango de IP local. Se inicia OpenVPN

/etc/init.d/openvpn start

En la configuración de red del servidor aparecerá un nuevo dispositivo:

ifconfig

Ahora que los dos servidores están configurados, hay que crear una conexión cliente en cada uno. Para eso hay que copiar las siguientes claves de un servidor a otro:

Servidor A → Servidor B:

• ca.crt• clienteb.crt• clienteb.key•

La claves se copian en la carpeta /etc/openvpn del servidor B.

Servidor B → Servidor A:

367

Page 379: Libro Asterisk 1.8.X - Versión 1.0 (1)

• ca.crt• clientea.crt• clientea.key

La claves se copian en la carpeta /etc/openvpn del servidor A.

Ahora en el servidor A se crea el archivo de configuración cliente para conectarse al servidor B:

cd /etc/openvpn

nano client.conf

se copian las siguientes lineas:

clientdev tunproto udpremote 66.228.49.216 1194resolv-retry infinitenobindpersist-keypersist-tunca /etc/openvpn/ca.crtcert /etc/openvpn/clientea.crtkey /etc/openvpn/clientea.keycomp-lzoverb 3ns-cert-type serverroute-method exeroute-delay 2

En la linea 4 se pone la dirección IP del servidor B y el puerto (1194). Se guardan los cambios y se reinicia OpenVPN:

service openvpn restart

Si todo ha salido bien, tendremos un nuevo dispositivo de red:

368

Page 380: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para que las llamadas puedan ser enrutadas correctamente por Asterisk, hay que añadir estas dos nuevas redes en la configuración del sip.conf:

nano /etc/asterisk/sip.conf

Después del primer parámetro localnet se añade:

localnet=10.8.0.0/255.255.255.0localnet=10.10.0.0/255.255.255.0

Se recarga la configuración SIP:

asterisk -rx "sip reload"

Se sigue el mismo procedimiento para el servidor B:

cd /etc/openvpn

nano client.conf

se copian las siguientes lineas:

clientdev tunproto udpremote 96.126.125.112 1194resolv-retry infinitenobindpersist-keypersist-tunca /etc/openvpn/ca.crtcert /etc/openvpn/clienteb.crtkey /etc/openvpn/clienteb.keycomp-lzoverb 3ns-cert-type server

369

Page 381: Libro Asterisk 1.8.X - Versión 1.0 (1)

route-method exeroute-delay 2

Se guardan los cambios y se reinicia OpenVPN:

service openvpn restart

Si todo ha salido bien, tendremos un nuevo dispositivo de red:

Para que las llamadas puedan ser enrutadas correctamente por Asterisk, hay que añadir estas dos nuevas redes en la configuración del sip.conf:

nano /etc/asterisk/sip.conf

Después del primer parámetro localnet se añade:

localnet=10.8.0.0/255.255.255.0localnet=10.10.0.0/255.255.255.0

Se recarga la configuración SIP:

asterisk -rx "sip reload"

Una vez terminada la configuración y la conexión OpenVPN entre los dos servidores, se crea una nueva troncal SIP entre los dos. Esta vez utilizando la autentificación por IP. Para crear la troncal podemos utilizar o el rango de IP 10.8.0.1 o el rango de IP 10.10.0.1

Servidor A

nano /etc/asterisk/sip.conf

al final del archivo se pone:

[serverbvpn]

370

Page 382: Libro Asterisk 1.8.X - Versión 1.0 (1)

type=peercontext=vpnhost=10.8.0.6disallow=allallow=g729allow=alawlanguage=esqualify=yesdtmfmode = rfc2833

Importante destacar la dirección IP VPN del servidor B en el parámetro host y el contexto (vpn). Se guarda los cambios y se pasa al servidor B.

Servidor B

nano /etc/asterisk/sip.conf

al final del archivo se pone:

[serveravpn]type=peercontext=vpnhost=10.8.0.1disallow=allallow=g729allow=alawlanguage=esqualify=yesdtmfmode = rfc2833

Se recarga la configuración SIP en ambos servidores:

asterisk -rx "sip reload"

Se entra en la consola de ambos servidores y se averigua que la conexión este funcionando:

asterisk -rvvvvvvvvvv

Servidor A:

CLI> sip show peers like serverbvpnName/username Host Dyn Nat ACL Port Status Realtimeserverbvpn 10.8.0.6 N 5060 OK (2 ms)1 sip peers [Monitored: 1 online, 0 offline Unmonitored: 0 online, 0 offline]

Servidor B:

371

Page 383: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> sip show peers like serveravpnName/username Host Dyn Nat ACL Port Status Realtimeserveravpn 10.8.0.1 N 5060 OK (2 ms)1 sip peers [Monitored: 1 online, 0 offline Unmonitored: 0 online, 0 offline]

Perfecto!!

Para probar las llamadas entre los servidores, utilizando la red OpenVPN, se modifica el dialplan acordándose que el contexto que se ha definido en la troncal es vpn. Como para la prueba con la conexión entre servidores Asterisk con el protocolo SIP, hay que “engañar” Asterisk para que acepte la llamada ya que las extensiones configuradas en los dos servidores son las mismas. En el caso de servidores con números de extensiones distintas, no hace falta añadir la linea donde se modifica el CALLERID

Servidor A

nano /etc/asterisk/extensions.conf

antes del contexto internas, se crea el nuevo contexto vpn y se añaden las siguientes lineas:

[vpn]exten => 70,1,Answersame => n,Playback(demo-congrats)same => n,Hangup

y en el contexto internas se pone:

exten => 70,1,Set(CALLERID(num)=openvpna)same => n,Dial(SIP/serverbvpn/${EXTEN})same => n,hangup

Servidor B

nano /etc/asterisk/extensions.conf

antes del contexto internas, se crea el nuevo contexto vpn y se añaden las siguientes lineas:

[vpn]exten => 70,1,Answersame => n,Playback(demo-congrats)same => n,Hangup

y en el contexto internas se pone:

exten => 70,1,Set(CALLERID(num)=openvpnb)same => n,Dial(SIP/serveravpn/${EXTEN})same => n,hangup

372

Page 384: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios en ambos servidores y se recarga el dialplan

asterisk -rx "dialplan reload"

Para terminar, se hace una prueba marcando desde la extensión 1000 del servidor A la extensión 70. En la consola de Asterisk de servidor A debería aparecer:

Executing [70@externas:1] NoOp("SIP/1000-00000045", "") in new stackExecuting [70@externas:2] Set("SIP/1000-00000045", "CALLERID(num)=openvpna") in new stack -- Executing [70@externas:3] NoOp("SIP/1000-00000045", "openvpna") in new stack -- Executing [70@externas:4] Dial("SIP/1000-00000045", "SIP/serverbvpn/70") in new stack == Using SIP RTP CoS mark 5 == Using SIP VRTP CoS mark 6 == Using UDPTL CoS mark 5 -- Called serverbvpn/70 -- SIP/serverbvpn-00000046 answered SIP/1000-00000045

La comodidad de tener las dos redes VPN es que se pueden configurar otros clientes OpenVPN en los computadores donde tenemos instalados los SoftPhone o los teléfonos que soportan este protocolo (ejemplo Yealink desde el modelo T26 para arriba).

18.5 Conectar dos Servidores Asterisk con TLS y SRTP

En esta parte se verá como configurar una conexión SIP entre dos servidores Asterisk y utilizar el protocolo TLS para la señalización SIP y el cifrado media con el protocolo SRTP.

Primero hay que crear los certificados para el servidor A y el servidor B. Esto se hace con una utilidad presente en las fuentes de Asterisk. Desde el servidor A:

mkdir /etc/asterisk/keys

Primero se crea el certificado CA y el certificado para el servidorA:

cd /usr/src/asterisk-1.8.11.0/contrib/scripts

./ast_tls_cert -d certs -C li374-112.members.linode.com -o serverA

No config file specified, creating 'certs/tmp.cfg'You can use this config file to create additional certs withoutre-entering the information for the fields in the certificateCreating certs/ca.keyGenerating RSA private key, 4096 bit long modulus..........++.....................................++e is 65537 (0x10001)

373

Page 385: Libro Asterisk 1.8.X - Versión 1.0 (1)

Enter pass phrase for certs/ca.key:Verifying - Enter pass phrase for certs/ca.key:Creating certs/ca.crtEnter pass phrase for certs/ca.key:Creating certs/serverA.keyGenerating RSA private key, 1024 bit long modulus...............++++++....++++++e is 65537 (0x10001)Creating signing requestCreating certs/serverA.crtSignature oksubject=/CN=li374-112.members.linode.com/O=AsteriskGetting CA Private KeyEnter pass phrase for certs/ca.key:Combining key and crt into certs/serverA.pem

En la opción -C se pone el nombre de dominio del servidor y cuando el script lo pide se ingresa una contraseña (por ejemplo servera)

Luego se crea el certificado para el servidorB

./ast_tls_cert -d certs -C li291-216.members.linode.com -o serverB

No config file specified, creating 'certs/tmp.cfg'You can use this config file to create additional certs withoutre-entering the information for the fields in the certificateCreating certs/ca.keyGenerating RSA private key, 4096 bit long modulus........................++.............................................................................................................................................................................................................................++e is 65537 (0x10001)Enter pass phrase for certs/ca.key:Verifying - Enter pass phrase for certs/ca.key:Creating certs/ca.crtEnter pass phrase for certs/ca.key:Creating certs/serverB.keyGenerating RSA private key, 1024 bit long modulus....................++++++..................................++++++e is 65537 (0x10001)Creating signing requestCreating certs/serverB.crtSignature oksubject=/CN=li291-216.members.linode.com/O=AsteriskGetting CA Private Key

374

Page 386: Libro Asterisk 1.8.X - Versión 1.0 (1)

Enter pass phrase for certs/ca.key:Combining key and crt into certs/serverB.pem

Cuando el script pide la contraseña, se pone la misma que se ha utilizado para crear las claves del servidorA (servera)

Ahora se copian los siguientes archivos en la carpeta /etc/asterisk/keys del servidorA:

cd certs

cp ca.crt /etc/asterisk/keys/cp serverA.pem /etc/asterisk/keys/

Para terminar se modifica la configuración del archivo sip.conf para activar el protocolo TLS y se crea la troncal para el servidorB con autentificación sobre IP:

nano /etc/asterisk/sip.conf

al final de la parte general se pone:

tlsenable=yestlsbindaddr=96.126.125.112tlscertfile=/etc/asterisk/keys/serverA.pemtlscafile=/etc/asterisk/keys/ca.crttlscapath=/etc/asterisk/keystlsdontverifyserver=yes

en tlsbindaddr se pone la dirección IP del servidorA

al final del archivo se configura la troncal para el servidorB

[serverbtls]type=peercontext=from-tlshost=66.228.49.216disallow=allallow=alawlanguage=esqualify=yestransport=tlsencryption=yes

Los parámetros importantes:

• context: nombre del contexto donde entrarán las llamadas del servidoB

375

Page 387: Libro Asterisk 1.8.X - Versión 1.0 (1)

• host: la dirección IP del servidorB• transport: de define como trasporte de la señalización SIP el protocolo TLS• encryption: se activa el cifrado del flujo media (protocolo SRTP)

El protocolo TLS en Asterisk, utiliza el puerto predefinido 5061 TCP. Hay que abrirlo en el firewall para la IP del servidorB

nano /etc/sysconfig/iptables

después de esta linea:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT

se pone:

-A INPUT -p tcp -m state --state NEW -m tcp -s 66.228.49.216 --dport 5061 -j ACCEPT

Se guardan los cambios y se reinicia iptables:

service iptables restart

En el dialplan se crea el nuevo contexto antes del contexto internas:

nano /etc/asterisk/extensions.conf

[from-tls]exten => 71,1,Answersame => n,Noop(TLS = ${CHANNEL(secure_signaling)}, SRTP = ${CHANNEL(secure_media)})same => n,Playback(tt-monkeys)same => n,Hangup

Con la segunda linea se lee la variable CHANNEL para el cifrado de la señalización y del flujo media. Si el valor es 1 significa que se están utilizando, si el valor es 0, significa que no están activos en el canal en uso.

En el contexto internas se añade.

exten => 71,1,Set(CALLERID(num)=serveratls)same => n,Dial(SIP/serverbtls/${EXTEN})same => n,hangup

Servidor B

Se crea la carpeta para los certificados:

376

Page 388: Libro Asterisk 1.8.X - Versión 1.0 (1)

mkdir /etc/asterisk/keys

Se vuelve al servidor A y se copian las dos claves:

scp ca.crt [email protected]:/etc/asterisk/keysscp serverB.pem [email protected]:/etc/asterisk/keys

Esto suponiendo que la IP publica del servidorB sea 66.228.49.216

Se abre el archivos sip.conf:

nano /etc/asterisk/sip.conf

y al final de la parte general se pone:

tlsenable=yestlsbindaddr=66.228.49.216tlscertfile=/etc/asterisk/keys/serverB.pemtlscafile=/etc/asterisk/keys/ca.crttlscapath=/etc/asterisk/keystlsdontverifyserver=yes

en tlsbindaddr se pone la dirección IP del servidorB. Al final del archivo se configura la troncal para el servidorA:

[serveratls]type=peercontext=from-tlshost=96.126.125.112disallow=allallow=alawlanguage=esqualify=yestransport=tlsencryption=yes

Se abre el puerto 5061 TCP en el firewall para la IP del servidorA

nano /etc/sysconfig/iptables

después de esta linea:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT

se pone:

-A INPUT -p tcp -m state --state NEW -m tcp -s 96.126.125.112 --dport 5061 -j ACCEPT

377

Page 389: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se reinicia iptables:

service iptables restart

Se pasa al dialplan:

nano /etc/asterisk/extensions.conf

Antes del contexto internas se pone:

[from-tls]exten => 71,1,Answersame => n,Noop(TLS = ${CHANNEL(secure_signaling)}, SRTP = ${CHANNEL(secure_media)})same => n,Playback(tt-monkeys)same => n,Hangup

En el contexto internas se pone:

exten => 71,1,Set(CALLERID(num)=serverbtls)same => n,Dial(SIP/serveratls/${EXTEN})same => n,hangup

Se guardan los cambios y se recarga la configuración de ambos servidores:

service asterisk reload

Se averigua en el servidorA que el servidorB esté conectado:

asterisk -rvvvvvvvvvvvvvvv

CLI> sip show peersserverbtls 66.228.49.216 N 5061 OK (1 ms)

Se hace la misma operación en el servidorB:

CLI> sip show peersserveratls 96.126.125.112 N 5061 OK (2 ms)

Ahora desde la extensión 1000 del servidorA se marca el numero 71 y se mira que pasa en la consola de ambos servidores:

Servidor A:

Executing [71@externas:1] Set("SIP/1000-00000022", "CALLERID(num)=serveratls") in new stack -- Executing [71@externas:2] Dial("SIP/1000-00000022", "SIP/serverbtls/71") in new stack

378

Page 390: Libro Asterisk 1.8.X - Versión 1.0 (1)

Servidor B:Executing [71@from-tls:1] Answer("SIP/serveratls-00000015", "") in new stack -- Executing [71@from-tls:2] NoOp("SIP/serveratls-00000015", "TLS = 1, SRTP = 1") in new stack -- Executing [71@from-tls:3] Playback("SIP/serveratls-00000015", "tt-monkeys") in new stack -- <SIP/serveratls-00000015> Playing 'tt-monkeys.ulaw' (language 'es') -- Executing [71@from-tls:4] Hangup("SIP/serveratls-00000015", "") in new stack

Como se puede ver en la consola del servidorB la llamada que llega tiene activado el protocolo TLS (1) y el protocolo SRTP(1). Esto quiere decir que la señalización y el flojo media serán cifrados.

Otra forma de averiguarlo es activar con Ngrep la captura en el puerto 5061 en uno de los dos servidores:

ngrep -W byline port 5061

Aparecerán puros bloques cifrados.

379

Page 391: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 392: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XIX

AMI y AGI

19.1 AMI (Asterisk Manager Interface)

AMI (Asterisk Manager Interface) es una interfaz de monitoreo y gestión que interactúa con la PBX recibiendo eventos y/o enviando acciones que el sistema ejecutará. Para conectarse a la AMI como cliente, se puede utilizar un socket TCP (puerto predefinido 5038) o el protocolo HTTP (puerto predefinido 8088). El AMI se configura en el archivo de configuración manager.conf y en el caso que se quiera utilizar también el protocolo HTTP, el archivo http.conf.

En la tabla a seguir se indicarán los parámetros que se van a configurar con una breve descripción. En negrita los valores de cada parámetro. Al final de la tabla, la configuración completa del archivo.

Parámetro Descripción[general] Etiqueta que indica el inicio de la configuración general del

archivoenabled yes – Se activa el acceso a la AMIwebenabled yes = se activa el acceso a la AMI vía HTTPport 5038 – el puerto predefinido para la conexión a la AMI de

Asterisk vía TCPbindaddr Dirección IP donde la AMI aceptará conexiones. Valor 0.0.0.0

todas las direcciones IP presentes en el servidor;tlsenable=no;tlsbindport=5039;tlsbindaddr=0.0.0.0 ;tlscertfile=/tmp/asterisk.pem ;tlsprivatekey=/tmp/private.pem

Es posible configurar la AMI para que utilice el protocolo TLS. Este tipo de configuración es aconsejado en el caso que se permita el acceso a la interfaz desde remoto. Los parámetros presentes son parecidos a la configuración del protocolo TLS en el archivo sip.conf. Se dejan comentados.

allowmultiplelogin Este parámetro define si por un usuario configurado en este archivo se aceptan una o más conexiones simultaneas. Valor yes

displayconnects yes – En la consola de Asterisk cada vez que un usuario configurado en el manager.conf se conecte o se desconecte aparecerá una linea que lo notificará.

timestampevents yes – añade una fecha en formato EPOCH para cada evento;channelvars = var1,var2,var3 permite configurar unas variables que aparecerán cada vez que

se genere un evento relacionado con un canal. De deja comentado

debug no – no se activa el debug de la AMI de forma predefinida. Es posible activarlo y desactivarlo en cualquier momento desde la

Page 393: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónconsola de Asterisk

authtimeout es el tiempo, expresado en segundos, que tiene un cliente para autenticarse. Valor 60

authlimit define el numero máximo de sesiones simultaneas no autenticadas que aceptará la AMI. Valor: 20

httptimeout define tres condiciones:1. el tiempo máximo de vida del cookie http generado por

la AMI2. el tiempo que esperará el servidor web de la AMI al

recibir una acción de tipo “waitevent” antes de cerrar la solicitud

3. tiempo que la AMI esperará antes de cerrar la sesión con un cliente después de haber enviado una respuesta a la solicitud recibida

Valor: 60[admin] a partir de esta etiqueta se define el primer usuario que tendrá

acceso a la AMI de Asterisk. El valor entre corchetes es el nombre del usuario.

secret La contraseña que el usuario utilizará para conectarse a la AMI de Asterisk. Utilizar siempre contraseñas fuertes. Para esta configuración de prueba el valor es sesamo

deny con este parámetro se define un rango de IP que no podrán acceder a la AMI de Asterisk con las credenciales del usuario configurado. Valor 0.0.0.0/0.0.0.0 (todas)

permit con este parámetro se define un rango de IP que tendrán acceso a la AMI de Asterisk con las credenciales del usuario configurado. Valor 127.0.0.1/255.255.255.255 En este caso solamente desde local.

;eventfilter=Event: Newchannel;eventfilter=!Channel: DAHDI*

El parámetro eventfilter permite filtrar los eventos que recibirá el usuario una vez que esté conectado a la AMI de Asterisk. Para los eventos se pueden crear dos tipos de configuraciones:

1. si el nombre del evento no empieza con un punto exclamativo, el tipo de evento se enviará

2. si el nombre del evento empieza con un punto exclamativo, se filtrará y no será enviado al cliente conectado a la AMI de Asterisk

Se dejan comentadas.writetimeout Valor en mili segundos que esperará Asterisk para enviar los

datos al cliente conectado a la AMI. Se utiliza en el caso que el cliente pierda la conexión con la AMI. Valor: 100

382

Page 394: Libro Asterisk 1.8.X - Versión 1.0 (1)

Una vez configurado el usuario, falta definir los permisos que el mismo usuario tendrá al conectarse con la AMI de Asterisk. Estos permisos son de dos tipos:

• lectura• escritura

En la tabla que sigue la lista completa y el significado de cada uno de ellos:

Parámetro Read Writeall El usuario puede leer todos los eventos de

la AMIEl usuario tiene acceso a todas las acciones de la AMI

system El usuario recibe todos los eventos relacionados con el funcionamiento de la PBX

El usuario puede enviar acciones de sistema (reiniciar la PBX, recargar la configuración, etc)

call Permite al usuario recibir informaciones relacionadas con los canales de la PBX

Permite al usuario modificar, crear canales en la PBX

agent permite al usuario acceder a todos los datos relacionados con las colas de espera y los agentes

Permite al usuario enviar acciones para gestionar y monitorear el estado de las colas y los agentes

user Recibe eventos relacionados con las extensiones y los usuarios Jabber (XMPP)

Permite generar eventos relacionados con las extensiones configuradas

config Solo escritura Permite al usuario leer, actualizar y recargar los archivos de configuración de Asterisk

command Solo escritura Permite al usuario ejecutar comandos de la consola de Asterisk

DTMF permite al usuario recibir los eventos relacionados con los tonos

Solo lectura

reporting permite al usuario recibir reportes de la calidad de las llamadas

permite al usuario ejecutar acciones para recibir estadísticas y reportes del sistema

cdr permite al usuario recibir eventos relacionados con el registro de las llamadas según la configuración del archivo cdr_manager.conf

Solo lectura

dialplan permite al usuario recibir eventos cuando se modifica una variable o se crea una nueva extensión en el dialplan

Solo lectura

originate Solo escritura Permite al usuario crear una nueva llamada utilizando la acción Originate de la AMI

383

Page 395: Libro Asterisk 1.8.X - Versión 1.0 (1)

agi permite al usuario recibir eventos generados por la ejecución de un AGI

Permite al usuario generar acciones para la gestión de los canales creados por un AGI en modo asíncrono

cc permite al usuario recibir eventos relacionados con el sistema CCSS (rellamada)

Solo lectura

aoc permite al usuario recibir eventos relacionados con AOC (advice of charge) es decir el costo de la llamada corrienteMás Informaciones en la wiki de Asterisk

permite al usuario generar un mensaje AOC para una determinada llamada.

Ahora se puede crear el archivo manager.conf. Se renombra el predefinido:

mv /etc/asterisk/manager.conf /etc/asterisk/manager.conf.old

se crea uno nuevo:

nano /etc/asterisk/manager.conf

y se copian las siguientes lineas:

[general]enabled=yeswebenabled=yesport=5038bindaddr=0.0.0.0;tlsenable=no;tlsbindport=5039;tlsbindaddr=0.0.0.0 ;tlscertfile=/tmp/asterisk.pem ;tlsprivatekey=/tmp/private.pemallowmultiplelogin=yesdisplayconnects=yestimestampevents=yes;channelvars = var1,var2,var3debug=noauthtimeout=60authlimit=20httptimeout=60

[admin]secret=sesamodeny=0.0.0.0/0.0.0.0permit=127.0.0.1/255.255.255.255;eventfilter=Event: Newchannel

384

Page 396: Libro Asterisk 1.8.X - Versión 1.0 (1)

;eventfilter=!Channel: DAHDI*writetimeout=100read=system,call,agent,user,dtmf,reporting,cdr,dialplan,agi,cc,aocwrite=system,call,agent,user,config,command,reporting,otiginate,agi,aoc

En las dos lineas read y write, se ponen todos los valores posibles. Se guardan los cambios y se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvv

Los comandos relacionados con la AMI de Asterisk:

CLI> help manager manager reload Reload manager configurations manager set debug [on|off] Show, enable, disable debugging of the manager code manager show command Show a manager interface command manager show commands List manager interface commands manager show connected List connected manager interface users manager show eventq List manager interface queued events manager show settings Show manager global settings manager show users List configured manager users manager show user Display information on a specific manager user

Primero se recarga la configuración:

CLI> manager reload

luego se controla que el usuario configurado aparezca::

CLI> manager show users

username--------admin-------------------1 manager users configured.

El usuario admin está presente. Con el comando:

CLI> manager show commands

aparecerá una lista de todos los comandos que se pueden utilizar desde la AMI de Asterisk. Por cada comando, en la columna Privilege, aparecen los privilegios que se necesitan para ejecutarlo. Entre ellos está el comando Login que permite conectarse a la AMI de Asterisk y es el que se utilizará para hacer la primera prueba. Para conocer la sintaxis:

CLI> manager show command Login

385

Page 397: Libro Asterisk 1.8.X - Versión 1.0 (1)

[Syntax]Action: Login[ActionID:] <value>Username: <value>[Secret:] <value>

[Synopsis]Login Manager.

[Description]Login Manager.

[Arguments]ActionID ActionID for this transaction. Will be returned.Username Username to login with as specified in manager.conf.Secret Secret to login with as specified in manager.conf.

[See Also]Not available

Para conectarse a la AMI de Asterisk se utilizará el programa Telnet. Se abre otra consola de Linux y se instala telnet:

yum install telnet

Se inicia el programa:

telnet

y se crea la conexión a la AMI de Asterisk:

telnet> o localhost 5038

Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Asterisk Call Manager/1.1

Action: Login Username: adminSecret: sesamoEvents: Off

Después de cada linea, para pasar a la siguiente se presiona la tecla envío. Después de la ultima linea la

386

Page 398: Libro Asterisk 1.8.X - Versión 1.0 (1)

tecla envío se presiona dos veces. El resultado será:

Response: SuccessMessage: Authentication accepted

Para salir de la AMI:

Action: Logoff

Response: GoodbyeMessage: Thanks for all the fish.

Connection closed by foreign host.

En la consola de Asterisk aparecerá:

== Manager 'admin' logged on from 127.0.0.1 == Manager 'admin' logged off from 127.0.0.1

Otra prueba que se se puede hacer es ver la configuración de la extensión 1000

telnet

telnet> o localhost 5038Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Asterisk Call Manager/1.1

Action: LoginUsername: adminSecret: sesamoEvents: On

Response: SuccessMessage: Authentication accepted

Event: FullyBootedPrivilege: system,allStatus: Fully Booted

En este caso, con Events:On, se activa la recepción de todos los eventos generados por la AMI. Luego se ejecuta la acción para ver la configuración de la extensión 1000

Action: SIPshowpeerPeer: 1000

387

Page 399: Libro Asterisk 1.8.X - Versión 1.0 (1)

Response: SuccessChanneltype: SIPObjectName: 1000ChanObjectType: peerSecretExist: YRemoteSecretExist: NMD5SecretExist: NContext: externasLanguage: esAccountcode: 1000AMAflags: UnknownCID-CallingPres: Presentation Allowed, Not ScreenedCallgroup: 1Pickupgroup: 1MOHSuggest: defaultVoiceMailbox: 1000@defaultTransferMode: openLastMsgsSent: -1Maxforwards: 0Call-limit: 2Busy-level: 0MaxCallBR: 384 kbpsDynamic: YCallerid: "callerid=Fulano" <1000>RegExpire: -1 secondsSIP-AuthInsecure: noSIP-Forcerport: YACL: NSIP-CanReinvite: NSIP-DirectMedia: NSIP-PromiscRedir: NSIP-UserPhone: NSIP-VideoSupport: YSIP-TextSupport: NSIP-T.38Support: YSIP-T.38EC: FECSIP-T.38MaxDtgrm: 400SIP-Sess-Timers: AcceptSIP-Sess-Refresh: uasSIP-Sess-Expires: 1800SIP-Sess-Min: 90SIP-RTP-Engine: asteriskSIP-Encryption: NSIP-DTMFmode: rfc2833ToHost:Address-IP: (null)Address-Port: 0

388

Page 400: Libro Asterisk 1.8.X - Versión 1.0 (1)

Default-addr-IP: (null)Default-addr-port: 0Default-Username: 1000Codecs: 0x8010c (ulaw|alaw|g729|h263)CodecOrder: alaw,ulaw,g729Status: UNKNOWNSIP-Useragent: X-Lite 4 release 4.1 stamp 63214Reg-Contact: sip:[email protected]:13642;rinstance=c25bb0cf558f37bbQualifyFreq: 60000 msParkinglot:SIP-Use-Reason-Header: Y

Action: Logoff

Connection closed by foreign host.

Una ultima prueba es conectarse a la AMI y mirar cuales eventos se generan a lo largo de una llamada entre la extensión 1000 y la extensión 1001:

telnet localhost 5038Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Asterisk Call Manager/1.1

Action: LoginUsername: adminSecret: sesamoEvents: On

Response: SuccessMessage: Authentication accepted

Event: FullyBootedPrivilege: system,allStatus: Fully Booted

Una vez conectado a la AMI desde la extensión 1000 se llama la extensión 1001 y se mira lo que aparece en la consola de Linux. Se verán toda una serie de informaciones relacionadas con la llamada; además aparecerán los eventos relacionados con el CCSS. Ya se puede salir de la AMI:

Action:Logoff

Response: GoodbyeMessage: Thanks for all the fish.

389

Page 401: Libro Asterisk 1.8.X - Versión 1.0 (1)

Connection closed by foreign host.

Claramente utilizar la AMI de esta forma es poco practico. Normalmente se hace escribiendo código en distintos lenguajes de programación, desde script bash hasta script en Ruby. De hecho existen muchas librerías que simplifican está operación: Entre ellas:

• PHP: PHPagi • Python: Starpy• Perl: Asterisk-perl• Java: Asterisk-java• Ruby: Adhearsion

Como se ha dicho al inicio de este párrafo, es posible interactuar con la AMI de Asterisk vía HTTP. De hecho hay soluciones que utilizan este tipo de conexión. Entre ellas hay que citar la GUI para Asterisk de Digium, cuya instalación se explicará en el capitulo XXVI, y FOP2 (Flash Operator Panel 2) que es un sistema que permite monitorear las actividad de las llamadas de Asterisk y al mismo tiempo efectuar algunas acciones entre las cuales: transferir una llamada, espiar una llamada, ver la actividad de una cola.

19.2 AGI (Asterisk Gateway Interface)

El Asterisk Gateway Interface (AGI) permite desarrollar aplicaciones externas que pueden interactuar con Asterisk. Estas aplicaciones pueden estar escritas en distintos lenguajes de programación y de hecho existen librerías en Perl, PHP, Python, Ruby que simplifican su escritura. Como para la AMI, también para el AGI es posible conocer los comandos disponibles desde la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvv

y se escribe:

CLI> help agi agi dump html Dumps a list of AGI commands in HTML format agi exec Add AGI command to a channel in Async AGI agi set debug [on|off] Enable/Disable AGI debugging agi show commands [topic] List AGI commands or specific help

Para una lista de los comandos que se pueden utilizar en un AGI:

CLI> agi show commands

¿Cómo Funciona?

La comunicación entre Asterisk y el AGI se apoya a los “files descriptors” del sistema operativo Linux que permiten una comunicación entre el Kernel y la aplicación que quiere acceder a un determinado archivo/programa. En Linux. Los tres estándar que se utilizan son:

390

Page 402: Libro Asterisk 1.8.X - Versión 1.0 (1)

• STDIN• STDOUT• STDERR

Visto de forma gráfica:

Esto permite, como ya se ha dicho, escribir el AGI utilizando prácticamente cualquier lenguaje de programación. Para los ejemplos a seguir, se utilizarán la librería PHPAGI y PHP. Para PHPAGI, primero se instala php:

yum install php-*

luego de descarga la librería:

cd /usr/src

wget http://downloads.sourceforge.net/project/phpagi/phpagi/2.20/phpagi-2.20.tgz

Se descomprime:

tar -xf phpagi-2.20.tgz

se entra en la carpeta creada:

cd phpagi-2.20

y se copian las dos librerías para AGI en la carpeta de agi-bin de Asterisk:

cp phpagi.php /var/lib/asterisk/agi-bincp phpagi-asmanager.php /var/lib/asterisk/agi-bin

391

Page 403: Libro Asterisk 1.8.X - Versión 1.0 (1)

se vuelven los archivos ejecutables:

chmod 755 /var/lib/asterisk/agi-bin/phpagi.phpchmod 755 /var/lib/asterisk/agi-bin

PHPAGI se apoya a un archivo de configuración que hay que crear en la carpeta /etc/asterisk.

nano /etc/asterisk/phpagi.conf

se copian las siguientes lineas:

[phpagi][email protected]=li374-112.members.linode.comtempdir=/var/spool/asterisk/tmp/

[asmanager]server=localhostport=5038username=adminsecret=sesamo

[fastagi]setuid=truebasedir=/var/lib/asterisk/agi-bin/

[festival]text2wave=/usr/bin/text2wave

El primer bloque del archivo es dedicado al la configuración de PHPAGI para la ejecución de script AGI.

En en segundo bloque [asmanager], se configura los datos de acceso a la AMI de Asterisk para el usuario admin anteriormente creado.

El tercer bloque es para la configuración de FastAGI (cuando se ejecutan los script AGI sobre una conexión TCP)

Por ultimo, para utilizar Festival como sistema de texto a voz, se indica la ubicación del archivo text2wave.

Se guardan los cambios y se crea el primer AGI:

nano /var/lib/asterisk/agi-bin/pruebaudio.php

392

Page 404: Libro Asterisk 1.8.X - Versión 1.0 (1)

#!/usr/bin/php -q<?php require('phpagi.php'); error_reporting(E_ALL); $agi = new AGI(); $agi-> answer(); $agi-> stream_file('demo-congrats'); $agi-> hangup();?>

Se vuelve ejecutable el archivo:

chmod +x /var/lib/asterisk/agi-bin/pruebaudio.php

Se modifica el dialplan para añadir el AGI:

nano /etc/asterisk/extensions.conf

en el contexto internas se añade:

exten => 250,1,Agi(pruebaudio.php)same => n,Hangup

Se guardan los cambios, se entra en la consola de Asterisk y se recarga el dialplan:

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

la sintaxis de la aplicación AGI:

CLI> core show application agi[Syntax]AGI(command[,arg1[,arg2[,...]]])

Desde la extensión 1000 se marca el numero 250. En la consola aparecerá:

-- Executing [250@externas:1] AGI("SIP/1000-00000050", "pruebaudio.php") in new stack -- Launched AGI Script /var/lib/asterisk/agi-bin/pruebaudio.php -- Playing 'demo-congrats' (escape_digits=) (sample_offset 0) -- <SIP/1000-00000050>AGI Script pruebaudio.php completed, returning 4 == Spawn extension (externas, 250, 1) exited non-zero on 'SIP/1000-00000050'

Si se activa el debug agi:

CLI> agi set debug on

393

Page 405: Libro Asterisk 1.8.X - Versión 1.0 (1)

El resultado será:

-- Executing [250@externas:1] AGI("SIP/1000-00000051", "pruebaudio.php") in new stack -- Launched AGI Script /var/lib/asterisk/agi-bin/pruebaudio.php<SIP/1000-00000051>AGI Tx >> agi_request: pruebaudio.php<SIP/1000-00000051>AGI Tx >> agi_channel: SIP/1000-00000051<SIP/1000-00000051>AGI Tx >> agi_language: es<SIP/1000-00000051>AGI Tx >> agi_type: SIP<SIP/1000-00000051>AGI Tx >> agi_uniqueid: 1331227067.81<SIP/1000-00000051>AGI Tx >> agi_version: 1.8.8.2<SIP/1000-00000051>AGI Tx >> agi_callerid: 1000<SIP/1000-00000051>AGI Tx >> agi_calleridname: callerid=Fulano<SIP/1000-00000051>AGI Tx >> agi_callingpres: 0<SIP/1000-00000051>AGI Tx >> agi_callingani2: 0<SIP/1000-00000051>AGI Tx >> agi_callington: 0<SIP/1000-00000051>AGI Tx >> agi_callingtns: 0<SIP/1000-00000051>AGI Tx >> agi_dnid: 250<SIP/1000-00000051>AGI Tx >> agi_rdnis: unknown<SIP/1000-00000051>AGI Tx >> agi_context: externas<SIP/1000-00000051>AGI Tx >> agi_extension: 250<SIP/1000-00000051>AGI Tx >> agi_priority: 1<SIP/1000-00000051>AGI Tx >> agi_enhanced: 0.0<SIP/1000-00000051>AGI Tx >> agi_accountcode: 1000<SIP/1000-00000051>AGI Tx >> agi_threadid: -1229980784<SIP/1000-00000051>AGI Tx >><SIP/1000-00000051>AGI Rx << ANSWER<SIP/1000-00000051>AGI Tx >> 200 result=0<SIP/1000-00000051>AGI Rx << STREAM FILE demo-congrats "" 0 -- Playing 'demo-congrats' (escape_digits=) (sample_offset 0)<SIP/1000-00000051>AGI Tx >> 200 result=0 endpos=313776<SIP/1000-00000051>AGI Rx << HANGUP<SIP/1000-00000051>AGI Tx >> 200 result=1 -- <SIP/1000-00000051>AGI Script pruebaudio.php completed, returning 4 == Spawn extension (externas, 250, 1) exited non-zero on 'SIP/1000-00000051'

Asterisk, antes de procesar el agi, envía todas las variables relacionadas con el canal. Otro ejemplo podría ser devolver al llamante su CallerID

nano /var/lib/asterisk/agi-bin/callerid.php

#!/usr/bin/php -q<?php require('phpagi.php'); error_reporting(E_ALL); $agi = new AGI(); $agi-> answer();

394

Page 406: Libro Asterisk 1.8.X - Versión 1.0 (1)

$callerid = $agi->request['agi_callerid']; $agi->text2wav("Hola extension $callerid"); $agi-> hangup();?>

chmod +x /var/lib/asterisk/agi-bin/callerid.php

nano /etc/asterisk/extensions.conf

exten => 251,1,Agi(callerid.php)same => n,Hangup

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Desde la extensión 1000 se marca 251.

El ultimo ejemplo es un despertador que no utiliza la librería PHPAGI sino PHP “puro”:

cd /usr/src

wget http://www.voztovoice.org/tmp/wakeup.2.0.tar

Se descomprime:

tar -xf wakeup.2.0.tar

Se entra en la carpeta:

cd wakeup.2.0

Se vuelve ejecutable el archivo wakeup.php:

chmod +x wakeup.php

se copia en la carpeta agi-bin de asterisk:

cp wakeup.php /var/lib/asterisk/agi-bin/

Terminada esta primera parte se modifica el Dialplan para crear una nueva extensión que se usará para programar el despertador

nano /etc/asterisk/extensions.conf

Se añaden las siguientes dos líneas en el contexto internas:

395

Page 407: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 77,1,Set(CHANNEL(language)=es)same => n,agi(wakeup.php)same=> n,Hangup

Se guarda el archivo y se recarga el dialplan:

asterisk -rvvvvvvvvvvv

CLI> dialplan reload

Ahora desde un extensión 1000 se marca el numero 77 y se siguen las instrucciones para programar el despertador. Una vez programado si desde la misma extensión se marca otra vez la extensión 77 se tendrá la opción de poder modificar la hora del despertador. Cuando llega la llamada del despertador, en el softphone aparecerá:

19.3 Las variantes AGI

Ademas de la aplicación AGI que se acaba de ilustrar, existen una variantes que se utilizan en algunos escenarios muy específicos. Estas son:

• EAGI• FastAGI• Async AGI

Hasta la versión 1.4.X de Asterisk existía también la aplicación DeadAGI que normalmente se utilizaba en un canal que había sido terminado. Esta aplicación desde la versión 1.6.X es “deprecated” y va sustituida con la normal aplicación AGI

19.3.1 EAGI

La gran diferencia entre AGI y EAGI es que el segundo, ademas de comunicarse con Asterisk a través de STDIN y STDOUT, utiliza un file descriptor para la creación de un flujo audio procedente del canal que ha llamado la aplicación.

Algunos datos:

CLI> core show application EAGI

396

Page 408: Libro Asterisk 1.8.X - Versión 1.0 (1)

-= Info about application 'EAGI' =-

[Synopsis]Executes an EAGI compliant application.

[Description]Using 'EAGI' provides enhanced AGI, with incoming audio available out of bandon file descriptor 3.Executes an Asterisk Gateway Interface compliant program on a channel. AGIallows Asterisk to launch external programs written in any language to controla telephony channel, play audio, read DTMF digits, etc. by communicating withthe AGI protocol on *stdin* and *stdout*. As of '1.6.0', this channel willnot stop dialplan execution on hangup inside of this application. Dialplanexecution will continue normally, even upon hangup until the AGI applicationsignals a desire to stop (either by exiting or, in the case of a net script,by closing the connection). A locally executed AGI script will receive SIGHUPon hangup from the channel except when using DeadAGI. A fast AGI server willcorrespondingly receive a HANGUP inline with the command dialog. Both of thesessignals may be disabled by setting the ${AGISIGHUP} channel variable to 'no'before executing the AGI application.Use the CLI command 'agi show commands' to list available agi commands.This application sets the following channel variable upon completion:${AGISTATUS}: The status of the attempt to the run the AGI script text string,one of: SUCCESS FAILURE NOTFOUND HANGUP

[Syntax]EAGI(command[,arg1[,arg2[,...]]])

[Arguments]Not available

[See Also]AGI(), DeadAGI()

19.3.2 FastAGI

FastAGI trabaja sobre una conexión TCP que se realiza con un servidor FastAGI. El control sobre el canal se hace vía TCP y no requiere iniciar un nuevo proceso por cada llamada. La sintaxis es:

AGI(agi://IPservidorFastAGI:puerto)

El puerto predefinido es el 4573

397

Page 409: Libro Asterisk 1.8.X - Versión 1.0 (1)

En las fuentes de Asterisk es presente un servidor FastAGI para hacer una prueba. Primero se modifica el dialplan:

nano /etc/asterisk/extensions.conf

En el contexto internas se añade el siguiente bloque:

exten => 252,1,Noopsame => n,AGI(agi://127.0.0.1:4573)same => n,Hangup

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

Se cambian los permisos del servidor FastAGI:

chmod 755 /usr/src/asterisk-1.8.11.0/agi/fastagi-test

y se inicia:

/usr/src/asterisk-1.8.11.0/agi/fastagi-test

Desde la extensión 1000 se marca el numero 252. Aparecerá:

Consola Asterisk:

-- Executing [253@externas:1] NoOp("SIP/1000-00000011", "") in new stack -- Executing [253@externas:2] AGI("SIP/1000-00000011", "agi://127.0.0.1:4573") in new stack -- <SIP/1000-00000011>AGI Script agi://127.0.0.1:4573 completed, returning 0 -- Executing [253@externas:3] Hangup("SIP/1000-00000011", "") in new stack == Spawn extension (externas, 253, 3) exited non-zero on 'SIP/1000-00000011'

Consola del servidor FastAgi:

AGI Environment Dump from 59836 -- -- accountcode = 1000 -- callerid = 1000 -- calleridname = callerid=Fulano -- callingani2 = 0 -- callingpres = 0 -- callingtns = 0 -- callington = 0

398

Page 410: Libro Asterisk 1.8.X - Versión 1.0 (1)

-- channel = SIP/1000-00000011 -- context = externas -- dnid = 253 -- enhanced = 0.0 -- extension = 253 -- language = es -- network = yes -- priority = 2 -- rdnis = unknown -- request = agi://127.0.0.1:4573 -- threadid = -1224852592 -- type = SIP -- uniqueid = 1331242231.21 -- version = 1.8.8.21. Testing 'sendfile'...PASS (0)2. Testing 'sendtext'...PASS (0)3. Testing 'sendimage'...PASS (0)4. Testing 'saynumber'...PASS (0)5. Testing 'waitdtmf'...PASS (0)6. Testing 'record'...PASS (0)6a. Testing 'record' playback...PASS (0)================== Complete ======================7 tests completed, 7 passed, 0 failed==================================================

Un “framework” que utiliza FastAGI es Adhearsion.

19.3.3 Async AGI

Async AGI permite el envío de los comandos a través de la AMI de Asterisk. De esta forma es posible abrir un canal y luego desde la AMI enviar los comandos al canal abierto.

Desde el punto de vista del dialplan la sintaxis es muy sencilla:

AGI(agi:async)

Para poder enviar las acciones AGI a la AMI de Asterisk, el usuario configurado en el manager.conf deber tener los permisos de lectura y escritura para el parámetro agi, cosa que se hizo cuando se configuró el usuario admin en el manager.conf.

Para probar la funcionalidad de modifica el dialplan:

nano /etc/asterisk/extensions.conf

y se añade el bloque que sigue:

399

Page 411: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 253,1,Noopsame => n,AGI(agi:async)same => n,Hangup

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvv

CLI> dialplan reload

Antes de marcar la extensión 253, se abre otra ventana terminal y se crea una conexión manual a la AMI de Asterisk:

telnet localhost 5038Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.Asterisk Call Manager/1.1

Se autentica el usuario admin:

Action:loginUsername:adminSecret:sesamoEvents:off

Response: SuccessMessage: Authentication accepted

Se ejecuta la primera acción agi para contestar el canal (el numero de canal aparece en la consola de Asterisk):

Action:AgiChannel:SIP/1000-00000017Command:Answer

Response: SuccessMessage: Added AGI command to queue

Se envía la música de espera al canal:

Action:AgiChannel:SIP/1000-00000017Command:Exec startmusiconhold

Response: SuccessMessage: Added AGI command to queue

400

Page 412: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se para la música de espera en el canal:

Action:AgiChannel:SIP/1000-00000017Command:Exec stopmusiconhold

Response: SuccessMessage: Added AGI command to queue

Se termina la llamada:

Action:AgiChannel:SIP/1000-00000017Command:hangup

Response: SuccessMessage: Added AGI command to queue

En la consola de Asterisk aparecerá:

-- Executing [254@externas:1] NoOp("SIP/1000-00000017", "") in new stack -- Executing [254@externas:2] AGI("SIP/1000-00000017", "agi:async") in new stack<SIP/1000-00000017>AGI Tx >> agi_request: async<SIP/1000-00000017>AGI Tx >> agi_channel: SIP/1000-00000017<SIP/1000-00000017>AGI Tx >> agi_language: es<SIP/1000-00000017>AGI Tx >> agi_type: SIP<SIP/1000-00000017>AGI Tx >> agi_uniqueid: 1331246894.27<SIP/1000-00000017>AGI Tx >> agi_version: 1.8.8.2<SIP/1000-00000017>AGI Tx >> agi_callerid: 1000<SIP/1000-00000017>AGI Tx >> agi_calleridname: callerid=Fulano<SIP/1000-00000017>AGI Tx >> agi_callingpres: 0<SIP/1000-00000017>AGI Tx >> agi_callingani2: 0<SIP/1000-00000017>AGI Tx >> agi_callington: 0<SIP/1000-00000017>AGI Tx >> agi_callingtns: 0<SIP/1000-00000017>AGI Tx >> agi_dnid: 254<SIP/1000-00000017>AGI Tx >> agi_rdnis: unknown<SIP/1000-00000017>AGI Tx >> agi_context: externas<SIP/1000-00000017>AGI Tx >> agi_extension: 254<SIP/1000-00000017>AGI Tx >> agi_priority: 2<SIP/1000-00000017>AGI Tx >> agi_enhanced: 0.0<SIP/1000-00000017>AGI Tx >> agi_accountcode: 1000<SIP/1000-00000017>AGI Tx >> agi_threadid: -1225098352<SIP/1000-00000017>AGI Tx >><SIP/1000-00000017>AGI Tx >> 200 result=0

-- AGI Script Executing Application: (startmusiconhold) Options: ()

401

Page 413: Libro Asterisk 1.8.X - Versión 1.0 (1)

-- Started music on hold, class 'default', on SIP/1000-00000017<SIP/1000-00000017>AGI Tx >> 200 result=0 -- AGI Script Executing Application: (stopmusiconhold) Options: () -- Stopped music on hold on SIP/1000-00000017<SIP/1000-00000017>AGI Tx >> 200 result=0<SIP/1000-00000017>AGI Tx >> 200 result=1 == Spawn extension (externas, 254, 2) exited non-zero on 'SIP/1000-00000017'

402

Page 414: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 415: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XX

Los registros en Asterisk

Asterisk guarda toda una serie de registros relacionados con su actividad en distintos archivos. Una parte están relacionados con las llamadas y otra parte con el funcionamiento de la PBX. En este capitulo se hablará de:

• CDR (Call Detail Record)• CEL (Channel Event Logging)• Logger.conf

20.1 CDR (Call Detail Record)

En el párrafo 1.7 se ha visto como crear una base de datos MySQL y una tabla (cdr) para guardar los registros de las llamadas. Mirando una entrada en la tabla CDR, se verán los siguientes datos:

En orden:

• id: numero progresivo que identifica cada entrada de la tabla• calldate: fecha y hora de la llamada• clid: callerID del llamante• src: numero de la extensión que ha iniciado la llamada• dst: numero de la extensión de destino• dcontext: contexto que se ha utilizado• channel: nombre del canal de quien ha originado la llamada• dstchannel: nombre del canal de destino• lastapp: aplicación utilizada• lastdata: opciones de la aplicación utilizadas• duration: duración total de la llamada• billsec: duración de la llamada después de que ha sido contestada• disposition: resultado de la aplicación ejecutada (en este caso BUSY)• amaflags: parámetro utilizado para la facturación de la llamada• accountcode: numero de cuenta para facturación de la llamada• peeraccount: cuenta del usuario (lado peer)• uniqueid: numero único que identifica la llamada• linkedid: numero único que identifica la llamada y que mantiene el mismo valor en el caso la

llamada sea transferida, parqueada, enviada a una cola, etc.. Útil para hacerle seguimiento a la

Page 416: Libro Asterisk 1.8.X - Versión 1.0 (1)

llamada• userfield: campo personalizable por el usuario.

Una primera cosa que se puede hacer es utilizar el campo userfield para guardar la IP de donde se originó la llamada. Para esta configuración se utiliza la función CHANNEL que permite leer muchos datos de un determinado canal, entre ellos “peerip”.

Se abre el dialplan:

nano /etc/asterisk/extensions.conf

y en el contexto internacio, después de esta linea:

exten => _00X.,1,NoOp

se añade:

same => n,Set(CDR(userfield)=${CHANNEL(peerip)})

Con esta linea se asocia al campo userfield del CDR, la IP del canal que está originando la llamada.

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvv

CLI> dialplan reload

Ahora desde la extensión 1000 se llama un numero de teléfono fijo/celular. Terminada la llamada se vuelve a Webmin y se mira la ultima entrada de la tabla CDR. En el campo userfield aparecerá la IP de donde se originó la llamada:

Este tipo de solución puede ser muy útil para conocer en cualquier momento de donde las extensiones están originando sus llamadas y de esta forma monitorear si se están presentando ataques exitosos a la PBX.

Los mismos datos se guardan también en distintos archivos CSV presentes en la la carpeta /var/log/asterisk.y algunas sub-carpetas (en negrita).

ls -l /var/log/asterisk

total 192drwxr-xr-x 2 root root 4096 Mar 22 11:42 cdr-csvdrwxr-xr-x 2 root root 4096 Mar 20 10:11 cdr-custom

405

Page 417: Libro Asterisk 1.8.X - Versión 1.0 (1)

drwxr-xr-x 2 root root 4096 Mar 20 10:11 cel-custom-rw-r--r-- 1 root root 24576 Mar 23 15:21 master.db-rw-r--r-- 1 root root 149285 Mar 23 15:27 messages-rw-r--r-- 1 root root 2022 Mar 22 17:35 queue_log

La carpeta cdr-csv contiene el archivo Master.csv, que contiene la lista de todas las llamadas efectuadas, y un archivo por cada extensión/cuenta.

total 72-rw-r--r-- 1 root root 18847 Mar 24 11:10 1000.csv-rw-r--r-- 1 root root 8055 Mar 22 17:44 1001.csv-rw-r--r-- 1 root root 1059 Mar 22 17:45 1002.csv-rw-r--r-- 1 root root 1113 Mar 23 16:26 marko2.csv-rw-r--r-- 1 root root 32149 Mar 24 11:10 Master.csv-rw-r--r-- 1 root root 261 Mar 21 11:09 Mengano.csv

20.1.1 cdr.conf

Lo que se guarda y como se guardan los datos en el CDR depende de la configuración del archivo cdr.conf. En la tabla que sigue los distintos parámetros con una descripción. En negrita el valor asignado a cada parámetro.

Parámetro Descripción[general] Etiqueta que indica el inicio de la parte general de la configuraciónenable yes = se habilita el registro CDR

unanswered yes = reporta todas las llamadas no contestadas con múltiples destinos y una sola origen. Ejemplo: cuando desde una extensión se marca a un grupo de extensiones.no = reporta todas las llamadas incluyendo la no contestadas siempre y cuando el destino sea un solo numero/extensión

endbeforehexten no = los datos se guardan en el CDR cuando ambos canales se hayan terminado. yes = se guardan antes de la extensión h (si presente).

initiatedseconds Asterisk para determinar la duración de una llamada hace un calculo entre los segundos totales de la llamada menos los segundos desde que la llamada ha sido contestada. Ejemplo: segundos de la llamada 20 – segundos desde que se contestó 10 = tiempo de conversación 10Esto porque a pesar que guarde los datos en micro segundos, redondea a los números enteros.Con yes el calculo tendrá en cuenta los micro segundos. Ejemplo:segundos de la llamada 20,222222 – segundos desde que se contestó 10,111111 = tiempo de conversación 10,111111 redondeado = 11

406

Page 418: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro DescripciónEsto resuelve el desenlace que a veces se encuentra entre la duración de la llamada presente en el CDR y la duración que factura el proveedor VoIP. Valor: yes

batch no = los datos se guardan en el CDR cada vez que una llamada termine. yes = los datos se guardan en un buffer de memoria y se escriben solamente cuando se alcance el numero o el tiempo definidos en el próximos dos parámetros. Si la PBX va en error o el proceso se termina, los datos en el buffer se perderán. Utilizar con cuidado.

;size=100 cuando en el buffer de memoria se alcancen 100 registros, estos se guardarán en los distintos archivos/base de datos. Se deja comentado.

;time=300 cada cuantos segundos guardar los registros del CDR presentes en el buffer de memoria. Este parámetro tiene prioridad sobre el parámetro size. Se deja comentado.

;scheduleronly=no si el parámetro size es mayor que 10, este parámetro se pone igual a no. Para un valor inferior a 10 se pone igual a yes. se deja comentado.

;safeshutdown=yes yes = si se para Asterisk, la PBX antes de cerrarse guardará los registros CDR presentes en el buffer de memoria

[csv] En este bloque se define como se guardarán los registros CDR en los archivos csv.

usegmtime no = no se guarda la hora en GMT sino en el huso horario configurado en el servidor

loguniqueid yes = en el archivo csv se guarda el campo uniqueIDloguserfield yes = en el archivo csv se guarda el campo userfieldaccountlogs yes = se creará un archivo para cada accountcode configurado en

Asterisk.

Se renombra el archivo predefinido:

mv /etc/asterisk/cdr.conf /etc/asterisk/cdr.conf.old

se crea uno nuevo:

nano /etc/asterisk/cdr.conf

y se copial las lineas que siguen:

[general]enable=yesunanswered=no

407

Page 419: Libro Asterisk 1.8.X - Versión 1.0 (1)

endbeforehexten=noinitiatedseconds=yesbatch=no;size=100;time=300;scheduleronly=no;safeshutdown=yes

[csv]usegmtime=nologuniqueid=yesloguserfield=yesaccountlogs=yes

Se guardan los cambios y se recarga la configuración de Asterisk:

service asterisk reload

Se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvv

y se revisa la configuración con el comando:

CLI> cdr show status

Call Detail Record (CDR) settings---------------------------------- Logging: Enabled Mode: Simple Log unanswered calls: No

* Registered Backends ------------------- mysql csv cdr_sqlite3_custom cdr-custom Adaptive ODBC

20.1.2 cdr_manager.conf

Como se ha visto en el parrafo 19.1, en la configuración del los usuarios en el manager.conf, entre los permisos que se pueden configurar, hay el parámetro “cdr” que permite recibir, en la AMI de Asterisk, los eventos relacionados con los registros CDR. Por defecto esta funcionalidad no está activada. Para volverla disponible, se abre el siguiente archivo:

408

Page 420: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/asterisk/cdr_manager.conf

y se modifica esta linea:

enabled=no

para que quede:

enabled=yes

Se guardan los cambios y se reinicia el modulo desde la consola de Asterisk:

CLI> module reload cdr_manager.so

Si se controla el estado del CDR se notará que la nueva funcionalidad está activada (en negrita):

CLI> cdr show status

Call Detail Record (CDR) settings---------------------------------- Logging: Enabled Mode: Simple Log unanswered calls: No

* Registered Backends ------------------- cdr_manager mysql csv cdr_sqlite3_custom cdr-custom Adaptive ODBC

Se puede hacer una prueba entrando en la AMI de asterisk:

telnet localhost 5038

autenticándose:

Action:LoginUsername:adminSecret:sesamo

y efectuando una llamada desde la extensión 1000 a la extensión 1001. Al terminar la llamada, entre los distintos eventos, en la AMI aparecerá:

409

Page 421: Libro Asterisk 1.8.X - Versión 1.0 (1)

Event: CdrPrivilege: cdr,allTimestamp: 1332542079.937863AccountCode: 1000Source: 1000Destination: 1001DestinationContext: externasCallerID: "callerid=Fulano" <1000>Channel: SIP/1000-00000008DestinationChannel: SIP/1001-00000009LastApplication: DialLastData: SIP/1001,45,hHkKtTwWxXStartTime: 2012-03-23 17:34:26AnswerTime: 2012-03-23 17:34:29EndTime: 2012-03-23 17:34:39Duration: 13BillableSeconds: 11Disposition: ANSWEREDAMAFlags: DOCUMENTATIONUniqueID: 1332542066.10UserField:

20.1.3 CDR adaptive

Como el modulo cdr-mysql en la ultima versión de la rama 1.8 ha sido etiquetado como “deprecated”, pronto ese modulo no estará disponible para la instalación. Para obviar este problema, una solución es utilizar el modulo cdr_adaptive_odbc que permite utilizar el conector ODBC para conectarse a una tabla de una base de datos y guardar los registros de las llamadas.

Para probarlo, primero se crea una segunda tabla en la base de datos asteriskcdr:

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> CREATE TABLE cdr2 ( id bigint(20) NOT NULL auto_increment, calldate datetime NOT NULL default '0000-00-00 00:00:00', clid varchar(80) NOT NULL default '', src varchar(80) NOT NULL default '', dst varchar(80) NOT NULL default '', dcontext varchar(80) NOT NULL default '', channel varchar(80) NOT NULL default '', dstchannel varchar(80) NOT NULL default '', lastapp varchar(80) NOT NULL default '', lastdata varchar(80) NOT NULL default '',

410

Page 422: Libro Asterisk 1.8.X - Versión 1.0 (1)

duration int(11) NOT NULL default '0', billsec int(11) NOT NULL default '0', disposition varchar(45) NOT NULL default '', amaflags int(11) NOT NULL default '0', accountcode varchar(20) NOT NULL default '', peeraccount varchar(20) NOT NULL default '', uniqueid varchar(32) NOT NULL default '', linkedid varchar(80) NOT NULL default '', userfield varchar(255) NOT NULL default '', PRIMARY KEY (`id`), KEY callerid (clid));

Se sale del cliente MySQL y se configura el odbc.ini:

mysql> quit

nano /etc/odbc.ini

Al final del archivo se añaden las siguientes lineas:

[asteriskcdr]Description = MySQL AsteriskCDRDriver = MySQLDatabase = asteriskcdrServer = localhostUser = asteriskPassword = sesamoPort = 3306Option = 3

Se pasa al archivo res_odbc:

nano /etc/asterisk/res_odbc.conf

y al final del archivo, se copian las siguientes lineas:

[asteriskcdr]enabled => yesdsn => asteriskcdrusername => asteriskpassword => sesamopre-connect => yessanitysql => select 1idlecheck => 3600connect_timeout => 10

411

Page 423: Libro Asterisk 1.8.X - Versión 1.0 (1)

Por ultimo se configura el archivo cdr_adaptive_odbc.conf

mv /etc/asterisk/cdr_adaptive_odbc.conf /etc/asterisk/cdr_adaptive_odbc.conf.old

se crea uno nuevo:

nano /etc/asterisk/cdr_adaptive_odbc.conf

y se copian las siguientes lineas:

[cdr2]connection=asteriskcdrtable=cdr2alias start => calldate

• [cdr2]: un nombre que se le asigna a la conexión• connection=asteriskcdr: en este parámetro hay que poner la etiqueta que define el bloque

creado en res_odbc.conf• table=cdr2: la tabla MySQL donde se guardarán los datos• alias start => calldate: en cdr_adaptive hay tres campos donde se guardan diferentes

momentos de la llamada: cuando inicia, cuando se contesta y cuando se termina. Los nombres de estos campos son respectivamente start, answer y end. El campo calldate no existe. Por este motivo para que este campo contenga un valor hay que escoger unos de los tres que crea cdr_adaptive. Esto se hace indicando un alias y definiendo que el campo calldate contendrá el valor del campo start de cdr_adaptive (cuando la llamada inicia).

Se guardan los cambios y se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvv

se recarga el moudlo res_odbc y luego el modulo cdr adaptive:

CLI> module reload res_odbc.conf Reloading module 'res_odbc.so' (ODBC resource) == Parsing '/etc/asterisk/res_odbc.conf': == Found[Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:1481 odbc_obj_connect: Connecting asterisk[Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:1511 odbc_obj_connect: res_odbc: Connected to asterisk [asterisk][Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:902 load_odbc_config: Registered ODBC class 'asterisk' dsn->[asterisk][Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:1481 odbc_obj_connect: Connecting asteriskcdr[Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:1511 odbc_obj_connect: res_odbc: Connected to asteriskcdr [asteriskcdr][Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:902 load_odbc_config: Registered ODBC class 'asteriskcdr' dsn->[asteriskcdr]

412

Page 424: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> module reload cdr_adaptive_odbc.so Reloading module 'cdr_adaptive_odbc.so' (Adaptive ODBC CDR backend) == Parsing '/etc/asterisk/cdr_adaptive_odbc.conf': == Found -- Found adaptive CDR table cdr2@asteriskcdr. > Found id column with type -5 with len 19, octetlen 19, and numlen (0,10) -- Found alias start for column calldate in cdr2@asteriskcdr > Found calldate column with type 93 with len 19, octetlen 19, and numlen (0,10) > Found clid column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found src column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found dst column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found dcontext column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found channel column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found dstchannel column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found lastapp column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found lastdata column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found duration column with type 4 with len 10, octetlen 10, and numlen (0,10) > Found billsec column with type 4 with len 10, octetlen 10, and numlen (0,10) > Found disposition column with type 12 with len 45, octetlen 45, and numlen (0,0) > Found amaflags column with type 4 with len 10, octetlen 10, and numlen (0,10) > Found accountcode column with type 12 with len 20, octetlen 20, and numlen (0,0) > Found peeraccount column with type 12 with len 20, octetlen 20, and numlen (0,0) > Found uniqueid column with type 12 with len 32, octetlen 32, and numlen (0,0) > Found linkedid column with type 12 with len 80, octetlen 80, and numlen (0,0) > Found userfield column with type 12 with len 255, octetlen 255, and numlen (0,0)

Ahora se puede efectuar una primera prueba. Desde la extensión 1000 se marca a la extensión 1001. Al terminar la llamada, en la consola de Asterisk aparecerá:

[INSERT INTO cdr2 (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,linkedid) VALUES ({ ts '2012-03-27 15:49:17' },'"callerid=Fulano" <1000>','1000','1001','externas','SIP/1000-0000000f','SIP/1001-00000010','Dial','SIP/1001,45,hHkKtTwWxX',12,10,'ANSWERED',3,'1000','1332881357.17','1332881357.17')]

Que indica que los datos de la llamada se han guardado en la tabla CDR2. En la tabla:

La misma entrada estará en la tabla CDR. Otra cosa que se puede hacer con el modulo CDR Adaptive

413

Page 425: Libro Asterisk 1.8.X - Versión 1.0 (1)

es filtrar los datos que se van a guardar en la tabla. En el ejemplo que sigue se guardarán en una nueva tabla solamente las llamadas originadas por la extensión 1000.

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> CREATE TABLE cdr3 ( id bigint(20) NOT NULL auto_increment, calldate datetime NOT NULL default '0000-00-00 00:00:00', clid varchar(80) NOT NULL default '', src varchar(80) NOT NULL default '', dst varchar(80) NOT NULL default '', dcontext varchar(80) NOT NULL default '', channel varchar(80) NOT NULL default '', dstchannel varchar(80) NOT NULL default '', lastapp varchar(80) NOT NULL default '', lastdata varchar(80) NOT NULL default '', duration int(11) NOT NULL default '0', billsec int(11) NOT NULL default '0', disposition varchar(45) NOT NULL default '', amaflags int(11) NOT NULL default '0', accountcode varchar(20) NOT NULL default '', peeraccount varchar(20) NOT NULL default '', uniqueid varchar(32) NOT NULL default '', linkedid varchar(80) NOT NULL default '', userfield varchar(255) NOT NULL default '', PRIMARY KEY (`id`), KEY callerid (clid));

Se sale del cliente MySQL:

mysql> quit

Luego se modifica el archivo cdr_adaptive_odbc.conf:

nano /etc/asterisk/cdr_adaptive_odbc.conf

Al final del archivo se añade el siguiente bloque:

[cdr3]connection=asteriskcdrtable=cdr3alias start => calldatefilter src => 1000

414

Page 426: Libro Asterisk 1.8.X - Versión 1.0 (1)

• filter src => 1000: en la tabla se guardarán solamente los registros de las llamadas originadas por la extensión 1000

Se guardan los cambios y se entra en la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvvvvvvv

En este caso se recarga solamente el modulo CDR adaptive:

CLI> module reload cdr_adaptive_odbc.so

Con la consola abierta desde la extensión 1001 se llama la extensión 1000. Al finalizar la llamada en la consola aparecerá:

> CDR column 'src' with value '1001' does not match filter of '1000'. Cancelling this CDR.

Como el campo src tiene como valor 1001 y el filtro se ha creado para el valor 1000, la llamada no se guardará en la tabla CDR3.

Si ahora desde la extensión 1000 se llama la extensión 1001:

[INSERT INTO cdr3 (calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,linkedid) VALUES ({ ts '2012-03-27 16:01:52' },'"callerid=Fulano" <1000>','1000','1001','externas','SIP/1000-00000015','SIP/1001-00000016','Dial','SIP/1001,45,hHkKtTwWxX',11,8,'ANSWERED',3,'1000','1332882112.23','1332882112.23')]

Los datos de la llamada se guardarán en la tabla CDR3

20.2 CEL (Channel Event Logging)

Aunque parezca que el CDR responda a todas las necesidades de los administradores de la PBX, tiene unas cuantas limitaciones. Esto porque su lógica se basa en tres eventos principales:

• inicio de la llamada• duración de la conversación• finalización de la llamada

El tiempo que se facturará es la diferencia entre la duración total de la llamada y el duración de la conversación. El problema es que con este tipo de lógica, es muy complicado tener una traza de todos los eventos que se pueden presentar a lo largo de la llamada. Algunos ejemplos:

• transferencia de la llamada a otra extensión• transferencia de la llamada a una conferencia

415

Page 427: Libro Asterisk 1.8.X - Versión 1.0 (1)

• parqueo y/o captura de la llamada por otra extensión• ejecución de un AGI a lo largo de la llamada.

Todos estos tipos de eventos, dificultan una correcta facturación y seguimiento de llamada. Es por eso que desde la versión 1.8 de Asterisk se ha añadido un nueva funcionalidad: el CEL (Channel Event Logging). El CEL a diferencia del CDR, basa su lógica sobre el canal de la llamada y va guardando todos los eventos que se van generando en ese canal. De esta forma es posible tener un registro mucho más detallado de las llamadas. El CEL, en su desarrollo actual, no sustituye el CDR, sin embargo la combinación de los dos permite un control y monitoreo de las llamadas muchos más detallado y completo. En este párrafo se ilustrará la configuración del modulo y como guardar los eventos en una tabla de una base de datos utilizando el conector ODBC.

Lo primero es configurar el archivo cel.conf. En la tabla que sigue los distintos parámetros con una descripción. En negrita el valor asignado a cada parámetro.

Parámetro Descripción[general] inicia la parte general de la configuración del archivoenable yes = se activa el registro de los eventos del modulo CELapps en este parámetro se especifica la lista de las aplicaciones por las

cuales se quiere recibir los eventos. Si se indica “all” se recibirán los eventos de todas las aplicaciones. Utilizar con cuidado ya que puede afectar el rendimiento de la PBX Valor: dial,park,queue,meetme

events En este parámetro se indica una lista de eventos, separados por una coma, de los que se quieres tener traza Estos son:

• ALL: todos• CHAN_START: fecha en que se ha creado el canal• CHAN_END: fecha en que el canal se ha terminado• ANSWER: fecha en que el canal ha sido contestado• HANGUP: fecha en que se ha presentado un Hangup (cierre

del canal)• CONF_ENTER: fecha en que un canal ha sido enviado a una

conferencia audio• CONF_EXIT: fecha en que un canal ha salido de una

conferencia audio• CONF_START: fecha en que el primer usuario ha entrado a

una conferencia• CONF_END: fecha en que el ultimo usuario presente ha

dejado una conferencia audio (y posiblemente apagado todas las luces :)

• APP_START: fecha en que la aplicación se ha iniciado• APP_END: fecha en que la aplicación ha terminado• PARK_START: fecha en que el canal ha sido parqueado

416

Page 428: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripción

• PARK_END: fecha en que el canal ha sido sacado del “slot” de parqueo

• BRIDGE_START: fecha en que el canal ha sido conectado con otro canal

• BRIDGE_END: fecha en que ha terminado la conexión con otro canal

• 3WAY_START: fecha en que ha iniciado una conferencia a 3 (normalmente con una transferencia asistida)

• 3WAY_END: fecha en que una conferencia a 3 ha sido terminada

• BLINDTRANSFER: fecha en que ha iniciado una transferencia ciega

• ATTENDEDTRANSFER: fecha en que ha iniciado una transferencia asistida

• TRANSFER: fecha en que se ha iniciado una transferencia• HOOKFLASH: fecha en que se ha iniciado un “descolgado

relampago” en un canal DAHDI (normalmente utilizado para contestar llamadas en espera o para activar la conferencia a 3)

• USER_DEFINED: evento personalizado que se puede enviar desde el dialpla a través de la aplicación CELGenUserEvent

Para esta prueba se recibirán todos los eventos. Valor: Alldateformat El formato de la fecha presente por cada evento. Valor: %F %T[manager] a partir de esta etiqueta inicia la configuración de CEL para la AMI

de Asteriskenabled yes = se activa el envío de los eventos a la AMI de Asterisk

Con estos datos, se puede crear el archivo de configuración para CEL. Se renombra el predefinido:

mv /etc/asterisk/cel.conf /etc/asterisk/cel.conf.old

se crea uno nuevo:

nano /etc/asterisk/cel.conf

y se añaden las siguientes lineas:

[general]enable=yesapps=dial,park,queue,meetmeevents=alldateformat=%F %T

[manager]

417

Page 429: Libro Asterisk 1.8.X - Versión 1.0 (1)

enabled=yes

Se guardan los cambios y se recarga la configuración de Asterisk:

service asterisk reload

Ahora falta crear la tabla y luego crear una conexión a la misma a través de ODBC. Se entra en cliente mysql:

mysql -u root -psesamo

Se crea la base de datos, la tabla y el usuario con los permisos:

mysql> create database asteriskcel

mysql> use asteriskcel

mysql> CREATE TABLE cel( eventtime TIMESTAMP NOT NULL , userdeftype VARCHAR( 255 ) NOT NULL , cid_name VARCHAR( 80 ) NOT NULL , cid_num VARCHAR( 80 ) NOT NULL , cid_ani VARCHAR( 80 ) NOT NULL , cid_rdnis VARCHAR( 80 ) NOT NULL , cid_dnid VARCHAR( 80 ) NOT NULL , exten VARCHAR( 80 ) NOT NULL , context VARCHAR( 80 ) NOT NULL , channame VARCHAR( 80 ) NOT NULL , appname VARCHAR( 80 ) NOT NULL , appdata VARCHAR( 80 ) NOT NULL , accountcode VARCHAR( 20 ) NOT NULL , peeraccount VARCHAR( 20 ) NOT NULL , uniqueid VARCHAR( 150 ) NOT NULL , linkedid VARCHAR( 150 ) NOT NULL , amaflags INT NOT NULL , userfield VARCHAR( 255 ) NOT NULL , peer VARCHAR( 80 ) NOT NULL);

mysql> GRANT ALL PRIVILEGES ON asteriskcel.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';

Se sale del cliente:

mysql> quit

Ahora los pasos a seguir son:

418

Page 430: Libro Asterisk 1.8.X - Versión 1.0 (1)

• Crear uno nuevo bloque en el archvo odbc.ini• Crear un nuevo bloque en el archivo res_odbc.conf• Configurar el archivo cel_odbc.conf

Se abre el archivo odbc.ini:

nano /etc/odbc.ini

y al final se añade el siguiente bloque:

[asteriskcel]Description = MySQL AsteriskCELDriver = MySQLDatabase = asteriskcelServer = localhostUser = asteriskPassword = sesamoPort = 3306Option = 3

Se guarda los cambios y se prueba la nueva conexión:

isql asteriskcel asterisk sesamo+---------------------------------------+| Connected! || || sql-statement || help [tablename] || quit || |+---------------------------------------+SQL> quit

Se pasa al archivo res_odbc.conf:

nano /etc/asterisk/res_odbc.conf

se añade el siguiente bloque:

[asteriskcel]enabled => yesdsn => asteriskcelusername => asteriskpassword => sesamopre-connect => yes

419

Page 431: Libro Asterisk 1.8.X - Versión 1.0 (1)

sanitysql => select 1idlecheck => 3600connect_timeout => 10

El valor que aparece en el parámetro dns tiene que ser el mismo con que inicia el bloque que se acaba de configurar en el archivo odbc.ini

Por ultimo se modifica el archivo cel_odbc.conf:

mv /etc/asterisk/cel_odbc.conf /etc/asterisk/cel_odbc.conf.old

nano /etc/asterisk/cel_odbc.conf

Se copian las siguientes lineas:

[CEL1]connection=asteriskceltable=cel

• CEL1:nombre que se le quiere asignar a la conexión• asteriskcel: tiene que ser el mismo valor con que inicia el bloque que se ha configurado en el

archivo res_odbc.conf• cel: nombre de la tabla que se ha creado y donde se guardarán los nuevos registros

Se guarda los cambios y se entra en la consola de Asteirsk:

asterisk -rvvvvvvvvvvvv

Se recarga primero el module res_odbc.so:

CLI> module reload res_odbc.so

Se averigua que haya conexión con ODBC:

CLI> odbc show

ODBC DSN Settings-----------------

Name: asterisk DSN: asterisk Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes

Name: asteriskcdr

420

Page 432: Libro Asterisk 1.8.X - Versión 1.0 (1)

DSN: asteriskcdr Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes

Name: asteriskcel DSN: asteriskcel Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes

Se recarga el modulo cel_odbc.so

CLI> module reload cel_odbc.so

Ahora desde la extensión 1001 se llama la extensión 1000 y utilizando el botón “Transfer” del softphone 3CX se transfiere la llamada a la conferencia numero 3500. Cuando la extensión 1000 esté en la conferencia, desde la extensión 1001 se marca el mismo numero de conferencia (3500). Una vez que las dos extensiones estén en la conferencia, primero cuelga la 1000 y luego la 1001. El resultado en la tabla CEL será:

CLI> quit

mysql -u root -psesamo

mysql> use asteriskcel

mysql> select eventtime,exten,context,channame,appname,appdata,uniqueid,linkedid from cel;

421

Page 433: Libro Asterisk 1.8.X - Versión 1.0 (1)

20.3 Logger.conf

Además de las llamadas, es posible tener traza del funcionamiento de Asterisk (errores, advertencias) en archivos de texto que se guardan en la carpeta /var/log/asterisk.

Que tipo de archivos y que tipo de registros se quieren guardar, se define en el archivo logger.conf.

En la tabla que sigue los distintos parámetros con una descripción. En negrita el valor asignado a cada parámetro.

Parámetro Descripción[general] inicia la parte general de la configuración del archivodateformat formato de la fecha. Predefinido ISO 8601 - %F %Tappendhostname si se quiere añadir o no al nombre del archivo el nombre del dominio

del servidor. Valor noqueue_log define si se quiere guardar o no las estadísticas de las colas de espera

en un archivo. Valor yesqueue_log_name El nombre del archivo donde guardar las estadísticas de la colas de

espera. Valor queue_logqueue_log_to_file yes = las estadísticas de las colas se siguen guardando en el archivo

queue_log aunque estén configuradas en Realtime.rotatestrategy Normalmente los archivos de Log pueden alcanzar un tamaño

considerable que dificulta su consulta. Para evitarlo se pueden “rotar” y con este parámetro se define que tipo de rotación se va a utilizar:

• secuential – se renombran los archivos siguiendo un orden donde el más reciente tendrá un numero más alto.

• rotate – se renombran los archivos siguiendo un orden donde el más viejo tendrá el numero más alto

• timestamp – se renombran los archivos añadiendo al nombre la fecha en que se archivaron

[logfiles] esta etiqueta define el inicio de la configuración de los archivos de registro. Cada archivo puede contener los siguientes valores:

• debug• notice• warning• error• verbose• dtmf• fax (desde la versión 1.8 de Asterisk)

debug => debug – se crea un archivo donde se guardará solamente el debug de

422

Page 434: Libro Asterisk 1.8.X - Versión 1.0 (1)

Parámetro Descripciónla actividad de Asterisk

verbose => verbose – se crea un archivo donde guardar muy en detalle los registros de la actividad de Asterisk

fax => fax – se crea un archivo donde se guardarán los registros de actividad del envío/recepción de FAX

console => notice,warning,error,debug,dtmf,fax El archivo console no es propiamente un archivo. Se indica que tipo de registros aparecerán en la consola de Asterisk.

messages => notice,warning,dtmf En el archivo messages se guardarán solamente los registros relacionados con noticias, advertencias, DTMF y fax

error => error En el archivo error se guardarán solamente los errores.

Para crear el nuevo archivo, se renombra el predefinido:

mv /etc/asterisk/logger.conf /etc/asterisk/logger.conf.old

y se crea uno nuevo:

nano /etc/asterisk/logger.conf

Se copian las siguientes lineas:

[general]dateformat=%F %Tappendhostname=noqueue_log=yesqueue_log_name=queue_logqueue_log_to_file=yesrotatestrategy=rotate

[logfiles]debug => debugverbose => verbosefax => faxconsole => notice,warning,error,debug,dtmf,faxmessages => notice,warning,dtmferror => error

Se guardan los cambios y se pasa a la definición de las política de rotación de los archivos de registro. Para definir estas políticas hay que instalar el programa Logrotate que se encarga de este tipo de tarea.

yum install logrotate

423

Page 435: Libro Asterisk 1.8.X - Versión 1.0 (1)

Una vez instalado se crea un nuevo archivo donde se va a definir la rotación de los archivos de Log de Asterisk:

nano /etc/logrotate.d/asterisk

Se copian las siguientes líneas:

/var/log/asterisk/messages/var/log/asterisk/error /var/log/debug/var/log/verbose {missingokrotate 7dailypostrotate/usr/sbin/asterisk -rx 'logger reload' > /dev/null 2> /dev/nullendscript}

/var/log/asterisk/queue_log {missingokrotate 5size=1000kpostrotate/usr/sbin/asterisk -rx 'logger reload'> /dev/null 2> /dev/nullendscript}

El primer bloque define la rotación para los archivos messages, error, debug y verbose La rotación será diaria y se crearán un máximo de 7 archivos secuenciales (archivo.1 archivo.2 , etc.). El más antiguo tendrá el numero secuencial más alto. Después de la rotación (postrotate) se actualiza la configuración del archivo logger.conf en asterisk.

El segundo bloque define la política de rotación del archivo de registro queue_log (las estadísticas de las colas de espera). En este caso el archivo rotará cuando alcanzará un tamaño de 1000 Kbyte y se creerán un máximo de 5 archivos secuenciales.

Para testar el archivo de configuración creado el procedimiento es:

cd /etc/logrotate.d

logrotate -fv asterisk

Para aplicar los cambios desde la consola de Asterisk:

asterisk -rvvvvvvvvvvvvvv

424

Page 436: Libro Asterisk 1.8.X - Versión 1.0 (1)

se escribe:

CLI> logger reload

Para ver la configuración del archivo:

CLI> logger show channels

Channel Type Status Configuration------- ---- ------ -------------/var/log/asterisk/error File Enabled - ERROR/var/log/asterisk/messages File Enabled - NOTICE WARNING DTMF Console Enabled - DEBUG NOTICE WARNING ERROR DTMF FAX/var/log/asterisk/fax File Enabled - FAX/var/log/asterisk/debug File Enabled - DEBUG/var/log/asterisk/verbose File Enabled - VERBOSE

CLI> quit

Se reinicia Asterisk

service asterisk restart

En la carpeta /var/log/asterisk estarán presentes los archivos configurados en logger.conf y se podrán revisar los errores en el archivo error:

nano /var/log/asterisk/error

De esta forma en cualquier momento se tendrá bajo control el funcionamiento de Asterisk.

20.3.1 Debug

Cuando algo no está funcionando en Asterisk, hay la posibilidad de aumentar el nivel de debug de la consola para buscar el tipo de problema que está afectando el funcionamiento de la PBX. Esto se hace con un comando especifico:

asterisk -rvvvvvvvvvvvvvvvvvvvvv

CLI> core set debug 9

El nivel de debug va de 0 (ningún debug) a 9 (máximo debug). De esta forma las informaciones que se reciben acerca de las operaciones efectuadas por Asterisk son mucho más detalladas y en la mayoría de los casos permite solucionar el problema.

Como en el logger.conf se ha definido que el debug se guardará en el archivo “debug”, ademas de la consola, se puede utilizar este archivo para encontrar eventuales errores.

425

Page 437: Libro Asterisk 1.8.X - Versión 1.0 (1)

De hecho si se vuelve a desactivar el debug:

CLI> core set debug 0

se sale de la consola de Asterisk:

CLI> quit

y se abre el archivo:

nano /var/log/asterisk/debug

se verá que ese archivo contiene todo el debug generado desde que se ha activado en la consola. La consulta de estos archivos puede ser bastante complicada si se ha generado una cantidad considerable de registros. Para buscar algo especifico se puede utilizar el programa “cat” junto al programa “grep”. El primero lee un archivo y devuelve su contenido en la ventana terminal de Linux, grep permite buscar una determinada palabra o frase en un archivo. Un ejemplo:

cat /var/log/asterisk/debug | grep odbc

De esta forma todas la lineas del archivo debug que contengan la palabra odbc aparecerán en la ventana terminal. Si se quiere enviar el resultado a un archivo:

cat /var/log/asterisk/debug | grep odbc > odbc

En el caso el problema sea con la señalización SIP, desde la consola se puede activar el debug de este protocolo con el siguiente comando:

asterisk -rvvvvvvvvvvvvvvvvvvvvv

CLI> sip set debug on

Si se quiere limitar el debug solamente a una determinada extensión, troncal:

CLI> sip set debug peer justvoip

Como se ha visto en el párrafo 3.4 , se puede utilizar también la utilidad ngrep.

426

Page 438: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 439: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XXI

Seguridad en Asterisk

21.1 Reglas de oro

Hay una reglas de oro que se necesita seguir en la configuración de Asterisk. Estas reglas permiten mejorar la seguridad de la PBX y evitar ataques exitosos:

1. utilizar siempre contraseñas bastantes largas y difíciles de memorizar.2. no utilizar la misma contraseña para todas las extensiones3. no aceptar llamadas entrantes de invitados. Esto se configura con el parámetro allowguest=no

en la parte general del sip.conf. Si se decide aceptar llamadas entrantes de invitados (sin autentificación), el contexto definido en la parte general del sip.conf no debe permitir el acceso a troncales SIP y/o lineas telefónicas tradicionales.

4. configurar en la parte general del sip.conf el parámetro alwaysauthreject=yes. De esta forma cualquier intento de registro a extensiones existentes en la centralita, recibirá como respuesta que la extensión no existe, evitando dar trazas al atacante

5. No permitir el acceso al AMI de Asterisk desde remoto (teniendo cerrado el puerto 5038 TCP del servidor Linux. En el caso que se necesite utilizar el AMI desde remoto, configurar Iptables de modo que acepte el trafico solo desde determinadas direcciones IP. Un ejemplo es esta linea:-A INPUT -p tcp -m state --state NEW -m tcp --dport 5038 -s 192.168.142.200 -j ACCEPTCon esta linea se podrá conectar desde remoto al AMI de Asterisk solamente la maquina con IP 192.168.142.200. Otra forma es utilizar el protocolo TLS.

6. Utilizar números o nombres de extensiones largos y no fácilmente memorizables.7. Utilizar las funciones GROUP y GRUP_COUNT para limitar las llamadas salientes de las

extensiones.

Ademas de estas 7 reglas, es posible instalar en el servidor Asterisk Fail2Ban., un programa que lee los registros de Asterisk del archivo /var/log/asterisk/messages y si hay un numero determinado de intentos de conexión sin éxito, bloquea la IP de donde se han originados, interactuando con iptables (cortafuegos).

21.2 Fail2ban

Se descarga el programa:

cd /usr/src

wget http://downloads.sourceforge.net/project/fail2ban/fail2ban-stable/fail2ban-0.8.4/fail2ban-0.8.4.tar.bz2

se descomprime:

tar -xf fail2ban-0.8.4.tar.bz2

Page 440: Libro Asterisk 1.8.X - Versión 1.0 (1)

se entra en la carpeta:

cd fail2ban-0.8.4

y se instala:

python setup.py install

Se activa el script para arrancarlo como servicio:

cp /usr/src/fail2ban-0.8.4/files/redhat-initd /etc/init.d/fail2ban

chkconfig --add fail2ban

chkconfig fail2ban on

Se configura para que lea los registros de Asterisk:

cd /etc/fail2ban/filter.d

nano asterisk.conf

y se añaden estas líneas:

# Fail2Ban configuration file#[INCLUDES]# Read common prefixes. If any customizations available -- read them from# common.local#before = common.conf

[Definition]#_daemon = asterisk

# Option: failregex# Notes.: regex to match the password failures messages in the logfile. The# host must be matched by a group named "host". The tag "<HOST>" can# be used for standard IP/hostname matching and is only an alias for# (?:::f{4,6}:)?(?P<host>\S+)# Values: TEXT#failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>(:[0-9]{1,5})?' - Wrong password NOTICE.* .*: Registration from '.*' failed for '<HOST>(:[0-9]{1,5})?' - No matching peer found NOTICE.* .*: Registration from '.*' failed for '<HOST>(:[0-9]{1,5})?' - Username/auth name mismatch NOTICE.* .*: Registration from '.*' failed for '<HOST>(:[0-9]{1,5})?' - Device does not match ACL NOTICE.* .*: Registration from '.*' failed for '<HOST>(:[0-9]{1,5})?' - Peer is not supposed to register NOTICE.* .*: <HOST> failed to authenticate as '.*'$ NOTICE.* .*: No registration for peer '.*' \(from <HOST>\) NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*) NOTICE.* .*: Failed to authenticate user .*@<HOST>.* NOTICE.* .*: Sending fake auth rejection for device .*@<HOST>.*

429

Page 441: Libro Asterisk 1.8.X - Versión 1.0 (1)

# Option: ignoreregex# Notes.: regex to ignore. If this regex matches, the line is ignored.# Values: TEXT#ignoreregex =

Con estas líneas se configura fail2ban para que controle eventuales accesos indeseados que aparecen en el archivo de registro de Asterisk.

Se termina modificando el archivo de configuración general de fail2ban:

cd /etc/fail2ban

nano jail.conf

al final del archivo se añaden las lineas que siguen:

[asterisk-iptables] enabled = truefilter = asteriskaction = iptables-allports[name=ASTERISK, protocol=all]sendmail-whois[name=ASTERISK, dest=root@localhost, [email protected]]logpath = /var/log/asterisk/messagesmaxretry = 5bantime = 1800

En la línea logpath aparece el archivo de registros que fail2ban leerá para averiguar intentos frustrados de conexión a Asterisk. En la configuración hay que modificar la dirección de correo electrónico. En lugar de root@localhost se pone la dirección de correo electrónico donde se quiere recibir las notificaciones. En sender, en lugar de [email protected] se pone fail2ban@nombrededominio del servidor donde está instalado Asterisk. Para enviar los correos, fail2ban está configurado con Sendmail. Con esta configuración cuando se verifiquen 5 ataques del mismo tipo procedentes de la misma IP, Fail2ban bloqueará el IP insertando una nueva linea en el archivo de configuración de Iptables y la mantendrá bloqueada por 1800 segundos.

Para que funcione hay que averiguar que en el archivo de configuración de Asterisk

nano /etc/asterisk/logger.conf

en la siguiente linea esté presente el valor notice (configuración predefinida):

messages => notice,warning,dtmf

Se inicia fail2ban:

/etc/init.d/fail2ban start

Starting fail2ban: [ OK ]

430

Page 442: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se averigua que no haya errores en el log de fail2ban:

tail -f /var/log/fail2ban.log

Si se quiere hacer una prueba se configura en X-lite una extensión que no existe en el sistema y se intenta registrarla a Asterisk:

La IP de donde se está intentando registrarse será bloqueada. Accediendo a la consola del servidor remoto desde otra dirección IP con el comando:

iptables -L

se verá la IP bloqueada:

Desde el log de fail2ban:

Si por error se bloquea la IP de un computador, la única forma de quitar el bloqueo es parar y reiniciar Iptables o reiniciar el servidor Linux.

431

Page 443: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 444: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XXII

Monitorear Asterisk

En este capitulo se ilustrará como monitorear Asterisk y el servidor Linux a través de dos distintos programas:

• Monit• Nagios y el protocolo SNMP

Se ilustrará también como monitorear la calidad de las llamadas directamente desde la consola de Asterisk y a través del programa VoIPmonitor.

22.1 Monit

Monit es un programa Open Source para la gestión y el monitoreo de procesos, programas, archivos, carpetas y particiones de un sistema Linux. Permite programar tareas de mantenimiento y de corrección de errores cuando se verifiquen problemas en el sistema.

Se instalará desde las fuentes:

cd /usr/src

wget http://mmonit.com/monit/dist/monit-5.3.2.tar.gz

tar -xf monit-5.3.2.tar.gz

cd monit-5.3.2

Se compila y se instala:

./configure --prefix=/usr

make

make install

Se termina la instalación con la copia y activación del script de inicio de monit:

cd contrib

cp rc.monit /etc/init.d/monit

chmod +x /etc/init.d/monit

chkconfig --add monit

Page 445: Libro Asterisk 1.8.X - Versión 1.0 (1)

chkconfig monit on

Ahora se modifica el archivo de configuración para monitorear los siguientes programas:

• Sendmail• MySQL• Asterisk• la troncal Justvoip

El archivo de configuración de Monit se divide en tres bloques:

• Global Section; aquí se pone la configuración general del programa• Services; donde se configuran los servicios• Includes: permite incluir a la configuración de Monit otros archivo que contienen a su vez la

configuración de otros procesos.

nano /etc/monitrc

set daemon 60# Indica cada cuantos segundos Monit controla los servicios (en este caso cada 60)

with start delay 30# Al iniciar el programa el primer ciclo se ejecutará después de 30 segundos

set logfile /var/log/monit.log# Nombre del archivo donde se guardarán todos los registros de Monit

set idfile /var/.monit.id# Nombre de la carpeta y archivo donde se guardará el numero del proceso de Monit

set mailserver localhost# nombre del host del servidor de correo electrónico que Monit utilizará para enviar las alertas

set eventqueue basedir /var/monit slots 100# Si por alguna razón el servidor de correo electrónico no esté funcionando podemos decirle a Monit de # guardar todas las alerta en una determinada carpeta. Cuando el servidor volverá a funcionar, todas las# alertas serán enviada siguiendo el orden cronológico en que se guardaron

set mail-format {From: [email protected]: monit alerta -- $EVENT $SERVICEMessage: $EVENT Servicio $SERVICE

Fecha: $DATEAccion: $ACTION

434

Page 446: Libro Asterisk 1.8.X - Versión 1.0 (1)

Host: $HOSTDescripcion: $DESCRIPTION

Tu devoto empleado,Monit}# Con el bloque de arriba, se define como tiene que ser enviado el correo electrónico de alerta

set alert [email protected]# Con esta línea se define el correo electrónico que recibirá todas las alertas (personalizar)

set httpd port 2812allow admin:sesamo# Monit viene con un servidor Web. En las dos lineas de arriba se activa en el puerto 2812# (que hay que abrir en el cortafuegos) y se define nombre de usuario y contraseña para ingresar a la # pagina

# Servidor Linuxcheck system cursoasterisk.orgif loadavg (1min) > 4 then alertif loadavg (5min) > 2 then alertif memory usage > 75% then alertif cpu usage (user) > 70% then alertif cpu usage (system) > 30% then alertif cpu usage (wait) > 20% then alert

# Asteriskcheck process asterisk with pidfile /var/run/asterisk/asterisk.pidstart program = "/etc/init.d/asterisk start" with timeout 60 secondsstop program = "/etc/init.d/asterisk stop" with timeout 60 secondsif failed host 127.0.0.1 port 5038 then restartif 5 restarts within 5 cycles then timeout

# Troncal SIPcheck host Justvoip with address sip.justvoip.comif failed port 5060 type udp protocol SIPand target [email protected] maxforward 10then alert

# SendMailcheck process sendmail with pidfile /var/run/sendmail.pidgroup mailstart program = "/etc/init.d/sendmail start"stop program = "/etc/init.d/sendmail stop"if failed port 25 protocol smtp then restartif 5 restarts within 5 cycles then timeout

435

Page 447: Libro Asterisk 1.8.X - Versión 1.0 (1)

# MySQLcheck process mysql with pidfile /var/run/mysqld/mysqld.pidgroup databasestart program = "/etc/init.d/mysqld start"stop program = "/etc/init.d/mysqld stop"if failed port 3306 protocol mysql then restartif 5 restarts within 5 cycles then timeout

Se guardan los cambios y se cambian los permisos del archivo de configuración:

chmod 700 /etc/monitrc

Se inicia Monit:

/etc/init.d/monit start

En el cortafuegos, hay que abrir el puerto 2812 TCP para tener acceso al servidor Web interno de Monit:

nano /etc/sysconfig/iptables

antes de este bloque:

# DUNDi-A INPUT -p udp -m udp --dport 4520 -j ACCEPT

se añade:

# Monit-A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT

Se guardan los cambios y se reinicia iptables

service iptables restart

Después de unos minutos se puede acceder a la pagina de administración de Monit:

http://ipservidor:2812

436

Page 448: Libro Asterisk 1.8.X - Versión 1.0 (1)

Nombre de usuario: adminContraseña: sesamo

Una vez entrados en la Web de Monit, el pagina principal aparecerán todos los procesos/programas monitoreados:

y en el caso del servidor Linux:

437

Page 449: Libro Asterisk 1.8.X - Versión 1.0 (1)

Cualquier problema se presente con el servidor y/o con los procesos/programas configurados, se recibirá una notificación al correo electrónico configurado.

22.2 SNMP

Una definición del protocolo SNMP tomada de wikipedia: “El Protocolo Simple de Administración de Red o SNMP es un protocolo de la capa de aplicación que facilita el intercambio de información de administración entre dispositivos de red. Es parte de la familia de protocolos TCP/IP. SNMP permite a los administradores supervisar el funcionamiento de la red, buscar y resolver sus problemas, y planear su crecimiento.” De hecho a través de este protocolo se monitorean servidores, router, switch y casi cualquier tipo de aparado conectado a la red (local o remota). Asterisk implementa el protocolo SNMP y a través de ese protocolo es posible monitorear muchos parámetros de la PBX.

Para empezar se averigua si el modulo res_snmp está instalado y cargado en Asterisk:

asterisk -rvvvvvvvvvvvvvvv

CLI> module show like snmp

Significa que el modulo está instalado.

Se sale de la consola de Asterisk:

438

Page 450: Libro Asterisk 1.8.X - Versión 1.0 (1)

CLI> quit

Se configura el modulo:

mv /etc/asterisk/res_snmp.conf /etc/asterisk/res_snmp.conf.old

nano /etc/asterisk/res_snmp.conf

Se añaden las siguientes lineas:

[general]subagent = yesenabled = yes

Se guardan los cambios y se descargan los OID de Asterisk en la carpeta de SNMP. Un OID (identificador de objeto) es una cadena alfanumérica que se utiliza para identificar de forma única un objeto que en el caso del protocolo SNMP representa un determinado parámetro del dispositivo que se quiere monitorear. Ejemplo: se puede conocer el numero de llamadas totales cursadas por la centralita desde su ultimo arranque.

cd /usr/share/snmp/mibs

wget http://www.voztovoice.org/tmp/asterisk-mib.txtwget http://www.voztovoice.org/tmp/digium-mib.txt

Ahora se configura SNMP de modo que pueda interactuar con Asterisk:

cd /etc/snmp

Se renombra el archivo de configuración predefinido:

mv snmpd.conf snmpd.conf.old

y se crea uno nuevo:

nano snmpd.conf

donde se ponen las siguientes líneas:

master agentxagentXPerms 0660 0550 root root

com2sec local localhost publiccom2sec remote XXX.XXX.XXX.XXX public

group asterisk v1 localgroup asterisk v2c local

439

Page 451: Libro Asterisk 1.8.X - Versión 1.0 (1)

group NetWork v1 remotegroup NetWork v2c remote

view all included .1

access asterisk "" any noauth exact all none noneaccess NetWork "" any noauth exact all none none

Una explicación. Primero se define el agente y los permisos de acceso. Luego se definen dos comunidades. Una tiene acceso local y otra remoto (útil si se quiere hacer consultas desde otro servidor). Hay que sustituir XXX.XXX.XXX.XXX con la ip del servidor remoto. Luego se definen dos grupos y que tipo de consultas pueden hacer (en este caso SNMP versión 1 y versión 2c. Se define el tipo de objetos que pueden consultar (en este caso todos) y los permisos que cada grupo tiene.

Se guardan los cambios y se reinicia Asterisk:

/etc/init.d/asterisk restart

se inicia snmp:

/etc/init.d/snmpd start

se vuelve el arranque automático:

chkconfig snmpd on

Para ver los resultados con la descripción de los OID en lugar de los números de los objetos:

export MIBS=all

Ahora ya se puede hacer una consulta utilizando el OID raiz de Asterisk:

snmpwalk -OT -c public -v 2c localhost .1.3.6.1.4.1.22736

De todas las lineas que aparecen, las que interesan son estas tres:

ASTERISK-MIB::astChanTypeName.6 = STRING: IAX2ASTERISK-MIB::astChanTypeName.4 = STRING: SIPASTERISK-MIB::astChanTypeName.7 = STRING: DAHDI

Se anotan los valores que aparecen en negrita y el tipo de canal asociado, es decir:

SIP 4IAX2 6DAHDI 7

Se pasa a la instalación y configuración de Nagios.

440

Page 452: Libro Asterisk 1.8.X - Versión 1.0 (1)

22.3 Nagios

Para la instalación de Nagios desde los paquetes precompilados, hay que instalar el repositorio rpmforge:

cd /usr/src

wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm

rpm -ivh rpmforge-release-0.5.2-2.el5.rf.i386.rpm

Ahora se controlan los paquetes disponibles para Nagios:

yum search nagios

check_logfiles.i386 : Logfile check plugin for nagiosicinga.i386 : Open Source host, service and network monitoring programnagios.i386 : Open Source host, service and network monitoring programnagios-devel.i386 : Header files, libraries and development documentation for nagiosnagios-nrpe.i386 : Nagios Remote Plug-ins Execution daemonnagios-nsca.i386 : Nagios Service Check Acceptornagios-nsca-client.i386 : nagios send_nscanagios-plugins.i386 : Host/service/network monitoring program plugins for Nagiosnagios-plugins-nrpe.i386 : Nagios plug-in for NRPEnagios-plugins-setuid.i386 : Host/service/network monitoring program plugins for Nagios requiring setuidndoutils.i386 : Nagios plugin to store Nagios data in a relational databasensc.i386 : Console monitor for Nagiosnsc.noarch : Console monitor for Nagiosperl-Nagios-Object.noarch : Nagios::Object - Nagios object configuration parsingperl-Nagios-Plugin.noarch : Family of perl modules to streamline writing Nagiosrss4nagios.i386 : Authenticated RSS alerts for nagios

Se instalan los siguientes paquetes: el programa, los plugins, una utilidad para guardar los registros de Nagios en una base de datos, unas librerías en Perl para utilizar el protocolo XMPP, una aplicación para el envío de los correo electrónicos desde Nagios utilizando una linea de comando.

yum install nagios nagios-plugins perl-Net-Jabber perl-IO-Socket-SSL ndoutils mailx httpd

CentOS se hará cargo de instalar también todas las dependencias necesarias. Se creará el grupo y usuario Nagios, unas carpetas donde se guardarán los registros y los archivo necesarios para que Nagios funcione, un archivo para la integración con el servidor Web (apache). Una vez terminada la instalación, se empieza con la configuración de Nagios.

El archivo principal donde se definen los parámetros para el programa es nagios.cfg y se encuentra en

441

Page 453: Libro Asterisk 1.8.X - Versión 1.0 (1)

la carpeta /etc/nagios.

Para este tipo de instalación no hace falta hacer algún tipo de modifica es ese archivo.

Los archivos de configuración de Nagios que hay que modificar son los siguientes y se encuentran en la carpeta /etc/nagios/objects:

• commands.cfg• localhost.cfg• contact.cfg• template.cfg

Se inicia con contact.cfg:

nano /etc/nagios/objects/contacts.cfg

En este archivo se cambian estas líneas:

define contact{contact_name nagiosadminuse generic-contactalias Nagios Adminemail nagios@localhost}

para que queden:

define contact{contact_name nagiosadminuse generic-contactalias Nagios Administradoremail [email protected] fulano}

[email protected] es la dirección de correo electrónico donde Nagios enviará las notificaciones (personalizar). Address1 es el usuario GoogleTalk donde Nagios enviará las notificaciones vía mensaje instantáneo. Nagiosadmin es el nombre del administrador predefinido en Nagios. Cada vez que aparece una línea que empieza con “use”, hace referencia a un template definido en el archivo templates.cfg.

Se guardan los cambios y se abre el archivo templates.cfg. En este archivo el bloque del generic-contact es:

nano /etc/nagios/objects/templates.cfg

define contact{

442

Page 454: Libro Asterisk 1.8.X - Versión 1.0 (1)

name generic-contact service_notification_period 24x7host_notification_period 24x7service_notification_options w,u,c,r,f,shost_notification_options d,u,r,f,sservice_notification_commands notify-service-by-email,notify-service-jabberhost_notification_commands notify-host-by-email,notify-host-jabbercan_submit_commands 1register 0}

En este bloque se añaden las dos partes en negrita. Esto para enviar las notificaciones también vía GoogleTalk.

Hay una explicación de estos parámetros en la documentación oficial de Nagios 3.0

En el servidor hay servicios que no son críticos y que se pueden monitorear cada 5 minutos (el tiempo predefinido en Nagios). Para Asterisk, a veces, estos cinco minutos pueden ser demasiados. Por eso al final del archivo se añade el siguiente bloque que define que para todos los servicios de Asterisk el control se hará cada 2 minutos (se puede personalizar):

define service{name asteriskuse generic-service max_check_attempts 4 normal_check_interval 2retry_check_interval 1register 0}

Ahora se modifica el tercer archivo (commands.cfg) donde se definen los comandos que luego se utilizarán para la configuración del monitoreo del servidor local. Los plugins de Nagios se instalan en /usr/lib/nagios/plugins. Para monitorear Asterisk, se usará el plugin check_snmp y otro que viene en la carpeta /usr/lib/nagios/plugins/contrib, check_asterisk.pl. Para monitorear las troncales, se descargará un plugin del repositorio de Nagios y por ultimo, para enviar las notificaciones via GoogleTalk se descargará otro plugin.

Se entra en la carpeta /usr/lib/nagios/plugins y se descargan los plugin que hacen falta:

cd /usr/lib/nagios/plugins

wget http://www.voztovoice.org/campus/a2b/check_asterisk_peerswget http://www.voztovoice.org/campus/a2b/notify_via_jabber.pl

Se cambian los permisos para que se pueda ejecutar:

chmod +x check_asterisk_peers

443

Page 455: Libro Asterisk 1.8.X - Versión 1.0 (1)

chmod +x notify_via_jabber.pl

Notify_via_jabber.pl es el único que tiene que ser modificado. Se abre:

nano notify_via_jabber.pl

se modifican estas dos lineas:

my $username = "usuarioGoogleTalk";my $password = "password";

para que queden:

my $username = "sutano";my $password = "password";

sutano es el usuario googletalk y password su contraseña (no hace falta poner @gmail.com)

Una paréntesis. El plugin funciona de la siguiente manera. En este archivo se configura el usuario de GoogleTalk que enviará las notificaciones. El usuario configurado en el contact.cfg serà él que las recibe siempre y cuando añadirá el usuario configurado en el plugin en su lista de amigos. Esto quiere decir que para que el sistema funcione se necesita tener dos cuentas de GoogleTalk.

Para conocer la sintaxis de un plugin de Nagios el comando es:

cd /usr/lib/nagios/plugins

./check_snmp -h

Para añadir los comandos en Nagios, se modificará el archivo commands.cfg

nano /etc/nagios/objects/commands.cfg

Primero se configura el comando para enviar las notificaciones vía mensaje instantáneo. Esto se hace para los servidores (en este caso uno) y los servicios. Después del bloque notify-service-by-email se añade:

# 'host-notify-by-jabber' command definitiondefine command{ command_name notify-host-jabber command_line /usr/lib/nagios/plugins/notify_via_jabber.pl $CONTACTADDRESS1$"Host '$HOSTALIAS$' is $HOSTSTATE$ - Info: $HOSTOUTPUT$" }

# 'service-notify-by-jabber' command definitiondefine command { command_name notify-service-jabber

444

Page 456: Libro Asterisk 1.8.X - Versión 1.0 (1)

command_line /usr/lib/nagios/plugins/notify_via_jabber.pl $CONTACTADDRESS1$"$NOTIFICATIONTYPE$ $HOSTNAME$ $SERVICEDESC$ $SERVICESTATE$ $SERVICEOUTPUT$ $LONGDATETIME$" }

IMPORTANTE: todo lo que aparece en la linea command-line debe estar en la misma linea

Se continua con el plugin check_snmp para monitorear Asterisk a través del protocolo SMNP. Se buscan estas lineas:

# 'check_snmp' command definitiondefine command{command_name check_snmpcommand_line $USER1$/check_snmp -H $HOSTADDRESS$ $ARG1$}

y se modifican para que queden:

define command{command_name check_snmpcommand_line $USER1$/check_snmp -H $HOSTADDRESS$ -C public -o $ARG1$ -P 2c -l $ARG2$ -w $ARG3$ -c $ARG4$}

IMPORTANTE: todo lo que aparece en la linea command-line debe estar en la misma linea

Command name: nombre del comandoCommand line: los parámetros que pasaremos al comando:

• La macro (variable) $USER1$ contiene el valor /usr/lib/nagios/plugins como especificado en el archivo /etc/nagios/resource.cfg

• check_snmp – Nombre del plugin• -H $HOSTADDRESS$ – la opción –H define el servidor que se va a consultar y

$HOSTADDRESS$ es una macro (variable) predefinida que contiene el nombre del servidor como se definirá luego en localhost.cfg

• -C public – es la comunidad que se va a utilizar para la conexión al agente como definido en el archivo /etc/snmp/snmp.conf

• -o – la OID que se consultará• -P 2c – versión de SNMP utilizada para la consulta• -l la etiqueta que luego se definirá• -w – está por Warning• -c – está por Critical• $ARG1$ $ARG2$ $ARG3$ ARG4$ son las macros (variables) cuyo valor será asignado desde

la configuración de localhost.cfg

Al verificarse el evento Warning y/o Critical, Nagios enviará una notificación por correo electrónico y

445

Page 457: Libro Asterisk 1.8.X - Versión 1.0 (1)

vía mensaje instantáneo.

El segundo plugin se define de la siguiente forma (añadir las lineas después del bloque anterior):

define command{command_name check_asteriskcommand_line $USER1$/contrib/check_asterisk.pl -h $HOSTADDRESS$ -m mgr -u nagios -p sesamo}

nagios y sesamo indican respectivamente el usuario y la contraseña para conectarse al AMI de Asterisk. Para definirlos, luego hay que modificar el manager.conf de Asterisk:

Como el servidor SSH está escuchando en el puerto 15000, se busca este bloque:

# 'check_ssh' command definitiondefine command{ command_name check_ssh command_line $USER1$/check_ssh $ARG1$ $HOSTADDRESS$ }

y se modifica para que quede:

# 'check_ssh' command definitiondefine command{ command_name check_ssh command_line $USER1$/check_ssh -p $ARG1$ $HOSTADDRESS$ }

El ultimo plugin que se define en el archivo command.cfg, es el que permite monitorear las troncales:

define command{command_name check_justvoipcommand_line sudo /usr/lib/nagios/plugins/check_asterisk_peers -t sip -p $ARG1$}

Se guardan los cambios.

Como se puede ver este plugin se activa con el programa sudo que permite ejecutar un comando con los permisos del usuario root. Esto porque el programa Nagios se inicia con usuario nagios y ese usuario no tiene los permisos para ejecutar el plugin. Para que pueda hacerlo hay que modificar el archivo sudousers que es donde se definen los usuarios que pueden ejecutar comandos con los permisos de root. Para modificar este archivo con el editor nano hay que seguir este procedimiento:

cd /root

nano .bash_profile

446

Page 458: Libro Asterisk 1.8.X - Versión 1.0 (1)

al final del archivo se añade la siguiente linea:

export EDITOR=/usr/bin/nano

Se guardan los cambios y se recarga el perfile de la shell bash:

source .bash_profile

Ahora se puede modificar el archivo sudousers con nano con el comando:

visudo

primero se modifica esta linea:

Defaults requiretty

para que quede:

# Defaults requiretty

luego se añade al final del archivo:

nagios ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/check_asterisk_peers

Se guardan los cambios.

Como se había dicho el plugin check_asterisk.pl funciona conectándose a la AMI de Asterisk. Para que funcione hay que modifica el archivo manager.conf de Asterisk:

nano /etc/asterisk/manager.conf

Al final del archivo se añade:

[nagios]secret = sesamodeny=0.0.0.0/0.0.0.0permit=127.0.0.1/255.255.255.255read=system,call,agent,user,dtmf,reporting,cdr,dialplan,agi,ccwrite=system,call,agent,user,config,command,reporting,otiginate,agi

Se guardan los cambios y se actualiza la configuración de Asterisk:

/etc/init.d/asterisk reload

Para terminar la configuración de Nagios se modifica el archivo localhost.cfg. Se mueve el predefinido:

447

Page 459: Libro Asterisk 1.8.X - Versión 1.0 (1)

mv /etc/nagios/objects/localhost.cfg /etc/nagios/objects/localhost.cfg.old

se crea uno nuevo:

nano /etc/nagios/objects/localhost.cfg

Se añaden las siguientes lineas:

define host{use linux-serverhost_name CursoAsteriskalias CursoAsteriskaddress 127.0.0.1}

define service{use asteriskhost_name CursoAsteriskservice_description SIPcheck_command check_snmp!ASTERISK-MIB::astChanTypeChannels.4!"Canales SIP Activos"!8!16}

Si los canales SIP activos son más de 8 se recibirá un WARNING, si son mas de 16 un CRITICAL. Se continua copiando las lineas que siguen:

define service{use asterisk host_name CursoAsteriskservice_description IAX2check_command check_snmp!ASTERISK-MIB::astChanTypeChannels.6!"Canales IAX2 Activos"!4!8}

define service{use asterisk host_name CursoAsteriskservice_description DAHDIcheck_command check_snmp!ASTERISK-MIB::astChanTypeChannels.7!"Canales DAHDI Activos"!4!8}

define service{use asteriskhost_name CursoAsteriskservice_description Asterisk_checkcheck_command check_asterisk}

448

Page 460: Libro Asterisk 1.8.X - Versión 1.0 (1)

define service{use asteriskhost_name CursoAsteriskservice_description Troncal_Justvoipcheck_command check_justvoip!justvoip}

Una pequeña explicación. En el primer bloque se define el nombre del servidor, un alias y la dirección IP (en este caso siendo Nagios y Asterisk instalados en el mismo servidor se indica 127.0.0.1 o localhost).

En los tres bloques que siguen se controla a través del plugin check_snmp, los canales SIP, IAX2 y DAHDI activos. Se asignan a las cuatros macros (variables), que se han visto al momento de la configuración del comando ($ARG1$ $ARG2$ $ARG3$ ARG4$), los respectivos valores separados por el caracter ! Las OID se toman interrogando Asterisk con SNMP como hemos visto en el párrafo anterior.

En el bloque que sigue se utiliza el plugin check_asterisk.pl y a través del AMI de Asterisk se controla que esté corriendo.

El ultimo bloque se utilizan para monitorear la troncal SIP Justvoip. En la segunda linea de cada bloque aparece el parámetro “use asterisk” que representa el template (la plantilla) configurada en templates.cfg que se utiliza para estos comandos.

Si se quiere controlar también algunos servicios básicos del servidor (usuarios, procesos, carga, etc…), se añaden estas líneas:

define service{use local-servicehost_name CursoAsteriskservice_description PINGcheck_command check_ping!100.0,20%!500.0,60%}

define service{use local-servicehost_name CursoAsteriskservice_description Current Userscheck_command check_local_users!20!50}

define service{use local-servicehost_name CursoAsteriskservice_description Total Processescheck_command check_local_procs!250!400!RSZDT}

449

Page 461: Libro Asterisk 1.8.X - Versión 1.0 (1)

define service{use local-servicehost_name CursoAsteriskservice_description Current Loadcheck_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0}

define service{use local-servicehost_name CursoAsteriskservice_description SSHcheck_command check_ssh!15000}

Antes de iniciar Nagios hay una forma para controlar que todos los archivos de configuración estén exentes de errores:

nagios -v /etc/nagios/nagios.cfg

Si la respuesta termina con:

Total Warnings: 0Total Errors: 0Things look okay - No serious problems were detected during the pre-flight check

Significa que la configuración está bien. En caso contrario Nagios indicará el archivo y la línea donde se encuentra el error.

El acceso a la pagina Web de administración de Nagios está protegido y para poder acceder hay que configurar la contraseña del usuario predefinido, nagiosadmin, de la siguiente forma:

htpasswd -bc /etc/nagios/htpasswd.users nagiosadmin sesamoAdding password for user nagiosadmin

Este comando creará una archivo htpasswd.users que contendrá los datos de acceso para el usuario predefinido nagiosadmin (en este caso la contraseña es sesamo)

Se configuran Nagios para que arranque en automático:

chkconfig nagios on

Se reinicia apache y luego se inicia Nagios:

/etc/init.d/httpd start/etc/init.d/nagios start

450

Page 462: Libro Asterisk 1.8.X - Versión 1.0 (1)

Antes de entrar a la pagina de administración de Nagios, hay que abrir el puerto 80 TCP (servidor WEB) en Iptables:

nano /etc/sysconfig/iptables

Antes de este bloque:

# Monit-A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT

se añade:

# HTTP-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

Se guardan los cambios y se reinicia Iptables:

service iptables restart

Para entrar en la pagina de Nagios:

http://IPservidor/nagios

Aparecerá una ventana donde habrá que insertar las credenciales de acceso es decir:

usuario: nagiosadmin contraseña: sesamo

Se presiona el botón Aceptar. Aparece la pagina inicial de Nagios:

451

Page 463: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la derecha se selecciona el enlace Hosts para ver el servidor configurado:

Se selecciona Services para ver los servicios monitoreados:

Todos están bien.

22.3.1 NDOutils

NDOutils permite guardar todos los datos de Nagios en una base de datos MySQL. Lo primero que hay que hacer es crear la base de datos:

mysql -u root -psesamo

mysql> create database nagios;

452

Page 464: Libro Asterisk 1.8.X - Versión 1.0 (1)

se asigna al usuario nagios los permisos para la base de datos creada:

mysql> GRANT ALL PRIVILEGES ON nagios.* TO 'nagios'@'localhost' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Se crean las tablas en la base de datos nagios desde un archivo instalado con el paquete NDOutils:

mysql -u root -psesamo nagios < /usr/share/ndoutils/mysql.sql

Ahora falta modificar dos archivos de configuración: nagios.cfg y ndo2db.cfg. Primero se modifica nagios.cfg

nano /etc/nagios/nagios.cfg

al final del archivo se añaden las siguientes lineas:

event_broker_options=-1broker_module=/usr/libexec/ndomod-3x.o config_file=/etc/nagios/ndomod.cfg

que permiten a Nagios conectarse a la librería de NDOutils y enviar todos los datos de configuración y los eventos:

Se guardan los cambios y se continua con el ndo2db.cfg:

nano /etc/nagios/ndo2db.cfg

Después de estas dos lineas:

ndo2db_user=nagiosndo2db_group=nagios

se añade:

lock_file=/var/nagios/ndo2db.lock

en db_user y db_password se pone:

db_user=nagiosdb_pass=sesamo

se guardan los cambios y se inicia NDOutils:

/etc/init.d/ndoutils start

453

Page 465: Libro Asterisk 1.8.X - Versión 1.0 (1)

y se reinicia Nagios:

/etc/init.d/nagios restart

se averigua que en el log de Nagios haya conexión con la librería NDOutils:

tail -f /var/log/nagios/nagios.log

Las lineas que interesan son:

En Webmin se puede controlar que las tablas se ha ido llenando de nuevas entradas como, por ejemplo, la tabla nagios_commands:

Todo está funcionando como debería. Hay disponibles distintos tipos de consultas de las tablas en la carpeta /usr/share/ndoutils/queries/

22.4 Monitoreo calidad llamadas

Como se ha dicho al inicio de este capitulo, es posible monitorear la calidad de las llamadas de distintas formas. La primera es desde la consola de Asterisk:

22.4.1 Monitoreo calidad llamadas desde la consola de Asterisk

Se entra en la consola de Asterisk:

454

Page 466: Libro Asterisk 1.8.X - Versión 1.0 (1)

asterisk -rvvvvvvvvvvvvvvvvvv

Si activan las estadísticas del protocolo RTCP (Real Time Control Protocol) definido en el RFC 3550.

CLI> rtcp set stats onRTCP Stats Enabled

Para ver como funciona, desde la extensión 1000 se llama la extensión 1002. Se contesta la llamada y después de unos segundos se cuelga. En la consola aparecerán todas una serie de datos relacionados con la llamada.

Otra forma de hacerlo es con el comando:

CLI> sip show channelstats

para verlo en acción, se vuelve a marcar desde la extensión 1000 la extensión 1001. Cuando las dos extensiones están hablando, se vuelve a ejecutar el comando:

CLI> sip show channelstats

En las lineas aparecen todos los datos relacionados con la llamadas corrientes (en este caso una):

• Peer: la IP de las extensiones• Call ID: el identificador único de llamada para cada extensión• Duration: la duración de la llamada hasta el momento (en segundos)• Recv: Pack: paquetes recibidos por Asterisk de las dos extensiones• Lost: paquetes perdidos de la extensiones a Asterisk• %: porcentaje de paquetes perdidos• Jitter : Jitter entre las extensiones y Asterisk• Send: Pack: paquete enviados por Asterisk• Lost: paquetes perdidos de Asterisk a las extensiones• %: porcentaje de paquetes perdidos• Jitter: Jitter entre Asterisk y las extensiones

Si el porcentaje de los paquetes perdidos se mantiene por abajo del 1%, la calidad de la llamada es muy buena. Entre el 1 y el 5%, aceptable.

22.4.2 Monitoreo calidad llamadas con VoIPMonitor

VoIPmonitor es un programa que permite guardar todos los datos relacionados con la calidad de las llamadas en una base de datos. De este programa existen dos versiones. Una Open Source sin parte

455

Page 467: Libro Asterisk 1.8.X - Versión 1.0 (1)

Web para ver la estadísticas desde un Navegador, una comercial que incluye la parte Web.

El programa analiza y captura todos los paquetes SIP (señalización) y RTP (flujo media). De cada llamada, para ambos canales, guarda los siguientes datos:

• Fecha de la llamada• Duración• CallerID llamante• CallerID llamado• Quien de los dos canales ha colgado• Codec Llamante• Codec Llamado• Paquetes recibidos, enviados, perdidos• Jitter canal llamante• Jitter canal llamado• Jitter promedio de la llamada• MOS (Mean Opinion Score) llamante• MOS (Mean Opinion Score) llamado

Pre requisitos para la compilación e instalación:

• una versión de Libpcap >= 1.0• Librería MySQL++

Primero se averigua la versión de libpcap instalada:

yum info libpcap

Como el numero de versión es inferior a 1, hay que instalar la librería desde la fuentes:

cd /usr/srcwget http://www.tcpdump.org/release/libpcap-1.2.1.tar.gztar -xf libpcap-1.2.1.tar.gzcd libpcap-1.2.1./configure --prefix=/usrmakemake install

456

Page 468: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se continua con MySQL++

cd /usr7srcwget http://tangentsoft.net/mysql++/releases/mysql++-3.1.0.tar.gz tar -xf mysql++-3.1.0.tar.gzcd mysql++-3.1.0./configure --prefix=/usrmakemake install

Instalados los pre requisitos ya se puede compilar e instalar VoIPMonitor. Primero se descarga:

svn co https://voipmonitor.svn.sourceforge.net/svnroot/voipmonitor/trunk voipmonitor-svn

Se entra en la carpeta creada:

cd voipmonitor-svn

Se compila y se instala:

makemake install

Se crea la carpeta donde se guardarán todos los datos de las llamadas (archivo pcap, archivo audio de la llamada si se utiliza el codec audio G711):

mkdir /var/spool/voipmonitor

Se crea la base de datos donde se guardarán los datos de las llamadas:

mysql -u root -psesamo

mysql> create database voipmonitor;

mysql> GRANT ALL PRIVILEGES ON voipmonitor.* to 'voipuser'@'localhost' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Se cargan las tablas en la base de datos:

mysql -u root -psesamo voipmonitor < cdrtable.sql

Se crea un archivo de configuración para el programa:

457

Page 469: Libro Asterisk 1.8.X - Versión 1.0 (1)

nano /etc/voipmonitor.conf

Se copian las lineas que siguen:

[general]# inicia la parte general de la configuracióninterface=any# el programa se pondrá a la escucha en todas las tarjetas de red presentes en el servidormanagerport=5029# puerto TCP para gestionar el programasipport=5060sipport=5061# puertos SIP donde voipmonitor se pondrá a la escucha. Se indica uno por linea# ringbuffer=10# Parámetro valido solamente para versiones del Kernel >= 2.6.31jitterbuffer_f1=yesjitterbuffer_f2=yesjitterbuffer_adapt=yes# tipos de jitterbuffer utilizados para el calculo del MOSrtp-firstleg=no# se capturará el flujo media de ambos canalessip-register=no# no se guardarán en la captura SIP, los mensajes de REGISTERnocdr=no# VoIPMonitos guardará los CDR de las llamadassavesip=yes# VoIPMonitos guardará los datos SIP en un archivosavertp=yes#VoIPMonitor guardará los paquetes RTP en un archivosavegraph=plain# Se guardarán los datos de los graficos en un archivo (en el caso se utilice la GUI)spooldir=/var/spool/voipmonitor# Carpeta donde se guardarán los datos de las llamadasmysqlhost=localhost# dirección IP o nombre de dominio del servidor MySQLmysqldb=voipmonitor# Nombre de la base de datosmysqltable=cdr# Nombre de la tablamysqlusername=voipuser# Nombre del usuario MySQL con los permisos para la base de datosmysqlpassword=sesamo# Password del usuario voipuser

Se guardan los cambios y se instala lo script para iniciar el servicio en automático:

458

Page 470: Libro Asterisk 1.8.X - Versión 1.0 (1)

cp config/init.d/voipmonitor /etc/init.d/chmod +x /etc/init.d/voipmonitorchkconfig --add voipmonitorchkconfig voipmonitor on

Se inicia el servicio:

service voipmonitor start

e se efectúa una llamada desde la extensión 1000 a la extensión 1001. Terminada la llamada se mira las entradas en la base de datos (serán dos).

459

Page 471: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 472: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XXIII

Conectar un Softphone (Blink) de forma segura: SIP TLS y SRTP

En algunos contextos la privacidad de las comunicaciones es un factor importante para el desarrollo de las actividades de la empresa, más aun si los datos que se intercambian a lo largo de las conversaciones son datos sensibles tipo: números de tarjetas de crédito, datos de cuentas bancarias, secretos industriales, etc... Las conversaciones seguras eran importantes en las comunicaciones tradicionales y más aun lo son en la voz sobre IP. Con la versión de Asterisk 1.8.X se han implementados dos nuevos protocolos:

• SIP TLS para el cifrado de la señalización SIP• SRTP para el cifrado del flujo media.

Aunque se puedan utilizar separadamente, no tendría mucho sentido, por las siguientes razones:

• Si se utiliza solamente el protocolo SIP TLS, el flujo media seguirá viajando en claro y podrá ser interceptado

• Las claves que intercambian el cliente y el servidor para instaurar el cifrado del flujo media, se envian a través de la señalización SIP. Si no se utiliza el cifrado del protocolo SIP y alguien logra interceptar este trafico, podrá tener acceso a las claves y de esta forma descifrar el flujo media.

El único Softphone con una versión gratuita que soporta los protocolos SIP TLS Y SRTP es Blink. De este producto existen versiones para Linux, MAC OS y Windows. Antes de instalarlo hay que configurar Asterisk para activar el protocolo SIP TLS y SRTP.

23.1 Creación de los certificados

El primer paso es crear los certificado cliente, servidor y de la autoridad de certificación. Se crea la carpeta donde se guardarán las claves:

mkdir /etc/asterisk/keys

y se entra en la carpeta de las fuentes de Asterisk que contiene uno script para la generación de los certificados:

cd /usr/src/asterisk-1.8.11.0/contrib/scripts/

Primero se crea el certificado de la autoridad de certificación y del servidor Asterisk:

./ast_tls_cert -C li374-112.members.linode.com -O "Campus VozToVoice" -d /etc/asterisk/keys

• con la opción -C se indica el nombre de dominio o la IP del servidor Asterisk• con la opción -O se indica el nombre de la empresa o de la institución

Page 473: Libro Asterisk 1.8.X - Versión 1.0 (1)

• con la opción -d se indica la ruta donde se guardarán los certificados

./ast_tls_cert -C li374-112.members.linode.com -O "Campus VozToVoice" -d /etc/asterisk/keys

No config file specified, creating '/etc/asterisk/keys/tmp.cfg'You can use this config file to create additional certs withoutre-entering the information for the fields in the certificateCreating /etc/asterisk/keys/ca.keyGenerating RSA private key, 4096 bit long modulus............++..........................................................................++e is 65537 (0x10001)Enter pass phrase for /etc/asterisk/keys/ca.key:Verifying - Enter pass phrase for /etc/asterisk/keys/ca.key:Creating /etc/asterisk/keys/ca.crtEnter pass phrase for /etc/asterisk/keys/ca.key:Creating /etc/asterisk/keys/asterisk.keyGenerating RSA private key, 1024 bit long modulus....................................++++++.........++++++e is 65537 (0x10001)Creating signing requestCreating /etc/asterisk/keys/asterisk.crtSignature oksubject=/CN=li374-112.members.linode.com/O=Campus VozToVoiceGetting CA Private KeyEnter pass phrase for /etc/asterisk/keys/ca.key:Combining key and crt into /etc/asterisk/keys/asterisk.pem

Cuando el sistema lo solicita, se indica una contraseña que tiene que ser la misma a lo largo de todo el proceso. En este caso se utilizará la contraseña server. Con esta operación se crearán el certificado de la autoridad de certificación con relativa clave y el certificado del servidor Asterisk con relativa clave.

El segundo paso es crear la clave del softphone utilizando la misa autoridad de certificación:

./ast_tls_cert -m client -c /etc/asterisk/keys/ca.crt -k /etc/asterisk/keys/ca.key -C blink1.li374-112.members.linode.com -O "Campus VozToVoice" -d /etc/asterisk/keys -o blink1

• con la opción -m se indica el tipo de certificado. En este caso un certificado cliente• con la opción -c se indica la ruta del certificado de la autoridad de certificación• con la opción -k se indica la ruta de la clave del certificado de la autoridad de certificación• con -C se indica el nombre de dominio o la IP de donde se conectará el softphone. Como en este

caso el computador desde donde se conectará el softphone no tiene un nombre de dominio o una IP fija, se pone un nombre que identifique el softphone y al mismo tiempo el dominio del servidor

• con la opción -O se indica el nombre de la empresa o de la institución

462

Page 474: Libro Asterisk 1.8.X - Versión 1.0 (1)

• con la opción -d se indica la ruta donde se guardarán los certificados

No config file specified, creating '/etc/asterisk/keys/tmp.cfg'You can use this config file to create additional certs withoutre-entering the information for the fields in the certificateCreating /etc/asterisk/keys/blink1.keyGenerating RSA private key, 1024 bit long modulus.....................++++++.....++++++e is 65537 (0x10001)Creating signing requestCreating /etc/asterisk/keys/blink1.crtSignature oksubject=/CN=blink1.li374-112.members.linode.com/O=Campus VozToVoiceGetting CA Private KeyEnter pass phrase for /etc/asterisk/keys/ca.key:Combining key and crt into /etc/asterisk/keys/blink1.pem

Cuando el sistema lo solicite, se ingresa la misma contraseña utilizada en la fase anterior, es decir, server.

Una vez creados los certificados se modifica la configuración del archivo sip.conf de Asterisk:

nano /etc/asterisk/sip.conf

al final de la parte general se añaden las siguientes lineas:

tlsenable=yestlsbindaddr=0.0.0.0tlscertfile=/etc/asterisk/keys/asterisk.pemtlscafile=/etc/asterisk/keys/ca.crttlscapath=/etc/asterisk/keystlsdontverifyserver=yes

• Linea 1: se activa el protocolo SIP TLS• Linea 2: Asterisk se pondrá a la escucha en todas las direcciones IP presentes en el servidor• Linea 3: ruta y nombre del certificado del servidor Asterisk• Linea 4: ruta y nombre del certificado de la autoridad de certificación• Linea 5: ruta donde se encuentran todos los certificados de las distintas autoridades de

certificación• Linea 6: como el softphone no utiliza un nombre de dominio propio, con este parámetro en yes,

se indica que el servidor Asterisk no deberá verificar el certificado del cliente

Al final del archivo se crea una nueva extensión:

[1005]

463

Page 475: Libro Asterisk 1.8.X - Versión 1.0 (1)

type=friendaccountcode=1005language=essecret=pbx9095qualify=yesmailbox=1005@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=Perengano <1001>callgroup=1pickupgroup=1disallow=allallow=ulawallow=alawallow=g729allow=h263cc_agent_policy=genericcc_monitor_policy=generictransport=tlsencryption=yes

Las ultimas dos lineas indican que para la extensión 1005, Asterisk aceptará solamente conexiones con el protocolo SIP TLS y el cifrado del flujo media.

Se guardan los cambios y se recarga la configuración SIP:

asterisk -rvvvvvvvvvvvvv

CLI> sip reload

Si todo sale bien, entre las varias lineas aparecerá:

SSL certificate ok

Como el protocolo SIP TLS utiliza el puerto 5061 TCP, hay que abrirlo en el cortafuegos:

nano /etc/sysconfig/iptables

Después de esta linea:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT

se pone:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 5061 -j ACCEPT

464

Page 476: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se reinicia iptables:

service iptables restart

Para terminar esta primera parte, hay que trasferir los certificado en el computador donde se instalará el Softphone Blink. Los archivos que hay que descargar son:

• ca.crt• blink1.pem

Para esta operación, en Windows se puede utilizar el programa winscp. Bajo Linux el comando scp.

23.2 Configuración Softphone Blink

Asterisk ya está configurado para el soporte SIP TLS y SRTP. Ahora se puede descargar el Softphone Blink según el sistema operativo utilizado. Una vez descargado se instala y se inicia la configuración entrando en el menú Blink → Accounts → Add Account:

465

Page 477: Libro Asterisk 1.8.X - Versión 1.0 (1)

• Display name: un nombre que se le asigna a la cuenta• SIP address: numero de extensión y dominio del servidor Asterisk• Password: contraseña de la extensión 1005

Se presiona el botón ADD y se va al menú Blink → Account → Manage accounts. En la pestaña “Media”:

Se selecciona el protocolo SRTP como obligatorio “mandatory”.

En la pestaña “Server settings”:

se configura como aparece en la imagen de arriba y se continua con la pestaña “Advanced”:

Se selecciona el certificado blink1.pem descargado del servidor Asterisk y se selecciona la casilla “Verify server”. Se pasa al icono Advanced:

466

Page 478: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se selecciona el certificado de la autoridad de certificación descargado del servidor Asterisk: Se vuelve a la pantalla principal del softphone y se averigua en la consola de Asterisk que esté registrado:

CLI> sip show peers

Prueba llamadas

Para probar la configuración, hay que modificar el dialplan:

nano /etc/asterisk/extensions.conf

Se modifica este bloque:

exten => _100[0-2,4],1,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Macro(voicemail)same => n,Hangup

para que quede:

exten => _100[0-2,4-5],1,Noop(Protocolo SIPTLS = ${CHANNEL(secure_signaling)})same => n,Noop(Protocolo SRTP = ${CHANNEL(secure_media)})same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Macro(voicemail)same => n,Hangup

En la primera linea se lee el valor asociado a la variable de canal “secure_signaling” Si es ugual a 1 significa que la llamada ha sido iniciada por una extensión configurada con el protocolo SIP TLS. En la segunda linea se lee el valor asociado a la variable de canal “secure_media”. Si es igual a 1 significa que la llamada ha sido iniciada por una extensión configurada con el protocolo SRTP activado.

Se guardan los cambios y se recarga el dialplan:

asterisk -rvvvvvvvvvvvvvvvvv

CLI> dialplan reload

Ahora se hacen dos llamadas:

1. desde la extensión 1000 a la extensión 1005

467

Page 479: Libro Asterisk 1.8.X - Versión 1.0 (1)

2. desde la extensión 1005 a la extensión 1000

Los resultados:

Executing [1005@externas:1] NoOp("SIP/1000-00000010", "Protocolo SIPTLS = ") in new stack-- Executing [1005@externas:2] NoOp("SIP/1000-00000010", "Protocolo SRTP = ") in new stack-- Executing [1005@externas:3] Dial("SIP/1000-00000010", "SIP/1005,45,hHkKtTwWxX")

Como la extensión 1000 (Softphone X-Lite) no soporta SIP TLS y SRTP, las dos variable de canal estarán vacías.

-- Executing [1000@externas:1] NoOp("SIP/1005-00000014", "Protocolo SIPTLS = 1") in new stack-- Executing [1000@externas:2] NoOp("SIP/1005-00000014", "Protocolo SRTP = 1") in new stack-- Executing [1000@externas:3] Dial("SIP/1005-00000014", "SIP/1000,45,hHkKtTwWxX")

Como la extensión 1005 (Softphone Blink) soporta SIP TLS y SRTP, las dos variables de canal tendrán el valor 1.

Consideraciones finales

Como se ha comentado en otro modulo, Asterisk siempre está en el medio de una llamada para la señalización SIP. Para el flujo media depende de la configuración del parámetro directmedia y si las extensiones se registran detrás de un NAT o no. Esto implica que es posible que se presenten estos escenarios:

SoftPhone Blink ---------------------> Asterisk -------------------------> SoftPhone X-Lite

o:

SoftPhone X-Lite ---------------------> Asterisk -------------------------> SoftPhone Blink

El el primer caso, aunque la segunda pata de la llamada no es segura, no implica que no se deban implementar los protocolo SIP TLS y SRTP cuando sea posible. Lo mismo vale para el segundo caso.

468

SIP TSL - SRTP SIP - RTP

SIP TSL - SRTPSIP - RTP

Page 480: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 481: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XXIV

Openfire y Asterisk

24.1 Instalación de Openfire

Openfire es un servidor Jabber. Con Openfire instalado se tendrá un servidor de mensajería instantánea sin tener que acudir a servicios de terceros. Esto implica tener una red de mensajería instantánea privada, fácilmente manejable y segura gracias al uso del protocolo TLS. ¿Porque Openfire?. Entre tantos servidores con protocolo XMMP Openfire se destaca por la sencillez de la instalación, la administración desde una página Web, su multiplicidad de funciones y la posibilidad de ser integrado con Asterisk. Openfire es escrito en java y, para que funcione, hay que instalar la JDK (Java SE Development Kit) o instalar (la opción que se usará) la versión OpenSource del java development Kit

yum install java-1.6.0-openjdk*

Terminada la instalación se controla la versión instalada:

java -versionjava version "1.6.0_20"OpenJDK Runtime Environment (IcedTea6 1.9.10) (rhel-1.23.1.9.10.el5_7-i386)OpenJDK Client VM (build 19.0-b09, mixed mode)

Se descarga el servidor jabber Openfire:

cd /opt

wget http://www.igniterealtime.org/downloadServlet?filename=openfire/openfire_3_7_1.tar.gz

se descomprime

tar -xf openfire_3_7_1.tar.gz

Se entra en la carpeta bin

cd /opt/openfire/bin

Se modifica el script de inicio:

nano openfire

modificando esta linea:# INSTALL4J_JAVA_HOME_OVERRIDE=

para que quede:

INSTALL4J_JAVA_HOME_OVERRIDE=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0

Page 482: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se inicia:

./openfire start

Se averigua que esté corriendo

./openfire status

Si aparece:

The daemon is running.

El servidor está funcionando.

Ahora hay que configurarlo. Openfire para registrar los datos puede utilizar una base de datos interna o externa. En este caso se usará MySQL.

Se crea la base de datos en MySQL

mysqladmin create openfire -u root -psesamo

Se entra en el cliente de mysql:

mysql -u root -psesamo

Se crea un usuario y se le otorgan todos los permisos para manejar la base de datos Openfire

mysql> GRANT ALL PRIVILEGES ON openfire.* TO 'openfire'@'localhost' IDENTIFIED BY 'sesamo';

Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

mysql> quit

Bye

sesamo es la contraseña del usuario openfire

Ahora se importan las tablas para la base de datos

mysql openfire < /opt/openfire/resources/database/openfire_mysql.sql -u root -psesamo

471

Page 483: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para que Openfire sea accesible desde afuera de la red local hay que abrir unos puertos en el cortafuegos.

nano /etc/sysconfig/iptables

Después de este bloque:

# Monit-A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT

Se añade:

# Openfire-A INPUT -p tcp -m state --state NEW -m tcp --dport 5222:5223 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 5275 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 7070 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 7443 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 9090 -j ACCEPT-A INPUT -p tcp -m state --state NEW -m tcp --dport 9091 -j ACCEPT

Se guardan los cambios y se reinicia iptables:

service iptables restart

Una vez configurado el firewall se accede a la pagina de configuración de Openfire. En la barra de la direcciones del navegador se escribe:

http://IPservidor:9090

en lugar de IPservidor se pone la dirección IP del servidor Linux o, si se tiene un dominio registrado, el nombre (Ej. www.ejemplo.com)

aparecerá una pagina de configuración:

472

Page 484: Libro Asterisk 1.8.X - Versión 1.0 (1)

se elige el idioma

Se configura el nombre del dominio o la dirección IP:

Se elige el tipo de base de datos que se utilizará:

473

Page 485: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se configura el acceso a MySQL y la base de datos:

En seteos de perfil se elige la opción “por defecto”

474

Page 486: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se configura el correo electrónico y la cuenta del administrador:

El servidor está listo para funcionar.

475

Page 487: Libro Asterisk 1.8.X - Versión 1.0 (1)

Antes de entrar en la página de administración de Openfire hay que parar y volver a arrancar el servidor:

/opt/openfire/bin/openfire stop/opt/openfire/bin/openfire start

Ahora se puede configurar el servidor; crear usuarios, instalar plugins, crear conferencias y otras cuantas funciones.

Para probar la conexión el cliente predefinido de Openfire es Spark (en este caso para Windows). Hay que descargarlo, instalarlo y abrirlo. Se pone come usuario admin, que es el que se ha creado a lo largo de la configuración de Openfire, y se presiona Login:

Después de unos segundos:

476

Page 488: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pueden configurar más usuarios y grupos desde la pagina de administración

Si se quiere iniciar Openfire en automático:

cd /opt/openfire/bin/extra/redhat

nano openfire-sysconfig

Se modifican estas lineas:

#OPENFIRE_HOME=""#OPENFIRE_USER="daemon"#OPENFIRE_PIDFILE="/var/run/openfire.pid"#OPENFIRE_LOGDIR="/some/where/logs"#OPENFIRE_OPTS="-Xmx1024m"#JAVA_HOME=/usr/java/default

para que queden

OPENFIRE_HOME="/opt/openfire"OPENFIRE_USER="root"OPENFIRE_PIDFILE="/var/run/openfire.pid"OPENFIRE_LOGDIR="/var/log"

477

Page 489: Libro Asterisk 1.8.X - Versión 1.0 (1)

OPENFIRE_OPTS="-Xmx256m"JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0

Se guardan los cambios y se copia el archivo en la carpeta /etc/sysconfig:

cp openfire-sysconfig /etc/sysconfig/openfire

Ahora se instala el servicio:

cp openfire /etc/init.d/openfired

se vuelve ejecutable:

chmod +x /etc/init.d/openfired

y se añade a los servicios:

chkconfig --add openfiredchkconfig openfired on

Para averiguar si Openfire arranca en automático se hace un un reboot de la maquina Linux.

reboot

Se vuelve a entrar en el servidor y se averigua que openfire esté corriendo:

/etc/init.d/openfired statusopenfire is running

24.2 Instalar el Plugin SIPPhone en Openfire

En este párrafo se verá come instalar el plugin SIPPhone para Openfire. Este plugin permite asociar a un usuario registrado en Openfire una cuenta SIP o extensión Asterisk. Luego se instala el mismo plugin en el cliente Spark y desde éste se podrán efectuar llamadas usando el dialplan configurado en Asterisk.

Desde un navegador Web entramos en la pagina de administración.

478

Page 490: Libro Asterisk 1.8.X - Versión 1.0 (1)

En el menú Plugins se escoge Available Plugins en el menú de la izquierda. Dependiendo de los plugins que ya se instalaron, aparecerá una lista de los plugins disponibles entre los cuales:

Se presiona el botón a la derecha del plugin para instalarlo. Se presiona el botón Server en la barra del menú. En la segunda línea del menú habrá un nuevo menú: “Phone”. Se presiona para entrar en el menú de configuración del plugin.

Se escoge “Agregar nuevo mapeo” y se rellenan los campos:

479

Page 491: Libro Asterisk 1.8.X - Versión 1.0 (1)

• Nombre de usuario XMPP : el nombre del usuario openfire• Nombre de usuario : el numero o nombre de la extensión• Usuario de Autorización : el numero o nombre de la extensión• Numero de teléfono a mostrar : el numero que aparecerá al llamado• Clave: la contraseña asociada a la extensión• Servidor: el nombre del dominio o IP del servidor Asterisk• Outbound Proxy : si se utiliza un proxy para conectarse al servidor Asterisk hay que indicarlo

aquí sino se pone la dirección IP o el nombre de dominio del servidor Asterisk• Numero Correo de voz : como en el dialplan se ha definido que para acceder al buzón de voz

se utiliza la extensión 97, se pone aquí el numero

Se presionas el botón “Crear” para guardar la configuración. Se repite la misma operación para todos los usuarios que se quiere asociar a una extensión de Asterisk. Una vez terminado hay que configurar el cliente Spark que es el único que funciona con este plugin.

Se abre el cliente Spark y se abre una conexión con el nombre de usuario configurado arriba (en este caso admin).

En el menú del cliente Spark se elige Spark → Plugins y en Plugins disponibles Phone client y se instala:

480

Page 492: Libro Asterisk 1.8.X - Versión 1.0 (1)

Cuando se termina de descargar el plugin, se cierra el cliente y se vuelve a iniciar. En el menú acciones se elige Phone Enabled. Aparecerá el cliente SIP en una nueva línea del menú de Spark y se podrá empezar a usarlo para hacer llamadas.

Ahora se puede hacer una primera prueba. Desde la extensión 1001 se marca la extensión 1000. Spark debería empezar a timbrar:

481

Page 493: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si se quiere usar un único programa para chatear, hacer llamadas VoIP y, como se verá en el próximo párrafo, monitorear las extensiones, esta es una buena solución.

24.3 El Plugin Asterisk-IM

Asterisk-IM permite asociar a cada usuario Openfire una extensión SIP configurada en sip.conf. De este modo cuando esa extensión está hablando, en el cliente jabber Spark el estado del usuario Openfire asociado con la extensión cambiará de disponible a “on the phone”.

Requisitos:

• haber instalado openfire con una base de datos externa (Mysql)• haber puesto el parámetro callevents=yes en la parte general del archivo sip.conf• haber configurado un usuario en el archivo manager.conf

Se modifica el archivo manager.conf:

nano /etc/asterisk/manager.conf

Al final del archivo se añade un nuevo usuario:

[openfire]secret = sesamodeny=0.0.0.0/0.0.0.0permit=127.0.0.1/255.255.255.255read=system,call,agent,user,dtmf,reporting,cdr,dialplan,agi,cc,aocwrite=system,call,agent,user,config,command,reporting,otiginate,agi,aoc

Se actualiza la configuración de Asterisk:

/etc/init.d/asterisk reload

482

Page 494: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se instala el plugin en Openfire. Desde un navegador Web se abre la pagina de administración de Openfire y se va al menú Plugins. Se presiona el menú “Available Plugins”

Para instalarlo se presiona el botón que aparece al fondo de la línea del plugin. Una vez instalado en el barra de los menú, habrá una nueva voz, Asterisk IM.

Se escoge el menú Asterisk-IM y luego General Settings. Se configura siguiendo las pautas indicadas en la imagen que sigue:

Se presiona el botón SAVE. En la misma ventana se escoge el menú Add Server y se configura la conexión al Asterisk Manager

483

Page 495: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la pagina que aparece se configura como en la imagen que sigue:

• Server Name: un nombre que se quiere asignar al servidor• Server Address: dirección IP o nombre de dominio del servidor Asterisk (en este caso como se

encuentra en el mismo servidor Linux, se pone localhost• Port: el puerto para conectarse a la AMI de Asterisk• Username: el nombre de usuario definido en el archivo manager.conf• Password: la contraseña configurada en el manager.conf

Se presiona el botón “Create Server”. La bolita verde a la izquierda indica che hay conexión con Asterisk.

Para averiguar que efectivamente el usuario Openfire esté conectado al Asterisk Manager se entra en la

484

Page 496: Libro Asterisk 1.8.X - Versión 1.0 (1)

consola de Asterisk:

asterisk -rvvvvvvvvvvvvvv

se digita el comando:

CLI> manager show connected

Username IP Address Start Elapsed FileDes HttpCnt Read Write openfire 127.0.0.1 1323817682 79 10 0 04079 04851

Se guardan los cambios y se entra en el menú Phone Mappings:

Se configuran todos los usuarios de Openfire que se quiere asociar con una extensión SIP presente en el servidor Asterisk. Para guardar los cambios, se presiona el botón “Add”.

Desde el cliente Spark se abre una conexión con el usuario admin que se ha configurado en Phone Mappings.

Desde el cliente Spark se marca el 97 para entrar en la buzón de voz, en el cliente Spark cambiará el estado del usuario admin:

Como cambiará en el cliente X-Lite:

485

Page 497: Libro Asterisk 1.8.X - Versión 1.0 (1)

24.4 Asterisk como cliente en Openfire

La configuración de Asterisk como cliente jabber en Openfire es parecida a la de GoogleTalk (párrafo 5.1). Se empieza con la modifica del archivo jabber.conf presente en la carpeta /etc/asterisk.

nano /etc/asterisk/jabber.conf

Al final del archivo, se copian las siguientes lineas:

[asterisk] ; etiqueta que define la conexión (importante para las funciones Jabberstatus y Jabbersend de Asterisk)

type=client ; Asterisk actuará como un cliente (las opciones son cliente, componente y server)

serverhost=localhost; el nombre de dominio o IP del servidor Openfire

username=asterisk@localhost/openfire ; Nombre del usuario Openfire del servidor asterisk

secret=sesamo; la contraseña

priority=10; el nivel de prioridad que tiene en cliente en caso de conflictos (ej: dos conexiones simultaneas del mismo usuario)

port=5222 ; el puerto TCP del servidor Openfire usado para conectarse

usetls=yes ; Usar el protocolo TLS

usesasl=yes; Usar el protocolo SASL

486

Page 498: Libro Asterisk 1.8.X - Versión 1.0 (1)

buddy=admin@localhost ; la lista de amigos, uno por línea

statusmessage=Asterisk server ; un mensaje personalizado del usuario

timeout=100 ;

Se guardan los cambios y antes de actualizar la configuración de Asterisk se configura este usuario en Openfire. Desde un navegador Web se entra en la pagina de administración de Opnefire

En la barra de menú se escoge “Users/Groups” y luego en el menú vertical en la izquierda “Create New User”

• Username: el nombre de usuario Openfire• Name: el nombre completo o un apodo• Email: la dirección del correo electrónico del usuario (personalizar)• Password: la contraseña creada en el jabber.conf (sesamo)• Confirm Password: otra vez la contraseña

487

Page 499: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se termina presionando el botón “Create User”.

Ya se puede recargar la configuración de Asterisk:

/etc/init.d/asterisk reload

Se averigua el resultado desde la consola de Asterisk

asterisk -rvvvvvvvvvvvv

CLI> jabber show connected Jabber Users and their status: User: asterisk@localhost/openfire - Connected

Para ver la lista de amigos:

CLI> jabber show buddies Client: asterisk@localhost/openfire Buddy: admin@localhost Resource: None

En el menú “Sessions” de Openfire:

Se inicia el cliente Spark y se añade el usuario asterisk.

488

Page 500: Libro Asterisk 1.8.X - Versión 1.0 (1)

El resultado será:

24.5 Conectar dos servidores Openfire

Si se conectan dos servidores Openfire entre ellos, los usuarios de uno podrán agregar en su lista de amigos usuarios del otro servidor. Para lograr este tipo de comportamiento hay que modificar la configuración en los dos servidor:

Los dos servidores están instalados en dos computadores de la misma LAN:

Openfire A dominio: li115-178.members.linode.com Openfire B dominio: li340-16.members.linode.com

• Primero: si hay un cortafuegos por el medio, hay que abrir el puerto 5269 TCP en ambos• Segundo: se entra en la pagina de administración del servidor A y se escoge el menú Server →

489

Page 501: Libro Asterisk 1.8.X - Versión 1.0 (1)

Server Settings → Server to Server

Se configura la página como sigue:

Luego se pasa al menú Server > Server settings > Security settings y bajo el cuadro Server Connection Security se selecciona la casilla:

490

Page 502: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se guardan los cambios y se sigue el mismo procedimiento en el servidor B indicando el dominio: li340-16.members.linode.com en la White List.

Se guardan los cambios. La conexión se activa solamente cuando de un servidor se envía una solicitud a otro servidor. Para probarla en el servidor B se crea un nuevo usuario (menú Users/Groups → Create New User):

Ahora desde el cliente Spark conectado al servidor A, se añade a la lista de amigos el usuario servidorb:

491

Page 503: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se entra en el menú Sessions > Server Session de ambos servidores donde debería aparecer:

Servidor A:

Servidor B:

492

Page 504: Libro Asterisk 1.8.X - Versión 1.0 (1)

Si no aparece ninguna conexión se puede usar el programa Telnet para averiguar si el puerto 5269 TCP esté efectivamente abierto. Desde la consola de Linux del servidor A se escribe:

yum install telnet

telnet

telnet> o -a li340-16.members.linode.com 5269

Trying 96.126.115.16...Connected to li340-16.members.linode.com.Escape character is '^]'.</stream:stream>Connection closed by foreign host.

Si aparece la expresión en negrita todo está bien.

Para tres o más servidores Openfire, que queremos conectar entre ellos, se sigue el mismo procedimiento.

24.6 Openfire Connection Manager

Si hay que manejar un numero considerable de usuarios (más de 1000 en linea a la vez), hay que recurrir al Connection Manager. Este programa se configura delante del servidor Openfire y gestiona las conexiones y las autenticaciones de los usuarios. Se pueden instalar uno o más Connection Manager según el numero de usuarios. Cada Connection Manager es capaz de manejar cinco mil usuarios. El esquema de funcionamiento es el que aparece en la imagen que sigue:

En ese ejemplo hay tres Connection Managers instalados que reciben los registros de los usuarios y a su vez están conectados con el servidor Openfire. Los clientes tendrán que conectarse a ese servidor y luego serán enrutados por el Connection Manager al servidor Openfire.

Se descarga el programa:

493

Page 505: Libro Asterisk 1.8.X - Versión 1.0 (1)

cd /opt

wget http://www.voztovoice.org/tmp/connection_manager_3_6_3.tar.gz

Se descomprime:

tar -xf connection_manager_3_6_3.tar.gz

Se entra en la carpeta de configuración y se modifica el archivo manager.xml

cd /opt/connection_manager/conf

nano manager.xml

Las líneas que hay que modificar son:

• domain: el nombre de dominio del servidor Openfire (ej: miodominio.org)

• hostname: la dirección IP del servidor Openfire

• port: el puerto configurado en el servidor Openfire para aceptar las conexiones del Connection Manager (5262 predefinido)

• password: la contraseña que se ha definido en el servidor Openfire para aceptar las conexiones del Connection Manager

• name: un nombre que se quiere asignar a el Connection Manager (muy útil si se tiene planeado instalar más de uno).

• interface: dirección IP o nombre de dominio donde el Connection Manager aceptará las conexiones.

Se guardan los cambios.

Para terminar se instala el “script” para iniciar Connection Manager en automático:

cd /opt/connection_manager/bin/extra

nano cmanagerd

Se modifican las siguientes líneas:

export CMANAGER_HOME=/opt/connection_manager

export CMANAGER_USER=root

494

Page 506: Libro Asterisk 1.8.X - Versión 1.0 (1)

CMD="./cmanager.sh $1"

Se guardan los cambios y se termina:

cp cmanagerd /etc/init.d/

chmod +x /etc/init.d/cmanagerd

chkconfig –add cmanagerd

chkconfig cmanagerd on

Antes de arrancar el Connection Manager hay que modificar la configuración del servidor Openfire. Desde la pagina di administración del servidor Openfire bajo el menú “Server settings” se elige “Connection Manager”. En la pagina que aparece se activa el servicio, se escoge el puerto y se define una contraseña.

Se presiona el botón “Save Settings”. Se abre el puerto 5262 TCP en el cortafuegos.

Ahora se puede arrancar el Connection Manager. En el servidor Linux donde se instaló se escribe:

/etc/init.d/cmanagerd start

Se averigua que esté corriendo:

/etc/init.d/cmanagerd statusrunning pid is 5747Connection Manager 3.6.3 [Feb 6, 2010 5:02:17 AM]

y en la pagina de administración de Openfire se verifica que está conectado:

495

Page 507: Libro Asterisk 1.8.X - Versión 1.0 (1)

Desde un cliente XMPP se abre una conexión usando como dirección IP o nombre de Dominio la que se ha configurado en la linea “interface” del archivo manager.xml

496

Page 508: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 509: Libro Asterisk 1.8.X - Versión 1.0 (1)

Capitulo XXV

Asterisk y alta disponibilidad

El servidor Asterisk ya está instalado y trabajando. Ahora se quiere tener una copia de la base de datos actualizada en tiempo real para hacer frente a cualquier tipo de evento que pueda afectar la integridad de los registros de las llamadas o de las configuraciones en Realtime. En este tipo de escenario hay disponible una funcionalidad de MySQL; la posibilidad de replicar los datos en un servidor MySQL instalado en otro computador. Hay dos formas de replicar los datos:

• configurar una replicación master-slave (maestro-esclavo)• configurar una replicación master-master (maestro-maestro)

Como no se pueden tener los dos tipos de configuraciones activas a la vez, antes de empezar, habrá que escoger el tipo que se quier implementar

25.1 Replicación MySQL Master-Slave

En este párrafo se verá como crear una replicación MySQL Master-Slave. La replicación master-slave no es una copia de backup de la base de datos, de hecho si se borra una entrada en el MySQL maestro, automáticamente se borrará también en el esclavo. La idea es tener siempre una copia de backup y además crear la replicación maestro-esclavo.

Se puede usar el esclavo para consultas desde otros programas y de esta manera no cargar demasiado el Maestro. Un ejemplo puede ser cuando se generan reportes mensuales de las llamadas. En vez de hacer las consultas en el maestro, se hacen en el esclavo.

Es buena practica usar una conexión dedicada para el intercambio de datos entre el maestro y el esclavo para evitar que hayan retrasos considerables en la actualización de la base de datos.

¿Como funciona la replicación MySQL Master-slave?

• El Maestro registra los cambios en un registro binario (Binary log)• El esclavo copia los eventos en un registro propio (Relay log)• El esclavo lee y repite los eventos presentes en el Relay log en la base de datos

Una imagen que explica el funcionamiento:

Page 510: Libro Asterisk 1.8.X - Versión 1.0 (1)

El escenario que se va a presentar es el siguiente:

ServidorA:IP LAN: 192.168.128.144Base de datos a replicar: asteriskMaster

ServidorB:IP LAN: 192.168.128.145Esclavo

Base de datos replicada: asteriskcdr

Servidor A:

Se crea una carpeta donde guardar los Binary log:

mkdir /var/log/mysql

Se cambian los permisos de modo que MySQL pueda escribir y leer en esa carpeta:

chown mysql:mysql /var/log/mysql

Se entra en el cliente mysql

mysql -u root -psesamo

y se crean los privilegios de replicación para un nuevo usuario que luego se configurará en el servidorB:

499

Page 511: Libro Asterisk 1.8.X - Versión 1.0 (1)

myslq> GRANT REPLICATION SLAVE ON *.* TO 'asterisk'@'192.168.128.145' IDENTIFIED BY 'sesamo';

Se actualizan los privilegios y se sale del cliente MySQL:

mysql> flush privileges;

mysql> quit

Ahora se modifica el archivo de configuración de MySQL para configurar los parámetros necesarios para la replicación:

nano /etc/my.cnf

Bajo la etiqueta [mysqld] se añaden las siguientes líneas:

server-id = 10log_bin = /var/log/mysql/mysql-bin.logexpire_logs_days = 10max_binlog_size = 100Mbinlog_do_db = asteriskcdrsync_binlog=1

Una pequeña explicación de los parámetros:

• server-id: identifica el servidor MySQL• log_bin: nombre del archivo donde se guardará el Binary log• expire_log_days: especifica que los archivos Binary log más viejos de 10 días se pueden borrar• max_binlog_size: el tamaño máximo de un Binary log• binlod_do_db: el nombre de la base de datos que se va a replicar• sync_binlog: cada evento generado en el Master será escrito inmediatamente en el Binary log.

Aumenta la carga del Master a cambio de una replicación más precisa

Se guardan los cambios y se reinicia MySQL

/etc/init.d/mysqld restart

Considerando que el servidor Asterisk tiene tiempo trabajando hay que crear una copia de la base de datos para luego importarla en el servidor MySQL esclavo:

mysql -u root -psesamo

Primero se selecciona la base de datos asteriskcdr:

mysql> use asteriskcdr

500

Page 512: Libro Asterisk 1.8.X - Versión 1.0 (1)

Segundo se bloquea la lectura de todas las tablas de todas las bases de datos:

mysql> FLUSH TABLES WITH READ LOCK;

Por ultimo se mira el estado del Master:

mysql> SHOW MASTER STATUS;

Aparecerá algo por el estilo:+------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 98 | asteriskcdr | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)

Se anotan los datos que aparecen en la columna File (mysql-bin.000001) y en la columna Position (98). Sin cerrar esta ventana, se abre otra ventana terminal o otra conexión al servidor Linux y se crea una copia de la base de datos asteriskcdr:

cd /tmp

mysqldump -u root -psesamo asteriskcdr > asteriskslave.sql

se copia el archivo en el servidoB en la carpeta tmp:

scp asteriskslave.sql [email protected]:/tmp

Se cierra esta ventana y se vuelve a la primera. Se desbloquean las tablas:

mysql> UNLOCK TABLES;

y se sale del cliente:

mysql> quit

Servidor B

Si MySQL, no está instalado se instala:

yum install mysql mysql-server mysql-devel

Se inicia:

/etc/init.d/mysqld start

501

Page 513: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se crea una contraseña para el usuario root:

mysqladmin –u root password sesamo

Se modifica el archivo de configuración de MySQL

nano /etc/my.cnf

bajo la etiqueta [mysqld] se pone:

server-id=20master-connect-retry=60replicate-do-db=asteriskcdrskip_slave_startread_only

Los parámetros:

• server-id: numero que identifica el servidor MySQL del servidorB• master-connect-retry: si el esclavo pierde la conexión con el maestro, cada 60 segundos

intentará restablecerla• replicate-do-db: la base de datos que vamos a replicar• skip_slave_start: evita que el esclavo se reinicie en el caso de un crash del servidor• read_only: no permite a la mayoría de los usuarios del servidor MySQL esclavo cambiar las

tablas

Se guardan los cambios y se reinicia MySQL:

/etc/init.d/mysqld restart

Se crea la base de datos asteriskcdr:

mysqladmin -u root -psesamo create asteriskcdr

se recuperan tablas y datos de la copia que está en la carpeta /tmp:

cd /tmp

mysql -u root -psesamo asteriskcdr < asteriskslave.sql

A este punto se crean los datos de acceso al servidor MySQL Master:

mysql -u root -psesamo

mysql> CHANGE MASTER TO MASTER_HOST='192.168.128.144',

502

Page 514: Libro Asterisk 1.8.X - Versión 1.0 (1)

MASTER_USER='asterisk', MASTER_PASSWORD='sesamo', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

En MASTER_LOG_FILE Y MASTER_LOG_POS, se ponen los datos del servidor MySQL A que se habían anotado.

Antes de iniciar el esclavo, hay que abrir el puerto TCP 3306 en el servidor A. Se hace indicando que la única IP que podrá conectarse será la del Servidor B:

nano /etc/sysconfig/iptables

Después de este bloque:

# Monit-A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT

Se pone:

# MySQL-A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.128.145 --dport 3306 -j ACCEPT

Se guardan los cambios y se reinicia iptables:

service iptables restart

Se vuelve a la ventana del servidorB y se inicia el esclavo:

mysql> START SLAVE;

Se controla el estado de la conexión con el Master:

mysql> SHOW SLAVE STATUS\G*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.142.248 Master_User: fulanoMaster_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes

503

Page 515: Libro Asterisk 1.8.X - Versión 1.0 (1)

Replicate_Do_DB: asteriskcdr Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 1 row in set (0.00 sec)

Se sale del cliente:

mysql> quit

Ahora se efectúa una llamada de prueba. Desde la extensión 1000 conectada al servidorA se llama el buzón de voz. Antes de hacerlo se activa en el servidorB la captura de paquetes con Ngrep para el puerto 3306 y la red local:

ngrep -d eth0:1 -W byline port 3306 > /tmp/esclavo

Terminada la llamada, se cierra la captura de paquetes y se mira que contiene el archivo /tmp/esclavo

El servidorA (192.168.128.144) ha enviado tress paquetes al servidorB (192.168.128.145) para actualizar las tablas CDR, CDR2 y CDR3 de la base de datos asteriskcdr del servidor B.

25.2 Replicación MySQL Master-Master

En el párrafo anterior se ha visto como usar la replicación MySQL Master-Slave para la base de datos de asteriskcdr. En éste se verá como utilizar la replicación MySQL Master-Master para la base de datos asteriskcdr solamente para la tabla CDR.

¿Qué diferencia hay entra una replicación Maestro-Esclavo y una Maestro-Maestro?

504

Page 516: Libro Asterisk 1.8.X - Versión 1.0 (1)

En el primer caso se tiene una copia de todos los registros en otro servidor y se pueden efectuar estadísticas usando el Esclavo sin sobrecargar el Maestro. En el segundo caso la configuración se utiliza para la alta disponibilidad en Asterisk. Ejemplo: hay dos servidores Asterisk: A y B. Si A se cae B toma su lugar. Cuando A vuelve a funcionar, B vuelve a ser el servidor de respaldo. Como se verá en los próximos párrafos, para la alta disponibilidad en Asterisk, además de la replicación Master-Master, se necesitará configurar otros programas.

Escenario:

ServidorA:IP 192.168.128.144Base de datos a replicar: asteriskcdr – Tabla: cdrMasterA SlaveA

ServidorB:IP 192.168.128.145Base de datos a replicar: asteriskcdr – Tabla: cdrMasterB SlaveB

La tabla CDR en el ServidorA ya existe y tiene unos cuantos datos registrados. El problema principal de la replicación Master-Master es el conflicto que se puede presentar en las entradas de la tabla.

Ejemplo: el servidorA se cae y toma su lugar el servidorB. Se registran unos cuantos datos en la tabla cdr del servidorB. Mientras el servidorA vuelve a funcionar y antes que el servidorB pueda actualizar los datos de la tabla CDR en el servidorA, este empieza a grabar nuevas entradas en la misma tabla. En este escenario se pueden generar conflictos entre los datos de las dos tablas y errores de replicación porque los dos presentan entradas con el mismo ID en la clave primaria de la tabla (siendo progresivo).

Para solucionar este tipo de problema se usarán estos dos parámetros:

• auto_increment_increment• auto_increment_offset

ServidorA

Se entra en el cliente MySQL y se consultan las fechas de las llamadas de la extensión 1000:

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> select id,calldate from cdr where dst=1000;+----+---------------------+| id | calldate |+----+---------------------+| 21 | 2011-12-14 13:21:42 |

505

Page 517: Libro Asterisk 1.8.X - Versión 1.0 (1)

| 55 | 2011-12-15 09:01:57 || 56 | 2011-12-15 09:03:10 || 57 | 2011-12-15 09:03:28 || 58 | 2011-12-15 09:03:56 |+----+---------------------+5 rows in set (0.00 sec)

Se crea una carpeta donde guardar los Binary log de MySQL y se cambia usuario y grupo que tiene los permisos en la carpeta creada:

mkdir /var/log/mysql

chown mysql:mysql /var/log/mysql

Se regresa al cliente MySQL y se crean los privilegios de replicación para un nuevo usuario:

mysql -u root -psesamo

mysql> GRANT REPLICATION SLAVE ON *.* TO 'masterb'@'192.168.128.145' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Se modifica el archivo de configuración de MySQL:

nano /etc/my.cnf

bajo la etiqueta [mysqld] se pone:

server-id = 10auto_increment_increment = 10auto_increment_offset = 1log_bin = /var/log/mysql/mysql-bin.logexpire_logs_days = 10max_binlog_size = 100Mreplicate-do-table =asteriskcdr.cdrsync_binlog =1

Los parámetros:

• Con auto_increment_increment a 10 cada entrada en la tabla cdr tendrá un ID progresivo que irá de 10 en 10.

• Con auto_increment_offset a 1 cada entrada usará el entero 1

506

Page 518: Libro Asterisk 1.8.X - Versión 1.0 (1)

En el caso de tres entradas en la tabla el resultado será:

ID 1ID 11ID 21

• Con replicate-do-table se define que la replicación es solamente para la tabla cdr de la base de datos asteriskcdr

Se reinicia mysql:

/etc/init.d/mysqld restart

Considerando que el servidor Asterisk tiene tiempo trabajando hay que crear una copia de la base de datos para luego importarla en el servidorB:

mysql -u root -psesamo

Primero se selecciona la base de datos asterisk:

mysql> use asteriskcdr

Segundo se bloquea la lectura de todas las tablas de todas las bases de datos:

mysql> FLUSH TABLES WITH READ LOCK;

Por ultimo se mira el estado del Master:

mysql> SHOW MASTER STATUS;

Aparecerá algo por el estilo:+------------------+----------+--------------+------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000001 | 98 | asterisk | |+------------------+----------+--------------+------------------+1 row in set (0.00 sec)

Se anotan los datos que aparecen en la columna File (mysql-bin.000001) y en la columna Position (98); sin cerrar esta ventana, se abre otra ventana terminal o otra conexión al servidor Linux y se crea una copia de la base de datos asteriskcdr:

cd /tmp

mysqldump -u root -psesamo asteriskcdr > cdr.sql

se copia el archivo en el servidorB en la carpeta tmp:

507

Page 519: Libro Asterisk 1.8.X - Versión 1.0 (1)

scp cdr.sql [email protected]:/tmp

Se cierra esta ventana y se regresa a la primera. Se desbloquean las tablas:

mysql> UNLOCK TABLES;

y se sale del cliente:

mysql> quit

ServidorB

Se crea la carpeta para guardar los Bynary log con los permisos para el usuario mysql:

mkdir /var/log/mysql

chown mysql:mysql /var/log/mysql

Se entra en el cliente mysql y se crea la base de datos asterisk:

mysql -u root -psesamo

mysql> create database asteriskcdr;

mysql> quit

Se importa la tabla cdr:

cd /tmp

mysql -u root -psesamo asteriskcdr < cdr.sql

Se averigua que efectivamente las tabla y los datos presentes se han guardado:

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> select id,calldate from cdr where dst=1000;+----+---------------------+| id | calldate |+----+---------------------+| 21 | 2011-12-14 13:21:42 || 55 | 2011-12-15 09:01:57 || 56 | 2011-12-15 09:03:10 |

508

Page 520: Libro Asterisk 1.8.X - Versión 1.0 (1)

| 57 | 2011-12-15 09:03:28 || 58 | 2011-12-15 09:03:56 |+----+---------------------+5 rows in set (0.00 sec)

Aparecerán las mismas entradas del servidorA. Se crea un nuevo usuarios con los permisos de replicación:

mysql> GRANT REPLICATION SLAVE ON *.* TO 'mastera'@'192.168.128.144' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Ahora se modifica el archivo de configuración de MySQL:

nano /etc/my.cnf

bajo la etiqueta [mysqld] se pone:

server-id = 20auto_increment_increment = 10auto_increment_offset = 2log_bin = /var/log/mysql/mysql-bin.logexpire_logs_days = 10max_binlog_size = 100Mreplicate-do-table =asteriskcdr.cdrsync_binlog =1

El auto_increment_offset es igual a 2. En el caso de tres entradas el ID sería:

ID 2ID 12ID 22

Como se puede ver, de esta forma no se presentarán conflictos en las entradas de la tabla CDR. Se reinicia Mysql:

/etc/init.d/mysqld restart

Y ahora como para el servidorA se mira el Binary log y se anotan los datos:

mysql -u root -psesamo

mysql> FLUSH TABLES WITH READ LOCK;

509

Page 521: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql> SHOW MASTER STATUS;+------------------+----------+--------------+------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000001 | 98 | | |+------------------+----------+--------------+------------------+1 row in set (0.00 sec)

mysql> quit

Para dar acceso a la base de datos al servidorA, hay que abrir el puerto TCP 3306 solamente para esa IP local:

nano /etc/sysconfig/iptables

En la sección filter se añade:

# MySQL-A INPUT -p tcp -m state --state NEW -m tcp -s 192.168.128.144 --dport 3306 -j ACCEPT

Se reinicia el servicio:

service iptables restart

Ahora se conecta el servidorB al servidorA:

mysql -u root -psesamo

mysql> CHANGE MASTER TO MASTER_HOST='192.168.128.144', MASTER_USER='masterb', MASTER_PASSWORD='sesamo', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;Query OK, 0 rows affected (0.00 sec)

Se inicia el esclavo:

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

y se mira el resultado:

mysql> SHOW SLAVE STATUS\G*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.142.248

510

Page 522: Libro Asterisk 1.8.X - Versión 1.0 (1)

Master_User: masterb Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: asteriskcdr.cdr Replicate_Ignore_Table: Replicate_Wild_Do_Table:Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 01 row in set (0.00 sec)

Se sigue el mismo procedimiento para el ServidorA:

mysql -u root -psesamo

mysql> CHANGE MASTER TO MASTER_HOST='192.168.128.145', MASTER_USER='mastera', MASTER_PASSWORD='sesamo', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;Query OK, 0 rows affected (0.10 sec)

mysql> START SLAVE;

mysql> SHOW SLAVE STATUS\G

511

Page 523: Libro Asterisk 1.8.X - Versión 1.0 (1)

*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.146.90 Master_User: mastera Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: asterisk.cdr Replicate_Ignore_Table: Replicate_Wild_Do_Table:Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 01 row in set (0.00 sec)

La prueba

Se para el MySQL del servidorB y se efectúan dos llamadas desde la extensión 1000 del Asterisk A al buzón de voz.

El resultado en la base de datos:

mysql -u root -psesamo

mysql> use asteriskcdr

512

Page 524: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql> select id,calldate from cdr where dst=97;+----+---------------------+| id | calldate |+----+---------------------+| 32 | 2011-12-14 18:06:06 || 54 | 2011-12-15 08:51:20 || 61 | 2011-12-15 09:33:23 || 71 | 2011-12-15 09:33:48 |+----+---------------------+4 rows in set (0.00 sec)

Mientras antes el ID era progresivo, las ultimas dos entradas tienen un salto de 10 y cada una termina con el numero 1.

Terminada la operación, se para MySQL en el servidorA y se inicia MySQL en el servidorB efectuando dos llamadas al buzón de voz usando el Asterisk del servidorB.

El resultado en la base de datos:

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> select id,calldate from cdr where dst=97;+----+---------------------+| id | calldate |+----+---------------------+| 32 | 2011-12-14 18:06:06 || 54 | 2011-12-15 08:51:20 || 61 | 2011-12-15 09:33:23 || 71 | 2011-12-15 09:33:48 || 72 | 2011-12-15 09:38:07 || 82 | 2011-12-15 09:39:14 |+----+---------------------+6 rows in set (0.00 sec)

El ID progresivo en el servidorB cambia con saltos de 10 y cada entrada termina con el numero 2. Ahora se inicia MySQL en el servidorA y se mira que pasa en los dos servidores:

ServidorA

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> select id,calldate from cdr where dst=97; +----+---------------------+

513

Page 525: Libro Asterisk 1.8.X - Versión 1.0 (1)

| id | calldate |+----+---------------------+| 32 | 2011-12-14 18:06:06 || 54 | 2011-12-15 08:51:20 || 61 | 2011-12-15 09:33:23 || 71 | 2011-12-15 09:33:48 || 72 | 2011-12-15 09:38:07 || 82 | 2011-12-15 09:39:14 |+----+---------------------+6 rows in set (0.00 sec)

ServidorB

mysql -u root -psesamo

mysql> use asteriskcdr

mysql> select id,calldate from cdr where dst=97;+----+---------------------+| id | calldate |+----+---------------------+| 32 | 2011-12-14 18:06:06 || 54 | 2011-12-15 08:51:20 || 61 | 2011-12-15 09:33:23 || 71 | 2011-12-15 09:33:48 || 72 | 2011-12-15 09:38:07 || 82 | 2011-12-15 09:39:14 |+----+---------------------+6 rows in set (0.00 sec)

Los datos se han replicado y no hubo ningún tipo de conflicto en la tabla cdr gracias al uso de:

• auto_increment_increment• auto_increment_offset

25.3 DRBD - Raid1 vía TCP

DRBD es un programa que permite conectar particiones presentes en distintos servidores y tenerlas sincronizadas. Funciona en el mismo modo de un sistema RAID1 con la sencilla diferencias que las copias de los datos se hacen a través de la red usando el protocolo TCP. Se verá como instalar DRBD en dos servidores VPS en Linode y de esta forma crear un sistema de alta disponibilidad para Asterisk. Lo mismo se puede hacer con dos servidores locales con las modificaciones oportunas.

Al momento de configurar el servidor Linode, se han creado 4 particiones:

514

Page 526: Libro Asterisk 1.8.X - Versión 1.0 (1)

La ultimas dos es las que se utilizarán para DRDB. Claramente las mismas particiones tienen que ser creadas el en segundo servidor de respaldo. Una vez terminada esta operación, tendremos los dos servidores Linode listos para la instalación y configuración de DRBD.

Servidor AIP publico: 69.164.201.178 IP Lan: 192.168.128.144Dominio: li115-178.members.linode.com

Servidor BIP publico: 96.126.115.16 IP Lan: 192.168.128.145Dominio: li340-16.members.linode.com

Se inicia la configuración de los dos servidores para que cada uno sepa a que dirección IP encontrar el otro:

Servidor A

nano /etc/hosts

Al final de archivo se añaden las siguientes líneas:

192.168.128.144 li115-178.members.linode.com192.168.128.145 li340-16.members.linode.com

Se guardan los cambios y se averigua que efectivamente se logra localizar el servidor B:

ping li340-16.members.linode.com

PING li340-16.members.linode.com (192.168.128.145) 56(84) bytes of data.64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=1 ttl=64 time=0.671 ms64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=2 ttl=64 time=0.430 ms64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=3 ttl=64 time=0.405 ms64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=4 ttl=64 time=0.479 ms

515

Page 527: Libro Asterisk 1.8.X - Versión 1.0 (1)

64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=5 ttl=64 time=0.518 ms64 bytes from li340-16.members.linode.com (192.168.128.145): icmp_seq=6 ttl=64 time=0.483 ms

--- li340-16.members.linode.com ping statistics ---6 packets transmitted, 6 received, 0% packet loss, time 4997msrtt min/avg/max/mdev = 0.405/0.497/0.671/0.089 ms

Se efectua el mismo procedimiento en el servidor B

Servidor B

nano /etc/hosts

Se añaden las siguientes líneas:

192.168.128.144 li115-178.members.linode.com192.168.128.145 li340-16.members.linode.com

ping li115-178.members.linode.com

PING li115-178.members.linode.com (192.168.128.144) 56(84) bytes of data.64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=1 ttl=64 time=0.587 ms64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=2 ttl=64 time=0.422 ms64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=3 ttl=64 time=0.542 ms64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=4 ttl=64 time=0.420 ms64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=5 ttl=64 time=0.386 ms64 bytes from li115-178.members.linode.com (192.168.128.144): icmp_seq=6 ttl=64 time=0.525 ms

--- li115-178.members.linode.com ping statistics ---6 packets transmitted, 6 received, 0% packet loss, time 4996msrtt min/avg/max/mdev = 0.386/0.480/0.587/0.076 ms

Una vez terminada esta parte se prepara el sistema para la instalación de DRBD:

Las operaciones que siguen hay que ejecutarlas en ambos servidores:

cd /usr/src

wget http://oss.linbit.com/drbd/8.3/drbd-8.3.7.tar.gz

tar -xf drbd-8.3.7.tar.gz

cd drbd-8.3.7

./configure --prefix=/ --with-km --with-xen

Se compila utilizando la ultimas versión de las fuentes del Kernel-XEN instalado en el servidor, es

516

Page 528: Libro Asterisk 1.8.X - Versión 1.0 (1)

decir:

uname -r2.6.18-308.1.1.el5xen

make KDIR=/usr/src/kernels/2.6.18-308.1.1.el5-xen-i686

make install

Se mueve la configuración predefinida que viene con la instalación de DRBD

mv /etc/drbd.conf /etc/drbd.conf.old

se crea una nueva:

nano /etc/drbd.conf

Se copian las lineas que siguen en ambos servidores:

global { usage-count yes; } common { protocol C; } resource data { net { allow-two-primaries; } startup { become-primary-on both; } on li115-178.members.linode.com { device /dev/drbd1; disk /dev/xvdc; address 192.168.128.144:7789; meta-disk /dev/xvdd[0]; } on li340-16.members.linode.com { device /dev/drbd1; disk /dev/xvdc; address 192.168.128.145:7789; meta-disk /dev/xvdd[0]; } }

De esta forma se crean dos nodos primarios usando el protocolo C y se nombra este recurso creado

517

Page 529: Libro Asterisk 1.8.X - Versión 1.0 (1)

“data”.

El nodo 1 será li115-178.members.linode.com cuya IP local es 192.168.128.144 Se utilizarán las dos particiones creadas (xvdc y xvdd) una para las copia de los datos y la otra como meta disco para guardar los datos que DRBD crea al momento de conectarse y sincronizarse con el segundo nodo.

El nodo 2 será li340-16.members.linode.com cuya IP local es 192.168.128.145.

Ahora se crean los meta-datos en la partición xvdd de ambos servidores:

drbdadm create-md data

Normalmente sale este error:

Found ext3 filesystem

This would corrupt existing data.If you want me to do this, you need to zero out the first partof the device (destroy the content).You should be very sure that you mean it.Operation refused.

Command 'drbdmeta 1 v08 /dev/xvdd 0 create-md' terminated with exit code 40

Se soluciona destruyendo todos los datos presentes en la partición:

dd if=/dev/zero of=/dev/xvdd bs=1M count=128128+0 records in128+0 records out134217728 bytes (134 MB) copied, 1,2176 seconds, 110 MB/s

Se ejecuta otra vez el comando:

drbdadm create-md dataWriting meta data...initializing activity logNOT initializing bitmapNew drbd meta data block successfully created.success

Se configurara el programa para que el servicio arranque en automático:

chkconfig --add drbd

chkconfig drbd on

Para crear una primera sincronización entre los datos de las dos particiones de los dos servidores se

518

Page 530: Libro Asterisk 1.8.X - Versión 1.0 (1)

carga el modulo DRBD en el Kernel:

modprobe drbd

se averigua que efectivamente esté corriendo:

lsmod | grep drbddrbd 251364 0

Ahora se crea la conexión entre los dos servidores:

drbdadm attach data

drbdadm syncer data

drbdadm connect data

Se efectuá una primera sincronización de los datos:

Servidor A

drbdadm -- --overwrite-data-of-peer primary data

Esta operación puede durar bastante tiempo dependiendo del tamaño de los discos. Se puede controlar en cualquier momento a que punto ha llegado con el comando:

cat /proc/drbd

version: 8.3.7 (api:88/proto:86-91)GIT-hash: ea9e28dbff98e331a62bcbcc63a6135808fe2917 build by [email protected], 2011-12-15 11:24:58

1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---- ns:3672 nr:0 dw:0 dr:3672 al:0 bm:0 lo:6 pe:0 ua:6 ap:0 ep:1 wo:b oos:815528 [>....................] sync'ed: 1.0% (815528/819200)K finish: 0:42:28 speed: 252 (244) K/sec

Cuando el proceso termine, aparecerá:

cat /proc/dbd

version: 8.3.7 (api:88/proto:86-91)GIT-hash: ea9e28dbff98e331a62bcbcc63a6135808fe2917 build by [email protected], 2011-12-15 11:24:58

1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----

519

Page 531: Libro Asterisk 1.8.X - Versión 1.0 (1)

ns:819200 nr:0 dw:0 dr:819200 al:0 bm:50 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

Se reinician ambos servidores:

reboot

Servidor A

Se crea una nueva carpeta donde se copiarán los datos que se quiere sincronizar:

mkdir /home/data

Se monta la partición de los datos:

mount /dev/drbd1 /home/data

se crean unos cuantos archivos de prueba:

touch /home/data/file1 touch /home/data/file2 touch /home/data/file3

ls /home/data

file1 file2 file3 lost+found

Se desmonta la partición:

umount /home/data

y se averigua el resultado en el servidor B

Servidor B

mkdir /home/data

mount /dev/drbd1 /home/data

ls /home/data

file1 file2 file3 lost+found

umount /home/data

En el caso que se quiera tener sincronizados los archivos de configuración de Asterisk, se copian

520

Page 532: Libro Asterisk 1.8.X - Versión 1.0 (1)

directamente la carpeta de esta forma:

Servidor A

mount /dev/drbd1 /home/data

mkdir /home/data/etc

cd /etc

mv asterisk /home/data/etc/asterisk

Para terminar se crea un enlace simbólico a la nueva carpeta:

ln -s /home/data/etc/asterisk asterisk

Lo mismo con DAHDI:

mv dahdi /home/data/etc/dahdi

ln -s /home/data/etc/dahdi dahdi

umount /home/data

Servidor B

mount /dev/drbd1 /home/data

cd /etc

rm -fr asterisk

rm -fr dahdi

ln -s /home/data/etc/asterisk asterisk

ln -s /home/data/etc/dahdi dahdi

umount /home/data

Ya está configurado y funcionando DRBD. No hace falta dejar la partición montada en ninguno de los dos servidores porque, como se verá en el próximo párrafo, Heartbeat se encargará de hacerlo según el servidor que esté activo en ese momento.

25.4 Heartbeat

521

Page 533: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se termina el capitulo dedicado a Asterisk y alta disponibilidad con la instalación y configuración de Heartbeat. Heartbeat se necesita para que los dos servidores sepan el estado del otro. Cuando el master se cae, el slave toma el control cargando la partición de DRBD donde hemos guardado los datos de configuración de Asterisk, poniendo activo el IP compartido y arrancando dahdi y asterisk. Cuando se utiliza Asterisk alta disponibilidad con este tipo de configuración, habrá un IP publico compartido que es él que se utilizará para registrar las extensiones. En el caso de una red publica y de Linode sería algo parecido:

IP Servidor Asterisk MasterIP Asterisk Publico

IP servidor Asterisk Slave

Se utilizará la misma configuración que se presentó en el párrafo 25.3. Para resumir:

Servidor AIP publico: 69.164.201.178 IP Lan: 192.168.128.144

Servidor BIP publico: 96.126.115.16 IP Lan: 192.168.128.145

Primero se compra en Linode un segundo IP publico para el servidor A (costo: un dólar al mes) que será el IP “virtual” que compartirán los dos servidores. Una vez comprado, hay que configurarlo en una nueva tarjeta de red virtual:

nano /etc/sysconfig/network-scripts/ifcfg-eth0:2

Se copian las siguientes lineas:

DEVICE=eth0:2BOOTPROTO=noneONBOOT=yesIPADDR=173.255.196.191NETMASK=255.255.255.0

173.255.196.191 es la nueva IP adquirida. Se reinicia el servidor:

reboot

Luego en la pagina de administración de Linode del servidor B se configura el failover. Esto permite que al caerse el servidor A, el servidor B tomará la gestión de ese IP. En el menú “Remote Access” de la pagina de administración del Linode:

522

Page 534: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se escoge el enlace “IP Failover”. En la nueva pagina:

Se selecciona la nueva IP adquirida y se presiona el botón “Save Changes”.

Ahora hay que instalar Heartbeat. Este programa es presente en los repositorios "extras” de CentOS. Para activarlos:

nano /etc/yum.repos.d/CentOS-Base.repo

se modifica este bloque:

[extras] name=CentOS-$releasever - Extras mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras #baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

para que quede:

[extras] name=CentOS-$releasever - Extras mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

Se guardan los cambios y se instala Heartbeat:

yum install heartbeat

Por algún raro motivo hay que repetir el comando dos veces:

523

Page 535: Libro Asterisk 1.8.X - Versión 1.0 (1)

yum install heartbeat

Ahora hay que crear tres archivos de configuración:• ha.cf• authkeys• haresources

Se empieza con el que se encarga de controlar el estado de los servidores.

Servidor A:

nano /etc/ha.d/ha.cf

se pegan las siguientes líneas:

debugfile /var/log/ha-debuglogfile /var/log/ha-loglogfacility local0keepalive 2deadtime 120initdead 120ucast eth0 192.168.128.145udpport 694auto_failback onnode li115-178.members.linode.comnode li340-16.members.linode.com

Servidor B:

nano /etc/ha.d/ha.cf

debugfile /var/log/ha-debuglogfile /var/log/ha-loglogfacility local0keepalive 2deadtime 120initdead 120ucast eth0 192.168.128.144udpport 694auto_failback onnode li115-178.members.linode.comnode li340-16.members.linode.com

Ahora en ambos servidores se crea el archivo que utilizará Heartbeat para el intercambios de llaves de autentificación y el archivo donde se indicará la IP virtual compartida y los servicios que heartbeat

524

Page 536: Libro Asterisk 1.8.X - Versión 1.0 (1)

deberá gestionar. Estos archivos tienen que ser iguales en ambos servidores:

nano /etc/ha.d/authkeys

auth 3 3 md5 sesamo

Se usa como método de cifrado MD5 y después se pone la contraseña que se quiere utilizar (en este caso sesamo).

Ahora hay que cambiar los permisos de este archivo para que sea accesible (en lectura y escritura) solamente para el usuario root:

chmod 600 /etc/ha.d/authkeys

Para terminar el archivo de los recursos:

nano /etc/ha.d/haresources

Se pone:

li115-178.members.linode.com IPaddr2::173.255.196.191 drbddisk::data Filesystem::/dev/drbd1::/home/data::ext3 dahdi asterisk

IMPORTANTE: tiene que estar todo el la misma línea

Se define como servidor Master li115-178.members.linode.com y se indica como IP virtual la que se acaba de comprar. drbddisk es el script que se encarga de montar la partición donde se han guardado los archivos de configuración de Asterisk, en este caso /dev/drbd1. Por ultimo se indican los servicios que Heartbeat tiene que iniciar, en este caso dahdi y asterisk.

Estos servicios tienen que ser indicados en la carpeta etc/ha.d/resource.d. Para hacerlo se crea un enlace simbólico:

cd /etc/ha.d/resource.d

ln -s /etc/init.d/asterisk asteriskln -s /etc/init.d/dahdi dahdi

Ahora el problema. Todo parecía funcionar bien pero heartbeat no montaba la partición /dev/drbd1 y Asterisk no podía funcionar.

Revisando las cosas el script drbddisk (que viene con la instalación de Heartbeat) estaba mal configurado. Se resuelve de la siguiente forma:

nano /etc/ha.d/resource.d/drbddisk

525

Page 537: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se cambia esta linea:

DEFAULTFILE="/etc/default/drbd"

para que quede:

DEFAULTFILE="/etc/drbd.conf"

indicando donde efectivamente se encuentra el archivo de configuración de drbd. Para terminar la configuración los últimos cambios en ambos servidores:

chkconfig asterisk offchkconfig dahdi off

Esto porque es Heartbeat que se encarga de iniciar los dos programas.

chkconfig --add heartbeatchkconfig heartbeat on

Se abre el puerto UDP 694 que permite a los servicios Hertbeat instalados en los dos servidores de comunicarse entre ellos:

Servidor A

nano /etc/sysconfig/iptables

después de este bloque:

# HTTP-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

se añade:

# Heartbeat-A INPUT -p udp -m udp -s 192.168.128.145 --dport 694 -j ACCEPT

Se reinicia iptables:

service iptables restart

Servidor B

nano /etc/sysconfig/iptables

después de este bloque:

526

Page 538: Libro Asterisk 1.8.X - Versión 1.0 (1)

# HTTP-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

se añade:

# Heartbeat-A INPUT -p udp -m udp -s 192.168.128.144 --dport 694 -j ACCEPT

Se reinicia iptables:

service iptables restart

Con esta ultima operación se ha terminado la configuración de Heartbeat. Solo falta reiniciar los dos servidores y mirar si todo funciona:

reboot

Si se hace una captura de paquetes en el Servidor A, puerto 694:

ngrep -d eth0:1 -W byline port 694

Se verán una serie de paquetes de este tipo:

U 192.168.128.145:54002 -> 192.168.128.144:694>>>t=statusst=activedt=1d4c0protocol=1src=li340-16.members.linode.com(1)srcuuid=9ku7IyMqS7uMVmJpcNsTCg==seq=274hg=4eea4a62ts=4eea4ec9ld=0.07 0.06 0.07 1/189 8883ttl=3auth=3 3fe72eec1f8c4df616b8067ce368f847<<<

Donde Heartbeat comunica al Servidor B su estado. Si en algún momento el servidor A se cae, automáticamente el servidor B tomará su lugar. Todas las extensiones tendrán que conectarse a la nueva IP compartida, es decir: 173.255.196.191.

527

Page 539: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 540: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO XXVI

Asterisk GUI

Asterisk GUI es una interfaz gráfica desarrollada para la gestión y la configuración de Asterisk desde un navegador Web. Simplifica el manejo de Asterisk siempre y cuando se tenga un conocimiento básico del funcionamiento de la PBX. Al arrancar la GUI, ésta añade macros y extensiones al plan de llamadas pero no lee totalmente la configuración ya presentes en la carpeta /etc/asterisk; para evitar de perder el trabajo que se ha hecho hasta el momento, es buena practica hacer una copia de todos los archivo de configuración de Asterisk presentes en la carpeta /etc/asterisk:

mkdir /tmp/asterisk

cp /etc/asterisk/* /tmp/asterisk/

Para descargar la ultima versión disponible hay que instalar el programa SUBVERSION.

yum install subversion

cd /usr/src

Se descargan los archivos de la GUI

svn co http://svn.asterisk.org/svn/asterisk-gui/branches/2.0

Se entra en la carpeta:

cd 2.0/

Se compila y instala:

./configuremakemake install

Para terminar con la instalación hay que modificar dos archivos de configuración de Asterisk. Primero el manager.conf (si ya se ha configurado como indicado en el párrafo 19.1, se añade solamente al final del archivo el nuevo usuario):

nano /etc/asterisk/manager.conf

Se averigua que todos los parámetros que siguen tengan el valor indicado:

[general]enabled=yeswebenabled=yesport=5038

Page 541: Libro Asterisk 1.8.X - Versión 1.0 (1)

bindaddr=0.0.0.0;tlsenable=no;tlsbindport=5039;tlsbindaddr=0.0.0.0;tlscertfile=/tmp/asterisk.pem;tlsprivatekey=/tmp/private.pemallowmultiplelogin=yesdisplayconnects=yestimestampevents=yes;channelvars = var1,var2,var3debug=noauthtimeout=60authlimit=20httptimeout=60

Se crea un usuario que sera él que se usará para entrar en la pagina de administración de la GUI de Asterisk

[asterisk]secret=sesamowritetimeout=100read=system,call,agent,user,dtmf,reporting,cdr,dialplan,agi,cc,aocwrite=system,call,agent,user,config,command,reporting,otiginate,agi,aoc

Se guardan los cambios y se sigue con el archivo http.conf

mv /etc/asterisk/http.conf /etc/asterisk/http.conf.old

nano /etc/asterisk/http.conf

[general]enabled = yesenablestatic = yes bindaddr=0.0.0.0bindport=8088

Se guardan los cambios y se reinicia Asterisk

/etc/init.d/asterisk restart

Ahora hay que abrir el puerto 8088 TCP en el cortafuegos

nano /etc/sysconfig/iptables

Después de este bloque:

# Apache

530

Page 542: Libro Asterisk 1.8.X - Versión 1.0 (1)

-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

Se añaden las siguientes linea:

# Asterisk GUI-A INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT

Se guardan los cambios y se reinicia el cortafuegos:

service iptables restart

Ahora se averigua que todo esté bien configurado

make checkconfig

* Checking for http.conf: OK* Checking for manager.conf: OK* Checking if HTTP is enabled: OK* Checking if HTTP static support is enabled: OK* Checking if manager is enabled: OK* Checking if manager over HTTP is enabled: OK --- Everything looks good --- * GUI should be available at http://li115-178.members.linode.com:8088/asterisk/static/config/index.html

A pesar que aparezca la linea en negrita como dirección para acceder a la GUI, la dirección exacta es:

http://li115-178.members.linode.com:8088/static/config/index.html

Desde un navegador Web se visita la pagina de administración de la GUI de Asterisk.

Username: AsteriskPassword: sesamo

Se presiona el botón “Login”

Después de unos segundos aparecerá:

531

Page 543: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se vuelve a la ventana terminal del servidor y se para y reinicia Asterisk:

service asterisk stopservice asterisk start

Se vuelve a la pagina de administración de Asterisk y se presiona el Botón Aceptar. Se vuelve a poner Username y password presionando el botón “Login”. El Asterisk GUI leerá algunas configuraciones (colas de espera, conferencias) desde los archivos presentes en la carpeta /etc/asterisk. Las extensiones configuradas en el sip.conf no aparecerán porque Asterisk GUI las lee y guarda en el archivo users.conf

Aquí van algunas imágenes de la interfaz gráfica

El orden para configurar la GUI es:

• Crear las troncales en el menú Trunks• Crear los contextos para las llamadas saliente en el menú Outgoing Calling Rules• Crear el dialplan en el menú Dial Plans

532

Page 544: Libro Asterisk 1.8.X - Versión 1.0 (1)

• Crear las extensiones en el menú Users

Una vez que que se ha probado la GUI de Asterisk y se quiere volver a la configuración anterior, se copian los dos archivos modificados y se recarga la configuración guardada:

cd /etc/asterisk

cp manager.conf /tmp/asteriskcp http.conf /tmp/asterisk

rm -fr *

cp /tmp/asterisk/* /etc/asterisk

/etc/init.d/asterisk restart

La diferencia entre esta GUI y otras es que no utiliza muchos recursos del sistema para funcionar porque no necesita un servidor Web externo (Apache). Para pequeñas instalaciones con configuraciones básicas, es la más indicada.

533

Page 545: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 546: Libro Asterisk 1.8.X - Versión 1.0 (1)

CAPITULO XXVII

FreePBX

Personalmente no soy partidario de la instalaciones de Asterisk con Interfaz gráfica. Como entiendo que a muchos puede interesar el tema, en este capitulo se verá como instalar la GUI FreePBX.

Como la GUI se basa en PHP, si no se ha ya instalado, se instala ahora junto al servidor Apache y el modulo mod_ssl. Antes, si se ha instalado, se remueve el paquete rpmforge-release:

yum remove rpmforge-release

yum install php-* httpd mod_ssl

Se añade el usuario Asterisk con home directory /var/lib/asterisk:

useradd -c "Asterisk PBX" -d /var/lib/asterisk asteriskuseradd: aviso: el directorio personal ya existe.No se copia ningún fichero del directorio skel en él.

Cambiamos los permisos en todas las carpetas creadas por la instalación de Asterisk asignándolos al usuario asterisk que se acaba de crear:

chown -R asterisk /var/run/asteriskchown -R asterisk /var/log/asteriskchown -R asterisk /var/lib/asterisk/mohchown -R asterisk /var/lib/php/sessionchown -R asterisk /var/spool/asteriskchown -R asterisk /etc/asterisk

Como para la música en espera Asterisk + FreePBX utilizan archivos en formato wav, si se quiere utilizar archivos mp3 hay que instalar mpg123 (si ya no se ha hecho en el párrafo 10.1) que se encargará de convertir los archivos mp3 en wav:

cd /usr/srcwget http://downloads.sourceforge.net/project/mpg123/mpg123/1.13.4/mpg123-1.13.4.tar.bz2tar -xf mpg123-1.13.4.tar.bz2cd mpg123-1.13.4./configure --prefix=/usrmakemake install

Se cambia el usuario y grupo predefinido del servidor WEB de apache a asterisk:

sed -i "s/User apache/User asterisk/" /etc/httpd/conf/httpd.confsed -i "s/Group apache/Group asterisk/" /etc/httpd/conf/httpd.conf

Page 547: Libro Asterisk 1.8.X - Versión 1.0 (1)

Para prevenir problemas de acceso se modifica el parámetro AllowOverride de All a None:

sed -i "s/AllowOverride All/AllowOverride None/" /etc/httpd/conf/httpd.conf

Se entra en el cliente MySQL y se crean dos bases de datos y los respectivos permisos (si no existen):

mysql -u root -psesamoWelcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 5Server version: 5.0.77 Source distributionType 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create database asterisk; Query OK, 1 row affected (0.02 sec)

mysql> create database asteriskcdrdb; Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON asteriskcdrdb.* TO asteriskuser@localhost IDENTIFIED BY 'sesamo'; Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON asterisk.* TO asteriskuser@localhost IDENTIFIED BY 'sesamo'; Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)

mysql> quit Bye

Se descarga la ultima versión estable de FreePBX:

cd /usr/src

wget http://mirror.freepbx.org/freepbx-2.9.0.tar.gz

Se descomprime el paquete y se entra en la carpeta creada:

tar -xf freepbx-2.9.0.tar.gz

cd freepbx-2.9.0

Se crean las tablas para las bases de datos asterisk y asteriskcdrdb:

mysql -u root -psesamo asterisk < SQL/newinstall.sql

536

Page 548: Libro Asterisk 1.8.X - Versión 1.0 (1)

mysql -u root -psesamo asteriskcdrdb < SQL/cdr_mysql_table.sql

Se reinicia Asterisk:

/etc/init.d/asterisk restart

Se reinicia el servidor Apache y se configura para que arranque en automático:

service httpd restart

chkconfig httpd on

Se lanza el script de instalación de FreePBX:

./install_amp

Se insertan los datos como aparecen en la imagen y al terminar se para FreePBX:

/usr/sbin/amportal stop

Se entra en el archivo de configuración de FreePBX y se modifican estas tres líneas (password para el administrador de la pagina de los buzones de voz personales, tipo de autentificación para acceder a la

537

Page 549: Libro Asterisk 1.8.X - Versión 1.0 (1)

pagina de administración del FreePBX y la dirección IP publica del servidor Linux, respectivamente):

nano /etc/amportal.conf

ARI_ADMIN_PASSWORD=ari_passwordAUTHTYPE=noneAMPWEBADDRESS=xx.xx.xx.xx

para que queden:

ARI_ADMIN_PASSWORD=sesamoAUTHTYPE=databaseAMPWEBADDRESS=IPservidor (poner la IP publica del servidor Linux)

Se guardan los cambios y se inicia nuevamente FreePBX:

/usr/sbin/amportal start

En el archivo rc.local se copia esta línea para que el arranque sea automático:

nano /etc/rc.local

/usr/sbin/amportal start

Se guardan los cambios y se entra a la pagina web para administrar FreePBX utilizando la siguiente dirección:

http://IPservidor

Se escoge el enlace “FreePBX Adminsitration”:

538

Page 550: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pone como usuario admin y como contraseña admin. Primero en el menú “Adminisitrators” se cambia la contraseña del usuario admin:

Se pone la nueva contraseña y se presiona el botón “Submit Changes”. Luego desde el menú izquierdo se selecciona “Module Admin”. Se averigua si hay actualizaciones y se instalan:

539

Page 551: Libro Asterisk 1.8.X - Versión 1.0 (1)

De la misma forma se pueden instalar los módulos que se necesiten. Se selecciona el menú “FreePBX System Status” y se controla que no hayan avisos, errores de configuración:

Una vez que se hayan corregido todos los avisos/errores:

Ya se puede empezar con la configuración de Asterisk a través de la GUI FreePBX.

540

Page 552: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 553: Libro Asterisk 1.8.X - Versión 1.0 (1)

Apéndice A

Instalar CentOS 5.8 en una maquina virtual con VirtualBox

En esta guía se ilustrará como instalar el sistema operativo CentOS 5.8 32bit en un maquina virtual creada con el sistema de virtualización VirtualBOX. Esta maquina se puede utilizar como laboratorio para trabajar con el libro.

Para iniciar se descarga Virtualbox desde esta pagina:

https://www.virtualbox.org/wiki/Downloads

Luego se instala y se continua con la descarga de la ISO de CentOS:

http://centos.arcticnetwork.ca/5.8/isos/i386/CentOS-5.8-i386-netinstall.iso

Una vez terminada la descarga se crea la maquina virtual:

Se abre VitualBox y se presiona el icono “Nueva”. En la ventana que aparecerá, se selecciona el botón “Siguiente” y se siguen los pasos mostrados en las imágenes:

Nombre: CentOSLocalSistema Operativo: LinuxVersión: Red Hat

Page 554: Libro Asterisk 1.8.X - Versión 1.0 (1)

En la memoria RAM para el sistema huésped, hay que poner por lo menos 512 Mb. Si el sistema lo permite, mejor aun seleccionar 1GB (1024 Mb)

543

Page 555: Libro Asterisk 1.8.X - Versión 1.0 (1)

544

Page 556: Libro Asterisk 1.8.X - Versión 1.0 (1)

545

Page 557: Libro Asterisk 1.8.X - Versión 1.0 (1)

546

Page 558: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se selecciona el icono marcado con el circulo y en la ventana que aparece se escoge la iso de CentOS que se acaba de bajar. Debe quedar:

547

Page 559: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se pasa a la configuración de red:

Se habilita un Adaptador y se escogen las opciones como aparecen en la pagina. En Nombre hay que poner la tarjeta de red instalada en el computador. Para terminar se presiona el botón “Aceptar”.

ya se puede iniciar la maquina.

548

Page 560: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se continua presionando la tecla Enter (Envío):

549

Page 561: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se escoge el idioma.

El tipo de teclado.

550

Page 562: Libro Asterisk 1.8.X - Versión 1.0 (1)

El tipo de instalación (vía HTTP):

Se activa la tarjeta de red para las direcciones Ipv4

551

Page 563: Libro Asterisk 1.8.X - Versión 1.0 (1)

Nombre del sitio Web: mirror.centos.orgDirectorio CentOS: /centos/5.8/os/i386

Terminada la primera fase se iniciará la configuración del sistema:

552

Page 564: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se borran todos los datos del disco virtual creado:

Se crean las particiones predefinidas:

553

Page 565: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se confirma:

Se modifica la configuración de la tarjeta de red.

554

Page 566: Libro Asterisk 1.8.X - Versión 1.0 (1)

Configurando una IP fija.

Se crea un nombre de dominio, puerta de enlace (normalmente la IP del router) y DNS primario (la IP del router).

555

Page 567: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se escoge la zona horaria:

Se crea una contraseña para el usuario root:

556

Page 568: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se escoge el tipo de instalación (Sever) y se personalizan los paquetes que se instalarán:

Se entra en el menú Servidores y se dejan seleccionados solo los paquetes que aparecen en la imagen:

557

Page 569: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se inicia la instalación del sistema operativo:

558

Page 570: Libro Asterisk 1.8.X - Versión 1.0 (1)

Cuando termine se presiona el botón reiniciar. El sistema se reiniciará y como el Cd todavía está presente, volverá a presentar la pagina de instalación del sistema operativo. Se cierra la ventana y en la configuración de la maquina virtual se entra en el menú Almacenamiento:

Se selecciona el icono evidenciado y en el menú que aparece se escoge la opción “Eliminar disco de la unidad virtual”, para que quede:

559

Page 571: Libro Asterisk 1.8.X - Versión 1.0 (1)

Ahora se puede iniciar nuevamente la maquina virtual. Al primer arranque aparecerá el siguiente menú:

Se entra en la configuración del cortafuegos:

560

Page 572: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se deshabilita el cortafuegos y Selinux.

Se sale de la herramienta de configuración. Para terminar, se activa una DMZ en el router para la IP del servidor Linux. Un ejemplo:

561

Page 573: Libro Asterisk 1.8.X - Versión 1.0 (1)

Se vuelve a la maquina virtual y se actualiza el sistema:

yum -y update

Se reinicia el servidor

reboot

Ya se puede retomar el libro desde la pagina 9 con la creación de la clave RSA.

562

Page 574: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 575: Libro Asterisk 1.8.X - Versión 1.0 (1)

Apéndice B

Archivos de configuración

sip.conf

[general]allowguest=nocontext=defaultallowtransfer=yes;realm=mydomain.tldudpbindaddr=0.0.0.0:5060tcpenable=yestcpbindaddr=0.0.0.0:5060tcpauthtimeout=30tcpauthlimit=100srvlookup=yesmaxexpiry=3600minexpiry=60defaultexpiry=120mwiexpiry=3600maxforwards=70qualifyfreq=60preferred_codec_only=nodisallow=allallow=ulawallow=alawmohinterpret=defaultmohsuggest=defaultparkinglot=defaultlanguage=essendrpid=yerpid_update=yesprematuremedia=nouseragent=VozToVoice v. 1.0sdpsession=asterisksdpowner=asteriskdtmfmode=rfc2833videosupport=yesmaxcallbitrate=384callevents=yesauthfailureevents=yesalwaysauthreject=yesuse_q850_reason=yesrtptimeout=60rtpholdtimeout=300rtpkeepalive=0allowsubscribe=yes

Page 576: Libro Asterisk 1.8.X - Versión 1.0 (1)

subscribecontext=subscribenotifyringing=yesnotifyhold=yescallcounter=yest38pt_udptl=yes,fec,maxdatagram=400 faxdetect=yeslocalnet=localnet=10.8.0.0/255.255.255.0localnet=10.10.0.0/255.255.255.0externaddr=;externhost=prueba.dyndns.org;externrefresh=180nat=force_rportdirectmedia=no;media_address=0.0.0.0rtcachefriends=nortupdate=yestlsenable=yestlsbindaddr=96.126.125.112tlscertfile=/etc/asterisk/keys/serverA.pemtlscafile=/etc/asterisk/keys/ca.crttlscapath=/etc/asterisk/keystlsdontverifyserver=yes

register => serverA:pass1@IPserverB/serverB;register => fulano:[email protected];register => fulano:[email protected]:5061;register => fulano:contraseñ[email protected]/1234registertimeout=20registerattempts=10;mwi => 1234:[email protected]/1234

[1000]accountcode=1000language=estype=friendsecret=pbx9090qualify=yesmailbox=1000@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=callerid=Fulano <1000>callgroup=1pickupgroup=1disallow=all

565

Page 577: Libro Asterisk 1.8.X - Versión 1.0 (1)

allow=alawallow=g722allow=g729allow=h263cc_agent_policy=genericcc_monitor_policy=generic

[1001]type=friendaccountcode=1001language=essecret=pbx9091qualify=yesmailbox=1001@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=zutano <1001>callgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263cc_agent_policy=genericcc_monitor_policy=generic

[int-locales](!)type=friendlanguage=esqualify=yeshost=dynamicdtmfmode=rfc2833context=localesdirectmedia=nocallgroup=1pickupgroup=1disallow=allallow=alawallow=g722allow=g729allow=h263

[1002](int-locales)accountcode=1002

566

Page 578: Libro Asterisk 1.8.X - Versión 1.0 (1)

secret=pbx9092mailbox=1002@defaultcallerid=Mengano <1002>cc_agent_policy=genericcc_monitor_policy=generic

[justvoip] type=peerhost=sip.justvoip.comfromdomain=sip.justvoip.comfromuser=defaultuser=secret=qualify=yesdtmfmode=rfc2833context=from-justvoipdirectmedia=nolanguage=esnat=nodisallow=allallow=alawallow=g729

[spa3102]type=friendsecret=passwordqualify=yesnat=yeshost=dynamicdirectmedia=nocontext=from-spa3102dtmfmode=rfc2833language=escallerid=LineaTel <NumTel>allowtransfer=yesallowsubscribe=yessubscribecontext=subscribecallcounter=yesdisallow=allallow=alawallow=g729

[serverB]type=friendremotesecret=pass2context=internasqualify=yes

567

Page 579: Libro Asterisk 1.8.X - Versión 1.0 (1)

host=dynamiclanguage=esdisallow=allallow=gsmallow=ulawallow=alaw

[serverbvpn]type=peercontext=vpnhost=10.8.0.6disallow=allallow=g729allow=alawlanguage=esqualify=yesdtmfmode = rfc2833

[serverbtls]type=peercontext=from-tlshost=66.228.49.216disallow=allallow=alawlanguage=esqualify=yestransport=tlsencryption=yes

[1005]type=friendaccountcode=1005language=essecret=pbx9095qualify=yesmailbox=1005@defaulthost=dynamicdtmfmode=rfc2833context=externasdirectmedia=nocallerid=Perengano <1001>callgroup=1pickupgroup=1disallow=allallow=ulawallow=alawallow=g729

568

Page 580: Libro Asterisk 1.8.X - Versión 1.0 (1)

allow=h263cc_agent_policy=genericcc_monitor_policy=generictransport=tlsencryption=yes

iax.conf

[general]bindport=4569bindaddr=0.0.0.0nochecksums=nodelayreject=yesamaflags=documentationsrvlookup=yeslanguage=esmohinterpret=defaultmohsuggest=defautlbandwidth=highdisallow=allallow=alawallow=alawminregexpire=60maxregexpire=60encryption=yesforceencryption=notrunkmaxsize=128000trunkmtu=1240autokill=yescodecpriority=hostrtcachefriends=nortupdate=yesparkinglot=defaultcalltokenoptional=0.0.0.0/0.0.0.0requirecalltoken=auto

;register => marko:[email protected];register => joe@remotehost:5656 ;register => marko:[key]@tormenta.linux-support.net

[marko]type=friendhost=dynamicsecret=pbx9094context=externasmailbox=1234@default

569

Page 581: Libro Asterisk 1.8.X - Versión 1.0 (1)

qualify=yescallerid=markorequirecalltoken=auto

[serverb]type=friendhost=66.228.49.216trunk=yescontext=internasqualify=yes

[server1]type=userdbsecret=dundi/secretcontext=servera-localqualify=yesdisallow=allallow=ulawallow=alaw

extensions.conf

[general]static=yeswriteprotect=yseautofallthrough=yseextenpatternmatchnew=yseclearglobalvars=no

[globals]1000=SIP/1000JUST=SIP/justvoipmarko=IAX2/markoDYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon

[from-didvoztovoice]exten => s,1,Answersame => n,Goto(IVR,s,2)same => n,Hangup

[calendario]exten => cal,1,NoOp(Llamada desde el calendario)same => n,Gotoif($[${ISNULL(${CALENDAR_EVENT(location)})} = 0 & "${CALENDAR_EVENT(summary)}" = "Conferencia"]?conf)same => n,Agi(googletts.agi,"${CALENDAR_EVENT(summary)} a las ${STRFTIME(${CALENDAR_EVENT(start)},,%H:%M)}.",es)

570

Page 582: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Wait(1)same => n,Playback(goodbye)same => n,Hangupsame => n(conf),Agi(googletts.agi,"${CALENDAR_EVENT(description)}",es)same => n,Confbridge(${CALENDAR_EVENT(location)},cM(default))same => n,Hangup

[test]switch => Realtime

[fax]exten => _X.,1,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

exten => 1234,1,Answersame => n,Receivefax(/tmp/${UNIQUEID}.tif,df)same => n,Hangupexten => h,1,Noop(FAXSTATUS ${FAXSTATUS}, FAXERROR ${FAXERROR})same => n,Hangup

exten => 1235,1,Answersame => n,Wait(6)same => n,Dial(SIP/1000,45)exten => fax,1,Dial(IAX2/iaxmodem2)same => n,hangup

[servera-local]exten => 20,1,Answer()exten => 20,n,Playback(hello-world)exten => 20,n,Hangup()

[dundi-remoto]switch => DUNDi/serverb

[vpn]exten => 70,1,Answersame => n,Playback(demo-congrats)same => n,Hangup

[from-tls]exten => 71,1,Answersame => n,Noop(TLS = ${CHANNEL(secure_signaling)}, SRTP = ${CHANNEL(secure_media)})same => n,Playback(tt-monkeys)same => n,Hangup

[internas]exten => *30,1,CallCompletionRequest

571

Page 583: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Agi(googletts.agi,"Rellamada activada",es)same => n,Hangup

exten => *31,1,CallCompletionCancelsame => n,Agi(googletts.agi,"Rellamada anulada",es)same => n,Hangup

exten => *70,1,Addqueuemember(ventas,SIP/${CALLERID(num)})same => n,Playback(agent-loginok)same => n,Hangup

exten => *71,1,Removequeuemember(ventas,SIP/${CALLERID(num)})same => n,Playback(agent-loggedoff)same => n,Hangup

exten => *72,1,PauseQueueMember(ventas,SIP/${CALLERID(num)})same => n,Playback(beep)same => n,Hangup

exten => *73,1,UnpauseQueueMember(ventas,SIP/${CALLERID(num)})same => n,Playback(beep)same => n,Hangup

exten => _*1XXX,1, Set(CALLERID(num)=serverA)same => n,Dial(SIP/serverB/${EXTEN:1},30)same => n,Hangup()

exten => _*1100X,1,Dial(IAX2/serverb/${EXTEN:2})same => n,Hangup

exten => 50,1,Set(PBX=${ENV(LANG)})same => n,Noop(Idioma Servidor ${PBX})same => n,Hangup

exten => 51,1,Noop(Consulta en el calendario)same => n,Set(fin=$[${EPOCH}+10800])same => n,Set(id=${CALENDAR_QUERY(campusvoztovoice,${EPOCH},${fin})})same => n,Set(numeve=${CALENDAR_QUERY_RESULT(${id},getnum)})same => n,Set(num=1)same => n,While($[${numeve} > 0])same => n,Agi(googletts.agi,"${CALENDAR_QUERY_RESULT(${id},summary,${num})}",es)same => n,Agi(googletts.agi,"a las ${STRFTIME(${CALENDAR_QUERY_RESULT(${id},start,${num})},,%H:%M)}",es)same => n,Set(numeve=$[${numeve}-1])same => n,Set(num=$[${num}+1])same => n,Endwhilesame => n,Hangup

572

Page 584: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 70,1,Set(CALLERID(num)=openvpna)same => n,Dial(SIP/serverbvpn/${EXTEN})same => n,hangup

exten => 71,1,Set(CALLERID(num)=serveratls)same => n,Dial(SIP/serverbtls/${EXTEN})same => n,hangup

exten => 75,1,Answersame => n,Wait(1)same => n,Goto(IVR,s,1)

exten => 77,1,Set(CHANNEL(language)=es)same => n,agi(wakeup.php)same=> n,Hangup

exten => 97,1,Answersame => n,VoiceMailMain(${CALLERID(num)}@default)same => n,Hangup

exten => 98,1,VoicemailMainsame => n,Hangup

exten => 99,1,Directory(default,internas,e)same => n,Hangup

exten => 100,1,Noopsame => n,Dial(SIP/1000&SIP/1001&SIP/1002,30)same => n,Hangup

exten => 123,1,Answersame => n,Dumpchansame => n,Playback(hello-world)same => n,Hangup

exten => 150,1,Answersame => n,Playback(demo-echotest)same => n,Echosame => n,Playback(demo-echodone)same => n,Hangup

exten => 200,1,Answersame => n,Jabbersend(campus.voztovoice,[email protected],Estamos escuchando MP3)same => n,MusicOnHold(mp3,60)same => n,Hangup

573

Page 585: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 250,1,Agi(pruebaudio.php)same => n,Hangup

exten => 251,1,Agi(callerid.php)same => n,Hangup

exten => 252,1,Noopsame => n,AGI(agi://127.0.0.1:4573)same => n,Hangup

exten => 253,1,Noopsame => n,AGI(agi:async)same => n,Hangup

exten => 650,1,Answer()same => n,Festival(Asterisk y Festival trabajan junto. Chevere!!!)same => n,Hangup()

exten => 660,1,Answersame => n,Wait(2)same => n,Festival(Por favor ingrese los 4 digitos de la matricula del empleado.)same => n,Read(EMPNUM,beep,4)same => n,Set(EMPNAME=${ODBC_Empleados(${EMPNUM})})same => n,GotoIf($[${EXISTS(${EMPNAME})}]?nombre)same => n,Festival(Ningun empleado encontrado. Hasta luego.)same => n,Hangupsame => n(nombre),Festival(El nombre del empleado es ${EMPNAME}. Hasta luego.)same => n,Hangup

exten => 670,1,Goto(encuesta,s,1)same => n,Hangup

exten => _100[0-2,4-5],1,Noop(Protocolo SIPTLS = ${CHANNEL(secure_signaling)})same => n,Noop(Protocolo SRTP = ${CHANNEL(secure_media)})same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)same => n,Macro(voicemail)same => n,Hangup

exten => 1234,1,Dial(IAX2/marko,30)same => n,Macro(voicemail)same => n,Hangup

exten => 1235,1,Dial(IAX2/marko2,30)same => n,Macro(voicemail)same => n,Hangup

exten => _200[012],1,Agentlogin(${EXTEN})

574

Page 586: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Hangup

exten => 3000,1,Answersame => n,Queue(ventas,R)same => n,Hangup

exten => 3001,1,Answersame => n,Queue(ventas)same => n,Voicemail(1000@default)same => n,Hangup

exten => _66XX,1,Answer()same => n,Wait(2)same => n,Record(/tmp/prompt${EXTEN:2}:wav)same => n,Wait(2)same => n,Playback(/tmp/prompt${EXTEN:2})same => n,Wait(2)same => n,Hangup()

exten => 6500,1,Set(CALLERID(name)=Calendario)same => n,Set(CALLERID(num)=CampusVozToVoice)same => n,Dial(SIP/1000,15)same => n,Gotoif($[${DIALSTATUS} = ANSWER)]?contestada)same => n,Dial(SIP/justvoip/0057XXXXXXXXXX)same => n,hangupsame => n(contestada),Hangup

exten => _8.,1,Dial(SIP/spa3102,45,D(${EXTEN:1}))same => n,Busy(3)same => n,Hangup

exten => _9[12456789]XXXXXXX!,1,Dial(DAHDI/R1/${EXTEN:1},45)same => n,Hangup

[conferencias]exten => 501,1,Page(SIP/1001&SIP/1002)same => n,Hangup

exten => 502,1,Page(SIP/1001&SIP/1002,d)same => n,Hangup

exten => _350[012],1,Meetme(${EXTEN},scM(default))same => n,Hangup

exten => 3510,1,Meetme(,DM(default))same => n,Hangup

575

Page 587: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 3520,1,Set(confmax=10)same => n,Macro(meetme)same => n,Hangup

exten => 3530,1,Answersame => n,ConfBridge(3530,Mcs)same => n,Hangup

exten => _500[01],1,Meetme(${EXTEN})same => n,Hangup

[encuesta]exten => s,1,Answersame => n,Wait(2)same => n,Festival(Pregunta uno)same => n,Read(var1,,1,,10)same => n,Festival(Pregunta dos)same => n,Read(var2,,1,,10)same => n,Festival(Pregunta tres)same => n,Read(var3,,1,,10)same => n,Festival(Pregunta cuatro)same => n,Read(var4,,1,,10)same => n,Set(ODBC_Encuesta()=${STRFTIME(${EPOCH},,%y%m%d%H%M%S)},${var1},${var2},${var3},${var4})same => n,Playback(thank-you-cooperation)same => n,Hangup

[auten]exten => _00.,1,NoOPsame => n,Authenticate(/tmp/pin.txt,am,4)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangup

[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001exten => 1002,hint,SIP/1002exten => 1004,hint,SIP/1004exten => marko,hint,IAX2/markoexten => marko2,hint,IAX2/marko2exten => 701,hint,park:701@parkedcallsexten => 702,hint,park:702@parkedcallsexten => 703,hint,park:703@parkedcallsexten => 704,hint,park:704@parkedcallsexten => 705,hint,park:705@parkedcallsexten => 706,hint,park:706@parkedcallsexten => 707,hint,park:707@parkedcalls

576

Page 588: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => 708,hint,park:708@parkedcallsexten => 709,hint,park:709@parkedcalls

[google-in]exten => s,1,NoOp( Call from Gtalk )same => n,SendText(Hola,Como te llamas?)same => n,Set(nombre=${JABBER_RECEIVE(campus.voztovoice,${CALLERID(name)},20)})same => n,SendText(Hola ${nombre}, bienvenido en VozToVoice)same => n,Set(CALLERID(name)=${nombre})same => n,Wait(2)same => n,SendText(Espera un momento mientras te comunicamos con un operador)same => n,Dial(SIP/1000,30)same => n,Hangup()

[from-spa3102]exten => s,1,NoOpsame => n,Dial(SIP/1000)same => n,Hangup

[from-pstn]exten => s,1,Dial(SIP/1000,45)exten => s,n,Hangup

[internacio]exten => _00X.,1,NoOpsame => n,Set(CDR(userfield)=${CHANNEL(peerip)})same => n,Set(CALENDAR_WRITE(llamadas,summary,description,location,start)=Llamada de ${CALLERID(num)} a ${EXTEN},Llamada desde la extension ${CALLERID(num)} al numero ${EXTEN},IP = ${CHANNEL(peerip)},${EPOCH})same => n,Set(GROUP(voip)=justvoip)same => n,Set(GROUP(salida)=${CALLERID(num)})same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)})same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)})same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip)same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy)same => n,Dial(SIP/justvoip/${EXTEN})same => n,Hangupsame => n(busy),Playback(all-outgoing-lines-unavailable)same => n,Hangup

exten => _1XXXXXXXXXX,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

exten => _NNXX.,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com)same => n,Hangup

577

Page 589: Libro Asterisk 1.8.X - Versión 1.0 (1)

[externas]include => internasinclude => internacioinclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

[locales]include => internasinclude => auteninclude => parkedcallsinclude => testinclude => conferenciasinclude => dundi-remoto

[macro-disponible]exten => s,1,Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})})exten => s,n,Gotoif($["${estado}" = "NOT_INUSE"]?5)exten => s,n,Busyexten => s,n,Hangupexten => s,n,MacroExit

[macro-calendario]exten => s,1,Noop(${MACRO_EXTEN})same => n,GotoIf($[${MACRO_EXTEN} = 1000]?calendario)same => n,MacroExitsame => n(calendario),Set(estado=${CALENDAR_BUSY(campusvoztovoice)})same => n,Noop(Estado = ${estado})same => n,Gotoif($[${estado} = 1]?ocupado)same => n,MacroExitsame => n(ocupado),Agi(googletts.agi,"la extensión se encuentra ocupada, llame mas tarde. Gracias",es)same => n,Hangup

[macro-voicemail]exten => s,1,Goto(s-${DIALSTATUS},1)exten => s-BUSY,1,Voicemail(${MACRO_EXTEN}@default,b)same => n,Hangupexten => s-CANCEL,1,Hangupexten => s-CONGESTION,1,Congestionsame => n,Hangupexten => _s-.,1,Voicemail(${MACRO_EXTEN}@default,u)same => n,Hangup

[macro-meetme]exten => s,1,MeetMeCount(${MACRO_EXTEN},count)

578

Page 590: Libro Asterisk 1.8.X - Versión 1.0 (1)

same => n,Gotoif($[${count} > ${confmax}]?llena)same => n,MeetMe(${MACRO_EXTEN},D)same => n,Hangupsame => n(llena),Playback(conf-invalid)same => n,Hangup

#include IVR

IVR

[IVR]exten => s,1,Wait(1)exten => s,2,Set(CHANNEL(language)=es)exten => s,3,Set(TIMEOUT(digit)=7)exten => s,4,Set(TIMEOUT(response)=10)exten => s,5,BackGround(custom/prompt01)exten => s,6,WaitExten()exten => 1,1,goto(IVR1,s,1)exten => 2,1,goto(IVR2,s,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR,s,2)exten => i,3,Hangupexten => t,1,goto(IVR,s,2)exten => h,1,Hangup

[IVR1]exten => s,1,Set(TIMEOUT(digit)=7)exten => s,2,Set(TIMEOUT(response)=10)exten => s,3,Set(CHANNEL(language)=en)exten => s,4,BackGround(custom/prompt03)exten => s,5,WaitExten()exten => 1,1,Playback(demo-echotest)exten => 1,2,Echo()exten => 2,1,MusicOnHoldexten => 3,1,Playback(pls-wait-connect-call)exten => 3,2,Goto(internas,100,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR1,s,1)exten => i,3,hangupexten => t,1,goto(IVR1,s,1)exten => h,1,Hangup

[IVR2]exten => s,1,Set(TIMEOUT(digit)=7)exten => s,2,Set(TIMEOUT(response)=10)exten => s,3,Set(CHANNEL(language)=es)

579

Page 591: Libro Asterisk 1.8.X - Versión 1.0 (1)

exten => s,4,BackGround(custom/prompt02)exten => s,5,WaitExten()exten => 1,1,Playback(demo-echotest)exten => 1,2,Echo()exten => 2,1,MusicOnHoldexten => 3,1,Playback(pls-wait-connect-call)exten => 3,2,Goto(internas,100,1)exten => i,1,Playback(invalid)exten => i,2,Goto(IVR2,s,1)exten => i,3,hangupexten => t,1,goto(IVR2,s,1)exten => h,1,Hangup

580

Page 592: Libro Asterisk 1.8.X - Versión 1.0 (1)
Page 593: Libro Asterisk 1.8.X - Versión 1.0 (1)

Apéndice C

Licencia GNU FDL

GNU Free Documentation LicenseVersion 1.3, 3 November 2008

Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

0. PREAMBLE

The purpose of this License is to make a manual, textbook, or otherfunctional and useful document "free" in the sense of freedom: toassure everyone the effective freedom to copy and redistribute it,with or without modifying it, either commercially or noncommercially.Secondarily, this License preserves for the author and publisher a wayto get credit for their work, while not being considered responsiblefor modifications made by others.

This License is a kind of "copyleft", which means that derivativeworks of the document must themselves be free in the same sense. Itcomplements the GNU General Public License, which is a copyleftlicense designed for free software.

We have designed this License in order to use it for manuals for freesoftware, because free software needs free documentation: a freeprogram should come with manuals providing the same freedoms that thesoftware does. But this License is not limited to software manuals;it can be used for any textual work, regardless of subject matter orwhether it is published as a printed book. We recommend this Licenseprincipally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, thatcontains a notice placed by the copyright holder saying it can bedistributed under the terms of this License. Such a notice grants aworld-wide, royalty-free license, unlimited in duration, to use thatwork under the conditions stated herein. The "Document", below,refers to any such manual or work. Any member of the public is alicensee, and is addressed as "you". You accept the license if youcopy, modify or distribute the work in a way requiring permissionunder copyright law.

A "Modified Version" of the Document means any work containing theDocument or a portion of it, either copied verbatim, or withmodifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section ofthe Document that deals exclusively with the relationship of thepublishers or authors of the Document to the Document's overall

Page 594: Libro Asterisk 1.8.X - Versión 1.0 (1)

subject (or to related matters) and contains nothing that could falldirectly within that overall subject. (Thus, if the Document is inpart a textbook of mathematics, a Secondary Section may not explainany mathematics.) The relationship could be a matter of historicalconnection with the subject or with related matters, or of legal,commercial, philosophical, ethical or political position regardingthem.

The "Invariant Sections" are certain Secondary Sections whose titlesare designated, as being those of Invariant Sections, in the noticethat says that the Document is released under this License. If asection does not fit the above definition of Secondary then it is notallowed to be designated as Invariant. The Document may contain zeroInvariant Sections. If the Document does not identify any InvariantSections then there are none.

The "Cover Texts" are certain short passages of text that are listed,as Front-Cover Texts or Back-Cover Texts, in the notice that says thatthe Document is released under this License. A Front-Cover Text maybe at most 5 words, and a Back-Cover Text may be at most 25 words.

A "Transparent" copy of the Document means a machine-readable copy,represented in a format whose specification is available to thegeneral public, that is suitable for revising the documentstraightforwardly with generic text editors or (for images composed ofpixels) generic paint programs or (for drawings) some widely availabledrawing editor, and that is suitable for input to text formatters orfor automatic translation to a variety of formats suitable for inputto text formatters. A copy made in an otherwise Transparent fileformat whose markup, or absence of markup, has been arranged to thwartor discourage subsequent modification by readers is not Transparent.An image format is not Transparent if used for any substantial amountof text. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plainASCII without markup, Texinfo input format, LaTeX input format, SGMLor XML using a publicly available DTD, and standard-conforming simpleHTML, PostScript or PDF designed for human modification. Examples oftransparent image formats include PNG, XCF and JPG. Opaque formatsinclude proprietary formats that can be read and edited only byproprietary word processors, SGML or XML for which the DTD and/orprocessing tools are not generally available, and themachine-generated HTML, PostScript or PDF produced by some wordprocessors for output purposes only.

The "Title Page" means, for a printed book, the title page itself,plus such following pages as are needed to hold, legibly, the materialthis License requires to appear in the title page. For works informats which do not have any title page as such, "Title Page" meansthe text near the most prominent appearance of the work's title,preceding the beginning of the body of the text.

The "publisher" means any person or entity that distributes copies ofthe Document to the public.

A section "Entitled XYZ" means a named subunit of the Document whosetitle either is precisely XYZ or contains XYZ in parentheses following

583

Page 595: Libro Asterisk 1.8.X - Versión 1.0 (1)

text that translates XYZ in another language. (Here XYZ stands for aspecific section name mentioned below, such as "Acknowledgements","Dedications", "Endorsements", or "History".) To "Preserve the Title"of such a section when you modify the Document means that it remains asection "Entitled XYZ" according to this definition.

The Document may include Warranty Disclaimers next to the notice whichstates that this License applies to the Document. These WarrantyDisclaimers are considered to be included by reference in thisLicense, but only as regards disclaiming warranties: any otherimplication that these Warranty Disclaimers may have is void and hasno effect on the meaning of this License.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, eithercommercially or noncommercially, provided that this License, thecopyright notices, and the license notice saying this License appliesto the Document are reproduced in all copies, and that you add noother conditions whatsoever to those of this License. You may not usetechnical measures to obstruct or control the reading or furthercopying of the copies you make or distribute. However, you may acceptcompensation in exchange for copies. If you distribute a large enoughnumber of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, andyou may publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly haveprinted covers) of the Document, numbering more than 100, and theDocument's license notice requires Cover Texts, you must enclose thecopies in covers that carry, clearly and legibly, all these CoverTexts: Front-Cover Texts on the front cover, and Back-Cover Texts onthe back cover. Both covers must also clearly and legibly identifyyou as the publisher of these copies. The front cover must presentthe full title with all words of the title equally prominent andvisible. You may add other material on the covers in addition.Copying with changes limited to the covers, as long as they preservethe title of the Document and satisfy these conditions, can be treatedas verbatim copying in other respects.

If the required texts for either cover are too voluminous to fitlegibly, you should put the first ones listed (as many as fitreasonably) on the actual cover, and continue the rest onto adjacentpages.

If you publish or distribute Opaque copies of the Document numberingmore than 100, you must either include a machine-readable Transparentcopy along with each Opaque copy, or state in or with each Opaque copya computer-network location from which the general network-usingpublic has access to download using public-standard network protocolsa complete Transparent copy of the Document, free of added material.If you use the latter option, you must take reasonably prudent steps,when you begin distribution of Opaque copies in quantity, to ensure

584

Page 596: Libro Asterisk 1.8.X - Versión 1.0 (1)

that this Transparent copy will remain thus accessible at the statedlocation until at least one year after the last time you distribute anOpaque copy (directly or through your agents or retailers) of thatedition to the public.

It is requested, but not required, that you contact the authors of theDocument well before redistributing any large number of copies, togive them a chance to provide you with an updated version of theDocument.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document underthe conditions of sections 2 and 3 above, provided that you releasethe Modified Version under precisely this License, with the ModifiedVersion filling the role of the Document, thus licensing distributionand modification of the Modified Version to whoever possesses a copyof it. In addition, you must do these things in the Modified Version:

A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.C. State on the Title page the name of the publisher of the Modified Version, as the publisher.D. Preserve all the copyright notices of the Document.E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.H. Include an unaltered copy of this License.I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all

585

Page 597: Libro Asterisk 1.8.X - Versión 1.0 (1)

the substance and tone of each of the contributor acknowledgements and/or dedications given therein.L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.O. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections orappendices that qualify as Secondary Sections and contain no materialcopied from the Document, you may at your option designate some or allof these sections as invariant. To do this, add their titles to thelist of Invariant Sections in the Modified Version's license notice.These titles must be distinct from any other section titles.

You may add a section Entitled "Endorsements", provided it containsnothing but endorsements of your Modified Version by variousparties--for example, statements of peer review or that the text hasbeen approved by an organization as the authoritative definition of astandard.

You may add a passage of up to five words as a Front-Cover Text, and apassage of up to 25 words as a Back-Cover Text, to the end of the listof Cover Texts in the Modified Version. Only one passage ofFront-Cover Text and one of Back-Cover Text may be added by (orthrough arrangements made by) any one entity. If the Document alreadyincludes a cover text for the same cover, previously added by you orby arrangement made by the same entity you are acting on behalf of,you may not add another; but you may replace the old one, on explicitpermission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this Licensegive permission to use their names for publicity for or to assert orimply endorsement of any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under thisLicense, under the terms defined in section 4 above for modifiedversions, provided that you include in the combination all of theInvariant Sections of all of the original documents, unmodified, andlist them all as Invariant Sections of your combined work in itslicense notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, andmultiple identical Invariant Sections may be replaced with a singlecopy. If there are multiple Invariant Sections with the same name butdifferent contents, make the title of each such section unique byadding at the end of it, in parentheses, the name of the originalauthor or publisher of that section if known, or else a unique number.Make the same adjustment to the section titles in the list ofInvariant Sections in the license notice of the combined work.

586

Page 598: Libro Asterisk 1.8.X - Versión 1.0 (1)

In the combination, you must combine any sections Entitled "History"in the various original documents, forming one section Entitled"History"; likewise combine any sections Entitled "Acknowledgements",and any sections Entitled "Dedications". You must delete all sectionsEntitled "Endorsements".

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and otherdocuments released under this License, and replace the individualcopies of this License in the various documents with a single copythat is included in the collection, provided that you follow the rulesof this License for verbatim copying of each of the documents in allother respects.

You may extract a single document from such a collection, anddistribute it individually under this License, provided you insert acopy of this License into the extracted document, and follow thisLicense in all other respects regarding verbatim copying of thatdocument.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separateand independent documents or works, in or on a volume of a storage ordistribution medium, is called an "aggregate" if the copyrightresulting from the compilation is not used to limit the legal rightsof the compilation's users beyond what the individual works permit.When the Document is included in an aggregate, this License does notapply to the other works in the aggregate which are not themselvesderivative works of the Document.

If the Cover Text requirement of section 3 is applicable to thesecopies of the Document, then if the Document is less than one half ofthe entire aggregate, the Document's Cover Texts may be placed oncovers that bracket the Document within the aggregate, or theelectronic equivalent of covers if the Document is in electronic form.Otherwise they must appear on printed covers that bracket the wholeaggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you maydistribute translations of the Document under the terms of section 4.Replacing Invariant Sections with translations requires specialpermission from their copyright holders, but you may includetranslations of some or all Invariant Sections in addition to theoriginal versions of these Invariant Sections. You may include atranslation of this License, and all the license notices in theDocument, and any Warranty Disclaimers, provided that you also includethe original English version of this License and the original versionsof those notices and disclaimers. In case of a disagreement betweenthe translation and the original version of this License or a noticeor disclaimer, the original version will prevail.

587

Page 599: Libro Asterisk 1.8.X - Versión 1.0 (1)

If a section in the Document is Entitled "Acknowledgements","Dedications", or "History", the requirement (section 4) to Preserveits Title (section 1) will typically require changing the actualtitle.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Documentexcept as expressly provided under this License. Any attemptotherwise to copy, modify, sublicense, or distribute it is void, andwill automatically terminate your rights under this License.

However, if you cease all violation of this License, then your licensefrom a particular copyright holder is reinstated (a) provisionally,unless and until the copyright holder explicitly and finallyterminates your license, and (b) permanently, if the copyright holderfails to notify you of the violation by some reasonable means prior to60 days after the cessation.

Moreover, your license from a particular copyright holder isreinstated permanently if the copyright holder notifies you of theviolation by some reasonable means, this is the first time you havereceived notice of violation of this License (for any work) from thatcopyright holder, and you cure the violation prior to 30 days afteryour receipt of the notice.

Termination of your rights under this section does not terminate thelicenses of parties who have received copies or rights from you underthis License. If your rights have been terminated and not permanentlyreinstated, receipt of a copy of some or all of the same material doesnot give you any rights to use it.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of theGNU Free Documentation License from time to time. Such new versionswill be similar in spirit to the present version, but may differ indetail to address new problems or concerns. Seehttp://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number.If the Document specifies that a particular numbered version of thisLicense "or any later version" applies to it, you have the option offollowing the terms and conditions either of that specified version orof any later version that has been published (not as a draft) by theFree Software Foundation. If the Document does not specify a versionnumber of this License, you may choose any version ever published (notas a draft) by the Free Software Foundation. If the Documentspecifies that a proxy can decide which future versions of thisLicense can be used, that proxy's public statement of acceptance of aversion permanently authorizes you to choose that version for theDocument.

11. RELICENSING

588

Page 600: Libro Asterisk 1.8.X - Versión 1.0 (1)

"Massive Multiauthor Collaboration Site" (or "MMC Site") means anyWorld Wide Web server that publishes copyrightable works and alsoprovides prominent facilities for anybody to edit those works. Apublic wiki that anybody can edit is an example of such a server. A"Massive Multiauthor Collaboration" (or "MMC") contained in the sitemeans any set of copyrightable works thus published on the MMC site.

"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

"Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document.

An MMC is "eligible for relicensing" if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

The operator of an MMC Site may republish an MMC contained in the siteunder CC-BY-SA on the same site at any time before August 1, 2009,provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy ofthe License in the document and put the following copyright andlicense notices just after the title page:

Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,replace the "with...Texts." line with this:

with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some othercombination of the three, merge those two alternatives to suit thesituation.

If your document contains nontrivial examples of program code, werecommend releasing these examples in parallel under your choice offree software license, such as the GNU General Public License,to permit their use in free software.

589