OpenZiti BrowZer Gateway

OpenZiti BrowZer Gateway

How to Acquire FQDN TLS Certificates from a Public CA

·

10 min read

Welcome back to the next article concerning BrowZer, a new group of open-source components from the OpenZiti project that enables automatic embedding of zero trust networking into web applications. The reason BrowZer exists, and the problem it aims to solve is preventing your internet-facing web applications from being attacked by malicious threat actors.

This article is part of the ongoing web application security series concerning BrowZer, and here I will provide instructions concerning how to acquire TLS certificates for its gateway component — or what we internally refer to as the HTTP Agent.

Before proceeding below, you may be interested in reading the architectural overview of the OpenZiti BrowZer Gateway to get some broader context if you haven't already read it.

This article describes how to acquire fully qualified domain name (FQDN) certs for use with BrowZer, but you may also be interested in Part-1 of this article where I describe how to acquire wildcard certs for use with BrowZer.

BrowZer Gateway Internet-Facing TLS

Customers of our CloudZiti offering will have everything described below automatically orchestrated for them. However, if you are a user of our OpenZiti open source offerings, then continue reading, and I'll provide information regarding the BrowZer Gateway TLS requirements and how to satisfy them.

The educational material contained in this article will certainly help enable you to deploy your own instance of the BrowZer Gateway, but please note that it is not exhaustive. Here we limit discussion to tooling you can use to acquire the necessary TLS certs you need to use with the BrowZer Gateway.

Upcoming articles in the series will be published soon and they will close the remaining gap and describe all the IdP integration/configuration details, the BrowZer Gateway Docker container, and all BrowZer Gateway configuration details related to the OpenZiti overlay network it will be a part of.

HTTPS

For general web-related usability and security reasons, as well as BrowZer architectural reasons, the BrowZer Gateway must be served over HTTPS.

Not using HTTPS causes nasty things to happen:

  • browsers render scary warnings to users

  • users are exposed to security issues (e.g man-in-the-middle attacks).

As discussed earlier in the architectural overview of the OpenZiti BrowZer Gateway, in a BrowZer environment your web app will be invisible to the internet, and the BrowZer Gateway is deployed such that it is the web server that your users will point their browsers to in order to reach your dark web app.

Self-signed Cert? That's a No-No!

Using HTTPS implies using a TLS certificate. And while using TLS certificates with the BrowZer Gateway is certainly a requirement, using just any TLS certificate isn't good enough.

For example, you might be thinking: "I'll just run a command similar to the following...

openssl req -new -x509 -sha256 -newkey rsa:2048 \
  -nodes -keyout example-com.key.pem -days 365 \
  -out example-com.cert.pem

... to generate a self-signed cert, and I'll use that."

The problem with using a self-signed cert to host the BrowZer Gateway is that doing so will result in the client-side browser rendering something resembling the following when it visits a web server that uses a self-signed cert:

image.png

That's an obvious show-stopper.

The solution is to acquire a TLS certificate from a public certificate authority (CA) because certificates generated by public CA's will be trusted by browsers.

TLS Cert From a Public CA

It's possible to pay money to a company like AWS, Godaddy, Namecheap, etc., in order to get a certificate from a well-known public certificate authority..., but don't worry...

You don't need to spend any money to get the certificates you need!

Let’s Encrypt is an organization that issues TLS certificates for free to the public. Let’s Encrypt is reputable, and trusted by browsers. They were created by the Internet Security Research Group (with members like Chrome, Mozilla, Cisco, the Bill and Melinda Gates Foundation, etc.) and aim to facilitate an Internet where all websites communicate over HTTPS even if the site’s owner does not have money to buy TLS certificates on a recurring basis.

Broadly speaking, you can use Let’s Encrypt to generate certificates in multiple ways:

  1. Using the automated system that your hosting company provides

  2. Generating a certificate by manually interacting with Let’s Encrypt with scripts you run

  3. Configuring your DNS zone and running a lightweight DNS-challenge name server to automatically use Let’s Encrypt to generate wildcard certificates

I'll skip any discussion of item #1 (hosting providers) since self-hosting BrowZer is the environment we're focused on here.

If you wish to serve a single dark web app via the BrowZer gateway, item #2 (Manual Cert Generation) will suffice, and this is what we will describe in the subsections below.

If you wish to serve multiple dark web apps via a single BrowZer gateway, item #3 (Automatic Wildcard Cert Generation) is the recipe you'll need, since wildcard certs are a key underpinning of how the BrowZer Gateway facilitates hosting multiple dark web apps. In that case, click over to the article where I describe how to acquire wildcard certs for use with BrowZer.

Manual Cert Generation (Mac)

You can use your Mac to get a TLS certificate issued by Let’s Encrypt. You can then use the cert on your laptop to get your feet wet in a local BrowZer environment. Later, you could then install this same cert on the (cloud) instance where you'd like to host your BrowZer Gateway.

Here are the required items:

  • computer running macOS.

  • reliable internet connection.

  • comfort with running commands in a terminal.

  • Homebrew: You can find instructions for installing it here.

Install certbot:

Open a terminal, and use Homebrew to install cerbot by running the following command in a terminal:

brew install certbot

Create a directory for Let’s Encrypt to save to:

Create a directory in a location you like (e.g in your home directory) and give it a name you want. Let’s say we want to use YOUR_HOME_DIR/lets-encrypt. We can create the said directory by running this command:

mkdir ~/lets-encrypt

Later, you will tell Let’s Encrypt to save its output in this directory. Otherwise, Let’s Encrypt will write to /etc/letsencrypt, and you may not have the permissions needed to access some of the contents in that location

Prove that you own the domain:

When you get a TLS certificate from Let’s Encrypt, their servers validate that you control the domain names for the certificate you are requesting. You need to prove to Let’s Encrypt that you own the domain. To do this, you need to solve a "challenge", as defined by the ACME standard. That is, you need to do something that you would not be able to do if you didn’t own the domain and have admin access to it.

You can accomplish this in multiple ways: with a HTTP-01 challenge or a DNS-01 challenge.

We will use the DNS-01 technique, and you will need to add a certain DNS record to your domain (i.e. the DNS challenge).

Run certbot to acquire a free TLS certificate:

Enter the following command to run certbot and start the process for getting a certificate:

certbot certonly --preferred-challenges=dns \
  --manual --config-dir ~/lets-encrypt \
  --work-dir ~/lets-encrypt --logs-dir ~/lets-encrypt

certbot will then prompt you like this:

Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel):

You will now enter the fully qualified domain name (FQDN) where you want to host the BrowZer Gateway. The FQDN you enter must reside in a DNS zone that you control (i.e. you need to prove you own the domain).

You might be using Google Domains, AWS Route53, or some other DNS administration tool. I will use an AWS Route53 example here.

I have the ability to administrate the .ziti.netfoundry.io domain, so I will use a FQDN of browzer-gateway.ziti.netfoundry.io for this example.

When I enter that FQDN, certbot will prompt like the following:

Saving debug log to /Users/curt/lets-encrypt/letsencrypt.log
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel): browzer-gateway.ziti.netfoundry.io
Requesting a certificate for browzer-gateway.ziti.netfoundry.io

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.browzer-gateway.ziti.netfoundry.io.

with the following value:

AsI-Nz4WrH7hKX9-cO2tIEbxyQBzXW0ROXw_KRidJ2Q

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.browzer-gateway.ziti.netfoundry.io.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

Using the values certbot specified, I enter them into the AWS Route53 console, like this:

image.png

I then click the "Create" button, and then Route53 will produce the TXT record, like this:

image.png

Now that the DNS challenge record is in place, I can return to the certbot prompt, and press ENTER. It will then respond like this:

Press Enter to Continue

Successfully received certificate.
Certificate is saved at: /Users/curt/lets-encrypt/live/browzer-gateway.ziti.netfoundry.io/fullchain.pem
Key is saved at:         /Users/curt/lets-encrypt/live/browzer-gateway.ziti.netfoundry.io/privkey.pem
This certificate expires on 2023-01-19.

Looking at what was produced, you'll see the following:

{13:29}~/lets-encrypt/archive ➭ ls -l /Users/curt/lets-encrypt/live/browzer-gateway.ziti.netfoundry.io
total 8
-rw-r--r--  1 curt  staff  692 Oct 21 13:29 README
lrwxr-xr-x  1 curt  staff   58 Oct 21 13:29 cert.pem -> ../../archive/browzer-gateway.ziti.netfoundry.io/cert1.pem
lrwxr-xr-x  1 curt  staff   59 Oct 21 13:29 chain.pem -> ../../archive/browzer-gateway.ziti.netfoundry.io/chain1.pem
lrwxr-xr-x  1 curt  staff   63 Oct 21 13:29 fullchain.pem -> ../../archive/browzer-gateway.ziti.netfoundry.io/fullchain1.pem
lrwxr-xr-x  1 curt  staff   61 Oct 21 13:29 privkey.pem -> ../../archive/browzer-gateway.ziti.netfoundry.io/privkey1.pem

If you paste the contents of the fullchain.pem file into a cert validator (e.g. https://www.sslchecker.com/certdecoder), you will then see the following:

image.png

Manual Cert Generation (Linux)

You can use Linux to get a TLS certificate issued by Let’s Encrypt. You can then use the cert on your laptop to get your feet wet in a local BrowZer environment. Later, you could then install this same cert on the (cloud) instance where you'd like to host your BrowZer Gateway.

Follow the instructions located here to get certbot installed on your system.

Once installed, you can use the same sequence of steps described in the above Mac sub-section to get your cert generated.

Manual Cert Generation (Windows)

You can use Windows to get a TLS certificate issued by Let’s Encrypt. You can then use the cert on your laptop to get your feet wet in a local BrowZer environment. Later, you could then install this same cert on the (cloud) instance where you'd like to host your BrowZer Gateway.

Follow the instructions located here to get certbot installed on your system.

Once installed, you can use the same sequence of steps described in the above Mac sub-section to get your cert generated.

Here is a looping/animated GIF showing what it looks like when executed, as well as some (non-essential) decoding of the acquired cert just to prove it contains what we need.

BrowZer Gateway Deployment & Configuration

Customers of our CloudZiti offering will have everything described in this article automatically orchestrated for them.

Meanwhile, if you are a user of our OpenZiti open-source offerings, and you'd like to take BrowZer out for a spin, then you will be interested in reading the next few articles in this series where I describe how to use the certificates you obtained as shown above, and then configure and deploy your own instance of the BrowZer Gateway.

Wrap up

Do you host a web app and want to be invisible to malicious threat actors?

Do you want your users to have easy access from anywhere with no additional software on their client laptop of mobile phone?

Do you want to do all this without making any modifications to your web app?

If so, I hope you'll join our community and try BrowZer.

Please subscribe to this blog to be notified of more information concerning how to succeed.