HTTP3 active but not used by browsers

1. The problem I’m having:

curl shows that http3 is enabled but browsers are not choosing it, they still choose to communicate over http2. I have been poking around different places but can’t figure out what is wrong.

2. Error messages and/or full log output:

docker run -it --rm ymuski/curl-http3 curl -vL -D/dev/stdout -o/dev/null --http3 https://imigrant.dk
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 172.104.142.58:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
*  subjectAltName: host "imigrant.dk" matched cert's "imigrant.dk"
* Connected to imigrant.dk (172.104.142.58) port 443 (#0)
* using HTTP/3
* Using HTTP/3 Stream ID: 0 (easy handle 0x55f4dbb81410)
> GET / HTTP/3
> Host: imigrant.dk
> User-Agent: curl/8.1.2-DEV
> Accept: */*
> 
< HTTP/3 200 
HTTP/3 200 
< content-type: text/html;charset=UTF-8
content-type: text/html;charset=UTF-8
< last-modified: Fri, 21 Jul 2023 20:21:38 GMT
last-modified: Fri, 21 Jul 2023 20:21:38 GMT
< cache-control: public, max-age=0, no-cache, no-transform
cache-control: public, max-age=0, no-cache, no-transform
< content-security-policy: test
content-security-policy: test
< x-xss-protection: 1; mode=block
x-xss-protection: 1; mode=block
< server: Caddy
server: Caddy
< vary: Accept-Encoding
vary: Accept-Encoding
< x-hyper-cache: hit - plain-https
x-hyper-cache: hit - plain-https
< content-length: 33266
content-length: 33266
< x-powered-by: PHP
x-powered-by: PHP
< x-content-type-options: nosniff
x-content-type-options: nosniff
< x-frame-options: DENY
x-frame-options: DENY

< 
{ [1035 bytes data]
100 33266  100 33266    0     0   240k      0 --:--:-- --:--:-- --:--:--  242k
* Connection #0 to host imigrant.dk left intact

3. Caddy version:

2.6.4

4. How I installed and ran Caddy:

a. System environment:

NixOS unstable, x86_64, systemd 253.5

b. Command:

The following comand is what the caddy.service executes.

/nix/store/8byahwsz6hgdynjjz9987gl0i6469mhj-caddy-2.6.4/bin/caddy run --config /etc/caddy/caddy_config --adapter caddyfile

c. Service/unit/compose file:

d. My complete Caddy config:

The following is the caddy file as it gets compiled by nix and outputted in /etc/caddy/caddy_config.

{
	servers {
		protocols h1 h2 h3
	}

	log {
		level ERROR
	}
}
imigrant.dk {
	log {
		output file /var/log/caddy/access-imigrant.dk.log
	}

	root * /nix/store/1bmn7ligp6g3g8i2ryhyizm0palx5vmg-wordpress-imigrant.dk-6.2.2/share/wordpress
	file_server

	php_fastcgi unix/run/phpfpm/wordpress-imigrant.dk.sock

	@uploads {
		path_regexp path /uploads\/(.*)\.php
	}
	rewrite @uploads /

	@wp-admin {
		path not ^\/wp-admin/*
	}
	rewrite @wp-admin {path}/index.php?{query}

	# Rewrite image paths to existent .webp files.
	rewrite @images {path}.webp
	# Definition of supported images.
	@images {
		# Match supported image paths and extensions
		path_regexp static (.*)\.(jpg|jpeg|gif|png)$
		# Ensure we have an .webp file corresponding with selected path.
		file {
			try_files {path}.webp
		}
	}
	# Definition of supported assets.
	@assets {
		path_regexp static (.*)\.(png|jp?g|gif|webp|ico|css|map|woff?|eot|svg|ttf|js)$
		file {
			try_files {path}
		}
	}
	# Use compression.
	encode {
		gzip
		# Compress the following MIME-Types.
		match {
			header Content-Type application/*
			header Content-Type font/*
			header Content-Type image/*
			header Content-Type text/*
		}
	}
	# Headers for assets.
	handle @assets {
		header cache-control "max-age=86400"
	}
	# Headers for /wp-admin/ paths.
	handle /wp-admin/* {
		header content-security-policy "admin"
	}
	# Headers for all other paths.
	handle {
		# Keep header names lowercased. They should be compared in a case-insensitive fashion.
		header {
			# Prevent MIME type sniffing attacks.
			x-content-type-options "nosniff"

			# Prevent website from framing this site.
			x-frame-options: "DENY"

			# Prevent XSS in older browsers that don't support CSP.
			x-xss-protection "1; mode=block"

			content-security-policy "test"
			# Replace the PHP signature from the existing headers, and don't set new headers where there aren't any.
			x-powered-by ".*" "PHP"
			# Delay assigning headers until everything is ready, essentially making this block authoritative.
			defer
		}
	}
}

www.imigrant.dk {
	log {
		output file /var/log/caddy/access-www.imigrant.dk.log
	}

	# Redirect www to non-www with https.
	redir https://{labels.1}.{labels.0}{uri}
}

5. Links to relevant resources:

Caddy is built in NixOS using this definition: https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/caddy/default.nix

It seems like I pinpointed the issue, a misconfiguration of IPv6 on the machine. Turning off IPv6 does allow for http3 connections. So now I need to figure out how to set IPv6 properly.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.