Parche para librdkafka: Hostname verification should include IP Address SAN verification (RFC2818 requirement) #3801
Mi infraestructura Kafka utiliza IPv6 y las interconexiones se configuran directamente utilizando direcciones IPv6 en vez de nombres de dominio. El motivo es independizar esa infraestructura Kafka de mi infraestructura DNS, por "motivos".
Mi infraestructura Kafka, que está repartida por todo el planeta (lo que tiene sus propios problemas, a documentar en un artículo futuro), requiere que las conexiones estén cifradas y protegidas. Kafka emplea TLS para ello, aunque la implementación es mejorable (otro artículo futuro), utilizando certificados x.509.
A nivel del cliente Kafka utilizo librdkafka, una librería en C (fácilmente accesible también desde Python), sorprendentemente capaz y completa aunque con algunas carencias incomprensibles.
En mi caso la verificación de los certificados X.509, creados correctamente indicando las direcciones IPv6 en el campo Subject Alternative Name como indica el estándar, fallan en los clientes que utilizan librdkafka. Investigando el asunto veo este bug documentado:
Hostname verification should include IP Address SAN verification (RFC2818 requirement) #3801.
El problema se documentó en 2022, pero sigue sin estar solucionado y, sinceramente, no parece que los autores de librdkafka estén muy interesados en solucionarla, a pesar de que la solución el simple (tal vez porque el problema solo afecta a los que utilizamos versiones viejas, pero soportadas, de OpenSSL).
Ahora mismo actualizar OpenSSL no es una opción, y menos aún cuando la versión que utilizo sigue teniendo soporte. Analizando, no obstante, los cambios en la versión 3 de OpenSSL comparados con mi versión, el cambio es pequeño y bastante trivial. Modificar el código fuente de librdkafka para que haga básicamente lo mismo es sencillo:
-- src/rdkafka_ssl.c.OLD 2026-02-16 13:55:19.536081667 +0100 +++ src/rdkafka_ssl.c 2026-02-16 13:57:39.056774393 +0100 @@ -535,8 +535,26 @@ } #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL) - if (!SSL_set1_host(rktrans->rktrans_ssl, name_for_verify)) - goto fail; + { /* JCEA - 20231220 */ + X509_VERIFY_PARAM *param; + char buf[RD_KAFKA_NODENAME_SIZE]; + + if (strlen(name_for_verify) && (name_for_verify[0] == '[') && + (name_for_verify[strlen(name_for_verify)-1] == ']') && + strchr(name_for_verify, ':')) + { + strcpy(buf, name_for_verify+1); + buf[strlen(buf)-1] = '\0'; + } else { + strcpy(buf, name_for_verify); + } + param = SSL_get0_param(rktrans->rktrans_ssl); + + if (X509_VERIFY_PARAM_set1_ip_asc(param, buf) != 1) + if (!SSL_set1_host(rktrans->rktrans_ssl, name_for_verify)) + goto fail; + } + #elif OPENSSL_VERSION_NUMBER >= 0x1000200fL /* 1.0.2 */ { X509_VERIFY_PARAM *param;
Con este parche mis certificados x.509 con direcciones IPv6 en el campo Subject Alternative Name ya funcionan correctamente en librdkafka.
Misión cumplida.