Domain names and HTTPS
Route 53, certificates and a padlock in the browser.
Part 1: The problem
The QuickCart app needed an address for its API. Noor, the mobile developer, copied the load balancer’s name from the console — a long string ending in elb.amazonaws.com — and put it straight into the app.
It was plain http://. iOS refused to connect, so Noor added an exception to App Transport Security to allow it.
A month later, the team rebuilt the load balancer. Its name changed. Every installed copy of the app now pointed at an address that no longer existed. Fixing it meant shipping an app update, waiting for review, and waiting again for customers to install it.
QuickCart needs three things:
- An address it owns, like
example.com, that stays the same whatever changes behind it. - A certificate, so the app talks HTTPS with no exceptions.
- A certificate that renews itself, so nobody has to remember.
Part 2: The idea
Computers find each other by IP address, like 203.0.113.10. People and apps use names, like example.com. DNS — the Domain Name System — is the internet’s way of turning a name into an address.
Where a name’s answer comes from
No single computer knows every name. A lookup is a chain of questions, and each server only knows who to ask next:
| Who | What they know | Their answer for example.com |
|---|---|---|
| Resolver | Nothing permanent. It asks on your behalf and remembers answers for a while. Run by your Wi-Fi, your mobile network, or a public service | “Let me find out” |
| Root servers | Who runs each ending, like .com or .org | “Ask the .com servers” |
.com servers | Which name servers are in charge of each .com domain | “Ask these four name servers” |
| Your name servers | Your actual records | “It’s 203.0.113.10” |
The resolver saves each answer for a number of seconds set by the record, called its TTL — time to live. That’s why a change can take a while to reach everyone.
The registrar and the hosted zone
Two different companies can be involved, and people mix them up:
| Piece | What it is | QuickCart’s |
|---|---|---|
| Registrar | Where you bought the domain. It tells the .com servers which name servers are in charge | Any registrar, including Route 53 itself |
| Hosted zone | Where the records live. In Route 53, one hosted zone per domain | The example.com hosted zone |
| NS record | The list of name servers in charge. Route 53 gives every hosted zone four | Copied from the hosted zone into the registrar |
Creating a hosted zone doesn’t make anyone use it. The registrar has to point to it. If you bought the domain through Route 53, that’s done for you. Anywhere else, you copy the hosted zone’s four name servers into the registrar’s settings. This is called delegation.
The records you’ll use
| Type | Points a name at | Example |
|---|---|---|
A | An IPv4 address | example.com → 203.0.113.10 |
AAAA | An IPv6 address | example.com → 2001:db8::10 |
CNAME | Another name. Not allowed at the domain’s root | www.example.com → example.com |
NS | The name servers in charge of the domain | Four Route 53 servers |
SOA | Housekeeping for the zone. Created for you | — |
| Alias (Route 53 only) | An AWS resource, like a load balancer. Allowed at the root | example.com → quickcart-web-alb |
Never point a record at one server’s IP address. Servers get replaced and their addresses change. Point it at the load balancer, which stays put while servers come and go behind it.
A load balancer has no fixed IP address either — AWS changes them as it scales. A normal A record would go stale. An alias record fixes that: Route 53 looks up the load balancer’s current addresses every time it answers. Alias queries to AWS resources are also free.
Why not a CNAME? The root of a domain, example.com itself (called the apex), must hold the NS and SOA records. DNS rules forbid a CNAME from sharing its name with any other record, so it can’t go there. An alias can.
HTTPS and certificates
HTTPS is HTTP inside an encrypted connection, using a protocol called TLS. It does two jobs:
| Job | What it means | Without it |
|---|---|---|
| Encryption | Nobody between the phone and QuickCart can read or change the traffic | Anyone on the same café Wi-Fi can read passwords and orders |
| Identity | The phone can check it’s really talking to example.com | An attacker can pretend to be QuickCart |
The identity part comes from a certificate: a file that says “this key belongs to example.com”, signed by a certificate authority that every browser and phone already trusts.
ACM: free certificates that renew themselves
ACM — AWS Certificate Manager — issues trusted certificates for free, as long as you use them on AWS services like a load balancer. Before it issues one, you prove you control the domain:
| Validation | How you prove it | Renews by itself? |
|---|---|---|
| DNS (use this) | ACM gives you a CNAME record to create. It checks the record appears in public DNS | Yes, as long as the record stays |
| ACM emails the domain’s contacts, and someone clicks a link | No — someone has to click again each time |
With the domain in Route 53, one button creates the validation record for you.
Where the encryption ends
The certificate goes on the load balancer, not on the servers. The load balancer decrypts each request and passes it to the servers inside the VPC. This is called TLS termination. The servers don’t handle certificates at all.
The load balancer gets two listeners — the ports it answers on:
| Listener | What it does |
|---|---|
| HTTPS on 443 | Uses the certificate. Sends requests on to the app |
| HTTP on 80 | Answers every request with a 301 redirect to the same address on https://. 301 means “moved permanently”, so browsers remember it |
If you don’t own a domain
A self-signed certificate is one you make yourself, signed by nobody. It’s free and instant, and the traffic is just as encrypted. But no trusted authority vouches for it, so every browser shows a warning, and apps refuse to connect.
| Your own domain + ACM | Self-signed | |
|---|---|---|
| Cost | A domain, roughly $10–15 a year for .com, plus $0.50 a month for the hosted zone | Nothing |
| Browser | A padlock | “Your connection is not private” |
| Apps | Connect normally | Refuse, unless you add an exception |
| Renewal | Automatic | You make a new one and import it |
| Good for | Anything customers use | Learning how the pieces fit |
Part 3: See it
Follow one lookup for example.com, from a customer’s phone to QuickCart’s load balancer. Then switch the registrar to Still the registrar’s — as if you created the hosted zone but forgot the last step — and try again.
What to notice: in the second run, Route 53 and its records didn’t change at all. The lookup simply never reached them. When DNS “isn’t working” after you create a hosted zone, check the name servers at the registrar first.
Part 4: Do it
Costs money — about $0.03 an hour for the load balancer and its public addresses in us-east-1 — delete it after. The hosted zone is $0.50 a month; AWS doesn’t charge for one deleted within 12 hours of creation. A domain, if you buy one, is roughly $10–15 a year for .com. Prices change; check the pricing pages.
You’ll put a load balancer on HTTPS, redirect HTTP to it, and — if you have a domain — give it a proper name. About 40 minutes, plus waiting for DNS.
There are two paths. Steps 1–3 and 8–9 are the same for both.
| Path | You need | Steps |
|---|---|---|
| A: your own domain | A domain you control. This lesson writes example.com; use yours everywhere you see it | 1, 2, 3, 4, 5, 6, 8, 9, 10, 11 |
| B: self-signed | Nothing extra | 1, 2, 3, 7, 8, 9, 11 |
Check the region selector at the top right says N. Virginia (us-east-1). The lab uses the default VPC, which every account has in every region, with a public subnet in each zone.
Create the load balancer's security group
In the AWS console: EC2Network & SecuritySecurity GroupsCreate security group
Field Enter Security group name quickcart-alb-sgDescription QuickCart load balancer: HTTP and HTTPS from anywhereVPC the default VPC Under Inbound rules, choose Add rule twice:
Type Source HTTP (port 80) Anywhere-IPv4 ( 0.0.0.0/0)HTTPS (port 443) Anywhere-IPv4 ( 0.0.0.0/0)Leave the outbound rule as it is. Choose Create security group.
You should seeThe group’s details page, with two inbound rules: ports 80 and 443 from
0.0.0.0/0.Create an empty target group
A load balancer needs somewhere to send traffic when you create it. There are no servers in this lab, so the target group stays empty; you’ll replace its job with a fixed response in step 8.
In the AWS console: EC2Load BalancingTarget GroupsCreate target group
Field Enter Choose a target type Instances Target group name quickcart-web-tgProtocol : Port HTTP : 80VPC the default VPC Leave the rest at its defaults and choose Next. Register nothing. Choose Create target group.
Create the load balancer
In the AWS console: EC2Load BalancingLoad BalancersCreate load balancer
Under Application Load Balancer, choose Create.
Field Enter Load balancer name quickcart-web-albScheme Internet-facing Load balancer IP address type IPv4 VPC the default VPC Availability Zones and subnets tick us-east-1a and us-east-1b Security groups remove default, choose quickcart-alb-sgListener HTTP : 80, default action Forward toquickcart-web-tgChoose Create load balancer, then View load balancer.
You should seeState: Provisioning, changing to Active after a few minutes. Copy its DNS name — a long name ending in
us-east-1.elb.amazonaws.com. This lesson calls itALB_DNS_NAME.Path A: create the hosted zone
If you bought your domain through Route 53, a hosted zone already exists. Skip to step 6 — creating a second one is a common mistake, below.
In the AWS console: Route 53Hosted zonesCreate hosted zone
Field Enter Domain name example.com— your domainType Public hosted zone Choose Create hosted zone.
You should seeTwo records already exist: an
NSrecord listing four name servers, likens-123.awsdns-45.com, and anSOArecord. Yours have different numbers.Path A: point the registrar at Route 53
Open your hosted zone and copy the four values from its
NSrecord.In your registrar’s website, find the domain’s name servers setting. Replace whatever is there with the four Route 53 name servers, and save. Every registrar’s page looks different; search its help pages for “change name servers” or “custom nameservers”.
Then check what the world sees, from your computer’s terminal:
Terminaldig +short NS example.comPart What it means digask DNS a question and print the answer +shortprint only the answer, not the full report NSask for the name servers in charge of the domain example.comyour domain You should seens-123.awsdns-45.com. ns-678.awsdns-12.net. ns-1024.awsdns-00.org. ns-1600.awsdns-10.co.uk.When this matches your hosted zone’s four, delegation is working. It often takes minutes, but can take up to a day or two, because resolvers may still hold the old answer until its TTL runs out.
Path A: request a certificate
In the AWS console: Certificate ManagerCertificatesRequest
Choose Request a public certificate, then Next.
Field Enter Fully qualified domain name example.comAdd another name to this certificate www.example.comValidation method DNS validation Key algorithm RSA 2048 Leave anything else at its default. Choose Request.
Open the new certificate. Its status is Pending validation. In the Domains section, choose Create records in Route 53, check both names are ticked, and choose Create records.
You should seeWithin a few minutes — occasionally up to half an hour — Status: Issued. In the hosted zone, a new
CNAMErecord with a long random name. Leave it there for good: ACM checks it again every time it renews the certificate.Now skip to step 8.
Path B: make and import a self-signed certificate
Make a certificate and its private key, in any folder on your computer:
Terminalopenssl req -x509 -newkey rsa:2048 -nodes -keyout quickcart-key.pem -out quickcart-cert.pem -days 30 -subj "/CN=quickcart.example.com"Part What it means openssl reqthe tool’s certificate-making command -x509make a finished, self-signed certificate, instead of a request for someone else to sign -newkey rsa:2048make a new 2048-bit RSA private key to go with it — a type ACM accepts -nodesdon’t protect the key with a password. ACM only imports unprotected keys -keyout quickcart-key.pemwhere to save the private key. Keep it secret -out quickcart-cert.pemwhere to save the certificate -days 30how long it lasts -subj "/CN=quickcart.example.com"the name it claims to be for, set here so it doesn’t ask you questions You should seeA burst of dots and plus signs while the key is generated, then two new files in the folder:
quickcart-key.pemandquickcart-cert.pem.Print the certificate, so you can copy it:
Terminalcat quickcart-cert.pemPart What it means catprint a file’s contents quickcart-cert.pemthe certificate you just made You should see-----BEGIN CERTIFICATE----- MIIDITCCAgmgAwIBAgIUU+7pZ7yAR4jewxjumSmlJukGtrcwDQYJKoZIhvcNAQELIt continues for about 20 lines and ends with
-----END CERTIFICATE-----. Yours has different letters.In the AWS console: Certificate ManagerCertificatesImport
Field Enter Certificate body everything printed by cat quickcart-cert.pem, including the BEGIN and END linesCertificate private key everything in quickcart-key.pem— print it the same wayCertificate chain leave empty. A self-signed certificate has no chain Choose Import. If the console shows a review page first, choose Import there too.
You should seeThe certificate in the list, Type: Imported, Status: Issued, for
quickcart.example.com.Add the HTTPS listener
In the AWS console: EC2Load Balancersquickcart-web-albListeners and rulesAdd listener
Field Enter Protocol : Port HTTPS : 443Default action Return fixed response Response code 200Content type text/plain Response body QuickCart over HTTPSSecurity policy leave the recommended default Default SSL/TLS server certificate From ACM, then your certificate Choose Add.
A real service would forward to a target group of servers here. The fixed response lets you test HTTPS without any.
You should seeTwo listeners: HTTP:80 and HTTPS:443, the second showing your certificate.
Redirect HTTP to HTTPS
In the same Listeners and rules tab, select HTTP:80, then choose Manage listener → Edit listener.
Field Enter Default action Redirect to URL Redirect to URI parts Protocol : Port HTTPS : 443Status code 301 - Permanently moved Choose Save changes.
Path A: point your domain at the load balancer
In the AWS console: Route 53Hosted zonesexample.comCreate record
Field Enter Record name leave empty — this is the apex, example.comitselfRecord type A Alias On Route traffic to Alias to Application and Classic Load Balancer Region US East (N. Virginia) Load balancer dualstack.quickcart-web-alb-followed by numbers — yoursRouting policy Simple routing Choose Create records. Do it once more with Record name
www, so both names on the certificate lead somewhere.Test it
Path A. Ask for the plain HTTP address:
Terminalcurl -I http://example.comPart What it means curlmake a web request from the terminal -Iprint only the response’s headers, not the page http://example.comyour domain, deliberately over plain HTTP You should seeHTTP/1.1 301 Moved Permanently Server: awselb/2.0 Location: https://example.com:443/There are a few more header lines; these are the ones that matter. The load balancer sent you to HTTPS. Now open
https://example.comin a browser.You should seeA padlock in the address bar and the text QuickCart over HTTPS. Select the padlock to see the certificate, issued by Amazon.
Path B. Use the load balancer’s DNS name from step 3:
Terminalcurl https://ALB_DNS_NAMEPart What it means curlmake a web request https://ALB_DNS_NAMEthe load balancer’s DNS name, over HTTPS You should seecurl: (60) SSL certificate problem: self signed certificateThe wording may differ slightly with your version of curl. Curl refused: the traffic would be encrypted, but nobody trusted vouches for the certificate. Tell curl you accept that, for this test only:
Terminalcurl -k https://ALB_DNS_NAMEPart What it means curlmake a web request -kcarry on even though the certificate isn’t trusted. Only ever for testing https://ALB_DNS_NAMEthe load balancer’s DNS name, over HTTPS You should seeQuickCart over HTTPSOpen the same address in a browser. It shows Your connection is not private — that’s the trade-off from the idea. You can click through it; your customers shouldn’t have to.
Clean-up step: Clean up
The load balancer bills every hour, so delete it first.
In the AWS console: EC2Load Balancersquickcart-web-albActionsDelete load balancer
Type
confirmand choose Delete. Then delete the rest, in this order:Where Delete EC2 > Target Groups quickcart-web-tg— Actions → DeleteEC2 > Security Groups quickcart-alb-sg— Actions → Delete security groups. If it refuses, wait a minute for the load balancer to finish deletingCertificate Manager your certificate — Delete Route 53 > Hosted zones > example.com (path A) the two Arecords and the validationCNAME. Then the hosted zone itself — Delete zoneA hosted zone can only be deleted once it holds nothing but its
NSandSOArecords. If you plan to keep using the domain with Route 53, keep the hosted zone instead, at $0.50 a month.For path B, delete the two
.pemfiles from your computer.You should seeNo load balancer, target group, certificate or hosted zone left. If you bought a domain just for this, it stays yours until it expires; turn off auto-renew at the registrar if you don’t want it.
Part 5: Check yourself
QuickCart created a hosted zone in Route 53 with the right records, but example.com still shows the registrar's parking page. What is the most likely cause?
Why does QuickCart point example.com at the load balancer with an alias record rather than a CNAME?
How does ACM's DNS validation prove you own example.com?
What is the trade-off of a self-signed certificate on the load balancer?
Someone types http://example.com. What should the load balancer's port 80 listener do?
QuickCart changes a record's value, but some customers still reach the old address for an hour. Why?
Part 6: Cheat sheet
| Term | In one line |
|---|---|
| DNS | Turns names into IP addresses, by a chain of servers |
| Resolver | Asks on your behalf, and caches answers |
| TTL | How many seconds an answer may be cached |
| Registrar | Where you bought the domain. Sets its name servers |
| Hosted zone | Where a domain’s records live in Route 53. $0.50 a month |
| NS record | The four name servers in charge. Must match at the registrar |
A / AAAA | Name → IPv4 / IPv6 address |
CNAME | Name → another name. Never at the apex |
| Alias | Route 53 only. Name → AWS resource, allowed at the apex |
| ACM | Free trusted certificates for load balancers. DNS validation renews itself |
| TLS termination | The load balancer decrypts; servers don’t handle certificates |
| Port 80 listener | 301 redirect to HTTPS |
| Self-signed | Encrypted, but untrusted. For learning only |
| DNS not working? | dig +short NS example.com — does it match the hosted zone? |