Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

lunes, 24 de mayo de 2021

Como implantar gratis el códec G729 en Asterisk

Los códecs de audio utilizados en Asterisk, generalmente son de uso abierto y sin licencia; siendo el códec G711 (allaw o ullaw) los más populares... Por desgracia, a veces nos podemos encontrar con impedimentos para implementar dichos códecs, viéndonos obligados a utilizar el códec G729, el cual es de pago... La cuestión está que es recomendable hacer pruebas de laboratorio antes de implementarlo, de ahí que sea recomendable montarnos un entorno gratuito en nuestro laboratorio a modo de testing... Es importante resaltar que el códec oficial siempre va a funcionar mejor, pero en entornos de desarrollo o de pruebas, la implementación de este códec es extremadamente interesante.

G729_portada

Este post es una pequeña guía está pensada para que uno pueda implementar el códec G729 con versiones de Asterisk 1.8 o superiores; los requisitos para instalarlo serían similares en todas las versiones pero con la diferencia de que la preparación del códec difiere en cada versión y habría que descargar el fichero adecuado para cada versión.  La web desde donde se descargan los ficheros sería la siguiente:

http://asterisk.hosting.lv/

A modo de recomendación, lo ideal sería descargar el fichero asterisk-g72x-1.4.3.tar.bz2 y compilarlo.

Para poder compilar los códecs G729 y G723 (ambos van incluidos en esta solución), lo primero de todo sería necesario instalar ciertas dependencias en Linux desde los repositorios oficiales de Linux vía APT; estas serían libtool,autoconf,zip y unzip, con lo que haríamos:

apt-get install libtool,autoconf,zip,unzip

Con las dependencias descargadas e instaladas, el primer paso sería instalar las librerías IPP de Intel, las cuales son necesarias para poder seguir adelante, aún sin tener una arquitectura de Intel. Dichas dependencias son fácilmente descargables desde la propia web oficial de Intel, descargando, siempre que sea posible, la versión más reciente posible.

https://software.intel.com/en-us/articles/intel-ipp-legacy-libraries

Con todo lo necesario descargado e instalado, ubicaríamos todos los ficheros descargados en /usr/src y ejecutaríamos los comandos:

tar -xf ipp90legacy_lin_9.0.0.008.tar
tar -xjf asterisk-g72x-1.4.3.tar.bz2

Accedemos al directorio descomprimido de ipp90… y allí hacemos:

unzip linux.zip

El proceso de descompresión pedirá una contraseña,  la cual sería: accept

Esto creará, tras un rato, una carpeta llamada linux, la cual habrá que mover a una ruta que inicialmente seguramente no exista con lo que lo que deberemos introducir dos comandos; uno para crear la ruta, y otra para mover la carpeta creada:

mkdir -p /opt/intel/ipp/
mv linux /opt/intel/ipp/legacy

Ahora accederíamos al directorio /opt/Intel/ipp/legacy/lib y dentro de este directorio descargaremos y descomprimiremos más librerías necesarias, librerías que serían necesarias para que los paquetes de Intel funcionen:

cd opt/Intel/ipp/legacy/lib
wget http://asterisk.hosting.lv/bin/icc-static-libs.tar.bz2
tar -xjf icc-static-libs.tar.bz2

Ahora que por fin tenemos las librerías preparadas,  accederíamos al directorio descomprimido de los códecs de Asterisk que hemos descomprimido antes:

cd /usr/src/asterisk-g72x-1.4.3/

Antes de preparar el códec haremos un enlace simbólico al directorio legacy, llamando a dicho enlace ipp:

ln -s opt/intel/ipp/legacy/ ipp

Finalmente ejecutamos el script autogen.sh, al cual habría que darle antes permisos de ejecución. Dicho script generará los deseados códecs:

chmod +x autogen.sh
./autogen.sh

Ahora podemos utilizar el códec G729 sin ningún problema; en cambio, para el códec G723 (en caso de querer usarlo) habría que acceder a /etc/asterisk/códecs.conf y añadir estas líneas:

[g723] ; 6.3Kbps stream, default sendrate=63 ; 5.3Kbps ;sendrate=53

Gracias a esto, ya tendríamos los códecs listos. Para verificar que los códecs han sido añadidos correctamente habría que acceder a Asterisk, recargar la configuración global y ejecutar el comando comando core show translations:

asterisk -rvvvvvvvv
reload
core show translation recalc 10

lista_codecs_asterisk

Como detalle, mencionar que en la lista veremos veremos guiones en todas las referencias a al códec G729; eso es debido a que éste no soporta transcoding (conversión de un códec a otro).

Por último, quedaría asegurarnos de que, tras este largo proceso, se va a utilizar el códec que queremos en /etc/asterisk/sip.conf; concretamente el códec debe de aparecer en el listado de códecs de allow; algo del estilo como el de a continuación:

allow=g729
disallow=all

Cabe recalcar, tal y como se ha dicho al principio, que siempre es recomendable optar por el códec oficial y que esta solución es útil en entornos que no sean de producción, como puede ser en laboratorios o en entornos de pruebas, o en entornos de aprendizaje.

Espero que os haya resultado útil; sí que es cierto que el proceso es tedioso, pero es muy útil para poder ahorrarnos el coste de la licencia asociada a dicho códec.

Saludos.

martes, 11 de mayo de 2021

Linux OOM (Out Of Memory) Killer: Qué es y qué importancia tiene

Pongámonos en la situación teórica de que tenemos un equipo con OS basado en Linux (independientemente de la distribución) con una alta carga de memoria RAM y múltiples servicios en marcha. De repente, el equipo tiene que realizar tareas que le suponen un mayor esfuerzo en términos de memoria y esto hace que al poco tiempo tengamos errores, tales como aplicaciones que misteriosamente se han cerrado solas, o errores más graves; como, por ejemplo, que una base de datos, haya entrado en modo “recovery mode”. ¿Por qué ha ocurrido esto?  Este fenómeno proviene del concepto OOM Killer.

Omm_Killer_portada

OOM Killer, se trata de un mecanismo que posee el kernel para liberar memoria RAM de forma abrupta para evitar el colapso del sistema; es decir que se trata de un mecanismo usado para evitar situaciones críticas, el cual, generalmente, previene de forma adecuada cualquier tipo de saturación del sistema y evita el bloqueo total del equipo/servidor. Desgraciadamente, en equipos con altas cargas de trabajo que poseen algunos servicios críticos (como puede ser PostgreSQL, MySQL o Apache), este mecanismo puede resultar fatal… Para entenderlo, primero hay que saber cómo funciona este mecanismo; o mejor dicho, qué prioridades tiene éste.

Las prioridades de OOM por defecto serían:

  • Mantener un mínimo de memoria RAM libre para que el Kernel pueda funcionar correctamente
  • Elimina el mínimo número de procesos posibles
  • Priorizar procesos que consuman mucha memoria
  • No eliminar procesos que consuman poca memoria
  • Mediante múltiples algoritmos internos dictaminar qué servicio con mucha memoria eliminar en caso de tener varios para elegir.

Además de esto, OOM revisa el oom_score (puntuación OOM), que revisa si el proceso tiene una mayor o menor prioridad para ser eliminado. Por defecto la mayoría de los procesos tienen una puntuación de 0, es decir que son servicios que ni tienen la prioridad de ser eliminados, ni tampoco tienen ninguna “protección” que les impida ser eliminados.  Dicha puntuación se puede ajustar asignarle un valor que puede oscilar entre -1000 y 1000, siendo -1000 el valor que haría que un proceso, jamás se eliminase, y 1000 el valor que haría que dicho proceso fuese eliminado el primero. 

Para revisar la puntuación por defecto de un proceso concreto habría que realizar el comando: 

cat /proc/numero_proceso/oom_score

Ejemplo:

cat /proc/1032/oom_score
0

Si deseásemos ajustar la puntuación de dicho proceso, habría que modificar el fichero /proc/numero_proceso/oom_score_adj, asignándole un valor entre -1000 y 1000, según conveniencia nuestra… 

echo -100 > /proc/1032/oom_score_adj

El problema que tiene este método es que es un método de ajuste “en vivo”, es decir que si bien ajustaría la puntuación del proceso, solamente sería valido mientras el proceso estuviese activo; si dicho proceso se parase/reiniciase por cualquier motivo, la puntuación volvería a ser la misma que se tenía originalmente… 

Afortunadamente, puede modificar de forma permanente, accediendo servicio de arranque del proceso deseado…  Presuponiendo que estemos usando un sistema basado en Systemd, simplemente habría que ir a la ruta /etc/systemd/system/ o a /run/systemd/generator.late/ (dependiendo del servicio) y editar el servicio que deseemos modificar. 

Dentro del fichero que estemos editando, habrá diferentes secciones, entre las cuales se encontrará la sección “service”; dentro de dicha sección habría que añadir la línea OOMScoreAdjust= Valor_deseado. Pongamos como ejemplo el servicio apache2.service

Antes:
[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/etc/init.d/apache2 start
ExecStop=/etc/init.d/apache2 stop
ExecReload=/etc/init.d/apache2 reload

Despues:
[Service]
OOMScoreAdjust=-100
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/etc/init.d/apache2 start
ExecStop=/etc/init.d/apache2 stop
ExecReload=/etc/init.d/apache2 reload

Gracias a esto habríamos ajustado la puntuación del servicio deseado; la gran cuestión sería… ¿Por qué casi siempre son escogidos los servicios más “críticos” tales como las webs o bases de datos?  Simplemente debido a que son procesos que de por sí consumen mucha memoria, pues manejan un gran volumen de datos y transacciones… En el caso de las bases de datos, podría también deberse a alguna consulta/operación SQL que esté tomando demasiado tiempo y recursos.

Si se desea, también se puede deshabilitar directamente esta utilidad, si bien no es recomendable, ya que se trata de una funcionalidad preventiva... Aún así, si fuese 100% hacerlo, solamente habría que ejecutar:
echo 1 > /proc/sys/vm/panic_on_oom
En caso de querer hacerlo permanente, habría que añadir dicho parámetro al fichero sysctl.conf, ya que el anterior comando solamente sería válido hasta el siguiente reinicio:
echo vm.oom-kill = 1 >> /etc/sysctl.conf
Es importante resaltar que esto no hace que OOM Killer sea una servicio “dañino”; simplemente ejecuta labores que protegen a todo el sistema, la cuestión está en que a veces, en un intento de protege el sistema entero,  se pueden llegar a detener de forma accidental servicios indeseados... Por eso, es recomendable no deshabilitarlo y buscar otras vías... Una de ellas es la modificación de un valor llamado overcommit_memory...

Linux por defecto puede asignar toda la memoria del mundo sin tener en cuenta la RAM disponible, cosa que no lo hace siempre sino que lo realiza cuando lo ve necesario; nosotros podemos editar el fichero overcommit_memory dentro /proc/sys/vm/ para que siempre lo haga o que solamente lo haga en determinadas circunstancias... El fichero en cuestión tiene un dígito que oscila entre 0 y 2 y que tiene lo siguientes comportamientos:

0: Valor por defecto. El sistema decide si asignarle más memoria de la que estaba previsa al proceso.
1: Si asignamos este valor, el sistema SIEMPRE  asignará toda la memoria al proceso en sin ningún tipo de garantía de que ésta esté disponible, en    caso de verlo necesario. Esta opción es peligrosa, pues corremos riesgo que el efecto OMM Killer ocurra aún más veces.
2: Al asignar este valor, solamente se asignará un % X de la memoria total sin garantía de que ésta esté disponible, donde X sería el valor numérico especificado en /proc/sys/vm/overcommit_ratio más la memoria swap de la que dispongamos. En caso de que no se pueda asignar más memoria de la que tengamos disponible, dicho asignamiento adicional de memoria no se realizaría, manteniendo "a salvo" el sistema y ayudando en parte a que no se ejecute el OMM Killer; especialmente cuando trabajamos con bases de datos como PostgreSQL. Es por eso que de que dicho valor se recomienda muy a menudo al trabajar con bases de datos PostgresSQL para garantizar que no se consuma más memoria la necesaria. Es importante resaltar que el valor por defecto es de 50, valor que es fácilmente modificable editando el fichero /proc/sys/vm/overcommit_ratio.

La formula exacta para conocer el limite de overcommit al tener el overcommit_memory con valor 2 sería:

(RAM_total * overcommit_ratio /100) + Memoria_swap

Visto todo esto, tendríamos una mayor comprensión de cómo funciona "Out Of Memory Killer", y las medidas a las que podemos recurrir para paliarlo. 

Como siempre, la solución más sencilla para estos casos siempre sería instalar más memoria RAM en el equipo; pero eso en muchas ocasiones es utópico, con lo que siempre es interesante conocer este tipo de medidas con el fin paliar el problema y evitar demasiados quebraderos de cabeza por cierres inesperados de programas.

Espero que os haya resultado útil.

Saludos.