This document describes making a self hosted nightscout instance, with SSL encryption and certificate with Let's Encrypt.
Make a fresh instance of Ubuntu 16.04.1 LTS as a VM or on a physical machine Download from http://www.ubuntu.com/download/server/thank-you?version=16.04.1&architecture=amd64
VIrtual machine host options :
- Virtualbox - https://www.virtualbox.org/
- Parallels - https://www.parallels.com/
- Vmware - https://www.vmware.com/ - various options including vmware workstation, vmware player, ESXi
Alternatively, consider hosting your Ubuntu instance elsewhere, for example:
-
https://www.digitalocean.com/ (create a new "one-click app" droplet, select (Mongo 3.4 on 16.04)
I recommend creating a non-root user with root privileges, at least that is what I did on my DigitalOcean droplet. Please read how to do it here: Initial Server Setup with Ubuntu 16.04
Update the Ubuntu instance:
sudo apt-get update && sudo apt-get upgrade
Install Node.js and npm sudo apt-get install nodejs npm
On DigitalOcean, I prefer to install nvm, and from there select the node.js version to install. Please take a look at this tutorial.
sudo apt-get update
sudo apt-get install build-essential libssl-dev
curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh -o install_nvm.sh
bash install_nvm.sh
source ~/.profile
nvm install 8.11.3
... or any other version that fits your needs, but at least for the dev branch of Nightscout, you need a newer version of node.js than the one included in Ubuntu 16.04 Server LTS.
Download cgm-remote-monitor (nightscout) from github:
git clone https://github.com/nightscout/cgm-remote-monitor.git
Alternatively fork a copy of cgm-remote-monitor and clone your own copy.
cd cgm-remote-monitor
Install cgm-remote-monitor:
git checkout dev
or git checkout master
(probably not necessary) and
npm install
setup your cgm-remote-monitor environment as you normally would, for example creating a file my.env :
MONGO_CONNECTION=mongodb://localhost/admin (if mongodb is hosted on the same machine as NS, as in this case)
MONGO_CONNECTION=mongodb://user:[email protected]:xxyyy/dbname (if using mlab)
DISPLAY_UNITS=mmol
BASE_URL=NIGHTSCOUT_SITE_URL
DEVICESTATUS_ADVANCED="true"
mongo_collection="mogocollection_name"
API_SECRET=AVeryLongString
ENABLE=careportal%20openaps%20iob%20bwp%20cage%20basal%20pump%20bridge
BRIDGE_SERVER=EU
BRIDGE_USER_NAME=USERNAME
BRIDGE_PASSWORD=PASSWORD
AUTH_DEFAULT_ROLES=readable%20devicestatus-upload
BG_HIGH=260
BG_TARGET_TOP=180
BG_TARGET_BOTTOM=80
BG_LOW=55
CUSTOM_TITLE=WHATEVER
In case you are not using a DigitalOcean droplet with pre-installed mongodb, you will have to install mongodb manually. How to Install MongoDB on Ubuntu 16.04.
More details are available here: Install MongoDB Community Edition on Ubuntu. Once installed and started, the mongodb server is accessible on the host machine on port 27017. That's why when mongodb and Nightscout are hosted on the same computer (physical or virtual), the mongo connection string in Nightscout's preferences is MONGO_CONNECTION=mongodb://localhost/admin.
Two databases are active, "admin" and "local", none of which have any content yet. You can access the mongo shell by typing mongo
, and after that issue commands like show dbs
, show collections
, show users
, as in the mongo Shell Quick Reference.
If you prefer not to run your own mongodb server, then your mongo string will be in the form MONGO_CONNECTION=mongodb://user:[email protected]:xxyyy/dbname, like in Azure or Heroku.
If you would like to also access your mongo database from the internet (for backup or analyzing them), you need to protect your database with a username and password, before making it available to the outside world.
Login to your host as root this time, or take on root priviliges with sudo -i
. Then access the mono shell with the comman mongo
and select the database you want to use, for example admin use admin
. Then create a user :
use admin
db.createUser({
user: 'your_username',
pwd: 'your_passwourd',
roles: [{ role: 'readWrite', db:'admin'}]
})
... and exit the mongo shell exit
.
Edit the mongod.conf file nano /etc/mongod.conf
, scroll down and uncomment the "security" line by removing the #, and add a line under it like this, then save and exit.
security:
authorization: 'enabled'
You will have to modify your MONGO_CONNECTION string in my.env like this:
MONGO_CONNECTION=mongodb://your_username:your_password@localhost/admin
Making your database accessible from the internet is useful only for pulling data into other applications (like Studio 3T or Robo 3T), or if you want to use this personally hosted mongodb instead of the Mlab. You will have to open specifiy in the mongod.conf file, which IPs is the database:
bindIp: 127.0.0.1,206.189.xxx.xxx
(or whatever your droplet's IP is).
Restart your mongodb server to make the changes active.
Opening a port on the firewall is not done using SSH, but in DigitalOcean's website where you need to link the firewall to your droplet and open the port mongodb is running on, to incoming TCP traffic (by default port 27017).
Your connection string will be: mongodb://your_username:[email protected]:2017/yourdatabase
sudo npm install pm2 -g
Start cgm-remote-monitor with pm2:
env $(cat my.env) PORT=1337 pm2 start server.js
Make pm2 start cgm-remote-monitor on startup
pm2 startup ubuntu
- this will give you a command you need to run as superuser to allow pm2 to start the app on reboot.
The command will be something like:
sudo su -c "env PATH=$PATH:/usr/bin pm2 startup ubuntu -u username --hp /home/username"
Finally in order to make pm2 remember what apps to start on next reboot:
pm2 save
Please note that every time you make modifications to your my.env file (your Nightscout environment variables), you will have to stop, delete and restart the server.js instance. Go to your /cgm-remote-monitor folder and :
pm2 list
will show your current processes, and their id number.
pm2 stop 0
will stop the current server process with id "0".
pm2 delete 0
will delete the server process with id "0".
Then start cgm-remote-monitor with pm2 again:
env $(cat my.env) PORT=1337 pm2 start server.js
Nginx is a server application. It will accept requests from clients, and when configured as a reverse proxy, it will forward these requests to another server. In our case, our Nightscout instance is available locally on the server at http://localhost:1337. Read more about Nginx for DigitalOcean here : Nginx Essentials: Installation and Configuration Troubleshooting
To make the connection more secure, we will protect it with SSL encryption using letsencrypt.
Install nginx:
sudo apt-get install nginx
edit this file:
sudo nano /etc/nginx/sites-available/default
Delete all the existing contents and replace with this:
I'm assuming the proxy is on the same host as nightscout and the proxy_pass http://127.0.0.1:1337
line - 1337
is replaced with the port that nightscout is using
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Then restart the nginx service
sudo service nginx restart
install Let's Encrypt
sudo apt-get install letsencrypt python-certbot-nginx
Obtain SSL certificate using webroot plugin
Allow access to /.well-known directory for Lets Encrypt
sudo nano /etc/nginx/sites-available/default
Stop ngnix service
sudo service nginx stop
Obtain letsencrypt certificate -
sudo letsencrypt certonly
enter your domain name when prompted. This will create the certificates for your domain name. The certificates should now be available at /etc/letsencrypt/live/your_domain_name
improve SSL security by generating a strong Diffie-Hellman group
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Modify the etc/nginx/sites-enabled/defaults file, filling in your domain name as in the example below:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen 443 ssl;
server_name yourdomain.com;
root /usr/share/nginx/html;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM$
CDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AE$
HE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-EC$
84:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES$
RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-$
HA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aE$
S-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location ~ /.well-known {
allow all;
}
}
Close the editor and check that your nginx configuration file is valid
sudo nginx -t
If there are errors in your configuration file, the command's output will tell you exactly where in the file the error was found.
restart nginx
sudo service nginx restart
You can test the quality of the SSL connection using: https://www.ssllabs.com/ssltest/analyze.html?d=your_domain_name Unfortunately only works with port 443
Arrange auto renewal of certificates. Add this line to the su crontab sudo crontab -e
30 2 * * 1 certbot renew >> /var/log/le-renew.log
Hopefully that is now done!