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

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

Previous topic - Next topic
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.

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.
Hardware:
DEC740

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

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 ?

Yes, definitely.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)


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.

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!

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

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.
Hardware:
DEC740

December 29, 2024, 12:00:25 PM #250 Last Edit: December 29, 2024, 01:23:20 PM by MrManor Reason: Solved
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?

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?

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?

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