SSL/TLS-Zertifikatsrotation ohne Neustarts in NGINX Open Source

NGINX | 26. September 2023

In der Welt der Hochleistungs-Webserver ist NGINX eine beliebte Wahl, da seine schlanke und effiziente Architektur die Verarbeitung großer Datenverkehrsmengen ermöglicht. Mit der Einführung der Funktion „Shared Dictionary“ als Teil des NGINX JavaScript module (njs) erreicht die Leistungsfähigkeit von NGINX ein neues Niveau.

In diesem Blogbeitrag untersuchen wir die Funktionen und Vorteile des gemeinsam genutzten njs-Wörterbuchs und zeigen, wie sich NGINX Open Source so einrichten lässt, dass beim Austausch von SSL/TLS-Zertifikaten kein Neustart erforderlich ist.

Grundlagen und Vorteile des Shared Dictionary

Die neue js_shared_dict_zone-Direktive ermöglicht es Benutzern von NGINX Open Source, gemeinsam genutzte Speicherbereiche für einen effizienten Datenaustausch zwischen Worker-Prozessen zu aktivieren. Diese gemeinsam genutzten Speicherbereiche fungieren als Schlüssel-Wert-Wörterbücher, in denen dynamische Konfigurationseinstellungen gespeichert werden, auf die in Echtzeit zugegriffen werden kann und die in Echtzeit geändert werden können.

Zu den wichtigsten Vorteilen des gemeinsam genutzten Wörterbuchs gehören:

  • Minimaler Overhead und einfache Bedienung – Da die Funktion direkt in njs integriert ist, lässt sie sich dank einer intuitiven API und unkomplizierten Implementierung einfach bereitstellen und nutzen. Zudem vereinfacht sie die Verwaltung und gemeinsame Nutzung von Daten durch Worker-Prozesse.
  • Ressourcenschonend und effizient – Lässt sich nahtlos in NGINX integrieren und nutzt dessen ereignisgesteuertes, nicht blockierendes E/A-Modell. Dieser Ansatz reduziert den Speicherverbrauch und verbessert die Parallelität, sodass NGINX viele gleichzeitige Verbindungen effizient verarbeiten kann.
  • Skalierbarkeit – Nutzt die Fähigkeit von NGINX zur horizontalen Skalierung über mehrere Worker-Prozesse hinweg, sodass Sie Daten zwischen diesen Prozessen teilen und synchronisieren können, ohne komplexe Mechanismen für die Interprozesskommunikation zu benötigen. Mit der Time-to-Live-Einstellung (TTL) können Sie Datensätze in Einträgen des gemeinsam genutzten Wörterbuchs verwalten, indem sie bei Inaktivität aus der Zone entfernt werden. Der Parameter evict entfernt das älteste Schlüssel-Wert-Paar, um Platz für neue Einträge zu schaffen.

SSL-Rotation mit dem gemeinsam genutzten Wörterbuch

Einer der wichtigsten Anwendungsfälle für das Shared Dictionary ist die Rotation von SSL/TLS-Zertifikaten. Bei Verwendung von js_shared_dict_zone muss NGINX bei einer Aktualisierung eines SSL/TLS-Zertifikats oder -Schlüssels nicht neu gestartet werden. Darüber hinaus steht Ihnen damit eine REST-ähnliche API zur Verwaltung von Zertifikaten auf NGINX zur Verfügung.

Nachfolgend finden Sie ein Beispiel für eine NGINX-Konfigurationsdatei, die den HTTPS-Server mit den Direktiven „js_set“ und „ssl_certificate“ einrichtet. Die JavaScript-Handler verwenden „js_set“, um das SSL/TLS-Zertifikat oder den Schlüssel aus einer Datei zu lesen.

Dieses Konfigurationsfragment verwendet das gemeinsam genutzte Dictionary, um Zertifikate und Schlüssel im gemeinsam genutzten Speicher zwischenzuspeichern. Ist der Schlüssel nicht vorhanden, wird das Zertifikat bzw. der Schlüssel vom Datenträger gelesen und im Cache abgelegt.

Sie können auch eine Location bereitstellen, über die sich der Cache leeren lässt. Sobald die Dateien auf dem Datenträger aktualisiert wurden (z. B. nach der Erneuerung der Zertifikate und Schlüssel), erzwingt das Shared Dictionary das erneute Einlesen vom Datenträger. Dadurch können Zertifikate und Schlüssel ausgetauscht werden, ohne den NGINX-Prozess neu starten zu müssen.

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;
    }
  ...
  }

Und hier ist die JavaScript-Implementierung für die Rotation von SSL/TLS-Zertifikaten und -Schlüsseln mithilfe von 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
}

Durch Senden der Anfrage /clear wird der Cache invalidiert, und NGINX lädt beim nächsten SSL/TLS-Handshake das SSL/TLS-Zertifikat bzw. den Schlüssel vom Datenträger. Darüber hinaus können Sie eine js_content-Funktion implementieren, die ein SSL/TLS-Zertifikat bzw. einen Schlüssel aus der Anfrage übernimmt und gleichzeitig im Cache speichert bzw. diesen aktualisiert.

Den vollständigen Code für dieses Beispiel finden Sie im njs-GitHub-Repository.

Legen Sie noch heute los

Die Shared-Dictionary-Funktion ist ein leistungsstarkes Werkzeug für die Programmierbarkeit Ihrer Anwendung und bietet erhebliche Vorteile bei der Optimierung und Skalierbarkeit. Durch die Nutzung der Funktionen von js_shared_dict_zone können Sie neue Wachstumschancen erschließen und steigende Datenverkehrsanforderungen effizient bewältigen.

Sind Sie bereit, Ihre NGINX-Bereitstellung mit js_shared_dict_zone auf die nächste Stufe zu heben? Mit js_shared_dict_zone können Sie Ihre NGINX-Bereitstellung erweitern, neue Anwendungsfälle erschließen und in unserer Dokumentation mehr über diese Funktion erfahren. Ein vollständiges Beispiel für eine Shared-Dictionary-Funktion finden Sie außerdem im kürzlich vorgestellten njs-acme-Projekt, das es der Laufzeitumgebung des njs-Moduls ermöglicht, mit ACME-Anbietern zusammenzuarbeiten.

Wenn Sie mit NGINX Open Source loslegen möchten und Fragen haben, treten Sie dem NGINX Community Slack bei – stellen Sie sich vor und lernen Sie diese Community von NGINX-Benutzern kennen!


Teilen
Schlagwörter: F5 NGINX, Tech

Ähnliche Blogbeiträge

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
NGINX | 23.08.2022

Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln

Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
NGINX | 08.09.2021

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen

Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
NGINX | 16.08.2021

Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet

Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
NGINX | 12.12.2018

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77

Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.

Ankündigung von NGINX Plus R16
NGINX | 05.09.2018

Ankündigung von NGINX Plus R16

NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
NGINX | 13.10.2016

5 Gründe für den Umstieg auf softwarebasiertes Load Balancing

Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.