Home

Installation On DigitalOcean Ubuntu 14.04 Droplet

DigitalOcean is a provider of VPS services. For small applications the server can run on a single Droplet. The references at the end provide some pointers for setting up production installations.

Since the website will be public it will use a free Lets Encrypt certificate to secure the traffic. DigitalOcean does not provide public domain names for Droplets so you will need to own or register a domain for the certificate.

  1. Create a DigitalOcean account if you do not already have one.

  2. Create a MEAN droplet as described in:

    How To Use the MEAN One-Click Install Image

    NOTE: To avoid install problems it's best to choose a 1GB or larger droplet.

    Try the sample application if desired but skim over the later sections on developing and deploying your own application.


  3. Do recommended server setup as described in:

    a) Initial Server Setup with Ubuntu 14.04

    b) Additional Recommended Steps for New Ubuntu 14.04 Servers

    When setting up a firewall as described in b), be sure to allow access on ports 80, 443, and 25.


  4. Install ScriptRemote

    Connect to the droplet as the non-root user created in step 3, then:

    >$ cd ~ (or your preferred install location)
    >$ npm install scriptremote --production
    >$ mv node_modules/scriptremote .
    

  5. Set up credentials/secrets

    First set up an email forwarding account. This will be used to send security-related messages and user notifications. Rather than using an existing account, you may want to create one just for this purpose. Then copy the sample credentials file and substitue your values for the MAILER dummy values:

    >$ cd ~/scriptremote
    >$ cp credentials.env .env
    >$ chmod 600 .env
    >$ vim .env
    

    Some services are stricter than others about relaying mail. To help ensure that mail can be sent choose the same provider as expected for registered user emails, and set MAILER_FROM to the same address as MAILER_EMAIL_ID. If users will have a variety of email providers then consider using a service like mailgun. Any mailing errors will be logged to the console. If there is a problem it will probably first show up when registering the admin user below.

    Secondly, generate a random string for the session middleware. For example:

    >$ openssl rand -base64 32
    
    Substitute the result for the SESSION_SECRET value in .env

  6. Make it possible to run node as non-root
    sudo setcap 'cap_net_bind_service=+ep' /usr/bin/nodejs
    

  7. Test the server
    >$ cd ~/scriptremote
    >$ npm run production
    
    This should start the server listening on port 80. Check that you can access the site with a browser by entering http://<droplet-ip&gt;

    Use ctrl-c to terminate the server when done.


  8. Set up domain DNS records

    Use the controls panels at your domain registrar and at Digital Ocean to set up DNS records for your domain, as described in:

    How To Set Up a Hostname with Digital Ocean

    Allow time for the changes to propagate. The ping and dig commands can be used to check DNS and reverse DNS lookup are working.


  9. Test the domain

    Start the server and check that you can access the site by entering http://<your-domain&gt;

    Use ctrl-c to terminate the server when done.


  10. Create a certificate

    First install the letsencrypt client:

    >$ cd ~
    >$ git clone https://github.com/letsencrypt/letsencrypt
    >$ cd letsencrypt
    >$ ./letsencrypt-auto --help
    
    Create the certificate and copy the key files to server directory:
    >$ mkdir ~/scriptremote/config/sslcerts
    >$ sudo -s
    >$ ./letsencrypt-auto certonly --standalone -d <your-domain> -d 
    >$ cp /etc/letsencrypt/live/<your-domain>/fullchain.pem ~/scriptremote/config/sslcerts
    >$ cp /etc/letsencrypt/live/<your-domain>/privkey.pem ~/scriptremote/config/sslcerts
    >$ chown <your-user:your-user> ~/scriptremote/config/sslcerts/
    >$ ctrl-d
    >$ chmod 600 ~/scriptremote/config/sslcerts/
    
    The certificate will be valid for 90 days. It can be renewed within 30 days of expiration by using the renew subcommand of letsencrypt-auto

  11. Test the certificate
    >$ cd ~/scriptremote
    >$ npm run secure
    
    This should start the server listening on port 443. Check that you can access the site with a browser by entering https://<your-domain&gt; The 'https' in the url is required the first time a browser loads the site since there is no listener on http port 80. (Older browsers that do not support strict transport security will require the protocol to be specified every time.)

    Use ctrl-c to terminate the server when done.


  12. Make it possible to disconnect from the droplet without terminating the server

    There are various ways to do this. Here we use the 'screen' terminal multiplexor, which is already installed in the droplet.

    >$ screen
    
    This will start a new terminal window to use for the following steps.

  13. Start the server
    >$ cd ~/scriptremote
    >$ npm run secure
    

  14. Check that the mongo database is still clean
    >$ mongo scriptremote
    >$ show collections
    
    If there are collections listed other than system.indexes, sessions, or startup_log then remove them and also sessions, using:
    >$ db.<collection>.drop()
    

  15. Register the admin user

    In the browser select Login/Register on the home screen and then Register Here on the login screen. The registration screen should display a message that the admin account is being registered.

    Continue the registration by entering at least an email and password, and by selecting one of the options for registration of other users. The default is to allow other users to register themselves. You can also select a timeout for idle sessions.

    A confirmation email should be sent to the registered address. Complete the registration by clicking the link in the email or by submitting the token value from the email into the form displayed when attempting to login.

    Return to the home page and login using the admin account.

    Get script credentials by selecting Settings in menu bar and then selecting Generate in the API Credentials section. The User Id and Token values will be needed to authenticate messages to the server from scripts running in the private network.


  16. Check that the server can be reached from the private network

    Copy the API credentials obtained above to a machine in the private network. Get the bash utility script scriptremote/public/dist/srio.sh. You can copy it from the server installation or it may be easier to download it from github using a browser.

    Set SRSERVER to the url of your server, by editing the script or as an environment variable. If the script will run behind a web proxy it may also be necessary to set the HTTPS_PROXY environment variable.

    >$ export SRSERVER=https://<your-domain&gt;
    
    Create a simple test:
    >$ cat > test.sh
    #!/bin/bash
    . ./srio.sh
    SR_start ${SRUSER} ${SRTOKEN} 'myproject' 'myjob'
    SR_set 'msg1' 'Hello World' 'false'
    SR_send 'mylocation'
    SR_end
    
    Export the API credentials and run the test:
    >$ export SRUSER=<your-userid>
    >$ export SRTOKEN=<your-token>
    >$ bash test.sh
    
    Check that the test message can be viewed in the browser by selecting Projects in the menu bar.

    If the script fails with a certificate verification error it may mean that there is no CA cert store available in the test machine OS. In that case you would need to install a root certificate.


  17. Detach the screen window and logout from server

    >$ ctrl-a d
    >$ exit
    

  18. To return to the screen window later

    Connect to the droplet as the non-root user and use the screen command:

    >$ screen -ls
    >$ screen -r <screen-id>
    
    If you need to scroll up in the window, the command to view the window's history buffer is:
    >$ crtl-a esc
    
    To exit the buffer type 'return' twice

  19. Optional: Create non-admin user

    Since the admin has elevated priviledges to do things like viewing user details and registering new users, it is best for security purposes to minimize use of that account. Instead register as a normal user for actual projects. This will require a different email address from the one used to for the admin account.


  20. Server logging

    Logging of server responses is enabled by default. The log directory is ~/scriptremote/log. The log file format is 'Apache common'. It is recommended to monitor the logs for signs of instrusion, such as an unknown source ip successfully accessing an endpoint other than the root or documentation.


  21. Optional: Enable MongoDB authentication

    For additional security you may want to enable authentication for MongoDB. Without authentication anyone who manages to obtain user access to the system can also access the database. MongoDB supports elaborate authentication/authorization schemes but for simplicity the following just sets up a "root" user with all access.

    Create the user in the mongo shell:

    >$mongo
    > use admin
    > db.createUser(
    >    {
    >      user: "<mongo-user>",
    >      pwd: "<mongo-password>",
    >      roles: [ "root" ]
    >    }
    >)
    >exit
    
    Then enable authentication in the mongo config file, which is often located at /etc/mongod.conf. Depending on the file format add either:
    security:
      authorization: enabled
    
    or
    auth = true
    
    Then restart mongod:
    >$ sudo restart mongod
    
    Check that the credentials work in the mongo shell:
    >$ mongo -u "mongo-user" -p "mongo-password" --authenticationDatabase "admin"
    
    Edit the ~/scriptremote/.env file to uncomment the mongo credentials and substitute your values, then restart the ScriptRemote server.

  22. Optional: Enable project data limits

    You may want to enable limits on the amount of message data that can be sent to the server, for example to help protect against scripting errors that could produce very large or very many messages. The available limits are defined in scriptremote/config/env/all.js. Any of them may be set as environment variables or added to the .env file prior to starting the server.


References:

How To Set Up a Node.js Application for Production on Ubuntu 14.04
Building for Production: Web Applications
How To Set Up a Firewall Using Iptables on Ubuntu 14.04