Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
kafka-keycloak-oauth — Apache Kafka 4.1.0 (KRaft) mit Keycloak OAuth2-Authentifizierung unter Verwendung von Strimzi – umgeht die URL-Allowlist-Einschränkung von CVE-2025-27817 | Kitploit
Tools/GitHubGitHub/oriolrius/kafka-keycloak-oauth
Cloud-Infrastruktur-SicherheitSchwachstellenanalyseKonfigurationsprüfungDevSecOpsAuthentifizierungLernen & Bildung
GitHuboriolrius/kafka-keycloak-oauth

kafka-keycloak-oauth

Apache Kafka 4.1.0 (KRaft) mit Keycloak OAuth2-Authentifizierung unter Verwendung von Strimzi – umgeht die URL-Allowlist-Einschränkung von CVE-2025-27817

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Repository anzeigen
5310vor 11 MonatenNoch nicht geprüft
Teilen

Apache Kafka 4.1.0 mit Keycloak OAuth2-Authentifizierung

Produktionsreifes Apache Kafka 4.1.0 (KRaft-Modus) mit Keycloak 26.1.1 OAuth2/OIDC-Authentifizierung unter Verwendung des Strimzi-Kafka-Images.

Warum dieses Projekt vs. kafka-oauth-keycloak-tls-demo

Dies ist eine Weiterentwicklung des vorherigen POC mit erheblichen Verbesserungen:

  • Strimzi OAuth 0.17.0 (statt 1.0.0) – stabile Produktionsversion, gebündelt im Strimzi-Kafka-0.48.0-Image
  • Kein benutzerdefinierter Docker-Build erforderlich – verwendet das offizielle Strimzi-Image mit vorinstalliertem OAuth, eliminiert die Dockerfile-Komplexität
  • CVE-2025-27817-Bewusstsein – dokumentiert die URL-Allowlist-Einschränkung und warum Strimzi OAuth diese umgeht
  • Vereinfachte Architektur – einzelner KRaft-Kombinationsmodus (Broker+Controller), keine Split-Architektur
  • librdkafka-Client-Fokus – getestet mit confluent-kafka-python (funktioniert ohne URL-Allowlist-Probleme), nicht mit nativen Java-Clients
  • Umfassende technische Dokumentation – Produktions-Checkliste, Fehlerbehebung, Leistungsoptimierung, Principal-Mapping-Details
  • Saubereres Zertifikatsmanagement – enthaltene Beispielzertifikate für sofortiges Testen
  • Automatisierte Keycloak-Einrichtung – skriptierte Realm-/Client-/Mapper-Erstellung mit Audience-Konfiguration
  • Funktionierende Python-Testsuite – validiert die OAuth-End-to-End-Nachrichtenzustellung
  • Explizite Issuer-URL-Behandlung – dokumentiert die Dualität von interner vs. externer URL für Token-Endpunkt vs. Issuer-Validierung
  • Architektur

    • Kafka-Distribution: Strimzi-Kafka-Image 0.48.0 (enthält Apache Kafka 4.1.0 + Strimzi OAuth 0.17.0 vorinstalliert)
    • Kafka-Version: Apache Kafka 4.1.0 (KRaft-Kombination aus Broker+Controller)
    • OAuth-Bibliothek: Strimzi Kafka OAuth 0.17.0 (im Image gebündelt, umgeht die CVE-2025-27817-URL-Allowlist-Einschränkung)
    • OAuth-Anbieter: Keycloak 26.1.1
    • Sicherheit: SASL_SSL (OAuth) für externe Clients, PLAINTEXT für Inter-Broker, SSL mit selbstsignierter CA

    CVE-2025-27817-Kontext

    Apache Kafka 4.0.0+ führte eine URL-Allowlist (org.apache.kafka.sasl.oauthbearer.allowed.urls) als JVM-Systemeigenschaft ein, um die SSRF-/beliebige-Dateilesen-Schwachstelle zu beheben. Dies bricht die Standard-OAuth-Nutzung in nativen Apache-Kafka-Clients.

    Lösung: Die Strimzi-Kafka-OAuth-Bibliothek implementiert diese Einschränkung nicht und ermöglicht so die OAuth-Funktionalität mit Kafka 4.1.0.

    Voraussetzungen

    • Docker Compose
    • Python 3.x mit uv (für Tests)
    • OpenSSL (für die Zertifikatserstellung)

    Schnellstart

    root@kitploit:~
    # SSL-Zertifikate generieren
    cd kafka-security
    ./generate-certs.sh
    cd ..
    
    # Dienste starten
    docker compose up -d
    
    # Keycloak verifizieren
    curl http://localhost:8080/health/ready
    
    # Keycloak-Realm und Clients einrichten
    ./scripts/setup-keycloak.sh
    
    # OAuth-Producer testen
    source ~/.venv/bin/activate
    uv pip install confluent-kafka
    python tests/quick_test.py
    

    Netzwerktopologie

    root@kitploit:~
    keycloak:8080 (HTTP) ←→ kafka-broker:9093 (SASL_SSL/OAuth)
                          ↔ kafka-broker:19092 (PLAINTEXT/Inter-Broker)
                          ↔ kafka-broker:29093 (PLAINTEXT/KRaft-Controller)
    

    SSL-Konfiguration

    CA-Struktur

    • Root-CA: kafka-security/ca-cert + ca-key
    • Broker-Keystore: kafka-security/broker/kafka.server.keystore.jks (enthält Serverzertifikat + privaten Schlüssel)
    • Broker-Truststore: kafka-security/broker/kafka.server.truststore.jks (enthält CA-Zertifikat)
    • Passwort: changeit (alle Keystores/Truststores)

    Zertifikatsdetails

    root@kitploit:~
    # Broker-Zertifikat
    CN=kafka-broker
    SAN=DNS:kafka-broker,DNS:localhost,IP:127.0.0.1
    
    # Gültigkeit: 3650 Tage
    # Schlüsselalgorithmus: RSA 2048-Bit
    # Signaturalgorithmus: SHA256withRSA
    

    Keycloak-OAuth-Konfiguration

    Realm: kafka-realm

    Clients

    kafka-broker (vertraulich)

    • Client-ID: kafka-broker
    • Client-Secret: Automatisch generiert von setup-keycloak.sh
    • Zweck: OAuth-Authentifizierung zwischen Brokern
    • Mapper:
      • Audience-Mapper: fügt kafka-broker zum JWT-aud-Anspruch hinzu
      • Benutzername-Mapper: enthält preferred_username im Token

    kafka-producer (vertraulich)

    • Client-ID: kafka-producer
    • Client-Secret: Automatisch generiert
    • Zweck: Externe Producer-Clients
    • Grant: client_credentials
    • Mapper: Wie bei kafka-broker

    kafka-consumer (vertraulich)

    • Client-ID: kafka-consumer
    • Client-Secret: Automatisch generiert
    • Zweck: Externe Consumer-Clients
    • Grant: client_credentials
    • Mapper: Wie bei kafka-broker

    Token-Endpunkt

    root@kitploit:~
    POST http://localhost:8080/realms/kafka-realm/protocol/openid-connect/token
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=client_credentials
    &client_id=kafka-producer
    &client_secret=<secret>
    &scope=profile email
    

    JWT-Token-Struktur

    root@kitploit:~
    {
      "aud": ["kafka-broker", "account"],
      "iss": "http://localhost:8080/realms/kafka-realm",
      "azp": "kafka-producer",
      "preferred_username": "service-account-kafka-producer",
      "scope": "profile email"
    }
    

    Kafka-Konfiguration

    KRaft-Modus (kraft-config.properties)

    root@kitploit:~
    # Knotenidentität
    node.id=1
    process.roles=broker,controller
    controller.quorum.voters=1@kafka-broker:29093
    
    # Listener
    listeners=SASL_SSL://0.0.0.0:9093,PLAINTEXT://0.0.0.0:19092,CONTROLLER://0.0.0.0:29093
    advertised.listeners=SASL_SSL://localhost:9093,PLAINTEXT://kafka-broker:19092
    listener.security.protocol.map=SASL_SSL:SASL_SSL,PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
    inter.broker.listener.name=PLAINTEXT
    controller.listener.names=CONTROLLER
    
    # SASL-Mechanismus
    sasl.enabled.mechanisms=OAUTHBEARER
    
    # Strimzi-OAuth-Handler (pro Listener für SASL_SSL)
    listener.name.sasl_ssl.oauthbearer.sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
    listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class=io.strimzi.kafka.oauth.server.JaasServerOauthValidatorCallbackHandler
    
    # OAuth-Konfiguration über JAAS
    listener.name.sasl_ssl.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.client.id="kafka-broker" \
      oauth.client.secret="<secret>" \
      oauth.token.endpoint.uri="http://keycloak:8080/realms/kafka-realm/protocol/openid-connect/token" \
      oauth.valid.issuer.uri="http://localhost:8080/realms/kafka-realm" \
      oauth.jwks.endpoint.uri="http://keycloak:8080/realms/kafka-realm/protocol/openid-connect/certs" \
      oauth.username.claim="preferred_username";
    

    Wichtige Strimzi-OAuth-Parameter

    • oauth.client.id: Client-Kennung für die Token-Beschaffung
    • oauth.client.secret: Client-Secret für die Token-Beschaffung
    • oauth.token.endpoint.uri: Keycloak-Token-Endpunkt (Broker verwendet internen Hostnamen keycloak:8080)
    • oauth.valid.issuer.uri: Erwarteter JWT-Issuer (muss mit dem Token-iss-Anspruch übereinstimmen, verwendet externes localhost:8080)
    • oauth.jwks.endpoint.uri: JWKS-Endpunkt für die JWT-Signaturvalidierung
    • oauth.username.claim: JWT-Anspruch für die Principal-Extraktion

    Autorisierung

    root@kitploit:~
    authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
    super.users=User:kafka-broker;User:ANONYMOUS
    allow.everyone.if.no.acl.found=true
    

    Hinweis: Derzeit permissiv für Tests. In der Produktion sollten ACLs verwendet werden.

    Client-Konfiguration

    Python-Producer (confluent-kafka)

    root@kitploit:~
    from confluent_kafka import Producer
    
    conf = {
        'bootstrap.servers': 'localhost:9093',
        'security.protocol': 'SASL_SSL',
        'sasl.mechanisms': 'OAUTHBEARER',
        'sasl.oauthbearer.method': 'oidc',
        'sasl.oauthbearer.client.id': 'kafka-producer',
        'sasl.oauthbearer.client.secret': '<secret>',
        'sasl.oauthbearer.token.endpoint.url': 'http://localhost:8080/realms/kafka-realm/protocol/openid-connect/token',
        'ssl.ca.location': 'kafka-security/ca-cert',
        'ssl.endpoint.identification.algorithm': 'none',
    }
    
    producer = Producer(conf)
    producer.produce('topic', b'message')
    producer.flush()
    

    Python-Consumer (confluent-kafka)

    root@kitploit:~
    from confluent_kafka import Consumer
    
    conf = {
        'bootstrap.servers': 'localhost:9093',
        'group.id': 'test-group',
        'security.protocol': 'SASL_SSL',
        'sasl.mechanisms': 'OAUTHBEARER',
        'sasl.oauthbearer.method': 'oidc',
        'sasl.oauthbearer.client.id': 'kafka-consumer',
        'sasl.oauthbearer.client.secret': '<secret>',
        'sasl.oauthbearer.token.endpoint.url': 'http://localhost:8080/realms/kafka-realm/protocol/openid-connect/token',
        'ssl.ca.location': 'kafka-security/ca-cert',
        'ssl.endpoint.identification.algorithm': 'none',
        'auto.offset.reset': 'earliest',
    }
    
    consumer = Consumer(conf)
    consumer.subscribe(['topic'])
    while True:
        msg = consumer.poll(1.0)
        if msg: print(msg.value())
    

    Warum librdkafka funktioniert

    confluent-kafka-python verwendet librdkafka (C-Bibliothek), das OAuth über sasl.oauthbearer.method=oidc implementiert. Diese Implementierung prüft die Systemeigenschaft org.apache.kafka.sasl.oauthbearer.allowed.urls nicht, die native Apache-Kafka-Java-Clients blockiert.

    Fehlerbehebung

    OAuth-Token verifizieren

    root@kitploit:~
    TOKEN=$(curl -s -X POST http://localhost:8080/realms/kafka-realm/protocol/openid-connect/token \
      -d "grant_type=client_credentials" \
      -d "client_id=kafka-producer" \
      -d "client_secret=<secret>" | jq -r .access_token)
    
    echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq .
    

    Erwartete Ansprüche:

    root@kitploit:~
    {
      "aud": ["kafka-broker", "account"],
      "iss": "http://localhost:8080/realms/kafka-realm",
      "azp": "kafka-producer",
      "preferred_username": "service-account-kafka-producer"
    }
    

    Broker-OAuth-Logs prüfen

    root@kitploit:~
    docker logs kafka-broker 2>&1 | grep -E "Strimzi|JWTSignatureValidator|OAUTHBEARER"
    

    Erwartet:

    root@kitploit:~
    [io.strimzi.kafka.oauth.validator.JWTSignatureValidator] JWKS keys change detected
    

    Broker-Listener verifizieren

    root@kitploit:~
    docker exec kafka-broker netstat -tlnp | grep java
    

    Erwartet:

    root@kitploit:~
    tcp6  0.0.0.0:9093   LISTEN  (SASL_SSL)
    tcp6  0.0.0.0:19092  LISTEN  (PLAINTEXT)
    tcp6  0.0.0.0:29093  LISTEN  (CONTROLLER)
    

    KRaft-Metadaten prüfen

    root@kitploit:~
    docker exec kafka-broker cat /var/lib/kafka/data/meta.properties
    

    Erwartet:

    root@kitploit:~
    version=1
    cluster.id=kafka-cluster-01
    node.id=1
    

    Häufige Probleme

    Problem: {"status":"invalid_token"}

    • Ursache: Fehler bei der JWT-Signaturvalidierung
    • Lösung: Stellen Sie sicher, dass oauth.jwks.endpoint.uri vom Broker-Container aus erreichbar ist
    • Prüfung: docker exec kafka-broker curl http://keycloak:8080/realms/kafka-realm/protocol/openid-connect/certs

    Problem: Token audience mismatch

    • Ursache: Der JWT-aud-Anspruch enthält nicht kafka-broker
    • Lösung: Führen Sie ./scripts/setup-keycloak.sh aus, um den Audience-Mapper hinzuzufügen
    • Verifizierung: Dekodieren Sie das Token und prüfen Sie, ob der aud-Anspruch kafka-broker enthält

    Problem: Token issuer mismatch

    • Ursache: Der JWT-iss stimmt nicht mit oauth.valid.issuer.uri überein
    • Lösung: Stellen Sie sicher, dass oauth.valid.issuer.uri=http://localhost:8080/realms/kafka-realm (externer Hostname) ist
    • Hinweis: Der Broker verwendet http://keycloak:8080 für den Token-Endpunkt, validiert aber gegen den Issuer http://localhost:8080

    Problem: Native Java-Kafka-Clients schlagen mit URL-Allowlist-Fehler fehl

    • Ursache: CVE-2025-27817-Fix in Apache Kafka 4.1.0
    • Lösung: Verwenden Sie librdkafka-basierte Clients (confluent-kafka-python) oder Strimzi OAuth auf der Broker-Seite (bereits konfiguriert)

    Leistungsoptimierung

    Token-Aktualisierung

    JWT-Tokens von Keycloak haben eine Ablaufzeit von 5 Minuten. Strimzi OAuth übernimmt die Aktualisierung automatisch:

    • oauth.refresh.token: Nicht verwendet (client_credentials-Grant)
    • Token wird zwischengespeichert und 30 Sekunden vor Ablauf aktualisiert

    JWKS-Caching

    root@kitploit:~
    sasl.oauthbearer.jwks.endpoint.refresh.ms=3600000  # 1 Stunde
    sasl.oauthbearer.jwks.endpoint.retry.backoff.ms=100
    sasl.oauthbearer.jwks.endpoint.retry.backoff.max.ms=10000
    

    Verbindungseinstellungen

    root@kitploit:~
    connections.max.idle.ms=600000
    connection.failed.authentication.delay.ms=1000
    

    Produktions-Checkliste

    • Selbstsignierte Zertifikate durch CA-signierte Zertifikate ersetzen
    • ssl.endpoint.identification.algorithm=https aktualisieren (none entfernen)
    • Korrekte ACLs konfigurieren (allow.everyone.if.no.acl.found=true entfernen)
    • ACLs einrichten:
      root@kitploit:~
      kafka-acls --bootstrap-server localhost:9093 \
        --command-config admin.properties \
        --add --allow-principal User:kafka-producer \
        --operation Write --topic '*'
      
    • Keycloak-Client-Secrets rotieren
    • Keycloak-HTTPS aktivieren
    • oauth.token.endpoint.uri und oauth.jwks.endpoint.uri auf HTTPS-URLs aktualisieren
    • Kafka-Überwachung konfigurieren (JMX, Prometheus)
    • Log-Aggregation für OAuth-Audit-Trail einrichten
    • Failover-Szenarien testen
    • Verfahren zur Secret-Rotation dokumentieren
    • Keycloak-Benutzer-Föderation (LDAP/AD) bei Bedarf aktivieren

    Verzeichnisstruktur

    root@kitploit:~
    .
    ├── docker-compose.yml              # Orchestrierung
    ├── .env                            # Secrets (gitignored)
    ├── kafka-config/
    │   ├── kraft-config.properties     # Kafka-Broker-Konfiguration
    │   ├── producer.properties         # Producer-OAuth-Konfiguration (für CLI-Tools)
    │   └── consumer.properties         # Consumer-OAuth-Konfiguration (für CLI-Tools)
    ├── kafka-security/
    │   ├── generate-certs.sh           # SSL-Zertifikatsgenerator
    │   ├── ca-cert                     # Root-CA-Zertifikat
    │   ├── ca-key                      # Root-CA-privater Schlüssel
    │   └── broker/
    │       ├── kafka.server.keystore.jks
    │       └── kafka.server.truststore.jks
    ├── scripts/
    │   └── setup-keycloak.sh           # Keycloak-Realm-/Client-Einrichtung
    └── tests/
        └── quick_test.py               # OAuth-Validierungstest
    
    

    Technische Hinweise

    Warum Strimzi-Kafka-Image statt offiziellem Apache-Kafka-Image

    Das Strimzi-Kafka-Image (quay.io/strimzi/kafka:0.48.0-kafka-4.1.0) wird anstelle des offiziellen Apache-Kafka-Images verwendet, weil:

    1. Gebündelte OAuth-Unterstützung: Enthält die Strimzi-OAuth-0.17.0-Bibliothek vorinstalliert (Klassen: io.strimzi.kafka.oauth.*)
    2. CVE-2025-27817-Umgehung: Die Strimzi-OAuth-Bibliothek implementiert die URL-Allowlist-Einschränkung nicht, die natives Kafka-OAuth bricht
    3. Produktionsreif: In Kubernetes-Umgebungen über den Strimzi-Operator kampferprobt
    4. Einzelnes Image: Kein manuelles Herunterladen und Mounten von OAuth-JAR-Dateien erforderlich

    Image-Aufschlüsselung:

    • Strimzi Kafka 0.48.0 = Docker-Image-Version/Release
    • Apache Kafka 4.1.0 = Kafka-Broker-Version, die darin gebündelt ist
    • Strimzi OAuth 0.17.0 = OAuth-Bibliotheksversion, die darin gebündelt ist

    Issuer-URL-Dualität

    Die Broker-Konfiguration enthält zwei URLs:

    • oauth.token.endpoint.uri=http://keycloak:8080/... (internes Docker-Netzwerk)
    • oauth.valid.issuer.uri=http://localhost:8080/... (extern, entspricht dem JWT-iss-Anspruch)

    Dies liegt daran, dass:

    • Der Broker Tokens über den internen DNS-Namen abruft
    • Keycloak Tokens mit der externen Issuer-URL ausstellt (in den Realm-Einstellungen konfiguriert)
    • Die JWT-Validierung eine exakte Issuer-Übereinstimmung erfordert

    Principal-Mapping

    Der Broker extrahiert den Principal aus dem JWT-preferred_username-Anspruch:

    root@kitploit:~
    service-account-kafka-producer → User:service-account-kafka-producer
    

    ACLs referenzieren diesen Principal für die Autorisierung.

    Versionskompatibilität

    KomponenteVersionHinweise
    Apache Kafka4.1.0KRaft-Modus (kein ZooKeeper)
    Strimzi-Kafka-Image0.48.0Docker-Image: quay.io/strimzi/kafka:0.48.0-kafka-4.1.0
    Strimzi-OAuth-Bibliothek0.17.0Vorinstalliert im Strimzi-Kafka-0.48.0-Image
    Keycloak26.1.1Neuestes LTS
    librdkafka2.12.0+OIDC-OAuth-Unterstützung
    confluent-kafka-python2.12.0+Entspricht der librdkafka-Version

    Referenzen

    • Strimzi Kafka OAuth
    • Apache Kafka Security
    • Keycloak OIDC
    • CVE-2025-27817
    • KRaft-Modus
    Tool herunterladen