SSL on multiple ports

1. Caddy version (caddy version):

v2.4.0 h1:yHnnbawH2G3ZBP2mAJF4XBLnJanqhULLP/wu01Qi9Io=

2. How I run Caddy:

caddy run

a. System environment:

Debian GNU/Linux 10

b. Command:

caddy run

c. Service/unit/compose file:

Paste full file contents here.
Make sure backticks stay on their own lines,
and the post looks nice in the preview pane.

d. My complete Caddyfile or JSON config:

(to-lower) {
        @{args.1} path_regexp {args.1} (.*)\.{args.0}
        redir @{args.1} {re.{args.1}.1}.{args.1}
}

:8080 {
        tls {
                on_demand
        }
        root * /var/www/
        }

:443 {
        tls {
                on_demand
        }
 import to-lower JPG jpg
        import to-lower JPEG jpeg
        import to-lower PNG png
        import to-lower GIF gif

        uri replace "%20" "-"
        uri replace " " "-"
        uri replace "(" ""
        uri replace ")" ""

 uri path_regexp "[?[\]\\=<>;,\"'&$#*()|~`!{}%+]" ""

  reverse_proxy 10.10.10.101 {
        header_up X-Forwarded-Proto https
        header_up X-Forwarded-Port 443
        }
}

3. The problem I’m having:

I would like to be able to use SSL both on port 443 and 8080. So I can serve an information page for visitors being banned by fail2ban by forwarding port 443 to 8080 for those blocked users.

4. Error messages and/or full log output:

curl -v https://www.domain.com:8080
*   Trying xxx.xx.xx.xx...
* TCP_NODELAY set
* Connected to www.domain.com (xxx.xx.xx.xx) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

a curl -v https://www.domain.com is working flawless.

5. What I already tried:

I’m not sure what else to try to get this working, if it’s even possible at all.

6. Links to relevant resources:

I’m a bit confused, but does your :8080 block work without TLS just as a http server?

The host block doesn’t appear to have any serving directives after setting root (root (Caddyfile directive) — Caddy Documentation)

Did you want to add a file_server directive?

It seems to work both with and without the file_server directive.

So over http the index.html would load, but over https it doesn’t.

Hmm, can you share the caddy logs as well, what you’re seeing doesn’t seem possible based on the caddy adapt output for your Caddyfile.

If you remove the 443 port does the 8080 port work?

Your error message definitely makes it seem like TLS isn’t even being attempted; it makes me wonder if caddy is even serving the responses.

Also, if you don’t need on_demand you could try to see if you see different behavior with explicit https domains in your config.

Also,

    header_up X-Forwarded-Proto https
    header_up X-Forwarded-Port 443

does this change anything in your config, those should be added for you whenever you use reverse_proxy.

That’s weird, as I specify only one domain explicit like:

www.domain.com:8080 {
        tls {
                on_demand
        }

respond "Hello, world!"

}

Then this does work perfectly fine over SSL.

And all other domains handshakes over SSL are successful as well. But I need to be able to get this working for a few hundred domains on demand.

Can someone confirm this isn’t possible to get working with on_demand SSL on multipe ports ?

It should work. Enabling debug logging would probably make the problem pretty obvious.

I added this to the top of my Caddyfile

{ debug }

But nothing gets logged when requesting a domain on port :8080 then.
So unfortunately that’s not giving any insights why it doesn’t work at all.

You must use newlines:

{
	debug
}

I do have them, code paste made them disappear above.

Screenshot 2021-06-10 14.47.09

If I combine the :443 and :8080 that does at least make all domains available on both ports.

Is there then a way to detect on what port the requests was received? As I could then get my logic there to separate the :8080 traffic to redirect it to a specific error page.

(to-lower) {
        @{args.1} path_regexp {args.1} (.*)\.{args.0}
        redir @{args.1} {re.{args.1}.1}.{args.1}
}

:443 :8080 {
        tls {
                on_demand
        }
 import to-lower JPG jpg
        import to-lower JPEG jpeg
        import to-lower PNG png
        import to-lower GIF gif

        uri replace "%20" "-"
        uri replace " " "-"
        uri replace "(" ""
        uri replace ")" ""

 uri path_regexp "[?[\]\\=<>;,\"'&$#*()|~`!{}%+]" ""

  reverse_proxy 10.10.10.101 {
        header_up X-Forwarded-Proto https
        header_up X-Forwarded-Port 443
        }
}

This does the trick… Still strange my original solution doesn’t seem to work as expected.

        @blocked {
                header_regexp Host :8080
        }

        respond @blocked "Hello, world!"