Using caddy layer4 for TLS passthrough

1. The problem I’m having:

I am currently using Caddy to serve a bunch of sites with automatic HTTPS and it has been working perfectly for this use-case.

However, I now need Caddy to serve another site that manages its own certificates by passing through all requests to that site (including ACME challenges). After doing some research, I found the caddy-l4 repository and I understand that it should be able to do what I want. I converted my Caddyfile to JSON and tried to add in the layer4 configuration by hand but it does not seem to work.

Here’s what I’ve tried to do:

  1. I left my configuration for the http app as is.
  2. I added a listener_wrapper and set layer4 as a wrapper.
  3. Inside the wrapper, I matched the SNIs of the site I want to pass through and proxied it to the service handling the site.

After doing this, when trying to load a site that is managed by Caddy’s http app, I run into the following:

$ curl -vvL https://abc.xyz.org
*   Trying 143.215.130.109:443...
* TCP_NODELAY set
* Connected to abc.xyz.org (143.215.130.109) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* 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=abc.xyz.org
*  start date: Dec 18 23:15:19 2023 GMT
*  expire date: Mar 17 23:15:18 2024 GMT
*  subjectAltName: host "abc.xyz.org" matched cert's "abc.xyz.org"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55b751f820c0)
> GET / HTTP/2
> Host: abc.xyz.org
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* http2 error: Remote peer returned unexpected data while we expected SETTINGS frame.  Perhaps, peer does not support HTTP/2 properly.
* OpenSSL SSL_write: Connection reset by peer, errno 104
* Failed sending HTTP2 data
* Connection #0 to host abc.xyz.org left intact
curl: (55) OpenSSL SSL_write: Connection reset by peer, errno 104

I am very new to Caddy’s JSON config and I’m sure there are some gaps in my understanding. I am also aware that there are older topics on this forum that address this but I am not sure if they are still relevant. I would also appreciate a solution that prevents me from writing more JSON than I need to xD.

2. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

3. How I installed and ran Caddy:

I installed Caddy using xcaddy -

xcaddy build --with github.com/mholt/caddy-l4

a. System environment:

Ubuntu 22.04.3 LTS
systemd 249

b. Command:

N/A - I run Caddy using the systemd service, see below.

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/config.json
ExecReload=/usr/bin/caddy reload --config /etc/caddy/config.json --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddy config:

{
    "logging": {
        "sink": {
            "writer": {
                "filename": "/var/log/caddy/sink.log",
                "output": "file"
            }
        },
        "logs": {
            "default": {
                "exclude": [
                    "http.log.access.log0",
                    "http.log.access.log1",
                    "http.log.access.log2",
                    "http.log.access.log3",
                    "http.log.access.log4"
                ],
                "writer": {
                    "filename": "/var/log/caddy/default.log",
                    "output": "file"
                },
                "level": "DEBUG"
            },
            "log0": {
                "writer": {
                    "filename": "/var/log/caddy/def.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log0"
                ]
            },
            "log1": {
                "writer": {
                    "filename": "/var/log/caddy/abc.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log1"
                ]
            },
            "log2": {
                "writer": {
                    "filename": "/var/log/caddy/coolsite.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log2"
                ]
            },
            "log3": {
                "writer": {
                    "filename": "/var/log/caddy/files.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log3"
                ]
            },
            "log4": {
                "writer": {
                    "filename": "/var/log/caddy/website.log",
                    "output": "file"
                },
                "include": [
                    "http.log.access.log4"
                ]
            }
        }
    },
    "apps": {
        "http": {
            "servers": {
                "srv443": {
                    "listen": [
                        ":443",
                        ":853"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": [
                                        "abc.xyz.org",
                                        "abc.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:1111"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "def.xyz.org",
                                        "def.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5003"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ],
                                            "match": [
                                                {
                                                    "path": [
                                                        "/randompath*"
                                                    ]
                                                }
                                            ]
                                        },
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5002"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "files.xyz.org",
                                        "files.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site-hosted-files"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/caddy/Caddyfile"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "www.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "static_response",
                                                    "headers": {
                                                        "Location": [
                                                            "https://xyz.fail{http.request.uri}"
                                                        ]
                                                    },
                                                    "status_code": 301
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "coolsite.dev"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:7732"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/caddy/Caddyfile"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ],
                    "listener_wrappers": [
                        {
                            "wrapper": "layer4",
                            "routes": [
                                {
                                    "match": [
                                        {
                                            "tls": {
                                                "sni": [
                                                    "coolsite-backend.io",
                                                    "admin.coolsite-backend.io",
                                                    "www.coolsite-backend.io",
                                                    "mfa-test.coolsite-backend.io",
                                                    "mdm.coolsite-backend.io",
                                                    "ns.coolsite-backend.io"
                                                ]
                                            }
                                        }
                                    ],
                                    "handle": [
                                        {
                                            "handler": "subroute",
                                            "routes": [
                                                {
                                                    "handle": [
                                                        {
                                                            "handler": "proxy",
                                                            "upstreams": [
                                                                {
                                                                    "dial": [
                                                                        "localhost:8443"
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ],
                    "logs": {
                        "logger_names": {
                            "abc.xyz.fail": "log1",
                            "abc.xyz.org": "log1",
                            "coolsite.dev": "log2",
                            "files.xyz.fail": "log3",
                            "files.xyz.org": "log3",
                            "xyz.fail": "log4",
                            "def.xyz.fail": "log0",
                            "def.xyz.org": "log0"
                        },
                        "skip_hosts": [
                            "www.xyz.fail"
                        ]
                    }
                }
            }
        }
    }
}

5. Links to relevant resources:

I’m not sure that the listener wrapper approach is functional yet. @WeidiDeng can you clarify?

I think the error you’re seeing is the same I talk about in the solution to https://caddy.community/t/combining-the-layer4-and-http-apps-ssl-pass-through-http-file-server-reverse-proxy

You need to send a non HTTP2 request to your server for it to work properly. But as that solution says, it’s not ideal.

As far as I can tell, the solution in that thread solves your problem exactly but it doesn’t use listener wrappers.

I keep a caddyfile which contains my http server configurations and then use the adapt command to produce my json that I copy and paste my layer4 config into the top of. So I usually don’t need to write json (or yaml in my case) ever.

1 Like

Thank you for replying!

You need to send a non HTTP2 request to your server for it to work properly. But as that solution says, it’s not ideal.

Is there a way to force Caddy to indicate that it only accepts HTTP 1.1 requests? I see in your solution that you talk about configuring the TLS handler like this:

{
	"handler": "tls",
	"connection_policies": [
		{"alpn": ["http/1.1"]}
	}
}

However, I don’t see this in your final config so I’m confused if it’s actually needed and if it is, where in my config do I add it?

Lastly, performance considerations aside, are you aware of any downsides to accepting only HTTP 1.1?

I keep a caddyfile which contains my http server configurations and then use the adapt command to produce my json that I copy and paste my layer4 config into the top of. So I usually don’t need to write json (or yaml in my case) ever.

That is exactly what I tried to do but failed spectacularly :smiley:

1 Like

Is there a way to force Caddy to indicate that it only accepts HTTP 1.1 requests? I see in your solution that you talk about configuring the TLS handler like this:

It goes after the handler: "tls" block that you can see in the final JSON config. It’s not in the final config since it’s not useful, though it would solve your immediate problem with curl I guess.

Lastly, performance considerations aside, are you aware of any downsides to accepting only HTTP 1.1?

As I said in that post:

It also breaks most of the automatic HTTPS functionality of caddy. You’ll be able to automate certificates via the tls app but you won’t get automatic HTTP → HTTPS redirects for example.

But I’m not familiar with the method you chose (wrappers) so it could be a different mechanism causing problems.

That is exactly what I tried to do but failed spectacularly

You can see my solution doens’t use listener_wrappers and just adds layer4 as an app with a couple routes. One forwarding based on TLS and one sending to the normal http app.

Is there a reason you are using listener_wrappers?

I also don’t see https_port in your json though as I said in my solution, it’s required for this setup to work correctly. You can’t listen to :443 since your layer4 app will be doing that.

It is possible that your solution should work for other reasons but I’m solving the exact same problem as detailed in the old post and it’s working with no problems for me.

Let me know if you have a specific question about the final solution there; I tried to write enough so that it was clear.

2 Likes

Thank you again for your reply! I think I managed to solve it. I now have HTTP 2, and automatic HTTP → HTTPS redirect working with TLS passthrough. This may be because it has been more than 2 years since you made your post and things have changed in the internals of layer4. I am not entirely sure.

I ended up ditching the idea of using the listener_wrapper and instead used your approach of proxying connections from the layer4 app to the http app.

Here’s my updated JSON config -

{
    "logging": {
        "sink": {
            "writer": {
                "filename": "/var/log/caddy/sink.log",
                "output": "file"
            }
        },
        "logs": {
            "default": {
                "exclude": [
                    "http.log.access.log0",
                    "http.log.access.log1",
                    "http.log.access.log2",
                    "http.log.access.log3",
                    "http.log.access.log4"
                ],
                "writer": {
                    "filename": "/var/log/caddy/default.log",
                    "output": "file"
                },
                "level": "DEBUG"
            },
            "log0": {
                "writer": {
                    "filename": "/var/log/caddy/def.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log0"
                ]
            },
            "log1": {
                "writer": {
                    "filename": "/var/log/caddy/abc.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log1"
                ]
            },
            "log2": {
                "writer": {
                    "filename": "/var/log/caddy/coolsite.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log2"
                ]
            },
            "log3": {
                "writer": {
                    "filename": "/var/log/caddy/files.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log3"
                ]
            },
            "log4": {
                "writer": {
                    "filename": "/var/log/caddy/website.log",
                    "output": "file"
                },
                "include": [
                    "http.log.access.log4"
                ]
            }
        }
    },
    "apps": {
        "http": {
            "https_port": 6969,
            "servers": {
                "srv443": {
                    "listen": [
                        ":80",
                        ":6969"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": [
                                        "abc.xyz.org",
                                        "abc.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:1111"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "def.xyz.org",
                                        "def.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5003"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ],
                                            "match": [
                                                {
                                                    "path": [
                                                        "/randompath*"
                                                    ]
                                                }
                                            ]
                                        },
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5002"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "files.xyz.org",
                                        "files.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site-hosted-files"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/caddy/Caddyfile"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "www.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "static_response",
                                                    "headers": {
                                                        "Location": [
                                                            "https://xyz.fail{http.request.uri}"
                                                        ]
                                                    },
                                                    "status_code": 301
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "coolsite.dev"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:7732"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/caddy/Caddyfile"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ],
                    "logs": {
                        "logger_names": {
                            "abc.xyz.fail": "log1",
                            "abc.xyz.org": "log1",
                            "coolsite.dev": "log2",
                            "files.xyz.fail": "log3",
                            "files.xyz.org": "log3",
                            "xyz.fail": "log4",
                            "def.xyz.fail": "log0",
                            "def.xyz.org": "log0"
                        },
                        "skip_hosts": [
                            "www.xyz.fail"
                        ]
                    }
                }
            }
        },
        "layer4": {
            "servers": {
                "enterprise": {
                    "listen": [
                        ":443",
                        ":853"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "tls": {
                                        "sni": [
                                            "coolsite-backend.io",
                                            "admin.coolsite-backend.io",
                                            "www.coolsite-backend.io",
                                            "mfa-test.coolsite-backend.io",
                                            "mdm.coolsite-backend.io",
                                            "ns.coolsite-backend.io",
                                            "coolsite-backup.com"
                                        ]
                                    }
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "proxy",
                                    "upstreams": [
                                        {
                                            "dial": [
                                                "localhost:8443"
                                            ]
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "handle": [
                                {
                                    "handler": "proxy",
                                    "upstreams": [
                                        {
                                            "dial": [
                                                "localhost:6969"
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }
}

Notably, I have my http app also listen on port 80 along with port 6969. My mental model is that when the http app encounters traffic on port 80, it redirects it to port 443. Here, the traffic is handled by layer4 which kicks it back to the http app on 6969, enabling HTTP → HTTPS redirects to work the way they did before.

Before I call this complete, I still have two unresolved questions, which I’m hoping someone can address:

  1. The IP addresses that the http app now sees are all 127.0.0.1. Is there any way I can preserve the client’s original IP addresses?
  2. I am not sure if automatic certificate management will continue to work given these changes. Is there a way that I can verify that it is enabled and working?
1 Like

You can enable PROXY protocol on the l4 proxy, and add the proxy_protocol listener wrapper in the http app. That’ll pass it through.

That’s handled by the tls app. As long as you list the domains in there to automate, it’ll work. Or, if the routes in your http app have a host matcher at the highest level, then Automatic HTTPS will pick them up and automate TLS for those hostnames. Check your logs, at startup it’ll say which domains are being managed for TLS.

1 Like

Thank you so much! I configured the proxy protocol like you suggested and checked the logs to verify that Caddy was picking up the correct domains for automatic HTTPS.

That pretty much resolves everything I set out to do.

2 Likes

Quick update: I realized that my automatic HTTP → HTTPS redirection was actually broken.

I stopped listening explicitly on port 80 and that solved it. Here’s my final config for anyone who might find it useful:

{
    "logging": {
        "sink": {
            "writer": {
                "filename": "/var/log/caddy/sink.log",
                "output": "file"
            }
        },
        "logs": {
            "default": {
                "exclude": [
                    "http.log.access.log0",
                    "http.log.access.log1",
                    "http.log.access.log2",
                    "http.log.access.log3",
                    "http.log.access.log4"
                ],
                "writer": {
                    "filename": "/var/log/caddy/default.log",
                    "output": "file"
                }
            },
            "log0": {
                "writer": {
                    "filename": "/var/log/caddy/def.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log0"
                ]
            },
            "log1": {
                "writer": {
                    "filename": "/var/log/caddy/abc.log",
                    "output": "file",
                    "roll_keep": 1000,
                    "roll_keep_days": 900
                },
                "include": [
                    "http.log.access.log1"
                ]
            },
            "log2": {
                "writer": {
                    "filename": "/var/log/caddy/coolsite.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log2"
                ]
            },
            "log3": {
                "writer": {
                    "filename": "/var/log/caddy/files.log",
                    "output": "file",
                    "roll_keep": 100,
                    "roll_keep_days": 90
                },
                "include": [
                    "http.log.access.log3"
                ]
            },
            "log4": {
                "writer": {
                    "filename": "/var/log/caddy/website.log",
                    "output": "file"
                },
                "include": [
                    "http.log.access.log4"
                ]
            }
        }
    },
    "apps": {
        "http": {
            "https_port": 6969,
            "servers": {
                "srv443": {
                    "listen": [
                        ":6969"
                    ],
                    "listener_wrappers": [
                        {
                            "wrapper": "proxy_protocol"
                        },
                        {
                            "wrapper": "tls"
                        }
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "host": [
                                        "abc.xyz.org",
                                        "abc.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:1111"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "def.xyz.org",
                                        "def.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5003"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ],
                                            "match": [
                                                {
                                                    "path": [
                                                        "/randompath*"
                                                    ]
                                                }
                                            ]
                                        },
                                        {
                                            "group": "group5",
                                            "handle": [
                                                {
                                                    "handler": "subroute",
                                                    "routes": [
                                                        {
                                                            "handle": [
                                                                {
                                                                    "handler": "reverse_proxy",
                                                                    "upstreams": [
                                                                        {
                                                                            "dial": "localhost:5002"
                                                                        }
                                                                    ]
                                                                }
                                                            ]
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "files.xyz.org",
                                        "files.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site-hosted-files"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/*"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "www.xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "static_response",
                                                    "headers": {
                                                        "Location": [
                                                            "https://xyz.fail{http.request.uri}"
                                                        ]
                                                    },
                                                    "status_code": 301
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "coolsite.dev"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "reverse_proxy",
                                                    "upstreams": [
                                                        {
                                                            "dial": "localhost:7732"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        },
                        {
                            "match": [
                                {
                                    "host": [
                                        "xyz.fail"
                                    ]
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "subroute",
                                    "routes": [
                                        {
                                            "handle": [
                                                {
                                                    "handler": "vars",
                                                    "root": "/opt/xyz-site"
                                                },
                                                {
                                                    "handler": "file_server",
                                                    "hide": [
                                                        "/etc/*"
                                                    ]
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ],
                            "terminal": true
                        }
                    ],
                    "logs": {
                        "logger_names": {
                            "abc.xyz.fail": "log1",
                            "abc.xyz.org": "log1",
                            "coolsite.dev": "log2",
                            "files.xyz.fail": "log3",
                            "files.xyz.org": "log3",
                            "xyz.fail": "log4",
                            "def.xyz.fail": "log0",
                            "def.xyz.org": "log0"
                        },
                        "skip_hosts": [
                            "www.xyz.fail"
                        ]
                    }
                }
            }
        },
        "layer4": {
            "servers": {
                "enterprise": {
                    "listen": [
                        ":443",
                        ":853"
                    ],
                    "routes": [
                        {
                            "match": [
                                {
                                    "tls": {
                                        "sni": [
                                            "coolsite-backend.io",
                                            "admin.coolsite-backend.io",
                                            "www.coolsite-backend.io",
                                            "mfa-test.coolsite-backend.io",
                                            "mdm.coolsite-backend.io",
                                            "ns.coolsite-backend.io",
                                            "coolsite-backup.com"
                                        ]
                                    }
                                }
                            ],
                            "handle": [
                                {
                                    "handler": "proxy",
                                    "upstreams": [
                                        {
                                            "dial": [
                                                "localhost:8443"
                                            ]
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "handle": [
                                {
                                    "handler": "proxy",
                                    "proxy_protocol": "v2",
                                    "upstreams": [
                                        {
                                            "dial": [
                                                "localhost:6969"
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }
}
1 Like

I’m looking to implement this for my use-case as well, but am unsure if it’s the right tool. This is regarding How to setup SSH over HTTPS with Caddy?
I have SSH being tunneled through HTTPS to access SSH in an environment with a packet sniffing firewall blocking SSH connections via GitHub - proxytunnel/proxytunnel: Stealth tunneling through HTTP(S) proxies.

Since Caddy doesn’t support HTTP CONNECT, I have to use Apache to handle this.
However, I need this to be available on subdomain.example.com and example.com is handled by Caddy. I naively thought, that simply doing a reverse_proxy on caddy from subdomain.example.com to Apache would allow this to work, but it doesn’t, Caddy breaks the HTTP CONNECT.

I guess the layer4 plugin would allow Caddy to passthrough the encrypted Apache packages. Is this correct? Can Caddy + layer4 be setup to passthrough subdomain.example.com of example.com to Apache without messing with the signal?

It should, yeah. You can match the subdomain using TLS-SNI and use l4’s proxy to transparently send the TCP bytes as-is upstream, and for other domains proxy it to your Caddy HTTP server instead.

1 Like

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