API with NestJS #100. The HTTPS protocol with Route 53 and AWS Certificate Manager

AWS

This entry is part 100 of 168 in the API with NestJS

In the latest articles, we deployed our NestJS application using AWS. However, we’ve been exclusively using the HTTP protocol so far. You probably noticed that almost every website nowadays uses HTTPS. And no wonder, because it solves a bunch of problems and makes surfing the internet more secure. In this article, we prepare our architecture to use HTTPS with AWS Certificate Manager. We also explain why establishing a secure connection to our API is worth it.

How using HTTPS benefits us

One of the malicious behaviors HTTPS can mitigate is the man in the middle. In this situation, the attackers put themselves between the client and the server. As a result, they can see the traffic, modify it, and pass it to the destination. All while remaining unnoticed. Picture sending a password to your banking account when they are listening!

The above situation is possible because we send the data in plain text when using HTTP. On the other hand, HTTPS uses encryption. Even if the attackers eavesdrop on our communication, they can’t make much sense of it. It is crucial when using a public WiFi network, such as in a restaurant or a hotel. The hacker can set up a WiFi hotspot named after a real public network hoping people would connect to it instead of the real hotspot. This is sometimes referred to as the “evil twin” attack.

Certificates

Besides encryption, HTTPS also aims to authenticate a website’s identity. For example, let’s open Twitter and click on the padlock next to the URL. By doing that, we can view its certificate.

To implement HTTPS on our site, we need to have a certificate issued by a certificate authority. In the screenshot above, you can see that the certificate for Twitter was issued by DigiCert. The owner of each website that uses HTTPS needs a certificate that verifies their ownership of the domain. Chrome gets the list of certificate authorities from our operating system. Firefox manages its own list. If a certificate was issued by an authority that’s not on the list, the browser won’t trust it and will display a warning.

Getting a custom domain with Route 53

Since a part of HTTPS is authenticating a website’s identity, we should get our custom domain first. To do that, we can use the Route 53 service built into AWS.

Once we register the domain, AWS will send us an email with a link. We need to open it to confirm our email address.

In one of the previous articles, we learned how to manage our NestJS instances using the Application Load Balancer. This way, we can access our API through a URL such as .

When we register a domain through Route 53, it creates a hosted zone for us. It’s a collection of DNS information that describes how we route traffic to the domain and its subdomains.

Since we now have a custom domain bought and managed through Route 53, we can set up our hosted zone to route the traffic to our load balancer.

To associate our domain with our load balancer, we need to go to the configuration page of our hosted zone.

We must now click the “Create record” button and choose the “Simple routing” policy.

Then, we need to click the “Define simple record” button and choose our existing load balancer.

Once we do the above, we can see a new record created for our hosted zone.

To communicate with a particular server, we need to know its exact address. Memorizing the IP addresses of all websites we visit would be very difficult for most people. Fortunately, we can use domain names that are a lot easier to wrap your head around. When we request a website under a particular domain, the Domain Name System (DNS) translates it to a machine-readable IP address.

The DNS servers contain DNS records that serve as various pieces of information about our domain. So far, we have three DNS records:

  • A record – holds the IP address of our domain. We created it when we associated our hosted zone with the load balancer.
  • NS record – contains the name server for the DNS entry.
  • SOA record – holds the admin information about the domain.

Thanks to doing all of the above, our API is now accessible through our custom domain.

Above, we make a request to our health check endpoint. If you want to know more, check out API with NestJS #98. Health checks with Terminus and Amazon ECS

Getting a certificate with AWS Certificate Manager

One way to obtain a certificate is to use AWS Certificate Manager. Let’s open it and click the “Request a certificate” button.

When we do that, we need to provide our domain name. We also need to select how we want to prove that we own our domain.

When we do the above, our new certificate is visible on the list.

Since we chose the “DNS validation”, we must perform additional actions. Let’s click on the above certificate to open it up.

Above, we can see the “Create records in Route 53” button. When we do that, we can add a CNAME DNS record to our domain with the value requested by the AWS Certificate Manager. Doing that proves that we are the owner of the domain.

Modifying our load balancer

The default port for websites accessed through HTTP is 80. Therefore, we’ve set up our load balancer to listen to the incoming traffic on port 80. However, the default port for websites accessed through HTTPS is 443. Therefore, we need to modify our load balancer and listen to the traffic on port 443.

To do that, we need to open the EC2 management console and go to the configuration of our application balancer. Then, we need to click on the “Add listener” button.

The first thing to set up in our listener is the “forward” action, where we select our target group.

We also need to select the certificate we generated through AWS Certificate Manager.

Besides the above, we need to go to the configuration of the security group attached to our Application Load Balancer and add HTTPS to the inbound rules.

Once we do all of the above, we can access our API through HTTPS.

Redirecting the HTTP traffic

So far, our API is accessible both through HTTP and HTTPS. Since accessing our website through HTTPS is much safer, we can enforce that by redirecting the user to the HTTPS version automatically.

To do that, we need to modify the HTTP listener in our load balancer configuration.

Summary

In this article, we’ve bought a new domain using Route 53 and attached it to our REST API made with NestJS. We’ve also generated a new certificate using the AWS Certificate Manager and associated it with our domain. Finally, thanks to making some changes to our load balancer, we’ve achieved a secure HTTPS connection to our API.

There is still more to learn when it comes to deploying NestJS with AWS, so stay tuned for more articles.

Series Navigation<< API with NestJS #99. Scaling the number of application instances with Amazon ECSAPI with NestJS #101. Managing sensitive data using the AWS Secrets Manager >>
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
gabo
gabo
1 year ago

Congrats on 100!!!!
This website is a blessing for any backend dev.

kevo
kevo
9 months ago

I believe I can use nginx here as well?