La importancia de una línea de código: como hacer debug a tu configuración de Asterisk

20 Mar

El fin de semana por la noche recibí una llamada de un cliente nuestro solicitando apoyo para revisar el estado de su E1. Al parecer habían estado con el servicio de telefonía caido todo ese día, y tras horas de conferencia con su carrier no habían podido encontrar la razón por la cual el servicio del E1 no levantaba. Asterisk podía hacer llamadas entre extensiones, pero no tenían comunicación con el exterior.

Por experiencia, mi primer acercamiento fue revisar el archivo chan_dahdi.conf, que es el responsable del E1. Lo abrí pero no noté nada fuera de lo normal, así que desde la consola de Asterisk procedí a descargarlo de memoria y cargarlo nuevamente, esperando que arrojara algo de información. El resultado fue algo como lo siguiente:

server1*CLI> module load chan_dahdi.so
[Mar 20 02:03:52]   == Registered application 'DAHDISendKeypadFacility'
[Mar 20 02:03:52]   == Registered application 'ZapSendKeypadFacility'
[Mar 20 02:03:52]   == Parsing '/etc/asterisk/chan_dahdi.conf': [Mar 20 02:03:52] Found
[Mar 20 02:03:52] WARNING[9583]: config.c:778 process_text_line: parse error: No category context for line 6 of /etc/asterisk/chan_dahdi.conf
[Mar 20 02:03:52] ERROR[9583]: chan_dahdi.c:12728 setup_dahdi: Unable to load chan_dahdi.conf
[Mar 20 02:03:52]   == Registered channel type 'DAHDI' (DAHDI Telephony Driver w/PRI)
[Mar 20 02:03:52]   == Manager registered action DAHDITransfer
[Mar 20 02:03:52]   == Manager registered action ZapTransfer
[Mar 20 02:03:52]   == Manager registered action DAHDIHangup
[Mar 20 02:03:52]   == Manager registered action ZapHangup
[Mar 20 02:03:52]   == Manager registered action DAHDIDialOffHook
[Mar 20 02:03:52]   == Manager registered action ZapDialOffHook
[Mar 20 02:03:52]   == Manager registered action DAHDIDNDon
[Mar 20 02:03:52]   == Manager registered action ZapDNDon
[Mar 20 02:03:52]   == Manager registered action DAHDIDNDoff
[Mar 20 02:03:52]   == Manager registered action ZapDNDoff
[Mar 20 02:03:52]   == Manager registered action DAHDIShowChannels
[Mar 20 02:03:52]   == Manager registered action ZapShowChannels
[Mar 20 02:03:52]   == Manager registered action DAHDIRestart
[Mar 20 02:03:52]   == Manager registered action ZapRestart
[Mar 20 02:03:52]  Loaded chan_dahdi.so => (DAHDI Telephony w/PRI)

De aquí lo que importa es la línea que nos da el error:

[Mar 20 02:03:52] WARNING[9583]: config.c:778 process_text_line: parse error: No category context for line 6 of /etc/asterisk/chan_dahdi.conf

Tras abrir el archivo chan_dahdi.conf nuevamente y prestar un poco más de atención, las primeras líneas indican lo siguiente:

;autogenerated by /usr/sbin/wancfg_dahdi do not hand edit
;autogenrated on 2011-10-11
;Dahdi Channels Configurations
;For detailed Dahdi options, view /etc/asterisk/chan_dahdi.conf.bak

language=es

[trunkgroups]

[channels]
context=default
usecallerid=yes
hidecallerid=no
callwaiting=yes
usecallingpres=yes
callwaitingcallerid=yes

Y aquí es donde tras poner atención, notamos que el error proviene de una sola línea de código, el language=es está fuera de cualquier contexto, y esto provoca un error de parsing al momento de cargar el módulo, lo que impide que el canal se cargue correctamente y por lo tanto, el E1 nunca levante.

Entonces, ¿Cuales son los pasos para hacer un debug correcto de la configuración de Asterisk?

Los sistemas informáticos, a diferencia de los seres vivos, no cambian por si solos. Si nuestro sistema estaba bien de principio y de pronto algo dejó de funcionar es porque algo cambió. Una manera sencilla de ver los archivos de configuración en el orden en que fueron recientemente modificados es usar el comando ls:

ls -lSt /etc/asterisk | head -n 20

Con este comando ordenaremos los archivos de configuración de más reciente a menos reciente, mostrando solo los últimos 20 modificados. De ahí, podemos ir retrocediendo en nuestros pasos hasta que demos con la línea de código que alteramos y el sistema se restituya tras recargar el módulo o reiniciar Asterisk.

Si tenemos localizado el archivo con el problema, pero no sabemos exactamente en que línea está, el CLI de Asterisk puede resultar muy útil. Solo debemos asegurarnos que el log de eventos se arroja a consola editando el archivo /etc/asterisk/logger.conf

#/etc/asterisk/logger.conf
[general]

[logfiles]
console => warning,error,notice,debug
full => notice,warning,error,verbose

Como se aprecia en el archivo, estamos diciéndole a Asterisk que envie a consola toda la información relacionada con eventos warning, error, notice y debug (nota: el debug arroja MUCHA información, si hemos resuelto el problema lo recomendable es retirarlo del archivo hasta la siguiente vez que lo ocupemos). Recuerden que después de modificarlo deben recargar el logger dentro del Asterisk CLI

*CLI> logger reload

Y por último pueden descargar/cargar el módulo que da problemas en memoria. Este es un ejemplo del módulo de SIP:

amx*CLI> module unload chan_sip.so
Unloaded chan_sip.so
== Unregistered channel type 'SIP'
== Unregistered custom function SIPCHANINFO
== Unregistered custom function SIPPEER
== Unregistered custom function SIP_HEADER
== Unregistered custom function CHECKSIPDOMAIN
== Unregistered application 'SIPDtmfMode'
== Unregistered application 'SIPAddHeader'
== Unregistered application 'SIPRemoveHeader'
== Unregistered RTP glue 'SIP'
== Manager unregistered action SIPpeers
== Manager unregistered action SIPshowpeer
== Manager unregistered action SIPqualifypeer
== Manager unregistered action SIPshowregistry
== Manager unregistered action SIPnotify
amx*CLI> module load chan_sip.so
Loaded chan_sip.so
SIP channel loading...
== Parsing '/etc/asterisk/sip.conf': == Found
== Parsing '/etc/asterisk/sip_general_additional.conf': == Found
== Parsing '/etc/asterisk/sip_general_custom.conf': == Found
== Parsing '/etc/asterisk/sip_nat.conf': == Found
== Parsing '/etc/asterisk/sip_registrations_custom.conf': == Found
== Parsing '/etc/asterisk/sip_registrations.conf': == Found
== Parsing '/etc/asterisk/sip_custom.conf': == Found
== Parsing '/etc/asterisk/sip_additional.conf': == Found
== Parsing '/etc/asterisk/sip_custom_post.conf': == Found
== Parsing '/etc/asterisk/users.conf': == Found
[2012-03-20 01:48:54] WARNING[4896]: chan_sip.c:28479 reload_config: No valid transports available, falling back to 'udp
'.
== SIP Listening on 0.0.0.0:5060
== Using SIP TOS bits 96
== Using SIP CoS mark 4

En este otro ejemplo puede notarse como el módulo SIP arroja un WARNING. Eso es un típico caso de que algo en mi configuración no está 100% bien, por lo que conviene revisarlo.

Este paso de quitar/cargar el módulo en memoria resulta muy adecuado porque la información que arroja ese módulo no se pierde entre toda la demás al momento de hacer un reload. Fíjense en los detalles y pregúntense que quiso decir el CLI cuando les dió un warning o error. Los mensajes suelen ser bastante explícitos, solo depende de ustedes interpretarlos.

¡Suerte!

Modelo de seguridad en Asterisk (parte 3 de 3)

8 Mar

Fuente: http://static.internetblog.org.uk/files/manjail.jpg


Llegamos al final de nuestras entregas discutiendo el modelo de seguridad de Asterisk. En la primera parte discutimos sobre la seguridad antes de llegar al conmutador, normalmente a cargo del firewall de nuestro acceso a internet. En la segunda partehablamos sobre como autenticar a los usuarios para permitirles acceder a nuestro sistema. En esta tercera entrega hablaremos sobre como limitar las características de los usuarios que ya se encuentran autenticados dentro de Asterisk.

Seguridad de operación

Existen errores en versiones anteriores de algunas interfases gráficas (léase: Elastix) que nos permitían leer la lista completa de extensiones del conmutador y sus contraseñas aún si el usuario no pasaba la autenticación de administrador. Esto quiere decir que a pesar de cerrar nuestra interfaz administrativa y que nadie pueda modificarla, al tener los usuario/contraseñas podría tomar un teléfono, registrarlo con estos datos y empezar a hacer llamadas. Peor aún: podría vender estos datos para que algún tercero haga llamadas ilegalmente desde nuestro equipo. Asumiendo que ya cometimos los errores de las otras 2 etapas, ¿cómo podemos evitar (o al menos reducir) el daño inminente?

El primer paso, es limitar los accesos de las extensiones de acuerdo a lo que deban hacer. Por ejemplo, es probable que la recepcionista necesite poder llamara a locales, LD y celulares. Sin embargo, ¿por qué la extensión que está en la cafetería tendría la necesidad de marcar hacia afuera? Limitar esto es muy sencillo haciendo uso de contextos:

[codesyntax lang=»bash» title=»extensions.conf»]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Dial(DAHDI/g0/${EXTEN})

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Dial(DAHDI/g0/${EXTEN})

[/codesyntax]

En este ejemplo, tenemos 3 contextos: [internas], [locales] y [largadistancia]. Cada uno incluye al anterior y además, agrega un grado más de permisos. La idea es que al configurar cada usuario SIP/IAX de nuestro sistema, limitemos los accesos que cada uno tenga, sabiendo que cada uno solo puede marcar estrictamente a lo que nosotros le permitimos, además de tener la facilidad de que al conceder un permiso superior, daremos acceso a lo anterior.

Es altamente recomendable que si no hacemos llamadas internacionales, entonces… ¡no las habilitemos! Si sabemos que nuestros negocios se centran en territorio nacional y quizá llamadas a EUA/Canadá, limitemos agregando el _001NXXXXXXXXX, pero no agreguemos algo tan general como permitir _00., que estaríamos dándole la oportunidad al atacante de que use el mundo entero. Recuerden que limitar las posibilidades improbables reduce el probable riesgo.

Una manera mucho más elegante sería hacer uso de Realtime para que al marcar, se consulte la BD para determinar si tenemos permisos de marcar a ese destino o no, y en base a eso reaccionar. Dado que Realtime es un poco más avanzado, lo veremos más adelante en otro artículo.

El segundo paso consistiría en poner limitantes no al teléfono sino a la persona. La manera de hacer esto sería obligar a quien marca a proporcionarnos un código que le autorice a marcar a ese destino. Si alguien puede marcar por nuestro sistema, al menos obliguemoslo a que se sepa las contraseñas de los usuarios. Usando el mismo ejemplo anterior, lo podríamos hacer así:

[codesyntax lang=»php» title=»extensions.conf»]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN})

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN})

[macro-salida]
exten => s,1,Authenticate(/etc/asterisk/pinset)
exten => s,n,Dial(${ARG1} )
exten => s,n,Hangup

[/codesyntax]

En el ejemplo de arriba estamos introduciendo un nuevo elemento, un macro que nos permitirá hacer 2 pasos en uno solo: la autenticación y luego la marcación. De acuerdo al ejemplo, cualquiera podria marcar extensiones locales sin restriccion (al final de cuentas, son gratis). Sin embargo, si trata de marcar a llamadas locales o larga distancia se le pedirá al usuario que ingrese un código (el cual estaría escrito dentro del archivo /etc/asterisk/pinset). Si el usuario no proporciona la contraseña correcta, la llamada termina.

Los 2 esquemas que hemos mencionado (contextos y contraseñas) deberían impedir que algo malo pase. Sin embargo, si en el peor de los casos alguien logra penetrar todo lo anterior, limitemos la cantidad de daño recibido. ¿Cómo? Limitando la cantidad de llamadas simultáneas que puede hacer. Este paso es sumamente importante ya que, para empezar, nadie tiene por que poder hacer 20 llamadas simultáneas, ¿o si?

Para hacer esto, reaprovechemos el ejemplo anterior:

[codesyntax lang=»php» title=»extensions.conf»]

[internas]
exten => _XXXX,1,Dial(SIP/${EXTEN})

[locales]
include => internas
exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},2)

[largadistancia]
include => locales
exten => _01NXXXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},1)

[macro-salida]
exten => s,1,GotoIf($[${GROUP_COUNT(${CALLERID(num)})}>=${ARG2}]?Permite)
exten => s,n,Congestion()
exten => s,n(Permite),Set(GROUP(${CDR(uniqueid)})=${CALLERID(num)})
exten => s,n,Authenticate(/etc/asterisk/pinset)

exten => s,n,Dial(${ARG1} )
exten => s,n,Hangup

[/codesyntax]

Notarán que el macro se ha hecho bastante más complejo. Hay una buena razón para esto:

Hemos agregado al Macro la posibilidad de determinar cuantas llamadas simultáneas activas tiene un usuario en un momento dado, y si se excede de esta cantidad, corta la llamada.

Observen esta línea:

[codesyntax lang=»php»]

exten => _ZXXXXXXX,1,Macro(salida,DAHDI/g0/${EXTEN},2)

[/codesyntax]

El 2 que está al final de la línea es la cantidad máxima de llamadas a ese tipo de destino que estamos permitiendo. En el ejemplo anterior, permitimos que alguien marque hasta 2 llamadas locales al mismo tiempo, pero solo puede marcar a una LD. No sería muy difícil seguir este patrón para limitar el acceso internacional, pero eso se los dejo a ustedes para que practiquen.

 

Conclusiones

Si sumamos todas las barreras que hemos puesto con estos 3 niveles de seguridad, al final obtenemos:

  • Cerrar el acceso por firewall externo a nuestro conmutador
  • Detener el acceso al conmutador por firewall interno (iptables)
  • Acortar el rango de IPs desde las que pueden registrarse los usuarios SIP/IAX
  • Bloquear a aquellos usuarios que intenten fuerza bruta contra nosotros
  • Activar solo el plan de llamadas  necesario
  • Restringir  al usuario dependiendo de si sabe la contraseña correcta para el destino o no
  • Reducir la cantidad de llamadas simultáneas que el usuario puede hacer

Lo mejor de estas reglas es que son acumulables. Mientras más de ellas usemos lograremos un conmutador más y más seguro. Inclusive si consideramos que llevar a cabo todas resulta difícil, aplicar tantas como se pueda nos garantizará que estaremos restringiendo la posibilidad de que algo salga mal.

Créanme: vale más invertir tiempo en tomar en cuenta estos pasos en lugar de tener que pagar la cuenta final.

¡Suerte!

Evaluación del Grandstream GXV3175

7 Mar

El día de ayer recibimos un producto que había querido evaluar desde hace algunos días, y se trata del teléfono estrella de la gama alta de teléfonos que promueve Grandstream: el GXV3175 que ofrece soporte para videollamadas y una amplia pantalla touchscreen.

El teléfono aún en su caja

La primera impresión tras recibir la caja es que se trata de un producto orientado no al profesional, sino al consumidor. Las descripciones, imágenes e inclusive el tipo de empaque deja en claro que lo que el teléfono promueve son toda la gama de funcionalidades extras de un teléfono que está orientado al mercado de alto nivel adquisitivo.

El precio de venta público de este teléfono en México es elevado, siendo de alrededor de $480 USD + IVA (unos $6,240 pesos mexicanos). Por un precio así, lo que uno está esperando es prácticamente todo: video, audio, alta calidad de fabricación, funcionalidades extra, expandibilidad, aplicaciones y cualquier medio de interconexión que pueda haber. Por tal motivo, haremos mención de los pros y los contras que $480 USD te pueden comprar.

 

Contenidos

El teléfono trae consigo todos los componentes necesarios para funcionar out-of-the-box, que son:

Contenido de la caja

  • Auricular
  • Cable de red
  • Eliminador de corriente (12 V)
  • Base de escritorio
  • Soporte para pared
  • Cable de A/V para conectarlo a una televisión
  • Manuales
  • Toalla de limpieza
El teléfono soporta PoE, por lo que tener un eliminador de corriente es un buen extra aunque claro está, para el precio debería traer su propio eliminador. Los cables de A/V también son un plus al no tener que adquirirlos como un extra.

 

Fabricación

El GXV3175 está hecho totalmente de plástico, salvo el espacio de la pantalla LCD que actúa como touchscreen. Debo ser honesto: el plástico con el que está hecho la unidad es un plástico negro mate que se siente ligeramente poroso, casi como si fuera pasta. Este sentimiento al tacto es compartido por los otros teléfonos de gama inferior de Grandstream, por lo que en esta ocasión esperábamos que fuera un poco diferente. Buscábamos sentir un material de mayor calidad para un teléfono de este precio. (nota: no pensamos someter la unidad a pruebas de resistencia física, por lo que la sensación de tener un material barato es solo nuestra percepción, no indicamos que el proceso de manufactura sea, efectivamente, malo)

La base del teléfono se siente pesada, sinónimo inequívoco de toda la circuitería que se necesita para darle vida a la pantalla LCD (la cual se lleva todo el show). Al ser totalmente touchscreen el teléfono no posee botones físicos, y cuenta con un único botón de «Home» situado en la parte inferior central de la base, justo debajo del LCD. La forma y diseño de este botón no hacen sino hacernos sentir que es un diseño copiado del iPhone/iPad de Apple.

El auricular, por otro lado, es bastante ligero. Carece del peso que muchas personas buscan al momento de comprar un teléfono de gama alta. Dado que es la única parte física del teléfono que puede sostenerse (no hay botones, solo superficie touch), nos deja con la sensación de que algo le faltó al aparato, algo que nos hiciera sentir que al menos compramos su peso.

Un punto a favor del teléfono son los puertos de expansión. En uno de los costados ofrece posibilidad de conectar 2 USBs, 1 tarjeta SD, 1 puerto para audífonos/manos libres (jack 2.5 mm) y 1 puerto para A/V (para poder proyectar hacia la televisión).

Puertos de expansión

En la parte posterior el teléfono cuenta con lo habitual: 2 puertos de red (hacia el ruteador y como puente hacia la PC) y el puerto del handset.

Parte trasera del teléfono

Dependiendo de donde se coloque la base, el teléfono ofrece dos niveles de altura, lo que permite ajustar el ángulo de la pantalla para mayor comodidad.

Dado que la pantalla es una touch screen resistiva, el teléfono viene con un stylus (que se almacena dentro de la unidad en la esquina superior derecha, viéndolo de frente)  que nos hace sentir de vuelta en los tiempos de la Palm. Si bien no es necesaria en la mayoría de los casos, acceder a ciertos botones en algunos momentos resulta más cómoda con la pluma. Sin embargo, tener que usar un aditamento adicional para utilizar nuestro teléfono no es lo más cómodo del mundo.

Por último, en la parte frontal superior el teléfono cuenta con un pequeño switch que nos permite ajustar el ángulo de la video cámara integrada al teléfono.

 

Características

La más obvia de todas es la pantalla LCD de 800×480, la cual actua como teclado y es el único medio para introducir información al teléfono sin usar la interfaz web. La pantalla viene de la mano de la cámara de video integrada, la cual es configurable tanto en codecs como en resolución y FPS que deseamos enviar. Los puertos de expansión ya mencionados le permiten conectar un manos libres tipo celular, por lo que aquellas diademas con conector RJ9 quedan fuera de consideración.

El teléfono soporta Wifi (802.11b/g/n) lo cual es una buena característica, pero que se anula inmediatamente si queremos hacer uso del PoE (¿qué sentido conectar por WiFi si necesitamos un cable de red para la corriente?). Otro punto en contra es que el teléfono carece de Bluetooth, por lo que no es posible hacer pairing de tu manos libres BT como otros teléfonos de gama alta (tales como el Aastra 6739i o el Cisco SPA525G).

Otra característica importante y que hasta el momento solo he visto en los teléfonos Yealink es el soporte para Open VPN. Para quien no lo sabe, OpenVPN es una solución gratuita en software que te permite crear VPNs en capa SSL. La gran ventaja de hacer esto en un teléfono, es que puedes encriptar el tráfico VoIP (tanto el SIP como el RTP) y con eso tener comunicación segura por todo el medio de la VPN. Otra ventaja es que al encriptar el tráfico, es imposible para los ruteadores intermedios saber que contiene, así que contra aquellos proveedores de internet que bloquean el tráfico VoIP, esta funcionalidad puede ser muy útil.

El punto fuerte del teléfono son las aplicaciones: es casi como si tuviéramos una tablet con handset integrado. La gama de servicios de redes sociales o consultas web es relativamente amplia, y superior a las que vienen de fábrica con otros teléfonos. Una aplicación muy importante que echamos de menos y que otros teléfonos de Grandstream tienen, es la integración con Skype. Si este teléfono pudiera hacer uso de esa red y enviar video a través de ella, tendríamos definitivamente un ganador aquí. Es una sorpresa que teléfonos inferiores tengan esta característica mientras que este no.

Uso del sistema

Al conectar el teléfono al PoE inmediatamente este arrancará con la pantalla de bienvenida de Grandstream y empezará a cargar su sistema. A nuestro parecer el re-arranque del teléfono es bastante lento (2 minutos aproximadamente), pero en parte resulta entendible porque la interfaz gráfica no es tan sencilla. Tras encender el teléfono por primera vez nos guiará por un wizard de configuración de primera ocasión, con lo que podremos guiar al teléfono para configurar la hora por NTP y configurar también nuestra primer cuenta SIP.

Configuración inicial de la primer cuenta SIP

Tras configurar la primer cuenta, el teléfono cargará y estará listo para hacer llamadas.

El GUI del teléfono está bastante bien hecho. En apariencia se asemeja a una interfaz modificada de Android 3.0 (para tablets), ya que ofrece la posibilidad de colocar widgets, tener múltiples escritorios para guardar y desplegar información en ellos y claro está, acceder a aplicaciones como Facebook, Twitter, Google Voice, feeds RSS y hasta Youtube. Con todas estas características se nos puede olvidar que el teléfono también hace llamadas.

La interfaz aunque se asemeja  a otras, tiene su estilo propio. Para empezar a hacer una llamada tienes una de dos opciones: presionar el botón de «Phone» en la parte inferior derecha o presionar el widget que contiene el nombre de la cuenta que configuraste. Tener que presionar algo antes de empezar a marcar resulta un tanto frustrante, pero es un sacrificio necesario para poder aprovechar la pantalla LCD para desplegar información de otros temas mientras que el teléfono no se está usando.

El sistema posee varias aplicaciones instaladas (en este momento desconozco si es posible agregarle más). Entre las que están disponibles vienen la integración con Google Calendar, Google Voice, Twitter, Facebook, feeds RSS, tipos de cambio, indicadores de la bolsa de valores, clima y algunas otras. Aunque al principio parecen muy llamativas, interactuar con muchas de ellas resulta complicado por el teclado de la pantalla touchscreen. Es bueno para ingresar texto corto, pero a veces hasta escribir un pequeño tweet de 140 caracteres resulta complicado usando el teléfono.

La estabilidad del sistema diría que está a un 80%. La respuesta de ingreso de órdenes del usuario no es inmediata (se siente a veces un tanto lenta la interfaz) y en ocasiones, el sistema se congeló al acceder a la aplicación de FB (la pantalla literalmente se congeló, aunque fue posible reiniciar el teléfono desde la interfaz web)

 

Configuración del teléfono

Como ya es costumbre, la configuración principal se hace mediante una interfaz web, la cual debo agregar esta muy por encima de las anteriores interfaces de Grandstream.

Podemos configurar hasta 3 cuentas SIP diferentes (algo bajo para este tipo de teléfonos), y en cada cuenta podemos ajustar parámetros individuales como codecs, ringtones, direcciones de proxy y otras. Aparte de las 3 cuentas podemos configurar detalles de las aplicaciones individuales, además de poder hacer uso de la red por WiFi (algo inútil a mi gusto si es que queremos aprovechar el PoE).

Todo cambio requiere de un reinicio del teléfono para poder aplicarlo, aunque al menos tienes la opción de decidir en que momento quieres reiniciar (no es tan severo como Polycom). Dado el largo tiempo de carga del teléfono (2+ minutos), es preferible hacer todos los cambios de una vez antes de enviar reiniciar el equipo.

Casi todas las opciones del teléfono son configurables mediante el GUI del touchscreen, pero ingresar valores en el teclado virtual no es tan sencillo como se cree. Hay que recordar que la pantalla es resistiva, por lo que es necesario hacer cierta presión al momento de teclear algo, además de que los sensores no son tan exactos como los de una pantalla capacitiva (como la de la mayoría de los celulares con touchscreen).

 

Operación

Dado que el estado estándar del teléfono es mostrar los widgets del escritorio, necesitas presionar el botón de phone antes de que puedas hacer una llamada. Dentro del panel de marcación debes escoger que línea (cuenta SIP) quieres usar, además de que al momento de enviar la marcación debes decir si es una llamada con o sin video (aunque puedes solicitar el video estando ya a mitad de la llamada).

La interacción con el teléfono puede requerir un poco de paciencia. Al no tener botones físicos debemos esperar a que el sistema procese nuestros comandos por touchscreen. Si a esto le agregamos errores de detección, tenemos un sistema que aunque muy bonito, nos obliga a ir lento para que detecte correctamente lo que estamos tratando de decirle.

La calidad del video es buena, pero sin llegar a lo expectacular. Quizá el mayor problema sea el tipo de pantalla, ya que al ser resistiva necesita no tener un recubrimiento de vidrio, lo cual le habría dado mejor apariencia a la pantalla y por consecuente, una mejor apreciación del video.

El manos libres (speaker) se escucha bastante bien, aunque la cancelación de ruido del teléfono es, para lo que cuesta, pobre. En nuestras pruebas el altavoz de un Yealink T38G resultó muy superior en términos de no retroalimentar el audio nuevamente por el micrófono, de manera que este teléfono se escucha muy bien, pero a quien le llamemos por el manos libres no opinará lo mismo.

 

Conclusiones

El GXV3175 es un buen teléfono, pero no para su precio. Por $480 USD esperamos lo mejor de lo mejor, y aunque la idea de las aplicaciones en el teléfono y el tamaño de la pantalla son puntos muy buenos de entrada, la operabilidad con la interfaz gráfica deja mucho que desear. La falta de Skype y Bluetooth con características básicas para este rango, y nos resulta inadmisible que Grandstream (teniendo ya teléfonos con soporte de Skype), decida dejar este fuera del juego. Esperemos y esto se corrija con una actualización del firmware futura, pero por este momento, no tenemos el soporte para el mismo.

La fabricación definitivamente no está al nivel de la de teléfonos como Cisco o Polycom e inclusive, nos atrevemos a decir que está aún por debajo de la de Yealink. El hecho de tener siquiera que incluir un stylus nos hace pensar que el fabricante pensó en posibles problemas con el touchscreen y decidió incorporarlo. Parece una solución rápida a un problema inevitable, pero prefirieron optar por ese camino.

Al final, el teléfono se siente como una tablet más que como un teléfono. Su potencial de aplicaciones es muy bueno, pero la a veces lentitud de respuesta puede desesperar al momento de hacer cualquier otra cosa que no sean llamadas. Creo que el procesador les quedó corto para lo que al final desearon que hiciera.

Definitivamente, este es un teléfono orientado para el entusiaste, más alla que para el alto ejecutivo. Características más conservadoras (pero mayor calidad) de otros fabricantes serán preferidas por encima de este equipo. La participación de Grandstream en el alto mercado es buena, pero se quedó a varios metros de hacer un home run con este producto. Esperamos que con el continuo avance al firmware que ha puesto la compañía en los últimos años, logren pulir los detalles que este teléfono tiene, para así acercarlo un paso más a la gloria.

Esta es la primera de varias futuras reseñas que planeamos publicar en nuestro blog. La idea es ofrecerle a nuestros visitantes una percepción objetiva de los equipos que evaluamos para ayudarlos a saber si el producto cumple con sus expectativas antes de comprar. Como siempre, los invitamos a compartir sus opiniones dejándonos comentarios al término del artículo

Modelo de seguridad en Asterisk (parte 2 de 3)

6 Mar

El día de ayer publicamos la primera de esta serie de entregas que buscan concientizar sobre los 3 diferentes niveldes de seguridad en un conmutador IP como lo es Asterisk. Discutimos sobre la seguridad de acceso al sistema, que es la primer barrera contra la quenos anfrentamos al acceder al equipo. Para esta entrega hablaremos del segundo nivel de seguridad, es decir: los atacantes ya pueden llegar hasta el equipo, ¿cómo podemos defendernos de lo que nos pueden hacer?

Seguridad de autenticación

Como mencioné en el párrafo anterior, esta es la segunda capa de protección contra atacantes externos: ya penetraron nuestra red, ya pueden «ver» nuestro conmutador. ¿Quiere eso decir que estamos a su merced? Obviamente no, pero debemos tener algunos aspectos muy importantes en cuenta para que esto no nos pase. De entre los puntos a mencionar, resaltemos estos:

  • Listas de acceso para usuarios SIP/IAX
  • Contraseñas SIP/IAX seguras
  • Defensa contra fuerza bruta

Listas de acceso

Esta es, sin duda, la característica mas evitada en seguridad de Asterisk: configurar listas de acceso que hagan una coincidencia con los dispositivos que deben/pueden registrarse en nuestro sistema, limitando el acceso a ciertas extensiones desde ciertas IPs.

Por ejemplo: si nuestra red interna está en el segmento 192.168.1.0/24, ¿por qué razón habríamos de permitir que la extensión que pertenece a la sala de juntas se registre desde la IP 189.200.45.13? Las listas de acceso nos permiten restringir desde que IP puede un dispositivo registrarse o hacer llamadas con nosotros. Esta es la única manera que tienen de hacer que solo ciertas extensiones puedan ser usadas desde afuera de nuestra red (usuarios móviles), mientras que el resto no (usuarios locales)

Las listas de acceso en Asterisk se configuran usando los campos de permit y deny dentro ya sea de la sección [general] o bien dentro de la configuración de cada usuario (esto aplica para sip.conf y para iax.conf). Tomen en cuenta que el orden si importa y que la metodología default es un permit any. Esto quiere decir que si no negamos la autenticación, se le permite el paso a todo. Observen el siguiente ejemplo:

[codesyntax lang=»ini»]

[100]
username=100
type=friend
context=default
secret=aBcDeF12345!
deny=0.0.0.0/0.0.0.0
permit=192.168.1.1/255.255.255.0

[/codesyntax]

 

En este ejemplo, la regla de deny=0.0.0.0/0.0.0.0 está negando el paso a todo, ya continuación el permit=192.168.1.1/255.255.255.0 está permitiendo el paso solamente a aquellos dispositivos que se encuentren dentro de la red 192.168.1.x. Tengan mucho cuidado ya que si invertimos el orden de declaración:

[codesyntax lang=»ini»]

[100]
username=100
type=friend
context=default
secret=aBcDeF12345!
permit=192.168.1.1/255.255.255.0
deny=0.0.0.0/0.0.0.0
[/codesyntax]

Al final, el deny (que es lo último declarado) prevalecerá, y dado que 0.0.0.0/0.0.0.0 hace match con todo, estamos negando el paso a todos (haciendo que la extensión no sirva).

También pueden usar la notación CIDR, por lo que pueden declarar un rango de red como 192.168.1.1/24 y es igual que 192.168.1.1/255.255.255.0.

Recuerden que al declarar el permit/deny dentro de [general] están habilitando esa regla para todos, pero si solo colocan reglas de permit individuales dentro de cada usuario, abrirán ese usuario solamente. Esta es la única manera que tendrán de permitir el acceso remoto a usuarios SIP/IAX específicos, negando la posibilidad a todos los demás. Esto resulta muy conveniente porque no exponen todas sus extensiones, sino solo las estrictamente necesarias.

Al tener que descuidar y permitir el paso a ciertos usuarios, deben asegurarse de que las contraseñas de aquellos usuarios a los que les permiten acceder desde el exterior son suficientemente seguras, y de ahí viene el siguiente punto.

 

Contraseñas SIP/IAX seguras

Un motivo que muchos administradores tienen para dejar contraseñas inseguras es por facilitarse la labor al momento de configurar sus dispositivos SIP. Lo que muchas personas desconocen es que las contraseñas SIP/IAX se hicieron para tener que teclearlas una única vez, y esto es cuando configuramos el dispositivo (de hecho, si hacemos la configuración por provisionamiento TFTP nunca tendremos que teclearlas, pero ese es material para otro artículo). Si la contraseña solo deble escribirse o copiarse una única vez, entonces no existe razón para aprovechar y echarle un poco más de tiempo en usar contraseñas que sean tan seguras que un sistema de fuerza bruta no pueda romper.

Existen muchos mecanismos sencillos para generar contraseñas aleatorias. Quizá uno disponible que cualquier sistema con Linux tendría (con el paquete de openssl instalado):

[codesyntax lang=»bash» title=»Desde el Linux CLI:»]

# Esto generará 20 contraseñas aleatorias de 12 caracteres
for i in {1..20}; do openssl rand -base64 12; done

[/codesyntax]

Podemos fácilmente cambiar el 20 por cualquier otro número y generar un pool de contraseñas aleatorias que podemos ocupar para nuestras extensiones, asegurándonos con esto de que nuestras contraseñas sean totalmente seguras.

También tomemos en cuenta peores casos: si no colocamos una contraseña en una cuenta IAX estaremos abriendo la posibilidad de que cualquier entidad que llegue a nuestro equipo aún y si no proporciona contraseña sea autenticado inmediatamente. Esto es por la propiedad de IAX que se basa totalmente en la contraseña para realizar la autenticación de un dispositivo. Si no llenamos este campo, cualquiera se podrá autenticar como tal, aún y sin proporcionar ningún dato.

El hecho de tener contraseñas seguras impedirá que los atacantes entren a nuestro sistema. Sin embargo, no impedirá que lo intenten. Aquí está la última parte de este rompecabezas:

 

Defensa contra fuerza bruta

Es un hecho: si nuestro equipo debe estar expuesto porque nuestros usuarios así lo requieren, entonces tarde o temprano será atacado. El ataque puede verse en la forma de cientos de intentos de registro que intentarán adivinar nuestra contraseña segura definida en el punto anterior. A pesar de que sabemos que nunca la encontrarán, tantos cientos (o miles) de intentos pueden generar un ataque DoS en nuestro conmutador. ¿Cómo defendernos ante esto?

La respuesta es un sencillo (pero eficiente) programa llamado fail2ban. El fail2ban es una herramienta que analiza logs de intentos de ataque y bloquea selectivamente por iptables a la IP que origina estos ataques. Es como traer la seguridad de acceso cuando alguien ya entró a nuestro equipo pero se delató proporcionando contraseñas equivocadas. Veanlo como el personal de seguridad que te saca del lugar por comportarte mal, permitiéndote bloquearlo a nivel de firewall por unos minutos, horas o de manera permanente, todo depende de como lo configures.

Si estás interesado en ver como puedes configurar fail2ban y los filtros que puedes aplicar, puedes consultar el artículo que escribí hace unos meses.

 

Con esto cubrimos el segundo nivel en esta serie de entregas. En la siguiente discutiremos sobre la manera en como autenticar no a los dispositivos, sino a los usuarios, que son los últimos elementos en la cadena de seguridad de nuestro sistema.

¡Suerte!

Modelo de seguridad en Asterisk (parte 1 de 3)

5 Mar

Fuente: http://upload.wikimedia.org/wikipedia/commons/5/5b/Firewall.png

Desafortunadamente y como hemos comentado en otros posts, la seguridad en Asterisk es algo que se ha visto sobrevalorado por la sencillez y rapidez que trae el dejar un sistema que funciona en unas cuantas horas a partir de una distribución todo integrado, pero que es inseguro por descuidos del administrador.

¿Cómo puede alcanzarse la seguridad al 100% del conmutador? La respuesta es no se puede. Sin embargo, lo que si podemos hacer es llevar nuestro sistema a un nivel de seguridad que haga que aquel que intente penetrarlo sin autorización tenga que invertir más tiempo del que está dispuesto a ceder.

Para explicar mejor esto, definiremos el modelo de seguridad de Asterisk en 3 niveles:

  1. Seguridad externa (acceso al sistema)
  2. Seguridad de autenticación
  3. Seguridad de operación

Seguridad externa

Todo acceso al sistema desde fuentes externas (WAN) debe estar restringido a través de un firewall. Idealmente, usaríamos un firewall en hardware, pero si nuestro proveedor nos entrega una IP directa y la configuramos en nuestro equipo, podemos hacer uso de iptables.

Cuando decidimos que puertos abrir en nuestro firewall, debemos hacernos las siguientes preguntas:

  • ¿Habrá extensiones externas?
  • ¿Habrá alguna administración externa del conmutador?
  • ¿Existe algún proceso externo que controle el conmutador (manager interface)?

El tema de las extensiones externas es delicado, ya que es una parte fundamental de las ventajas de Asterisk pero al mismo tiempo es lo que permite el mal uso del conmutador. Si no pensamos tener extensiones externas, los puertos UDP 5060 y 4569 (SIP e IAX) deben estar cerrados. Si no abrimos los puertos, nadie ajeno al sistema, aún sabiendo las contraseñas de las extensiones podrá hacer llamadas. Al cerrar los puertos, cortamos el cable de acceso, y nada puede pasar. Es por eso que esta es la parte más importante de seguridad del sistema.

Si nos encontramos bajo el escenario que debemos tener extensiones externas, tenemos que asegurarnos que el nivel de seguridad secundario sea bueno, ya que al conceder acceso a entidades externas, debemos dejar la responsabilidad de la seguridad a las capas interiores. De esto nos encargaremos en la parte 2 de este artículo.

Nota: Al momento de hacer un register hacia una entidad SIP/IAX2 externa estaremos abriendo una sesión a través del firewall, lo que permitiría a esta entidad enviarnos llamadas a pesar de que el firewall esté cerrado. Hay que tomar esto en cuenta pues si alguien tuviera acceso administrativo a nuestro equipo podria generar un register hacia su propio conmutador y con ello, enviarnos llamadas en sentido inverso. El caso es muy raro, pero puede ocurrir. Ténganlo en cuenta.

Si necesitamos contar con administración remota del equipo debemos decidir correctamente que tipo de seguridad proveer. Si utilizamos alguna interfaz gráfica como FreePBX nunca, pero nunca debemos abrir el puerto HTTPS (TCP 443). Abrir el puerto 443 permitiria que cualquier vulnerabilidad de nuestra web, ya sea por FreePBX, Webmin, phpMyAdmin o cualquier otra interfaz que nos exponga contra atacantes externos.

Sobre este punto debo decir que dadas múltiples vulnerabilidades que han sido encontradas en interfaces gráficas, ningún administrador que considere su trabajo digno dejaría expuesto el puerto de HTTPS. Si acaso se necesita (para la administración), lo correcto es usar un túnel SSH o mejor aún, una conexión por VPN (sobre este último punto, si creamos una VPN podríamos no tener que abrir ni un solo puerto entrante en el firewall, por lo que este resultaría el caso más seguro de todos).

Por último, si tuviéramos necesidad de controlar Asterisk a través del Manager Interface (AMI), es necesario saber que toda la comunicación por este puerto siempre viaja sin encriptación, por lo que si alguien intercepta los paquetes del AMI podría fácilmente controlar completamente nuestro conmutador, creando extensiones o solicitando llamadas de la nada. El puerto que se ocupa para esta comunicación es el 5038 TCP y por lo tanto, nunca deberíamos dejarlo expuesto en nuestro firewall.

 

Este es el final de la primera de tres entregas sobre el modelo de seguridad de Asterisk. En las siguientes 2 partes haremos mención de como configurar ACLs dentro de Asterisk para asegurar el acceso, así como las opciones que debemos tomar en cuenta al momento de generar contraseñas seguras para acceso a nuestros usuarios SIP/IAX.

Recuerden que también pueden dejarnos sus comentarios a través de Twitter o Facebook.

¡Suerte!

El carrier no siempre tiene la razón

1 Mar

(por cuestiones de confidencialidad no puedo revelar nombres, pero esta historia aplica en general)

Desde el pasado noviembre recibí una llamada de uno de mis clientes indicándome que su equipo Elastix muy frecuentemente le daba el ya conocido mensaje «todos los circuitos se encuentran ocupados«. Su enlace con la PSTN era a través de un enlace digital E1 ISDN.  Pensé que algo estaría mal con la configuración del equipo, así que decidí acceder a la consola para ver que era lo que lo ocasionaba.

Intentó varias llamadas a un mismo número: todas fallaron. Mi creencia fue pensar que Elastix estaba mal interpretando el código Q.931 que el carrier entregaba de vuelta tras el resultado de la llamada. Para quienes no saben, el Q.931 es el protocolo estándar de la ITU para la señalización de control de conexión en ISDN (en otras palabras, es el responsable de indicar el estado de una llamada generada a través de un E1 ISDN). Por default, Elastix interpreta prácticamente todo con la misma respuesta de «todos los circuitos se encuentran ocupados», por lo que a pesar de que la razón de terminado de la llamada sea una congestión del carrier o bien que el número marcado no existe, siempre obtenemos la misma respuesta.

Implementé la solución de uno de mis post anteriores esperando que eso resolviera el problema y el cliente se enterara de cual era la verdadera razón para la desconexión. Poco tiempo paso cuando mi cliente me indicó que no hubo cambio, sino que todo continuó exactamente igual que al principio (mismo mensaje para todos los casos). Esto me extrañó dado que esta solución ha sido exitosa en muchos casos e inclusive, otras empresas lo han sugerido a sus clientes para resolver problemas con el servicio recibido por otros carriers, por lo que tuve que indagar más para encontrar la causa del problema.

Tras analizar los logs, encontré cientos de registros como este:

[Feb 9 08:34:03] VERBOSE[10458] pbx.c:     -- Executing [continue@macro-dialout-trunk:3] NoOp("SIP/31163-00002883", "TRUNK Dial failed due to CONGESTION HANGUPCAUSE: 31 - failing through to other trunks") in new stack
[Feb 9 08:36:42] VERBOSE[10472] pbx.c:     -- Executing [continue@macro-dialout-trunk:3] NoOp("SIP/31142-0000288d", "TRUNK Dial failed due to CONGESTION HANGUPCAUSE: 31 - failing through to other trunks") in new stack
[Feb 9 08:42:10] VERBOSE[10499] pbx.c:     -- Executing [continue@macro-dialout-trunk:3] NoOp("SIP/31161-00002897", "TRUNK Dial failed due to CONGESTION HANGUPCAUSE: 31 - failing through to other trunks") in new stack
[Feb 9 08:44:45] VERBOSE[10512] pbx.c:     -- Executing [continue@macro-dialout-trunk:3] NoOp("SIP/31131-0000289c", "TRUNK Dial failed due to CONGESTION HANGUPCAUSE: 31 - failing through to other trunks") in new stack
[Feb 9 08:49:55] VERBOSE[10523] pbx.c:     -- Executing [continue@macro-dialout-trunk:3] NoOp("SIP/31112-0000289f", "TRUNK Dial failed due to CONGESTION HANGUPCAUSE: 31 - failing through to other trunks") in new stack

Aquí se aprecia que el código de terminación de la llamada fue el 31. Si buscamos en Google encontraremos que el código 31 dice «Normal, unspecified», significando que la llamada terminó por causas normales que no fueron especificadas. Esto es normal de vez en cuando, pero tener tantos intentos fallidos en el mismo intervalo de tiempo me hizo investigar más.

Encontré los números que se marcaban y tomé mi línea analógica convencional y marqué a ellos. Los resultados fueron diferentes para los diferentes números:

  • «El número que marcó está fuera de servicio»
  • «El número que marcó está suspendido»
  • «El número que marcó no existe»
  • «El número celular que usted marcó no está disponible o se encuentra fuera del área de servicio»

Entonces no era problema que todos los canales estuvieran ocupados, sino que el carrier NO estaba regresándonos la causa correcta de terminación de la llamada para cada caso específico. Esto es sumamente importante, ya que en base al código de error obtenido sabes como debes retroalimentar a los usuarios para que reintenten pasados unos minutos o bien, que dejen de intentar llamar a un número imposible de localizar.

A pesar que trates de explicarle esto a los clientes, muchos no entienden que las líneas digitales se basan en códigos de error y no en grabaciones que escuchan en su línea al momento de marcar. Decir que todos los circuitos están ocupados normalmente es asociado con problemas de capacidad (piensan que hacen demasiadas llamadas simultáneas) o con un problema del conmutador, y acaban echándote la culpa a ti como proveedor del mismo.

Como el problema escalaba de lo que éramos capaces de ofrecer (ya que el enlace es provisto por el carrier, no por nosotros) no nos quedó de otra que levantar la incidencia. Esto fue desde noviembre 2011. Múltiples pruebas se tuvieron que hacer para demostrar a los ingenieros de soporte del carrier que el problema no venía del conmutador, sino de su enlace (o bien, de la interconexión de ellos con el destino al que se estaba marcando).

Tras 3 meses de idas y vueltas, reportes enviados y pruebas fallidas, antier me reportaron que por fin pudieron cumplirse pruebas exitosas del proyecto. El problema radicó en la interconexión entre carriers, no en la conexión de Asterisk.

Los ingenieros de soporte nos hicieron notar que gracias a la insistencia de nuestra parte el problema pudo detectarse e inclusive, se corrigió para todos los usuarios del mismo tipo de servicio. Inclusive la retroalimentación fue que muchos proveedores de conmutadores de telefonía convencional disfrazan los códigos de error recibidos para otorgarle al usuario respuestas aceptables en los problemas de los enlaces digitales. Sin embargo, Asterisk es de los pocos conmutadores con acceso total a la información (sin restricciones), por lo que pudimos meternos a hacer un debug intensivo del medio y pudimos refutar al carrier que el problema no venía de nuestro lado.

Sin acceso a la información que Asterisk entrega, nunca hubiéramos tenido las pruebas para acusar a quien tuvo la verdadera culpa del problema y hoy, seguiríamos igual que al principio.

Creo que la moraleja de esta historia es: nunca asuman que el proveedor grande siempre tiene la razón. Consigan pruebas, experimenten y evalúen sus resultados. Es muy probable que ustedes sean quienes puedan salir victoriosos de la contienda, solo infórmense bien de lo que ustedes saben que deberían estar recibiendo.

¡Suerte!

Como exportar el AstDB (Asterisk Database)

11 Ene

En algunas ocasiones nos hemos topado con clientes cuyo sistema empieza a hacer cosas… raras. Resulta que el call forward deja de funcionar correctamente, o que las llamadas se ciclan después de entrar al IVR y apuntar hacia alguna dirección. Esto lo hemos visto en casos con FreePBX/Elastix donde el equipo por alguna error (a veces falla de hardware) se traba y es necesario reiniciarlo físicamente, haciendo que archivos como el astdb se corrompan y queden incompletos. Esto ocasione que nuevos valores no puedan ser guardados en el astdb, o que valores viejos no puedan ser modificados.

Un síntoma típico de estos problemas es cambiar algún valor desde el GUI que ocasione que el AstDB cambie. Ejemplo: un nuevo speeddial del addressbook o activar/desactivar el call-waiting de alguna extensión. Si nos hemos preguntado: ¿por qué Asterisk no está guardando los valores que le doy? Esta es una probabilidad…

La solución más radical es la siguiente:

  1. Detener Asterisk
  2. Eliminar el archivo /var/lib/asterisk/astdb
  3. Reiniciar Asterisk

Con esto, Asterisk creará una nueva astdb desde cero, pero habremos perdido cualquier valor que ya existiera allí. Cualquier campo personalizado se perdió tras este paso.

¿Cómo podemos exportar los valores del astdb, a manera que podamos restaurarla en una nueva recién creada que no tiene estos errores?

Una respuesta a este problema fue crear un script que se conecte por el AMI y haga un dump en código bash que después se pueda usar para aplicarlo en cualquier otro momento. Este dump seria una serie de comandos que harían una conexión a Asterisk indicándole recrear los valores. El código es el siguiente:

[codesyntax lang=»php» title=»/var/lib/asterisk/agi-bin/astdb.php»]

#!/usr/bin/php -q
<?php
include «phpagi-asmanager.php»;

$user = ‘admin’;
$pass = ‘elastix456’;

$agi = new AGI_AsteriskManager();
$agi->connect(‘127.0.0.1’,$user,$pass);

$r = $agi->database_show();
$x = array();
echo «#!/bin/bashn»;
foreach ($r as $k => $v) {
echo «asterisk -rx ‘database put «.substr($k,1,strpos($k,’/’,2)-1) . ‘ ‘ .
substr($k,strpos($k,’/’,2)+1) . ‘ ‘.
«»$v»‘».
«n»;
}

?>

Hay que notar que en el código estoy incluyendo al archivo phpagi-asmanager.php el cual es un componente de la clase PHPAGI que existe en todas las distribuciones de FreePBX (y eso incluye a Elastix/Trixbox). Yo recomiendo colocar este código en un archivo como /var/lib/asterisk/agi-bin/astdb.php, ya que esa carpeta ya contiene la librería arriba mencionada.

Invocarlo es muy sencillo. Lo hacemos ejecutale y lo corremos:»

[codesyntax lang=»bash»]

chmod 755 /var/lib/asterisk/agi-bin/astdb.php
/var/lib/asterisk/agi-bin/astdb.php > /tmp/astdb.sh

[/codesyntax]

Tras ejectutar el comando anterior, tendremos un archivo astdb.sh dentro de la carpeta /tmp. Este archivo tendrá un contenido parecido al que sigue:

[codesyntax lang=»bash» title=»/tmp/astdb.sh»]

#!/bin/bash
asterisk -rx 'database put AMPUSER 100/cidname "Juan Perez"'
asterisk -rx 'database put AMPUSER 100/cidnum "100"'
asterisk -rx 'database put AMPUSER 100/device "100"'
asterisk -rx 'database put AMPUSER 100/followme/changecid "default"'
asterisk -rx 'database put AMPUSER 100/followme/ddial "DIRECT"'
asterisk -rx 'database put AMPUSER 100/followme/fixedcid ""'
asterisk -rx 'database put AMPUSER 100/followme/grpconf "DISABLED"'
asterisk -rx 'database put AMPUSER 100/followme/grplist "815#"'
asterisk -rx 'database put AMPUSER 100/followme/grptime "20"'
asterisk -rx 'database put AMPUSER 100/followme/prering "15"'
asterisk -rx 'database put AMPUSER 100/language "es"'

[/codesyntax]

Estos son una serie de comandos que podemos ejecutar para hacer que el nuevo Asterisk importe el contenido del AstDB anterior para tener acceso a la misma información que el anterior. ¿Por que no simplemente respaldamos el archivo /var/lib/asterisk/astdb? Porque al reemplazar el nuevo archivo sobreescribiríamos todo, y perderiamos cualquier personalización que hubiera en el viejo sistema. Además, si respaldamos un archivo dañado, lo único que conseguiríamos seria copiar el daño de nuevo.

Espero esto les sirva. A nosotros nos resolvió el problema de un cliente que no le permitía guardar nueva información (sus speeddials no podían ser editados ni podiamos agregar nuevos).

¡Suerte!

Nueva imagen para nuestro sitio

5 Ene

Para quien entró al sitio desde temprano habrá notado algo diferente, y es que por fin actualizamos nuestra página principal para que coincidiera con nuestros foros de discusión.

Durante los siguientes días estaremos haciendo algunos ajustes de apariencia, pero el contenido sigue siendo el mismo. Esperamos que a todos nuestros visitantes les agrade el cambio para tener ahora una imagen más personalizada.

¡Suerte!

¡Feliz año a todos! Tenemos nuevos cursos para 2012

3 Ene

El 2011 fue un año muy bueno: vimos la salida oficial de Asterisk 10, productos como Elastix/PiaF siguen madurando y nosotros tuvimos la oportunidad de capacitar a más de 80 personas en el ramo de Asterisk en el año que terminó. Queremos llegar a más profesionales del medio y por lo tanto, hacemos de conocimiento público las nuevas fechas que tenemos para nuestros cursos (en las 3 principales ciudades de México):

  • México, DF. 25, 26, 27 y 28 de enero 2012
  • Monterrey, Nuevo León. 15, 16 17 y 18 de febrero 2012
  • Guadalajara, Jalisco. 22, 23, 24 y 25 de febrero 2012

El temario para las 3 ciudades es exactamente el mismo y cubrimos desde una intruducción a Linux (para el que nunca ha usado este sistema operativo) hasta características avanzadas de Asterisk como lo son el uso de AGIs y el AMI.

Estamos ofreciendo un descuento para todos aquellos que reserven su lugar antes del 6/enero. Si desean más información, pueden visitar la página de nuestros cursos o bien ponerse en contacto con nosotros.

¡Feliz año a todos! Esperamos poder conocerlos a todos en persona.

¡Suerte!

T1s ISDN PRI con el medio arriba pero caídos en servicios

2 Dic

Vicidial con 150 posiciones en San Juan, PR


Nos por la mañana nos desmadrugó un cliente que tenemos en Puerto Rico (en México estamos 2 atrasados con respecto de ellos), indicándonos que los agentes no podian sacar llamadas al exterior en ocasiones. Algunas veces podían marcando manualmente, otras no.

Como antecedente, el cliente tiene 8 T1s en ISDN PRI, dándole un total de 23*8=184 canales totales. De ese total de canales, tiene 10 reservados en los primeros 2 T1s para solo inbound, y lo demás es outbound libre, de manera que los agentes toman cualquiera de los canales que estén disponibles para marcar al exterior.

Los T1s de salida estaban agrupados en uno solo, el grupo 0 (cero), con lo cual yo mandaba la llamada así:

[codesyntax lang=»php»]

exten => _787ZXXXXXX,n,Dial(DAHDI/r0/${EXTEN})

[/codesyntax]

De esta manera, no tengo que preocuparme por ver por cual canal mandar la llamada, sino que en round robin se irá rotando por el total de canales disponibles para outbound. En teoría todo está bien, pero…

Al momento de hacer pruebas, efectivamente, algunos agentes en ocasiones no podian sacarlas. El sistema no les daba error, sino que se quedaba en vacio, sin que nada apareciera o se escuchara. Si colgábamos y volviamos a marcar el mismo número, el resultado era diferente y la llamada ya pasaba.

¿Qué podía estar pasando?

Dedicimos probar uno por uno los T1s. Sin embargo, dado que sus canales estaban todos agrupados en uno solo, no nos era posible enviar llamadas que se distinguieran por cada uno de ellos. La solución fue modificar el chan_dahdi.conf para que se viera así:

[codesyntax lang=»bash»]

;;;;;;;;;;;;;;;;;;;;;;;;;
;; Llamadas de outbound
;;;;;;;;;;;;;;;;;;;;;;;;;
switchtype=national
context=trunkinbound
group=0,21
echocancel=yes
faxdetect=incoming
signalling=pri_cpe
channel =>13-23
group=0,22
channel =>38-47
group=0,23
channel =>49-71
group=0,24
channel =>73-95
group=0,25
channel => 97-119
group=0,28
channel => 169-191

;;;;;;;;;;;;;;;;;;;;;;;;;
;; Llamadas de outbound - Marcacion especial
;;;;;;;;;;;;;;;;;;;;;;;;;
switchtype=national
context=trunkinbound
group=1
echocancel=yes
faxdetect=incoming
signalling=pri_cpe
group = 1,26
channel =>121-143
group = 1,27
channel => 145-167

;;;;;;;;;;;;;;;;;;;;;;;;;
;; Llamadas de inbound
;;;;;;;;;;;;;;;;;;;;;;;;;
switchtype=national
context=trunkinbound
group=9
echocancel=yes
faxdetect=incoming
signalling=pri_cpe
channel =>1-12,25-37

[/codesyntax]

Observando el primer bloque de llamadas de outbound, veremos que los canales ahora siguen estando agrupados en el 0, pero también lo separé y cree los grupos 21-27.  De esta manera, yo puedo escoger cuando marcar por cada uno de esos grupos y saber si el T1 está mal (recordemos que en señalización están perfectos porque no tienen alarmas, pero administrativamente la telefónica no le está dando servicio por alguno de ellos). La parte de las llamadas la resolví con esto dentro del extensions.conf:

[codesyntax lang=»bash»]

exten => _8Z787ZXXXXXX,1,Dial(DAHDI/r2${EXTEN:1:1}/${EXTEN:2});

[/codesyntax]

La idea es que marcando por ejemplo, 81 + 10 digitos estamos obligando a que la llamada salga por el T1 1. Si marcáramos con 82 saldría por el 2 y así sucesivamente. Esto le da la opción al administrador de hacer un debug y determinar si las llamadas por allí son efectivamente válidas.

Tras unos intentos de llamada fue posible notar que los T1s 3 y 5 no tenían salida a pesar de no estar alarmados. Como el formato de round robin se brinca aquellos canales que están alarmados, la solución sencilla fue desconectar físicamente esos T1s y reportarlos con la telefónica. Cundo le restauren el servicio, el administrador podrá conectarlos nuevamente y probarlos con 83 u 85 para comprobar que esos si sirven.

En este momento, el callcenter está operando correctamente y los agentes hacen llamadas de manera normal. Ahora solo resta a la telefónica resolver el problema para que todo esté al 100%.

¡Suerte!