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 CAS services rely on the REST services, including:

  • lnurl for the Lightning network,

  • Veriff,

  • Onfido,

  • Morphis,

  • Operator Extensions.

CAS exposes port 7743 for it’s REST API. This port requires SSL/TLS, but uses a self-signed certificate. These types of certificates cannot be authenticated by web browsers - and are therefore unverified and unusable. A proxy server (on the same host) can ignore that “self-signed” limitation and presents the REST API to the Internet with a different, valid certificate that can be authenticated by any browser.

  • NGINX provides 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.

Ubuntu 22.04 LTS was used for this article.

This process is not a trivial task.

We encourage you to consult with an IT professional.


Port 7743 is exposed to the world (when necessary) to enable the CAS REST API to be authenticated as a service originating from a genuine, verified site (origin). The exposed port (of your choosing) will be validated online, and the “self-signed certificate” restrictions will be disregarded (because your server will be certified using verifiable credentials).

The NGINX proxy server will map local port 7743 to a subdomain on your registered domain.

AUTOMATED INSTRUCTIONS: batm-manage install-reverse-proxy

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

sudo /batm/batm-manage install-reverse-proxy

This tool will only configure your server extensions, and only to well-known port 443.

The script is currently broken (20230901) and an adjustment will need to be made.

Prerequisites before using install-reverse-proxy:

  1. Open port 80 to enable the Let’s Encrypt certbot domain-control-check, and

  2. open port 443 to expose the extensions.

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

    1. for example, 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. 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. The file must contain just a valid domain, e.g.:

    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:

    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

URL path examples (replace “" with your actual domain):

  • Veriff example:

  • lnurl example:

These instructions are provided for finer control over your installation, modification of the installation, and troubleshooting.

Install NGINX

Partial source (and more info):

1. Install the APT package NGINX:

sudo apt update && sudo apt install nginx

Check your version to ensure that NGINX is installed:

nginx -v

2. Create an NGINX server block.

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

  • Note the IP - that will be used in the server block (next).

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

Insert the following text:

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

  • The subdomain “agent86” can be replaced with any text - and will be justified in the next steps.

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

    • Port 7743 remains the same.

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

This server block ADDS another possible port exposure to the world. The default configuration already exposes port 80 (HTTP), and this additional server block adds port 443 (HTTPS) to the list. It isn’t secure yet (that comes next) - when we use Let’s Encrypt to do the heavy lifting.

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 “”. 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 (“” 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:

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) Temporarily disable your firewall:

Expose port 80 (HTTP) to the world while running certbot. The simplest way to do this:

b) 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.

c) Restart NGINX:

d) Test the automatic renewal:

e) Re-enable UFW to secure your server.

3. Change the exposed port.

The certbot routine will automatically set your exposed port to 443. That’s a normal HTTPS port - but it’s predictable. Change the port to a random number between 1024 - 49151 to make your server more difficult to recognize & attack. We’ll use 7443 in this example.

Modify the port number in the NGINX server block:

  • Change port “443” to port “7443” (or whatever number you prefer):

  • Press Ctrl+X, then “Y” to exit. Dd not change the filename.

  • Remember the port - it’s imPORTant. You’ll use this elsewhere in CAS configuration.

4. Expose the chosen port in UFW.

  • Replace “7443” with whatever port you’ve chosen.

You're done!

Test your domain by navigating with your browser to:

  • Replace “” with your actual domain, and

  • replace “7443” with your chosen port.


Save and remember the URL for use in configuring CAS services that rely upon the REST API.

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).


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.


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 less secure than implementing the Admin VPN:

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