Possible tls @except directive?

Decided not to start the post with the template and please don’t be upset - I assure you the request has nothing to do with the config :slight_smile: I am using Caddy as a reverse proxy for a lot of custom traffic. I have a working Caddyfile configured to my needs, but I’m just wondering if there exists a shorthand with Caddyfile for not applying the tls directive to specific sites?

I am using port 8080 for HTTP and 8443 for HTTPS, due to ports 80/443 being used for something else. So I apply for Let’sEncrypt certs manually and point to them them inside Caddyfile.

My Caddyfile is something like this

{
   http_port 8080
   https_port 8443
}
http://mysite.com {
   @exclude { not path /app1 /app2 /app3 ... /app100 }
   reverse_proxy /app1 172.0.0.1:80
   reverse_proxy /app2 172.0.0.2:80
   reverse_proxy /app3 172.0.0.3:80
   ...
   reverse_proxy /app100 172.0.0.100:80
   file_server
   root @exclude /var/www
}
https://mysite.com {
   tls /path/ssl.crt /path/ssl.key
   @exclude { not path /app1 /app2 /app3 ... /p100 }
   reverse_proxy /app1 172.0.0.1:80
   reverse_proxy /app2 172.0.0.2:80
   reverse_proxy /app3 172.0.0.3:80
   ...
   reverse_proxy /app100 172.0.0.100:80
   file_server
   root @exclude /var/www
}

As you can see, the HTTP and HTTPS blocks are basically identical apart from the tls directive. By separating them into different blocks, extra effort is needed to maintain them and to avoid mistakes, that is at least until I’ve figured out the JSON config method.

Is there way I can put both the http and https servers in the same block, and apply an exclude rule to the tls directive so that the tls setting is ignored by the HTTP service, similar to the behavior of Caddy1?

Many thanks.

1. Caddy version (caddy version):

v2.2.1 h1:Q62GWHMtztnvyRU+KPOpw6fNfeCD3SkwH7SfT1Tgt2c=

2. How I run Caddy:

service caddy start

a. System environment:

systemd

b. Command:

/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

c. Service/unit/compose file:

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

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

[Install]
WantedBy=multi-user.target

d. My complete Caddyfile or JSON config:

{
        http_port  8080
        https_port 8443
}
http://cyberpunk.buzz {
        @exclude { not path /app1 /app2 /app3 }
        reverse_proxy /app1 172.0.0.1:80
        reverse_proxy /app2 172.0.0.2:80
        reverse_proxy /app3 172.0.0.3:80
        file_server
        root @exclude /var/www
}
https://cyberpunk.buzz {
        tls /etc/ssl/caddy.pem /etc/ssl/caddy.key
        @exclude { not path /app1 /app2 /app3 }
        reverse_proxy /app1 172.0.0.1:80
        reverse_proxy /app2 172.0.0.2:80
        reverse_proxy /app3 172.0.0.3:80
        file_server
        root @exclude /var/www
}

Have to remove some of the paths to increase clarity.

3. The problem I’m having:

Need to repeat 99% of the configurations inside the HTTP and HTTPS block, as Caddy2 will throw startup error once a TLS directive exists in a configuration with HTTP.

4. Error messages and/or full log output:

Dec 22 22:26:27 Caddy caddy[2389]: {"level":"info","ts":1608647187.9637349,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
Dec 22 22:26:27 Caddy caddy[2389]: reload: adapting config using caddyfile: server listening on [:8080] is HTTP, but attempts to configure TLS connection policies
Dec 22 22:26:27 Caddy systemd[1]: caddy.service: Control process exited, code=exited, status=1/FAILURE

5. What I already tried:

Separate config blocks for HTTP and HTTPS

6. Links to relevant resources:

You can make use of snippets to reuse parts of your config in more than one place:

FWIW, I would rewrite your config like this:

	redir / https://www.cyberpunk.buzz

	handle /app1* {
		reverse_proxy 172.0.0.1:80
	}

	handle /app2* {
		reverse_proxy 172.0.0.2:80
	}

	handle /app3* {
		reverse_proxy 172.0.0.3:80
	}

	handle {
		root * /var/www
		file_server
	}

This makes use of the handle directive’s mutual exclusivity, so you can avoid the @exclude matcher. Only the first matching handle will be executed (and the one without a matcher is a fallback)

P.S. You have a syntax issue with the @exclude matcher FYI, you should omit the { } there if using single-line matcher syntax, or use the longer form with newlines; it’s not valid to have { } braces on a single line.

Thanks for the handle suggestion. I’ll give it a try and report back.

Just to confirm these handle { } directives are to be placed outside the http:// and https:// server scopes, right?

No, that needs to be inside a site block. Or if you use snippets (which are just fancy copy-paste in the Caddyfile, pasted where you import it) then it can be in the snippet.

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