| 27. März 2026

Eine IBM-ELM-Plattform (Engineering Lifecycle Management) hinter einem Reverse Proxy bereitzustellen, ist ein unverzichtbarer Schritt für jedes Produktiv-Deployment. Damit lassen sich Zugriffe zentralisieren, SSL-Zertifikate an einer einzigen Stelle verwalten und die öffentliche URL unabhängig von der internen Infrastruktur halten.

Dieser Leitfaden behandelt zwei Implementierungen: Nginx (die weit verbreitete Open-Source-Lösung) und IBM HTTP Server (IHS) (der von IBM ausgelieferte, auf Apache basierende Server, empfohlen für ELM). Die hier gezeigten Konfigurationen wurden produktiv auf Jazz-Umgebungen mit mehreren Servern validiert.


Zielarchitektur

Internet
    │
    ▼
[Reverse Proxy: 443]           ← einzige öffentliche URL
    │
    ├──→ jazz1:9443  (JTS, RM)
    ├──→ jazz2:9443  (CCM, QM)
    └──→ jazz3:9443  (GC, RS)

Der Reverse Proxy ist der einzige zum Internet exponierte Punkt. Die internen Jazz-Server kommunizieren untereinander über ihre internen URLs (Port 9443), und der Proxy übernimmt die gesamte Anpassung.


Die 5 zu lösenden technischen Herausforderungen

1. Umschreiben der URLs in Jazz-Antworten

Jazz bettet eigene URLs in die HTTP-Antworten ein (Location-Header, HTML-Inhalt, JSON, JavaScript). Zeigen diese URLs auf jazz1:9443, während der Benutzer über jazz.meinedomain.net zugreift, bricht alles zusammen.

Nginx-Lösung — die Direktive sub_filter:

sub_filter "https://jazz1.syncheo.tech:9443" "https://jazz1.syncheo.tech";
sub_filter ':9443/' '/';
sub_filter_once off;

⚠️ Nginx-Falle: sub_filter interpoliert keine $host-Variablen. Sie müssen einen map{}-Block verwenden, um statische Variablen pro Hostname zu erzeugen.

IHS-Lösung — die Direktive ProxyHTMLURLMap:

ProxyHTMLURLMap https://jazz1\.kse\.ksegroup\.net:9443  https://jazz.syncheo.tech  Riex
ProxyHTMLURLMap https://jazz2\.kse\.ksegroup\.net:9443  https://jazz.syncheo.tech  Riex
ProxyHTMLURLMap https://jazz3\.kse\.ksegroup\.net:9443  https://jazz.syncheo.tech  Riex

ProxyHTMLURLMap ist leistungsfähiger als sub_filter: Es parst das HTML tatsächlich und versteht die Struktur der Attribute (href, src, action…).


2. Dekomprimierung der Antworten vor dem Umschreiben

Jazz komprimiert seine Antworten mit gzip. Ein Proxy kann komprimierten Text nicht umschreiben.

Nginx-Lösung:

proxy_set_header Accept-Encoding "";

Sie weisen Jazz an, nicht zu komprimieren, indem Sie den Header Accept-Encoding entfernen.

IHS-Lösung:

RequestHeader unset Accept-Encoding
SetOutputFilter INFLATE;PROXY-HTML

IHS bietet eine elegantere Option: INFLATE dekomprimiert die Antwort im laufenden Betrieb, bevor PROXY-HTML sie umschreibt, und komprimiert sie anschließend wieder für den Client.


3. Umschreiben der Redirect-Header

Wenn Jazz eine HTTP-Weiterleitung ausgibt (Location: https://jazz1:9443/jts/...), würde der Browser der internen URL folgen. Diese Header müssen abgefangen werden.

Nginx:

proxy_redirect https://127.0.0.1:9443/  /;
proxy_redirect ~*^https://jazz[1-3]\.kse\.ksegroup\.net:9443(/.*)$  $1;

IHS:

ProxyPassReverse / https://127.0.0.1:9443/
ProxyPassReverse / https://jazz1.syncheo.tech:9443/
ProxyPassReverse / https://jazz2.syncheo.tech:9443/
ProxyPassReverse / https://jazz3.syncheo.tech:9443/

4. CORS für Jazz-Anwendungen

Jazz verwendet Cross-Origin-Anfragen (OSLC, EWM-Widgets, REST-API). Der Header Access-Control-Allow-Origin unterstützt den Platzhalter * nicht, wenn credentials: true erforderlich ist — es wird ein dynamischer Wert benötigt.

Nginx-Falleif()-Blöcke erben keine add_header-Direktiven vom übergeordneten Kontext. Sie müssen alle CORS-Header innerhalb des OPTIONS-Blocks erneut deklarieren:

if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin'      '$cors_origin' always;
    add_header 'Access-Control-Allow-Methods'     'GET, POST, OPTIONS, PUT, DELETE, PATCH' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Headers'     '...' always;
    add_header 'Access-Control-Max-Age'           1728000;
    return 204;
}

IHS löst dies sauber mit <If>, das den übergeordneten Kontext korrekt erbt:

<If "%{REQUEST_METHOD} == 'OPTIONS'">
    Header always set Access-Control-Max-Age "1728000"
    Return 204
</If>

5. SSL zum Jazz-Backend

Jazz-Server verwenden intern häufig selbstsignierte Zertifikate.

Nginx — implizit deaktiviert über proxy_pass https:// (akzeptiert standardmäßig alles).

IHS — explizite Deaktivierung erforderlich:

SSLProxyEngine          on
SSLProxyVerify          none
SSLProxyCheckPeerCN     off
SSLProxyCheckPeerName   off
SSLProxyCheckPeerExpire off

💡 Setzen Sie SSLProxyVerify require, wenn die Backends über gültige Zertifikate verfügen — die bessere Sicherheitspraxis.


Leitfaden zur Server-Umbenennung

Hier sind die genauen Stellen, die Sie ändern müssen, wenn Sie Ihre Jazz-Server umbenennen.

Fall 1 — Änderung des öffentlichen Domainnamens

Beispiel: jazz.syncheo.techjazz.meinunternehmen.com

DateiDirektiveAlter WertNeuer Wert
nginx.confserver_namejazz[1-3].kse...jazz[1-3].meinunternehmen.com
nginx.confmap $host $internal_urlSchlüssel jazz[1-3]...jazz[1-3]...
nginx.confmap $host $external_urlWerte jazz[1-3]...jazz[1-3]...
nginx.confif ($http_origin ~*Regex jazz[1-3]...Regex jazz[1-3]...
ihs.confServerNamejazz.kse...jazz.meinunternehmen.com
ihs.confProxyHTMLURLMap (×3)jazz[1-3]...jazz[1-3]...
ihs.confSetEnvIf OriginRegex jazz...Regex jazz...
ihs.confSSLCertificateFilejazz...crtjazz...crt

⚠️ Nicht vergessen: Die Jazz Public URIs werden bei der Installation in der JTS-Administrationsoberfläche konfiguriert (https://ihr-jts/jts/admin). Wenn Sie den öffentlichen Namen ändern, müssen Sie sie auch in Jazz aktualisieren — ein sensibler Vorgang, der einen Neustart der Dienste erfordert.


Fall 2 — Umbenennung eines internen Backend-Servers

Beispiel: jazz1jazz-prod-jts

In nginx.conf die map{}-Blöcke anpassen:

map $host $internal_url {
    jazz-prod-jts.syncheo.tech  "https://jazz-prod-jts.syncheo.tech:9443";
    # ...
}

In ihs.conf die Direktiven ProxyHTMLURLMap und ProxyPassReverse anpassen:

ProxyPassReverse / https://jazz-prod-jts.syncheo.tech:9443/
ProxyHTMLURLMap https://jazz-prod-jts\.kse\.ksegroup\.net:9443  https://jazz.syncheo.tech  Riex

Fall 3 — Migration auf getrennte Server (Scale-out)

Wenn JTS/RM, CCM/QM und GC/RS jeweils auf ihre eigene Maschine umziehen:

Nginx:

location ~ ^/(jts|rm) {
    proxy_pass https://10.0.0.1:9443;
    # ... dieselben sub_filter-, CORS- usw. Direktiven
}

location ~ ^/(ccm|qm) {
    proxy_pass https://10.0.0.2:9443;
}

location ~ ^/(gc|rs) {
    proxy_pass https://10.0.0.3:9443;
}

IHS:

<Location ~ "^/(jts|rm)">
    ProxyPass        https://10.0.0.1:9443
    ProxyPassReverse https://10.0.0.1:9443/
    # ... dieselben ProxyHTMLURLMap-, CORS- usw. Direktiven
</Location>

Validierungs-Checkliste nach der Konfiguration

Prüfen Sie nach jeder Änderung diese Punkte der Reihe nach:

1. SSL-Test:

openssl s_client -connect jazz.syncheo.tech:443 -servername jazz.syncheo.tech

2. Test der HTTP→HTTPS-Weiterleitung:

curl -I http://jazz.syncheo.tech
# Erwartet: HTTP/1.1 301 Moved Permanently + Location: https://...

3. Test des JTS-Zugriffs:

curl -k https://jazz.syncheo.tech/jts/auth/authrequired
# Erwartet: 200 oder 401 (kein Proxy-Fehler)

4. CORS-Preflight-Test:

curl -I -X OPTIONS https://jazz.syncheo.tech/jts/ \
  -H "Origin: https://jazz.syncheo.tech" \
  -H "Access-Control-Request-Method: POST"
# Erwartet: 204 + Access-Control-Allow-Origin vorhanden

5. Überprüfung der SANs des Zertifikats:

openssl x509 -in /etc/nginx/ssl/jazz.crt -text -noout | grep -A5 "Subject Alternative"

Nginx vs. IHS: Was wählen?

KriteriumNginxIBM HTTP Server
IBM-EmpfehlungInoffiziell✅ Offiziell
HTML-Umschreibungsub_filter (textbasiert)mod_proxy_html (HTML-Parsing)
CORS-if()-Handhabung⚠️ Header nicht vererbt✅ Korrekte Vererbung
Transparentes gzipDeaktivierung upstreamDekomprimierung im laufenden Betrieb
Performance✅ AusgezeichnetGut
CommunityGroßIBM Support

Für eine produktive IBM-ELM-Umgebung wird IHS empfohlen — die native Handhabung von mod_proxy_html vermeidet die Fallstricke von sub_filter, und der IBM-Support deckt den gesamten Stack ab.


Fazit

Die Konfiguration eines Reverse Proxy vor IBM Jazz ist vor allem wegen dreier Punkte komplex: dem Umschreiben interner URLs in den Antworten, der Handhabung von CORS mit Anmeldedaten und der SSL-Entschlüsselung zu den Backends. Die hier vorgestellten Konfigurationen haben sich produktiv bewährt und decken alle drei Aspekte ab.

Bei Zweifeln zu einer Migration oder Umbenennung kontaktieren Sie gerne das Syncheo-Team — genau diese Art von Einsatz führen wir täglich für unsere IBM-ELM-Kunden durch.