With TLS-ALPN arriving, I am wondering what the envisioned way for “most people” to actually deploy it is?
For some background: ALPN is an extension in TLS that allows the application-layer protocol (http/1.1, h2, acme/tls-1) to be negotiated in the ClientHello/ServerHello messages of a TLS connection. A nice overview can be found at: https://www.keycdn.com/support/alpn/ .
For Let’s Encrypt, TLS-ALPN allows the validation process to be completed by including the
acme/tls-1 ALPN ID in the ClientHello message, and responding with the same ALPN ID and ACME key authorization in the ServerHello response.
This means that the implementation of the validation process has to be done within the context of the TLS implementation of the web server, and the web server needs to know “what to do” when it encounters an ALPN ID such as TLS-ALPN’s.
What I’m finding is that a hypothetical deployment of TLS-ALPN by users today will involve one of:
- Abandoning their current TLS termination (nginx, Apache, etc) in favor of a TLS proxy that is capable of implementing TLS-ALPN or passing-through the ClientHello. . Nobody wants to abandon battle-tested TLS termination, it’s a big change.
- Temporarily bringing down their web server’s 443 listener during validation, and allowing a “standalone” 443 server to complete the validation challenge. This is what Certbot does today. . Downtime isn’t a strategy.
- Temporarily (using netfilter/nftables) redirecting new connections to port 443 to a “standalone” server that is capable of serving both the application traffic and the TLS-ALPN traffic simultaneously. . Seems overly complex and brittle.
So where do we go from here?
It seems inevitable that web servers will need to make some changes.
- This could be done in Apache httpd by building a module (or extending mod_md) that registers an ALPN handler. . Edit: I gave this a shot, but it turns out you can’t override the ServerHello from a module, it requires a core change to httpd’s SSL engine. .
- This would require first-party changes in nginx. . Edit: ngx_stream_ssl_preread might provide the solution (though it is not compiled-in by default), it is capable of muxing ALPN IDs.
- This would require first-party changes in haproxy.
I don’t see TLS-ALPN being widely deployed (or at all) if it can’t practically fulfill the premise of the challenge: to enable validations over port 443 and truly replace TLS-SNI. Is any kind of progress being made, planned or proposed? I’d love to hear about it.