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.
example of a registered domain: yourcasdomain.com
example of a subdomain: agent86.yourcasdomain.com
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:
Open port 80 (HTTP) in UFW to enable the Let’s Encrypt certbot domain-control-check.
Open port 443 in UFW to expose/enable HTTPS.
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 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 to improve security:
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
Testing
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/
When properly configured, either URL should connect to their respective REST API and display success.
MANUAL INSTALLATION:
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
DO NOT use your CAS host as a web server. Although NGINX is a web server, it’s used (in this context) as a proxy server only. Web services are notorious for being hackable (and hacked) - and knowingly exposing your CAS server to attack is irresponsible. Keep web content off your CAS host.
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:
sudo grep -m 1 "master_bind_ip=" /batm/config/network
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:
sudo nano /etc/nginx/conf.d/cas-rest-api.conf
Insert the following text:
server { listen 443; server_name agent86.yourcasdomain.com; location / { proxy_pass https://10.3.2.1:7743; } }
Replace "yourcasdomain.com" with your registered (and active) domain name.
The subdomain “agent86” can be replaced with any RFC 952 compliant text.
The subdomain is published (goes “live”) later: Create an "A" record
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:
sudo nginx -t
If any problems are found, fix them before proceeding.
Restart NGINX:
sudo systemctl restart nginx
Enable NGINX to startup at system boot:
sudo systemctl enable nginx
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
If you use a Cloudflare tunnel, do not conflict this DNS entry with the tunnel name. You do not need to use both NGINX and the cloudflared tunnel (they serve the same purpose) anyway.
If you must use both services, simply choose a different subdomain than the one used by the Cloudflare tunnel.
Let’s Encrypt
SSL/TLS is required to proceed. Let’s Encrypt is the easiest (and cheapest) way to put the “S” in “HTTPS”.
If you already have certificates from a CA, then you should install those certificates as instructed by the provider. This article does not address that topic.
Example Certificate Authority: https://www.digicert.com/tls-ssl/compare-certificates
The certificates must be installed before moving forward, and
follow any NGINX configuration provided by the CA.
Cloudflare offers free certificates if you use their DNS services.
https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/
See below (bottom of this article) for further assistance in this context.
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:
sudo snap install --classic certbot
Add the binary to your path:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
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.
To permanently enable automatic certbot renewals, read below: Certbot Certificate Renewals
a) Execute certbot:
sudo certbot --nginx
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:
sudo nginx -t && sudo systemctl restart nginx
c) Test the automatic renewal:
sudo certbot renew --dry-run
You're done!
Test your configuration as identified above: https://generalbytes.atlassian.net/wiki/spaces/ESD/pages/2942631937/NGINX+as+a+Proxy+Server#Testing
All CAS services that rely upon the REST API may use the same sub+domain.
Additional notes:
Make sure Apache isn't running (it will conflict with the install).
Do not assume an obfuscated subdomain is invisible. Your subdomains may be visible online! The key concept of obfuscation is to increase the hack difficulty and reduce predictability. If you want certainties - you’re out of luck in this business.
Check your DNS visibility using these tools:
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:
sudo nano /etc/nginx/conf.d/cas-rest-api.conf
Then add 2 lines to the NGINX server block to point to the 2 files:
ssl_certificate /etc/ssl/private/whatever.cloudflare.pem; ssl_certificate_key /etc/ssl/private/whatever.cloudflare.key;
Disable the existing “ssl_certificate
“ and “ssl_certificate_key
“ by placing a hashtag “#” at the beginning of the each line, like this:
ssl_certificate /etc/ssl/private/whatever.cloudflare.pem; ssl_certificate_key /etc/ssl/private/whatever.cloudflare.key; # ssl_certificate /etc/letsencrypt/live/agent86.yourcasdomain.com/fullchain.pem; # managed by Certbot # ssl_certificate_key /etc/letsencrypt/live/agent86.yourcasdomain.com/privkey.pem; # managed by Certbot
Save & exit (Ctrl+X, “y”)
After replacing the Let’s Encrypt certificates, certbot can be disabled (or uninstalled).
Uninstall certbot:
sudo snap remove certbot
CAS Admin
While possible, we strongly discourage exposing the Admin service.
Use the VPN to access CAS over the Internet: Admin OpenVPN (using batm-manage)
or: https://generalbytes.atlassian.net/wiki/x/AYCxsw
Using a proxy server to access CAS Admin increases risk and is no longer suggested.
Protecting the Admin interface behind a VPN is far stronger protection for your operation.
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:
Admin OpenVPN (using batm-manage)
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.