Getting 421 Misdirected on auto-TLS

1. Caddy version (caddy version):

2.4.6

2. How I run Caddy:

I’m not running in production yet. Testing with a trivial case, one of 41 virtual domains, one of the few with a dedicated IP address. Running with log-level debug, in foreground (“caddy run”).

a. System environment:

CentOS 7.9.2003. Not yet integrated with systemd.

b. Command:

caddy run

c. Service/unit/compose file:

(none yet)

d. My complete Caddyfile or JSON config:

# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

#:80 {
#	# Set this path to your site's directory.
#	root * /usr/share/caddy
#
#	# Enable the static file server.
#	file_server
#
#	# Another common task is to set up a reverse proxy:
#	# reverse_proxy localhost:8080
#
#	# Or serve a PHP site through php-fpm:
#	# php_fastcgi localhost:9000
#}
{
	debug
}
# groups.queernet.org
groups.queernet.org {
	log {
		output file /var/log/caddy/groups.queernet.org-access.log
		level debug
	}
	log {
		output file /var/log/caddy/groups.queernet.org-error.log
		level error
	}

	route /images* {
		uri strip_prefix /images
		file_server {
			root /usr/share/sympa/static_content
		}
	}
	root * /var/lib/sympa/list_data/list-data/groups.queernet.org
	php_fastcgi unix//run/sympa/wwsympa.socket

	# Legacy mailman redirects
	#redir /pipermail https://lists.noisebridge.net{uri}
	#redir /mailman https://lists.noisebridge.net{uri}

	#rewrite / /index.php?title={path}
	redir / /sympa.php
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile

3. The problem I’m having:

curl -v http://groups.queernet.org

* About to connect() to groups.queernet.org port 80 (#0)

* Trying 216.252.162.114...

* Connected to groups.queernet.org (216.252.162.114) port 80 (#0)

> GET / HTTP/1.1

> User-Agent: curl/7.29.0

> Host: groups.queernet.org

> Accept: */*

>

< HTTP/1.1 308 Permanent Redirect

< Connection: close

< Location: https://groups.queernet.org/

< Server: Caddy

< Date: Sun, 24 Apr 2022 00:30:42 GMT

< Content-Length: 0

<

* Closing connection 0

4. Error messages and/or full log output:

2022/04/24 00:07:17.547 error   http.log.access.log1    handled request {"request": {"remote_addr": "97.113.197.229:59731", "proto": "HTTP/2.0", "method": "GET", "host": "groups.queernet.org", "uri": "/sympa.php", "headers": {"Accept-Encoding": ["gzip, deflate, br"], "User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], "Accept-Language": ["en-US,en;q=0.9"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "groups.queernet.org"}}, "common_log": "97.113.197.229 - - [23/Apr/2022:17:07:17 -0700] \"GET /sympa.php HTTP/2.0\" 421 1", "user_id": "", "duration": 0.352837206, "size": 1, "status": 421, "resp_headers": {"Server": ["Caddy"], "Status": ["421 Misdirected Request"]}}
2022/04/24 00:07:17.548 error   http.log.access.log1    handled request {"request": {"remote_addr": "97.113.197.229:59731", "proto": "HTTP/2.0", "method": "GET", "host": "groups.queernet.org", "uri": "/sympa.php", "headers": {"Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], "Accept-Language": ["en-US,en;q=0.9"], "Accept-Encoding": ["gzip, deflate, br"], "User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "groups.queernet.org"}}, "common_log": "97.113.197.229 - - [23/Apr/2022:17:07:17 -0700] \"GET /sympa.php HTTP/2.0\" 421 1", "user_id": "", "duration": 0.402926325, "size": 1, "status": 421, "resp_headers": {"Server": ["Caddy"], "Status": ["421 Misdirected Request"]}}
2022/04/24 00:12:34.373 error   http.log.access.log1    handled request {"request": {"remote_addr": "97.113.197.229:59886", "proto": "HTTP/2.0", "method": "GET", "host": "groups.queernet.org", "uri": "/sympa.php", "headers": {"User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], "Accept-Language": ["en-US,en;q=0.9"], "Accept-Encoding": ["gzip, deflate, br"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "groups.queernet.org"}}, "common_log": "97.113.197.229 - - [23/Apr/2022:17:12:34 -0700] \"GET /sympa.php HTTP/2.0\" 421 1", "user_id": "", "duration": 0.354340506, "size": 1, "status": 421, "resp_headers": {"Server": ["Caddy"], "Status": ["421 Misdirected Request"]}}

5. What I already tried:

6. Links to relevant resources:

Welcome.

I don’t understand, what is the problem exactly?

The problem is the 421 Misdirected error codes. Not Caddy’s fault, I am certain, since I experience it with other web servers in this new start-from-scratch enrironment. But the only domain the web server knows about is groups.queernet.org, which is a singleton on its IP address, and the only domain Simp is serving on that address. So it’s unclear at what point a domain name that is a mismatch for the Caddy-issued cert could be introduced.

1 Like

The only time Caddy returns a 421 itself is if strict_sni_host is configured – which is also automatically enabled if client authentication is enabled; neither of those seem to be the case from your config, so that must be coming from your PHP app itself, not Caddy… I think. Do you see reverse_proxy debug logs when it does happen (i.e. does Caddy do a roundtrip to your upstream?)

I think you can probably change this to a rewrite, btw.

I’d suggest writing this like this instead:

handle_path /images* {
	root * /usr/share/sympa/static_content
	file_server
}

handle {
	root * /var/lib/sympa/list_data/list-data/groups.queernet.org
	php_fastcgi unix//run/sympa/wwsympa.socket
	file_server
}

Also I suggest turning on encode gzip to save on some traffic.

1 Like

You’re being a great help, @francislavoie

Part of what I’ve discovered is that it keeps slipping my mind that I’m dealing with a Perl app, not PHP…!

I’ve fixed the rewrite, but what’s the appropriate tool for coding the FastCGI interface?

1 Like

Also, does caddy listen on IP addresses even if they have no servers configured on them?

The php_fastcgi directive is a shortcut for this longer bit of config:

If you don’t need the extra PHP-specific logic, you can just use reverse_proxy with the fastcgi transport, as show in that example in the docs.

Caddy will listen on all interfaces by default, unless you configure bind to limit it to certain interfaces:

The bind tip helped me guarantee that the single site on the single IP address would indeed be the only thing Caddy was trying to serve.

I have to admit I’m pretty unclear on the concept in reverse-proxy-land. I often learn concepts, alas, in the rear-view mirror.

In this case, I wasn’t to take any request to DOMAIN, rewrite it to DOMAIN/sympa, and deliver it to the FastCGI handler and on to WWSympa.

The way this worked in Apache 2.2 was:

AddHandler fcgid-script .fcgi ProcessLifeTime 7200 IPCCommTimeout 7200 IPCConnectTimeout 300

…and…

ScriptAlias /sympa /home/sympa/bin/wwsympa-wrapper.fcgi
ScriptAlias /index.fcgi /home/sympa/bin/wwsympa-wrapper.fcgi

…which was a compiled wrapper, which is no longer needed. wwsympa now listens to the UDS, started under systemd:

[Unit]
Description=Sympa web interface FastCGI backend
After=sympa.service
Requires=wwsympa.socket

[Service]
User=sympa
Group=sympa
ExecStart=/usr/bin/multiwatch \
          -f $FCGI_CHILDREN -- \
          $EXECCGIDIR/wwsympa.fcgi
StandardOutput=null
StandardInput=socket
StandardError=journal
Environment="FCGI_CHILDREN=5"
Restart=always
RestartSec=5

[Install]
Also=wwsympa.socket
WantedBy=multi-user.target

The directory names are correctly replaced on the system.

Sorry, I’m not really following at this point; is the issue resolved? Did you figure out what was causing the problem?

No, it isn’t - I really don’t get what I want to code for the reverse proxy.

Probably something like this:

	reverse_proxy unix//run/sympa/wwsympa.socket {
		transport fastcgi
	}

But I don’t know what your Perl app’s requirements are.

I was actually thinking “it can’t be that simple, can it?”… will try shortly.

1 Like

So with logging properly enabled for wwsympa, it is showing me:

Apr 24 09:38:41 divine wwsympa[2366]: debug main:: ORIG_PATH_INFO=
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: ORIG_SCRIPT_NAME=
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: PATH_INFO=https://groups.queernet.org/sympa.pl
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: QUERY_STRING=
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: REMOTE_ADDR=97.113.197.229
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: REMOTE_HOST=97.113.197.229
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: REQUEST_METHOD=GET
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: SCRIPT_NAME=
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: SERVER_NAME=groups.queernet.org
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: SERVER_PORT=
Apr 24 09:38:41 divine wwsympa[2366]: debug main:: SYMPA_DOMAIN=

Sure looks like SERVER_NAME should at least be matching here…