Ravindra BagaleCourses & study guides Track your progress

Labs · Cyber Security

Lab: Add HTTPS with Certbot, Force the HTTP-to-HTTPS Redirect and Test Renewal with a Dry Run

Intermediate45 minYour EC2 server with Nginx · Your own domain (Chapter 12) · Certbot · curl

Course: Cyber Security · Chapter 13: Multiple Websites on One Server and HTTPS with Certbot

Chapter 13 hosts several websites and adds HTTPS with Certbot; this lab adds the redirect, HSTS and a renewal test.

Chala mitrano! Without HTTPS, anyone on the same Wi-Fi can read what users type on our site. Let's Encrypt gives free certificates, and Certbot installs them in two minutes. But the real skill is making sure HTTP always redirects and that renewal works before the certificate expires in 90 days. Chala, safe website banvuya!

Suppose we are…

Suppose we run the website of a coaching class that sells test-series on Unacademy-style pages, on our own Nginx server. A student reports a browser warning "Not secure" on the login page. We add a free TLS certificate (the file that proves the site's identity and turns on encryption) with Certbot, force every http:// visit to https://, and test that the certificate will renew itself.

Goal of this lab

By the end you will have:

  • A valid Let's Encrypt certificate on your own domain or sub-domain.
  • HTTP returning 301 to HTTPS, and an HSTS header (it tells browsers to use only HTTPS for this site).
  • A successful certbot renew --dry-run and the renewal timer switched on.

What you need (all free)

  • Your EC2 Amazon Linux 2023 server with Nginx (Labs 7–8).
  • A domain or sub-domain you own, with an A record pointing to the server's Elastic IP (Chapter 12), for example lab.mydomain.in.
  • Security group: HTTP 80 and HTTPS 443 from Anywhere during this lab (Let's Encrypt must reach port 80 to check that you own the domain). SSH stays My IP.
  • 40–45 minutes.

Safety and ethics

Request certificates only for domains you own or manage. Let's Encrypt has rate limits, so test with --dry-run instead of requesting real certificates again and again.

Steps

  1. Check the domain points to your server (replace with your name):

    dig lab.mydomain.in +short
    

    What you should see: your server's Elastic IP.

  2. SSH to the server. Tell Nginx the site's name. Create /etc/nginx/conf.d/lab.conf with sudo nano and paste:

    server {
        listen 80;
        server_name lab.mydomain.in;
        root /usr/share/nginx/html;
    }
    

    Then run sudo nginx -t && sudo systemctl reload nginx.

  3. Install Certbot with the Nginx plugin:

    sudo dnf install -y certbot python3-certbot-nginx
    
  4. Request the certificate:

    sudo certbot --nginx -d lab.mydomain.in
    

    Enter your email, type Y to agree to the terms, and choose whether to share your email with the EFF. If asked about redirecting HTTP to HTTPS, choose Redirect.

    What you should see: Successfully received certificate and Successfully deployed certificate for lab.mydomain.in to /etc/nginx/conf.d/lab.conf.

  5. Check the redirect from your laptop:

    curl -I http://lab.mydomain.in
    

    What you should see: HTTP/1.1 301 Moved Permanently and Location: https://lab.mydomain.in/.

  6. Add HSTS. Open /etc/nginx/conf.d/lab.conf; inside the server block that has listen 443 ssl, add:

    add_header Strict-Transport-Security "max-age=86400" always;
    

    We start with one day (86400 seconds). After a week without problems you can raise it to 31536000 (one year). Run sudo nginx -t && sudo systemctl reload nginx.

  7. Check the HTTPS response and the certificate:

    curl -sI https://lab.mydomain.in | grep -i strict
    echo | openssl s_client -connect lab.mydomain.in:443 -servername lab.mydomain.in 2>/dev/null | openssl x509 -noout -issuer -dates
    

    What you should see: strict-transport-security: max-age=86400, an issuer from Let's Encrypt, and notAfter about 90 days from today.

  8. Test renewal without using up rate limits:

    sudo certbot renew --dry-run
    

    What you should see: Congratulations, all simulated renewals succeeded.

  9. Make sure renewal runs automatically:

    sudo systemctl enable --now certbot-renew.timer
    systemctl list-timers | grep certbot
    

    What you should see: a certbot-renew.timer line with the next run time.

  10. In your browser open https://lab.mydomain.in and click the padlock (or the site-information icon) → Connection is secure → Certificate is valid to see the details.

Ravindra Bagale's Tip

Real outages happen when renewal silently fails, for example because someone closed port 80 later. Add a reminder in your calendar 20 days before notAfter for the first cycle, and check certbot renew --dry-run after every firewall change. Vishwas theva, pan check kara!

Common mistakes

Mistake What happens Fix
Port 80 closed or only My IP Timeout during connect (likely firewall problem) Allow HTTP 80 from Anywhere so Let's Encrypt can check
A record not pointing to this server yet DNS problem or wrong server answers the challenge Fix the A record and wait for TTL; check with dig
No server_name in Nginx Certbot cannot find where to install the certificate Add a server block with your server_name
Setting HSTS to one year on day one A mistake can lock users out of HTTP for a year Start with max-age=86400, raise later
Requesting real certificates again and again while testing Rate limit errors for days Use --dry-run or --staging for tests

Self-check checklist

0 of 5 done

Try-at-home challenge

Find out exactly when your certificate expires using only the browser, and then using sudo certbot certificates on the server. Do the dates match?

Check your answer

In the browser: padlock → certificate details → Validity: Expires on. On the server, sudo certbot certificates shows Expiry Date: ... (VALID: 89 days). Both show the same date (the browser may show it in your local time zone). Let's Encrypt certificates last 90 days, and Certbot renews them when about 30 days are left.

Clean up to avoid charges

  1. If you are done with the server, terminate it: EC2 → Instances → Instance state → Terminate (delete) instance.
  2. Release the Elastic IP: EC2 → Elastic IPs → select it → Actions → Release Elastic IP address. An Elastic IP that is not attached to a running server is charged by the hour.
  3. Delete the A record for lab.mydomain.in at your domain provider, so the name does not point to an IP someone else may get next.

Samjla ka? Certificate, redirect, HSTS, and a renewal you have tested. Aata pudhe jaauya: Chapter 14 stores files privately in S3.