¿Cómo puedo usar un certificado SSL de LetsEncrypt en mi aplicación Heroku Node Express?

Tengo una aplicación Node Express que se ejecuta en Heroku que quiero cifrar con un certificado SSL gratuito de LetsEncrypt. Sin embargo, los métodos que he visto requieren abrir los puertos 443 y 80 para permitir que el proceso ACME funcione.

Heroku solo te da un puerto, y no te deja elegir qué puerto. Entonces, ¿cómo puedo usar LetsEncrypt?

Pasé un montón de tiempo pensando en esto ayer. ¡La primera vez en mucho tiempo que no había respuestas en StackOverflow para algo que estaba tratando de hacer!

Actualizar:

Heroku ahora soporta LetsEncrypt de forma nativa! Así que esta solución ya no es necesaria.

Instrucciones aquí:

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

Para las aplicaciones nuevas, no tiene que hacer nada, está activado de forma predeterminada. Para las aplicaciones creadas antes del 21 de marzo de 2017, puede activarlo con este comando Heroku cli: heroku certs:auto:enable

Gracias @Spain Train


Fondo

Idealmente, LetsEncrypt permite un proceso de renovación de certificado automatizado. Es más difícil hacerlo en Heroku, por lo que esta respuesta describe cómo usar un proceso manual. Al usar una var de Heroku environment, podrá actualizar sus certificados manualmente de forma bastante sencilla y sin cambios de código.

El crédito por esta respuesta se debe principalmente a dos publicaciones de blog agradables: https://medium.com/@franxyzxyz/setting-up-free-https-with-heroku-ssl-and-lets-encrypt-80cf6eac108e#.67pjxutaw
y
https://medium.com/should-designers-code/how-to-set-up-ssl-with-lets-encrypt-on-heroku-for-free-266c185630db#.ldr9wrg2j

Hay un proyecto de GitHub que aparentemente soporta actualizaciones de certificados automatizados en Heroku. Actualizaré esta respuesta cuando la haya probado:
https://github.com/dmathieu/sabayon

Usando LetsEncrypt en Heroku con una aplicación Node Express

Prepare el servidor Express:

Agrega este middleware a tu aplicación Express. Asegúrese de agregarlo ANTES de cualquier middleware que redireccione http a https, ya que este punto final debe ser 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); }); 

Crea los archivos de certificado usando certbot:

  1. Iniciar certbot: sudo certbot certonly --manual
    Introduzca la URL del sitio cuando se le solicite (www.example.com)
    certbot mostrará una cadena de Respuesta de desafío en el formato
    xxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyy
    DEJAR CERTBOT ESPERANDO EN ESTE ESTADO. No presione todavía entrar ni salir.
  2. Ve al panel de Heroku y ve la configuración de la aplicación:
    https://dashboard.heroku.com/apps/your-heroku-app-name/settings
    Bajo Config Variables, haga clic en ‘Revelar Config Vars’
    Edite el valor de la var CERTBOT_RESPONSE para que coincida con la Respuesta de desafío del paso a.
  3. Espera a que la aplicación heroku se reinicie.
  4. Pruebe la configuración visitando http://www.example.com/.well-known/acme-challenge/whatever
    TENGA EN CUENTA EL HTTP, NO HTTPS
    Debe mostrar la cadena Respuesta de desafío. Si esto sucede, continúe con el siguiente paso. De lo contrario, haga lo que sea necesario para que la URL devuelva la cadena CR antes de continuar, o tendrá que repetir todo el proceso.
  5. Regresa a Certbot y presiona Enter para continuar.
    Si todo sale según lo planeado, certbot le dirá todo lo que funcionó y mostrará la ubicación de los certificados creados. Utilizará esta ubicación en el siguiente paso. Tenga en cuenta que es posible que no pueda inspeccionar el contenido de la carpeta debido a los permisos del sistema operativo. En caso de duda, sudo ls /etc/letsencrypt/live/www.example.com para ver si existen los archivos.

Actualice la instancia de Heroku para usar los nuevos certificados:

Ejecute heroku certs:add si su sitio no tiene un certificado. Si está actualizando, ejecute 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

También puede validar la propiedad de su dominio a Let’s Encrypt con DNS en lugar de HTTP.

Con certbot , especifique DNS como su desafío preferido:

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

Después de un par de indicaciones, certbot le indicará que aplique un registro TXT de DNS para validar su dominio:

 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 

Su registrador de dominios probablemente tenga sus propios documentos para implementar un registro TXT. Haga eso, y vuelva a certbot y presione ENTER. Let’s Encrypt verificará el registro TXT, firmará el certbot y certbot lo guardará para que lo cargue en heroku.

Ver mi blog detallado para más .