Resumen

  • ALPN lleva una lista ordenada de identificadores opacos del cliente y permite que el servidor seleccione un valor común. La selección manda sobre los datos de aplicación de esa conexión TLS, no sobre otra conexión ni sobre una capacidad permanente del servicio.
  • Un proxy que termina TLS es servidor en el tramo descendente y cliente nuevo en el ascendente. Puede hablar HTTP/2 en el primero y HTTP/1.1 en el segundo sin contradicción; cada tramo necesita su propio registro.
  • Registro IANA, configuración y callback instalado describen posibilidad. La evidencia operativa requiere oferta, selección o alerta, ejecución del callback, fin del handshake e inicio del protocolo ligados a una conexión concreta.

El dato era correcto; la atribución, no

En el tramo del navegador aparecía todo lo que un investigador querría ver: ClientHello ofreció dos valores, EncryptedExtensions devolvió h2, Finished protegió la transcripción y las dos partes intercambiaron el prefacio y SETTINGS de HTTP/2.

Después venía una frontera. El borde había terminado aquella sesión y abierto otra hacia el origen con claves, certificado, política y quizá versión HTTP diferentes. Allí podía negociar http/1.1 o no recibir ALPN y aplicar una caída configurada a HTTP/1.1.

Traducir protocolos no es necesariamente el fallo. El fallo fue borrar ambos identificadores de conexión y el evento de terminación antes de guardar el valor seleccionado como atributo del origen. Un hecho estrecho y fuerte pasó a ser una inferencia amplia y débil.

No son nombres tolerantes: son octetos exactos

La extensión application_layer_protocol_negotiation tiene el valor 16. RFC 7301 define cada ProtocolName como una cadena opaca, no vacía, de uno a 255 octetos con prefijo de longitud. Una entrada vacía o truncada no es válida.

Por eso la capa de visualización no puede cambiar mayúsculas, recortar o buscar semejanzas. HTTP/2 sobre TLS usa exactamente los dos octetos de h2. RFC 9113 prohíbe enviar o seleccionar h2c dentro de ALPN sobre TLS.

El orden del cliente expresa preferencia; el servidor decide dentro de la intersección conforme a su política. Que h2 aparezca primero no acredita que se seleccionó. Que figure en una configuración tampoco demuestra qué SSL_CTX o instancia atendió la conexión.

Cuando no hay intersección, RFC 7301 exige la alerta fatal no_application_protocol. RFC 9325 insiste en el comportamiento estricto para reducir confusiones entre protocolos. Seleccionar algo que el cliente no ofreció no es un mecanismo de compatibilidad.

Una selección firme, con jurisdicción pequeña

El identificador elegido es definitivo para los datos de aplicación de la misma conexión. Si el servidor devuelve h2, no puede interpretar luego ese flujo como HTTP/1.1. El prefacio de conexión y SETTINGS de HTTP/2 añaden una comprobación posterior al handshake.

De ahí sale una escalera: oferta, respuesta, Finished autenticado, prefacio válido, intercambio útil. Cada peldaño tiene un alcance. Un ClientHello capturado no prueba que la negociación terminara; una selección sin prefacio no prueba que HTTP/2 arrancara; una petición exitosa no garantiza la siguiente conexión.

RFC 9113 advierte además que el soporte anterior no es una señal fuerte para conexiones futuras, porque cambian instancias, configuración y condiciones de red. La conexión es la unidad correcta de atribución, no un detalle que deba eliminar el panel.

Dos tramos no comparten automáticamente protocolo

Ante el usuario, el proxy es servidor TLS. Ante un origen con TLS, pasa a ser cliente. Cada función tiene oferta, selección, alerta y generación de política propias.

Las opciones oficiales de Envoy hacen visible esa separación. El proxy puede usar explícitamente el protocolo descendente, negociar HTTP/1.1 o HTTP/2 de forma independiente en el ascendente, o caer a HTTP/1.1 si el origen no aporta ALPN. Copiar el protocolo descendente no es una ley de la red: es una conducta que debe configurarse y ejecutarse.

Un túnel puro es distinto. El intermediario puede reenviar bytes sin ser extremo TLS ni conocer el resultado interior. RFC 7639 permite expresar en CONNECT qué protocolos se pretende usar dentro del túnel, pero una intención declarada tampoco demuestra un handshake completado.

La topología defendible guarda un tuple descendente, otro ascendente y un evento de terminación, traducción o túnel que los relaciona. Relacionar no significa fusionar.

Lo que el callback revela —y lo que no

OpenSSL permite borrar la lista del cliente con longitud cero; en ese caso no se envía la extensión. Si ClientHello no propone ALPN, el callback del servidor no se invoca. Tenerlo instalado solo acredita capacidad de código.

Antes de ALPN se ejecuta el callback de servername, que puede sustituir SSL_CTX. Por tanto, la política efectiva puede depender del nombre virtual y no coincidir con el inventario global.

La salida debe señalar un valor del vector cliente. SSL_get0_alpn_selected devuelve memoria prestada, con longitud y sin terminación NUL. Tratarla como texto convencional puede truncar o deformar la evidencia.

SSL_select_next_proto ofrece una prueba negativa especialmente útil: aun sin coincidencia, coloca el primer elemento cliente en la salida y devuelve OPENSSL_NPN_NO_OVERLAP. OpenSSL exige ignorar esa salida en ALPN. Registrar el valor antes de revisar el resultado fabrica un acuerdo.

Tampoco deben mezclarse ausencia, vector inválido, falta de coincidencia fatal, NOACK sin selección, error del callback y selección correcta. alpn=false no alcanza para reconstruir ninguna de esas rutas.

La reanudación no conserva la vieja autoridad

RFC 7301 define ALPN como propiedad de la conexión, no de la sesión. Al reanudar, los valores anteriores dejan de gobernar; importan los mensajes nuevos.

Un ticket emitido cuando h2 estaba activo no obliga a una nueva instancia a conservarlo. Copiar el resultado viejo a la telemetría nueva oculta cambios de despliegue.

En TLS 1.3, los parámetros asociados a una PSK para 0-RTT incluyen ALPN. El servidor solo puede aceptar datos tempranos si la selección nueva coincide. Si los rechaza y el protocolo final cambia, quizá la aplicación deba construir otro mensaje.

RFC 9846 prohíbe que TLS reenvíe automáticamente datos tempranos salvo que se seleccione el mismo ALPN. Solo la aplicación comprende si el encuadre y la semántica siguen siendo válidos.

Protocolo, identidad y permiso son tres resultados

ALPN responde cómo hablar. La validación del certificado y la identidad de servicio responden con quién. La autorización decide qué acción puede realizar ese sujeto.

HTTP/3 ofrece un ejemplo nítido: normalmente selecciona h3 durante TLS sobre QUIC, pero RFC 9114 exige además verificar el certificado para el origen de la URI. Un h3 legítimo no hace autoritativo a un servidor con identidad inaceptable.

La inscripción IANA tampoco prueba despliegue. Define el significado interoperable de unos bytes. Código, compilación y configuración ayudan a explicar un resultado ejecutado, pero no sustituyen la oferta, la selección y el prefacio vistos en la conexión.

Pruebas negativas para un registro fiable

Ofrecer h2,http/1.1 y hacer que el servidor prefiera http/1.1; la telemetría debe guardar lo elegido. Intentar devolver un valor no ofrecido y comprobar el aborto.

Enviar ClientHello sin ALPN y observar que el callback no corre. Separar no_application_protocol de un NOACK deliberado. Activar el caso OPENSSL_NPN_NO_OVERLAP sin registrar su salida como selección. Cambiar SSL_CTX desde servername y atribuir la decisión a la generación correcta.

En el proxy, producir h2 descendente y HTTP/1.1 ascendente, conservando conexiones y traducción. Reanudar tras cambiar política sin heredar el ALPN viejo. Rechazar 0-RTT cuando el protocolo final cambie y verificar que TLS no reenvía automáticamente.

Por último, dejar que ALPN tenga éxito mientras falla la identidad, y que ambos tengan éxito mientras la aplicación niega el recurso. Esos resultados separados son la prueba de que cada capa conserva su autoridad.

Fuentes