Self-host audio recordings with AudioVault and Nginx

Self-hosting call recordings on your QueueMetrics-Live instance can save money, and make management easier. In this guide, we’ll show you how to use AudioVault and Nginx as a secure proxy on ports 4005 and 4006, allowing your QueueMetrics-Live instance or remote QueueMetrics server to play back recordings directly from reports for a low cost SSL certificate.

In this guide we are going to focuse on FreePBX version 16; as well as using two different ports, 4005 and 4006, since 80 and 443 are usually reserved by FreePBX.

Prerequisites

  • a hosted FreePBX instance;

  • a domain name for the FreePBX server (in this guide, “audiovault.mydomain.com”);

  • a valid SSL certificate for the domain (not self-signed nor Let’s Encrypt);

  • a QueueMetrics-Live instance;

  • ort 4006 opened in your firewall;

  • recordings divided in sub-folders by year/month/day.

Setting up the PBX server

On the PBX server, we simply need to make sure that the recordings are present (usually in the /var/spool/asterisk/monitor/ folder). Make sure the Uniloader service is installed (at least version 21.4).

You can check the Uniloader version with:

uniloader -v

If Uniloader is not installed, use the following commands:

wget https://yum.loway.ch/loway.repo -O /etc/yum.repos.d/loway.repo
yum install uniloader

Creating the AudioVault service

Create and edit the “uniloader-audiovault” file with:

nano /etc/init.d/uniloader-audiovault

With:

#!/bin/bash
#
# Startup script for Uniloader AudioVault.

# Source function library.
. /etc/rc.d/init.d/functions

pidfile=${PIDFILE-/var/run/uniloader-audiovault.pid}
logfile=${LOGFILE-/var/log/asterisk/uniloader-audiovault.log}
lockfile=${LOCKFILE-/var/lock/subsys/uniloader-audiovault}

prog=$0
RETVAL=0

start() {
    echo -n $"Starting AudioVault:"
    uniloader av serve \
    --path file:/var/spool/asterisk/monitor/%YY/%MM/%DD/ \
    --token MYTOKEN \
    --public-url https://audiovault.mydomain.com:4006 \
    --bind-to localhost:4005 \
    --pid $pidfile \
    >>$logfile 2>&1 &
    echo_success
    echo
    touch ${lockfile}
    return 1
}

stop() {
    echo -n $"Stopping AudioVault:"
    kill $(cat ${pidfile}) 2> /var/null
    sleep 1
    RETVAL=$?
#    echo_success
#    echo
    if [ $RETVAL = 0 ]
    then
  rm -f ${lockfile} ${pidfile}
    fi
    return $RETVAL
}

status() {
  if [ ! -f ${pidfile} ]
  then
    echo "$prog is not running"
    RETVAL=3
  else
    echo "$prog is running..."
    RETVAL=0
  fi
  return $RETVAL
}
# See how we were called.
case "$1" in
  start)
        start
    ;;
  stop)
        stop
    ;;
  restart)
    stop
    start
    ;;
  status)
  status
  ;;
  force-reload)
    stop
    start
    ;;
  *)
  echo $"Usage: $prog {start|stop|restart|status|force-reload}"
  exit 1
esac

exit $RETVAL

You will need to edit the following variable with:

  • path file:…​. → the path to the recordings

  • token → the token, basically the password that you chose, to access the recordings

  • public-url → the domain name, where the recordings will be found, as seen from QueueMetrics Live

  • :4006 → we are going to use this port, you can change it if you need to

  • bind-to localhost → in this case we are going to be using port 4005, you can change it if you need to

Add permissions using:

chmod 757 /etc/init.d/uniloader-audiovault

Reload the Unit changed on disk:

systemctl daemon-reload

Enable the uniloader-audiovault service with:

systemctl enable uniloader-audiovault

And finally, start the AudioVault service with:

service uniloader-audiovault start

Setting up the Nginx service

Make sure Nginx is installed on your server (at least version 1.16).

Edit the Nginx configuration file in this folder:

nano /etc/nginx/nginx.conf

Like this:

user nginx nginx;
worker_processes auto;

error_log /var/log/nginx/error.log info;

pid /run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
}

http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        log_format main
                '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $bytes_sent '
                '"$http_referer" "$http_user_agent" '
                '"$gzip_ratio"';
        client_header_timeout 10m;
        client_body_timeout 10m;
        send_timeout 10m;
        connection_pool_size 256;
        client_header_buffer_size 1k;
        request_pool_size 4k;
        gzip off;
        output_buffers 1 32k;
        postpone_output 1460;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 75 20;
        ignore_invalid_headers on;
        large_client_header_buffers 4 128k;
        server_tokens off;

        include /etc/nginx/conf.d/audiovault_https.conf;
}

Create a new “audiovault_https.conf” configuration file here:

/etc/nginx/conf.d/audiovault_https.conf

Like this:

server {
        listen 4006 ssl http2;
        server_name audiovault.mydomain.com;

        access_log /var/log/nginx/audiovault.mydomain.com.access_log main;
        error_log /var/log/nginx/audiovault.mydomain.com.error_log info;

        ssl on;
        ssl_certificate /etc/ssl/nginx/audiovault_mydomain_com.crt;
        ssl_certificate_key /etc/ssl/nginx/audiovault_mydomain_com.key;
        ssl_dhparam /etc/ssl/nginx/dhparam;

        ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+aRSA+AESGCM !EECDH+ECDSA+AESGCM !EECDH+ECDSA+SHA384 !EECDH+ECDSA+SHA256 !EECDH+aRSA+SHA384 !EECDH+aRSA+SHA256 !EDH+aRSA !aNULL !eNULL !LOW !MD5 !EXP !PSK !SRP !DSS !RC4 !EECDH+aRSA+RC4 !3DES";
        ssl_session_cache shared:SSL:50m;
        ssl_session_timeout 5m;
        add_header Strict-Transport-Security "max-age=31536000; preload" always;

        root /var/www;


        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Port $server_port;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header X-Forwarded-Webapp /audiovault;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Url-Scheme $scheme;
                proxy_pass http://127.0.0.1:4005;
                proxy_read_timeout 240s;
        }
}

Create the following folder:

mkdir -p /etc/ssl/nginx

Generate the “dhparam” file with the following command:

openssl dhparam -dsaparam -out /etc/ssl/nginx/dhparam 4096

Don’t forget to copy your .crt and .key files in the /etc/ssl/nginx/ folder.

Make sure to enable the Nginx service with:

systemctl enable nginx

And restart the service with:

service nginx restart

Opening port 4006 in FreePBX

In order for QueueMetrics to be able to see the call recordings, we will need to make sure Port 4006 is open, and accessible from outside your network.

If you are using FreePBX it would be enough to create a new Custom Service:

FreePBX Homepage → Connectivity → Firewall → Services (menu on the right) → Custom Services → Create new service:

Description: AudioVault
Protocol: Both
Port Range: 4006

Save and apply the changes.

Setting up the QueueMetrics-Live instance

Now, the only thing to do, is to make sure QueueMetrics knows where to look for the call recordings.

Go to your QueueMetrics-Live instance and add the following parameters at the end of the file:

Homepage → Settings → Edit system parameters

# AudioVault configuration
audio.server=it.loway.app.queuemetrics.callListen.listeners.JsonListener
audio.jsonlistener.url=https://audiovault.mydomain.com:4006/search/
audio.jsonlistener.method=POST
audio.jsonlistener.searchtoken=MYTOKEN
audio.jsonlistener.verbose=false
audio.html5player=true
  • audio.jsonlistener.url → is the URL to the AudioVault recordings and the port you are using, followed by /search/

  • audio.jsonlistener.searchtoken → is the token that we chose previously, when creating the AudioVault service

Log out and then back in QueueMetrics, for the changes to take effect.

You can now open the call details of a call, and find the audio recordings in the QA tab.

Troubleshooting

Call recordings are not visible

  • Make sure that the call recordings are accessible in the /var/spool/asterisk/monitor/ and the name of the audio files include the Asterisk Unique ID of the call.

  • Verify that your SSL certificate is installed correctly on your server, using a service like geocertsssl ssl-checker.

  • Make sure port 4006 is open in your firewall, as stated above.

The report page is slow to load the recording

The recordings need to be divided in sub-folders by year, month and day, for better performance. If you need to change the settings on your FreePBX, you can have a look at this guide.