We have made our server component (AWARE Dashboard) open-source over GitHub. This allows you to host your own server and full control over the AWARE Dashboard. Feel free to break it, fix it, enhance it and share it back.

With great power comes great responsibility” – Uncle Ben, from Spider-Man.

This tutorial is not for everyone. If all you need is to host a study database, we do offer a remote database setup per study in our own AWARE Dashboard. We use a self-signed SHA-256 with a 2048-bit long RSA strong encryption key on our setup in all communications between clients and our server. It is your responsibility to make sure you do too. We are not responsible for any misconfiguration from your side!

aware-architecture

At its core, the current version of AWARE Dashboard runs on top of a LAMP (Linux, Apache, MySQL, PHP) + a Mosquitto MQTT Server infrastructure. There are many guides online on how to setup your own LAMP server, and they depend on the distribution you use. We use Ubuntu 14.04 LTS on this guide, but these instructions should be somewhat compatible with other Linux distributions, adjusting accordingly to your distribution package manager and package names. Install your LAMP stack before continuing this tutorial.

In terms of firewall, the server will need 3 TCP/UDP ports open:

  • 443 – used by HTTPS AWARE Dashboard access and data synching
  • 80 – used by HTTP AWARE clients to download the server.crt and ca.crt public SSL certificates (not necessary if using LetsEncrypt)
  • 8883 – used by Mosquitto MQTT-SSL connections
  • 3306 – used by MySQL, also over an encrypted SSL connection

0. LetsEncrypt SSL for LAMP + Mosquitto servers (HIGHLY recommended for a grade A security protection for study data)

There is an official client from LetsEncrypt that generates a valid SSL certificate that you can use with your AWARE server. This assumes your server has a registered domain associated with it (henceforth referred as YOUR_DOMAIN). Please replace YOUR_DOMAIN with your own server’s public domain name. The client is called CertBot (https://certbot.eff.org/). Specify your server configuration and a certbot executable will be made available to you. Selecting Apache and Ubuntu 14.04, you need first some packages.

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-apache

CertBot allows you to automatically configure Apache and assign the certificates to your host.

$ sudo certbot --apache

Running this command will get a certificate for you and have Certbot edit your Apache configuration automatically to serve it. Certbot come with a cron job that renews the certificate automatically before they expire. As LetsEncrypt certificates are valid for 90 days, we must take advantage of this feature. You can test automatic renewals using this command:

$ sudo certbot renew --dry-run

If all is OK, you can add a cron or systemd job running this command to actually renew your certificate:

certbot renew

Please refer to Certbot’s official documentation if you encounter any issues regarding deploying LetsEncrypt certificates on your server. You can now go to step 1.

0. Self-signed SSL encryption keys for our LAMP + Mosquitto servers (not recommended anymore as browsers are blocking access to self-signed SSL websites…)

The following commands (as $) will install the necessary packages and create the files you will need to secure your LAMP and Mosquitto servers. We are creating a strong SHA-256 2048-bit RSA encryption certificate, just like ours.

When creating SSL certificates, the most important piece of information to validate the server URL/IP is the Common Name, which always needs to match your server’s domain/IP. The Common Name must be the same for both the Certificate Authority (CA) and the server SSL certificate.

#Installing necessary packages
$ sudo apt-get install openssl ssl-cert apache2-utils ca-certificates php5-mcrypt php5-mysql default-jre libwebsockets-dev

#Activating support for SSL on Apache
$ sudo a2enmod ssl

#Activating support for SSL in PHP
$ sudo php5enmod mcrypt

#Restart Apache and PHP
$ sudo service apache2 restart

#Generate a self-Certificate Authority (CA) key issuer
$ openssl req -sha256 -new -x509 -days 1825 -extensions v3_ca -keyout ca.key -out ca.crt

#Create SSL certificate SHA-256 2048-bit RSA encryption
$ openssl req -sha256 -new -newkey rsa:2048 -days 1825 -nodes -x509 -keyout server.key

#Generate a Certificate Signing Request (CSR) for your CA
$ openssl req -sha256 -out server.csr -key server.key -new

#Sign this certificate with your CA key
$ openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1825

You will now need to keep the files ca.key, server.key and server.csr safe. You will need them every time you want to renew your certificates (in 5 years). The only certificates you need to share with the AWARE client are the server.crt and ca.crt (which are public SSL certificates). You must host them on your server’s publicly accessible URL so AWARE client can download them and use to communicate with your AWARE Dashboard and Mosquitto MQTT server. You do so by copying them both to /var/www/html/public:

$ sudo mkdir /var/www/html/public
$ sudo cp server.crt ca.crt /var/www/html/public

1. Installing AWARE Dashboard on your LAMP server

We encourage you to use Git to checkout the code, since it is easier for you to update your server as we fix any reported bugs and integrate new functionalities.

However, if you downloaded the source as a .zip package, uncompress it to a folder (aware-server) inside your server’s Apache hosting folder (in Ubuntu, it is located in /var/www/html/) and go to step 1.4.

aware-server-github

1.1) Installing Git

$ sudo apt-get install git

1.2) Checking out AWARE Dashboard Git project

$ cd /var/www/html
$ sudo git clone https://github.com/denzilferreira/aware-server.git

This will create a folder called aware-server on the root of your Apache host. We will come back to this folder in the following steps. Go to step 2. Do not open your browser and point to your server URL yet, we still have setup to do.

1.3) Fetching updates to AWARE Dashboard

$ cd /var/www/html/aware-server
$ sudo git pull

This will only update the core dashboard files, and leave your configuration files intact.

1.4) Securing your AWARE Dashboard (old guide)

We will now modify Apache to use HTTPS for the AWARE Dashboard, while still allowing access to the public certificates over HTTP. You need to replace YOUR_DOMAIN with your server’s domain or IP address (without leading http:// or https://). You need to specify where you put the private server.key of your server for HTTPS to work. We are also adding support for downloads of .apk files (Android apps), required to download plugins hosted on your server.

Edit the file /etc/apache2/apache2.conf

$ sudo nano /etc/apache2/apache2.conf

#Append this to the end of the file
AddType application/vnd.android.package-archive .apk
<VirtualHost *:443>
 DocumentRoot /var/www/html/aware-server
 ServerName YOUR_DOMAIN
 SSLEngine on
 SSLProtocol all -SSLv2 -SSLv3
 SSLHonorCipherOrder on
 SSLCipherSuite "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS"
 SSLCertificateFile /var/www/html/server.crt
 SSLCertificateKeyFile /PATH/TO/server.key
</VirtualHost>
<VirtualHost *:80>
 DocumentRoot /var/www/html/public
 ServerPath "/public/"
 ServerName YOUR_DOMAIN
</VirtualHost>

1.4) Securing your AWARE Dashboard with LetsEncrypt

Now that we have LetsEncrypt certificates in our server, and you have used Certbot, you will need to edit the VirtualHost entry in your /etc/apache2/apache2.conf. Make sure your VirtualHost entry is similar to:

$ sudo nano /etc/apache2/apache2.conf

#Append this to the end of the file
AddType application/vnd.android.package-archive .apk
<VirtualHost *:443>
 DocumentRoot /var/www/html/aware-server
 ServerName YOUR_DOMAIN
 <Directory "/var/www/html/aware-server">
   Allow from all
   Options +Indexes
 </Directory>
 SSLEngine on
 SSLProtocol all -SSLv2 -SSLv3
 SSLHonorCipherOrder on
 SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
 SSLCertificateFile /etc/letsencrypt/live/YOUR_DOMAIN/cert.pem
 SSLCertificateChainFile /etc/letsencrypt/live/YOUR_DOMAIN/chain.pem
 SSLCertificateKeyFile /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem
 ErrorLog logs/ssl_error_log
 LogLevel emerg
 TransferLog logs/ssl_access_log
</VirtualHost>
<VirtualHost *:80>
 DocumentRoot /var/www/html/public #this is the Apache public folder to host our ca.crt and server.crt
 ServerPath "/public/"
 ServerName YOUR_DOMAIN
</VirtualHost>

This configures your Apache to use LetsEncrypt certificates, obtaining a grade A in SSL security (evaluated https://www.ssllabs.com/ssltest/analyze.html?d=api.awareframework.com&latest). We also need to export the certificates to a format that CodeIgniter (the PHP framework we used for the dashboard at the time) can understand. To do this, create a public folder that you will later need in Section 5.2, use openssl to extract the certificate and copy the ca.crt and server.crt to this folder (replace CRT_FOLDER with the path for the public folder reacheable in http://YOUR_DOMAIN/public), and lastly making them readable to Apache.

$ mkdir CRT_FOLDER
$ openssl x509 -outform der -in /etc/letsencrypt/live/YOUR_DOMAIN/cert.pem -out CRT_FOLDER/server.crt
$ cp CRT_FOLDER/server.crt CRT_FOLDER/ca.crt
$ chmod -R 777 CRT_FOLDER

1.5) Increasing PHP upload file size limit

By default, PHP limits file uploads to 2MB. This is not enough for nowadays’ Android package sizes. We will increase this size to 200MB, but you can choose any number you wish.

$ sudo nano /etc/php5/apache2/php.ini

#modify this line to
upload_max_filesize = 200M

2. MySQL Configuration

2.0 Copy LetsEncrypt certificates and allow access to them by MySQL

MySQL can be configured to allow SSL-encrypted access to your database. You will need to make a copy of your LetsEncrypt certificates to a folder that MySQL can read, like this:

$ sudo mkdir /etc/mysql
$ sudo cp /etc/letsencrypt/live/YOUR_DOMAIN/*.pem /etc/mysql
$ sudo chown mysql:mysql /etc/mysql/*.pem

Then we need to edit our MySQL server configuration (e.g., /etc/my.cnf) to add the following:

[mysqld]
...
ssl
ssl-ca=/etc/mysql/chain.pem
ssl-cert=/etc/mysql/cert.pem
ssl-key=/etc/mysql/privkey.pem
...

2.1 Create a MySQL database for the AWARE Dashboard

We must create an empty aware_dashboard database. Don’t name it anything else, because the dashboard depends on it to work properly. In the following commands, we use the user root, but you should use your own credentials to your MySQL server that allows you to create databases and add new users.

$ mysql -u root -p
$ (enter the password of the MySQL root user)
mysql> CREATE DATABASE aware_dashboard;

2.2 Create a MySQL user that has administrative rights for AWARE Dashboard

We now create a user (YOUR_DB_USER) for the dashboard with all privileges on this server. For security, this user is only allowed to login from localhost (i.e., your server), so no one else can use/access it remotely. This user manages creating and deleting the databases and user credentials per study.

Don’t forget to change the bolded text with your user and password of choice on the following commands.

mysql> CREATE USER 'YOUR_DB_USER'@'localhost' IDENTIFIED BY 'YOUR_DB_USER_PWD';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'YOUR_DB_USER'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> exit;

2.3 Load AWARE Dashboard core database

We will now add the tables we need to the aware_dashboard database. These tables contain all the studies configurations, user accounts and all the information needed to manage the dashboard.

$ mysql -u YOUR_DB_USER --password=YOUR_DB_USER_PWD aware_dashboard < /var/www/html/aware-server/aware_dashboard.sql

2.4 Set MySQL configuration on your AWARE Dashboard

Edit the database.php file in /var/www/html/aware-server/application/config/database.php

$db['aware_dashboard']['hostname'] = 'localhost';
$db['aware_dashboard']['port'] = '3306';
$db['aware_dashboard']['username'] = 'YOUR_DB_USER';
$db['aware_dashboard']['password'] = 'YOUR_DB_USER_PWD';
$db['aware_dashboard']['database'] = 'aware_dashboard';

3. Mosquitto MQTT Server

We use Mosquitto MQTT Server to interact with study participants. MQTT is a Machine-2-Machine publish/subscribe protocol that is extremely low-bandwidth and super fast. We use it to:

  • Issue ESMs on-the-fly during a study to all or selected participants;
  • Allow changes on the study configuration on all or selected participants;
  • Request participants to sync their data;
  • Reset the study and start over data collection.

3.1 Download and install Mosquitto

$ sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
$ sudo apt-get update; sudo apt-get install mosquitto mosquitto-clients python-mosquitto libmosquitto-dev

# We will stop the service because we have to set it up!
$ sudo service mosquitto stop

3.2 Download source and configure MySQL-Mosquitto adapter

For security, each participant is assigned an MQTT client user and password, and each study has its own MQTT client credentials. This makes sure that only the study client can send messages to the participants of the study. This is automatically handled by the server using this adapter.

When you install mosquitto in 3.1, note the version number. When you download the source code of mosquitto, it needs to match!

$ mkdir mosquitto_driver && cd $_ 
$ git clone https://github.com/jpmens/mosquitto-auth-plug 
$ wget "http://mosquitto.org/files/source/mosquitto-1.4.10.tar.gz" 
$ tar xvzf mosquitto-1.4.10.tar.gz 
$ cd mosquitto-auth-plug 
$ cp config.mk.in config.mk 
$ sudo nano config.mk

Tell the adapter that you will be using MySQL to handle the users’ credentials:

# Select your backends from this list
BACKEND_CDB ?= no
BACKEND_MYSQL ?= yes
...

# Specify the path to the Mosquitto sources
MOSQUITTO_SRC = ../mosquitto-1.4.10

3.3 Compile Mosquitto-MySQL adapter

We will now check if we have all the required libraries we need to compile the Mosquitto-MySQL adapter.

$ sudo apt-get install libssl-dev libmysqlclient-dev libc-ares-dev g++ uuid-dev gcc-multilib lib32z1 lib32stdc++6
$ cd ~/mosquitto_driver/mosquitto-1.4.10
$ nano config.mk

You will need to edit the config.mk in mosquitto-1.4.10 directory and change the following lines to:

WITH_SRV:=no
WITH_WEBSOCKETS:=yes

Save and then compile the source of Mosquitto. We disabled DNS name resolving (not needed) and activated real-time websockets support.

$ sudo make clean; make
... compiling takes place ...

$ sudo make install

We will now compile the adapter for your Mosquitto server:

$ cd ~/mosquitto_driver/mosquitto-auth-plug
$ sudo make clean; make
... compiling takes place ...

At the end of the compiling process, you will have a file called auth-plug.so in the mosquitto-auth-plug folder, which allows Mosquitto and MySQL to talk to each other. We’ll make it readable and we also need the path for this file on the following step.

$ chmod 777 auth-plug.so
$ pwd auth-plug.so
/.../mosquitto_driver/mosquitto-auth-plug

3.4 Configure Mosquitto to use SSL for all communications and authenticate all clients

Allow logging messages from Mosquitto on our server’s log folder:

$ sudo chmod -R 777 /var/log/mosquitto

Copy ca.crt, server.crt and server.key to Mosquitto’s certs folder:

$ sudo cp ca.crt server.crt server.key /etc/mosquitto/certs

Now we need to edit Mosquitto’s configuration to use this adapter and activate user credentials, message delivery persistence, quality of service, and other things. Edit the configuration file for Mosquitto in /etc/mosquitto/mosquitto.conf

$ sudo nano /etc/mosquitto/mosquitto.conf

Copy and append the following configuration details. Do replace the YOUR_DB_USER and YOUR_DB_USER_PWD with the appropriate information in the mosquitto.conf file content to match your MySQL credentials for the aware_dashboard database. Your final configuration file should look like this:

autosave_interval 1800 
persistence true
persistence_file mosquitto.db
persistence_location /var/lib/mosquitto/ 
connection_messages true 
log_timestamp true 
log_dest file /var/log/mosquitto/mosquitto.log

#Used by the dashboard, accessible only on localhost
listener 9001 127.0.0.1
protocol websockets
#Used by our participants, accessible with SSL encryption
listener 8883
protocol mqtt
require_certificate false #clients don't need a copy of the certificate
cafile /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem
certfile /etc/letsencrypt/live/YOUR_DOMAIN/cert.pem
keyfile /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem

allow_anonymous false 
allow_duplicate_messages false 
max_connections -1
max_inflight_messages 1
persistent_client_expiration 7d 
max_queued_messages 999 
upgrade_outgoing_qos true 
retry_interval 30 
queue_qos0_messages true 

#change /.../ to where you have downloaded the mosquitto_driver folder
auth_plugin /.../mosquitto_driver/mosquitto-auth-plug/auth-plug.so
auth_opt_backends mysql 
auth_opt_host localhost 
auth_opt_port 3306 
auth_opt_dbname aware_dashboard 
auth_opt_user YOUR_DB_USER 
auth_opt_pass YOUR_DB_USER_PWD 

auth_opt_userquery SELECT pw FROM mosquitto_users WHERE username = '%s' LIMIT 1 

auth_opt_superquery SELECT IFNULL(COUNT(*), 0) FROM mosquitto_users WHERE username = '%s' AND super = 1 

auth_opt_aclquery SELECT topic FROM mosquitto_permissions WHERE (username = '%s') AND (rw & %d)

Finally, restart Mosquitto to activate our new configuration:

$ sudo service mosquitto restart

3.5 Installing Mosquitto-PHP library

We need a PHP client for Mosquitto, allowing us to send MQTT messages to the participants on a secure SSL connection.

$ sudo apt-get install php-pear php5-dev libcurl3-gnutls
$ sudo pecl install Mosquitto-alpha

# Load Mosquitto client extension for PHP
$ sudo nano /etc/php5/apache2/php.ini
# Append this line to the end of the file
extension=mosquitto.so
# Save the file (Ctrl + X)

# Reload Apache
$ sudo service apache2 restart

4. Install Android SDK

We will need Android SDK command-line tools to parse uploaded plugins’ information automatically.

$ wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
$ tar zxvf android-sdk_r24.4.1-linux.tgz

# Add Android SDK to your user's bash profile
$ sudo nano ~/.bash_profile

# Add this content to .bash_profile
export ANDROID_HOME = ~/android-sdk-linux
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

# Save the file (Ctrl + X). We now install Android SDK.
cd android-sdk-linux/tools
sudo ./android update sdk --no-ui -t platform-tools

# This will take some time, depending on the network connection speed. Accept any licensing agreements and let it download all the SDK levels and build tools.

5. Configuring AWARE Dashboard

To login on AWARE Dashboard, we don’t use usernames and passwords and instead we leverage Google’s OAUTH service. This provides a secure and fast way to identify yourself on your server. This also allows your do invite fellow researchers to use your very own AWARE Dashboard and share their plugins.

The mobile AWARE application fetches our public plugins by default, and also what you have on your own server when you join a study hosted on your server.

5.1 Add your server to Google OAUTH credentials

First go to the Google’s Developer Console, at https://console.developers.google.com. Create a new project and then create a new Google OAUTH credentials client. When you create this account, you need to specify:

  • Authorised JavaScript origins: https://yourdomain
  • Authorized redirect URI: https://yourdomain/index.php/auth/session/google

You will also need the Client ID (e.g., 90853489753.apps.googleusercontent.com) and Client secret (e.g., lkdfjglkjdsflgkj) for the final step.

5.2 Final AWARE Dashboard configuration

We now have all the infrastructure running. We now need to modify AWARE Dashboard config file to know where everything, OAUTH credentials is and your AWARE Dashboard is ready.

$ sudo nano /var/www/html/aware-server/application/config/config.php

#Add a strong random alphanumeric string here
$config['encryption_key'] = 'CHANGE_THIS_KEY';

#Only use cookies securely over HTTPS
$config['cookie_secure'] = TRUE;

#Tell where you have Android SDK folder
$config['android_sdk'] = '/home/your_user/android-sdk-linux/';

#Tell where you have the public SSL keys folder
$config['public_keys'] = 'CRT_FOLDER';
#Set MQTT host
$config['mqtt_hostname'] = 'YOUR_DOMAIN';
$config['mqtt_port'] = 8883;

#Add your Google OAUTH Client ID
$config['oauth_id'] = '90853489753.apps.googleusercontent.com';
$config['oauth_secret'] = 'lkdfjglkjdsflgkj';

#Save file (Ctrl + X)

You can now access your AWARE Dashboard at https://yourdomain. One last thing, you need to enable yourself as a manager of this server. You can do that by setting your user as a manager on the MySQL aware_dashboard database, table user_levels. You will find only one row for now with user_id = 1 (that’s you!). Change the manager value from 0 to 1. When you login now on the AWARE Dashboard, you can now manage other accounts’ access levels and more.

Congratulations! You made it 🙂

Hosting your own AWARE Dashboard