Can't get non-default HTTPS upgrade to work

1. Caddy version (caddy version):

caddy:2.4.6-alpine from Docker hub

v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

Caddy is running in a Docker container on AWS ECS.

Dockerfile looks like:

FROM caddy:builder AS builder

RUN caddy-builder \
  github.com/caddy-dns/cloudflare

FROM caddy:2.4.6-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy
COPY Caddyfile /etc/caddy/Caddyfile

a. System environment:

AWS ECS backed by EC2.

b. Command:

n/a

c. Service/unit/compose file:

This is CDK:

    const proxyContainer = proxyTaskDefinition.addContainer('ProxyContainer', {
      image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, './docker')),
      environment: {
        'BUCKET_DOMAIN_NAME': bucket.bucketWebsiteDomainName,
        ...configuration.runtime
      },
      secrets: {
        'CLOUDFLARE_TOKEN': ecs.Secret.fromSecretsManager(
          secretsmanager.Secret.fromSecretNameV2(
            this, 'CloudflareToken', 'infrastructure/cloudflare-token'
          )
        )
      },
      containerName: 'proxy',
      memoryReservationMiB,
      essential: true,
      logging
    })
    proxyContainer.addMountPoints(
      {
        containerPath: '/data',
        sourceVolume: volumeConfig.name,
        readOnly: false
      }
    )

    proxyContainer.addPortMappings({
      containerPort: 80,
      hostPort: 80,
      protocol: ecs.Protocol.TCP
    })
    proxyContainer.addPortMappings({
      containerPort: 443,
      hostPort: 443,
      protocol: ecs.Protocol.TCP
    })

d. My complete Caddyfile or JSON config:

{
	email me@example.com
	admin off
}

# Caddy by default issues a 308 to redirect http to https. However certain
# ISPs (9Mobile in Nigeria) do not handle a 308 status code correctly,
# having users ending up stuck on a non-working page.
http:// {
	redir https://{hostport}{uri} 301
}

{$DOMAIN_NAME} {
	log

	encode gzip

	tls {
		dns cloudflare {$CLOUDFLARE_TOKEN}
	}

	handle /db* {
		uri strip_prefix /db
		reverse_proxy {
			to https://{$COUCHDB_PROXY_TARGET}
			header_up +Host {$COUCHDB_PROXY_TARGET}
		}
	}

	handle /api* {
		uri replace /api/ /indicators/
		reverse_proxy {
			to https://{$INDICATORS_PROXY_TARGET}
			header_up +Host {$INDICATORS_PROXY_TARGET}
		}
	}

	handle {
		reverse_proxy {
			to http://{$BUCKET_DOMAIN_NAME}
			header_up +Host {$BUCKET_DOMAIN_NAME}
			header_down +X-Frame-Options deny
		}
	}
}

3. The problem I’m having:

I would like to have Caddy issue 301 redirects instead of the default 308 when upgrading http to https. (see 308 http to https redirect does not work with some ISPs · Issue #3722 · caddyserver/caddy · GitHub for background). The approach described in the GitHub issue works well for me in different setups, however using the above Caddyfile upgrades will still return an 308:

➜   curl -I http://example.com
HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://example.com/
Server: Caddy
Date: Tue, 25 Jan 2022 12:17:02 GMT

4. Error messages and/or full log output:

n/a

5. What I already tried:

Using the above configuration.

6. Links to relevant resources:

n/a

I tried finding out what is causing this in the Caddyfile but couldn’t really make any sense of what’s going on. In any case the following very simple Caddyfile will also redirect using a 308 when I would expect a 301:

# Caddy by default issues a 308 to redirect http to https. However certain
# ISPs (9Mobile in Nigeria) do not handle a 308 status code correctly,
# having users ending up stuck on a non-working page.
http:// {
	redir https://{hostport}{uri} 301
}

hardcoded.domain.name.here.com {
	reverse_proxy http://{$BUCKET_DOMAIN_NAME}
}

This seems to be a regression in Caddy. Said configuration will work in 2.1.1 but does not work in 2.4.6 albeit I can’t build 2.1.1 myself as it fails adding that Cloudflare DNS module.

This was an “intended” regression. Essentially, now http:// blocks have lower precedence than the built-in HTTP->HTTPS redirects, because otherwise it was impossible to just write an http:// fallback and still keep the redirects (many users wanted this).

So what you need to do is disable Caddy’s built-in redirects, which you can do with the global option auto_https disable_redirects. That way they won’t be inserted in front of your http:// and your custom handlers will always apply instead.

That’s a bit surprising, but I can confirm using auto_https disable_redirects definitely works as intended for me. Thanks for looking into this.

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