Instalación de un certificado SSL en Node.js

Después de emitir el certificado SSL, debe implementarse en el servidor web para habilitar las conexiones HTTPS. Tras la emisión, la Autoridad de Certificación enviará por correo electrónico los archivos del certificado; estos archivos también estarán disponibles para su descarga desde su cuenta TecnoWeb.

Este artículo cubrirá la implementación de certificados para Node.js y Express . Puede saltar a las secciones apropiadas de la tabla de contenido a continuación.

Actualmente, la versión LTS de Node.js es 10.15.0 y la última versión de Express es 4.16.4. Estas versiones se utilizarán y se hará referencia a lo largo de esta guía.

Importante

Esta guía también asume una comprensión básica de JavaScript, ya que Node.js es un entorno de tiempo de ejecución de JavaScript, así como conceptos básicos de Node.js y/o Express.

Requisitos Previos

La instalación del certificado SSL requiere los archivos de certificado proporcionados por la autoridad de certificación, así como la clave privada correspondiente para el certificado SSL.

Estos archivos deben cargarse en su servidor (o donde se encuentre la aplicación Node.js) antes de continuar con los siguientes pasos:

  • Certificado (generalmente un archivo .crt).
  • Paquete/cadena de CA (generalmente un archivo .ca-bundle).
  • Clave privada (generalmente un archivo .key).

La clave privada se genera antes de la activación del certificado, normalmente al mismo tiempo que la Solicitud de firma del certificado (CSR). Aunque tengas la clave privada, vale la pena comprobar que es la correcta comparándola con tu certificado SSL en esta herramienta .

Tenga en Cuenta

Si bien los archivos se pueden colocar en cualquier directorio, asegúrese de que el directorio que contiene la clave privada no sea público. La clave privada está destinada a almacenarse de forma segura en el servidor sin ningún acceso público.

Si no está seguro de dónde encontrar la clave privada, recomendamos revisar el servidor en donde se haya generado la solitud del SSL (CSR). En caso de que se pierda la clave privada o no haya forma de recuperarla, siempre puede volver a emitir su certificado con un nuevo CSR y un par de claves.

Importante

Al descargar archivos de certificado de su cuenta de TecnoWeb, también recibirá un archivo .cer o .crt (certificado PKCS#7). Este archivo no es la clave privada y no será necesario para la instalación.

Importación de archivos de certificado a su aplicación

Las capacidades SSL/TLS de Node.js se basan en la biblioteca OpenSSL, por lo que es flexible en la forma en que acepta archivos de certificados SSL. Los archivos se pueden leer como búfer o como texto (especificando la codificación UTF-8) utilizando el módulo FS (Sistema de archivos) , o simplemente se pueden proporcionar como cadenas con el código de certificado en formato PEM.

En la mayoría de los casos, se prefiere la forma más directa, que consiste en leer los archivos del certificado SSL del sistema de archivos, como se muestra a continuación:

const fs = require('fs');

const cert = fs.readFileSync('./path/to/the/cert.crt');
const ca = fs.readFileSync('./path/to/the/ca.crt');
const key = fs.readFileSync('./path/to/the/private.key');

Las rutas a estos archivos pueden ser relativas o absolutas. Siéntase libre de usar el módulo Ruta para crear las rutas en lugar de usar cadenas simples.

A continuación se muestra una configuración de ejemplo cuando se cargan los archivos:

En este ejemplo, el directorio ssl se creó específicamente para archivos relacionados con SSL y los archivos se leen desde él. Las constantes cert , ca y key contienen las representaciones respectivas del certificado SSL, el paquete de CA y los archivos de clave privada.

Importante

Se admiten varios certificados en un solo archivo (que normalmente se necesita para el archivo de paquete de CA) desde la versión 5.2.0 de Node.js. Si está utilizando una versión anterior de Node.js, deberá proporcionar una serie de certificados de CA como se muestra a continuación.

La versión de Node.js que ha instalado se puede verificar ejecutando node -v .

Si usa Node.js 5.2.0 o superior, puede omitir esta sección y pasar directamente a HTTPS en Node.js o HTTPS en Express .

En caso de que esté utilizando una versión de Node.js anterior a la 5.2.0, puede seguir las instrucciones a continuación para dividir el paquete de CA en certificados SSL separados.

Puede separar manualmente el archivo .ca-bundle en archivos de certificado separados usando cualquier editor de texto y cargarlos en una matriz. O bien, puede separar el archivo .ca-bundle dentro de su aplicación. A continuación se proporcionan ejemplos de ambos:

Uso de varios archivos de certificado de CA:

const ca = [
   fs.readFileSync('./ssl/CAcert1.crt'),
   fs.readFileSync('./ssl/CAcert2.crt')
];

Si separa los archivos manualmente, asegúrese de proporcionarlos en el mismo orden en que están en el archivo .ca-bundle.

Separando el archivo dentro de la aplicación:

const caBundle = fs.readFileSync('./ssl/example.ca-bundle', {encoding:'utf8'});
const ca = caBundle.split('-----END CERTIFICATE-----\r\n') .map(cert => cert +'-----END CERTIFICATE-----\r\n');
// We had to remove one extra item that is present due to
// an extra line at the end of the file.
// This may or may not be needed depending on the formatting
// of your .ca-bundle file.
ca.pop();
console.log(ca);

El resultado de ejecutar el código anterior debería ser una matriz de certificados como se muestra a continuación:

HTTPS en Node.js

Crear un servidor HTTPS

El servidor HTTPS se crea utilizando el método https.createServer() , que toma un objeto de opciones como primer argumento y la devolución de llamada del oyente de solicitud como segundo. El objeto de opciones debe contener las siguientes propiedades:

  • certificado – el certificado
  • ca – el paquete CA (cadena) proporcionado en un archivo o como una matriz
  • clave – la clave privada

Se pueden agregar opciones adicionales al objeto si es necesario.

Tenga en cuenta : si tiene el certificado en formato .pfx (PKCS#12), puede usarlo proporcionando un objeto de opciones con la propiedad pfx que contiene el archivo pfx y una propiedad de frase de contraseña si es necesario.

Como siempre, puede crear el objeto antes de llamar al método, o puede pasar un objeto anónimo con las propiedades requeridas, como se muestra a continuación:

let options = {
   cert: cert, // fs.readFileSync('./ssl/example.crt');
   ca: ca, // fs.readFileSync('./ssl/example.ca-bundle');
   key: key // fs.readFileSync('./ssl/example.key');
};

// also okay: https.createServer({cert, ca, key}, (req, res) => { ...
const httpsServer = https.createServer(options, (req, res) => {
   res.statusCode = 200;
   res.setHeader('Content-Type', 'text/html');
   res.end("<h1>HTTPS server running</h1>");
});

Al final, el código del servidor repetitivo debería verse así:

Aquí importamos los archivos de certificado a un objeto en las líneas 7-11, luego pasamos este objeto al método createServer en la línea 13 que crea el servidor HTTPS y finalmente llamamos al método listen() en la línea 19 para iniciar el servidor.

Asegúrese de reiniciar su aplicación Node.js si ya se estaba ejecutando para aplicar los cambios. Para iniciar la aplicación, simplemente puede ejecutar nodo .js en el directorio con su aplicación, donde .js es el archivo de inicio de su aplicación.

¡Esto completa la configuración! Puede utilizar la siguiente herramienta para verificar la instalación del certificado SSL ingresando el nombre de host y el puerto correspondientes que está utilizando: https://decoder.link

Redirigir a HTTPS

Para redirigir las solicitudes HTTP a HTTPS, también deberá configurar un servidor HTTP con el módulo HTTP .

En esencia, redirigir una solicitud HTTP a otra URL requiere dos cosas: el código de respuesta correspondiente (301 o 302) y el encabezado HTTP «Ubicación» con la URL que debe usarse en su lugar.

A continuación puede encontrar un ejemplo de cómo se puede configurar un servidor HTTP de este tipo:

const http = require('http');
const hostname = 'exampledomain.com';
const httpServer = http.createServer((req, res) => {
   res.statusCode = 301;
   res.setHeader('Location', `https://${hostname}${req.url}`);
   res.end(); // make sure to call send() or end() to send the response
});
httpServer.listen(80);

En el ejemplo anterior, también pasamos la URL solicitada de req.url

Si estaba sirviendo todo el contenido a través de HTTP antes y le gustaría cambiar a HTTPS y configurar la redirección, la forma más fácil debería ser simplemente cambiar su servidor HTTP a un servidor HTTPS y crear un servidor HTTP adicional que redirigirá las solicitudes.

A continuación, puede ver una solicitud realizada a dicho servidor HTTP con una URL personalizada:

And then correctly passed to the HTTPS server:

HTTPS on Express

Configuración de una aplicación HTTPS con Express

El uso de HTTPS con Express requiere la creación de un servidor HTTPS con el módulo HTTPS de Node.js. Su aplicación Express debe pasarse como parámetro al método https.createServer() :

const https = require('https');
const express = require('express');

// const httpsOptions = {cert, ca, key};

const app = express();
const httpsServer = https.createServer(httpsOptions, app);

// Your app code here

httpsServer.listen(443, 'exampledomain.com');

El parámetro httpsOptions es un objeto idéntico al utilizado en esta sección de la guía.

A continuación se muestra un ejemplo del código completo para crear una aplicación HTTPS Express:

En este punto, tendrá una aplicación Express a la que se puede acceder a través de HTTPS. Tenga en cuenta que la aplicación de ejemplo antes mencionada escuchará solo las solicitudes HTTPS en el puerto especificado. Si también necesita que su aplicación escuche las solicitudes HTTP, deberá configurar un servidor HTTP de manera similar usando http.createServer() desde el módulo HTTP .

Asegúrese de reiniciar su aplicación si ya se estaba ejecutando para aplicar los cambios. Para reiniciar la aplicación, simplemente puede ejecutar el nodo.jsen el directorio con su aplicación.

Esta herramienta se puede utilizar para comprobar la instalación del certificado SSL: https://decoder.link

Redirigir a HTTPS con Express

Para redirigir cualquier solicitud HTTP a HTTPS, también deberá tener un servidor HTTP en ejecución que pueda escuchar las solicitudes HTTP. El servidor debe crearse con el módulo HTTP y pasar su aplicación Express como parámetro de la misma manera que se pasó la aplicación para el servidor HTTPS.

Para crear una redirección a HTTPS, puede configurar una función de middleware que verificará si una solicitud se realiza a través de HTTP y la redirigirá a HTTPS si es así. A continuación se muestra un ejemplo de este tipo de middleware utilizando el método redirect() integrado de Express:

app.use((req, res, next) => {
   if(req.protocol === 'http') {
     res.redirect(301, `https://${req.headers.host}${req.url}`);
   }
   next();
});

A continuación se muestra un ejemplo de un código de aplicación Express completo que utiliza HTTPS y redirige todas las solicitudes HTTP a HTTPS:

En el código anterior, configuramos nuestra aplicación Express en la línea 16, luego creamos servidores HTTP y HTTPS en las líneas 17 y 18. Las líneas 20-25 crean el middleware que redirige las solicitudes HTTP a HTTPS. Por último, como ejemplo, configuramos un código de servidor en las líneas 30-35 e iniciamos los servidores HTTP y HTTPS llamando a sus métodos listen() en las líneas 37 y 38.

A continuación, puede ver las capturas de pantalla que ilustran las solicitudes HTTP tanto para archivos estáticos como para URL personalizadas, que se redirigen correctamente.

Archivos estáticos:

URL personalizadas: