Configuring HTTPs on a standalone Ardor installation

From ArdorDocs
Jump to: navigation, search
This page contains changes which are not marked for translation.

Introduction

This tutorial explains how to configure HTTPS on a standalone Ardor installation running on a Linux or macOS system.

It is provided an easy mechanism to configure HTTPS without using a reverse proxy and automation certificates renewal without having to restart the full node.

The steps below have been tested on macOS 10.14.6 and Linux system, Debian derivative like Ubuntu.


The challenges

If you want to configure HTTPS for you node's API and Wallet port you face two challenges:

  1. The certificate
  2. The listening port

The certificate proves that you are the domain that you claim to be and allows the browser and server to establish a secure channel for communications.

You probably want a certificate signed by a public CA (Certificate Authority) to avoid nasty security messages from browsers. In the past that would mean buying one from a well known company and following some technical steps. Fortunately we currently have Let's Encrypt, a free, open and automated certificate authority.

The listening port is where you point your browser to open the wallet, the 27876 in the usual http://localhost:27876. The challenge comes when you want to use the standard HTTPS port (443) so you can have some nice URI like https://ardor.myserver.com without a :port modifier. In order to use a port under 1024 you need to have special privileges. In the MacOS and Linux world that means being root or using the authbind utility.


Using a Let's Encrypt cerficate with Ardor

Let's assume that you don't have a web server or any other service listening on port 80 (HTTP). The Let's Encrypt service uses that port to perform a challenge resolution in order to prove that you own a certain domain.

Actually the port 80 is only needed during the issue and renewal of certificates so if you have any other service you could, for example, just shut it down for a few seconds while you perform the operation.

Please follow the official documentation (https://certbot.eff.org) in order to install Certbot. In macOS it will be needed some other packages such as homebrew (https://brew.sh), Ruby and cURL.

Node configuration

You need to add a few properties to the nxt.properties file. At least these ones:

nxt.apiSSL=true
nxt.keyStorePath=keystore
nxt.keyStorePassword=PutHereLongPassword
nxt.keyStoreType=PKCS12

Take a look also at these properties: nxt.allowedBotHosts, nxt.apiServerHost, nxt.adminPassword

Certificate's first issuance

For the first generation of the certificate you can use a command like this:

certbot certonly -d DOMAIN --standalone

Where DOMAIN is your domain name. If everything is correct you should have your certificate and private key under /etc/letsencrypt/live/DOMAIN.

Afterwards you need to export the certificate to a java keystore. In order to do this operation you can use a command like this:

sudo openssl pkcs12 -export -in /etc/letsencrypt/live/DOMAIN/fullchain.pem -inkey /etc/letsencrypt/live/DOMAIN/privkey.pem -out KEYSTORE -name nrs -passout pass:KEYSTORE_PASS

Copy the java keystore to a folder with permissions from the Ardor user and finally configure the nxt.keyStorePath, nxt.keyStorePassword and nxt.keyStoreType=PKCS12 in the nxt.properties file.

Automatic renewal and the Ardor keystore

The Certbot software automatically takes care of renewals but we need to configure it to also deploy the new certificates to the running NRS node.

sudo certbot certonly -d DOMAIN -n --standalone --deploy-hook "/PATH/TO/NRS_INSTALLATION/pem.to.pkcs12.keystore.certbot.hook.sh" --force-renewal

Replace DOMAIN with the domain name. That will force the renewal, execute the script and also update the certbot configuration to use the script with every certificate renewal for that domain.

NOTE: The script pem.to.pkcs12.keystore.certbot.hook.sh is included with version 2.2.6 or later but you can check it in the following box:

#!/bin/sh

#######################################################################
## This script takes the pem files from a Let's Encrypt / Certbot
## directory and bundles them together for use by the current NRS
## installation, reading the corresponding properties from the
## nxt.properties file.
##
## It is designed to be run from the --deploy-hook Certbot option,
## meaning that it expects the RENEWED_LINEAGE environment variable
## to point to a directory with the PEM encoded files.
#######################################################################

PROPERTIES_PATH="conf/nxt.properties"

if [ -z $RENEWED_LINEAGE ]; then
	echo "RENEWED_LINEAGE environtment variable not found, running from certbot --deploy-hook ?"
	exit
fi

OLD_DIR="$(pwd)"
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
cd $SCRIPTPATH

if [ ! -r $PROPERTIES_PATH ]; then
	echo "nxt.properties file not found"
	exit
fi

KEYSTORE=$(grep "^nxt.keyStorePath=" $PROPERTIES_PATH | cut -d'=' -f2)

if [ -z $KEYSTORE ]; then
	echo "You need to define nxt.keyStorePath on nxt.properties"
	exit
fi

KEYSTORE_PASS=$(grep "^nxt.keyStorePassword=" $PROPERTIES_PATH | cut -d'=' -f2)

if [ -z $KEYSTORE_PASS ]; then
	echo "You need to define nxt.keyStorePassword on nxt.properties"
	exit
fi

KEYSTORE_TYPE=$(grep "^nxt.keyStoreType=" $PROPERTIES_PATH | cut -d'=' -f2)

if [ -z $KEYSTORE_TYPE ] || [ $KEYSTORE_TYPE != "PKCS12" ]; then
	echo "You need to define the keystore type as PKCS12. Add \"nxt.keyStoreType=PKCS12\" to your nxt.properties file "
	exit
fi

openssl pkcs12 -export -in $RENEWED_LINEAGE/fullchain.pem -inkey $RENEWED_LINEAGE/privkey.pem -out $KEYSTORE -name nrs -passout pass:$KEYSTORE_PASS
chmod a+r $KEYSTORE

cd $OLD_DIR

If you had the node running while performing these operations you need to restart it in order to pick up the new certificates. The next renewals will be picked up automatically if you are using Ardor version 2.2.6 or newer.


Setting up Ardor to listen to a privileged port

If you want your node to listen on a privileged port, like the standard HTTPS port 443, you need root privileges or an alternative mechanism.

We do not recommend running your node, or any non system software, as root.

Linux system

Here we will describe how to use authbind, a tool available in Ubuntu and other Debian derivates, to allow the Ardor software to listen to port 443 without running it as root.

First, make sure you have authbind installed:

sudo apt install authbind Then, also as root, you need to create a file to tell authbind that binding to port 443 is allowed.

sudo touch /etc/authbind/byport/443

Authbind determines that a process can bind to that port if it has execute permissions to that file. Let's suppose you are running your node as the local user ardor. You need to execute these commands:

sudo chgrp ardor /etc/authbind/byport/443
sudo chmod g+x /etc/authbind/byport/443

Now authbind will provide a mechanism for any process run by that user to just bind to port 443. In order to use that mecanism you need to run your command inside a authbind execution. You can use the --authbind modifier of run.sh for that purpose.

You specify the HTTPS port in the nxt.properties file:

nxt.apiServerSSLPort=443

MacOS

Here we will describe how to use MacOSX-authbind. It is a tool available in https://github.com/Castaglia/MacOSX-authbind for Mac OSC 10.7 Lion and later versions, to allow the Ardor software to listen to port 443 without running it as root.

First download the software. Then simply do:

$ cd MacOSX-authbind
$ make`
$ sudo make install

Then, also as root, you need to create a file to tell authbind that binding to port 443 is allowed.

sudo touch /etc/authbind/byport/443

Authbind determines that a process can bind to that port if it has execute permissions to that file. Let's suppose you are running your node as the local user ardor. You need to execute these commands:

sudo touch /etc/authbind/byport/443
sudo chown ardor /etc/authbind/byport/443
sudo chmod 755 /etc/authbind/byport/443

You can test the correct installation and configuration of authbind using the following command:

authbind nc -l localhost 443

If it fails, please check the correct installation and configuration of authbind.

Now authbind will provide a mechanism for any process run by that user to just bind to port 443. In order to use that mecanism you need to run your command inside a authbind execution tou can use the --authbind modifier of run.sh for that purpose.

Conclusion

We've seen how to, easily, overcome the two main challenges when setting up HTTPS support on a node. Of course there are alternative methods like using a standard certificate issued by a CA which use to have longer valid periods or using the firewall / NAT subsystem to solve the port problem. These instructions try to cover one of the most usual setup.

Internals about certbot and the certificates

This section dives into a bit more of detail about how the certificate management works between certbot and the NRS. You don't need to read it unless you want to understand more details or are trying to troubleshoot problems with the process.

If you have any problem about the certicates you should check the certbot support site (https://certbot.eff.org/help/) and also the community forum (https://community.letsencrypt.org/).

When generating the certificates for your domain (let's call it DOMAIN) correctly you should have your certificate and private key in plain text (PEM) format under /etc/letsencrypt/live/DOMAIN.

If at any moment you need to troubleshoot the certbot execution it usually creates a log file on /var/log/letsencrypt/letsencrypt.log You can track the invocation of pem.to.pkcs12.keystore.certbot.hook.sh by looking for "Running deploy-hook command:" in this file. Check the Certbot documentation for your platform for more details.

The NRS software uses Jetty internally as the web server. Unfortunately Jetty cannot directly use those files so we need to convert and pack them into a single "keystore" file. That's not hard, you can do that with a single OpenSSL command. The problem is that Let's Encrypt certificates expire in 90 days so you need some way to automate the renewal and "repacking" of your new keys.

The Certbot software automatically takes care of renewals and we can even instruct it to call a script every time a certificate gets renewed. So we are going to use a custom script that will convert the new certificates and keys to the proper format and location for the Ardor software to use.

That's the purpose of the pem.to.pkcs12.keystore.certbot.hook.sh script from the root of the installation directory. And execute it every time the certificate is renewed. In order to instruct certbot to use it with every deployment we need to do a manual renew with the configured hook.

Once the new keystore is in place the node needs to reload them. Since Ardor version 2.2.6 or newer the software will check for changes on the keystore every day. So that will be enough as certificates are renewed several days in advance. You can force it with a node restart.