Restringe el acceso a carpetas específicas usando Apache

18 Dic

url7[1]Nosotros nunca recomendamos exponer la interfaz web de tu conmutador (entiéndase: FreePBX/Elastix/Trixbox) bajo ningún motivo. Sin embargo, hay casos específicos en los cuales puede existir la necesidad de abrir el puerto HTTP/HTTPS para algunos servicios (ej. un CRM o alguna aplicación in house). Si esto debe de hacerse, es mejor hacerlo teniendo en cuenta algunas funciones básicas de seguridad.

Si aplicáramos lo que vimos en nuestros artículos del modelo de seguridad en Asterisk veremos que no es posible defender a nivel de firewall externo/iptables, ya que no hay una manera de permitir el paso solamente a ciertas carpetas. Para lograrlo, debemos hacer uso de la configuración de Apache la cual nos permite aplicar un mini firewall interno que solo permitirá a ciertas IPs ver ciertas páginas.

Primero, localicemos el archivo /etc/httpd/conf/httpd.conf (en algunos casos cambia de nombre a /etc/apache2/httpd.conf, así que hay que buscarlo con calma). Lo que buscamos es encontrar una directriz que permite el acceso por default a toda nuestra carpeta /var/www/html. El default en Elastix lo encuentran escrito así:

<Directory "/var/www/html">

#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
    Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    AllowOverride None

#
# Controls who can get stuff from this server.
#
    Order allow,deny
    Allow from all

</Directory>

Haciendo a un lado los comentarios, quedamos con estas instrucciones:

<Directory "/var/www/html">
SymLinksifOwnerMatch ExecCGI MultiViews
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Queremos ponerle atención a las lineas de Order allow,denyAllow from all. Explicamos lo que quiere decir:

  • Order allow,deny quiere decir que las instrucciones están declaradas como Permite primero, niega después.
  • Allow from all es una cláusula que permite que todos vean todo (default), lo cual le quita todas las restricciones a los usuarios.

El primer paso consiste en cerrar todo y permitir el paso solamente a direcciones IPs de confianza. Esto lo podemos conseguir con lo siguiente:

<Directory "/var/www/html">
SymLinksifOwnerMatch ExecCGI MultiViews
    Options Indexes FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 192.168.1.0/24
    Allow from 127
    Allow from 10.200.1.0/24
</Directory>

¿Notan la diferencia? Ahora estamos negando el paso a todo y permitiendo solamente que las redes de confianza 192.168.1.0/24, 10.200.1.0/24 y la de loopback tengan acceso completo al servidor. En otras palabras: solo las redes locales van a poder entrar a la administración web completa.

Para crear ahora carpetas sin restricción (ej. que cualquier usuario interno o externo las pueda ver), las agregamos como directrices nuevas:

<Directory "/var/www/html/vtigercrm" >
   Order deny,allow
   Allow from all
</Directory>

Y ahora estamos permitiendo el acceso completo a esa carpeta en particular (nuestro CRM). Por cada carpeta debemos crear una directiva <Directory> que permita el acceso.

Recuerden reiniciar el servicio de Apache:

/etc/init.d/httpd restart

# Según nuestra distro, el servicio se llama Apache2
/etc/init.d/apache2 restart

De esta manera, si abrimos http://<direccion ip publica>/vtigercrm podremos ver el CRM de nuestro equipo, pero si tratáramos de ver nuestra interfaz de administración con http://<direccion ip publica>/adminhttp://<direccion ip publica>

Advertencia: Siempre asegúrate de probar tu configuración de seguridad antes de ponerla en producción. Nosotros nunca recomendamos exponer el puerto HTTP/HTTPS, ya que aunque al usar esta configuración no permites el paso a otros usuarios, no quiere decir que no haya vulnerabilidades en tu código mostrado por Apache, así que acepta el riesgo de exponer tu equipo así. Lo mejor que puedes hacer es crear un nuevo equipo que hostee tu aplicación y exponer ese, sin que tengas abierto lo mismo en tu conmutador.

¡Suerte!

Recibe notificaciones push en tu móvil de llamadas hechas en Asterisk

13 Dic
pushover

Pushover está disponible para iOS y Android

Hace unos cuantos meses empecé a probar una aplicación para iOS/Android llamada Pushover que te permite crear notificaciones personalizadas de tipo push en tu móvil. El servicio es gratuito (solo debes comprar la aplicación que cuesta $4 USD) y te permite recibir hasta 7500 notificaciones al mes (suficientes creo yo). La aplicación es muy fácil de configurar: tras darte de alta solo debes registrar una aplicación (se te proporcionará un token al registrarla) y tomar nota de tu user key. Tras obtener esos datos, crea un script como el que sigue (puedes ponerlo en /sbin/push.php):

#!/usr/bin/php
<?php

// Reemplaza este valor por tu verdadero userKey de Pushover
$userKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

/**************************************************
 Reemplaza este valor con el de tu propia aplicación.
 Si no lo cambias recibirás notificaciones de parte de "Asterisk México"
 (según la cantidad de usuarios que usen este token, pueden acabarse las notificaciones
 permitidas por Pushover al mes 
***************************************************/
$appToken="ptTjW6PlKHU7lB5jOdhLN7vHlKSIei";

curl_setopt_array($ch = curl_init(), array(
  CURLOPT_URL => "https://api.pushover.net/1/messages.json",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POSTFIELDS => array(
     "token" => $appToken,
     "user" => $userKey,
     "message" => $argv[1],
   )));
curl_exec($ch);
curl_close($ch);

?>

No te olvides de hacer el script ejecutable:

chmod 755 /sbin/push.php

Con esto el script ya debe de enviarte notificaciones a tu teléfono. Puedes enviarte un mensaje de prueba para validarlo. Teclea en el CLI de Linux:

/sbin/push.php "Este es un mensaje de prueba"

Si lo ejecutas, deberas recibir una notificación como la siguiente:

Ejemplo de notificación de Pushover

Ejemplo de notificación de Pushover

Ahora toca decirle a Asterisk que nos envíe notificaciones. Vamos a ver el código necesario para 2 escenarios: Asterisk puro y Asterisk bajo FreePBX (Elastix/Trixbox)

 

Para Asterisk Puro:

Lo que necesitamos insertar es insertar una llamada a la aplicación System que invoque nuestra aplicación con los valores que necesitamos. Por ejemplo, supongamos que tenemos esta línea en nuestro plan de llamadas para hacer una marcación internacional (archivo extensions.conf):

exten => _00ZXXXX.,1,Dial(DAHDI/g0/${EXTEN})

Lo que requerimos es mandar llamar a la notificación antes de que se genere el Dial, quedando algo así:

exten => _00ZXXXX.,1,System(/sbin/push.php "Llamada de ${CALLERID(num)} hacia ${EXTEN}")
exten => _00ZXXXX.,n,Dial(DAHDI/g0/${EXTEN})

Es importante que escapemos correctamente las comillas » «, de lo contrario solo nos llegará la primer palabra del mensaje.

Si tratamos de marcar al exterior, recibiremos una notificación como la que sigue:

Notificaciones de llamadas de Asterisk en Pushover

Notificaciones de llamadas de Asterisk en Pushover

Con esto ya quedan las notificaciones a nuestro sistema usando Asterisk puro.

Para FreePBX/Trixbox/Elastix:

Editamos el archivo de extensions_custom.conf y hacemos uso del hook que ya existe en FreePBX para no tener que modificar nuestro código:

[macro-dialout-trunk-predial-hook]
exten => s,1,System(/sbin/push.php "Llamada de ${CALLERID(num)} hacia ${OUTNUM}")

Ojo: esto enviará notificaciones por cada llamada que use troncales. Si quieren que solo se use para cierto tipo de llamadas, necesitan validar la variable ${OUTNUM} para que solo contenga los números que ustedes quieran.

 

¡Suerte!

Asterisk con Alta-Disponibilidad + MySQL

10 Dic

Este tutorial fue escrito por uno de los participantes de nuestro foro: navaismo.
El artículo original lo pueden encontrar aquí.

En algunas ocasiones nos vemos en la necesidad de crear un Cluster de alta disponibilidad para nuestros servicios de Asterisk. A continuación se describen los pasos necesarios para llevar esto acabo en nuestros servidores usando Asterisk y Mysql(por si queremos usar Asterisk Realtime Architechture).

Algunas indicaciones iniciales:

  • Estos pasos están basados en las instrucciones que brinda Digium y los tutoriales de DRBD para Mysql.
  • Este tutorial no esta hecho para hacer copy&paste.
  • El color verde indica que son pasos para realizar en ambos servidores.
  • El color Naranja indica que son pasos para realizar en el servidor primario.
  • El color Rojo indica que son pasos para realizar en el servidor secundario.
  • El Hostname del Servidor primario es «node1«.
  • El Hostname del Servidor secundario es «node2«.
  • La dirección IP del servidor primario es 10.0.1.51
  • La dirección IP del servidor secundario es 10.0.1.52
  • La dirección IP compartida del cluster y a la que deberán apuntar los servicios(como el registro de teléfonos, MySQL o apache) es 10.0.1.50.
  • La dirección IP del Gateway es 10.0.1.1.
  • Se puede adaptar fácilmente el Hardware Failover que provee Digium(rseries) y los servicios de Apache.

DRBD Cluster

La Imagen anterior describe el funcionamiento del Cluster:

  • Escenario 1: El servidor primario esta activo y el secundario esta en modo pasivo esperando.
  • Escenario 2: El servidor Primario ha entrado en estado de falla(por conexión de RED o por reinicio o falla en el kernel), el servidor secundario entonces, se convierte en el servidor primario y es marcado como activo.
  • Escenario 3: El servidor secundario(antes primario) se ha recuperado de la falla y ha entrado en modo pasivo.
  • Escenario 4: El servidor primario(antes secundario)  ha presentado falla  y el servidor secundario(antes primario) es marcado como servidor primario nuevamente y entra en modo activo.

 

Paso 1 —- Realizar en Ambos Servidores:

Instala CentOS 5.X(Los agentes de recursos «ocf»de Digium no son compatibles con las versiones 6.X de CentOS). Escoger el modo de partición manual y dejar un espacio libre sin formateo ni nada, en este tutorial yo he dejado 5GB sin particionar. Este espacio será donde guardemos nuestros datos a replicar en el Cluster, así que deberán considerar cuanto espacio necesitaran para sus archivos y logs.

 

Paso 2 —- Realizar en Ambos Servidores:

Instala las dependencias para nuestros servidores. Primero añadiré el repositorio de rpmforge:

rpm -ihv http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.[ARCH].rpm

Cambia [ARCH] por la arquitectura del servidor: i386 o x86_64.

Ahora instala las dependencias:

yum -y install kernel kernel-devel libxml2  libxml2-devel  libtiff  libtiff-devel  lame httpd  mysql mysql-devel mysql-server php  php-pear  php-mysql  php-gd openssl openssl-devel perl  bison ncurses-devel audiofile-devel curl sox gcc newt-devel libusb-devel glibc-devel  zlib-devel svn gcc-c++ subversion make nano wget cfdisk

 

Paso 3 —- Realizar en Ambos Servidores:

Ejecuta el comando:

cfdisk

Obtendrás una ventana como esta:

Selecciona el espacio libre y crea una nueva partición con todo el espacio libre usando los botones: New, Primary, Write. Al finalizar te preguntara si quieres efectuar los cambios, escribe la palabra: yes y da enter.

Cuando el proceso termine reinicia el servidor:

reboot

Una vez que el servidor haya arrancado de nuevo hay que limpiar la nueva partición usando el siguiente comando:

dd if=/dev/zero of=/dev/[hs]da[#] bs=1M; sync

Cambia /dev/[hs]da[#] por tu dispositivo que puede ser SDA3,HDA3 o SDB3 HDB3 etc. En este tutorial es HDA3.

Veras una salida similar cuando termine el proceso, dependiendo del tamaño de tu partición y de la velocidad de tus discos duros puede tomar minutos u horas.

Crea un nuevo directorio en /usr/src:

cd /usr/src/
mkdir asterisk
cd asterisk/

En el nuevo directorio descarga Asterisk y sus componentes:

wget http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/dahdi-linux-complete-2.6.1+2.6.1.tar.gz
wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-1.4.13.tar.gz
wget http://downloads.asterisk.org/pub/telephony/certified-asterisk/certified-asterisk-1.8.11-current.tar.gz
wget http://downloads.digium.com/pub/telephony/rseries/rseries-current.tar.gz

Descomprime los archivos fuente:

for i in `ls *gz`; do tar zxvf $i; done

Compilamos DAHDI:

cd dahdi-linux-complete-2.6.1+2.6.1
make && make all && make install && make config

Compilamos LibrPRI y configuramos DAHDI:

cd ../libpri-1.4.13
make && make install
service dahdi start
dahdi_genconf
dahdi_cfg -vvvvv

Instalamos los agentes de Digium para el cluster:

cd ../rseries-1.0.0/
make && make install

 

Paso 4 —- Realizar solo en  Servidor Primario..

Instalar Asterisk en el servidor primario:

cd ../certified-asterisk-1.8.11-cert9
contrib/scripts/get_mp3_source.sh
./configure && make menuselect

En el menú selecciona las aplicaciones que quieras disponibles en tu asterisk:

Guarda los cambios y compila Asterisk:

make && make install && make config && make samples

Inicia el servicio de Mysql y detenlo esto solo para crear las bases de datos por default.

service mysqld start
service mysqld stop

 

Paso 5 —- Realizar en Ambos Servidores.

Cambiate al directorio de rseries:

cd /usr/src/asterisk/rseries-1.0.0/

Instala los servicios de DRBD:

yum -y install drbd83 kmod-drbd83

Instala Libesmtp, dependencia necesaria para Pacemaker:

wget http://dl.fedoraproject.org/pub/epel/5/[ARCH]/libesmtp-1.0.4-5.el5.[ARCH].rpm #64bits

Cambia [ARCH] por la arquitectura del servidor: i386 o x86_64.

Instala PaceMaker y Corosync:

wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm/epel-5/clusterlabs.repo
yum -y install -x heartbeat-stonith* pacemaker corosync

Estamos exluyendo el paquete heratbeat-stonith ya que cre un conflicto con pacemaker.

Instala los archivos de configuración que provee Digium:

make samples

Agrega estas lineas al archivo /etc/drbd.conf:

echo «include «drbd.d/global_common.conf»;» >> /etc/drbd.conf

echo «include «drbd.d/*.res»;» >> /etc/drbd.conf

Edita el archivo /etc/drbd.d/asterisk.res. Cambia astnode1 por el nombre el hostname del servidor primario, cambia astnode2 por el hostname del servidor secundario, cambia /dev/sda3 por la partición que creamos con el espacio libre(en este tutorial hda3). Cambia las IPs por las de tus servidores primarios y secundarios.Cambia el correo electrónico por el tuyo o el administrador del sistema en este tutorial el archivo quedo así:

resource asterisk {
  handlers {
    split-brain "/usr/lib/drbd/notify-split-brain.sh clusteradmin@example.com";
  }

  net {
    after-sb-0pri discard-younger-primary;
    after-sb-1pri discard-secondary;
    after-sb-2pri disconnect;
  }

  on node1 {
    device    /dev/drbd0;
    disk      /dev/hda3;
    address   10.0.1.51:7789;    
    meta-disk internal;
  }
  on node2 {
    device    /dev/drbd0;
    disk      /dev/hda3;
    address   10.0.1.52:7789;
    meta-disk internal;
  }
}

Crea el Recurso llamado asterisk e inicia el servicio de DRDB:

drbdadm create-md asterisk
service drbd start

 

Paso 6 —- Realizar solo en  Servidor Primario.

A continuación crea el UUID llamado Asterisk, y formatea la partición que será usada por el cluster tipo: EXT3

drbdadm disconnect asterisk
drbdadm -- --clear-bitmap new-current-uuid asterisk
drbdadm -- --overwrite-data-of-peer primary asterisk
mkfs.ext3 -m0 /dev/drbd0
drbdadm secondary asterisk
drbdadm detach asterisk
drbdadm up asterisk

Crea el directorio que será usado para el cluster, pero antes marca como nodo primario para poder montarlo:

drbdadm primary asterisk
mkdir /mnt/asterisk

Monta la partición:

mount -t ext3 /dev/drbd0 /mnt/asterisk

Ahora crea el directorio donde estará Mysql:

mkdir /mnt/asterisk/mysql
mkdir /mnt/asterisk/mysql/data
cd /mnt/asterisk/mysql

 

Copia el contenido del directorio de Mysql al nuevo directorio:

cp -aR /var/lib/mysql/* /mnt/asterisk/mysql/data
ls data/

 

Mueve el archivo /etc/my.cnf al nuevo directorio de Mysql:

mv /etc/my.cnf .

Crea un enlace simbólico al nuevo directorio:

ln -s /mnt/asterisk/mysql/my.cnf /etc/

Edita el archivo my.cnf y cambia la directiva de DATADIR: datadir=/mnt/asterisk/mysql/data.


Crea un archivo dummy solo para verificar la replicación en el nodo secundario.

touch test11

Desmonta la partición y marca el nodo como secundario:

cd --
umount /mnt/asterisk
drbdadm secondary asterisk

 

Paso 7 —- Realizar solo en Servidor Secundario

Elimina el archivo /etc/my.cnf

rm -rf /etc/my.cnf

 

Vamos a verificar que los archivos de nuestra partición en el cluster se repliquen. Marca el servidor como primario y crea el mismo directorio:

drbdadm primary asterisk
mkdir /mnt/asterisk

 

Monta la partición y cambiate al directorio:

mount -t ext3 /dev/drbd0 /mnt/asterisk
cd /mnt/asterisk

Haz un enlace simbolico del archo my.cnf al directorio de la partición del cluster:

ln -s /mnt/asterisk/mysql/my.cnf /etc/

Verifica que el archivo my.cnf sea el mismo que editamos anteriormente, es decir, que contenga:  datadir=/mnt/asterisk/mysql/data

Verifica que los archivos de Mysql y el archivo test11 existan en el directorio:

ls

Si los archivos existen la replicación va de maravilla.

Desmonta la partición y marca el nodo como secundario:

cd --
umount /mnt/asterisk
drbdadm secondary asterisk

 

Paso 8 —- Realizar solo en  Servidor Primario.

Cambiate al directorio de rseries, mara el servdiro como primario y monta la partición:

cd /usr/src/asterisk/rseries-1.0.0
drbdadm primary asterisk
mount -t ext3 /dev/drbd0 /mnt/asterisk/

 

Ejecuta el script cretalinks.sh:

./createlinks.sh

Veras una salida como la siguiente:

Elimina el script de asterisk para que no arranque automáticamente cuando inicie el sistema, desmonta la partición y marca el nodo como secundario:

chkconfig --del asterisk
umount /mnt/asterisk
drbdadm secondary asterisk

 

Paso 9 —- Realizar solo en Servidor Secundario

Cambiate al directorio de rseries, marca el nodo como primario, monta la partición y ejecuta el script createlinks.sh:

cd /usr/src/asterisk/rseries-1.0.0
drbdadm primary asterisk
mount -t ext3 /dev/drbd0 /mnt/asterisk/
./createlinks.sh

Veras una salida como en la imagen anterior.

Cambiate al directorio de Asterisk, configura las mismas opciones que se configuraron en el servidor primario. Compilalo solo ejecutando make && make install. Desmonta la partición y marca el nodo como secundario.

cd ../certified-asterisk-1.8.11-cert9
contrib/scripts/get_mp3_source.sh
./configure && make menuselect
make && make install
umount /mnt/asterisk/
drbdadm secondary asterisk


Paso 10 —- Realizar en Ambos Servidores.

Edita el archivo /etc/corosync/corosync.conf. Cambia la opción bindnetaddr, y las opciones memberaddr. Para este tutorial el archivo quedo de la siguiente manera:

totem {
        version: 2
        token: 3000
        token_retransmits_before_loss_const: 10
        join: 60
        consensus: 5000
        vsftype: none
        max_messages: 20
        clear_node_high_bit: yes
        secauth: off
        threads: 0
        rrp_mode: none

        interface {
                ringnumber: 0
                bindnetaddr: 10.0.1.0
                broadcast: yes
                mcastport: 5405
                member {
                        memberaddr: 10.0.1.51
                }
                member {
                        memberaddr: 10.0.1.52
                }
        }
}

aisexec {
        user:   root
        group:  root
}

logging {
        fileline: off
        to_stderr: yes
        to_logfile: no
        to_syslog: yes
        syslog_facility: daemon
        debug: off
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
                tags: enter|leave|trace1|trace2|trace3|trace4|trace6
        }
}

amf {
        mode: disabled
}

Inicia el servicio de Corosync y añade drbd y corosync al startup:

service corosync start
chkconfig drdb on
chkconfig corosync on

Verifica el estado del Cluster con el siguiente comando:

cat /proc/drbd

Veras una imagen como la siguiente:

Veras que se esta sincronizando la particion del cluster, también verás como Secondary/Secondary(no como en la imagen).

Si el proceso de sincronización reporta que tardará mucho tiempo puedes usar este comando para acelerar la velocidad de sincronización:

drbdsetup /dev/drbd0 syncer -r 250M

La velocidad máxima de sincronización dependerá de la velocidad de tus tarjetas de red así como la velocidad de escritura de tus discos duros. Para más información de como calcular la velocidad ve a este enlace.

Una vez que el estado sea UpToDate/UpToDate reinicia los servidores:

reboot

 

Paso 11 —- Realizar solo en  Servidor Primario.

Edita el siguiente codigo para que:

— node1 y node2. Sean los hostnames de tus servidores. En este ejemplo node1 y node2

ip bajo ClusterIP. Sea la Ip de tu Cluster, la IP flotante. En este ejemplo 10.0.1.51

cidr_mask bajo ClusterIP. Sea la mascara de tu red. en este ejemplo de 24bits(255.255.255.0)

– –host_list bajo GatewayStatus. Sea el gateway de tu red. en este ejemplo 10.0.1.1

node node1
node node2
primitive ClusterIP ocf:heartbeat:IPaddr2 
        params ip="10.0.1.50" cidr_netmask="24" 
        op monitor interval="5"
primitive drbd ocf:linbit:drbd 
      params drbd_resource="asterisk" 
      op monitor start-delay="10" interval="5"  
primitive drbd_fs ocf:heartbeat:Filesystem 
      params device="/dev/drbd0" directory="/mnt/asterisk/" fstype="ext3"
primitive mysqld lsb:mysqld
primitive Asterisk ocf:Digium:asterisk 
        op monitor interval="5"
primitive GatewayStatus ocf:pacemaker:ping 
        params host_list="10.0.1.1" multiplier="100" 
        op monitor interval="5" timeout="10"
ms drbd_ms drbd 
        meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
clone GatewayStatusClone GatewayStatus
location Asterisk-with-ping Asterisk 
        rule $id="Asterisk-with-ping-rule" -inf: not_defined pingd or pingd lte 0
group mysql drbd_fs ClusterIP mysqld
colocation mysql_on_drbd inf: mysql drbd_ms:Master
order mysql_after_drbd inf: drbd_ms:promote mysql:start
colocation Everything-with-Asterisk inf: ( drbd_ms:Master )  ( ClusterIP drbd_fs )  Asterisk
order  Asterisk-after-Everything inf:   ( drbd_ms:promote ) ( ClusterIP drbd_fs )  Asterisk:start
property $id="cib-bootstrap-options" 
        cluster-infrastructure="openais" 
        expected-quorum-votes="2" 
        stonith-enabled="false" 
        no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" 
        resource-stickiness="99"

Una vez que has editado el archivo Cluster_Mysql_Asterisk.cfg, actualiza la configuración de pacemaker:

crm configure load update Cluster_Mysql_Asterisk.cfg

Si todo sale bien veras una salida como la siguiente y los servicios de MySQL y Asterisk se iniciaran en el nodo primario:

Para verificar que los servicios estén corriendo puedes revisar el estado del cluster con:

crm_mon

Y verás algo así:

Demostración:


El siguiente video muestra las pruebas del cluster. Asterisk esta configurado con «static realtime» obteniendo los datos de una base de datos de MySQL. Este tutorial no cubre la cofiguración de ARA(Asterisk Realtime Architechture).

Herramientas para diagnosticar fallas:

Puedes ejecutar el siguiente comando en el nodo secundario para verificar que la configuración de pacemaker se replico:

crm configure show

Para detener los servicios del cluster:

crm configure property stop-all-resources=true

Para borrar la configuracion del cluster:

crm configure erase

Verificar el estado del cluster:

crm_mon

Verificar el estado de la sincronización y los roles de los servidores:

cat /prco/drbd

Aumentar la velocidad de sincronización:

drbdsetup /dev/drbd0 syncer -r 250M

Como bloquear extensiones al final del día (cerrar extensión cuando el trabajador se retira)

3 Dic

En ocasiones en nuestras oficinas (sobretodo en grandes corporativos), estamos sujetos a presupuestos de llamadas por mes. Esto quiere decir que recibimos una bolsa de minutos a ciertos destinos (para control de gastos) y debemos cuidarlos, ya que si nos los agotamos tendremos que hacer solicitudes de «crédito» interno y ante nuestros superiores parecería como que estamos desperdiciando dinero (llamadas) de la empresa.

Contemplando escenarios similares a este, podemos configurar Asterisk para que las extensiones de cada persona sean bloqueadas al momento en que la persona se retira a su casa. De esta manera, si alguien se queda cercano a su área de trabajo no podrá tomar su teléfono y hacer llamadas al exterior, reduciendo el crédito del trabajador que ya se fue (y ahorrándose el suyo). Al día siguiente, cuando el trabajador regresa, marca un código de desbloqueo junto con su contraseña y su teléfono vuelve a estar habilitado.

¿Cómo hacer eso?

Partiremos de los siguientes supuestos:

  • El contexto al que mis extensiones «normales» tienen derecho es el from-internal.
  • El código para bloquear la extensión (cuando el trabajador se va), será *51.
  • El código para desbloquear la extensión (cuando el trabajador regresa por la mañana), será *52.
  • Todas las extensiones deben tener un buzón asignado. El número de buzón debe ser el mismo que el de la extensión.
  • La marcación que negaremos será solamente la que corresponda a llamadas locales, larga distancia, celulares e internaciones (es decir, todas las que cuesten).
  • La sintaxis que estoy ocupando (same =>) es para Asterisk 1.6.2 o superior.

Toda la magia viene en el archivo extensions.conf (si usas Trixbox/Elastix/FreePBX, debes de hacerlo dentro del archivo extensions_custom.conf)

[from-internal-custom]
; Estos son los patrones para hacer las llamadas
; Si necesitas cerrar más patrones, agrégalos siguiendo el mismo formato
exten => _ZXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _04[45]ZXXXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _01ZXXXXXXXXX,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)
exten => _00ZXXXXXXXX.,1,Macro(permitir)
same => n,Goto(from-internal-additional,${EXTEN},1)

; Este es el código de bloqueo. Es lo que el trabajador marca antes de retirarse
exten => *51,1,Noop(Bloqueando ${CALLERID(num)})
;same => n,VMAuthenticate(${CALLERID(num)})     ; Descomenta esta línea si quieres pedir contraseña también al bloquear
same => n,Set(DB(bloqueo/${CALLERID(num)})=1)
same => n,Playback(vm-goodbye)
same => n,Hangup
; Este es el código de desbloqueo. Es lo que marca a la mañana siguiente
exten => *52,1,Answer
same => n,VMAuthenticate(${CALLERID(num)})
same => n,Noop(${DB_DELETE(bloqueo/${CALLERID(num)})})
same => n,Playback(auth-thankyou)
same => n,Hangup

; El macro-permitir es lo que valida si una extensión tiene o no activada el bloqueo
[macro-permitir]
exten => s,1,Noop(Revisando permisos de ${CALLERID(num)})
same => n,GotoIf($[${DB_EXISTS(bloqueo/${CALLERID(num)})}]?Bloquear:Permitir)
same => n(Bloquear),Noop(Deteniendo el paso de ${CALLERID(num)})
same => n,Playback(pbx-invalid)  ; Reemplazar por cualquier archivo de sonido deseado
same => n,Congestion()
same => n(Permitir),Noop(Permitiendo el paso de ${CALLERID(num)} --> ${MACRO_EXTEN})

Una breve explicación de lo que hace cada cosa:

  • Los patrones de ZXXXXXXX, 01ZXXXXXXXXX, 04[45]ZXXXXXXXXX y 00ZXXXXXX. son para controlar las llamadas locales, larga distancia nacional, celulares y LD internacional respectivamente. Si tienes más patrones de marcación o destinos que desees bloquear (por ejemplo, alguna marcación corta por telular), necesitas agregar el patrón correspondiente siguiendo el mismo formato (tras cada patrón debe haber una continuación same => n,Goto(from-internal-additional,${EXTEN},1) que te permite continuar con el contexto from-internal-additional.
  • *51 y *52 son, como habíamos comentado, los códigos para bloqueo/desbloqueo respectivamente. Puedes reemplazar los Playbacks por lo que tu elijas para dar diferentes mensajes
  • El [macro-permitir] es el que checa el contenido del Asterisk DB. Si la familia bloqueo/CALLERID existe, entonces no se le permiten las llamadas. Si no existe, el macro permite el paso y la llamada continúa de manera normal.
  • Las autenticaciones se hacen con la misma contraseña del buzón de voz, así cada quien tiene la suya, es actualizable por el usuario y solo funciona dentro de su mismo teléfono.
  • Si deseas desbloquear manualmente alguna extensión (ej. alguien olvidó su contraseña), solo debes ejecutar database del bloqueo <ext> dentro del *CLI.

Con esto lograremos que al cierre del turno, el trabajador pueda bloquear su teléfono y reactivarlo a la mañana siguiente con solo ingresar su contraseña.

Debo agregar que funciona tan bien que anoche que lo implementé dejé cerrada mi extensión y hoy no me permitía hacer llamadas, hasta que marqué *52 e introduje mi contraseña nuevamente.

¡Suerte!