OPNsense Forum

English Forums => Tutorials and FAQs => Topic started by: Monviech (Cedrik) on February 09, 2024, 01:31:44 PM

Title: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on February 09, 2024, 01:31:44 PM
Like this plugin? Consider donating to me. 8)
(https://upload.wikimedia.org/wikipedia/de/thumb/5/5f/PayPal_2023_logo.svg/1920px-PayPal_2023_logo.svg.png) (https://www.paypal.com/paypalme/pischem)




This plugin is simple to use and very easy to configure. Yet, it also offers plenty of advanced options for more complicated usecases at the same time.

- For Reverse Proxy + automatic Let's Encrypt Certificates follow these steps:

1. Installation (https://docs.opnsense.org/manual/how-tos/caddy.html#installation)
2. Prepare OPNsense for Caddy after installation (https://docs.opnsense.org/manual/how-tos/caddy.html#prepare-opnsense-for-caddy-after-installation)
3. Creating a simple reverse proxy (https://docs.opnsense.org/manual/how-tos/caddy.html#creating-a-simple-reverse-proxy)
(Please note that the docs have been updated for 24.7, so there might be different terminology at a few steps.)

- For Dynamic DNS follow this additional step:

4. Dynamic DNS (https://docs.opnsense.org/manual/how-tos/caddy.html#dynamic-dns)

Layer 4 module:

https://docs.opnsense.org/manual/how-tos/caddy.html#caddy-layer4-proxy




If you have questions or find an issue, please ask here or post on Github, I will answer them and fix problems as soon as possible.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: gspannu on February 14, 2024, 10:11:50 PM
Thankyou. A very well written piece of software, a great plugin that makes Caddy a breeze to use.

Great work done... hope to see this integrated into the official OPNsense library someday.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jemkewl on February 21, 2024, 03:01:21 AM
Appreciate the work you've done and the help on github.

I have several handlers working now for my domain.  Only one is accessible externally (Internet) and the rest are all available internally only on my LAN or VPN via the Access lists functions.  This was far easier than HAProxy or nginx for my needs.  I've actually disabled the configs I had there and migrated them to Caddy since my use cases are straightforward.

In an effort to try and give something back, I've front-ended my Unifi console with this Caddy plugin and wish to share a quick tutorial here.  There are many ways to do this (e.g. update the cert for Unifi itself to a Trusted Cert).  However, this method is potentially an easier way where we will just trust the Unifi cert.  Every 2 years or so, this cert will need to be updated.

Step 1 - Get the Unifi CA cert:  Many ways to do this, but opted for lazy way.  Navigate to your Unifi console in any browser.  Click the cert icon in the address bar (most likely will say "Not secure").  Then click the "cert is not valid" link or the link your browser has to show the cert.  Go to the details tab and find "Export".  Export the cert and save it to a location with a name you'll recognize (e.g. Unifi.crt).

Step 2 - Get the cert text: Right click on the "Unifi.crt" or whatever you named it and open it with notepad or notepad++ or vi or nano or your text editor of choice.  Copy the details to your clipboard:
At time of this writing for my version of the Unifi console the text for the Unifi.crt is/was:
-----BEGIN CERTIFICATE-----
MIIDfTCCAmWgAwIBAgIEZVl1bjANBgkqhkiG9w0BAQsFADBrMQswCQYDVQQGEwJV
UzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYwFAYDVQQK
DA1VYmlxdWl0aSBJbmMuMQ4wDAYDVQQLDAVVbmlGaTEOMAwGA1UEAwwFVW5pRmkw
HhcNMjMxMTE5MDIzOTQyWhcNMjYwMjIxMDIzOTQyWjBrMQswCQYDVQQGEwJVUzER
MA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYwFAYDVQQKDA1V
YmlxdWl0aSBJbmMuMQ4wDAYDVQQLDAVVbmlGaTEOMAwGA1UEAwwFVW5pRmkwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaxheTfuaMfIltQuageZS7T55k
cs9xGlvgP3QGGpqeEpk43lHJBZaJmhUtI91dFkfBxyMUBe5AcSWoazRpLYmIuDqI
6T1GDzwe38Hjsy+sCl/CLtjBqga4FCVhqDwMppqqgyBAU6eSLdHr3mTNQk21X5VS
rgU5/zNx9Yon9ChhIxxukqCqMneVXDr8gSGWB3n9AxwTeVm8xVEWWxd+1ho0KP+T
6mxy3UhygoKbgJgxGH8rXgoAwxV8J7YG/soJ5SrJBHm3mZEquUZkFnjmd7Vd0Sl0
6y+44mkxOa0f0evh9LYpvCfXT7Q/705Ucqn9u0lSK86yZN2hjf3GUU5koiOJAgMB
AAGjKTAnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBAGA1UdEQQJMAeCBVVuaUZpMA0G
CSqGSIb3DQEBCwUAA4IBAQCS9KXCOjT7tqplCrMR3CyeYQAOJsyr1fAGK6AF9jHO
KD7CidfR7ZJi/ocZABr7i+F2zSaPXw9PwHrbRF44uiTxHt5jlXLDhYNI/MqI2Yx/
yx1ddT1UiJF3MM4v8xx7CBpvBKYl6Wr8D561wT7ywb/PcGZ/N7TZbT3yqEr/W3CB
5LhDitlf+DZ0F/SmDFvmFdf0Y9vQuqrylYnTwTr4di7UUoPYbBFf3w4Uu4DAfROX
MoB9Jr0jBi7+nH+MtUHFtn1vcrRU8Q8O4TCq0S+WLGhbrILzBbrX6hCbsrzxEYzW
tzDGic7FQrRpqGfwfeCHsEU42LpBPpaIGKZXt3EhzYo9
-----END CERTIFICATE-----

Step 3 - Add cert to OPNsense trusted store:  Login to OPNsense console and go to System-> Trust -> Authorities.  Click the + to add a Trust Authority.
Descriptive name : Unifi's Self-Signed Console CA
Method: Import an existing Certificate Authority
Certificate data: paste the full text from Step 2
Click Save
(We will need to edit this trusted cert once it expires and replace it with the newly issued one.  with my current Unifi console version, that will be February 20th, 2026.  If upgrading the console version, the cert may change and need to be updated as well - depends on what Ubiquiti does with the Unifi Console)


Step 3 - Create the Unifi handler: Assuming domains, subdomains, etc. are all configured via other tutorials.
Create a "handler" in Caddy "Handlers" as normal like you would for any other http site with the backend server domain and port for the Unifi console in your infrastructure.  Unifi's console requires https, so to avoid the 502 and similar errors, we need to configure Caddy to "handle" the https.  This is completed by supplying the Subject Alternative Name (SAN) value from the Unifi.crt which is DNS Name=Unifi, the CA we added to the trusted authorities for OPNsense, and utilizing TLS between caddy and the Unifi console.

Handle type: handle
handle path: (blank).
backend server domain: your unifi's IP / hostname
backend server port: your unifi's port (usually 8443)
TLS: "checked"
TLS Trust CA Certificate: select the item named from Step 2 (e.g. Unifi's Self-Signed Console CA).
TLS Server Name: Unifi

Add a description, save and apply.  Navigate to the handler for Unifi's console and your connection should now be encrypted and trusted: https -> Caddy -> https to Unifi server.

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on February 21, 2024, 10:11:21 AM
Thank you a lot I have added your post to the main post as additional tutorial. ^^
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MeroP on March 04, 2024, 07:26:31 PM
My utmost respect. This is a very successful plugin. Simple, direct and, above all, easy to use for inexperienced users.
The alternative HAProxy/Nginx are really not characterized by their user-friendliness and simplicity.

WHERE CAN I BUY YOU A BEER OR COFFEE? would like to support your work!

Perhaps it would be possible to add a few more aspects, pitfalls and tips to the above tutorial.

- Specific syntax of the API key for the DNS challenge
- Where to find Subject Alternative Name (SAN)
- Instructions for e.g. Nextcloud etc.

What I have not yet managed to get right.

That the OPNsense internal calls are forwarded directly to the backend server and certificates are still issued by Caddy. All connections only succeed via HTTP without certificates. Could you help with an example or give me a hint? I have now tried it with Vaultwarden and Sterling PDF (both in a docker container), resolution to external works without problems even with wildcard, but to internal only as described above.

Many thanks for the great work and good luck with the integration in OPNsense!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 04, 2024, 07:47:10 PM
Hey, thanks for the praise. Right now I don't have any donations set up, I'm doing this mostly because I use this plugin myself excessively everywhere.

Regarding TLS Certificates, it's a good idea to follow this tutorial for a successful backend TLS connection. When you get this to work you can also get all other TLS examples to work: https://github.com/Monviech/os-caddy-plugin#how-to-create-a-handle-with-tls-and-a-trusted-self-signed-certificate

In the coming version the API Key stuff is documented a bit better, also with a reference to the repository where Caddy stores all DNS Providers: https://github.com/caddy-dns (Here you can find the docs for each dns provider module).

I don't have instructions for Nextcloud, but you can always check the /usr/local/etc/caddy/Caddyfile and also browse the https://caddy.community where there are a lot of Caddyfile examples for specific setups like Nextcloud.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MeroP on March 07, 2024, 10:14:25 PM
Many thanks for your advice. I followed your tutorials - it works perfectly.
(Self-signed) certificates from OPNsense, Unifi, Proxmox TLS works between proxy and backend.

However, it is unclear to me how this should work for virtual machines, containers - which do not yet have a certificate.
Was under the assumption that the certificate that Caddy issues externally can also be used for the connection between ReversProxy and the backend.

Or should I simply create an override in Unbound?

Like:
host.example.com ---- unbound----opnsense 127.0.0.1-----caddy----TLS----backend

Somehow I can't see the way right now.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 08, 2024, 06:32:39 AM
TLS is not a requirement to create a connection between Caddy and your Backend Servers. The standard is to use HTTP without encryption (which is also the Caddy default).

That is called TLS Termination https://en.m.wikipedia.org/wiki/TLS_termination_proxy in Reverse Proxy Jargon. Just leave the port in the Handler empty, and it will use Port 80 and HTTP. Or use any other port (other than 443) and leave TLS unchecked to use an unencrypted connection per default.

Encrypting the connection in a trusted network (aka not internet) is unneeded most of the time.

You also use Caddy internally if you want to access these VMs with a TLS connection. Since you have made an A-Record in your authorative nameserver that points to the external IP of the OPNsense, all internal requests to this A-Record will reach the OPNsense per default (with HTTPS), and Caddy will reverse proxy them back to your backend servers (with HTTP). You dont need any special NAT rules or any unbound overrides or anything.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jemkewl on March 10, 2024, 09:12:17 PM
Hello - I recently upgraded and am wondering if something isn't quite working as expected.

Short version -

1) upgraded OPNsense to 24.1.3_1

2) I had two new subdomains I wanted to add (in addition to the ones I've already created).  However, I am unable to get these to work.  Other/previous subdomains are still working without issue.

3) To troubleshoot, I enabled "http access log" for my domain and also enabled Log HTTP Access in JSON Format.

4) Have hit apply, save, and even restarted the Caddy service a few times.

No logs in
:/var/log/caddy/access # ls
:/var/log/caddy/access #

nothing is showing in the caddy.log either for access

The Caddyfile looks correct with the new host and handle
The autosave.json in /usr/local/etc/caddy/.config/caddy does not have the new host and handle (don't think that  is an issue, but just mentioning it).

Any ideas to tell me what I am doing wrong?


edit: To troubleshoot further, I modified an existing working "Handle" via the Caddy UI.  I changed the IP and port to be of the settings for one of the new domains.  After saving and applying, I am still presented the original configuration in the browser when I access that Handler subdomain.  Seems like something isn't being persisted properly based on this test; at worst, I should receive an error, but instead things still work, albeit for the original subdomain configuration.

edit2:  Since the plugin is close to being or is already available natively, do I need to do some cleanup steps with the repo since I installed the plugin prior to the native access?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 11, 2024, 06:36:55 AM
I would suggest you remove the plugin one time, restart the firewall, and then reinstall it. Your config won't be lost. There has been a big cleanup due to the code review and a lot of things changed. The .config folder isnt used anymore now either.

The autoconf.json is somewhere in "/var/db/caddy/config/caddy" now cause the standard rc.d file of freebsd is used now "/usr/local/etc/rc.d/caddy". It should define that autosave path as ${caddy_directory:="/var/db/${name}"}.

The plugin has been merged but it will be available natively in a future version, probably during the next OPNsense update. After that you can remove my repo. So far my repo serves the plugin, and the actual caddy binary already comes from the OPNsense Repo now.
"caddy-custom-2.7.6.3.0.3.5.3_XX.pkg" (Check here: https://pkg.opnsense.org/FreeBSD:13:amd64/snapshots/latest/All/)

(I had to remove and reinstall the plugin too, I'm using it on a few firewalls myself)

Sorry that you're having trouble, an integration like this and changing a lot of things is pretty hard without having some weird things happen.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jemkewl on March 12, 2024, 02:32:18 AM
Disregard - uninstall, reboot, reinstall worked.

Thank you!

This is a great plug-in and I appreciate your efforts.  Weird things always happen - appreciate the help

The new handlers are working as expected - one with TLS and the other clear.  Straightforward and works well.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 12, 2024, 05:59:01 AM
Awesome. Good to know. ^^
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Walki on March 12, 2024, 09:12:42 PM
I have problems with "Timeout during connect (likely firewall problem)". Which rules have to be set on Port 80 and 443 to "ThisFirewall"? Is it correct to setup a IN-Rule for the LAN to "ThisFirewall" or should "ThisFirewall" the Source?

I do not receive a certificate and wonder what to do. In your FAQ is no need for additional rules.

Great plugin. Thank you very much for your efforts. It should make a Reverse proxy setup much easier.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 12, 2024, 09:34:14 PM
Hello.

The rule on WAN/LAN/ other interfaces should be:

Direction: In
TCP/IP Version: IPv4/IPv6
Protocol: TCP
Source: Any
Destination: This Firewall
Destination Port Range: HTTP

A second rule with HTTPS should be made too.

The WAN rule makes sure external clients can connect to your domains, and that Let's Encrypt can issue the certificate.

The same rules on LAN allows your internal clients to connect to the same domains.

If you want to restrict access afterwards while retaining the Lets Encrypt functionality you can use basic auth or access lists (build into the plugin). Dont use Firewall rules for that.

If you dont get a certificate then, check that your FQDN resolves to the external IP Adress of your Firewall (A-Record).

Also, make sure you have the GUI redirect rule disabled, and have the WEB UI listen on an alternate port.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: bucky2780 on March 28, 2024, 10:44:26 PM
nice plugin... super simple !

Is it possible to defer certs to the opnsense trust store ? 
I already have LE generating certs there... and would like to use those, rather than have caddy own the process of creating/renewing the cert ?

------------ answer ------
I can see now, that you can select other cert if you use advanced option for the domain.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 29, 2024, 06:12:19 AM
Glad you could find the option you need. I think the ACME Plugin and Caddy can run at the same time and issue certificates too, I don't think there are regressions, but I don't know.

Its interesting to use the build in certificate generation of caddy because it also does automatic ocsp stapling.

Also, make sure you create an automation that restarts caddy when the Lets Encrypt certificates are renewed by the ACME Plugin if you continue using it. Otherwise the certs wont be reloaded if theyre reissued.

I'll check if I can create a pull request to add that as automation like nginx and haproxy.

EDIT: https://github.com/opnsense/plugins/pull/3877
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: bucky2780 on March 30, 2024, 04:59:16 AM
Thanks monviech...  I gave caddy another try... I currently run HAProxy, but dont really need load balancing for the home network, caddy is simpler.
My results were uneven... thus far. Here is what I did....
- Turned off ddns as relying on opnsense for that
- Gave the domain a custom cert located in the opnsense trust store.
- Gave the domain a custom port of 30000, as haproxy is currently binding to 443 and 80.
- With this approach, caddy does not terminate the connection. Seems to work however if I give it default 443

- Further to this... I disabled haproxy, and enabled caddy
- created a brand new domain and opnsense LE cert.
- bound caddy to 443 and seemed to work ok
- Home assistant loaded fine, the backend is unencrypted
- when backend was encrypted however, I checked the tls box for the backend, but alas failed to certify
  - this was the opnsense gui... which I put on a different port (41443)
  - Gui failed to load.
  - Similar approach seems to work in haproxy... where you check tls but dont bother to certify.

I will try again in a few days... to see if I can work around some of these things...
best regards,
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 30, 2024, 06:20:19 AM
Caddy has port 80 and 443 as a requirement for itself. Running it at the same time as other services that use it is not supported.

When using the build in certificate generation, any port on the Domain works, even ports like 30000 etc. I know that cause a small project uses this plugin where they have the same domain from 30000 to 30050 listening on the front end, reverse proxying each port to a different handler. (Reverse Proxying a lot of stable diffusion instances for the API.)

For the "check a box that just skips TLS verification" there is a new feature for that coming in the next version that allows that.

Otherwise the docs have examples how it works with the OPNsense GUI right now.

Thanks for trying the plugin. ^^
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: pieter123 on March 31, 2024, 05:55:34 PM
Hi,

I would like to install this plug in but can't find it in the Plugins list under firmware.

Opnsense version 24.1.b_130

Any suggestions?

Thanks!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on March 31, 2024, 06:17:59 PM
It's in 24.1.4
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: pieter123 on March 31, 2024, 08:16:59 PM
Quote from: Patrick M. Hausen on March 31, 2024, 06:17:59 PM
It's in 24.1.4

Got it, thanks!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: thg0432 on May 04, 2024, 05:21:33 PM
Has anyone had issues with Google home devices (not the routers but the hubs or other display devices) losing functionality after implementing caddy directly on the firewall?  I previously had nginx proxy manager and currently used zoraxy.  Both of which i had a nat rule setup and everything works fine.  I'd like to use caddy and have everything setup directly on the firewall but that's a deal breaker.  I setup the wan/lan rules and removed the nat as noted in the guide.  Everything works great with the exception of it breaking functionality of those devices
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 04, 2024, 08:12:02 PM
I'm using Google Home Minis and also Chromecasts. I didn't experience any breakage in functionality after implementing Caddy on my firewall.

I can't imagine what the problem should be, maybe a configuration problem of the Firewall or NAT rules.

Please check the firewall live log what happens when you voice command your google devices. Check if DNS fails (most probable cause), or packets get blocked.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: thg0432 on May 04, 2024, 08:28:52 PM
that's the thing...I won't even load...it appears to be a dns issue.  Because it can't contact google, it just hangs on the either the loading screen or it displays the clock but the clock never updates because it can't contact google.  My tv's which have google built in work fine, but just an older lenovo google display device craps the bed whenever i've tried.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 04, 2024, 09:12:35 PM
There's probably not much I can do about that without being able to know what exactly is going wrong, and how to reproduce it.

It's highly unlikely it has to do with running Caddy. Its more likely to be a firewall configuration issue.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: thg0432 on May 05, 2024, 02:55:39 AM
I tend to agree.  Just wanted to ask in case you'd heard anything like that before.  I appreciate it
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on May 19, 2024, 07:16:11 PM
Hi,

how can i add a wildcard DNS entry with Ionos as DNS provider? The plugin is only creating the "@" entry
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 19, 2024, 08:02:19 PM
Hello,

I am using this module and the configuration examples from it: https://github.com/mholt/caddy-dynamicdns

If there is something my template does wrong, please give me a caddyfile configuration example, or ask in the issues of the plugin maintainer if you can update a full wildcard domain.

So far, the plugin either updates a base domain with @, or subdomains. I dont think *.example.com will be updated, but I dont know for sure since I programmed the template only with the given examples.

I also inquired further here before making the template: https://caddy.community/t/dynamic-dns-module-question-about-domain-configuration/22291
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on May 20, 2024, 10:07:56 AM
Hi,

i've addad a ddns.global file in /usr/local/etc/caddy/caddy.d with

dynamic_dns {
provider ionos xyz-api-key
domains {
domain.tld * @
}
check_interval 5m
versions ipv4
ttl 1h
}


an with this it's creating the @ and * DNS entry (at least for Ionos).
So a extra field in the config GUI would be nice to fill some extra DNS entrys and just use @ if nothing is enterd there  :)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 20, 2024, 10:54:22 AM
Looks good, thanks for testing. I will adjust the template to turn '@' into '*' if it is a wildcard domain like *.example.com, but leave it as '@' when it is a base domain like example.com.

A simple fix in the template logic should do it I think? Since *.example.com and example.com need to coexist anyway in the GUI when wildcard and base domain are both needed, since they don't include each other.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on May 20, 2024, 11:20:52 AM
would be awesome  :D waiting for the update.

I'll test it and report back (if i can remember). If i forget to report back then you can assume that it's working  ;)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 21, 2024, 04:14:31 PM
@Aergernis:

https://github.com/opnsense/plugins/pull/3989
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: xm4rcell0x on May 23, 2024, 09:38:07 PM
Hi! Thank you for this plugin! I just moved from the "other sense" so i'm a newb here....
I tried to configure caddy but it won't even start. It gave me these error:2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"tls","msg":"finished cleaning storage units"}
2024-05-23T21:31:23 Error caddy "error","ts":"2024-05-23T19:31:23Z","logger":"tls","msg":"could not clean default/global storage","error":"unable to acquire storage_clean lock: context canceled"}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0x87024b400"}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x87024b400"}
2024-05-23T21:31:23 Informational caddy "info","ts":"2024-05-23T19:31:23Z","logger":"admin","msg":"admin endpoint started","address":"unix//var/run/caddy/caddy.sock","enforce_origin":false,"origins":["//::1","","//127.0.0.1"]}
2024-05-23T21:30:58 Informational caddy "info","ts":"2024-05-23T19:30:58Z","logger":"tls","msg":"finished cleaning storage units"}
2024-05-23T21:30:58 Error caddy "error","ts":"2024-05-23T19:30:58Z","logger":"tls","msg":"could not clean default/global storage","error":"unable to acquire storage_clean lock: context canceled"}
2024-05-23T21:30:58 Informational caddy "info","ts":"2024-05-23T19:30:58Z","logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0x870496380"}



If i press play it won't start at all. I already tried to uninstall, reboot and reinstall.



problem seems to be Auto HTTPS "On". If i turn off or any other one it starts automatically
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 24, 2024, 06:14:03 AM
Hey, did you follow the docs? If that happens it sounds like you didnt disable the WebGui redirect rule of the OPNsense. AutoHTTPs enables port 80, if thats already used then Caddy cant bind to it and wont start.

https://docs.opnsense.org/manual/how-tos/caddy.html#prepare-opnsense-for-caddy-after-installation
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on May 25, 2024, 12:48:44 PM
Quote from: Monviech on May 21, 2024, 04:14:31 PM
@Aergernis:

https://github.com/opnsense/plugins/pull/3989

is this already< included in 1.5.5_1?  If so, it's not working. The only difference is that there are now 2 @ entries for the domain

dynamic_dns {
provider ionos *****
domains {
domian.tld @
domian.tld @
}
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 25, 2024, 01:44:55 PM
Oh no its not, you have to use opnsense-patch to include it:


opnsense-patch -c plugins f3532fc9d878e1f8b13dd0b6242f2ee6918b9b72


Its gonna be in 1.5.6.

Docs about opnsense-patch: https://docs.opnsense.org/manual/opnsense_tools.html#id2
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on May 25, 2024, 02:12:29 PM
Quote from: Monviech on May 25, 2024, 01:44:55 PM
Oh no its not, you have to use opnsense-patch to include it:


opnsense-patch -c plugins f3532fc9d878e1f8b13dd0b6242f2ee6918b9b72


Its gonna be in 1.5.6.

Docs about opnsense-patch: https://docs.opnsense.org/manual/opnsense_tools.html#id2

Perfect. Working now, thanks  :D
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 25, 2024, 02:24:23 PM
Awesome, thank you for testing and creating this issue. Your efforts helped to make the plugin better. ^^
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: xm4rcell0x on May 30, 2024, 03:43:31 PM
Quote from: Monviech on May 24, 2024, 06:14:03 AM
Hey, did you follow the docs? If that happens it sounds like you didnt disable the WebGui redirect rule of the OPNsense. AutoHTTPs enables port 80, if thats already used then Caddy cant bind to it and wont start.

https://docs.opnsense.org/manual/how-tos/caddy.html#prepare-opnsense-for-caddy-after-installation

Sorry for my late reply.
You're right, i didn't disable the webgui redirect :( , my fault, after that the plugin works perfectly!

Thank you again for your work!!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 30, 2024, 04:27:56 PM
Thanks for the feedback. Im working on adding a validation so it won't happen again to others.

https://github.com/opnsense/plugins/pull/3999
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: xm4rcell0x on May 30, 2024, 06:01:17 PM
You said, in another thread this :"I just dislike the idea that it will be an easy way out and people will use it for all scenarios where they could use proper certificate handling instead..." regarding the TLS insecure skip verify.

At the moment the only way to make nextcloud and plex work behind caddy is thanks to this check.
If i'd like uncheck this, could be a good way follow this approach ? https://docs.opnsense.org/manual/how-tos/caddy.html#reverse-proxy-the-opnsense-webui

I completely understand if you don't want explaining something that may seem trivial to you, no problem at all ;)
And sorry if i made a dumb question, again...   :-[
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 30, 2024, 08:40:54 PM
Yes this approach is the right one.

You have to build trust between Caddy (which is the client) communicating with plex or nextcloud (which is the server)

To establish the connection over TLS, the certificates have to be trusted.

When your PC is the client towards Caddy, they trust each other because your PC has a root certificate for Lets Encrypt installed automatically.

When Caddy is the Client towards a server with a self signed certificate (like Nextcloud), it doesnt have any root certificate stored for that. Thats why it needs to be explicitely added, and the SAN name of the certificate has to match.

Though, if you don't get it to work, there is no shame using the Skip Verify, if your upstream is in your private LAN. Its mostly important if your upstream is in the internet again.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on May 30, 2024, 09:15:50 PM
If the upstream is in the same private infrastructure as Caddy or any other reverse proxy a perfectly valid option in my opinion is to drop TLS for the backend connection altogether.

That's how I run Confluence and all that other Java/Tomcat based stuff because managing certificates in Java just sucks.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: youmas on June 01, 2024, 12:00:20 PM
-///-
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Amodin on June 03, 2024, 06:08:52 AM
So I am a little confused on this - forgive me, new to Caddy and setting up reverse proxies.

First off - having issues with Firewall Rules after implementing this, and I am already weak with them, but no matter what I'm doing with rules, I can't ever seem to get them working with Caddy.

I know in the documentation it says:

Port Forwards, NAT Reflection, Split Horizon DNS or DNS Overrides in Unbound are not required. Only create Firewall rules that allow traffic to the default ports of Caddy.
So are we creating rules that just point to 80 and 443?  I tried that, didn't go so well, lol.

Second thing, under Creating the Simple Proxy section - for the Upstream Domain IP:  Is this our firewall IP, or our hosted DNS name?  The documentation doesn't do a good job for me on this.  Currently, I just have my domain name there, but at first believed it would have been my OPN.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 03, 2024, 06:41:51 AM
I recently updated that section, its not live yet.

https://github.com/opnsense/docs/blob/master/source/manual/how-tos/caddy.rst#creating-a-simple-reverse-proxy

Also, the firewall rules as stated at the beginning of these docs are all that are needed.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Amodin on June 03, 2024, 06:54:52 AM
Thanks for the updated notes.

So, for the Upstream Domain in your notes:   192.168.10.1

Is this the IP of OPN you are using, or the ISP router IP?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 03, 2024, 07:23:56 AM
A reverse proxy works like this:

It is a webserver, that is the frontend part. You input your domains there, and it listens for these domain names.

At the same time it is also a client, like a browser. It needs to know where to send traffic to. This is the Upstream part, it will connect to an internal hosted service like a Nextcloud.

It combines both, to intercept all requests, and sending them to a different destination. Its a proxy from the internet to your internal services. (reverse proxy)

e.g.

nextcloud.example.com -> A Record points to external IP address (e.g. 1.1.1.1) of your OPNsenses WAN interface where Caddy listens.

1. Client (Your phone) tries to connect to --> example.com
2. It reaches the Opnsense, on which Caddy listens for the Domain nextcloud.example.com
3. Caddy then dials the Upstream (E.g. the internal IP address (192.168.1.1) of the Nextcloud in your private network behind the OPNsense)
4. The Nextcloud server receives the request from caddy, and sends it back to caddy, and caddy to your phone.

                      1.1.1.1          192.168.1.1
Phone Browser <-> Caddy <-> Nextcloud
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: wirehire on June 04, 2024, 01:47:50 PM
can i bind caddy on specific interface?

i have two wan interface and run nginx proxy on one. i want use caddy for the second, to test , but i see no options to bind caddy on a specific interface.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 04, 2024, 02:30:03 PM
Hello, there is no implementation for that in the GUI.

https://caddyserver.com/docs/caddyfile/directives/bind#syntax

It uses the standard wildcard interface. And it can only bind to a specific IP address, or hostname.

Since the directive "bind" does only accept "network addresses", including that is a little unreliable on a firewall (especially when the IP can vanish since its dynamic) I expect caddy to just crash then.

I mean potentially it could be there in global options, but I really don't know if I want to offer it. You could always create a custom configuration though in the import folders that includes this directive.

https://caddyserver.com/docs/caddyfile/options#default-bind

You can create these two files to override the interface globally for whole caddy:

/usr/local/etc/caddy/caddy.d/defaultbind.global
default_bind 1.1.1.1

/usr/local/etc/caddy/caddy.d/defaultbind.conf

http:// {
    bind 1.1.1.1
}


The http block is explained in the documentation about default_bind.

That will be imported into the Caddyfile and Caddy will bind globally to that IP. Now you can freely use the GUI to test out Caddy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: wirehire on June 04, 2024, 02:51:49 PM
nice , i will try.

then i have no conflicts with the nginx plugin , what used port 80/443 on the first wan port?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 04, 2024, 02:53:48 PM
If nginx binds to e.g.:

1.1.1.1:80 and 1.1.1.1:443

And Caddy will bind to

1.1.1.2:80 and 1.1.1.2:443

there will be no socket overlap and no conflicts.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: wirehire on June 04, 2024, 02:57:13 PM
i have it done, on first look, looks good.

but why are run caddy on root user? should it not www?

root     caddy      56705 8  tcp4   ip:443
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 04, 2024, 03:00:28 PM
Ah yes, its possible but not easy. I wanted to implement it but I don't know what this kind of stuff will influence on the firewall.

It would have to use an /old/ subsystem in FreeBSD called "mac_portacl".

https://github.com/opnsense/core/issues/7419
https://github.com/opnsense/plugins/issues/3946
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: catchyuser on June 14, 2024, 08:01:39 AM
Hello,

I have installed Caddy with LE, and have no issues with Opnsense access.

For some reason my Synology NAS worked fine for a while and then I am getting the error message.

This page isn't working nas.domain.com redirected you too many times.
Try deleting your cookies.
ERR_TOO_MANY_REDIRECTS.

Also I am not able. to setup reverse proxy for Portainer and Couchdb installed on docker in Synology NAS. I have used the same settings for all of the them. And only Opnsense is working for me.

Can someone help me to fix the issue and I can share more information if needed to understand the issue.

Thank you in advance.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 14, 2024, 08:43:50 AM
I think Synology has a forced redirect from port 80/443 to port 5000/5001 that has to be disabled to prevent a redirection loop.

https://forum.opnsense.org/index.php?topic=39942.msg195706#msg195706
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: catchyuser on June 16, 2024, 12:06:28 AM
I tried changing the redirect for https tp port 4443, but still getting the same error.

This page isn't working synology.domain.com redirected you too many times.
Try deleting your cookies.
ERR_TOO_MANY_REDIRECTS
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MeroP on June 21, 2024, 11:04:16 PM
Because some questions have already arisen here regarding a Nextcloud installation behind an opnsense with reversproxy caddy plugin. A small guide:

1. Follow the Documentation of this great plugin of Monviech [do it exactly as described]
https://docs.opnsense.org/manual/how-tos/caddy.html#how-to-install (https://docs.opnsense.org/manual/how-tos/caddy.html#how-to-install)
- 1. Installation
- 2. Prepare OPNsense for Caddy after installation

2. Create an A-Record with an external DNS Provider that points to the external IP Address of the OPNsense

3. Create a VM/SERVER/LXC/CONTAINER on your favorite hypervisor
- must be accessible from the opnsense via a static ip
- For example 192.168.10.1

4. Create a simple-reverse-proxy for nextcloud
https://docs.opnsense.org/manual/how-tos/caddy.html#creating-a-simple-reverse-proxy (https://docs.opnsense.org/manual/how-tos/caddy.html#creating-a-simple-reverse-proxy)
For example:

[FRONTEND]
Domain: nextcloud.yourdomain.eu
Port: Leave empty to use port 443 with automatic redirection from port 80
Description: nextcloud.yourdomain.eu - frontend

[BACKEND]
Domain: nextcloud.yourdomain.eu
Description: nextcloud.yourdomain.eu - backend
Upstream Domain:192.168.10.1
Upstream Port: 11000 [IMPORTANT - you need to reach the apache web server in the nextcloud instance]

DONT FORGET TO APPLY

5. Run a shell in the VM/SERVER/LXC/CONTAINER and prepare the nextcloud installation

sudo apt update && apt upgrade && apt-get install unattended-upgrades && apt install curl -y

curl -fsSL https://get.docker.com | sudo sh

docker version

mkdir /nextcloud

mkdir /mnt/data


6. Create a docker-compose.yml file for the nextcloud container

Quote

nano /nextcloud/docker-compose.yml

[PASTE]
services:
  nextcloud-aio-mastercontainer:
    image: nextcloud/all-in-one:latest
    init: true
    restart: always
    container_name: nextcloud-aio-mastercontainer
    volumes:
      - nextcloud_aio_mastercontainer:/mnt/docker-aio-config
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - 8080:8080   
    environment:
      AIO_DISABLE_BACKUP_SECTION: false
      APACHE_PORT: 11000
      APACHE_IP_BINDING: 0.0.0.0
      NEXTCLOUD_DATADIR: /mnt/data
      NEXTCLOUD_MOUNT: /mnt/
      NEXTCLOUD_UPLOAD_LIMIT: 20G
      NEXTCLOUD_MAX_TIME: 7200
      NEXTCLOUD_MEMORY_LIMIT: 4096M
      NEXTCLOUD_TRUSTED_CACERTS_DIR: /path/to/my/cacerts
      NEXTCLOUD_STARTUP_APPS: deck twofactor_totp tasks calendar contacts notes
      TALK_PORT: 3478
      WATCHTOWER_DOCKER_SOCKET_PATH: /var/run/docker.sock

volumes:
  nextcloud_aio_mastercontainer:
    name: nextcloud_aio_mastercontainer

7. Go to https://192.168.10.1:8080
- Login the AIO installer with pw seed
- Enter nextcloud.yourdomain.eu
- Follow the Nextcloud AIO installer as shown

8. Go to https://nextcloud.yourdomain.eu
- reverse proxy and ssl-cert via caddy plugin
- If you wish restrict access to only internal IPs
- https://scan.nextcloud.com
- https://www.ssllabs.com/ssltest/


For further reading: https://github.com/nextcloud/all-in-one (https://github.com/nextcloud/all-in-one)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 10, 2024, 02:15:09 PM
Quote from: wirehire on June 04, 2024, 02:57:13 PM
i have it done, on first look, looks good.

but why are run caddy on root user? should it not www?

root     caddy      56705 8  tcp4   ip:443

Soon it can be enabled optionally to run as www user, with restriction to upper-ports.

https://github.com/opnsense/plugins/pull/4081

This means, you can run caddy on any upper ports, e.g. 8080 and 8443, and use the port forwarding of PF to bind port 80 and 443, using Port address translation to send them to 8080 and 8443.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: felixao on July 11, 2024, 10:20:42 AM
Hey, first of all: thank you for this plugin!

I switched from deSEC to Cloudflare and now I'm getting Error's and it stopped working. I configured Cloudflare's API as mentioned in the caddy docs (https://github.com/caddy-dns/cloudflare). It looked like an API problem, but the API is working correctly. Anyone an Idea what I'm missing here? Drives me crazy, because it worked fine through deSEC...


2024-07-11T11:20:20 Debug caddy "debug","ts":"2024-07-11T09:20:20Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/NPCUGkSt_wD2IWe237P8Ug","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["449"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:20 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["RFqgHTYGSgLDQn5zyQus3TlVAA0dV_AgfEfYCSqlEbE"],"Retry-After":["86400"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-07-11T11:20:17 Debug caddy "debug","ts":"2024-07-11T09:20:17Z","logger":"tls.issuance.acme.acme_client","msg":"challenge accepted","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:17 Debug caddy "debug","ts":"2024-07-11T09:20:17Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/chall/klxrvi7gfralxj_sO71jWg","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["164"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:17 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90/authz/NPCUGkSt_wD2IWe237P8Ug>;rel=\"up\""],"Replay-Nonce":["6E5wD7Bn28fzZFdRIhxY-kHq1V7Pib5lfX1hjTipyjI"],"Retry-After":["60"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-07-11T11:20:15 Debug caddy "debug","ts":"2024-07-11T09:20:15Z","logger":"tls.issuance.acme.acme_client","msg":"done waiting for solver","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:15 Debug caddy "debug","ts":"2024-07-11T09:20:15Z","logger":"tls.issuance.acme.acme_client","msg":"waiting for solver before continuing","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:15 Informational caddy "info","ts":"2024-07-11T09:20:15Z","logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"vault.domain.xyz","challenge_type":"http-01","ca":"https://acme.zerossl.com/v2/DV90"}
2024-07-11T11:20:15 Debug caddy "debug","ts":"2024-07-11T09:20:15Z","logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"dns-01"}
2024-07-11T11:20:15 Debug caddy "debug","ts":"2024-07-11T09:20:15Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/authz/NPCUGkSt_wD2IWe237P8Ug","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["449"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:15 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["mc4smWXSmABMoANYjQXXXzYPNBKrPnIS8Mg6fx_0J6Y"],"Retry-After":["86400"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-07-11T11:20:12 Debug caddy "debug","ts":"2024-07-11T09:20:12Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme.zerossl.com/v2/DV90/newOrder","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Length":["278"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:12 GMT"],"Location":["https://acme.zerossl.com/v2/DV90/order/ePdppdFxHGxCGbOdAvumEQ"],"Replay-Nonce":["N0RQNWJzpxpg9jw-t0w10AV1et-TIz90-K-awUNs-2A"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":201}
2024-07-11T11:20:11 Debug caddy "debug","ts":"2024-07-11T09:20:11Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"HEAD","url":"https://acme.zerossl.com/v2/DV90/newNonce","headers":{"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Cache-Control":["max-age=0, no-cache, no-store"],"Content-Type":["application/octet-stream"],"Date":["Thu, 11 Jul 2024 09:20:11 GMT"],"Link":["<https://acme.zerossl.com/v2/DV90>;rel=\"index\""],"Replay-Nonce":["dubyvT4QrKuMzUWj3QzTladPHhmL43wwc9PWuhz7z4U"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"creating order","account":"https://acme.zerossl.com/v2/DV90/account/zI17MJiuzZy2KCCeoxuxow","identifiers":["vault.domain.xyz"]}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"GET","url":"https://acme.zerossl.com/v2/DV90","headers":{"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Access-Control-Allow-Origin":["*"],"Content-Length":["645"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:10 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=15724800; includeSubDomains"]},"status_code":200}
2024-07-11T11:20:10 Informational caddy "info","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme.zerossl.com/v2/DV90/account/zI17MJiuzZy2KCCeoxuxow","account_contact":["mailto:abc@abc.de"]}
2024-07-11T11:20:10 Informational caddy "info","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["vault.domain.xyz"],"ca":"https://acme.zerossl.com/v2/DV90","account":"abc@abc.de"}
2024-07-11T11:20:10 Informational caddy "info","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["vault.domain.xyz"],"ca":"https://acme.zerossl.com/v2/DV90","account":"abc@abc.de"}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.obtain","msg":"trying issuer 2/2","issuer":"acme.zerossl.com-v2-DV90"}
2024-07-11T11:20:10 Error caddy "error","ts":"2024-07-11T09:20:10Z","logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"vault.domain.xyz","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 403 urn:ietf:params:acme:error:unauthorized - Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge"}
2024-07-11T11:20:10 Error caddy "error","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"validating authorization","identifier":"vault.domain.xyz","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge","instance":"","subproblems":[]},"order":"https://acme-v02.api.letsencrypt.org/acme/order/1830756237/286284483307","attempt":2,"max_attempts":3}
2024-07-11T11:20:10 Error caddy "error","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"challenge failed","identifier":"vault.domain.xyz","challenge_type":"tls-alpn-01","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge","instance":"","subproblems":[]}}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540185137","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["979"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:10 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-e62lhajWnK7NFktNLv_vxDvmyIHriusfwdEbgwDHJBI"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"challenge accepted","identifier":"vault.domain.xyz","challenge_type":"tls-alpn-01"}
2024-07-11T11:20:10 Debug caddy "debug","ts":"2024-07-11T09:20:10Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/chall-v3/375540185137/6dCOjw","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["191"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:10 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540185137>;rel=\"up\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/chall-v3/375540185137/6dCOjw"],"Replay-Nonce":["zgT1AlV-ZNjqD20ClwybZ8eDxXrUqmgEm1TZobqpM9QB218Jj-w"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:09 Error caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"http.stdlib","msg":"http: TLS handshake error from 127.0.0.1:23624: EOF"}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"done waiting for solver","identifier":"vault.domain.xyz","challenge_type":"tls-alpn-01"}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"waiting for solver before continuing","identifier":"vault.domain.xyz","challenge_type":"tls-alpn-01"}
2024-07-11T11:20:09 Informational caddy "info","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"vault.domain.xyz","challenge_type":"tls-alpn-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"no solver configured","challenge_type":"dns-01"}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540185137","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:09 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8U4xWcZeKJWc2ZPIjm64cHusyQhzX7_35gDM3LNRN3kJE"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["342"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:09 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/1830756237/286284483307"],"Replay-Nonce":["zgT1AlV-BI6xmFywkTmeWStBmnzrHpVzGovRTMo3kXra6Adr0ak"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":201}
2024-07-11T11:20:09 Debug caddy "debug","ts":"2024-07-11T09:20:09Z","logger":"tls.issuance.acme.acme_client","msg":"creating order","account":"https://acme-v02.api.letsencrypt.org/acme/acct/1830756237","identifiers":["vault.domain.xyz"]}
2024-07-11T11:20:08 Error caddy "error","ts":"2024-07-11T09:20:08Z","logger":"tls.issuance.acme.acme_client","msg":"validating authorization","identifier":"vault.domain.xyz","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"2606:4700:3036::ac43:d41a: Invalid response from http://vault.domain.xyz/.well-known/acme-challenge/7l0JbJU_ZyHGmhvKl75evbljzzBgdrwE6H7OWNDGReo: 521","instance":"","subproblems":[]},"order":"https://acme-v02.api.letsencrypt.org/acme/order/1830756237/286284439187","attempt":1,"max_attempts":3}
2024-07-11T11:20:08 Error caddy "error","ts":"2024-07-11T09:20:08Z","logger":"tls.issuance.acme.acme_client","msg":"challenge failed","identifier":"vault.domain.xyz","challenge_type":"http-01","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"2606:4700:3036::ac43:d41a: Invalid response from http://vault.domain.xyz/.well-known/acme-challenge/7l0JbJU_ZyHGmhvKl75evbljzzBgdrwE6H7OWNDGReo: 521","instance":"","subproblems":[]}}
2024-07-11T11:20:08 Debug caddy "debug","ts":"2024-07-11T09:20:08Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["1166"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:08 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8U7eKR1AlXtU9lRLDgHnVy6EN2gqEZVm9KRytegcxucrg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:08 Debug caddy "debug","ts":"2024-07-11T09:20:08Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:08 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-euTwn1vhs0TH98VKYpMMKLgHg3M6TgZdhDenSu9HmYg"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:07 Debug caddy "debug","ts":"2024-07-11T09:20:07Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:07 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8UYhJhC44nClV9RV6nvIIzaK2DAjImU5JGJdz44gWUncU"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:07 Debug caddy "debug","ts":"2024-07-11T09:20:07Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:07 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8USQKy9NDO6JcHhf_MBteZI361LL4GYaDlA5z_9xyAuFM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:06 Debug caddy "debug","ts":"2024-07-11T09:20:06Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:06 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8UxmzVHyJhwPe9eEQ6tvQV01TrVht81-oIAqP7mhai5OM"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:06 Debug caddy "debug","ts":"2024-07-11T09:20:06Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:06 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-OJT-LyggcLxiAMMSFuyoLzmCBEOLBXPQxBeybPGmESo"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:06 Debug caddy "debug","ts":"2024-07-11T09:20:06Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:05 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8U6obW-QWTqVmyaxPKEVACLYUXFXFxCHYe-O4PAFHjYkY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:05 Debug caddy "debug","ts":"2024-07-11T09:20:05Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:05 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8USJMpZQkltYIVjT5-CjgsbvQkBKO0KvsY626muUBfs6s"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:05 Informational caddy "info","ts":"2024-07-11T09:20:05Z","logger":"dynamic_dns","msg":"finished updating DNS","current_ips":["IPv4","IPv6"]}
2024-07-11T11:20:05 Error caddy "error","ts":"2024-07-11T09:20:05Z","logger":"dynamic_dns","msg":"failed setting DNS record(s) with new IP address(es)","zone":"vault.domain.xyz","error":"expected 1 zone, got 0 for vault.domain.xyz"}
2024-07-11T11:20:05 Debug caddy "debug","ts":"2024-07-11T09:20:05Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:05 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-CvYAXwpXuF1shAoALOl7uw1a2tfIsDvEFPZQXx47cdY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:04 Debug caddy "debug","ts":"2024-07-11T09:20:04Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:04 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8UY_XLOY2Bx8vljY4TUUxGIWBp6I1TPViNFndKjcC-4Ck"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:04 Debug caddy "debug","ts":"2024-07-11T09:20:04Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:04 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-LYsOEdE5lzwAGFIFauFJxas65qd56rV33pJfPFQIves"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:03 Debug caddy "debug","ts":"2024-07-11T09:20:03Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:03 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-xLtdkY8POAtrKQ9a4t3v_xHSQNG3UhG6BnZnfADaK1M"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:03 Informational caddy "info","ts":"2024-07-11T09:20:03Z","logger":"dynamic_dns","msg":"updating DNS record","zone":"vault.domain.xyz","type":"AAAA","name":"@","value":"IPv6","ttl":0}
2024-07-11T11:20:03 Informational caddy "info","ts":"2024-07-11T09:20:03Z","logger":"dynamic_dns","msg":"updating DNS record","zone":"vault.domain.xyz","type":"A","name":"@","value":"IPv4","ttl":0}
2024-07-11T11:20:03 Debug caddy "debug","ts":"2024-07-11T09:20:03Z","logger":"dynamic_dns.ip_sources.simple_http","msg":"lookup","type":"IPv6","endpoint":"https://api64.ipify.org","ip":"IPv6"}
2024-07-11T11:20:03 Debug caddy "debug","ts":"2024-07-11T09:20:03Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:03 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8Ush8AvtRobCEsVGwqCUm2GexI1Hp2bWusYFHkTRgjsuw"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:03 Debug caddy "debug","ts":"2024-07-11T09:20:03Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:02 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-8ayFaFcJYlewB8vBEfzHuzQBzzf2uB0mGWAAgIX_qRY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:03 Debug caddy "debug","ts":"2024-07-11T09:20:03Z","logger":"dynamic_dns.ip_sources.simple_http","msg":"lookup","type":"IPv4","endpoint":"https://api64.ipify.org","ip":"IPv4"}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:02 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["zgT1AlV-iPhTWKwNrOl_pJclv7FEUfeIEqzZ5H_5hZ7OHWz4RbI"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"dynamic_dns","msg":"looked up current IPs from DNS","lastIPs":null}
2024-07-11T11:20:02 Error caddy "error","ts":"2024-07-11T09:20:02Z","logger":"dynamic_dns","msg":"unable to lookup current IPs from DNS records","error":"expected 1 zone, got 0 for vault.domain.xyz"}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"challenge accepted","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/chall-v3/375540126317/1Lewag","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["187"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:02 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\"","<https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317>;rel=\"up\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/chall-v3/375540126317/1Lewag"],"Replay-Nonce":["eFSVlf8UyZXdEZd8mwkJB6yFDyoZ-wVUZbRYH-OsfEukg-tTT9I"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"done waiting for solver","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"waiting for solver before continuing","identifier":"vault.domain.xyz","challenge_type":"http-01"}
2024-07-11T11:20:02 Informational caddy "info","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"trying to solve challenge","identifier":"vault.domain.xyz","challenge_type":"http-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
2024-07-11T11:20:02 Debug caddy "debug","ts":"2024-07-11T09:20:02Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/authz-v3/375540126317","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["800"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:01 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8UnTzZAxtF3xpZJCTUeU2Ps5MRqmWxZClrlIGYYwpLiyI"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:01 Debug caddy "debug","ts":"2024-07-11T09:20:01Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"POST","url":"https://acme-v02.api.letsencrypt.org/acme/new-order","headers":{"Content-Type":["application/jose+json"],"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Boulder-Requester":["1830756237"],"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["342"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:01 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Location":["https://acme-v02.api.letsencrypt.org/acme/order/1830756237/286284439187"],"Replay-Nonce":["eFSVlf8UgxC3Ov5ci2luZFH8tZxr_XJq2m-T3zKw4ZccQBsd0PI"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":201}
2024-07-11T11:20:01 Debug caddy "debug","ts":"2024-07-11T09:20:01Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"HEAD","url":"https://acme-v02.api.letsencrypt.org/acme/new-nonce","headers":{"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Date":["Thu, 11 Jul 2024 09:20:01 GMT"],"Link":["<https://acme-v02.api.letsencrypt.org/directory>;rel=\"index\""],"Replay-Nonce":["eFSVlf8UldoMJHBdgupStVclatMJ6jwCSZ6H_08oajcJghaPbxY"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:01 Debug caddy "debug","ts":"2024-07-11T09:20:01Z","logger":"tls.issuance.acme.acme_client","msg":"creating order","account":"https://acme-v02.api.letsencrypt.org/acme/acct/1830756237","identifiers":["vault.domain.xyz"]}
2024-07-11T11:20:01 Debug caddy "debug","ts":"2024-07-11T09:20:01Z","logger":"tls.issuance.acme.acme_client","msg":"http request","method":"GET","url":"https://acme-v02.api.letsencrypt.org/directory","headers":{"User-Agent":["Caddy/2.8.4 CertMagic acmez (freebsd; amd64)"]},"response_headers":{"Cache-Control":["public, max-age=0, no-cache"],"Content-Length":["746"],"Content-Type":["application/json"],"Date":["Thu, 11 Jul 2024 09:20:01 GMT"],"Server":["nginx"],"Strict-Transport-Security":["max-age=604800"],"X-Frame-Options":["DENY"]},"status_code":200}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.issuance.acme","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/1830756237","account_contact":["mailto:abc@abc.de"]}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.issuance.acme","msg":"done waiting on internal rate limiter","identifiers":["vault.domain.xyz"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"abc@abc.de"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.issuance.acme","msg":"waiting on internal rate limiter","identifiers":["vault.domain.xyz"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":"abc@abc.de"}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"tls.obtain","msg":"trying issuer 1/2","issuer":"acme-v02.api.letsencrypt.org-directory"}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"events","msg":"event","name":"cert_obtaining","id":"a3ed979c-3d86-499c-92ad-5ae7deba6b1e","origin":"tls","data":{"identifier":"vault.domain.xyz"}}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.obtain","msg":"obtaining certificate","identifier":"vault.domain.xyz"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.obtain","msg":"lock acquired","identifier":"vault.domain.xyz"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls","msg":"finished cleaning storage units"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/var/db/caddy/data/caddy","instance":"68f4b45b-f584-42d9-bafa-99c122f2bda3","try_again":"2024-07-12T09:20:00Z","try_again_in":86399.999997449}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.obtain","msg":"acquiring lock","identifier":"vault.domain.xyz"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","msg":"serving initial configuration"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","msg":"autosaved config (load with --resume flag)","file":"/var/db/caddy/config/caddy/autosave.json"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http","msg":"enabling automatic TLS certificate management","domains":["vault.domain.xyz"]}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":true}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"dynamic_dns","msg":"beginning IP address check"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
2024-07-11T11:20:00 Debug caddy "debug","ts":"2024-07-11T09:20:00Z","logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{"subjects":["vault.domain.xyz"]},{}]}},"http":{"grace_period":10000000000,"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}]},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.178.6:8000"}]}]}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{}}}}}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x870981180"}
2024-07-11T11:20:00 Informational caddy "info","ts":"2024-07-11T09:20:00Z","logger":"admin","msg":"admin endpoint started","address":"unix//var/run/caddy/caddy.sock","enforce_origin":false,"origins":["","//127.0.0.1","//::1"]}
   


Caddy-Config:

# Global Options
{
log {
output net unixgram//var/caddy/var/run/log {
}
format json {
time_format rfc3339
}
level DEBUG
}

dynamic_dns {
provider cloudflare API-Token
domains {
vault.domain.xyz @
}
}

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

# Reverse Proxy Configuration


# Reverse Proxy Domain: "8e333c2b-cff5-465f-b899-d89f446438c5"
vault.domain.xyz {
handle {
reverse_proxy 192.168.178.6:8000 {
}
}
}

import /usr/local/etc/caddy/caddy.d/*.conf


Thanks in advance, hope its not a totally dumb mistake  ::) ;D
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 11, 2024, 12:11:54 PM
Hello, I don't see the TLS block in your domain. It should look like this:


# Reverse Proxy Domain: "d5c1169f-8f95-4091-823b-7095c15fbb5f"
example.com {
tls {
dns cloudflare secretapikeyhere
}

handle {
reverse_proxy 172.16.100.1 {
}
}
}


Did you check the Checkbox "Dns-01 Challenge" in your domain in "Trust"?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: felixao on July 11, 2024, 10:30:58 PM
Puh, thanks alot! :-[ - got a certificate now:

2024-07-11T22:11:37 Informational caddy "info","ts":"2024-07-11T20:11:37Z","logger":"dynamic_dns","msg":"updating DNS record","zone":"vault.domain.xyz","type":"AAAA","name":"@","value":"IPv6","ttl":0}
2024-07-11T22:11:37 Informational caddy "info","ts":"2024-07-11T20:11:37Z","logger":"dynamic_dns","msg":"updating DNS record","zone":"vault.domain.xyz","type":"A","name":"@","value":"IPv4","ttl":0}
2024-07-11T22:11:35 Debug caddy "debug","ts":"2024-07-11T20:11:35Z","logger":"events","msg":"event","name":"cached_managed_cert","id":"30f5dd13-a0ea-4f72-8ab9-ef83302c2b13","origin":"tls","data":{"sans":["vault.domain.xyz"]}}
2024-07-11T22:11:35 Debug caddy "debug","ts":"2024-07-11T20:11:35Z","logger":"tls.cache","msg":"added certificate to cache","subjects":["vault.domain.xyz"],"expiration":"2024-10-09T09:55:23Z","managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"51760c73851d473ec28884675ecde4e5413d434e12f04760093aecb819909f51","cache_size":1,"cache_capacity":10000}


I already thought it was such a small thing...

Now of course I have the next problem, namely that I can't reach the domain and get an error at Cloudflare (error code 521). Host is reachable, CNAME is also configured. Is there anything else I need to consider for Cloudflare?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 11, 2024, 10:52:22 PM
If Cloudflare is only your DNS Proviser and nothing more (no CDN or Cloudflare tunnels etc), then nothing else has to be considered there.

Now the issue should be your upstream. If you get a blank page + certificate in the browser, then there is a connection issue to the upstream (so your internal service+port).

The most likely cause is that the internal service listens on https instead of http, so try to enable "TLS Insecure Skip Verify" in the handler and see if it works then.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: felixao on July 12, 2024, 10:50:50 AM
You are the man! Thank you so much for the great support! Everything is now working as it should.  :D :D :D
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MeroP on July 12, 2024, 11:28:05 AM
Hello,
may i ask for your help @Monviech. i would like to install stalwart mailserver behind the caddy plugin. according to the documentation https://stalw.art/docs/server/reverse-proxy/caddy/ (https://stalw.art/docs/server/reverse-proxy/caddy/), the following must be done to enable Proxy Protocol support directly within Caddy.
It is mentioned that the plugin called proxy_protocol should be used. As I understand it this is already integrated in Caddy.

Caddyfile example

mail.example.com {
    redir https://example.com{uri}
}

example.com {
    # Set this path to your site's directory.
    root * /usr/share/caddy

    # Enable the static file server.
    file_server
}

mail.example.com {
    reverse_proxy 127.0.0.1:8080
}


In addition, crontab must be created in order to automate copying the certificates obtained by Caddy

0 3 * * * cat /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/example.com/example.com.crt > /opt/stalwart-mail/cert/example.com.pem
0 3 * * * cat /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/example.com/example.com.key > /opt/stalwart-mail/cert/example.com.priv.pem


My questions:
1. can this be implemented with the plugin and the GUI or do I have to use Custom Configuration File
2. How do I create the automated copying oft the certificates obtained by Caddy to the stalwart container

Thank you very much for your help and for your great plugin. It has helped me on many levels and also given me a lot of insight.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 12, 2024, 12:00:24 PM
Hello, anything could be implemented into the plugin. The question is if it makes sense. For edge cases like these the custom configuration files are the best choice.

I don't understand why they need a fileserver and a root web directory. It's not needed for the reverse proxy. If this is a requirement, please /don't/ set it up on the OPNsense.

Also this cronjob can break since Caddy creates more than just Lets Encrypt folder, it also creates a ZeroSSL folder.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on July 12, 2024, 06:15:22 PM
Hi,
would love to see MultiWAN support for dynamic DNS so that all public IPs get a DNS entry (in my case 2)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 12, 2024, 06:21:45 PM
If you leave the checks empty, Caddy will check your current IP with a default HTTP check, and update your A and AAAA Records accordingly. If the default route of the OPNsense to the internet should change, Caddy will update your entries with the other WAN IP at the next check interval.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: sharkpunch on July 14, 2024, 12:28:34 PM
Great plugin however when i set it up and try to navigate to the domain i've configured (as per tutorial )

subdomain.domain.com uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH

I'm using the dns challenge to generate the certificate, any ideas why this would cause a problem?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 14, 2024, 12:40:32 PM
Hey, to help you I need your Caddyfile (please redact any api keys or passwords).

And I need some debug logs. Put your log settings to debug, do the request that fails and post them here.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: sharkpunch on July 14, 2024, 11:19:03 PM
Thanks, I've attached the caddyfile and log and the letsencrypt challenge works successfully so it has been able to request a certificate, its when i navigate to the page I get that error in my browser
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 15, 2024, 06:08:34 AM
Which application do you reverse proxy? Does it listen internally on HTTP or HTTPS?

For HTTPS enable "TLS Insecure Skip Verify" in the handler.

Or better, use HTTP internally.

Sadly the log doesnt show anything.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: sharkpunch on July 15, 2024, 10:22:17 AM
i tried both sonarr and portainer (one with and without ssl) and neither are working.
its worth mentioning I only forwarded the internal 80/443 on my LAN rather than exposing on the WAN - I assume this is fine if I don't want any of my servers to be public facing.

any other idea's on what to test? my opnsense is more or less out of the box, I'm not doing anything particularly interesting with my configuration outside of this.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 15, 2024, 11:19:43 AM
I have no experience with the configuration you are doing.

I am always using the public domain name pointing to the public IP address of the OPNsense, and use Access Lists to restrict access to internal networks.

Reference: https://docs.opnsense.org/manual/how-tos/caddy.html#restrict-access-to-internal-ips

Another reference where I explained my preferred setup in detail: https://www.reddit.com/r/opnsense/comments/1dwbr88/issue_using_oscaddy_to_generate_wildcard_cert/

In your case, you might have to use Split DNS, to avoid NAT Reflection/Hairpinning problems. (https://docs.opnsense.org/manual/how-tos/nat_reflection.html)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 16, 2024, 03:55:26 PM
Just FYI for all os-caddy users.

Version os-caddy-1.6.1 which will be part of 24.7 will be the point the plugin stays feature wise for now. New feature requests will be weighted heavily for benefit vs. making the UI more cluttered due to being an edge case.

It can do a lot of things, it can fit many usecases, and it is still pretty simple to configure. I think this is the right point to stop active developement and go into full maintaining mode.

That means:
- Fixing Bugs
- Maintaining the code base
- Maintaining/Updating the build of the caddy binary and dns providers

The point where active developement would start again is when new features are introduced, like Layer 4 proxy support in the Caddyfile, which could happen somewhere next year.

Thank you all ^^
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 21, 2024, 11:50:54 AM
I made a video to show off the new widgets, and how fast a reverse proxy is set up with this plugin.

https://www.youtube.com/watch?v=6ip8Sx4zcDA
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 25, 2024, 09:53:30 AM
Out of nowhere, the Caddyfile Layer 4 support came.

I have implemented TLS SNI matching of hostnames, and streaming this traffic to an upstream without tls termination:

https://github.com/opnsense/plugins/pull/4112

If anybody wants to test it, I would love some feedback, since it is a complicated new feature (still tried to keep the scope small and make it very easy to configure)

https://cloud.pischem.com/index.php/s/rw8Z86AzkEx3673

- Install the .pkg and replace the caddy binary with the new one

- Go to "General Settings" - Enable the advanced options - Enable "Enable Layer4"
- Go to the "Layer4 Routes" Tab, and create a route for a domain. All matched TLS traffic will then be sent to an upstream without being terminated.

- If you don't want the Layer4 Support anymore, just deactivate the option and it will be gone completely.

At the same time, the normal Reverse Proxy continues to work. Since this is all based on SNI, both the Layer4 Routes and the HTTP Reverse Proxy work on the same ports, giving maximum flexibility how your traffic is handled.

EDIT:
Already rewriting the feature slightly. I want to allow multiple domains per matcher, and also a not matcher.

EDIT2:
New version is uploaded that can do more stuff. Read the PR for examples.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 25, 2024, 11:07:00 PM
It worked once yesterday, then the DHCP went haywire and I had to reset the config. Now a day later, updated caddy to 1.6.0 and re-entered the exact same information, it doesn't want to anymore.

The goal was to make my Unify controller reachable on controller.example.com within my LAN. So it is not accessable from outside. I am on IONOS, so I have set up the following accordingly:

General Settings
- ACME Email: my address from IONOS
- DNS Provider: IONOS
- DNS API Standard Field: my API Key

Reverse Proxy
Domains
- example.com
  - DNS: Dynamic DNS [ x ]

This means that I can at least see the current WAN IP in my IONOS account, as my WAN IP is dynamic. Wonderful then. I create a wildcard domain:

Domains
- *.example.com
  - DNS-01 Challenge [ x ]

Subdomains
- controller.example.com
  - Domain: *.example.com
  - Subdomain: controller.example.com
  - Access List: private_ipv4

Handlers
- controller.example.com
  - Domain: *.example.com
  - Subdomain: controller.example.com
  - Upstream domain 192.168.10.10
  - Upstream Port: 8443

I don't see any errors in the Caddy log and on the other hand, my browser just says "Page could not be found".
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 25, 2024, 11:14:48 PM
Shouldnt dynamic DNS be activated on the subdomain too? Otherwise it won't update "controller.example.com" at ionos.

Please post your Caddyfile for further analysis.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 25, 2024, 11:34:14 PM
I tried that now, but it won't work. My browser still complains, that the site could not be found. However, at IONOS, an entry for the subdomain was added. However, I set this subdomain in caddy, to be only accessible from LAN 192.168.0.0/16. I have the feeling, that caddy won't update the local side..

Just to inform you, I'm going to sleep now, but I'll be back tomorrow.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 12:15:31 PM
I have checked your Caddyfile and it looks fine.

The only thing I can see is that "Dynamic DNS" is activated for the wildcard domain "*.example.com" too. That means, all subdomains under the wildcard domain are matched automatically by the dynamic DNS entry for the wildcard domain.

Otherwise, I don't see any mistakes here, so I am at a loss without some logs. If you don't see any logs, it must mean that Caddy does not receive anything.

Check the HTTP Access logs for your domains in the filesystem if your requests get through to Caddy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 01:23:59 PM
After some time had passed and it still wasn't working, I decided to take a very radical step. I reinstalled OPNsense completely using a previous config that I created before I started to use Caddy. Then I followed the same procedure as before. So one domain for example.com and one for *.example.com. I have activated DynDNS for both. Even if I wasn't sure - especially after your statement for the wildcard. However, I absolutely wanted to avoid a limitation by LetsEncrypt. It then successfully created a certificate for both domains. I then created a subdomain unify.example.com. I specified the wildcard domain as the domain. I wonder under what circumstances I would select example.com as the domain if I were to create a subdomain.

I have given the handler 192.168.10.10 with port 8443. TLS and Skip Verify are checked.

The only explanation I can come up with is that I was either limited and that's why it didn't work, or that something was wrong with the configuration of Caddy.

By the way. OPNsense with the widgets is a real cool and helpful bonus.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 01:31:21 PM
Im happy it works again, and you like the widgets. Maybe something went wrong somewhere.

Also, you /only/ need to add "example.com" if you want to route traffic directed /exactly/ to that domain.

For example you have:
example.com - Your website is hosted there.
cloud.example.com - Your nextcloud is there.

*.example.com would /not/ match example.com.

So if you don't have any use for example.com cause nothing matches that domain exactly, you can remove or deactivate it.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 02:12:13 PM
Thank you. Is it correct, that if I only want to have nextcloud.example.com available internally, that I still need to activate DynDNS?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 02:35:26 PM
If you have activated the DNS-01 challenge for a domain, Caddy does not necessarily have to be opened to the outside and does not really need to have Dynamic DNS activated.

You could just as well work with an internal DNS Server (Split DNS Zone) that points "nextcloud.example.com" to an internal IP address like "192.168.1.1".

How you set it all up depends on your usecase. It's very flexible, but when you stray too far from the documentation I wrote, things might get harder to set up and maintain.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 03:24:08 PM
Are there any more information to NAT reflection, related to Caddy? I found some forum posts, issues from users and blog entries related to NGINX. However, it would be nice to have it on a similar easy level, as it is on the Caddy OPNsense documentation.
In addition to that, I would be interested in any advantages or disadvantages to a override in UBound..
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 03:31:06 PM
You do not have any NAT when using Caddy in any scenario.

Caddy listens on "any" interface.

That means, if it receives a request from the internet, e.g. from 1.1.1.1, that targets the external IP of the OPNsense, e.g. 2.2.2.2 (DNS record of nextcloud.example.com), the request will be taken by Caddy, and then proxied to an internal IP, e.g. 192.168.1.2 (actual IP of nextcloud server). No NAT here.

Same happens when Caddy receives something from an internal IP address. E.g., there is an Unbound DNS override that points the nextcloud.example.com to an interface IP address of the OPNsense, e.g. 192.168.1.1. When one of your internal clients, e.g. 192.168.1.10 sends a request to nextcloud.example.com, it will hit 192.168.1.1 where Caddy listens. Cady proxies that request to 192.168.1.2 (where the actual nextcloud server listens.) Also no NAT.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 03:39:22 PM
I think you got me wrong. Similar to the documentation "Prepare OPNsense for Caddy After Installation" https://docs.opnsense.org/manual/how-tos/caddy.html#id4, I would like to know, how to setup NAT reflection or a Domain override in OPNsense.

One side note, am I correct that if I use Caddy for a subdomain that is actually only accessible from LAN (set access to LAN), I at least get the benefit of a valid certificate?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 03:41:30 PM
You understood me wrong. Why do you want NAT Reflection if there is no NAT to begin with?

I explained that in my last post.

If you meant you search for tutorials because you want to NAT other services, here you go: https://docs.opnsense.org/manual/how-tos/nat_reflection.html
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 26, 2024, 06:40:18 PM
Hi, i'm trying to switch from a docker install of NGINX Proxy Manager behind the opnsense firewall to this caddy plugin right on the firewall.
I got a couple of internal address i use that can be accessed only on the local network.
There's a wildcard setup with a proper certificate ( *local.domain.tld ) and it works on NGINX.

After following the guide at the first page, it does not seem to work on caddy.

I got 2 domains : 1 with the main domain.tld, one with the wildcard.
Under subdomains, i've setup the first one there under the wildcard *.local.domain.tld
I got 2 handlers, 1 with the main domain link to localhost under upstream, 1 with the wildcard+subdomain linked to a local lan address with a specified port.

The main domain link works and gets a proper page/certificate
The subdomain is unreachable/can't connect

What am i missing?!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 06:43:28 PM
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...)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 26, 2024, 06:50:47 PM
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
}
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 06:57:01 PM

*.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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 26, 2024, 08:49:54 PM
'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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) 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".
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 10:21:25 PM
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...
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 10:25:15 PM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: 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.. 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!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on July 26, 2024, 10:29:51 PM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 10:35:44 PM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 26, 2024, 10:41:48 PM
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..
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 26, 2024, 10:45:09 PM
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. ;)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 27, 2024, 03:45:25 AM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 27, 2024, 07:21:45 AM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 27, 2024, 10:48:25 AM
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.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on July 27, 2024, 11:07:33 AM
Is it correct, that if I add rules to the LAN interface, that I can replace any for source with LAN net? I ask, because the instruction states to use the same rules for WAN for LAN.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 27, 2024, 12:40:32 PM
Yes you can if you want. Though it does not really matter since only the LAN interface receives pakets from the LAN anyway already.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 27, 2024, 07:21:52 PM
Quote from: Monviech on July 27, 2024, 07:21:45 AM
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.

So, thanks for the heads up! I finally managed to make it work.
As every time something ain't working in networking... its always dns !

For DNS resolving, i'm using pi-hole > unbound > DoT

Pi-hole was not resolving the "local" domain and was throwing "non-existing domain"

Adding a local dns record thru pihole, pointing to the firewall made it resolve.

Now works as intended !
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 27, 2024, 07:36:51 PM
Good job, yeah DNS is tricky sometimes. Great it works :D
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: NeoDragon on July 27, 2024, 08:21:21 PM
Would you happen to know where the www folder for caddy is located?
I'd like the main domain to point to a single html file inside caddy

something like this :

<!DOCTYPE html>
<html>
  <body style="overflow:hidden; margin:0; text-align:center;">
    <img src="image.jpg" style="height:100vh; max-width:100%; object-fit: contain;">
  </body>
</html>
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 27, 2024, 09:07:19 PM
The plugin is not set up for it. It only serves as reverse proxy.

Though, you can read the documentation here:

https://caddyserver.com/docs/caddyfile/directives/file_server

You would need to set up a "root path". I would suggest to put it somewhere inside "/var/db/caddy/data/caddy/..."

To configure the file_server, you could then use the import statements. The *.conf file can set it up inside the site block. https://docs.opnsense.org/manual/how-tos/caddy.html#custom-configuration-files

I actually never used Caddy as a static web server before, only as reverse proxy. So, I'm not much of help here. Good luck though, shouldn't be too hard.

Also, I do not recommend to serve files from the firewall itself.  ;)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 28, 2024, 02:40:26 PM
Here is a new video that shows off the Layer4 routing of the next plugin version os-caddy-1.6.2

It remains very simple to configure, which is the main focus of this plugin.

https://www.youtube.com/watch?v=1IykZemclVA
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on July 31, 2024, 05:02:17 PM
The first version of the Layer4 feature is now complete and will be in the next plugin version. Additional Traffic matchers have been added.

https://github.com/opnsense/plugins/pull/4133

This means as an example:

The firewall only has port 443 open and Caddy listens there with its new Layer 4 module.

- SSH can be sent from port 443 to 192.168.1.1:22
- At the same time, RDP can be sent from 443 to 172.16.100.99:3389
- A TLS connection for OpenConnect VPN matched by SNI "vpn.example.com" can be sent to 127.0.0.1:8443
- The normal reverse Proxy can continue to work and serve any number of HTTPS Domains.

Since this is quite new in this form in Caddy, feedback is valuable.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 03, 2024, 09:32:26 PM
Hi Monviech, thank you very much for this great plugin. I would have a suggestion for improvement for the documentation "Reverse Proxy the OPNsense WebGUI". I followed the description to secure my subdomain. Therefore, I followed the description from the point of view that it is not about the OPNsense WebGUI for me: "The same approach can be used for any upstream destination using TLS and a self-signed certificate." From my point of view, it was difficult for me to get started in the section "Add a new HTTP Handler with the following options" because at first I didn't realize that "TLS Server Name: OPNsense.localdomain" should also be entered here for my case.

Background why I wanted to do this: I have the Unify Controller running via Docker in a DMZ and wanted to access it via the URL unify.example.com.

In Caddy I created
- a wildcard domain: "*.example.com"
- a subdomain "unify.example.com" with access list at 192.168.1.0/24
- a handler
  - with Upsteam domain and port to the Docker host of the Unify Controller
  - set "TLS Insecure Skip Verify" [ x ], otherwise the subdomain would not work
  - activated TLS under "Trust"

So today I went to unify.example.com and was greeted with a different interface. The interface belonged to a "securepoint utm v12". That set my alarm bells ringing. With "nslookup unify.example.com" I saw that numerous IP addresses lead to the subdomain, but only one of the listed ones was the current IPv4 of my Internet connection. I don't know if the settings for Unbound could have anything to do with it, so I suspect that I was allowed to see a live application of a man-in-the-middle attack.

So I followed the documentation. I went to the IP address of my Unify controller, clicked on the 🔒 lock, which was crossed out, and obtained the .pem file. I added the contents of the file under System ‣ Trust ‣ Authorities as "Import an existing Certificate Authority" in Certificate data. Including "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----". As I didn't have any "Private key data" and didn't know what to enter for "Serial for next certificate", I left this blank.

Under the handler, I adjusted the settings under "Trust", for "TLS Trust Pool" my created "Authorities" and under "TLS Server Name: OPNsense.localdomain". I would have thought that I could uncheck "TLS Insecure Skip Verify", but then the page remains blank/white.

The steps led to the Unify controller actually being displayed again.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 03, 2024, 09:41:25 PM
https://forum.opnsense.org/index.php?topic=38714.msg190745#msg190745

The tls server name is not always "opnsense.local". It is actually the SAN (subject alternative name) of the certificate you add into system - trust - authorities.

You have to check the certificate in the browser to find it out.

If both the certificate and the name are correct, then the connection works without tls insecure skip verify.

If you want something improved, feel free to open an issue here, or even better create a pull request and improve the section in the docs.

https://github.com/opnsense/docs
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 03, 2024, 09:55:56 PM
Thank you, for the explenation and the link. I edited the handler, and now it works without "TLS Insecure Skip Verify".

QuoteThe tls server name is not always "opnsense.local". It is actually the SAN (subject alternative name) of the certificate you add into system - trust - authorities.
Personally, I would be satisfied with the information or the sentence in the tip box.

I did not find the word SAN explicitly in Firefox, but only under "Security" "Validated by: CN=unifi" and under "Show certificate" only the owner or issuer name unify. I therefore did not see the connection to SAN here. If you could improve this part and put it in the green tip box, I'd be fine.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: aaronntw on August 05, 2024, 09:17:12 AM
how do I enable http.realip for domains behind cloudflare proxy?

https://caddy.its-em.ma/v1/docs/http.realip
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 05, 2024, 11:57:22 AM
I think it happens automatically as soon as you configure "trusted proxies" in the General Settings (advanced view)

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gryphon on August 07, 2024, 11:10:56 AM
This looks fantastic, but somehow it has managed to feel more complicated to setup than just a small VM with Caddy on it lol. Followed the instructions for the firewall and everything else for the initial setup, added my DNS provider with all the keys. I did turn off the ability to automatically create records, as many of my services I absolutely don't want accessible from off the network.

Despite having a functional A record in my DNS, I see a bunch of errors from Let's Encrypt claiming that there are no valid A or AAAA records for the domain I had entered. It actually errored enough times before I noticed that I got locked out.

Also, I've definitely never needed an email for Let's Encrypt before, not sure what that's about if I'm being honest, but whatever. Really I'd like to figure out why they're claiming there are no valid records despite having been perfectly fine on my VM that I paused 10 minutes before setting up.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 07, 2024, 11:46:44 AM
The email has been changed to required since there are two issuers inside. ZeroSSL requires an Email, Let's Encrypt does not. If one fails the other is tried automatically.

To keep it simple I required the Email. Just put in whatever ;D
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gryphon on August 07, 2024, 12:33:33 PM
Quote from: Monviech on August 07, 2024, 11:46:44 AM
The email has been changed to required since there are two issuers inside. ZeroSSL requires an Email, Let's Encrypt does not. If one fails the other is tried automatically.

To keep it simple I required the Email. Just put in whatever ;D

Ah, that makes sense. Any idea why Let's Encrypt would be claiming I have no valid A or AAAA records? They're definitely there.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 07, 2024, 12:46:14 PM
Sorry I'm not sure here, not so good with Lets Encrypt Troubleshooting. Maybe related to this?

https://github.com/opnsense/plugins/issues/4161

If in doubt, its /always DNS/™

If not maybe ask in the https://caddy.community and show your debug logs. They know this plugin exists.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 09, 2024, 03:37:07 PM
I have a problem with a dockerized Unify Controller. I was able to set a subdomain to the web GUI of Unify (Port 8443) with Cuddy. The subdomain is unify.example.com. There is an option for the AP, to set  a domain instead of an IP, for the guest hotspot. Without the domain option active, connecting to the Guest WLAN opens 192.168.1.10:8080 (http). It is possible to enable https, however without a proper certificate, this will a valid option.

So I thought, it would be a good option to use Caddy and activate the domain option in the AP. The problem is, that the hotspot tries to resolve to https://unify.example.com:8843 for https and :8080 for http.
I guess, that this will not work with caddy, because it only listens on 80 and 443, right?

Is it possible, to use Caddy here? Do I need to add FW rules for WAN, that allow 8843 or 8080?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 09, 2024, 04:30:08 PM
You can add the same domains multiple times, with different ports.

e.g.

example.com
example.com:8080
example.com:8443

and give each of them the right handler.

Thats a supported configuration.

And yes of course they need firewall rules.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 09, 2024, 04:45:49 PM
Do I need a specific configuration for that? I mean in the WebGUI of OPNsense, I set a domain example.com and a wildcard domain *.example.com. All actual subdomains are a result of the wildcard domain. I ask, because the description of the port states, that all subdomains will listen on the same port as the domain..
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 09, 2024, 04:47:12 PM
You should be able to add the same wildcard domain with different ports multiple times, and then select the other wildcard domain with the different port in a handler in addition to the same already created subdomain.

Essentially I think that should work, I have never tested it before though.

I don't think you have to duplicate the subdomains in the subdomain tab. I think it should just work to add the existing ones with the different wildcard domain in a handler, since they will get added to it.

Just try it out and if you get strange results show me your Caddyfile.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 09, 2024, 06:18:07 PM
Is it required to adjust the firewall rules? I ask, because the Caddy documentation assume, that Caddy uses Port 443 and 80 and so the firewall rules. If I add a domain with port 8843, is it required to add a corresponding firewall rule as well?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 09, 2024, 06:33:21 PM
Yes you have to open all ports in firewall rules that Caddy uses. It does not open any ports for you automatically.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on August 13, 2024, 08:41:37 PM
Hi,
Caddy is always adding new A records for * and @ even when update only is checked in settings
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 14, 2024, 06:30:11 AM
It depends on the provider, all of them are different, and all of the modules are written by different people so they do not all share the same featureset.

Best go to https://github.com/caddy-dns and find the provider you are using and open an issue where you also share part of your caddyfile.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 14, 2024, 10:52:46 AM
This explains a lot. I noticed, that my A-records increased with old IP addresses, since I use Caddy. I deleted old entries by hand on the IONOS dashboard.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on August 14, 2024, 03:46:24 PM
Quote from: Monviech on August 14, 2024, 06:30:11 AM
It depends on the provider, all of them are different, and all of the modules are written by different people so they do not all share the same featureset.

Best go to https://github.com/caddy-dns and find the provider you are using and open an issue where you also share part of your caddyfile.

Thanks for Info.

Quote from: Baender on August 14, 2024, 10:52:46 AM
This explains a lot. I noticed, that my A-records increased with old IP addresses, since I use Caddy. I deleted old entries by hand on the IONOS dashboard.
It's the same for me with IONOS
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 14, 2024, 03:54:02 PM
Here is the issue where I implemented the "Update Only" checkbox. It seems like it was broken for Ghandi too with duplicate A records being created.

https://github.com/opnsense/plugins/issues/4036

https://github.com/caddy-dns/gandi/issues/9

I do not doubt that other modules suffer from the same jank sometimes. The Dynamic DNS is not a "core" module of Caddy. So only the DNS Challenge will always work correctly since that seems to be the main usecase.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 14, 2024, 07:09:41 PM
I will open an issue for IONOS and see if it can be closed. In the meantime, I'll check whether setting the Update Only setting brings any improvement. It hasn't been active for me yet.

Btw. it would also be great if there was a link to the repository (https://github.com/caddy-dns) next to "DNS Provider". Because either I overlooked the solution or I couldn't find the way to enter the API key for IONOS straight away. In the end, I did find the solution, but it probably took me 15 minutes. A quick click on the repository now shows me that it's right there.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 14, 2024, 08:39:49 PM
It is actually baked into the very helptext inside the plugin.

Reading the help text... helps. :)

https://github.com/opnsense/plugins/blob/f9610f33c559498a1354cb6ba3154aa26a828b21/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/forms/dnsprovider.xml#L6
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on August 14, 2024, 10:55:48 PM
To be able to read it means to have found it. In other words, to have seen it. I guess I haven't. So everything is fine. Thank you!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: otakian on August 15, 2024, 11:25:58 PM
Hi Monvlech

New user to OPNsense here. I followed the installation guide and setup the firewall rules. However something is still missing when I attempt to create a new domain and it doesn't end up working.

For starters on my Caddy Certificates widget it says "Caddy does not manage any automatic certificates" and I get the following error from my logs

2024-08-15T16:10:33-05:00 Error caddy "error","ts":"2024-08-15T21:10:33Z","logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"opnsense-test.marquez.com","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 403 urn:ietf:params:acme:error:unauthorized - Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge"}
2024-08-15T16:10:33-05:00 Error caddy "error","ts":"2024-08-15T21:10:33Z","logger":"tls.issuance.acme.acme_client","msg":"validating authorization","identifier":"opnsense-test.marquez.com","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge","instance":"","subproblems":[]},"order":"https://acme-v02.api.letsencrypt.org/acme/order/1893209516/296576201246","attempt":2,"max_attempts":3}
2024-08-15T16:10:33-05:00 Error caddy "error","ts":"2024-08-15T21:10:33Z","logger":"tls.issuance.acme.acme_client","msg":"challenge failed","identifier":"opnsense-test.marquez.com","challenge_type":"tls-alpn-01","problem":{"type":"urn:ietf:params:acme:error:unauthorized","title":"","detail":"Cannot negotiate ALPN protocol \"acme-tls/1\" for tls-alpn-01 challenge","instance":"","subproblems":[]}}

Would appreciate any help trying to figure out what I haven't configured correctly. Appreciate the help!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 16, 2024, 06:05:05 AM
The error means that the TLS-ALPN-01 challenge fails.

Without knowing more of the infrastructure its hard to help.

Make sure Caddy can receive traffic directed to it for your Domain Name, on IPv4 and (if available) IPv6. That means the A and AAAA records have to point to the external IP address of the OPNsense, or to the external IP of the router you use that forwards or DNATs this traffic to the OPNsense with Caddy.

If you can't open Firewall for ACME, consider using the DNS-01 challenge with a DNS Provider to receive certificatea without Firewall issues.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: otakian on August 16, 2024, 06:27:59 AM
Thanks for confirming. I was researching for a couple of hours and finally realized my issue. I need a domain first and to point it in the right spot. I was so new and your tutorial made it seem so simple that that part never registered. Thank you, I think once I sort that out I should be good to go.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 16, 2024, 06:53:40 AM
Yeah the tutorial does imply some knowledge about how the domain name system works, and that you need your own domains and stuff.

But it's hard to make it clearer cause at some point you just have to assume a certain level of knowledge, or you have to start with adam and eve in these tutorials.

Happy you understood whats not working and how to fix it.  :)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on August 18, 2024, 06:49:36 PM
Quote from: Monviech on August 14, 2024, 06:30:11 AM
It depends on the provider, all of them are different, and all of the modules are written by different people so they do not all share the same featureset.

Best go to https://github.com/caddy-dns and find the provider you are using and open an issue where you also share part of your caddyfile.

The problem with the IONOS DNS Plugin is fixed and working as it should when "Update only" is selected. See Issue: https://github.com/caddy-dns/ionos/issues/7 (https://github.com/caddy-dns/ionos/issues/7)

Will caddy will be updated automaticly in near future by OPNSense or do i have to stick with my own build? Not sure how it works.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 18, 2024, 07:11:36 PM
Thanks for taking care of it.

I'll update the build for the next os-caddy version (1.6.3).

The build works like this:

https://github.com/opnsense/tools/blob/a1c883deffd29c15588e852f7a143bea04d7214a/config/24.7/make.conf#L97

The commit hashes are updated manually every once in a while to keep the build reproducible.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 20, 2024, 07:02:26 PM
Im still waiting for another module to get an update so I won't update the dependencies for this minor version since I want to do it in one swoop.

I gonna try again for os-caddy-1.6.4.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: W0nderW0lf on August 23, 2024, 01:31:04 PM
no one cares...
<delete me>
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Aergernis on August 29, 2024, 05:05:22 PM
Quote from: Monviech on August 20, 2024, 07:02:26 PM
I gonna try again for os-caddy-1.6.4.

Is the IONOS Patch included in 1.6.4?


Never mind. Thought i've seen 1.6.4 but it's 1.6.3_1
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on August 29, 2024, 05:18:04 PM
@Aergernis

I have updated the build though, so just go to packages and press "reinstall" on "caddy-custom". The ionos patch should be included then.

https://github.com/opnsense/tools/pull/429

@W0nderW0lf

I did not know an answer there, best go to https://caddy.community.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on September 02, 2024, 10:04:57 AM
I have allowed ports 80 and 443 on both WAN and LAN for Caddy. If I now set a subdomain in Caddy for a LAN application: https://foo.example.com:8843, do I then have to allow the port on WAN and on LAN or is LAN sufficient? The application should not be accessible from the Internet.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 02, 2024, 10:23:24 AM
Just LAN will be enough I think.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Calimarina on September 10, 2024, 11:10:04 PM
Do you have any advice on how I can get wordpress working. I have Caddy working with these domains except wp.domain.org:
       
kuma.domain.org
unraid.domain.org
proxmox.domain.org
portainer.domain.org
wp.domain.org

All of them Kuma, unRaid, Proxmox, and Portainer come up with no problem. Certificates working as well. Except for Wordpress. Kuma, Portainer and Wordpress are all docker containers. When I try to load Wordpress I get a, "Bad gateway Error code 502" from Cloudflare. I just don't understand why all the others work, but WordPress doesn't. Any advise would be greatly appreciated.

I get these two errors from Caddy. I took out my IP's and replaced it with DOMAIN for this message:

"error","ts":"2024-09-10T20:59:47Z","logger":"http.log.access","msg":"handled request","request":{"remote_ip":"DOMAIN","remote_port":"62058","client_ip":"DOMAIN","proto":"HTTP/2.0","method":"GET","host":"DOMAIN","uri":"/","headers":{"Accept-Language":["en-US,en;q=0.5"],"Sec-Fetch-User":["?1"],"X-Forwarded-Proto":["https"],"Cf-Ipcountry":["US"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8"],"X-Forwarded-For":["DOMAIN"],"Priority":["u=0, i"],"Accept-Encoding":["gzip, br"],"Sec-Fetch-Site":["none"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Upgrade-Insecure-Requests":["1"],"Cdn-Loop":["cloudflare; loops=1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0"],"Cf-Ray":["8c1257f16b642863"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Dest":["document"],"Sec-Gpc":["1"],"Cf-Connecting-Ip":["DOMAIN"],"Dnt":["1"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"DOMAIN"}},"bytes_read":0,"user_id":"","duration":3.011785027,"size":0,"status":502,"resp_headers":{"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"]}}

"error","ts":"2024-09-10T20:59:47Z","logger":"http.log.error","msg":"dial tcp 10.10.72.10:8189: i/o timeout","request":{"remote_ip":"DOMAIN","remote_port":"62058","client_ip":"DOMAIN","proto":"HTTP/2.0","method":"GET","host":"DOMAIN","uri":"/","headers":{"X-Forwarded-Proto":["https"],"Cf-Ipcountry":["US"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Sec-Fetch-User":["?1"],"X-Forwarded-For":["DOMAIN"],"Priority":["u=0, i"],"Cf-Visitor":["{\"scheme\":\"https\"}"],"Upgrade-Insecure-Requests":["1"],"Cdn-Loop":["cloudflare; loops=1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0"],"Accept-Encoding":["gzip, br"],"Sec-Fetch-Site":["none"],"Sec-Fetch-Dest":["document"],"Sec-Gpc":["1"],"Cf-Connecting-Ip":["DOMAIN"],"Dnt":["1"],"Cf-Ray":["8c1257f16b642863"],"Sec-Fetch-Mode":["navigate"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"DOMAIN"}},"duration":3.011785027,"status":502,"err_id":"hydwhx7fz","err_trace":"reverseproxy.statusError (reverseproxy.go:1269)"}
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 11, 2024, 06:12:41 AM
Hey. The log states that caddy is unable to connect to
dial tcp 10.10.72.10:8189: i/o timeout

Its a Layer 3 Problem. Maybe a typo? Or the host has a firewall rule that denies access from the IP Caddy comes from? It must be a network problem.

https://caddy.community/t/log-i-o-timeout-meaning/20048
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Calimarina on September 11, 2024, 05:28:39 PM
I configured my firewall to allow everything in and out for testing purposes, but it still doesn't work so it has to be something else. I'm going to try other CMS's like Joomla and Drupal to see if they work. Everything else I've tried like Kuma, unRaid, Proxmox, and Portainer all work just fine.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 11, 2024, 05:54:05 PM
I didnt mean the firewall of the opnsense. I mean maybe theres a firewall on the host itself that serves wordpress, and it blocks the incoming connection. Maybe theres fail2ban or something on that host too. I would check anything that blocks IP addresses. I tried with my own wordpress and it "justworks TM".
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Calimarina on September 11, 2024, 09:45:13 PM
I apologize I didn't understand what you meant. However since you showed me it could be done I went back and figured it out. I was using a template in Portainer. When I redeployed using stack method it worked. Thank you very much for your plugin. I couldn't get nginx or haproxy to work because they are too complicated for me.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on September 12, 2024, 04:12:10 PM
Some weeks ago, there was an issue with the dynamic DNS for IONOS, where the API added new records instead of updating them. The issue was fixed, but I wonder when it will come to OPNsense caddy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 12, 2024, 04:59:34 PM
Today :)

If the caddy-custom is not updated automatically, just go to

/ui/core/firmware#packages

search the caddy-custom package and press "reinstall"
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on September 12, 2024, 05:37:36 PM
Nice. It became a very annoying routine, in the last few weeks, to clean old records. I am looking forward to the update.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 12, 2024, 05:59:13 PM
I mean its in here: https://forum.opnsense.org/index.php?topic=42787

So already available.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: RobLatour on September 15, 2024, 10:07:07 PM
This plug in looks great - but also a bit over my paygrade.

I've read thru the documentation, and this post, and have a request ...

Would it be possible to put together a youtube video showing a setup walk through for the following scenario (which I suspect would be beneficial for many homelab users):

Assuming the user already has a registered domain name ( for example: example.com )
Assuming they are already set up with a Cloudflare account

The video to show what would be required in OPNSense / the caddy plug in to:

set up to have a certificate that automatically renews associated with example.com

set up to have caddy used to securely reference specific internal addresses such as:

opnsense.example.com
homeassistant.example.com
openmediavault.example.com
jellyfin.example.com
etc.
(on which ever ports are required)

setup to ensure none of the above can be accessed externally from the internet  (i.e. access only applies to internal accesses)

setup to have the external ip address of example.com updated via Cloudflare when it changes.








Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on September 19, 2024, 04:52:49 PM
In addition to Caddy on the OPNsense, I set up a Caddy proxy in a subnet 192.168.50.10. In that Caddy file, I would like to add the global trusted_proxies directive:
QuoteEnabling this causes trusted requests to have the real client IP parsed from HTTP headers (by default,

Is the IP address of the trusted proxy, the gateway of the subnet? 192.168.50.1? So to say, the Caddy proxy of the OPNsense is a trusted source?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: frauhottelmann on September 19, 2024, 05:10:25 PM
I feel like I should add this here as well:

How to enable HSTS for the "official" Nextcloud docker.

Go to Caddy --> Reverse Proxy --> HTTP Headers and add a new one.
Header: header_down
Header Type: +Strict-Transport-Security
Header Value:  max-age=31536000;

Save and add it to your Nextcloud http handler. Save and apply.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: baragsen on September 26, 2024, 03:26:40 PM
Heya,
Thanks a lot for your work and for the tutorial. It really helped me out a lot.
There is one small issue that I am having with Caddy and  my nextcloud (of course) container.
I can access it using my domain from outside my local network, but when trying to connect it through my local network, I keep getting ERR_SOCKET_NOT_CONNECTED or PR_END_OF_FILE_ERROR issues. I did not mess with NAT reflection nor with Unbound DNS as the tutorial says that there won't be a need for it, but I still cannot get access locally.
My caddyfile is as follows:

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


# caddy_user=root

# Global Options
{
log {
output net unixgram//var/run/caddy/log.sock {
}
format json {
time_format rfc3339
}
level DEBUG
}

dynamic_dns {
provider cloudflare xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
domains {
example.com *
example.com nc
}
}

email example@mail.com
grace_period 10s
import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


# Reverse Proxy Domain: "a46e07f0-97d6-40ee-a4ba-c219beee103f"
*.example.com {
tls {
issuer acme {
dns cloudflare xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
}
}

@f601ec75-1d72-4165-a41c-34322ad8a17a {
host nc.example.com
}
handle @f601ec75-1d72-4165-a41c-34322ad8a17a {
handle {
reverse_proxy 10.150.0.10:8666 {
header_down +Strict-Transport-Security "max-age=31536000;"
}
}
}
}

import /usr/local/etc/caddy/caddy.d/*.conf


Unfortunately no logs from caddy as nothing shows up when trying to access it internally. When using nslookup on the domain, I get my opnsense ip.
Server:  firewall.home.lan
Address:  10.150.0.1

Name:    nc.example.com
Address:  10.150.0.1


Any help would be appreciated!!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 26, 2024, 03:34:23 PM
Did you create the same Firewall rule for WAN also for LAN/other interfaces you use?

You shouldn't use Split DNS Zones with Caddy, just use the external IP address from internally and externally. I can see your nextcloud resolves to the internal IP of your OPNsense. (Technically its possible and people do it but it complicates some firewall rules and stuff)

https://docs.opnsense.org/manual/how-tos/caddy.html#caddy-troubleshooting

If nothing of these hints work please post some debug logs where caddy logged the error you see happening.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: baragsen on September 27, 2024, 01:23:38 PM
Quote from: Monviech on September 26, 2024, 03:34:23 PM
Did you create the same Firewall rule for WAN also for LAN/other interfaces you use?

You shouldn't use Split DNS Zones with Caddy, just use the external IP address from internally and externally. I can see your nextcloud resolves to the internal IP of your OPNsense. (Technically its possible and people do it but it complicates some firewall rules and stuff)

https://docs.opnsense.org/manual/how-tos/caddy.html#caddy-troubleshooting

If nothing of these hints work please post some debug logs where caddy logged the error you see happening.

The Split DNS setup in Unbound was remaining config from my old HAProxy setup, that's fixed now. But it did not solve my issue. The actual problem I found was that I was checking the Dynamic DNS box in both Domains and Subdomains, and I have some misconfiguration as well on the Cloudflare dashboard. Since cleaning all that up, it has been working perfectly.

Thanks a lot!

Edit: Quick question, is there any way to use other caddy directives in the GUI e.g. php_fastcgi and fileserver? It would be an improvement for me to use caddy instead of using Nextcloud with its own embedded Apache web server.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on September 27, 2024, 01:41:02 PM
Great that you figured it out.

No you can only use the directives in the GUI that you can see in the GUI.

For custom stuff you can always use custom configuration files:
https://docs.opnsense.org/manual/how-tos/caddy.html#custom-configuration-files

I advice against it though. Use it only as reverse proxy. Do not serve static files with it (on the OPNsense).
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: DivHunter on October 01, 2024, 02:43:45 AM
I can't add multiple ports for load balancing? Am I missing something?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 01, 2024, 06:18:32 AM
No the GUI only allows for the same port being used on all backend webservers in the same loadbalancing group.

Whats the usecase for different ports there?

Since all webservers that load balance should be configured the same way, why serve them on different ports?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: DivHunter on October 01, 2024, 06:34:26 AM
Multiple instances per machine/GPU for the service.

Looking at the caddy config I did wonder why it was not just one field with ip:port entries so you could do any combination as you can in the config itself.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 01, 2024, 06:41:43 AM
It has grown historically while building the plugin and now its hard to change it without breaking existing setups.

Its one of these things.

There are some validations attached tp the port field too, since when you change to the www user it gets validated extensively.

Im sure it could all be somehow resolved with migrations and different fieldtypes but the usecase is very small so somebody who needs it would have to invest time there.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: DivHunter on October 01, 2024, 07:04:26 AM
Is what it is, I'll just use something else for now.

It's a pain when you have things tied up in validation and existing configs.

It's very cool to have the additional functions of caddy available on opnsense.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 01, 2024, 07:19:48 AM
well you could work around it by having multiple virtual IPs on that host and bind one GPU instance per virtual IP on the same port for each. Then each socket on the same host would also be unique even with the same port.

But yeah this wont be resolved anytime soon.

Or write your own config file for that one usecase. You can still use the GUI for all other things.

https://docs.opnsense.org/manual/how-tos/caddy.html#custom-configuration-files
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gautier on October 11, 2024, 09:48:21 AM
Hi,
I install Caddy and configure follow the tutorial but I have error:
"error","ts":"2024-10-11T07:26:56Z","logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"toto.pequod.sokil.fr","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:connection - 89.219.181.98: Timeout during connect (likely firewall problem)"}

I really don't know where to start
I also on freeBSD and debian install caddy to test with the same error.

I have another site with OPNsense and caddy on debian behind without error, I miss something but what ?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 11, 2024, 09:51:57 AM
Well I get no connection to your IP either. So its either a firewall problem, the IP is a CGNAT IP, you have to troubleshoot that with curl for example:

curl -v 89.219.181.98
*   Trying 89.219.181.98:80...
^C
curl -v 89.219.181.98:443
*   Trying 89.219.181.98:443...
^C

See theres nothing, no response. So Let's Encrypt can not connect either.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gautier on October 11, 2024, 11:21:48 AM
https://imgur.com/a/y2YyIJN

I created nat port forward to my server directly with the port 80 and everything work.
If I forward 443 to 80, can be considerate as a good test to check if ISP block something ?

https://imgur.com/n3XyyQt I reach the webserver


Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 11, 2024, 02:12:08 PM
Maybe the This Firewall alias does not work for you for some reason.

Try to disable the port forward rule.

Set the rules on WAN to "WAN address" instead.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on October 11, 2024, 02:20:32 PM
I have a similar problem. From time to time, my domains are not reachable. I restricted them to the LAN network. Some services and my vacuum robot. The only thing that helps, is to perform a restart of the OPNsense and to get a new IP and new Records for the domains. A restart of caddy won't work. The services are reachable by their IP, when the problem occurs.

Would it help to set caddy to debug and send the log from the beginning, when it's working until the moment it fails? It could be a lot of log data, because I don't know when it will happen. Moreover I think, that this is related to a problem with IPv6 prefix delegation. In general, would it be a good idea, to combine the caddy logs, with the logs of the OPNSENSE system? Is this only manually possible?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 11, 2024, 02:37:44 PM
I do think such a problem is out of scope for me to troubleshoot. Sorry.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gautier on October 11, 2024, 04:12:15 PM
I m agree with you, it's firewall problem config but witch checkbox  ;D
I continue to search
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on October 18, 2024, 08:12:13 AM
Hey there, thank you very much, for bringing Caddy to OPNsense. It is a real pleasure, to such wonderful tool on the sense. I even like it that much, that I use Caddy as a webserver or reverse proxy in other projects as well.

I would like to add a TURN and STUN Server (Coturn: https://github.com/coturn/coturn (https://github.com/coturn/coturn)) to my infrastructure. It is a requirement for my Nextcloud. At first I tried to an additional subdomain to Caddy, that extents to my nextcloud.example.com.
However, that required to have a wildcard domain with the port 3478 and the actual subdomain nextcloud.example.com:3478. Not to mention opening another port on the firewall.

Would it be possible to use the Caddy: Layer4 Routes feature for my project? Is it an TLS (SNI) type then and moreover, is it still required to open the port 3478 for it?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 18, 2024, 08:56:28 AM
Using Nextcloud Talk is notoriously difficult.

I would rather use IPv6 where a stun and turn server is not needed, because webrtc can create a direct socket from endpoint to endpoint.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on October 18, 2024, 09:00:00 AM
Quote from: Baender on October 18, 2024, 08:12:13 AM
Would it be possible to use the Caddy: Layer4 Routes feature for my project? Is it an TLS (SNI) type then and moreover, is it still required to open the port 3478 for it?

STUN and TURN is UDP, so no. You need inbound NAT port forwarding for that. Which answers the port question, I guess :)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 18, 2024, 09:03:15 AM
Actually the Layer 4 feature in Caddy had a big overhaul, so you can use it to stream UDP traffic too, from any port to any port. And you can even use layer 7 matchers additionally inside the layer 4 matchers to selectively match and route traffic.

Check it out :)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on October 18, 2024, 09:05:33 AM
Quote from: Monviech on October 18, 2024, 09:03:15 AM
Actually the Layer 4 feature in Caddy had a big overhaul, so you can use it to stream UDP traffic too, from any port to any port.

TIL - thanks :)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 18, 2024, 09:06:25 AM
@Patrick

E.g. you can match and route wireguard which is UDP

https://github.com/opnsense/plugins/issues/4201#issuecomment-2405077886
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on October 24, 2024, 06:03:44 PM
Thank you for the explanation.

I have noticed, that since I enabled IPv6 and using Track Interface, most of my subdomains, that are restricted to local IPs, won't work. This is because I only set IPv4 addresses to the access list. How can I allow "local" IPv6 addresses?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 24, 2024, 06:53:27 PM
You just have to add your GUA to that access list.

e.g.

2001:db8:1234:5600::/56

If its not static you are a little out of luck here since the access list can not be updated with a dynamic prefix. In that casw it would be easier to only have A Records and no AAAA records for your domains.

If you use the dynamic dns feature set it to ipv4 only.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on October 24, 2024, 07:22:27 PM
Oh, no. Please don't tell me that.. Yes, it is dynamic.. Could I override the Caddyfile then? I know, that for Caddy there might be such Plugin, but if I would write a script, that checks the current IP? Would that help?

Just a side note from my side: with one of the recent caddy releases on OPNsense, the description for domains and subdomains got a bit out of control. I personally find it problematic, to show the domain and the description, that results in a lot of text, in the selection GUI and on the overview. Do you know what I mean?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 24, 2024, 07:33:12 PM
The issue here is how to tell caddy that the IP has to change in the access list, and then also reload the service so it is indeed loaded. This can be rather complex, since there is no general default access list into which this could be implemented genericly. Everybody manages their own lists that are saved in their own configuration.

There is no official module for this: https://github.com/caddyserver/caddy/issues/5813

And regarding the description, I had to add it to the subdomain dropdown since otherwise there would be no way to keep different subdomains apart, that have the same subdomain name, but are added under multiple wildcard domains with different ports. So we have to life with that now.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 24, 2024, 07:43:53 PM
If you want to write a script it has to be a php script that targets the API that the framework of the caddy plugin provides. You could update your specific access list witj your correct IPv6 network when it changes and then use the service API to trigger a reconfigure act.

https://github.com/opnsense/plugins/tree/master/www/caddy/src/opnsense/mvc/app/controllers/OPNsense/Caddy/Api
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 24, 2024, 07:58:10 PM
All descriptions in domains/subdomains etc... are optional btw so delete the ones you dont need.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Baender on October 24, 2024, 08:55:15 PM
Okay a really complex topic then. Would it be (in theory) possible, to let Caddy read the aliases of the firewall? Would it be a polling, or as it might be in the memory, on the fly change, if I would add the IPv6 address as an alias?

I guess, still out of scope. However, I am just curious.

Edit:
Would it be possible, to set dynamic DNS setting on the domain/subdomain? I mean if it should pass a IPV6 and/or IPv4 address? Maybe the module for dynDNS is not structured for this..
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: dinguz on October 24, 2024, 08:58:09 PM
I have caddy configured as a reverse proxy for the OPNsense GUI and as a SSH multiplexer, more or less according to the docs found here: https://github.com/opnsense/docs/blob/11e66816989bb12633e01e144ebf42b11508755a/source/manual/how-tos/caddy.rst (https://github.com/opnsense/docs/blob/11e66816989bb12633e01e144ebf42b11508755a/source/manual/how-tos/caddy.rst)

Unfortunately, I am having an issue where it prevents system reboots, both from the GUI and from the CLI menu (option 6). The rebooting hangs on shutting down caddy, which apparently never happens. The only thing that currently works is issue a 'shutdown -r now' from the CLI. The log files aren't giving me much direction how to go about investigating this. Any tips or advice?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 24, 2024, 09:07:33 PM
@dinguz

I have to ask upstream for this. I'll come back to this when I know more. What I can say is I do sometimes fight with the shutdown behavior of caddy. When it has open tcp/udp connections it can wait indefinitely until they are closed in certain configurations.

Thats why the service script now has sigkill implemented. But that will not happen on "service caddy stop" (which is used during reboot), only on "configctl caddy stop".
https://github.com/opnsense/plugins/pull/4261


@Baender

The dynamic dns module only has global settings. So set Ipv4 only globally if you need access lists with rfc1918 addresses. Otherwise look into forward auth or basic auth to secure access if you rely on dynamic ipv6. The way access lists are handled will not be changed in the current plugin implementation.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 25, 2024, 01:58:40 PM
@dinguz

https://github.com/mholt/caddy-l4/issues/258

For now either close the ssh connection after initiating a restart, or use "configctl caddy stop" since it has a mechanism that will kill caddy after 20 seconds.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: dinguz on October 25, 2024, 08:12:46 PM
Quote from: Monviech on October 25, 2024, 01:58:40 PM
For now, either close the ssh connection after initiating a restart, or use "configctl caddy stop" since it has a mechanism that will kill caddy after 20 seconds.

Many thanks!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: meyergru on October 26, 2024, 10:00:55 PM
Today I took the opportunity to try out Caddy reverse proxy instead of HAproxy, mostly because of a very specific problem with HAproxy...

I must say I reverted after trying it thouroughly. My 2cents on this are as follows:

- Caddy is suited to home setups and inexperienced users. HAproxy is much more complex.
- For example, the certificate setup is much easier, because you just have to specify the domain and it just works (tm).
- However, if you have more than just one domain, Caddy setup gets a little tedious:
* you have to create one domain/certificate plus a http backend for any domain, which includes creating different ones for www.domain.de and domain.de. You cannot combine certificates for multiple domains unless they are subdomains.
* You do not have much control over what type of certificate(s) are created - you cannot specifiy strength or ECC vs. RSA (much less both) and I have not found a means to control if ZeroSSL vs. LetsEncrypt is used.
* The ciphers being employed cannot be controlled easily - or, for TLS 1.3, at all. That results in an ssllabs.com score which is suboptimal, becaus 128bit ciphers are allowed. This cannot be changed because of Go limitations (https://caddy.community/t/specify-tlsv1-3-cipher-suites/13058/3).
* You cannot use more than one type of DNS-01 verification if you use wildcard domains.
* The Auto HTTPS feature looks nice first, but indeed it uses a 308 instead of a 301 code, which breaks some monitoring and can only be modified via custom include files.

So, if you just want to reverse-proxy some services in your home network, go with Caddy. For an OpnSense guarding your internet site with several services/domains, stay with HAproxy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on October 26, 2024, 10:04:00 PM
@meyergru exactly the situation with my home lab vs. our data centre operation  ;)

Thanks for the concise summary.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 26, 2024, 11:04:29 PM
I just knew the target audience of this. Caddy filled the niche pretty well imo for home setups.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: meyergru on October 26, 2024, 11:09:22 PM
No complaints for the right target audience, Cedrik - I just heard it was much easier and tried it.

Even if you would add some features, you would only end up at something inherently more complex. Plus, some restrictions seem to be hard-wired (like the TLS 1.3 ciphers imposed by Go).
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 26, 2024, 11:17:57 PM
The Reverse Proxy is pretty much finished, but the layer 4 module will get more features over time.

Next thing is an OpenVPN matcher where you can multiplex on the same port via tls static keys for example.

Theres some neat Layer 7 matchers coming.

https://github.com/mholt/caddy-l4/pull/251
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: yarcod on October 27, 2024, 01:06:15 AM
Hi!

I tried setting up the Caddy plugin but ran into some issues. Just setting up a basic reverse proxy does not seem to work for me when following the guide. It doesn't give me any errors from the GUI and the Caddy service appears to be running properly, but trying to run caddy reload --config /usr/local/etc/caddy/Caddyfile results in an error not displayed elsewhere:

Error: sending configuration to instance: performing request: Post "http://127.0.0.1:2019/load": dial tcp 127.0.0.1:2019: connect: connection refused

Maybe it is not possible/supported to reload caddy this way? Even though the service appears to be up, it does not seem able to connect properly, given:

> curl -vL 127.0.0.1:80
*   Trying 127.0.0.1:80...
* Immediate connect fail for 127.0.0.1: Connection refused
* Failed to connect to 127.0.0.1 port 80 after 0 ms: Could not connect to server
* closing connection #0
curl: (7) Failed to connect to 127.0.0.1 port 80 after 0 ms: Could not connect to server

What could I be missing? Thanks in advance!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 27, 2024, 05:42:48 AM
sockstat -l | grep -i 80
sockstat -l | grep -i 443

Make sure no other services use port 80 and 443.

service caddy status

Check if Caddy is running

service caddy restart
service caddy reload

Restart Caddy if needed
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: yarcod on October 27, 2024, 10:06:40 AM
Quote from: Monviech on October 27, 2024, 05:42:48 AM
sockstat -l | grep -i 80
sockstat -l | grep -i 443
I can see that Caddy has managed to bind to port 443, but not 80. AFAICT no other service has taken port 80 either: Doing curl on localhost:443 results in "error:0A000438:SSL routines::tlsv1 alert internal error". Output of sockstat for port 80:

# sockstat -l | grep -i 80
root     lighttpd   30649 4   tcp4   127.0.0.1:43580       *:*
root     lighttpd   30649 5   tcp6   ::1:43580             *:*
root     ntpd       10336 23  udp6   fe80::e01d:f0ff:fe2a:e3c2%vtnet0:123 *:*
root     ntpd       10336 24  udp6   fe80::b8a0:afff:fe98:12fe%vtnet1:123 *:*
root     ntpd       10336 27  udp6   fe80::1%lo0:123       *:*
root     php-cgi    38055 0   stream /tmp/php-fastcgi.socket-0
root     php-cgi    38040 0   stream /tmp/php-fastcgi.socket-0
root     sshd       11827 8   tcp6   fe80::1%lo0:2223      *:*


Quote from: Monviech on October 27, 2024, 05:42:48 AM
service caddy status
Caddy appears to be running just fine: "caddy is running as pid 72385."

Quote from: Monviech on October 27, 2024, 05:42:48 AM
service caddy restart
service caddy reload
This did perform a clean restart and reload of Caddy, as opposed to asking Caddy to reload itself. So that's nice to know! Still, it unfortunately did not make any difference.

I noticed that I had used an older version of the plugin, so just to be safe I also did reset most settings and applied it again to see if the update had fixed something related to what I attempted to setup. But still no success.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on October 27, 2024, 01:31:02 PM
Quote from: yarcod on October 27, 2024, 10:06:40 AM
I can see that Caddy has managed to bind to port 443, but not 80. AFAICT no other service has taken port 80 either: [...]

Make sure System > Settings > Administration > HTTP Redirect - Disable web GUI redirect rule

is checked.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 27, 2024, 04:35:12 PM
I could say more if I can see the Caddyfile. But right now no idea really.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: yarcod on October 27, 2024, 06:46:19 PM
Quote from: Patrick M. Hausen on October 27, 2024, 01:31:02 PM
Thanks -- I ensured that it was still checked.

Quote from: Monviech on October 27, 2024, 04:35:12 PM
I could say more if I can see the Caddyfile. But right now no idea really.

The Caddyfile looks like this (did not find any spoiler tag to compress my message):

{
   log {
      output net unixgram//var/run/caddy/log.sock {
      }
      format json {
         time_format rfc3339
      }
      level DEBUG
   }

   servers {
      protocols h1 h2 h3
   }

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

# Reverse Proxy Configuration


# Reverse Proxy Domain: "62300f65-2a08-47ef-b1f7-d0e31bbd30c4"
*.edholm.cc {
   tls /var/db/caddy/data/caddy/certificates/temp/64c1e555e19da.pem /var/db/caddy/data/caddy/certificates/temp/64c1e555e19da.key

   @07356a3a-8362-4a3e-afd3-7f0b521a44e9 {
      host jelly
   }
   handle @07356a3a-8362-4a3e-afd3-7f0b521a44e9 {
      handle {
         reverse_proxy 192.168.1.101:8096 {
         }
      }
   }
}

import /usr/local/etc/caddy/caddy.d/*.conf
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 27, 2024, 06:56:52 PM
Auto HTTPS is off thats why there is no port 80.

Change the setting in general settings.

It needs to be on for the automatic http to https redirect even if you dont use lets encrypt.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 27, 2024, 08:29:56 PM
@Meyergru:

Thanks for trying it out and your review. I can add some comments to your points:

QuoteToday I took the opportunity to try out Caddy reverse proxy instead of HAproxy, mostly because of a very specific problem with HAproxy...

I must say I reverted after trying it thouroughly. My 2cents on this are as follows:

Quote- Caddy is suited to home setups and inexperienced users. HAproxy is much more complex.
- For example, the certificate setup is much easier, because you just have to specify the domain and it just works (tm).

-> Perfect, that was the target audience. So I guess I hit the right spot if that was noticable. ;D They like how neatly integrated features like dynamic dns, dns providers and the dns01 challenge is for their certificates. Creating a new domain just takes a few clicks and it just worksTM. These features are mostly unnecessary for enterprises. Steps to set things up are kept to a minimum with minimal abstraction.

Quote- However, if you have more than just one domain, Caddy setup gets a little tedious:
* you have to create one domain/certificate plus a http backend for any domain, which includes creating different ones for www.domain.de and domain.de. You cannot combine certificates for multiple domains unless they are subdomains.

-> Thats the tradeoff of less abstraction. It means experts will find limitations here.

Quote* You do not have much control over what type of certificate(s) are created - you cannot specifiy strength or ECC vs. RSA (much less both) and I have not found a means to control if ZeroSSL vs. LetsEncrypt is used.
* The ciphers being employed cannot be controlled easily - or, for TLS 1.3, at all. That results in an ssllabs.com score which is suboptimal, becaus 128bit ciphers are allowed. This cannot be changed because of Go limitations.

-> That one is indeed for the Go developers to battle out with their userbase: https://github.com/golang/go/issues/29349

Though the defaults are okay, and an online test that gives a score can be misleading in this case. It probably comes down to company policies. Most of the discussion here always revolves about compliance.

Quote* You cannot use more than one type of DNS-01 verification if you use wildcard domains.

-> Limitation of the plugin, not of caddy. The plugin combines the same DNS provider for dynamic dns (which only allows one provider) and the dns01 challenge (which allows multiple providers). To make it simple and less confusing, the lowest denominator was chosen. So it is more suited for home/homelab environments or small businesses here that have one provider for their domains. I know of some people who use it to reverse proxy exchange servers for example, that works well even with outlook etc...

Quote* The Auto HTTPS feature looks nice first, but indeed it uses a 308 instead of a 301 code, which breaks some monitoring and can only be modified via custom include files.

-> That sounds like an easy fix if you can tell me what is needed there to change the default if needed.

QuoteSo, if you just want to reverse-proxy some services in your home network, go with Caddy. For an OpnSense guarding your internet site with several services/domains, stay with HAproxy.

-> That is a very sane conclusion and I mostly agree with it. Though the way the layer4/7 proxy and matcher ecosystem evolves makes it pretty powerful in its own way, if not only looking at the reverse proxy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: meyergru on October 27, 2024, 10:39:32 PM
Quote from: Monviech on October 27, 2024, 08:29:56 PM
Quote* The Auto HTTPS feature looks nice first, but indeed it uses a 308 instead of a 301 code, which breaks some monitoring and can only be modified via custom include files.

-> That sounds like an easy fix if you can tell me what is needed there to change the default if needed.

That can be done via something like:

/usr/local/etc/caddy/caddy.d/redirect.conf:

    http:// {
        redir https://{hostport}{uri} 301
    }


You may also need this to avoid conflicts:


/usr/local/etc/caddy/caddy.d/redirect.global:

    auto_https disable_redirects


Would be nice to have a switch for this, because the custom files are not part of the saved configuration.

Quote from: Monviech on October 27, 2024, 08:29:56 PM
QuoteSo, if you just want to reverse-proxy some services in your home network, go with Caddy. For an OpnSense guarding your internet site with several services/domains, stay with HAproxy.

-> That is a very sane conclusion and I mostly agree with it. Though the way the layer4/7 proxy and matcher ecosystem evolves makes it pretty powerful in its own way, if not only looking at the reverse proxy.

HAproxy can do layer 4 proxying as well. I use this to translate IPv6 to IPv4 backends all the time, for example to access intranet docker services behind dynamic IPv6 prefixes (as docker is not easy to set up with IPv6, even less so with dynamic IPs).
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 28, 2024, 07:39:25 AM
I have asked a caddy maintainer about the redirect and since there is no global setting that changes the way "Auto HTTPS" creates them, I will not offer it.

It would also conflict with current features like the http01 challenge redirection that create a http domain when enabled.

https://github.com/opnsense/plugins/blob/5c4e3a231f6a46cef9d9ae9dc87d92b12ad97fb9/www/caddy/src/opnsense/service/templates/OPNsense/Caddy/Caddyfile#L280

Also it would need deduplication if multiple domains with the same hostname and different ports are created.

It would sadly get a little messy and convoluted in my opinion.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: yarcod on October 28, 2024, 11:42:00 PM
Quote from: Monviech on October 27, 2024, 06:56:52 PM
Auto HTTPS is off thats why there is no port 80.

Change the setting in general settings.

It needs to be on for the automatic http to https redirect even if you dont use lets encrypt.

Ah, thanks! That explains the lack of port 80! And indeed, checking that box immediately redirected http to https. However, perhaps the help text for this option should be slightly updated? It currently states:
QuoteSelect the Auto HTTPS option. "On (default)" creates automatic certificates using "Let's Encrypt" or "ZeroSSL". "Off" turns all automatic certificate requests off.
Something mentioning the redirect could be added?

Regardless, I am still running into the issue I had when prodding https before:

# curl -vL https://127.0.0.1:443
*   Trying 127.0.0.1:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS alert, internal error (592):
* OpenSSL/3.0.15: error:0A000438:SSL routines::tlsv1 alert internal error
* closing connection #0
curl: (35) OpenSSL/3.0.15: error:0A000438:SSL routines::tlsv1 alert internal error


The Let's encrypt TLS cert is setup inside OPNsense (this guide is probably the closest to what I have: https://sysadmin102.com/2023/05/create-lets-encrypt-wildcard-certificates-on-opnsense-with-acme-client/) in order to re-use the certificate elsewhere in the network. However, despite the plugin being setup to use this certificate it does not seem able to serve it:


<15>1 2024-10-28T23:20:18+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="11"] "debug","ts":"2024-10-28T22:20:18Z","logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"90.229.225.174","remote_port":"31331","server_name":"edholm.cc","remote":"90.229.225.174:31331","identifier":"edholm.cc","cipher_suites":[4866,4867,4865,49196,49200,159,52393,52392,52394,49195,49199,158,49188,49192,107,49187,49191,103,49162,49172,57,49161,49171,51,157,156,61,60,53,47,255],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
<11>1 2024-10-28T23:20:18+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="12"] "debug","ts":"2024-10-28T22:20:18Z","logger":"http.stdlib","msg":"http: TLS handshake error from 90.229.225.174:31331: no certificate available for 'edholm.cc'"}
<15>1 2024-10-28T23:27:38+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="1"] "debug","ts":"2024-10-28T22:27:38Z","logger":"events","msg":"event","name":"tls_get_certificate","id":"c99f387a-0cb1-4de9-af74-f764659607dd","origin":"tls","data":{"client_hello":{"CipherSuites":[52393,52392,49195,49199,49196,49200,49161,49171,49162,49172,156,157,47,53,49170,10,4867,4865,4866],"ServerName":"","SupportedCurves":[29,23,24,25],"SupportedPoints":"AA==","SignatureSchemes":[2052,1027,2055,2053,2054,1025,1281,1537,1283,1539,513,515],"SupportedProtos":null,"SupportedVersions":[772,771,770,769],"RemoteAddr":{"IP":"45.79.163.72","Port":65403,"Zone":""},"LocalAddr":{"IP":"192.168.1.1","Port":443,"Zone":""}}}}
<15>1 2024-10-28T23:27:38+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="2"] "debug","ts":"2024-10-28T22:27:38Z","logger":"tls.handshake","msg":"no matching certificates and no custom selection logic","identifier":"192.168.1.1"}
<15>1 2024-10-28T23:27:38+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="3"] "debug","ts":"2024-10-28T22:27:38Z","logger":"tls.handshake","msg":"no certificate matching TLS ClientHello","remote_ip":"45.79.163.72","remote_port":"65403","server_name":"","remote":"45.79.163.72:65403","identifier":"192.168.1.1","cipher_suites":[52393,52392,49195,49199,49196,49200,49161,49171,49162,49172,156,157,47,53,49170,10,4867,4865,4866],"cert_cache_fill":0.0001,"load_or_obtain_if_necessary":true,"on_demand":false}
<11>1 2024-10-28T23:27:38+01:00 OPNsense.edholm.cc caddy - - [meta sequenceId="4"] "debug","ts":"2024-10-28T22:27:38Z","logger":"http.stdlib","msg":"http: TLS handshake error from 45.79.163.72:65403: no certificate available for '192.168.1.1'"}


Does the logs above tell you anything? I don't get why it would not find a matching certificate, because the one I have is setup for "*.edholm.cc". What could I be missing for that not to work?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: yarcod on October 28, 2024, 11:55:25 PM
Another question for that matter, would it possible to add an option to include files under "caddy.d" inside a domain matcher? In my case it would create a Caddyfile like this:

*.edholm.cc {
  # Options
  import /usr/local/etc/caddy/caddy.d/*.conf
  # Or perhaps lookup files with the configured domain as a prefix, like *.edholm.cc.conf
}

Mainly this is to make external automations able to add individual handlers as separate files for an existing domain. Benefit is that the plugin keeps track of the TLS cert and some other FW configured things, and, in my case, Ansible could still add configurations without requiring opening the webui manually. This should not break any existing plugin functionality, I think, except if you add files which handles the same subdomains as the plugin is set up to handle already.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on October 29, 2024, 06:24:41 AM
Your *.edholm.cc certificate probably doesn't have a SAN for exactly edholm.cc.

Its only valid for subdomains under edholm.cc but not for the domain exactly.

Im not sure why it doesnt work for your setup though, it looks correct in the caddyfile if the cert is really for *.example.com. All manual wildcards I have used before, and also ones generated by Caddy itself always worked. If you have s supported DNS Provider just let caddy handle the wildcard domain generation.

------

If you want to change options remotely, use the REST API the plugin provides. Most modern OPNsense plugins and core features have this API.

e.g., in a browser call /api/caddy/reverse_proxy/get

https://docs.opnsense.org/development/api.html

Main advantage, everything you do will be validated and serialized into the /conf/config.xml so OPNsense backups contain it.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 03, 2024, 10:07:15 PM
I'm working on getting Caddy set up on my OPNSense box, and running into some issues that are probably stupid user error from someone who's brand new to the featureset of OPNSense. Hoping someone can help.

My situation: I got Caddy set up with cloudflare pointing to my domain. Was able to obtain a wildcart cert from cloudflare. Set up my subdomains for Plex, Sonarr, HomeAssistant, and router GUI.

I'm getting 502 errors on all of them from the WAN, but can access Plex from the local network (the rest give 502). I can't play anything on Plex, but can see and interact with my dashboard.

As far as my setup goes, here's what I have:

Cloudflare DNS records:

ha.example.us. 1 IN A <my WAN IP>
plex.example.us. 1 IN A <my WAN IP>
*.example.us. 1 IN A <my WAN IP>
example.us. 1 IN A <my WAN IP>
router.example.us. 1 IN A <my WAN IP>
sonarr.example.us. 1 IN A <my WAN IP>


I set up the firewall rules as directed in the tutorial, with HTTP and HTTPS rules on both LAN and WAN.

Domain:
Protocol: https://
domain: *.example.us
Cert: ACME
DNS-01 Challenge: checked
Dynamic DNS: unchecked


Subdomains:
Domain: *.example.us
Subdomain: plex.example.us
Dynamic DNS: checked


Other services are set up the same.

HTTP Handlers:
Domain: *.example.us
Subdomain: plex.example.us
directive: reverse_proxy
Protocol: Https://
Upstream Domain: plex server's local IP
Upstream Port: 32400
TLS Insecure Skip Verify: checked


Other services are set up the same, but with correct subdomain, local IP, and port.


Here's a my caddyfile:
# DO NOT EDIT THIS FILE -- OPNsense auto-generated file


# caddy_user=root

# Global Options
{
log {
output net unixgram//var/run/caddy/log.sock {
}
format json {
time_format rfc3339
}
}

servers {
protocols h1 h2 h3
}

dynamic_dns {
provider cloudflare <my token>
domains {
example.us plex
example.us router
example.us sonarr
example.us ha
}
}

email myemail@gmail.com
grace_period 10s
import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


# Reverse Proxy Domain: "14b010dd-6f6d-4ba8-94df-898d341059b8"
*.example.us {
tls {
issuer acme {
dns cloudflare <my token>
}
}

@85082da4-6d7a-410d-9955-d9c114e40692 {
host plex.example.us
}
handle @85082da4-6d7a-410d-9955-d9c114e40692 {
handle {
reverse_proxy 192.168.1.137:32400 {
transport http {
tls
tls_insecure_skip_verify
}
}
}
}
@fc7226be-505c-4b24-b95b-e01cb5e11a32 {
host router.example.us
}
handle @fc7226be-505c-4b24-b95b-e01cb5e11a32 {
handle {
reverse_proxy 192.168.1.1:8443 {
}
}
}
@e857ccbe-2f6a-4d4d-86f5-f8a5ab908e70 {
host sonarr.example.us
}
handle @e857ccbe-2f6a-4d4d-86f5-f8a5ab908e70 {
handle {
reverse_proxy 192.168.1.137:8989 {
transport http {
tls
tls_insecure_skip_verify
}
}
}
}
@fa0581ec-66ca-4526-ae6b-6a059d16f73c {
host ha.example.us
}
handle @fa0581ec-66ca-4526-ae6b-6a059d16f73c {
handle {
reverse_proxy 192.168.1.138:8123 {
}
}
}
}

import /usr/local/etc/caddy/caddy.d/*.conf



Any help here? Do I need to do any setup on my Plex/Sonarr/HA box? Forward ports 443/80? Is unbound DNS tripping me up somehow? Or did I just miss something else?

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on November 03, 2024, 10:32:48 PM
Did you move the OPNsense UI to a different port and disable the HTTP --> HTTPS redirect?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 03, 2024, 11:20:32 PM
Yes I did. Sorry for forgetting to mention that
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 04, 2024, 06:12:19 AM
I think you have to configure "trusted proxies" to a list of cloudflare IPs in General Settings. (if you use it as CDN and not only as DNS provider)

There can also be cloudflare specific settings to be done at cloudflare itself I do not know about. I dont use it sorry. I think Cloudflare can itself be tje reverse proxy entry point for domains configured on it.

Check out what

curl -v example.com

returns from the outside.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Gautier on November 04, 2024, 05:53:41 PM
Quote from: Gautier on October 11, 2024, 09:48:21 AM
Hi,
I install Caddy and configure follow the tutorial but I have error:
"error","ts":"2024-10-11T07:26:56Z","logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"toto.pequod.sokil.fr","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:connection - 89.219.181.98: Timeout during connect (likely firewall problem)"}

I really don't know where to start
I also on freeBSD and debian install caddy to test with the same error.

I have another site with OPNsense and caddy on debian behind without error, I miss something but what ?

Hi,

Just to say I just install opnsense with caddy on another ISP (another country) and it's work like a charm. I ask mu isp to help me but they send a pastry chef so ...

Anyway just to say thank you for your help.

Regards
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 04, 2024, 06:29:33 PM
Hey thanks for checking back in. Yeah ISPs are a big factor, some use CGNAT, some block port 80/443 etc..
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 04, 2024, 06:54:56 PM
Quote from: Monviech on November 04, 2024, 06:12:19 AM
I think you have to configure "trusted proxies" to a list of cloudflare IPs in General Settings. (if you use it as CDN and not only as DNS provider)

There can also be cloudflare specific settings to be done at cloudflare itself I do not know about. I dont use it sorry. I think Cloudflare can itself be tje reverse proxy entry point for domains configured on it.

Check out what

curl -v example.com

returns from the outside.

I'm only using cloudflare for DNS to access my home network. My server is inside the network. As far as cloudflare specific settings, to my knowledge there aren't any. I watched several youtube tutorials on setting up cloudflare as DDNS with OPNSense, but unfortunately, I couldn't find anything tied to your plugin (there's really next to no info I've found outside of this thread and a handful of posts you've replied to on Reddit)


Here's the result of the curl entry...

* Host sonarr.mydomain.us:80 was resolved.
* IPv6: (none)
* IPv4: <mywanip>
*   Trying <mywanip>:80...
* Connected to sonarr.mydomain.us (<mywanip>) port 80
> GET / HTTP/1.1
> Host: sonarr.mydomain.us
> User-Agent: curl/8.9.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://sonarr.mydomain.us/
< Server: Caddy
< Date: Mon, 04 Nov 2024 17:52:26 GMT
< Content-Length: 0
<
* we are done reading and this is set to close, stop send
* shutting down connection #0
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 04, 2024, 06:59:47 PM
Well that looks good. Port 80 is caddy answering. Do the same curl for 443 too.

curl -v example.com:443

Yeah the plugin is still less than a year old so I dont expect any other user tutorials yet. Might take some more time. Thats why I wrote these big docs maybe somebody can PR a cloudflare tutorial sometime.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 04, 2024, 08:38:52 PM
* Host sonarr.mydomain.us:80 was resolved.
* IPv6: (none)
* IPv4: <wanip>
*   Trying <wanip>:80...
* Connected to sonarr.mydomain.us (<wanip>) port 80
> GET / HTTP/1.1
> Host: sonarr.mydomain.us
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://sonarr.mydomain.us/
< Server: Caddy
< Date: Mon, 04 Nov 2024 19:32:57 GMT
< Content-Length: 0
<
* shutting down connection #0


Looks the same as what I got on port 80, other than the "HTTP/1.1 308 Permanent Redirect" line. So if cloudflare is getting through to Caddy, any suggestions as far as what's blocking the request from getting through the firewall?

As for setting up cloudflare, assuming my current issues are on the firewall side, there's nothing special about the setup. You just have to create an A record for your root domain, or using * to get a wildcard cert. I didn't even create the DNS entries for my subdomains, cloudflare did it dynamically.


Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 04, 2024, 08:50:21 PM
I think you have to curl -v https://example.com

So far we have just seen port 80 open but never port 443. If connections time out externally its 443 that could be the issue.

If 443 is indeed open and caddy answers and there are no timeouts then its weird.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 04, 2024, 09:56:16 PM
Apparently my brain isn't turned on yet today. I didn't even notice that both tests were for port 80. Here's 443

curl -v sonarr.example.us:443
* Host sonarr.example.us:443 was resolved.
* IPv6: (none)
* IPv4: <wanip>
*   Trying <wanip>:443...
* Connected to sonarr.example.us (<wanip>) port 443
> GET / HTTP/1.1
> Host: sonarr.example.us:443
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
* HTTP 1.0, assume close after body
< HTTP/1.0 400 Bad Request
<
Client sent an HTTP request to an HTTPS server.
* shutting down connection #0
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 04, 2024, 10:04:01 PM
Yeah well that works too, I would have tested with https://example.com instead of only using example.com:443 but this shows the port is open and theres at least some answer. It is not clear what answers though.

Just try to fiddle a bit around and see what responds. Im unable to do this step by step here in this thread. Also check out the tutorial section here that explains what should happen if things work.

Your Caddyfile looks totally fine so it has to be some networking issue.

https://docs.opnsense.org/manual/how-tos/caddy.html#help-nothing-works
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: jrob801 on November 04, 2024, 10:28:52 PM
I ran the curl command a few more ways and got some results that seem mildly interesting. Figured I'd repost them in case they're telling to you...

C:\Users\me>curl -v mydomain.us
* Host mydomain.us:80 was resolved.
* IPv6: (none)
* IPv4: <wanIP>
*   Trying <wanIP>:80...
* Connected to mydomain.us (<wanIP>) port 80
> GET / HTTP/1.1
> Host: mydomain.us
> User-Agent: curl/8.9.1
> Accept: */*
>
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://mydomain.us/
< Server: Caddy
< Date: Mon, 04 Nov 2024 21:16:01 GMT
< Content-Length: 0
<
* we are done reading and this is set to close, stop send
* shutting down connection #0




C:\Users\me>curl -v https://mydomain.us
* Host mydomain.us:443 was resolved.
* IPv6: (none)
* IPv4: <wanIP>
*   Trying <wanIP>:443...
* Connected to mydomain.us (<wanIP>) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.
* closing connection #0
curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.



C:\Users\me>curl -v https://www.mydomain.us
* Host www.mydomain.us:443 was resolved.
* IPv6: (none)
* IPv4: <wanIP>
*   Trying <wanIP>:443...
* Connected to www.mydomain.us (<wanIP>) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
* using HTTP/1.x
> GET / HTTP/1.1
> Host: www.mydomain.us
> User-Agent: curl/8.9.1
> Accept: */*
>
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
< HTTP/1.1 200 OK
< Alt-Svc: h3=":443"; ma=2592000
< Server: Caddy
< Date: Mon, 04 Nov 2024 21:19:35 GMT
< Content-Length: 0
<
* Connection #0 to host www.mydomain.us left intact


So it looks like a request to the bare domain responds over http/port 80, a bare request trying to force https results in a TLS handshake error, but a https request to www works.  That's particularly interesting to me since I didn't set up a www entry in my DNS record.

Is there anything noteworthy you're seeing from those results?

I'm running through the troubleshooting steps and reviewing firewall rules etc to see if I can find something on the firewall end that's stopping the request from passing through to the client...
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 05, 2024, 06:20:44 AM
It really doesnt tell me mich, Ive never seen errors like these before.

Maybe Caddy Debug logs of the failed requests or HTTP access logs can show whats happening. Right now Im just as much in the dark as you though, sorry.

It looks like a weirder problem, maybe https://caddy.community can help better.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: spocko on November 06, 2024, 10:03:12 AM
I am a noob and try to play arround with caddy in opnsense'

i have a question regarding certificates that are showing up in the lobby dashboard but not needed anymore. Is there a way to delete those certificates?

thanks in advance
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 06, 2024, 10:35:11 AM
Hello, these certificates should be eventually cleaned up by caddy's storage cleanup routine. But that can take till past expiry or longer.

You can delete them manually in the filesystem.

/var/db/caddy/data/caddy/certificates/


Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: vorago on November 18, 2024, 02:42:31 PM
Hello, caddy doesn't seem to like the firewall live log view. Auto-refresh will not stay enabled. I don't have this problem when viewing logs via direct IP.

Caddy logs show this "context canceled" error when it happens:
"debug","ts":"2024-11-18T13:32:10Z","logger":"http.handlers.reverse_proxy","msg":"upstream roundtrip","upstream":"192.168.5.1:444","duration":0.001754159,"request":{"remote_ip":"192.168.5.4","remote_port":"59054","client_ip":"192.168.5.4","proto":"HTTP/2.0","method":"GET","host":"opn.example.com","uri":"/api/diagnostics/firewall/log/?digest=91a55b1d9ceb232a54b94da9ad86d84e&limit=1000","headers":{"Accept":["application/json, text/javascript, */*; q=0.01"],"Sec-Gpc":["1"],"Sec-Fetch-Mode":["cors"],"Accept-Language":["en-US,en;q=0.5"],"X-Csrftoken":["EzCqIYHuVYedZX-dW038qA"],"Sec-Fetch-Dest":["empty"],"Cookie":["REDACTED"],"X-Forwarded-For":["192.168.5.4"],"Referer":["https://opn.example.com/ui/diagnostics/firewall/log"],"Sec-Fetch-Site":["same-origin"],"Te":["trailers"],"Dnt":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0"],"X-Requested-With":["XMLHttpRequest"],"Content-Type":["application/json"],"X-Forwarded-Proto":["https"],"X-Forwarded-Host":["opn.example.com"],"Accept-Encoding":["gzip, deflate, br, zstd"]},"tls":{"resumed":true,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"opn.example.com"}},"error":"context canceled"}

What could be the problem?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 18, 2024, 03:12:59 PM
Hello, I just tested the firewall live log with both the layer 4 proxy and the reverse proxy and auto refresh always worked for me.

My WebGUI runs on HTTPS and 4444.

Here is my Caddyfile section:


vpn1.example.com {
handle {
reverse_proxy 127.0.0.1:4444 {
transport http {
tls
tls_insecure_skip_verify
}
}
}
}
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: vorago on November 18, 2024, 03:32:12 PM
I wonder what I'm doing wrong then. My section looks similar to yours, with the addition of the certificate, I just have the WebUI bound to a specific interface:

handle {
reverse_proxy 192.168.5.1:444 {
transport http {
tls
tls_trust_pool file /var/db/caddy/data/caddy/certificates/temp/670931cbb863a.pem
tls_server_name OPNsense.localdomain
}
}
}
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 18, 2024, 04:26:08 PM
Can you try if the same issue happens with the layer4 proxy?

It's really easy, just add this to "Layer4 Proxy". You do not even have to disable your Reverse Proxy for the OPNsense Webgui configuration since Layer 4 will match first:

Services: Caddy Web Server: Layer4 Proxy
Edit Layer4 Route
Description: OPNsense WebGUI
Matchers: TLS (SNI Client Hello)
Domain: opnsense.example.com (Your opnsense domain name)
Upstream Domain: 127.0.0.1 (Or your IP address if the WebGUI does not listen on ALL interfaces)
Upstream Port: 444

Save, Apply.

Reopen the WebGUI and it should serve the self signed certificate through Caddy instead of the Lets Encrypt one. Test if the LiveLog still doesn't work.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: vorago on November 18, 2024, 04:54:03 PM
Live logs work with that method. So is the issue somehow with the LE cert? I'd much prefer to use my LE cert for this.

Edit: it seems to be a browser issue. Live logs work fine with my original set up in Brave, but not librewolf. Strange.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: vorago on November 18, 2024, 05:09:29 PM
It's the combination of the ResistFingerprinting setting and Caddy with LE certs that seems to be the problem, for me at least.

Never mind, was looking via direct IP and didn't notice.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on November 18, 2024, 06:00:32 PM
Oh okay so things work now with a different browser? I tested with Blink based one, Chrome on Mac.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: vorago on November 18, 2024, 06:03:44 PM
They do. I tried in normal Firefox and it also works fine there. So I'm guessing it's some hardening setting in Librewolf. Thanks for helping me narrow this down! I'll keep digging into the settings of LW.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: pacman on December 01, 2024, 12:35:44 PM
I need some help with this great plugin. I want to use Caddy, as reverse proxy. I have in my local network, a immich-server running.

If I make the configuration with only http:// everthing works perfect. But i want to use it with https://.

I always get this error in the browser.

Fehlercode: SSL_ERROR_INTERNAL_ERROR_ALERT
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on December 01, 2024, 12:49:11 PM
Where do you want to use https?

Domain (Frontend) or HTTP Handler (Upstream to Backend)?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: spocko on December 02, 2024, 08:02:17 AM
Hi all I need some help with the following:

I configured caddy with subdomains and using cloudflare api.
The problem is i get a lots of errors in my log ( see example and no its not my real ip)

"debug","ts":"2024-12-02T03:28:36Z","logger":"http.stdlib","msg":"http: TLS handshake error from 34.38.48.249:37638: no certificate available for '22.200.100.002'"}

Can someone point me in the rightdirection to block this?

Thank in advance
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on December 02, 2024, 08:13:44 AM
Any request that hits caddy on its ports will trigger an evaluation if it should be further processed or not. So these are not warning or errors, but a debug message that the frontend received a connection request that could not be mapped to any configured hostname (thus no available certificate).

If you think its an attack block the requesting IP via Crowdsec or Firewall rules.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: pacman on December 02, 2024, 11:34:41 AM
Quote from: Monviech (Cedrik) on December 01, 2024, 12:49:11 PM
Where do you want to use https?

Domain (Frontend) or HTTP Handler (Upstream to Backend)?

Domain (Fronted), the backend has only http.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on December 02, 2024, 12:34:07 PM
Have you checked the Caddy Certificate widget (dashboard) if there is a certificate when you enable https for the frontend? If not check the caddy logs why it fails to issue one.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: stefan21 on December 03, 2024, 07:07:38 PM
Actually I tried to split port 443 in HAProxy. I couldn't find a working solution for my setup. While struggling around Cedrik gave me the hint to try Caddy. The idea behind HAProxy was to restrict access to the LAN and to present all certs to any clients or applications in the LAN. Connections from outside are only allowed through VPN. In this setup there's only a minimum of ports at the WAN interface open.

The main reason for port-sharing is that more and more wifi's in hotels or airports have only two ports open. As long as there's no deep packet inspection, one could use port 443 for openvpn. In other enviroments wireguard maybe a good choice.

Here are the steps sharing the port 443 between openvpn and a web application running on https, which are working for me. As pre-requisites there are (up-to-date)

OPNsense 24.7.9_1-amd64
FreeBSD 14.1-RELEASE-p6
OpenSSL 3.0.15

- all DNS records setup at the ISP/DNS registrar
- all (let's encrypt) certificates are stored at the correct local places and up-to-date
- there's a user created for openvpn
- local certificates have been created for the vpn-server and the vpn-client (user)
- there's a VPN instance up and running bound to 127.0.0.1 on port 1194

a) in Caddy - general settings - enable caddy and layer4 proxy. Advanced, Log, DNS, etc. are left on default.
b) in reverse proxy - http access - create your acl. I allow access only to LAN and VPN. HTTP response code for me is 403, the message is "HTTP 403 - Forbidden"
c) in reverse proxy - Domains - create your web-application on port 443 (https). Don't forget the corresponding certificate and the access list to this application.
d) in reverse proxy - http handlers - create the web-application which belongs to step c). Handler is "handle", leave path to "any", directive is "reverse_proxy", leave http version on default, protocol is "https", define your upstream domain/IP on the upstream port 443. Leave upstream path empty. Change the TLS server name that matches the SAN "Subject Alternative Name" of the offered upstream certificate.
e) in layer4 proxy - leave/change routing type "listener_wrappers", protocol is TCP, local port leave empty, matchers is "openvpn", mode and key is "any", upstream domain is "127.0.0.1", upstream port is 1194. Leave the rest empty/on default.

Connect your roadwarrior through port 443 to the openvpn instance. I used for client export "file only".

That's it. Working at least for me. If there are questions with this setup, I'll try to help. I had to start over for a second try. The first approach didn't work as expected. While re-installing (I removed every leftover from caddy via cli) it worked in the way I described. This time I was better prepared and didn't change or alter any setting while configuring caddy. Be sure to have all pre-requisites working as they should. Then start configuring caddy.

I can't push the DNS through the linux client (not working with WIN-clients), access to the LAN apps works only with IP's. Or connecting via vnc to a machine in the LAN. I can live with that. Or maybe someone is able to rule this out.

regards,
stefan

P.S. thank's to cedrik - all credits to him
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: caplam on December 18, 2024, 10:03:53 AM
Hello,

I'm quite new to OPNsense. I installed it on N100 box. It replaces an unifi udr.
So far I managed to replace udr successfully even for Wireguard server and a site2site openvpn. The worst part had been to transfer unifi settings from udr to network controller as it's unsupported by unifi.
And I'm very happy with that. My connection is much more stable and consistent. I let you guess when the replacement occurred on the screenshot

Now I'd like to replace my nginx proxy manager (hosted on an Unraid docker container) with caddy on opnsense.
Does caddy support reverse proxying hosts using web sockets like home assistant, jeedom or Plex ?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on December 18, 2024, 10:09:00 AM
Yes, definitely.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: caplam on December 18, 2024, 11:06:50 AM
Thanks. I'll try that.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: caplam on December 18, 2024, 12:27:49 PM
I see that acme plugin is not necessary. I already setup acme plugin for issuing a certificate for opnsense webgui. It's not publicly available so I guess it's normal to not have record in my dns zone (domain is registered at ovh and so is the zone)
Can it live along with caddy plugin ?

if I use caddy with dns challenge and all keys correctly filled in does it take care of issuing certificates as well as creating cname records ?
Can I delete cname records already made for nginx prox manager ?
i have a domain and use subdomains for publishing apps like home assistant.

Ovh dynamic dns client doesn't handle ipv6 is there a way to make apps available also in ipv6?


edit: quick followup
it's setup. Certificates are issued and the widget on dashboard is very convenient.
I hadn't payed attention to dyndns but in my case not very useful for caddy. I use it for my domain ip and all my published apps are subdomains so setting up a cname record in my provider webui is more convenient than adding a dyndns for each subdomain.
For the moment I can't use ipv6. I suppose if I want to I would have to transfer the zone to Cloudflare.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: this.is.tom on December 28, 2024, 05:23:07 PM
Hi everyone,

I just setup caddy and it works totally fine - for one domains.

The second domain always fails on the external interface.

I have two domains:
image.example1[.]com
image.example2[.]com

Both point to the same reverse proxy (caddy).

image.example1[.]com - works totally fine. EDIT: Doesnt work anymore. Only when this DNS resolves to internal interface of FW
image.example2[.]com - results in a server connect error.

If I test it from my internal network, setting up a local DNS resolver pointing image.example2[.]com to the internal interface of my FW, it works totally fine.

So the firewall accepts the requests for this hostname / domain. Internally it works. Externally it fails.

Duplicating the caddy configuration from example2 domain to example1 (which works with with multiple sites) it works totally fine.

There must be something wrong with the domain. But I have no idea why. I verified it multiple times in my local DNS, my public DNS etc.

Any input is highly appreciated! I am totally lost on this one.

Tom

EDIT: Now the same hostname on both different domains doesnt work externally.

having DNS for image.example1[.]com and image.example2[.]com pointing to internal interface of FW - All good!

having DNS for image.example1[.]com and image.example2[.]com pointing to external interface of FW - Cant connect to server!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: this.is.tom on December 28, 2024, 06:16:30 PM
This is the config.
# DO NOT EDIT THIS FILE -- OPNsense auto-generated file


# caddy_user=root

# Global Options
{
   log {
      output net unixgram//var/run/caddy/log.sock {
      }
      format json {
         time_format rfc3339
      }
   }

   servers {
      protocols h1 h2 h3
   }

   email security@example-1.com
   auto_https off
   grace_period 10s
   import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


# Reverse Proxy Domain: "79179cc0-6ab4-4a49-9d79-5d58cf46062a"
drive.example-1.com {
   tls /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.pem /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.key

   handle {
      reverse_proxy 192.168.1.110:10003 {
         transport http {
            tls
            tls_insecure_skip_verify
         }
      }
   }
}
# Reverse Proxy Domain: "cfb6ccd1-1006-453b-92f6-1d449b125935"
data.example-1.com {
   tls /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.pem /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.key

   handle {
      reverse_proxy 192.168.1.110:5001 {
         transport http {
            tls
            tls_insecure_skip_verify
         }
      }
   }
}
# Reverse Proxy Domain: "03f9ea48-f45d-4609-9df8-01bdba6806ed"
file.example-1.com {
   tls /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.pem /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.key

   handle {
      reverse_proxy 192.168.1.110:7001 {
         transport http {
            tls
            tls_insecure_skip_verify
         }
      }
   }
}
# Reverse Proxy Domain: "0a5d6560-cd3b-44a3-8d34-fd86f6e7b37e"
photos.example-1.com {
   tls /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.pem /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.key

   handle {
      reverse_proxy 192.168.1.110:5003 {
         transport http {
            tls
            tls_insecure_skip_verify
         }
      }
   }
}
# Reverse Proxy Domain: "a76af138-0c5c-453d-80d0-e21bd176672a"
photos.example-2.my {
   tls /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.pem /var/db/caddy/data/caddy/certificates/temp/65d767a6b7244.key

   handle {
      reverse_proxy 192.168.1.110:5003 {
         transport http {
            tls
            tls_insecure_skip_verify
         }
      }
   }
}

import /usr/local/etc/caddy/caddy.d/*.conf
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on December 28, 2024, 10:52:18 PM
If they all use the same wildcard certificate you must use one wildcard domain with the certificate and the rest subdomains.

https://docs.opnsense.org/manual/how-tos/caddy.html#wildcard-domain-with-subdomains

In your case ignore DNS Provider and DNS challenge in that document.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MrManor on December 29, 2024, 12:00:25 PM
Please ignore the below: I removed all configuration and recreated from scratch - now both certificates is present

Hi, I am new to this plugin but succeeded to setup a test domain yesterday. After testing I disabled the http and https fw port rules. Today I wanted to add a subdomain but forgot to enable access to the web ports. After reopening I have tried to restart caddy, delete and recreate several subdomains but no joy. I seems that the the certificate is still from yesterday and has no subdomains.

Is there anyway to trigger a new attempt?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: MrManor on December 29, 2024, 02:03:27 PM
I currently use a DNS provider that is not supported by your plug-in (I'm not sure if my provider have any API support at all), so I guess that it not possible to use DNS Challenge?

Up to now (using certbot) I have just added all my subdomains to Subject Alt names on the main domain. Is it possible to use this plugin with Subject Alt names, or do I have to create a "Domain" for every sub domain and ignore the subdomain section in the user interface?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Schnuffel2008 on December 29, 2024, 10:01:56 PM
Hi,
I am fairly new to this topic and I only need caddy as a reverse proxy. My Dyn-DNS Provider (ipv64.net) is not listed in the app and so I really don't know what to do. I've tried the acme-plugin and I was able to get a proper wildcard certificate for my website with the dns challenge.
I can choose this certificate under certificate in the reverse proxy tab. But on the dashborad there is a message that there is no certificate handled by caddy. So is this okay?
I think it would be better to get rid of the acme-plugin and manged everything with the caddy plugin, but how can I configure this?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: spocko on January 01, 2025, 09:51:01 PM
hi all,

Can somebody help me with the following. I want to understand if its possible within caddy to restrict/block a certain url like e.g. abc.def.com/xyz and leave abc.def.com accassible. what would be the best way to config this.

thanks in advance
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 01, 2025, 10:18:28 PM
This here explains it. Enable advanced mode in a handler to see all options like "path"

https://docs.opnsense.org/manual/how-tos/caddy.html#multiple-http-handlers-for-the-same-domain
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on January 07, 2025, 12:08:48 AM
@Cedrik, First off, thank you so very much for creating this (and other) wonder plugins for OPNsense. You make our lives so convenient.

I've read through plugin configuration documentation (https://docs.opnsense.org/manual/how-tos/caddy.html) and through this thread. But, an answer didn't jump out. So, I hope you could excuse me for bothering you with a little issue of mine. TLDR: If os-caddy plugin acts as an ACME server for a site, then a) what would be the ACME url? b) will the location of root ca be /var/db/caddy/data/caddy/certificates/local/<site>?

Presently, I use caddy cascaded (https://caddy.community/t/use-caddy-for-local-https-tls-between-front-end-reverse-proxy-and-lan-hosts/11650) in my internal network with a made-up domain name TLS'ed by Caddy. I did so prior to having an externally valid domain name - which I now do. Previously working caddy setup at a high-level was:

Caddy master instance (say on internal1.domain)
 {
   acme_server
   tls_internal
  }

Caddy slaves instances (say on internal2.domain)
 https://internal2.domain{
   tls {
     ca https://<internal1.domain>/acme/local/directory
     ca_root <path_to_caddy_master_ca>.pem
   }
  }

Caddy slaves instances (say on internal3.domain)
 https://internal3.domain{
   tls {
     ca https://<internal1.domain>/acme/local/directory
     ca_root <path_to_caddy_master_ca>.pem
   }
  }
... and so on


Now, with os-caddy on Opnsense being available, I'd like to rid of Caddy master on <instance1.domain> and utilize Opnsense caddy plug-in instead. GUI doesn't provide an option to declare acme_server, tls_internal. But inclusion of *.conf on a per-site basis is allowed. So, I added it like so: (reverse proxied external domain to internal2.domain running caddy slave1)

# Reverse Proxy Domain: "104d6421-2b1f-407e-af83-f087021ee1b1"
valid.domain {
log {
output file /var/log/caddy/access/104d6421-2b1f-407e-af83-f087021ee1b1.log {
roll_keep_for 10d
}
}
acme_server
tls internal


@08831d42-ad4c-40dc-a7d5-53af52ac6490_validdomain {
not client_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
}
handle @08831d42-ad4c-40dc-a7d5-53af52ac6490_validdomain {
abort
}

handle {
reverse_proxy internal2.domain {
                     transport http {
tls_insecure_skip_verify
}
     header_up Host {http.reverse_proxy.upstream.hostport}
  }
}
}

Then Caddy slaves instances's (internal2.domain) config is changed as:
https://internal2.domain{
   tls {
     ca https://<external.domain>/acme/local/directory
     ca_root <path_to_caddy_master_ca copied from /var/db/caddy/data/caddy/certificates/local/internal1.domain>.crt
   }
  }


Unbound resolves external.domain to Opsense's address (192.168.0.1) via host overrides. This is to prevent local request for external domain being handled and served locally without having to go out into the interwebs.

Because Opnsense webGUI is running on 8443, I also tried https://<192.168.0.1>:8443/acme/local/directory but to no avail. ACME server's url appears invalid. I'm unsure how to proceed. Your guidance would be much appreciated.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 07, 2025, 07:20:58 AM
You could use the HTTP01 challenge redirection on the Caddy Server of OPNsense to the cascaded other Caddy Servers. All Caddy Servers listen per default on 80/443 so nothing speciaö needs to be configured. Its what I do.

No need for ACME Server directive.

https://docs.opnsense.org/manual/how-tos/caddy.html#redirect-acme-http-01-challenge

In each domain the IP for the Challenge redirection wouöd be the backend Caddy responsible for it.

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on January 07, 2025, 04:20:28 PM
Quote from: Monviech (Cedrik) on January 07, 2025, 07:20:58 AMYou could use the HTTP01 challenge redirection on the Caddy Server of OPNsense to the cascaded other Caddy Servers.

I see. I was under the impression that the challenges on cascades servers would work because they get their certs (and therefore a hierarchy) from cascade master. Meaning, Caddy opnsense has, for a given external site, a valid cert. If acme challenge is sent to an internal (hosting an internal site) caddy instance, then the request would not have the same valid verification chain on client-side? Please grant me follow-ups in case I get stuck.


An other unrelated questions for your guidance:
GitHub code for this plugin indicates a custom caddy build (with DNS providers, L4 etc) is being used (120 standard modules, 80 or so optional modules). Would there be steps on how to add modules of interest eg crowdsec? I have used xcaddy in the past to generate custom images on Linux but not on freebsd. I can update this post with a working caddy config where crowdsec together with rate L5-7 rate limiters can take L4-7 information (not just L3 - which is what I think present crowdsec integration provides) to block unwanted behaviors.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 07, 2025, 05:52:10 PM
If Caddy(Main) and Caddy(Sub) are in a trusted network, you can reverse_proxy between these Caddies without using TLS.

TLS is only important on the way through untrusted networks, e.g. from Client on the Internet to your Caddy(Main).

Caddy(Main) will hold all certificates and terminate tls. The other Caddies would not need to issue any certificates.

So you do not really need an ACME Server or a ACME Challenge redirection. Just use Plaintext.

Regarding the build:

https://caddyserver.com/docs/command-line#caddy-add-package

You can use this to add any package you want from the command line. It will not be persistent though. If the opnsense repo pushes an update at some point you must do it again.

Currently the plugin is rather finished and very specific or overly complicated things will most likely not be added to prevent feature creep.




Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on January 08, 2025, 02:55:50 AM
Quote from: Monviech (Cedrik) on January 07, 2025, 05:52:10 PMIf Caddy(Main) and Caddy(Sub) are in a trusted network, you can reverse_proxy between these Caddies without using TLS.

TLS is only important on the way through untrusted networks, e.g. from Client on the Internet to your Caddy(Main).

Caddy(Main) will hold all certificates and terminate tls. The other Caddies would not need to issue any certificates.

So you do not really need an ACME Server or a ACME Challenge redirection. Just use Plaintext.
I understand. Perhaps a better qualification of one of my use-case is in order.

Reference telegraf (https://github.com/influxdata/telegraf/blob/master/plugins/outputs/influxdb_v2/README.md) client information required:
  ## Optional TLS Config for use on HTTP connections.
  # tls_ca = "/etc/telegraf/ca.pem"
  # tls_cert = "/etc/telegraf/cert.pem"
  # tls_key = "/etc/telegraf/key.pem"
  ## Use TLS but skip chain & host verification
  # insecure_skip_verify = false

Similar information is required for influx and Grafana.

Quote from: Monviech (Cedrik) on January 07, 2025, 05:52:10 PMRegarding the build:

https://caddyserver.com/docs/command-line#caddy-add-package

You can use this to add any package you want from the command line. It will not be persistent though. If the opnsense repo pushes an update at some point you must do it again.
Thank you for the reference. I understand.

The crowdsec usage I referred to earlier is as follows:

--> Global block of Caddyfile (info generated using cscli bouncer add
{
crowdsec {
api_url http://<Opnsense_fw>:8080
api_key <valid_key>
ticker_interval 15s
}
}

--> In the site-block of clients
{
route {
# crowdsec based filtering
crowdsec
                ... whatever logic is necessary ...
        }

}


Quote from: Monviech (Cedrik) on January 07, 2025, 05:52:10 PMCurrently the plugin is rather finished and very specific or overly complicated things will most likely not be added to prevent feature creep.
Thank you for sharing the plugin status and roadmap. I only asked about crowdsec (https://caddyserver.com/docs/modules/crowdsec) modules (which can be used like above) because a log-based integration of crowdsec is already implemented on your plugin for Opnsense. Addition of the few extra parameters required may increase the hardening posture.[/list]
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on January 12, 2025, 07:25:42 AM
Hi,

I'm currently using the Nginx Proxy Manager and I'm trying to switch to the Caddy plug-in.

Originally I was getting errors with Let's Encrypt and fixed that issue but I'm still unable to access anything behind the reverse proxy.  All I'm seeing in the logs is this:

"info","ts":"2025-01-12T06:13:00Z","logger":"http.log.access","msg":"handled request","request":{"remote_ip":"127.0.0.1","remote_port":"12807","client_ip":"127.0.0.1","proto":"HTTP/1.1","method":"GET","host":"localhost","uri":"/scrape.php?v=6&url=https://www.spamhaus.org/drop/asndrop.json","headers":{"User-Agent":["python-requests/2.32.3"],"Accept-Encoding":["gzip, deflate"],"Accept":["*/*"],"Connection":["keep-alive"]}},"bytes_read":0,"user_id":"","duration":0.000013514,"size":0,"status":308,"resp_headers":{"Server":["Caddy"],"Connection":["close"],"Location":["https://localhost/scrape.php?v=6&url=https://www.spamhaus.org/drop/asndrop.json"],"Content-Type":[]}}

I'm not exactly sure what the problem is.  All suggestions are welcome.

Thank you!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 12, 2025, 07:37:44 AM
That looks like a configuration issue. localhost tries to reach spamhaus on lovalhost? Really weird. Without Caddyfile I dont know whats going on.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on January 12, 2025, 09:41:53 PM
Here's my caddy file.  I've removed the personal info.  I hope this helps.

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


# caddy_user=root

# Global Options
{
   log {
      output net unixgram//var/run/caddy/log.sock {
      }
      format json {
         time_format rfc3339
      }
   }

   servers {
      protocols h1 h2 h3
      log_credentials
   }

   dynamic_dns {
      provider duckdns xxx-xxxxx-xxxx
      domains {
         mysite.duckdns.org *
         mysite.duckdns.org ab
      }
      versions ipv4
      update_only
   }

   email myemail@domain.com
   grace_period 10s
   import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


# Reverse Proxy Domain: "xxx-xxx-xxxxx"
*.mysite.duckdns.org {
   tls {
      issuer acme {
         dns duckdns {
            api_token xxx-xxx-xxxxx
         }
      }
   }

   @xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {
      host ab.mysite.duckdns.org
   }
   handle @xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {
      handle {
         reverse_proxy 192.168.x.xxx {
         }
      }
   }
}

import /usr/local/etc/caddy/caddy.d/*.conf
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Patrick M. Hausen on January 12, 2025, 10:08:44 PM
@awshirley please place code inside code tags like so:

This
  is
code
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 12, 2025, 10:23:01 PM
I see nothing wrong with the config at first glance so it remains a mystery that must be solved in the infrastructure it happens.

Maybe check the opnsense docs for the troubleshooting guide for caddy or open a new thread in the caddy community or here in the forum so somebody can pick it up. Its probably an infrastructure issue in some way.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on January 14, 2025, 06:12:11 PM
Thank you for reviewing my caddy file.  You pointed me in the right direction, and infrastructure issue.  I had port forwarding turned on for 40 and 443 to point to NPM.  I turned it off and Caddy now has the ports.

Thanks again!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: smoofus on January 19, 2025, 03:22:12 AM
I'm so stoked for this plugin!  I'm migrating from pfSense and caddy running in docker and I currently rely pretty heavily on the caddy-security, https://github.com/greenpau/caddy-security, plugin. Would you consider adding this module in the caddy build included here?  Not sure if there is a formal request route for this or not so let me know.  I've added the caddy-security module myself w/ the add-package param but I'm guessing it will get nuked with the next update.

Also, I'm doing some snippet imports in the global block due to my use of caddy-security and there is no method to import custom configs before the global block.  I added an 'import /usr/local/etc/caddy/caddy.d/*.snippet' line above the global block in the auto generated "DO NOT EDIT THIS FILE" Caddyfile to work around this but I suspect that will get nuked at some point as well. I'm betting I'm probably no where near best practice here so no sweat if it doesn't make sense but if there are use cases to load custom configs/snippets ahead of the global block it would be cool to have an import line included in the auto generated Caddyfile.

Can't express how grateful I am for this... awesome work!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 19, 2025, 06:29:36 AM
Hey there,

I will not add the caddy security package or make it configurable in the GUI. I suggest you use forward_auth instead with the supported Auth Providers in the plugin.

https://docs.opnsense.org/manual/how-tos/caddy.html#forward-auth

This method is more lightweight and flexible and there are no known issues.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: smoofus on January 31, 2025, 04:31:27 PM
Quote from: Monviech (Cedrik) on January 19, 2025, 06:29:36 AMHey there,

I will not add the caddy security package or make it configurable in the GUI. I suggest you use forward_auth instead with the supported Auth Providers in the plugin.

https://docs.opnsense.org/manual/how-tos/caddy.html#forward-auth

This method is more lightweight and flexible and there are no known issues.


All good, I'm currently using Organizr and the caddy-security plugin for my forward_auth needs so I figured it wouldn't hurt to ask.  I've got Authentik running now and although it's a bit overkill for my homelab needs it does the trick.  Thanks again for making this happen!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on January 31, 2025, 05:15:27 PM
Hey good to know you got it to work with Authentik.

Yeah I just got to be careful with how much to include and caddy-security seems to have some history.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: smoofus on February 03, 2025, 05:09:21 AM
Quote from: Monviech (Cedrik) on January 31, 2025, 05:15:27 PMHey good to know you got it to work with Authentik.

Yeah I just got to be careful with how much to include and caddy-security seems to have some history.

Totally understand!  Admittedly, I was not aware of the caddy-security plugin history.
Quote from: Monviech (Cedrik) on January 31, 2025, 05:15:27 PMHey good to know you got it to work with Authentik.

Yeah I just got to be careful with how much to include and caddy-security seems to have some history.


Admitedly, I was not aware of the history with the caddy-security plugin but dug this up... https://github.com/greenpau/caddy-security/issues/349.  Dropping it here for future reference/context.  Totally get the need to keep the risk profile low w/ the included caddy build. All good!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: schubdog on February 09, 2025, 08:39:16 PM
Quote from: smoofus on January 31, 2025, 04:31:27 PM
Quote from: Monviech (Cedrik) on January 19, 2025, 06:29:36 AMHey there,

I will not add the caddy security package or make it configurable in the GUI. I suggest you use forward_auth instead with the supported Auth Providers in the plugin.

https://docs.opnsense.org/manual/how-tos/caddy.html#forward-auth

This method is more lightweight and flexible and there are no known issues.


All good, I'm currently using Organizr and the caddy-security plugin for my forward_auth needs so I figured it wouldn't hurt to ask.  I've got Authentik running now and although it's a bit overkill for my homelab needs it does the trick.  Thanks again for making this happen!

Hey,

sorry for dropping in, but could you give me more Feedback on how you got Authentik running with Caddy ? I'm struggeling to get it running with setting Authentik as Forward Auth.

br
Schubdog
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: smoofus on February 13, 2025, 05:54:40 AM
Quote from: schubdog on February 09, 2025, 08:39:16 PMHey,

sorry for dropping in, but could you give me more Feedback on how you got Authentik running with Caddy ? I'm struggeling to get it running with setting Authentik as Forward Auth.

br
Schubdog

Happy to help if I can.  Are you having issues with the authentik config or the caddy Auth Provider config?

Caddy Auth Provider config:
 Forward Auth Provider: Authentik
 Protocol: http://
 Forward Auth Domain: ip or domain of host running authentik
 Forward Auth Port: 9000
 Forward Auth URI: /outpost.goauthentik.io/auth/caddy
 Copy Headers: Select any headers you need to forward. Most my stuff needs the X-Authentik-Username, X-Authentik-Groups and X-Authentik-Email headers

I think the auth port and uri are default and should work unless you changed them when configuring authentik.  You can verify by going to Applications -> Providers in authentik, select the forward auth provider for your app and then click on the "Caddy(Standalone)" section under the setup section.  You will see the # forward authentication to outpost snippet with the needed port and uri. Mine looks like this...

# forward authentication to outpost
        forward_auth http://outpost.company:9000 {
            uri /outpost.goauthentik.io/auth/caddy

High level Authentik config:
Create a new application and proxy provider (I typically use the wizard and then tweak if needed after)

Application:
Nothing of note to call out here

Provider:
Select 'Proxy Provider'
Choose the 'implicit' Authorization flow
Select the "Forward auth (single application) box
Add the url of the app you want to forward auth to

Outposts:
Edit the authentik Embedded Outpost
Pick your application on the left and add it to the outpost with the >
Save

Caddy Handler:
When configuring the handler enable advanced mode, upper left, and tick the 'Forward Auth' setting


Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on February 13, 2025, 07:06:28 AM
copy headers can be left empty, the needed headers are added automatically by the template generation. Its just for additional headers like "Authorization" when Authentik sends a Basic Auth Header for example.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: schubdog on February 13, 2025, 10:14:29 PM
Hey,

thank your for the reply. I got it now worky partly, so i can access my proxied Domains secure by Authentik from outside my lan.

But there are two things i'm still struggeling.

1. Bypass with API. I'm used to work with Authelia and was able to set bypass rules with API Keys for Vaultwarden and notifiarr but i don't get it working with Caddy and Authentik

2. How can i access my proxied domain in Lan ?

br

Schubdog
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: smoofus on February 14, 2025, 03:50:42 AM
Quote from: schubdog on February 13, 2025, 10:14:29 PMHey,

thank your for the reply. I got it now worky partly, so i can access my proxied Domains secure by Authentik from outside my lan.

But there are two things i'm still struggeling.

1. Bypass with API. I'm used to work with Authelia and was able to set bypass rules with API Keys for Vaultwarden and notifiarr but i don't get it working with Caddy and Authentik

2. How can i access my proxied domain in Lan ?

br

Schubdog

For #1, go to Applications -> Providers ->  (edit the application proxy prorivider for the app you want to bypass api) -> Advanced protocol settings -> Unauthenticated Paths, and then add the api path to the "Unauthenticated Paths" field.

For example:
Unauthenticated Paths:  */api/.*

For #2, not sure I follow 100% here.  Maybe add local dns entries to point to your wan ip? 
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: ceeeeej on March 08, 2025, 12:56:41 AM
Great plugin (once I figured it out!)

I'm not a networking expert, more of a homelabber. I have OPNSense setup with Adguard Home and Unbound with DNS over TLS.

I was having some trouble getting the Caddy access lists working to restrict some services to my LAN IPs only. To get this all working I had to setup overrides in Unbound that point these URLs back to my Caddy when on my LAN. i.e. I setup example.website.com in Caddy and then in Unbound I had to setup an override to point this URL back to 192.168.1.1 (where Caddy is running on my opnsense router).

My assumption was that because they were encrypted with DNS over TLS that the Caddy reverse proxy can't intercept them?

I think the only other way to get Caddy working with this setup was using the layer4 proxy? I took a look but the options and setup was just a bit too confusing for me. Downside is I just need to setup an override for every service but it really isn't that bad.

Just posting in case anyone has feedback or other ideas here. I was hoping to not require setting these up but it works now.

If there is any feedback on the layer4 proxy with my setup or another way to avoid the overrides in Unbound, I'd love to hear it!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on March 12, 2025, 07:21:36 PM
I need assistance with two Caddy issues

1.  I started using Caddy for a reverse proxy last week.  Once I got it work, I started having issues when it had been running for 6 - 12 hours.  The reverse proxy was working and then it would stop.  I didn't see anything in the logs that indicated what the problem is.  I'm not using a dyndns service.

2.  I followed the instructions to use Caddy as a Layer 4/7 proxy for SSH.  When trying to SSH in, all I got was a message stating the connection had been reset.  I couldn't log into SSH.  I didn't see anything unusual in the logs.

I can post any config or logs that are needed.

Thanks!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 12, 2025, 07:26:43 PM
If you use UDP (only UDP matters) in the layer 4 proxy right now there is an open issue that can make it crash after a while:

https://github.com/mholt/caddy-l4/issues/295

For SSH, last time I tested it was working. Don't know what could be the issue if its like in the docs.

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on March 13, 2025, 04:17:21 PM
Thank you for the info on the UDP bug.  I don't recall seeing and option to turn UDP off for Layer 4 to work properly.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 13, 2025, 04:18:30 PM
You just don't define any UDP rules in the layer4 proxy and you should be fine (for now until the bug is fixed upstream).

Though you can take a look at /var/log/caddy/caddy.log to see if you can find any panics in there.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: OPNenthu on March 15, 2025, 04:14:49 AM
Hi Cedrik, apologies if this is answered elsewhere (I didn't find it)-

I've changed the Caddy user to 'www' from 'root' and set the ports to 8080 and 8443 respectively.  Issue now is that I am getting permission errors in the log.  Example:

2025-03-14T23:03:05-04:00    Error    caddy    "error","ts":"2025-03-15T03:03:05Z","logger":"admin.api","msg":"request error","error":"loading config: loading new config: starting caddy administration endpoint: unable to set permissions (--w--w----) on /var/run/caddy/caddy.sock: chmod /var/run/caddy/caddy.sock: operation not permitted","status_code":400}

I've stopped/started the Caddy service and also rebooted OPNsense but it didn't fix it.  Should I need to change some permissions manually on the filesystem?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 15, 2025, 06:06:47 AM
Its weird to see that error it should have been fixed here:

https://github.com/opnsense/plugins/pull/4403

Which version of the plugin do you use?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: OPNenthu on March 15, 2025, 07:00:52 AM
I have plugin version 1.8.3.  I did a fresh install of OPN 25.1 and upgraded along the way to 25.1.3, and then installed os-caddy.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on March 15, 2025, 11:31:19 AM
Well you should be able to delete the socket file, it will get recreated automatically when caddy starts.

I gonna see if there are issues next week.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: OPNenthu on March 15, 2025, 12:37:17 PM
Thanks- I deleted the file and don't see the error now after bouncing the service.

Here's the 'before' and 'after' state:

root@firewall:~ # cd /var/run/caddy/
root@firewall:/var/run/caddy # ls -l
total 2
-rw-rw----  1 root www 6 Mar 14 23:00 caddy.pid
s-w--w----  1 root www 0 Mar 14 23:00 caddy.sock
srw-rw-rw-  1 root www 0 Mar 14 22:57 log.sock
root@firewall:/var/run/caddy #
root@firewall:/var/run/caddy # rm caddy.sock

(bounced the service here)

root@firewall:/var/run/caddy # ls -l
total 2
-rw-------  1 www  www 6 Mar 15 07:32 caddy.pid
s-w--w----  1 www  www 0 Mar 15 07:32 caddy.sock
srw-rw-rw-  1 root www 0 Mar 14 22:57 log.sock

Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: awshirley on March 20, 2025, 02:11:57 AM
I'm getting an error in the Caddy log when trying to use the reverse proxy on a Plex instance.  The log shows:

"error","ts":"2025-03-19T23:36:47Z","logger":"http.log.error","msg":"EOF","request":{"remote_ip":"192.168.x.xxx","remote_port":"50589","client_ip":"192.168.x.xxx","proto":"HTTP/2.0","method":"GET","host":"plexsub.mydomain.com","uri":"/media/providers?X-Plex-Product=Plex%20Web&X-Plex-Version=4.145.1&X-Plex-Client-Identifier=y1574g5pgysu0b7435g9qsqd&X-Plex-Platform=Firefox&X-Plex-Platform-Version=136.0&X-Plex-Features=external-media%2Cindirect-media%2Chub-style-list&X-Plex-Model=bundled&X-Plex-Device=Windows&X-Plex-Device-Name=Firefox&X-Plex-Device-Screen-Resolution=1536x731%2C1536x864&X-Plex-Token=TWeNgtGispep-E4RBR1m&X-Plex-Language=en&X-Plex-Session-Id=72ff17fc-21db-4b3b-8437-9194ca66bd7d","headers":{"Referer":["http://192.168.x.xxx:32400/"],"Accept-Encoding":["gzip, deflate, br, zstd"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0"],"Accept-Language":["en"],"Dnt":["1"],"Sec-Fetch-Site":["cross-site"],"Accept":["application/json"],"Sec-Fetch-Dest":["empty"],"Sec-Fetch-Mode":["cors"],"Sec-Gpc":["1"],"Te":["trailers"],"Origin":["http://192.168.x.xxx:32400"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"plexsub.mydomain.com"}},"duration":0.000950754,"status":502,"err_id":"kr1iycyqd","err_trace":"reverseproxy.statusError (reverseproxy.go:1373)"}

Plex is stating that remote access through the reverse proxy doesn't work.  Is this something easily fixed?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on April 08, 2025, 06:07:04 PM
TWIMC Just warning here that DNS Providers might get a bit more inconvenient soon.

https://github.com/opnsense/plugins/issues/4643

Only cloudflare will remain default compiled in as it is maintained directly by the caddy organization. All other providers will be optionally installable via CLI with e.g.

caddy add-package github.com/caddy-dns/duckdns

https://caddyserver.com/docs/command-line#caddy-add-package

If they won't compile after the caddy binary is updated to caddy-v2.10.0 please reach out to their maintainers via https://github.com/caddy-dns

This had happened once already and I don't want to run after 40 repos with for something I don't even use personally (I dont use dns-challenge or dynamic-dns, I maintain this in my free time)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: OPNenthu on April 29, 2025, 05:04:19 PM
JFYI- the earlier issue about caddy.sock file being owned by root and causing errors when using the 'www' user in Caddy can still be seen.  Yesterday I re-installed OPNsense and imported my config, then installed the Caddy plugin.  Because of my configs the user was preset to 'www' but the sock file was owned by root and needed to be deleted manually.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on April 29, 2025, 05:56:01 PM
Im a little surprised, can you find out the exact spot where it happens so it can be reproduced?

Please take this as reference what was implemented to mitigate it and the discussion:

https://github.com/opnsense/plugins/pull/4403

If there is still an issue please open one.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: OPNenthu on April 30, 2025, 03:10:02 AM
I tried to reproduce on a test install of OPNsense in Proxmox, but could not.  After changing the user to 'www' and default ports to 8080/8443 the service started fine.

Looking at the GitHub ticket, the fix was merged in December.  I started using OPNsense around 24.7 so I'm wondering if there's something in my main router config file from before the fix that is getting carried over and causing an issue?  I know it sounds crazy but I can't imagine what else it could be. I blew away my previous root filesystem when I did the fresh install yesterday using the 25.1 installer, so literally the only difference between it and the test instance in Proxmox would be the config import.

The socket file does have the correct ownership & permissions (root:www, 0220), and I confirmed that the 'www' user is in the 'www' group as well, so there shouldn't be an issue with that.

I'll post back if I notice anything in my config.xml file, but since this is not reproducible on a clean install then I don't think it warrants a ticket.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on May 01, 2025, 03:26:38 AM
Hello,

I recently upgraded from Opnsense (FreeBSD 14.2-RELEASE-p2) Business Edition 24.10 --> 25.4, and caddy server stopped working.

caddy --version
v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

I have crowdsec plugin on caddy which I use in Caddyfile for integration w/ crowdsec. So, usually, after major upgrades on Opnsense I end up doing the following:

caddy add-package github.com/hslatman/caddy-crowdsec-bouncer github.com/caddyserver/transform-encoder
and off to the races I go. However, this time around, I'm getting a weird 400 error.

caddy add-package github.com/hslatman/caddy-crowdsec-bouncer github.com/caddyserver/transform-encoder
2025/05/01 01:17:17.322 INFO this executable will be replaced {"path": "/usr/local/bin/caddy"}
2025/05/01 01:17:17.322 INFO requesting build {"os": "freebsd", "arch": "amd64", "packages": ["github.com/caddy-dns/desec@v0.0.0-20240526070323-822a6a2014b2", "github.com/caddy-dns/scaleway@v0.0.0-20231227190624-561fd7f77b1b", "github.com/caddyserver/transform-encoder", "github.com/caddy-dns/namedotcom@v0.1.3-0.20231028060845-b9fae156cd97", "github.com/caddy-dns/ovh@v0.0.3", "github.com/caddy-dns/porkbun@v0.2.1", "github.com/caddy-dns/rfc2136@v0.1.1", "github.com/hslatman/caddy-crowdsec-bouncer", "github.com/caddy-dns/netcup@v0.1.1", "github.com/caddy-dns/vultr@v0.0.0-20230331143537-35618104157e", "github.com/caddyserver/ntlm-transport@v0.1.3-0.20230224201505-e0c1e46a3009", "github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e", "github.com/caddy-dns/directadmin@v0.3.1", "github.com/caddy-dns/hetzner@v0.0.2-0.20240820184004-23343c04385f", "github.com/caddy-dns/linode@v0.7.2", "github.com/caddy-dns/namecheap@v0.0.0-20240114194457-7095083a3538", "github.com/caddy-dns/acmedns@v0.3.0", "github.com/caddy-dns/bunny@v0.1.1-0.20240209091254-71ced26b4224", "github.com/caddy-dns/acmeproxy@v1.0.6", "github.com/caddy-dns/infomaniak@v1.0.1", "github.com/caddy-dns/inwx@v0.3.1", "github.com/caddy-dns/mailinabox@v0.0.2-0.20240829173454-39d0e3ce8e25", "github.com/caddy-dns/powerdns@v1.0.1", "github.com/caddy-dns/azure@v0.5.0", "github.com/caddy-dns/gandi@v1.0.4-0.20240531160843-d814cce86812", "github.com/caddy-dns/hexonet@v0.1.0", "github.com/mholt/caddy-ratelimit@v0.1.0", "github.com/mholt/caddy-l4@v0.0.0-20250102174933-6e5f5e311ead", "github.com/caddy-dns/dnsmadeeasy@v1.1.3", "github.com/mholt/caddy-dynamicdns@v0.0.0-20241025234131-7c818ab3fc34", "github.com/caddy-dns/duckdns@v0.4.0", "github.com/caddy-dns/ionos@v1.1.0"]}
Error: download failed: download failed: HTTP 400: unable to fulfill download request (id=43358b0e-5041-4319-adac-d96d6a1e570e)

caddy upgrade
2025/05/01 01:24:33.309 INFO this executable will be replaced {"path": "/usr/local/bin/caddy"}
2025/05/01 01:24:33.309 INFO requesting build {"os": "freebsd", "arch": "amd64", "packages": ["github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e", "github.com/caddy-dns/gandi@v1.0.4-0.20240531160843-d814cce86812", "github.com/caddy-dns/inwx@v0.3.1", "github.com/caddy-dns/acmeproxy@v1.0.6", "github.com/caddy-dns/dnsmadeeasy@v1.1.3", "github.com/caddy-dns/duckdns@v0.4.0", "github.com/caddy-dns/hetzner@v0.0.2-0.20240820184004-23343c04385f", "github.com/caddy-dns/mailinabox@v0.0.2-0.20240829173454-39d0e3ce8e25", "github.com/caddy-dns/namecheap@v0.0.0-20240114194457-7095083a3538", "github.com/mholt/caddy-ratelimit@v0.1.0", "github.com/mholt/caddy-l4@v0.0.0-20250102174933-6e5f5e311ead", "github.com/caddy-dns/bunny@v0.1.1-0.20240209091254-71ced26b4224", "github.com/caddy-dns/directadmin@v0.3.1", "github.com/caddy-dns/linode@v0.7.2", "github.com/caddy-dns/infomaniak@v1.0.1", "github.com/caddy-dns/netcup@v0.1.1", "github.com/caddy-dns/vultr@v0.0.0-20230331143537-35618104157e", "github.com/caddy-dns/acmedns@v0.3.0", "github.com/caddy-dns/azure@v0.5.0", "github.com/caddy-dns/desec@v0.0.0-20240526070323-822a6a2014b2", "github.com/caddy-dns/ovh@v0.0.3", "github.com/caddy-dns/porkbun@v0.2.1", "github.com/caddy-dns/scaleway@v0.0.0-20231227190624-561fd7f77b1b", "github.com/caddyserver/ntlm-transport@v0.1.3-0.20230224201505-e0c1e46a3009", "github.com/caddy-dns/rfc2136@v0.1.1", "github.com/caddy-dns/hexonet@v0.1.0", "github.com/caddy-dns/ionos@v1.1.0", "github.com/caddy-dns/namedotcom@v0.1.3-0.20231028060845-b9fae156cd97", "github.com/caddy-dns/powerdns@v1.0.1", "github.com/mholt/caddy-dynamicdns@v0.0.0-20241025234131-7c818ab3fc34"]}
Error: download failed: download failed: HTTP 400: unable to fulfill download request (id=704dc2db-afa9-4ee4-953a-6ba7ffec9803)

Firewall is not blocking either DNS translation of GitHub or ip connectivity to it. I am wondering if anyone else is having this issue?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 01, 2025, 06:55:57 AM
caddy add-package uses the build servers of the caddy project to supply you with a binary.

They have no SLA and always serve the latest version of caddy.

Right now the latest version probably has build incompatabilities with the build you are requesting.

Try using xcaddy instead for your personal build.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on May 01, 2025, 05:48:37 PM
Thank you, Cedrik.

Quote from: Monviech (Cedrik) on May 01, 2025, 06:55:57 AMTry using xcaddy instead for your personal build.
I presume this'd mean I'd issue xcaddy with all the package names indicated in the previously failed command, like:

xcaddy build \
 --with github.com/caddy-dns/scaleway \
 --with github.com/caddy-dns/desec \
 ...
 (+ packages of my interest e.g. crowdsec)

/r
morik
PS: Your efforts in maintaining os-caddy port for OPNsense and other software are very much appreciated!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 01, 2025, 06:08:31 PM
You only need to specify the packets you want to use. The base build uses the top 4 packages in this list and then just the single DNS provider you need + your custom packages.

https://github.com/opnsense/tools/blob/31002815e15e1f50cc7ab0af5c3f1cd155878926/config/25.1/make.conf#L100

If you cannot build caddy 2.10.0 try to pass version 2.9.1 and use the same commit hashes as I do in the link.



Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on May 01, 2025, 06:36:00 PM
Thank you, Cedrik.

OPNSense: You want to do what?
Me: pkg install xcaddy
OPNSense: Did you take me for a fool?
OPNSense:
pkg install xcaddy
Updating OPNsense repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%  249 KiB 255.0kB/s    00:01
Processing entries: 100%
OPNsense repository update completed. 870 packages processed.
All repositories are up to date.
pkg: No packages available to install matching 'xcaddy' have been found in the repositories

Me:
sed -in 's/no/yes/'  /usr/local/etc/pkg/repos/FreeBSD.conf
FreeBSD: { enabled: yes }


pkg install xcaddy
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating OPNsense repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%  249 KiB 255.0kB/s    00:01
Processing entries: 100%
OPNsense repository update completed. 870 packages processed.
All repositories are up to date.
New version of pkg detected; it needs to be installed first.
The following 1 package(s) will be affected (of 0 checked):

Installed packages to be UPGRADED:
pkg: 1.19.2_5 -> 2.1.2 [FreeBSD]

Number of packages to be upgraded: 1

The process will require 31 MiB more space.
12 MiB to be downloaded.

Proceed with this action? [y/N]: N


OPNSense: Told you, I'll win.
Me: I give up

Also, few minutes later,
Me: having never done ports, why don't we hose our system...
pkg install git
...
git clone --depth=1 https://git.FreeBSD.org/ports.git /usr/ports
cd /usr/ports/www/xcaddy
make install clean
....

mkdir -p ~/caddy_build && cd ~/caddy_build
xcaddy build \
  --with github.com/caddyserver/ntlm-transport \
  --with github.com/mholt/caddy-dynamicdns \
  --with github.com/mholt/caddy-l4 \
  --with github.com/mholt/caddy-ratelimit \
  --with github.com/hslatman/caddy-crowdsec-bouncer \
  --with github.com/caddyserver/transform-encoder
...
...
././caddy version
v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=

<< make my changes on crowdsec >>
configctl caddy restart
OK

Phew.. No idea what else did I break, but the feature which I wanted works now. Of course, I do not know how future os-caddy updates will behave. Life is indeed an adventure :-)
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 01, 2025, 08:41:45 PM
You probably did not break anything, I plan to evaluate to make it more straight forward in the future, maybe.

https://github.com/opnsense/plugins/issues/4668
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on May 01, 2025, 11:04:48 PM
Quote from: Monviech (Cedrik) on May 01, 2025, 08:41:45 PMhttps://github.com/opnsense/plugins/issues/4668

Thank you!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 04, 2025, 04:47:53 PM
I evaluated it and its possible but very brittle. So its not going to be included in the plugin.

In your case you built caddy with go121 which might be an issue since go124 is required for all features to work correctly.

The build will be thinned out soon to only include cloudflare, which will make caddy add-package less prone to fail.

It failed because there was a breaking libdns change again and it includes a couple of dns providers that are dependent on it, thus it failed.

For xcaddy, using a separate freebsd vm where you can tightly control the build environment might be the best choice.

All in all, go limits the flexibility of caddy here, comparing it to dynamic modules in nginx or apache.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: spetrillo on May 26, 2025, 07:25:06 PM
So in my config I have as follows:

1) OPNsense firewall sits behind ISP router.
2) ISP router is configured for DDNS, going to NO-IP
3) Cloudflare is handling external DNS, and CNAMEs are setup in Cloudflare to point back to the NO-IP DNS name

This way everything looks like a static IP/DNS setup. With that said I would assume I do NOT need to configure Caddy for DDNS correct? I would just use the CNAMEs that are stup for the services I want Caddy to proxy correct?
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on May 26, 2025, 08:20:05 PM
If you do a dig or nslookup and your FQDNs always point to the correct IP address with your current setup, you do not need to configure dynamic dns in the caddy plugin, it's that simple.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: janstadt on June 08, 2025, 10:49:38 PM
Im having a heck of a time getting opnsense caddy plugin working with immich. The logs are stating that CORS is failing. Immich states that all i should need to do is set the reverse_proxy (https://immich.app/docs/administration/reverse-proxy#caddy-example-config) which i have done but it fails on CORS requests. I was able to add 4 or 5 additional headers (more here: https://forum.opnsense.org/index.php?topic=46177.msg239034#msg239034) but its stating that the preflight response was a non 2xx response. Any help would be greatly appreciated.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: JanS on June 17, 2025, 08:29:56 PM
Just spent a couple hours debugging a reload(not restart) of the caddy service from the acme client and gave up.
I'll try to briefly summarize the problem/observed behaviour.
System is on 25.1.8_1
Caddy package is 2.0.1
Caddy is setup to run as www and runs nicely.

- Checking /var/run/caddy after restarting the service via GUI shows caddy.sock owned by www:www with 0220
- Applying caddy config from GUI changes that to root:www with 0220
- Restarting the service via GUI changes that back to www:www with 0220

So far so good besides the strange ownership discrepancies between applying config and restarting via GUI.

Setting up an automation in ACME to reload(!) caddy is where things get strange and I can't figure out why.
- Reload fails with log:
"loading config: loading new config: starting caddy administration endpoint: unable to set permissions (--w--w----) on /var/run/caddy/caddy.sock: chmod /var/run/caddy/caddy.sock: operation not permitted"
- Ownership/permission on caddy.sock after running that automation are root:www with 0220 regardless what they where before.

If I use a caddy restart automation in ACME, everything is fine, ownership/permissions after run are www:www with 0220.

As soon as the ownership/permission on caddy.sock is root:www with 0220 running "service caddy reloadssl" fails with the same error, "service caddy restart" reverts ist back to www:www with 0200 after which "service caddy reloadssl" also works fine from the CLI.
So something goes wrong when "service caddy reloadssl" is run via an ACME automation, at least I think that is also run via the system action from within ACME.

I failed digging through all the scripts and includes and system actions etc to identify the cause and now had to give up due to time constraints, am now using caddy restart action from ACME which is fine for now.

Hopefully this helps someone way more knowledgeable then me in all the internals of the system to narrow down the issue.


Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: Monviech (Cedrik) on June 17, 2025, 09:18:58 PM
Thanks for the report, if I have time I will look into it.

Best would be an issue in https://github.com/opnsense/plugins
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: lucasconde on June 28, 2025, 06:07:54 AM
Hi all, I'm setting up Caddy behind OPNsense and running into an issue that I suspect is either a misconfiguration on my part or a misunderstanding of how NAT and Caddy work together.

Setup details:

- OPNsense as the router
  - VLAN 20 for LAN
  - VLAN 50 for servers

Caddy is configured and successfully issues Let's Encrypt certificates

The upstream service (Minio) is running over HTTP on port 9001

I created a NAT rule to forward HTTPS traffic to port 9001 on the server, but I'm getting a ERR_SSL_PROTOCOL_ERROR. If I create a NAT rule for plain HTTP instead, it works fine.

A few questions:

- Has anyone experienced this behavior with Minio over HTTP? Could Minio be rejecting the SSL termination from Caddy?

- I assumed that once a handler is set up in the Caddyfile, Caddy would take care of routing automatically—but it seems like it doesn't touch NAT rules. Is that correct?

Any guidance or clarification on how Caddy and OPNsense should interact in this case would be greatly appreciated!

Thanks in advance.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: AG_2023 on June 30, 2025, 03:57:13 AM
Hi,

I have setup Caddy exactly as described in OPNsense documentation.
I changed the OPNsense https port to 8443, checked the Disable web GUI redirect rule.
I have created the WAN and LAN rules for This firewall destination.
Enabled Caddy, supplied e-mail, Auto HTTPS is ON.
Domain is https://test.duckdns.org. Certificate is Auto HTTPS.
Handler: Domain is https://test.duckdns.org, Directive: reverse_proxy
Upstream:
Protocol: http://
Upstream domain: 192.168.250.162
Upstream port: 2283
Access list private_ipv4 created as per documentation and added to the domain access list

OPNsense runs on a dedicated hardware box, WAN and LAN interfaces only. Dynamic DNS is configured in OPNsense to use DuckDNS. I can do nslookup test.duckdns.org and it resolves to my WAN IP address, no problem. If I access https://test.duckdns.org from within my local network, it can access the server on 192.168.250.162:2283 without any issues. But when I access from internet, I get the error:

net::ERR_HTTP2_PROTOCOL_ERROR


The Caddy file is:

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


# caddy_user=root

# Global Options
{
   log {
      output net unixgram//var/run/caddy/log.sock {
      }
      format json {
         time_format rfc3339
      }
   }

   servers {
      protocols h1 h2
   }

   email xyz@gmail.com
   grace_period 10s
   import /usr/local/etc/caddy/caddy.d/*.global
}

# Reverse Proxy Configuration


test.duckdns.org {
   @c1ac6e21-c93d-461e-8546-246789993f33_testduckdnsorg {
      not client_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
   }
   handle @c1ac6e21-c93d-461e-8546-246789993f33_testduckdnsorg {
      abort
   }

   handle {
      reverse_proxy 192.168.250.162:2283 {
      }
   }
}

import /usr/local/etc/caddy/caddy.d/*.conf


I have done Google search but nothing. I have read all 21 pages of this thread but no matching issue. Caddy is getting certificate from Lets Encrypt. Any help would be appreciated.

OPNsense 25.1.9_2-amd647
os-caddy 2.0.1

Thanks,
Arun

Update: Issue resolved. The documentation is not good. It did not say when to stop creating reverse proxy. It went to configure access list for local access only. I did that and it blocked access from internet. I had to remove the access list from the domain and then reverse proxy started to work from internet. The documentation of Caddy needs to be revised as some options do not exist in OPNsense. It also needs to be made more descriptive to describe so many other options available.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: lucasconde on July 01, 2025, 12:35:24 AM
I was able to fix it, it was a bad config on the DNS, it was pointing to the server IP instead of OPNsense IP to handle the reverse proxy correctly.

Quote from: lucasconde on June 28, 2025, 06:07:54 AMHi all, I'm setting up Caddy behind OPNsense and running into an issue that I suspect is either a misconfiguration on my part or a misunderstanding of how NAT and Caddy work together.

Setup details:

- OPNsense as the router
  - VLAN 20 for LAN
  - VLAN 50 for servers

Caddy is configured and successfully issues Let's Encrypt certificates

The upstream service (Minio) is running over HTTP on port 9001

I created a NAT rule to forward HTTPS traffic to port 9001 on the server, but I'm getting a ERR_SSL_PROTOCOL_ERROR. If I create a NAT rule for plain HTTP instead, it works fine.

A few questions:

- Has anyone experienced this behavior with Minio over HTTP? Could Minio be rejecting the SSL termination from Caddy?

- I assumed that once a handler is set up in the Caddyfile, Caddy would take care of routing automatically—but it seems like it doesn't touch NAT rules. Is that correct?

Any guidance or clarification on how Caddy and OPNsense should interact in this case would be greatly appreciated!

Thanks in advance.
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on July 01, 2025, 08:28:47 AM
Quote from: Monviech (Cedrik) on May 04, 2025, 04:47:53 PMI evaluated it and its possible but very brittle. So it's not going to be included in the plugin.
Thank you for taking the time to look into this matter!

QuoteThe build will be thinned out soon to only include cloudflare, which will make caddy add-package less prone to fail.
Good to hear! I finally got around to using DNS-01 challenge with Porkbun DNS, so had to rebuild caddy 2.10.1 with porkbun module using xcaddy. go124 upgrade was done implicitly. Slightly painful but works. Thank you for writing such a helpful plugin!
Title: Re: Tutorial: Caddy (Reverse Proxy) + Let's Encrypt Certificates + Dynamic DNS
Post by: morik_opnsense on July 01, 2025, 08:35:30 AM
How to use environment variables with caddy?

I had a need to reuse certain parameters in different reverse proxy handler blocks. The manual way of duplicating the same value in multiple places works ofcourse. It'd be easier to use environment variables. So, I tried add caddy.conf in /usr/local/opnsense/service/conf/configd.conf.d with content like so

CADDY_RESOLVERS_DNS_TLS=149.112.112.112 1.1.1.1 8.8.8.8 8.8.4.4

followed by

service configd restart
configctl caddy restart
caddy environ

startup fails w/ the environment variable value not found. Perhaps a wiser being could tell me whether there is a trick to this getting the env variables working?