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:
Update the Ubuntu instance:
sudo apt-get update && sudo apt-get upgrade
Update node:
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Install Node.js and npm sudo apt-get install nodejs npm
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
npm install
setup your cgm-remote-monitor environment as you normally would, for example creating a file my.env :
MONGO_CONNECTION=MONGOCONNECTIONSTRING
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
sudo npm install pm2 -g
Start cgm-remote-monitor with pm2:
env $(cat my.env) PORT=1337 pm2 start lib/server/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"
And then:
pm2 save
Install nginx:
sudo apt-get install nginx
edit this file:
sudo vi /etc/nginx/sites-available/default
Delete 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
Add this to the etc/nginx/sites-enabled/defaults file:
server {
listen 443 ssl;
server_name your_domain_name;
root /usr/share/nginx/html;
ssl_certificate /etc/letsencrypt/live/your_domain_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain_name/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-SHA384:ECDHE-E
CDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECD
HE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA3
84:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-
RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-S
HA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DE
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;
}
location / {
proxy_pass http://localhost:1337/; # Note port number for your cgm-remote-monitor should be changed if it isn't 1337
}
}
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!
Thanks for the great post @johnmales . I also found @lsandini gist most helpful for explaining the mongodB installation. I have everything going well with the exception of my Dexcom bridge. All login attempts fail (although I can successfully login via the web so I know my creds are correct).
my.env
MONGO_CONNECTION=mongodb://localhost/admin MONGO_COLLECTION=entries API_SECRET=secret AUTH_DEFAULT_ROLES=denied BRIDGE_SERVER=EU BRIDGE_USER_NAME=username BRIDGE_PASSWORD=password BG_HIGH=504 BG_TARGET_BOTTOM=90 BG_TARGET_TOP=144 BG_LOW=70.2 DISPLAY_UNITS=mmol ENABLE=careportal%20cors%20basal%20sage%20bridge SHOW_PLUGINS=careportal THEME=colors TIME_FORMAT=24
The error I receive:
Cannot authorize account: null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed', SubCode: '<OnlineException DateThrownLocal="2022-09-09T04:16:54.865" DateThrown="2022-09-09T04:16:54.865Z" ErrorCode="AccountPasswordInvalid" Type="13" Category="4" Severity="1" TypeString="InvalidPassword" CategoryString="Validation" SeverityString="Minor" HostName="" HostIP="" Id="{idgoeshere}" Message="Publisher account password failed" FullText="com.dexcom.udp.common.data.exception.OnlineException: Publisher account password failed" />', TypeName: 'FaultException' } Error refreshing token null 500 { Code: 'AccountPasswordInvalid', Message: 'Publisher account password failed',
It's almost like the server doesn't recognise I'm outside of the US even though the setting for EU is set in my.env
Any thoughts (apologies, don't know how to get line breaks into a code snippet)?