[SOLVED] HTTPs to non-HTTP Backend, that needs to "know", transfer was HTTPs

1. My Caddy version (caddy version):


a. System environment:

docker image: caddy:2.0.0-rc.3-alpine

d. My complete Caddyfile or JSON config:

ipn.mydomain.de {
  reverse_proxy * unix//tmp/caddy.socket

3. The problem I’m having:

I want to use caddy to forward the requests to a unix socket. The socket is being created by an nginx from a passenger-standalone.

The routing is fine.

My problem is, that the request to https://ipn.mydomain.de is translated to http://ipn.mydomain.de in the socket.
The problem appears within the application, because the full url, which the browser “thinks” it has, is not transported to the application.

To solve this there are imho 2 options:

  1. Change the protocol on transfer, to fake the https scheme for the receiver, and hope, the application is able to work with it.

  2. Get Caddy to talk also with the destination socket (unix file) in SSL.

I don’t know, what is the common practice for such a situation, but I would expect option 2 to be the better one, especially for security reasons.
But I’m not sure, which kind of certificates are needed on the destination node. It’s funny, as I didnt want to get a hassle with certificates, and that’s why I started with caddy :wink:

Is there a way of “forwarding” the Certificates, to make the receiving application re-use the same certs? Or is it possible to create a wildcard local-signed certificate on the destination?
But how can Caddy talk SSL with a socket?

Back to my 2 options. I didnt get any of those to run.

I hope you can help me out,

thanks alot!

5. What I already tried:

Google, google, google, but the most documentation and examples I find for Caddy is V1.

I think this is what you need:

ipn.mydomain.de {
  reverse_proxy * unix//tmp/caddy.socket {
    transport http {

See the transport docs here:

1 Like

Thanks alot francislavoie for your fast feedback!

I really noticed the part in the doc, but I was like: I’m not looking for http connection in this layer, but for sockets explicitely.

transport defines how to communicate with the backend. Default is http .

Didnt realize, that it’s also working for “the extra step”… my fault.

A further question regarding the destination’s certificate:
When I first tried, I got the following error:
certificate is valid for localhost, not /tmp/caddy.socket

As it might make no sense (or even won’t work) to create a certificate for a host, which is called like a socket path, I wasn’t sure how to solve it.

I now accomplished with adding:

Ok, it’s working now (yay! ;-))
But is this the only way, to get this done, or do I miss something?

Thanks again!

I think if you add this as a reverse_proxy subdirective:

header_up Host localhost

I think you would get further, but if the certificate is self-signed, you’d still run into validation issues. You could make Caddy trust it with the tls_trusted_ca_certs option, but that might be brittle depending on how often the self-signed cert is refreshed or when it expires.

In Caddy v2.1 there will be an embedded ACME server, so you could use that to implement mTLS (mutual TLS) so that you can use your Caddy instance to issue certificates for your proxied service that the proxy can trust. That might be useful for you here, to avoid needing to turn off verification entirely.


Ok great, then I’m looking forward to this change.

Thanks again for your help!

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