16

How to run HTTP/3 with Caddy 2

 2 years ago
source link: https://ma.ttias.be/how-run-http-3-with-caddy-2/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

I just migrated this webserver to Caddy 2 and with it, enabled HTTP/3 support. This post will give a short explanation how you can do that.

Run Caddy 2

The HTTP/3 feature is only available in caddy 2, make sure you run at least version 2 or higher.

This is bad:

caddy --version
Caddy v1.0.3 (h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w=)

This is good:

$ caddy version
v2.0.0-rc.2 h1:7NOaxYrsnQ5D3rcLGn2UnLZHLfBpgrfM/JNTLhjCJ1c=

(Note how the syntax changed from --version to version).

Enable HTTP/3

In your Caddyfile, at the very top, enable the HTTP/3 feature.

{
    experimental_http3
}

ma.ttias.be {
    root * /var/www/html/ma.ttias.be/public
    file_server
    encode zstd gzip
    [...]
}

The critical part is experimental_http3.

TCP and UDP

One major change is that HTTP/3 operates on the UDP protocol instead of TCP. Most webservers will only bind on port :80 and :443 on TCP, as they don’t need to do any UDP traffic.

By default, Caddy will also only listen on TCP:

tcp6       0      0 :::80      :::*     LISTEN      27373/caddy
tcp6       0      0 :::443     :::*     LISTEN      27373/caddy

If you enable the experimental_http3 option, it’ll listen on UDP as well.

tcp6       0      0 :::80      :::*     LISTEN      27422/caddy
tcp6       0      0 :::443     :::*     LISTEN      27422/caddy
udp6       0      0 :::443     :::*                 27422/caddy

(Note: if you’re used to running netstat | grep " LISTEN ", be aware that the UDP protocol doesn’t have a LISTEN state attached to it and won’t return any results).

If you see a UDP listener, you’re ready to receive connections.

Allow UDP traffic

Since the shift from TCP to UDP might catch some firewall vendors by surprise, make sure you’re allowing 443/udp incoming to your server.

443/tcp is probably already allowed (or you wouldn’t be serving HTTPS sites today).

Test HTTP/3 connections

This part is a bit more tricky, since it’s all very experimental and none of the client tooling supports HTTP/3 by default.

Via curl

Curl has, since its recent versions, introduced a --http3 flag you can use to force HTTP/3 connections.

$ curl -I --http3 https://ma.ttias.be
HTTP/3 200
alt-svc: h3-27=":443"; ma=2592000
server: Caddy
...

You’ll need a modern version though, and most distributions don’t ship with it by default. The above was done with a custom-compiled version of curl to test HTTP/3.

$ curl --version
curl 7.70.0-DEV

Via Chrome Canary

Chrome Canary is a nightly build of Chrome, with some more experimental features in it.

To test it out, make sure you’re running the latest version and start Chrome Canary with the --enable-quic and --quic-version=h3-27 flag. You will need to start Chrome Canary via the CLI.

(Note: the version of QUIC should match the one that is advertised in the alt-svc header.)

If you are on a Mac, you can start Chrome Canary like this:

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary \
    --enable-quic \
    --quic-version=h3-27

The first page load will show HTTP/2. From then on, the browser has received the alt-svc header to indicate there is HTTP/3 support and will retry the next request over UDP & HTTP/3.

HTTP/3 enabled in Firefox

Because HTTP/3 is still evolving, Chrome shows the exact revision of the HTTP/3 protocol being used.

Via Firefox Nightly

Just like Chrome, Firefox has an experimental build called Firefox Nightly.

First, enable HTTP/3. Navigate to about:config and find the option network.http.http3.enabled. Doubleclick it to toggle it from disabled to enabled.

Enable HTTP/3 in Firefox

Refresh your site and it should show HTTP/3 in the inspector. Make sure the Protocol column is shown.

HTTP/3 enabled in Firefox

Conclusion

HTTP/3 is still very experimental. Server-side support is slowly coming, but client-side support is disabled by default everywhere.

We’re still in the trial & error phase, I’m curious to see when the the first browsers will ship with HTTP/3 enabled.

It’s a chicken and egg situation right now: there’s little incentive for servers to implement it, as no clients support it. And why should clients push forward, if no servers provide the support?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK