1. The problem I’m having:
I have a Minecraft server on a domain with the .app
extension, which is a strict transport security domain that only allows HTTPS connections. The Minecraft server runs the Dynmap plugin, which is a browser app that serves all content through HTTP. The domain, play.minecraftserver.app
has an A record pointing to the server IP, 123.45.67.89
. I can connect to the server with the domain and access the Dynmap through the server’s IP like http://123.45.67.89:8123
. But when I configured Caddy with TLS and reverse_proxy 123.45.67.89:8123
for the /map
handle path, https://play.minecraftserver.app/map
just returns an empty page. I believe that the problem is caused by the upstream app only giving HTTP responses which are getting blocked by the HSTS domain, so I want to know how to configure Caddy to display the Dynmap on https://play.minecraftserver.app/map
or a subdomain.
Log information about the request from the Caddy container:
{"level":"debug","ts":1683912268.6151292,"logger":"http.handlers.reverse_proxy","msg":"selected upstream","dial":"123.45.67.89:8123","total_upstreams":1}
{"level":"debug","ts":1683912268.618348,"logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"123.45.67.89:8123","duration":0.003144619,"request":{"remote_ip":"123.45.67.89","remote_port":"36136","proto":"HTTP/2.0","method":"GET","host":"play.minecraftserver.app","uri":"/","headers":{"User-Agent":["curl/7.81.0"],"Accept":["*/*"],"X-Forwarded-For":["123.45.67.89"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["play.minecraftserver.app"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"play.minecraftserver.app"}},"error":"tls: first record does not look like a TLS handshake"}
{"level":"error","ts":1683912268.6187713,"logger":"http.log.error","msg":"tls: first record does not look like a TLS handshake","request":{"remote_ip":"123.45.67.89","remote_port":"36136","proto":"HTTP/2.0","method":"GET","host":"play.minecraftserver.app","uri":"/map","headers":{"User-Agent":["curl/7.81.0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"play.minecraftserver.app"}},"duration":0.003718811,"status":502,"err_id":"g84qsjact","err_trace":"reverseproxy.statusError (reverseproxy.go:1272)"}
2. Error messages and/or full log output:
Response of curl -vL https://play.minecraftserver.app/map
:
* Trying 123.45.67.89:443...
* Connected to play.minecraftserver.app (123.45.67.89) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=play.minecraftserver.app
* start date: May 8 09:02:31 2023 GMT
* expire date: Aug 6 09:02:30 2023 GMT
* subjectAltName: host "play.minecraftserver.app" matched cert's "play.minecraftserver.app"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x55f643f4fe80)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /map HTTP/2
> Host: play.minecraftserver.app
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 502
< alt-svc: h3=":443"; ma=2592000
< server: Caddy
< content-length: 0
< date: Fri, 12 May 2023 17:24:28 GMT
<
* Connection #0 to host play.minecraftserver.app left intact
3. Caddy version:
2.6.4
4. How I installed and ran Caddy:
Official Docker image
a. System environment:
Ubuntu 22.04
b. Docker Compose file, command and Caddyfile:
version: "3.7"
services:
caddy:
image: caddy:2
volumes:
- ./caddy:/data/caddy
command:
- /bin/sh
- -c
- |
cat <<EOF > /etc/caddy/Caddyfile && caddy run --config /etc/caddy/Caddyfile
{
debug
}
(hsts) {
header Strict-Transport-Security max-age=63072000
}
play.minecraftserver.app {
import hsts
log
handle_path /map {
reverse_proxy 123.45.67.89:8123 {
transport http {
tls_insecure_skip_verify
}
}
}
tls {
on_demand
}
}
EOF
network_mode: "host"
minecraft:
image: itzg/minecraft-server
ports:
- 8123:8123
- 25565:25565
environment:
EULA: "TRUE"
networks:
minecraft-network:
ipv4_address: 172.59.0.100
tty: true
stdin_open: true
restart: unless-stopped
volumes:
- ./minecraft:/data
networks:
minecraft-network:
driver: bridge
ipam:
config:
- subnet: 172.59.0.0/16
5. What I already tried:
Placing the Dynmap under a subdomain rather than a subdirectory to avoid the subfolder problem still causes the same error.
play.minecraftserver.app {
import hsts
log
reverse_proxy 123.45.67.89:8123 {
transport http {
tls_insecure_skip_verify
}
}
tls {
on_demand
}
}
curl -vL play.minecraftserver.app:8132
returns “Connection refused”.
6. Links to relevant resources:
None