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.
CAS REST API
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.
example of a subdomain: agent86.yourcasdomain.com
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.
After usage, see: https://generalbytes.atlassian.net/wiki/spaces/ESD/pages/2942631937/NGINX+as+a+Proxy+Server#2.-Create-an-NGINX-server-block.
Change
localhost
to the bound network IP for the master service.
Prerequisites before using install-reverse-proxy:
Open port 80 to enable the Let’s Encrypt certbot domain-control-check, and
open port 443 to expose the extensions.
You must own and control a valid DNS domain,
for example,
agent86.yourcasdomain.com
must resolve (to your CAS public IP).See below: Create an “A” record
The script will fail if you cannot supply a valid DNS domain. If the script fails for this reason, then:
add the domain (e.g.
agent86.yourcasdomain.com
) to your DNS records, andrun
sudo certbot --nginx
to try again.
The
/batm/config/hostname
file must point to that valid domain to be used.The file must contain just a valid domain, e.g.:
agent86.yourcasdomain.com
The script will fail if this file is missing. If the file is missing:
create the file (with the correct contents),
restart CAS, and
run
install-reverse-proxy
again.
Disable version reporting in NGINX:
Edit the file:
/etc/nginx/nginx.conf
Find the line:
# server_tokens off;
Delete the leading hashtag “
#
" (only the hashtag) to disable version reporting.Test the configuration and restart NGINX:
sudo nginx -t && sudo systemctl reload nginx
URL path 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/
These instructions are provided for finer control over your installation, modification of the installation, and troubleshooting.
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:
nginx -v
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: https://generalbytes.atlassian.net/l/cp/PLXJxmC1 ).
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 "yourcasdomain.com" 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 “
10.3.2.1
" 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 “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.
the same domain name (e.g agent86.yourcasdomain.com) is used (from above).
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:
to permanently enable automatic certbot renewals, read below: Certbot Certificate Renewals
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: https://agent86.yourcasdomain.com:7443/extensions/lnurl/
Replace “agent86.yourcasdomain.com” with your actual domain, and
replace “7443” with your chosen port.
Perfect:
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).
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:
DNS authentication: https://letsencrypt.org/docs/challenge-types/#dns-01-challenge
which uses scripting to interact with your DNS server (without open ports), or
a Cloudflare tunnel, see: https://generalbytes.atlassian.net/l/cp/PDLuKPoB, or
an ngrok Secure Tunnel: https://ngrok.com/product/secure-tunnels
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 less secure than implementing the Admin VPN:
Proxying CAS Admin:
Following the instructions from the REST API, you’ll make a few changes.
Create an A record:
you can’t use BOTH the REST API and CAS ADMIN on the same subdomain, so
use a different subdomain name for CAS ADMIN (e.g. “admin99” instead of “agent86”), and
you may have multiple subdomains without issue.
Change the NGINX server block:
use a differently named configuration file, e.g.
“
/etc/nginx/conf.d/cas-admin.conf
" instead of “/etc/nginx/conf.d/cas-rest-api.conf
""
server_name
“ should be adjusted to match the “A record” fully qualified subdomain, and“
proxy_pass
" needs to point to your admin service IP+ port.See the result of
sudo /batm/batm-manage info
to determine your admin IP, andthe default port is “7777”.
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.
You cannot use the same exposed port for both admin & REST.
Copyright © 2020-2024 General Bytes USA LLC