abiosoft / caddy-docker

Docker container for Caddy
https://hub.docker.com/r/abiosoft/caddy/
MIT License
766 stars 314 forks source link

Strict host matching: SNI and HTTP Host value differ #213

Open MexHigh opened 4 years ago

MexHigh commented 4 years ago

1. Which version of Caddy are you using?

abiosoft/caddy:php-no-stats

sha256:458bd53bc567430cadd65a8d7e9a0dfc0c28ee5d4f9a9d5cf854d3dde4edeef9

(don't know why I'm still using the php version, since I'm running my own fpm server)

2. What are you trying to do?

I'm hosting some services mainly in Docker containers and using Caddy as reverse proxy. I want to secure some subdomains with client cert authentication. (certs are accepted as valid client authentication by caddy)

3. What is your Caddyfile?

(Removed some hosts, because they are all configured almost the same and replaced my root domain with \<domain>)

# HTTP Redirects
http://<domain> http://*.<domain> http://*.*.<domain> {

  import snippets/logging
  import snippets/sec-headers

  redir https://{hostonly}{uri}

}

# Rootdomain
https://<domain> https://www.<domain> {

  import snippets/logging
  import snippets/tls
  import snippets/sec-headers

  redir {
    if {hostonly} is "www.<domain>"
    / https://<domain>{uri}
  }

  import sites/<domain>

}

# Subdomains
https://admin.<domain> {

  import snippets/logging
  import snippets/tls-client-verify
  import snippets/sec-headers

  import sites/admin.<domain>

}

https://cloud.<domain> {

  import snippets/logging
  import snippets/tls
  import snippets/sec-headers

  import sites/cloud.<domain>

}

https://private.<domain> {

  import snippets/logging
  import snippets/tls-client-verify
  import snippets/sec-headers

  import sites/private.<domain>

}

https://p.<domain> {

  import snippets/logging
  import snippets/tls
  import snippets/sec-headers

  redir https://private.<domain>

}

snippets/tls:

tls /root/.caddy/ssl/fullchain.pem /root/.caddy/ssl/privkey.pem

snippets/tls-client-verify:

tls /root/.caddy/ssl/fullchain.pem /root/.caddy/ssl/privkey.pem {
    clients /root/.caddy/ssl/ca.crt
}

(I'm using an existing wildcard cert from letsencrypt (valid, of course))

snippets/sec-headers:

header / {
    # Static Headers
    X-Xss-Protection "1; mode=block"
    X-Content-Type-Options "nosniff"
    X-Robots-Tag "none"
    X-Permitted-Cross-Domain-Policies "none"
    X-Download-Options "noopen"
    Referrer-Policy "strict-origin-when-cross-origin"
    Cache-Control "public, max-age=15, must-revalidate"
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    # Server Signature
    Server "<removed>"
    # Dynamic Headers
    X-Frame-Options "SAMEORIGIN"
    Feature-Policy "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'self'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture *; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none'"
    Content-Security-Policy "upgrade-insecure-requests"
}

4. How did you run Caddy (give the full command and describe the execution environment)?

With Docker Compose on Ubuntu Server LTS 18.04:

docker-compose version 1.17.1, build unknown docker-py version: 2.5.1 CPython version: 2.7.15+ OpenSSL version: OpenSSL 1.1.1c 28 May 2019

version: '3'
services:

  caddy:
    image: abiosoft/caddy:php-no-stats
    container_name: caddy
    hostname: caddy
    network_mode: host
    volumes:
      - /var/www:/srv
      - /etc/caddy/Caddyfile:/etc/Caddyfile:ro
      - /etc/caddy/snippets:/etc/snippets:ro
      - /etc/caddy/sites:/etc/sites:ro
      - /etc/caddy/templates:/etc/templates:ro
      - /etc/caddy/data:/root/.caddy
      - /etc/caddy/logs:/logs/caddy
    labels:
      com.centurylinklabs.watchtower.enable: "true"
    depends_on:
      - fpm-server

  fpm-server:
    image: <private registry>/leon/php:fpm-custom
    container_name: fpm
    hostname: fpm
    network_mode: host
    volumes:
      - /var/www:/srv
    labels:
      com.centurylinklabs.watchtower.enable: "true"

5. What did you expect to see?

Server asks me for client cert when entering admin.\<domain> or private.\<domain>.

6. What did you see instead (give full error messages and/or log)?

With admin.\<domain> it works like a charm, but when entering p.\<domain>, it redirects me to private.\<domain> (like it should) but it only displays "403 Forbidden" and not asks me for a certificate. When requesting p.\<domain> the following shows up in docker logs -f caddy:

2019/08/14 11:34:25 [ERROR] https://private.<domain> - strict host matching: SNI (cloud.<domain>) and HTTP Host (private.<domain>) values differ

with the first domain given in the error message (here: cloud.\<domain>) beeing different at every server restart.

The error.log itself (declared in snippets/logging) doesn't contains anything related to this issue.