Quantcast
Channel: Active questions tagged https - Stack Overflow
Viewing all articles
Browse latest Browse all 1854

Caddy reverse proxy configuration without ACME, with strict SNI

$
0
0

I want to use Caddy as a reverse proxy for my system. The system contains a backend running on localhost:8080 to which all traffic is redirected. The proxy listens for HTTP traffic on :80 and for HTTPS traffic on :443. In the system, there's also a storage (a Vault, Caddy was built with the Vault module) on which the certificates are stored.

I don't want Caddy to manage the certificates. The certs creation, renewal and deletion is done by another process. The only feature of Caddy I'm interested in is its ability to lazy load the certificates, I have a lot of them and I don't want to use a proxy that preloads them, it takes too much time.

When Caddy receives traffic on :443, it checks in its storage whether it has a certificate for the requested SNI. If it does, the TLS connection is established. If it doesn't, the connection is dropped, the client gets an HTTP error.

However, I'm not sure Caddy is able to do it. When I allow Caddy to manage certificates by providing an ACME configuration, it works. When I have certificates already and I only configure the storage, each HTTPS request leads to a failure.

As an example, here's a working Caddyfile, cert management is made by Caddy using ACME:

{    on_demand_tls {        ask http://my.checking.service/check    }    storage vault {        addresses "https://my.vault.instance"        token_path "/etc/caddy/vault_token"        secrets_mount_path secret        secrets_path_prefix caddy/certificates    }}http://:80 {    reverse_proxy :8080}https://:443 {    tls {        on_demand        issuer acme {            dir https://my.vault.instance/v1/pki_int/acme/directory            timeout 10m            disable_tlsalpn_challenge        }    }    reverse_proxy :8080}

Assuming http://my.checking.service/check allows me to create a certificate for https://my-domain.local, the result is that I get a .crt& .key for my-domain.local in the Vault instance. Further requests to https://my-domain.local don't lead to a certificate renewal as it already exists, Caddy just uses the one that has been generated, as expected.

Now I want to stop Caddy from issuing certificates, as mentioned, this is done by another process. I tried multiple directives, none of them was relevant for this goal and I find the documentation quite limited.

Here is my Caddyfile so far:

{    auto_https off    storage vault {        addresses "https://my.vault.instance"        token_path "/etc/caddy/vault_token"        secrets_mount_path secret        secrets_path_prefix caddy/certificates    }    debug}http://:80 {    reverse_proxy :8080}https://:443 {    tls {        # load caddy/certificates # This directive is of no use since the certs are not on the local storage, but I also tested with local storage, and it doesn't load the certs it has access to anyway ¯\_(ツ)_/¯        client_auth {            mode require_and_verify            # trust_pool file caddy/pki/authorities/local/root.crt # Same comment as for the `load` directive        }    }    reverse_proxy :8080}

Caddy is running on localhost, on the same computer I run the following command:

curl -vvLkI https://my-domain.local --connect-to 'my-domain.local:443:127.0.0.1'

And I get this error:

* Connecting to hostname: 127.0.0.1*   Trying 127.0.0.1:443...* Connected to (nil) (127.0.0.1) port 443 (#0)* ALPN: offers h2,http/1.1* TLSv1.3 (OUT), TLS handshake, Client hello (1):* TLSv1.3 (IN), TLS alert, internal error (592):* OpenSSL/3.0.17: error:0A000438:SSL routines::tlsv1 alert internal error* Closing connection 0curl: (35) OpenSSL/3.0.17: error:0A000438:SSL routines::tlsv1 alert internal error

Caddy can't find a certificate for this domain:

DEBUG   events  event   {"name": "tls_get_certificate", "id": "ea472fdf-59d8-43ec-90f8-7215a0ca057d", "origin": "tls", "data": {"client_hello":{"CipherSuites":[4866,4867,4865,49196,49200,159,52393,52392,52394,49195,49199,158,49188,49192,107,49187,49191,103,49162,49172,57,49161,49171,51,157,156,61,60,53,47,255],"ServerName":"my-domain.local","SupportedCurves":[29,23,30,25,24,256,257,258,259,260],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771,770,769],"RemoteAddr":{"IP":"127.0.0.1","Port":32874,"Zone":""},"LocalAddr":{"IP":"127.0.0.1","Port":443,"Zone":""}}}}DEBUG   tls.handshake   no matching certificates and no custom selection logic  {"identifier": "my-domain.local"}DEBUG   tls.handshake   no matching certificates and no custom selection logic  {"identifier": "*.local"}DEBUG   tls.handshake   no matching certificates and no custom selection logic  {"identifier": "*.*"}DEBUG   tls.handshake   no certificate matching TLS ClientHello {"remote_ip": "127.0.0.1", "remote_port": "32874", "server_name": "my-domain.local", "remote": "127.0.0.1:32874", "identifier": "my-domain.local", "cipher_suites": [4866, 4867, 4865, 49196, 49200, 159, 52393, 52392, 52394, 49195, 49199, 158, 49188, 49192, 107, 49187, 49191, 103, 49162, 49172, 57, 49161, 49171, 51, 157, 156, 61, 60, 53, 47, 255], "cert_cache_fill": 0, "load_or_obtain_if_necessary": true, "on_demand": false}DEBUG   http.stdlib     http: TLS handshake error from 127.0.0.1:32874: no certificate available for 'my-domain.local'

Long story short, I need a reverse proxy that can:

  • Share its certificate storage across multiple instances (in this case, Vault)
  • Handle a lot of certificates (in this case lazy loading)
  • Match certificates based on SNI
  • Strict SNI, TLS connections for a SNI that doesn't match a certificate are dropped

Is there a configuration that could make it or should I consider switching to another proxy?


Viewing all articles
Browse latest Browse all 1854

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>