Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS

Started by Monviech (Cedrik), February 09, 2024, 01:31:44 PM

Previous topic - Next topic
Hello, please share your Caddyfile and point to the spot that does not work. Otherwise it will be hard to help you. You can find the Caddyfile in "Diagnostics". Make sure you omit sensitive information (like API keys etc...)
Hardware:
DEC740

There you go!

# DO NOT EDIT THIS FILE -- OPNsense auto-generated file


# caddy_user=root

# Global Options
{
log {
include http.log.access.6a100fb9-863d-4a8e-a6dc-6aaad5598184
output net unixgram//var/run/caddy/log.sock {
}
format json {
time_format rfc3339
}
}

email *email*
grace_period 10s
import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


# Reverse Proxy Domain: "ef64738b-136e-4bba-b267-f6307990db7b"
domain.tld {
tls /var/db/caddy/data/caddy/certificates/temp/66a3c470808dc.pem /var/db/caddy/data/caddy/certificates/temp/66a3c470808dc.key

handle {
reverse_proxy 127.0.0.1 {
transport http {
tls
}
}
}

abort
}
[u][b]
This section does not work[/b][/u]
# Reverse Proxy Domain: "6a100fb9-863d-4a8e-a6dc-6aaad5598184"
*.local.domain.tld {
log 6a100fb9-863d-4a8e-a6dc-6aaad5598184
tls /var/db/caddy/data/caddy/certificates/temp/66a26c37d9228.pem /var/db/caddy/data/caddy/certificates/temp/66a26c37d9228.key

@febd140e-6307-4080-8419-d1de0c6a23b2 {
host *.local.domain.tld
}
handle @febd140e-6307-4080-8419-d1de0c6a23b2 {
handle {
reverse_proxy *local 192 address*:port {
transport http {
tls
tls_server_name *.local.domain.tld
}
}
}

abort
}

@dbd15585-f172-4fbd-8524-13d6dcd351af {
client_ip local 192 address
}

handle @dbd15585-f172-4fbd-8524-13d6dcd351af {
}

abort
}


*.local.domain.tld {
log 6a100fb9-863d-4a8e-a6dc-6aaad5598184
tls /var/db/caddy/data/caddy/certificates/temp/66a26c37d9228.pem /var/db/caddy/data/caddy/certificates/temp/66a26c37d9228.key

@febd140e-6307-4080-8419-d1de0c6a23b2 {
host *.local.domain.tld
}


This does not make sense. You defined a wildcard domain, and then put the same wildcard domain as its subdomain?

If "*.local.domain.tld" is set up, it should then be something like "sub1.local.domain.tld" that matches below it.

It is explained here in the docs.
https://docs.opnsense.org/manual/how-tos/caddy.html#wildcard-domain-with-subdomains

If your intention was to send all subdomains to that target, regardless of what they are, put the handler directly on the wildcard domain, without choosing any subdomain for it.
Hardware:
DEC740

'ive redacted wrongly sorry :

*.local.domain.tld {
   log 6a100fb9-863d-4a8e-a6dc-6aaad5598184

@febd140e-6307-4080-8419-d1de0c6a23b2 {
      host sub1.local.domain.tld

The Caddyfile does validate under diagnostics, but still won't proxy to the local server.

You have enabled TLS, does that mean your internal service has a globally trusted certificate? Because if not, you need to make sure Caddy trusts the certificate.

Check this out, it explains it: https://docs.opnsense.org/manual/how-tos/caddy.html#reverse-proxy-the-opnsense-webgui

Otherwise, disable both TLS options you have set, and enable "TLS Insecure Skip Verify", it will skip certifocate handling and the internal HTTPS connection will "just work".
Hardware:
DEC740

Hey Monviech, I'm sorry to have to ask you again. I think I've understood it now and the tutorials I've found give me a better feeling about going in the right direction. However, what I still don't understand is that the examples for a DNS override assume that Caddy is on a system outside the firewall/OPNsense. I'm alluding to the fact that you specify an IP for an override.... What kind of IP do I specify if the respective gateway, i.e. Caddy, is to be addressed from the respective subnet? I have several VLANS for which I would like to set the override. Presumably there is no such thing as ThisFirewall for this...

It does not matter for which of the interface IP addresses you set the DNS Override. In each of the VLANs, the OPNsense is the default gateway. It receives all packets by default.

That means, regardless of which IP you take for your single override, as long as it points to an interface the OPNsense has, the traffic will reach Caddy.

Just make sure you have a Firewall rule on each VLAN that allows HTTP and HTTPS to "This Firewall" and each VLAN uses Unbound as their DNS server.
Hardware:
DEC740

Oh. I assumed that I have to redirect e.g. nextcloud.example.com to 192.168.1.1 LAN GW so that it arrives at the firewall and thus at Caddy and Caddy forwards it to the Nextcloud 192.168.10.10.. So I just have to directly name the destination on which the Nextcloud is running? For example, 192.168.10.10? That's crazy. Just crazy!

Just skip DNS overrides altogether and use the external address of your firewall even from internal networks. Caddy is layer 7 proxying, so neither NAT nor NAT reflection is necessary.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

Quote from: Baender on July 26, 2024, 10:29:25 PM
Oh. I assumed that I have to redirect e.g. nextcloud.example.com to 192.168.1.1 LAN GW so that it arrives at the firewall and thus at Caddy and Caddy forwards it to the Nextcloud 192.168.10.10.

That assumption is right, I also explained that.

But I especially didn't write dns overrides into the Caddy docs since its just kinda wonky in practice. Patrick is right here.
Hardware:
DEC740

I guess I need more knowledge about these layers.. I just ask, because I have noticed, that every call of my subdomain, from my local network, has the destination of my WAN address. So I assumed, that the request for an internal service is send to the Unbound DNS, then to IONOS and then back to the FW/Caddy.. That's the story behind my questions..

No, it is not sent across the internet. Read what I wrote again earlier. Since the OPNsense also has your WAN address, Caddy listens on there and will just bounce it back into your network.

Also its no shame to ask, networking is pretty complex, so you should definitely read some more and try stuff out. ;)
Hardware:
DEC740

Quote from: Monviech on July 26, 2024, 10:06:16 PM
You have enabled TLS, does that mean your internal service has a globally trusted certificate? Because if not, you need to make sure Caddy trusts the certificate.

Check this out, it explains it: https://docs.opnsense.org/manual/how-tos/caddy.html#reverse-proxy-the-opnsense-webgui

Otherwise, disable both TLS options you have set, and enable "TLS Insecure Skip Verify", it will skip certifocate handling and the internal HTTPS connection will "just work".

Disabling evrything TLS made no change.

Sorry I don't know then. Without some debug logs its uncertain what happens there. I need some info that is not anynomized so theres no mistakes due to wrong omissions.

- Check your DNS, does "nslookup yoursubdomainname" really resolve to the IP address of the OPNsense?

- If Yes, Whats the output of "curl -v subdomainname"

- What do the debug logs show when you try to reach it?

- Which kind of application is listening there? Is it a HTTP or HTTPS application.

- If the application demands a HTTPS connection, did you enable "TLS Insecure Skip Verify" like I asked?

- When you deactivate the handler for the subdomain AND disable "abort", do you at least see an empty webpage and the certificate?

If its a very complex issue, you can also go to https://caddy.community and fill out their help template. Show your old nginx configuration, and your current Caddyfile. That way they can see if theres a mistake.
Hardware:
DEC740

Since there are a lot of troubleshooting requests, I have expanded the documentation:

https://github.com/Monviech/opnsense-docs/blob/caddy-layer4/source/manual/how-tos/caddy.rst#help-nothing-works

It is not live in the main docs yet, but it can be read here.
Hardware:
DEC740