Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
kafka-keycloak-oauth — Apache Kafka 4.1.0 (KRaft) con autenticación OAuth2 de Keycloak usando Strimzi: evita la restricción de la lista de permitidos de URL de CVE-2025-27817 | Kitploit
Herramientas/GitHubGitHub/oriolrius/kafka-keycloak-oauth
Seguridad de Infraestructura en la NubeAnálisis de VulnerabilidadesAuditoría de ConfiguraciónDevSecOpsAutenticaciónAprendizaje y Educación
GitHuboriolrius/kafka-keycloak-oauth

kafka-keycloak-oauth

Apache Kafka 4.1.0 (KRaft) con autenticación OAuth2 de Keycloak usando Strimzi: evita la restricción de la lista de permitidos de URL de CVE-2025-27817

Ver Repositorio
5323hace 11 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Apache Kafka 4.1.0 con autenticación OAuth2 de Keycloak

Apache Kafka 4.1.0 listo para producción (modo KRaft) con autenticación OAuth2/OIDC de Keycloak 26.1.1 utilizando la imagen de Kafka de Strimzi.

Por qué este proyecto vs kafka-oauth-keycloak-tls-demo

Esta es una evolución del POC anterior con mejoras significativas:

  • Strimzi OAuth 0.17.0 (vs 1.0.0) - versión de producción estable incluida en la imagen de Strimzi Kafka 0.48.0
  • Sin necesidad de build Docker personalizado - utiliza la imagen oficial de Strimzi con OAuth preinstalado, elimina la complejidad del Dockerfile
  • Conciencia de CVE-2025-27817 - documenta la restricción de la lista de URLs permitidas y por qué Strimzi OAuth la evita
  • Arquitectura simplificada - modo combinado KRaft único (broker+controller), no arquitectura dividida
  • Enfoque en cliente librdkafka - probado con confluent-kafka-python (funciona sin problemas de lista de URLs permitidas), no con clientes Java nativos
  • Documentación técnica completa - lista de verificación de producción, solución de problemas, ajuste de rendimiento, detalles de mapeo de principal
  • Gestión de certificados más limpia - certificados de ejemplo incluidos para pruebas inmediatas
  • Configuración automatizada de Keycloak - creación de realm/cliente/mapper mediante scripts con configuración de audiencia
  • Suite de pruebas Python funcional - valida la entrega de mensajes OAuth de extremo a extremo
  • Manejo explícito de URL del emisor - documenta la dualidad de URL interna vs externa para el endpoint de token vs validación del emisor

Arquitectura

  • Distribución de Kafka: Imagen de Strimzi Kafka 0.48.0 (incluye Apache Kafka 4.1.0 + Strimzi OAuth 0.17.0 preinstalado)
  • Versión de Kafka: Apache Kafka 4.1.0 (KRaft combinado broker+controller)
  • Biblioteca OAuth: Strimzi Kafka OAuth 0.17.0 (incluida en la imagen, evita la restricción de lista de URLs permitidas de CVE-2025-27817)
  • Proveedor OAuth: Keycloak 26.1.1
  • Seguridad: SASL_SSL (OAuth) para clientes externos, PLAINTEXT para inter-broker, SSL con CA autofirmada

Contexto de CVE-2025-27817

Apache Kafka 4.0.0+ introdujo una lista de URLs permitidas (org.apache.kafka.sasl.oauthbearer.allowed.urls) como propiedad del sistema JVM para corregir la vulnerabilidad SSRF/lectura arbitraria de archivos. Esto rompe el uso estándar de OAuth en clientes nativos de Apache Kafka.

Solución: La biblioteca Strimzi Kafka OAuth no implementa esta restricción, lo que permite la funcionalidad OAuth con Kafka 4.1.0.

Requisitos previos

  • Docker Compose
  • Python 3.x con uv (para pruebas)
  • OpenSSL (para generación de certificados)

Inicio rápido

# Generar certificados SSL
cd kafka-security
./generate-certs.sh
cd ..

# Iniciar servicios
docker compose up -d

# Verificar Keycloak
curl http://localhost:8080/health/ready

# Configurar realm y clientes de Keycloak
./scripts/setup-keycloak.sh

# Probar productor OAuth
source ~/.venv/bin/activate
uv pip install confluent-kafka
python tests/quick_test.py

Topología de red

keycloak:8080 (HTTP) ←→ kafka-broker:9093 (SASL_SSL/OAuth)
                      ↔ kafka-broker:19092 (PLAINTEXT/inter-broker)
                      ↔ kafka-broker:29093 (PLAINTEXT/controlador KRaft)

Configuración SSL

Estructura de CA

  • CA raíz: kafka-security/ca-cert + ca-key
  • Almacén de claves del broker: kafka-security/broker/kafka.server.keystore.jks (contiene certificado del servidor + clave privada)
  • Almacén de confianza del broker: kafka-security/broker/kafka.server.truststore.jks (contiene certificado de CA)
  • Contraseña: changeit (todos los almacenes de claves/confianza)

Detalles del certificado

# Certificado del broker
CN=kafka-broker
SAN=DNS:kafka-broker,DNS:localhost,IP:127.0.0.1

# Validez: 3650 días
# Algoritmo de clave: RSA 2048 bits
# Algoritmo de firma: SHA256withRSA

Configuración OAuth de Keycloak

Realm: kafka-realm

Clientes

kafka-broker (confidencial)

  • ID de cliente: kafka-broker
  • Secreto de cliente: Generado automáticamente por setup-keycloak.sh
  • Propósito: Autenticación OAuth inter-broker
  • Mappers:
    • Mapper de audiencia: añade kafka-broker a la reclamación aud del JWT
    • Mapper de nombre de usuario: incluye preferred_username en el token

kafka-producer (confidencial)

  • ID de cliente: kafka-producer
  • Secreto de cliente: Generado automáticamente
  • Propósito: Clientes productores externos
  • Grant: client_credentials
  • Mappers: Igual que kafka-broker

kafka-consumer (confidencial)

  • ID de cliente: kafka-consumer
  • Secreto de cliente: Generado automáticamente
  • Propósito: Clientes consumidores externos
  • Grant: client_credentials
  • Mappers: Igual que kafka-broker

Endpoint de token

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=<secreto>
&scope=profile email

Estructura del token JWT

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

Configuración de Kafka

Modo KRaft (kraft-config.properties)

# Identidad del nodo
node.id=1
process.roles=broker,controller
controller.quorum.voters=1@kafka-broker:29093

# Listeners
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

# Mecanismo SASL
sasl.enabled.mechanisms=OAUTHBEARER

# Handlers OAuth de Strimzi (por listener para 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

# Configuración OAuth mediante 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="<secreto>" \
  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";

Parámetros clave de Strimzi OAuth

  • oauth.client.id: Identificador de cliente para la obtención de tokens
  • oauth.client.secret: Secreto de cliente para la obtención de tokens
  • oauth.token.endpoint.uri: Endpoint de token de Keycloak (el broker usa el nombre de host interno keycloak:8080)
  • oauth.valid.issuer.uri: Emisor JWT esperado (debe coincidir con la reclamación iss del token, usa localhost:8080 externo)
  • oauth.jwks.endpoint.uri: Endpoint JWKS para validación de firma JWT
  • oauth.username.claim: Reclamación JWT para extracción del principal

Autorización

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

Nota: Actualmente permisivo para pruebas. La producción debería usar ACLs.

Configuración del cliente

Productor Python (confluent-kafka)

from confluent_kafka import Producer
Descargar herramienta