Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source

NGINX | 26 de septiembre de 2023

En el mundo de los servidores web de alto rendimiento, NGINX es una opción muy popular porque su arquitectura ligera y eficiente le permite gestionar grandes volúmenes de tráfico. Con la incorporación de la función de diccionario compartido como parte del módulo JavaScript de NGINX (njs), las capacidades de rendimiento de NGINX alcanzan un nuevo nivel.

En esta entrada del blog, analizamos la funcionalidad y las ventajas del diccionario compartido de njs y mostramos cómo configurar NGINX Open Source sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.

Conceptos básicos y ventajas del diccionario compartido

La nueva directiva js_shared_dict_zone permite a los usuarios de NGINX Open Source habilitar zonas de memoria compartida para intercambiar datos de forma eficiente entre los procesos de trabajo. Estas zonas de memoria compartida funcionan como diccionarios de pares clave-valor y almacenan ajustes de configuración dinámicos a los que se puede acceder y que se pueden modificar en tiempo real.

Entre las principales ventajas del diccionario compartido se incluyen:

  • Sobrecarga mínima y facilidad de uso: Al estar integrado directamente en njs, resulta fácil de configurar y utilizar gracias a una API intuitiva y una implementación sencilla. También permite simplificar la gestión y el intercambio de datos entre los procesos de trabajo.
  • Ligero y eficiente – Se integra perfectamente con NGINX y aprovecha su modelo de E/S no bloqueante y basado en eventos. Este enfoque reduce el uso de memoria y mejora la concurrencia, lo que permite a NGINX gestionar de forma eficiente numerosas conexiones simultáneas.
  • Escalabilidad – Aprovecha la capacidad de NGINX para escalar horizontalmente entre varios procesos de trabajo, lo que permite compartir y sincronizar datos entre dichos procesos sin necesidad de complejos mecanismos de comunicación entre procesos. La configuración del tiempo de vida (TTL) permite gestionar los registros de las entradas del diccionario compartido eliminándolos de la zona por inactividad. El parámetro evict elimina el par clave-valor más antiguo para dejar espacio a nuevas entradas.

Rotación de SSL con el diccionario compartido

Uno de los casos de uso más relevantes del diccionario compartido es la rotación de SSL/TLS. Al utilizar js_shared_dict_zone, no es necesario reiniciar NGINX cuando se actualiza un certificado o una clave SSL/TLS. Además, proporciona una API similar a REST para gestionar certificados en NGINX.

A continuación se muestra un ejemplo del archivo de configuración de NGINX que configura el servidor HTTPS con las directivas js_set y ssl_certificate. Los controladores de JavaScript utilizan js_set para leer el certificado SSL/TLS o la clave desde un archivo.

Este fragmento de configuración utiliza el diccionario compartido para almacenar certificados y claves en la memoria compartida a modo de caché. Si la clave no está presente, lee el certificado o la clave del disco y los guarda en la caché.

También puede exponer una ubicación que borre la caché. Una vez actualizados los archivos del disco (por ejemplo, al renovar los certificados y las claves), el diccionario compartido fuerza su lectura desde el disco. Este ajuste permite rotar los certificados y las claves sin necesidad de reiniciar el proceso de NGINX.

http {     ...
    js_shared_dict_zone zone=kv:1m;
   
    server {
    …
     # Sets an njs function for the variable. Returns a value of cert/key
      js_set $dynamic_ssl_cert main.js_cert;
      js_set $dynamic_ssl_key main.js_key;
   
      # use variable's data
      ssl_certificate data:$dynamic_ssl_cert;
      ssl_certificate_key data:$dynamic_ssl_key;
     
     # a location to clear cache 
   location = /clear {
      js_content main.clear_cache;
      # allow 127.0.0.1;
      # deny all;
    }
  ...
  }

Y aquí está la implementación en JavaScript para la rotación de certificados y claves SSL/TLS mediante «js_shared_dict_zone»:

function js_cert(r) {  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.cert.pem');
  } else {
    return '';
  }
}

function js_key(r) {
  if (r.variables['ssl_server_name']) {
    return read_cert_or_key(r, '.key.pem');
  } else {
    return '';
  }
}
/** 
   * Retrieves the key/cert value from Shared memory or fallback to disk
   */
  function read_cert_or_key(r, fileExtension) {
    let data = '';
    let path = '';
    const zone = 'kv';
    let certName = r.variables.ssl_server_name;
    let prefix =  '/etc/nginx/certs/';
    path = prefix + certName + fileExtension;
    r.log('Resolving ${path}');
    const key = ['certs', path].join(':');
    const cache = zone && ngx.shared && ngx.shared[zone];
   
    if (cache) {
    data = cache.get(key) || '';
    if (data) {
      r.log(`Read ${key} from cache`);
      return data;
    }
  }
  try {
    data = fs.readFileSync(path, 'utf8');
    r.log('Read from cache');
  } catch (e) {
    data = '';
    r.log(`Error reading from file:${path}. Error=${e}`);
  }
  if (cache && data) {
    try {
      cache.set(key, data);
      r.log('Persisted in cache');
    } catch (e) {
      const errMsg = `Error writing to shared dict zone: ${zone}. Error=${e}`;
      r.log(errMsg);
    }
  }
  return data
}

Al enviar la solicitud /clear, la caché se invalida y NGINX carga el certificado o la clave SSL/TLS desde el disco en el siguiente protocolo de enlace SSL/TLS. Además, puede implementar un elemento js_content que obtenga un certificado o una clave SSL/TLS de la solicitud y que, al mismo tiempo, conserve y actualice la caché.

El código completo de este ejemplo se encuentra en el repositorio de njs en GitHub.

Empieza hoy mismo

La función de diccionario compartido es una potente herramienta para la programabilidad de su aplicación que ofrece importantes ventajas en cuanto a optimización y escalabilidad. Al aprovechar las capacidades de js_shared_dict_zone, puede acceder a nuevas oportunidades de crecimiento y gestionar de forma eficiente el aumento de la demanda de tráfico.

¿Todo listo para potenciar tu implementación de NGINX con js_shared_dict_zone? Puedes actualizar tu implementación de NGINX con js_shared_dict_zone para habilitar nuevos casos de uso y obtener más información sobre esta función en nuestra documentación. Además, puedes consultar un ejemplo completo de una función de diccionario compartido en el recientemente presentado proyecto njs-acme, que permite que el entorno de ejecución del módulo njs funcione con proveedores de ACME.

Si te interesa empezar a utilizar NGINX Open Source y tienes alguna pregunta, únete al Slack de la comunidad de NGINX : ¡preséntate y conoce a esta comunidad de usuarios de NGINX!


Compartir
Etiquetas: F5 NGINX, Tech

Artículos relacionados del blog

Únete a F5 NGINX en AppWorld 2024
NGINX | 04/01/2024

Únete a F5 NGINX en AppWorld 2024

Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
NGINX | 26/09/2023

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source

La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.

Exposición de APIs en Kubernetes
NGINX | 10/03/2022

Exposición de APIs en Kubernetes

La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
NGINX | 23/08/2021

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto

Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.

Presentamos NGINX Plus R22
NGINX | 09/06/2020

Presentamos NGINX Plus R22

NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.

Presentamos NGINX Plus R17
NGINX | 11/12/2018

Presentamos NGINX Plus R17

NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.