NGINX as a Proxy Server

A proxy server is an intermediary server that processes requests from clients seeking resources from other servers, often providing functions such as security, caching, and content control.

A number of external services rely on CAS REST services, including:

  • lnurl for the Lightning network,

  • Veriff,

  • Onfido,

  • Morphis,

  • Operator Extensions.

CAS exposes a REST API for this functionality, and

  • NGINX functions as a proxy service with a few simple tweeks.

  • Let’s Encrypt offers free certificates/credentials and easy SSL/TLS configuration.

This guide walks you through the NGINX and Let's Encrypt installation & configuration to expose the CAS REST API (when required). It increases your online footprint, so do not perform this unless it is required.

Ubuntu 22.04 LTS was used for this article.


We encourage you to consult with an IT professional to minimize security risks.


Overview

This API implements SSL/TLS using a self-signed certificate. These types of certificates cannot be authenticated by web browsers - and are therefore unverified and thus: unusable. A proxy server (on the same host) can override that “self-signed” limitation and present the REST API to the Internet with a different, valid certificate that can be seamlessly authenticated by any browser.

The REST API is natively exposed by CAS on port 7743. Exposing the REST API to the world (when necessary) in this manner will enable it to be authenticated as a service originating from a genuine, verified site (origin). Port 7743 is a non-standard port. After a successful installation here, NGINX will certify the REST API content using verifiable credentials on the standard port 443. The REST API can then be validated online, and the “self-signed certificate” restrictions will be disregarded. You’ll be “legit”.

When used as illustrated, the NGINX proxy server maps the firewalled, local port 7743 to a specific subdomain on your registered domain.


Expose HTTP and HTTPS in UFW

Both of the following approaches (AUTOMATED or MANUAL) require you to open ports 80 and 443 in UFW for HTTP and HTTPS access. This must be done before proceeding.

This command opens both at the same time:

sudo ufw allow "Nginx Full"

AUTOMATED INSTALLATION

The CAS CLI tool batm-manage includes an automated script to install NGINX and Let’s Encrypt.

To start the installation, use:

sudo /batm/batm-manage install-reverse-proxy
  • This tool will configure your REST API proxy to the standard, well-known port 443.

  • Port 443 is the standard TLS/SSL port exposed used by secure (HTTPS) websites.

Prerequisites before using install-reverse-proxy:

  1. Open port 80 (HTTP) in UFW to enable the Let’s Encrypt certbot domain-control-check.

    1. See:

  2. Open port 443 in UFW to expose/enable HTTPS.

    1. See:

  3. You must own and control a valid DNS domain,

    1. for example, agent86.yourcasdomain.com must resolve (to your CAS public IP).

    2. See below: Create an “A” record

    3. The script will fail if you cannot supply a valid DNS domain. If the script fails for this reason, then:

      1. add the domain (e.g. agent86.yourcasdomain.com) to your DNS records, and

      2. run sudo certbot --nginx to try again.

  4. The /batm/config/hostname file must point to that valid domain to be used.

    1. See:

    2. The script will fail if this file is missing. If the file is missing:

      1. create the file (with the correct contents),

      2. restart CAS, and

      3. run install-reverse-proxy again.

  5. Disable version reporting in NGINX to improve security:

    1. Edit the file: /etc/nginx/nginx.conf

    2. Find the line: # server_tokens off;

    3. Delete the leading hashtag “#" (only the hashtag) to disable version reporting.

    4. Test the configuration and restart NGINX: sudo nginx -t && sudo systemctl reload nginx


Testing

Enter one of the following testing URLs into a browser.

Examples (replace “agent86.yourcasdomain.com" with your actual domain):

  • Veriff example: https://agent86.yourcasdomain.com/server/serverapi/apiv1/identity-check/veriffwh/

  • lnurl example: https://agent86.yourcasdomain.com/server/extensions/lnurl/

When properly configured, either URL should connect to their respective REST API without errors.

Example of testing success in Chrome:

image-20240821-200201.png

These instructions are provided for finer control over your installation, modification of the installation, and troubleshooting. The automated instructions are recommended for most situations.

Install NGINX

Partial source (and more info): https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-as-a-reverse-proxy-on-ubuntu-22-04

1. Install the APT package NGINX:

sudo apt update && sudo apt install nginx

Check your version to ensure that NGINX is installed:

  • Should return something similar to: nginx version: nginx/1.18.0 (Ubuntu)

  • version 1.18.0 is documented in this article (newer versions should work as well, please report any issues found: ).

2. Create an NGINX server block.

Determine the bound loopback network IP for the CAS master service:

  • Note the IP returned by that command; that IP will be used in the server block (in the next step).

Create a new NGINX configuration file, dedicated to the CAS REST API:

Insert the following text:

  • Replace "yourcasdomain.com" with your registered (and active) domain name.

  • The subdomain “agent86” can be replaced with any RFC 952 compliant text.

  • Modify the example master service bound IP “10.3.2.1" as needed.

    • This example presents a typical case and 10.3.2.1 is usually correct.

    • Port 7743 always remains the same.

  • Press CTRL-X to save the file and exit (leave the filename unchanged).

3. Verify the NGINX configuration and test it.

Verify the configuration is valid:

  • If any problems are found, fix them before proceeding.

Restart NGINX:

Enable NGINX to startup at system boot:


Create an “A” record

You'll need a DNS entry pointing to a subdomain on your primary domain.

An "A" record in DNS (Domain Name System) is a type of DNS record that maps a domain name to its corresponding IP address. In this case, we’re creating a subdomain “agent86” for your primary domain “yourcasdomain.com”. The subdomain will point to your CAS server.

This process varies by DNS provider, but this is where the subdomain is assigned a “name”. It has to be registered with your DNS provider to be recognized by the internet.

Example on Cloudflare:

  • Use your actual CAS IP for the IPv4 address (“12.34.56.78” in the graphic), and

  • use an obscure name (e.g. “agent86”). Your customers will see this name, and it should be unique.

  • Disable any proxy for this entry (e.g. on Cloudflare).

  • in this example, the FQDN would be: agent86.yourcasdomain.com


Let’s Encrypt

SSL/TLS is required to proceed. Let’s Encrypt is the easiest (and cheapest) way to put the “S” in “HTTPS”.

For this example we’ll install certbot from Let’s Encrypt to do the work for us.

1. Install the certbot SNAP:

Add the binary to your path:

2. Install SSL/TLS

Get your Certificate and Key from Let’s Encrypt, allowing it to modify your NGINX configuration to adhere to current SSL/TLS advised standards.

a) Execute certbot:

  • Enter your email & agree to the terms (if offered).

  • When NGINX is properly configured, the “agent86” subdomain (in this example) will be automatically suggested (and the proper server block thus modified).

  • If the challenge fails, check your firewall and DNS records.

b) Restart NGINX:

c) Test the automatic renewal:


You're done!

Test your configuration as identified above:

  • All CAS services that rely upon the REST API may use the same sub+domain.


Additional notes:

Certbot Certificate Renewals

Unlike certificates from Certificate Authorities, the Let’s Encrypt certificates are only valid for 90 days. Certbot will attempt to automatically renew your certificates periodically. This renewal will expectedly fail, as a normally hardened CAS server should block port 80 (HTTP).

AUTOMATED CERTBOT RENEWALS ARE DISCOURAGED

Certbot relies upon port 80 (HTTP) being exposed to the world, which exposes your CAS host to risk. Since GB does not advocate risk, we discourage you from using automated certbot renewals.

To expose port 80 (HTTP) to the world via UFW, use: sudo ufw allow 80

  • The NGINX default web page will now be live at your subdomain.

Instead of exposing port 80, automatic certbot renewals, or UFW disruption, consider implementing:

Using a Cloudflare Certificate and Key

Cloudflare offers free site origin certificates when using their DNS services. These certificates are valid for up to 15 years. After following Let’s Encrypt instructions, replace with Cloudflare files to enable “Full (strict) - SSL/TLS” encryption modes with Cloudflare.

First, create the certificate and key(at Cloudflare), then download them to: /etc/ssl/private/

Edit the NGINX server block:

Then add 2 lines to the NGINX server block to point to the 2 files:

Disable the existing “ssl_certificate“ and “ssl_certificate_key“ by placing a hashtag “#” at the beginning of the each line, like this:

  • Save & exit (Ctrl+X, “y”)

After replacing the Let’s Encrypt certificates, certbot can be disabled (or uninstalled).

Uninstall certbot:


CAS Admin

Logging into the CAS Admin server the first time will trigger a series of warnings from your browser. The browser is doing it's job - warning you that the host may not be who you think it is.

Good browser (pat on the head):

The CAS administrative interface IS encrypted point-to-point. It IS secure, but it is possible that a determined and privileged actor may breech your security and gain access to your network, including CAS.

Implementing NGINX on your host may (if properly installed) eliminate one particular false flag - and turn it into a VALID warning. After installing certificates, you'll be able to confidently log in to your CAS host, assured that no Man-in-the-Middle attack is happening. The browser warnings will (normally) stop as NGINX will act as a reverse proxy, using your domain name and a Certificate Authority to verify the connection's integrity.

THIS PROCEDURE DOES NOT INCREASE SECURITY!

It DOES validate the browser warnings when they are received. After you have completed the steps in this article, any warnings you receive from your browser are REAL and should be taken seriously! Some would say this DOES increase security, but this is not a forum for such debates. It is your choice whether to implement NGINX.

This process is insecure and discouraged. Use the Admin VPN instead:

Proxying CAS Admin:

Following the instructions from the REST API, you’ll make a few changes.

  1. Create an A record:

    1. you can’t use BOTH the REST API and CAS ADMIN on the same subdomain, so

    2. use a different subdomain name for CAS ADMIN (e.g. “admin99” instead of “agent86”), and

    3. you may have multiple subdomains without issue.

  2. Change the NGINX server block:

    1. use a differently named configuration file, e.g.

      1. /etc/nginx/conf.d/cas-admin.conf" instead of “/etc/nginx/conf.d/cas-rest-api.conf"

      2. "server_name“ should be adjusted to match the “A record” fully qualified subdomain, and

      3. proxy_pass" needs to point to your admin service IP+ port.

        1. See the result of sudo /batm/batm-manage info to determine your admin IP, and

        2. the default port is “7777”.

  3. Let’s Encrypt should find your admin server block (too), and you should expose a different port if you’re using the REST API as well.

    1. You cannot use the same exposed port for both admin & REST.


Copyright © 2020-2024 General Bytes USA LLC