How to setup SSH over HTTPS with Caddy?

1. Output of caddy version:


2. How I run Caddy:

Via NixOS’s config file

services = {
    caddy = {
        enable = true;
        globalConfig = builtins.readFile ./CaddyfileGlobal;
        extraConfig = builtins.readFile ./Caddyfile;

a. System environment:

NixOS 23.05

d. My complete Caddy config:

CaddyfileGlobal: Just my E-Mail.
    reverse_proxy localhost:8080
    root * /srv

3. The problem I’m having:

TL;DR: I am trying to setup SSH over HTTPS and don’t know how to do so with Caddy. This can be done with Apache, but I have a caddy setup. VPNs are not an option. Can someone point me in the right direction?

I’m in an environment, that blocks SSH connections. Not by simple port blocking, but by packet inspection. There exist two tools known to work around this: GitHub - bryanpkc/corkscrew: A tool for tunneling SSH through HTTP proxies and GitHub - proxytunnel/proxytunnel: Stealth tunneling through HTTP(S) proxies. Both methods work by instructing a proxy to perform an HTTP CONNECT for the SSH connection to be routed by. This worked, but not anymore with packet inspection. This is where SSL encryption comes in, which can be layered on top of SSH, to allow SSH connection to be indistinguishable from HTTPS connections. In that case the HTTP server, in my case Caddy, needs to play along.

The proxytunnel repo explains this setup along with an Apache sample setup:

If you want to have the first proxy connect to another http proxy (like one you can control, specify -r proxy2:port. The first proxy will then connect to this remote proxy, which will be asked to connect to the requested destination. Note that authentication doesn’t (yet) work on this remote proxy. For more information regarding this feature, check out

If your proxy is more advanced, and does protocol inspection it will detect that your connection is not a real HTTPS/SSL connection. You can enable SSL encryption (using -e), which will work around this problem, however, you need to setup stunnel4 on the other side, or connect to a process that understands SSL itself.

The core of the question: How can Caddy be instructed to forward an SSH connection and apply its own SSL encryption?

6. Links to relevant resources:

The package used to for connections in question: GitHub - proxytunnel/proxytunnel: Stealth tunneling through HTTP(S) proxies
The article regarding setting up SSH over HTTPS with Apache:

Caddy doesn’t have CONNECT support right now. But the Caddy2 support · Issue #72 · caddyserver/forwardproxy · GitHub plugin might do that? I don’t know, never had a usecase for it myself so I don’t have a good understanding of how that plugin works.

You could use GitHub - mholt/caddy-l4: Layer 4 (TCP/UDP) app for Caddy to terminate TLS traffic and proxy raw TCP, but I don’t know if that works for your usecase?

That’s a pretty old version at this point, make sure to use the latest version of Caddy, 2.7.5.

Interesting. 2.6.4 is the newest version in the NixOS repo. I contacted the package maintainers about it.

So basically, install PullRequest Support Caddy 2 by mholt · Pull Request #74 · caddyserver/forwardproxy · GitHub as a plugin somehow and try it out is the play here?

In that case Caddy does not apply its own encryption and I would need to implement it myself using Caddy’s certificates, which is a headache and a half. Do I understand that correctly? At this point it might make sense to go the Apache route and reverse-proxy Apache maybe?

No, it does. Caddy would automate TLS cert issuance and terminate TLS which means it would encrypt from between the client and Caddy, and then send the TLS-decrypted TCP bytes to whatever upstream server you want.

But the client would need to know how to wrap its traffic with a TLS layer, and I don’t know if that’s the case for what you’re trying to do.

Probably. You can use xcaddy to build Caddy with the plugin. Maybe something like xcaddy build --with

First of all, thanks for the mail you sent to the nixpkgs Caddy maintainers a few hours ago.
There is however a misunderstanding how versioning (usually) works in nixpkgs.

You are on the 23.05 stable channel.
Stable channels, unlike the unstable channel, do not receive breaking updates in their lifecycle (with the exception of extremely security critical things like browsers).
23.05 will be EOL in around two months time, with 23.11 getting released end of next month.

Because the bump from had breaking changes, we (the nixpkgs maintainers) decided against backporting it from unstable to 23.05 (stable).

There are, as mentioned above, exceptions to this.
2.7.5 contained a fix for the HTTP/2 rapid reset issue.

Given it’s only low to medium severity in combination to it being unlikely to be exploited on most instances and the ease of simply using the Caddy package provided from the nixpkgs unstable channel, I decided against backporting it.

2.6.4 is the latest version in the stable (non-breaking) 23.05 channel.
2.7.5 is the latest version in the unstable (breaking) unstable channel.

See NixOS Search.

23.11’s branch-off from unstable is soon, and thus will contain whatever the unstable channel is on when that happens, followed by receiving non-breaking backports, in its lifecycle, as usual.


Ohh, thanks for the clarification!

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