How can I use a LetsEncrypt SSL cert in my Heroku Node Express app?

前端 未结 2 1925
猫巷女王i
猫巷女王i 2020-12-28 08:30

I have a Node Express app running on Heroku that I want to encrypt with a free-of-charge SSL cert from LetsEncrypt. However, the methods I\'ve seen require opening up ports

相关标签:
2条回答
  • 2020-12-28 08:56

    Update:

    Heroku now supports LetsEncrypt natively! So this workaround is no longer needed.

    Instructions here:

    https://devcenter.heroku.com/articles/automated-certificate-management

    For new apps, you don't have to do anything, it's turned on by default. For apps created before March 21 2017, you can turn it on with this Heroku cli command: heroku certs:auto:enable

    Thanks @Spain Train


    Background

    Ideally, LetsEncrypt allows for an automated certificate renewal process. That's harder to do on Heroku, so this answer describes how to use a manual process. Using a Heroku environment var, you'll be able to update your certs manually fairly easily going forward - no code changes.

    Credit for this answer goes largely to two nice blog posts: https://medium.com/@franxyzxyz/setting-up-free-https-with-heroku-ssl-and-lets-encrypt-80cf6eac108e#.67pjxutaw
    and
    https://medium.com/should-designers-code/how-to-set-up-ssl-with-lets-encrypt-on-heroku-for-free-266c185630db#.ldr9wrg2j

    There's a GitHub project which apparently supports automated certs updates on Heroku. I'll update this answer when I've tried it out:
    https://github.com/dmathieu/sabayon

    Using LetsEncrypt on Heroku with a Node Express app

    Get the Express server ready:

    Add this middleware to your Express app. Be sure to add it BEFORE any middleware that redirects http to https, because this endpoint must be http.

    // Read the Certbot response from an environment variable; we'll set this later:
    
    const letsEncryptReponse = process.env.CERTBOT_RESPONSE;
    
    // Return the Let's Encrypt certbot response:
    app.get('/.well-known/acme-challenge/:content', function(req, res) {
      res.send(letsEncryptReponse);
    });
    

    Create the certificate files using certbot:

    1. Start certbot: sudo certbot certonly --manual
      Enter the site url when prompted (www.example.com)
      certbot will display a Challenge Response string in the format
      xxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyy
      LEAVE CERTBOT WAITING IN THIS STATE. Do not press enter yet or exit.
    2. Go to the Heroku dashboard and view app settings:
      https://dashboard.heroku.com/apps/your-heroku-app-name/settings
      Under Config Variables, click 'Reveal Config Vars'
      Edit the CERTBOT_RESPONSE var's value to match the Challenge Response from step a.
    3. Wait for the heroku app to restart.
    4. Test the setting by visiting http://www.example.com/.well-known/acme-challenge/whatever
      NOTE THE HTTP, NOT HTTPS
      It should display the Challenge Response string. If this happens, go on to the next step. If not, do whatever it takes to get that URL to return the CR string before proceeding, or you will need to repeat this entire process.
    5. Return to Certbot and press Enter to continue.
      If all goes as planned, certbot will tell you everything worked and display the location of the created certs. You'll use this location in the next step. Note that you might not be able to inspect the contents of the folder due to os permissions. If in doubt, sudo ls /etc/letsencrypt/live/www.example.com to see if the files exist.

    Update the Heroku instance to use the new certs:

    Run heroku certs:add if your site doesn't have a cert. If updating, run heroku certs:update.
    sudo heroku certs:update --app your-heroku-app-name /etc/letsencrypt/live/www.example.com/fullchain.pem /etc/letsencrypt/live/www.example.com/privkey.pem

    0 讨论(0)
  • 2020-12-28 09:09

    You can also validate your domain ownership to Let's Encrypt with DNS instead of HTTP.

    With certbot, specify DNS as your preferred challenge:

    sudo certbot certonly --manual --preferred-challenges dns
    

    After a couple of prompts, certbot will tell you to deply a DNS TXT record to validate your domain:

    Please deploy a DNS TXT record under the name
    _acme-challenge.www.codesy.io with the following value:
    
    CxYdvM...5WvXR0
    
    Once this is deployed,
    Press ENTER to continue
    

    Your domain registrar probably has its own docs for deploying a TXT record. Do that, and go back to certbot and press ENTER - Let's Encrypt will check the TXT record, sign the cert, and certbot will save it for you to upload to heroku.

    See my detailed blog post for more.

    0 讨论(0)
提交回复
热议问题