Managing your PKI using AWS Certificate Manager

Image for post
Image for post

PKI (Public Key Infrastructure)

Common examples of PKI today are SSL Certificates on websites. SSL Certificates ensures that the visitors are actually accessing the intended website and not the malicious website. We can use PKI for public websites and also for our internal website/internal services. In this blog, we will focus on how we manage our PKI for internal websites/services like AWS Load balancers, S3 endpoints, API Gateways etc…

Traditional way of managing internal PKI is bit complex, since we have to create our own Root certificate, Intermediate certificate and issue certificates for all our services. Rotating and managing each and every certificate is a tedious process. AWS Certificate Manager provides support to manage our own PKI on Cloud, where all the manual work will be taken care by AWS itself. Let’s see the workflow of the PKI below.

Workflow

Image for post
Image for post
PKI with AWS ELB

In this blog, we are going to create our own Root CA, Intermediate CA and provision SSL Certificates for our (internal) DNS record which is pointing to the ELB DNS and we will see how AWS automatically renews our certificate. Below are the AWS Services we used,

  1. ELB — Application Load Balancer.
  2. EC2 installed with Nginx/Apache.
  3. AWS Certificate Manger.
  4. Route 53 — Private domain.

Let’s go in detail on how we configure everything.

Create Root CA and Intermediate CA Certificates

Image for post
Image for post
Image for post
Image for post

Fill in your details, only Common Name(CN) field is mandatory.

Image for post
Image for post
Image for post
Image for post

Add required tags if needed.

Image for post
Image for post

This is the place where you authorize ACM to use this CA Certificate to create private certificates for our application/services.

Finally review everything and create the Root certificate. Now you will be automatically redirected to configure few parameters for our Root CA. I chose the validity as 10 years and SHA256withRSA algorithm.

Image for post
Image for post

And review the parameters and create the CA. This is going to be our Root CA certificate. And you can now see the same in ACM portal.

Image for post
Image for post

Next, we are going to create Intermediate CA using our Root CA. This time we are using Subordinate CA.

Image for post
Image for post
Image for post
Image for post

Follow the same process as we used to create our Root CA Certificate. Once you provisioned the intermediate CA, set the certificate parameters. We are going to point our Root CA Certificate as Parent private CA and I set the validity as 5 years. If you want more Intermediate CA’s you can achieve it using path length variable.

Image for post
Image for post

Review and create Intermediate certificate as well.

Image for post
Image for post

Now provision your private certificates using our newly created CA certificate. Go to ACM — Certificate Manger — Request a private Certificate.

Provision your certificates in few clicks!

Image for post
Image for post

Now we need to choose our CA, whatever the CA we select will be used to provision our certificate. Here, I am selecting the subordinate CA (i.e. intermediate CA). Since we used our Root CA to provision Intermediate CA, by selecting Intermediate CA we create the following chain of trust with Root CA — Intermediate CA — Private Certificates.

Image for post
Image for post

Enter your domain name.

Image for post
Image for post

shoppingapp.com is the internal domain I created in Route 53.

Optionally add tags if you want. Then review and provision the certificate.

Image for post
Image for post

That’s it! We have provisioned our private certificate using our own Root CA and Intermediate CA.

Image for post
Image for post

For this example, I provisioned an EC2 instance and installed Nginx. No configuration is touched in Nginx. On Route 53, I have created a local zone named shoppingapp.com.

On to the Load Balancer now

Image for post
Image for post

When you navigate to next page, AWS automatically populate our ACM certificate here. Just select the correct certificate and proceed. There is only one certificate for me, nothing much to do here.

Image for post
Image for post

Next configure security group allow port 80 and 443 from everywhere and outbound to all.

Image for post
Image for post
Image for post
Image for post

Register your target nodes, I just have one node to register, then review and provision your ALB.

Let’s look at the ALB Listeners now.

Image for post
Image for post

Our Load balancer listens on both http and https port (80 and 443 respectively) and forwards both traffic to target group. In target group we have a single EC2 instance with Nginx installed and Nginx listening on port 80. Health check is also configured on port 80.

User access — http://app.shoppingapp.com — Route 53 resolves to ALB DNS — ALB listens on port 80 and sends traffic to TG (app-shoppingapp-tg) — EC2 where Nginx is running. And the same flow happens to https request also.

We need to force http requests also to redirect to https. View/edit rules the http listener, delete the forward to target group and add redirect to https and update.

Image for post
Image for post

Now everything is configured, let’s verify it. Curl request clearly says the what we configured on http listener rule.

~$ curl app.shoppingapp.com
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
</body>
</html>

Now the modified workflow is,

User access → http://app.shoppingapp.com → Route 53 resolves to ALB DNS → ALB listens on port 80 and forwards traffic to https on port 443 with 301 http code → ALB listens on port 443 also and sends traffic to TG (app-shoppingapp-tg) → EC2 where Nginx is running. And the same flow happens to https request also.

SSL termination happens in the ALB and all the backend connection (from ALB to EC2) will use http port.

Image for post
Image for post

Accessing in a web browser redirects me to the https url as well. Let’s look at the certificate now.

Image for post
Image for post

My website app.shoppingapp.com is signed by Shoppingapp-Subordinate CA (which is our Intermediate CA) which is signed by Shoppingapp-Root (Root CA). This is how our chain of trust looks like. I already added my Root cert to the browser trusted store, so I don’t get any warning here. Just add the Root Certificate trusted store on your organization, all your certificates created from the Root CA will be automatically trusted.

Image for post
Image for post

Closing Notes

Image for post
Image for post

AWS Cloud Engineer, Bangalore

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store