Register for the iXsystems Community to get an ad-free experience and exclusive discounts in our eBay Store.
Resource icon

Reverse Proxy using Caddy (with optional automatic TLS)

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
I've thought for a while that it would be nice to set up a reverse proxy in a jail to give easier access to many of the other apps I have installed in jails, without having to remember their port numbers. And it would be nice for the sake of security if it did TLS termination as well. Fortunately, Caddy is designed to do exactly this with a minimum of configuration.

See the Resource for the current version of these instructions.

Nice-to-have
If you want to create a landing page with links to all the other apps you have proxied, you can put it at /usr/local/www/html/index.html. I expect I'll put something basic together using Skeleton, but you're free to use whatever you like here.
 

Jailer

Not strong, but bad
Joined
Sep 12, 2014
Messages
4,346
Nice post. I thought maybe you had given up on Caddy since you haven't posted much about it a while. And thanks for the link to Skeleton, I'm going to look that one over.

I love all the rabbit holes I seem to find on this forum......
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
IIRC, last time I looked at it (which was a while back), it didn't support DNS validation for the cert, which greatly limited its utility for me. It still doesn't support acme-dns, which would really be my preference, but Cloudflare works well for me as well. I seem to recall having trouble with some of the apps I'm using when I tried before, but most of them seem to be working now (Duplicati doesn't, and I think Tautulli will need some work, but the rest do so far). And you get:
  • Simple configuration
  • Automatically obtains (and renews) certs
  • Modern, secure TLS configuration
  • Easy proxying
The downside is that, being written in Go, it doesn't really deal with "plugins" in the sense that they'd otherwise be used--everything has to be compiled into one binary. It sounds like the developer is seriously considering bundling all the DNS plugins into the base binary, though, which would presumably mean that would make its way into the FreeBSD package.

Edit: the simple proxy block I show above works for:
  • Radarr
  • Sonarr
  • SABnzbd
  • NZBget
  • Transmission
  • Tautulli (with the additional directive noted above, though it's far from clear why it should be required, as it should be implied by transparent)
  • ...and probably others, but I haven't tried them yet
Radarr, Sonarr, and Tautulli require that the base URL be set. The other apps above don't seem to require this. Not working so far:
  • Duplicati
  • Urbackup
Not tried yet, but planning to:
  • Xen Orchestra
 

jgreco

Resident Grinch
Moderator
Joined
May 29, 2011
Messages
12,390
... idly wonders wtf a "DNS plugin" is or why your "DNS provider" matters.

I never did care for this business of outsourcing fundamental aspects of the network to random third parties. OTOH I've been running DNS since the '80's and I have an xmas card from Paul Vixie posted on the wall here, so maybe the things I think are easy ... aren't.
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
Looks like it was three years ago I first played with Caddy--apparently it's changed since then.
... idly wonders wtf a "DNS plugin" is or why your "DNS provider" matters.
Caddy automatically obtains TLS certificates from Let's Encrypt. In order to do this, it must solve a challenge, of which there are three possibilities. The first two (HTTP and TLS-ALPN) require that at least one port (80 or 443, respectively) be open from the Internet to the Caddy instance. The third (DNS) requires that Caddy be able to publish DNS TXT records.

If you're willing and able to open ports 80 and 443 from the Internet to your Caddy installation, your DNS provider doesn't matter--Caddy will validate domain control that way. If you aren't, though, it matters because most DNS hosts don't support an automated means of updating your records (e.g., a public API or via RFC 2136). The DNS plugin tells Caddy how to do the updates. My preference is to self-host this portion of my DNS using acme-dns, but Caddy doesn't support that API.
 

jgreco

Resident Grinch
Moderator
Joined
May 29, 2011
Messages
12,390
Honestly, Paul and friends wrote RFC 2136 around 22 years ago. Setting up TSIG isn't hard. Etc.
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
Sure. And if you want to be responsible for that, and have the infrastructure to have multiple geographically-diverse DNS servers, go for it--and Caddy will support that too.
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
danb35 submitted a new resource:

Reverse Proxy using Caddy (with optional automatic TLS) - Install Caddy Server to use as a reverse proxy for web applications in your FreeNAS jails

Many users install a variety of web applications in jails on their FreeNAS servers, and often those applications run on non-standard ports like 6789, 8181, 7878, etc. These port numbers are far from intuitive, and the applications often either don't implement HTTPS at all, or make it difficult to configure. A common recommendation to address these issues is to install a separate web server to act as a reverse proxy (allowing you to browse to simpler URLs like...
Read more about this resource...
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
OK, further development on Duplicati. It doesn't support not being at the host's root (i.e., accessing it as apps.yourdomain.com/duplicati). But if you can dedicate a separate hostname to duplicati, you can do it with a Caddyfile block like this:
Code:
dup.yourdomain.com {
gzip
tls {
        dns cloudflare
}
proxy / http://192.168.1.20:8200 {
        transparent
}
}

The same technique works with Urbackup.
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
And thanks for the link to Skeleton, I'm going to look that one over.
It's pretty basic, but it makes it much easier to put together a decent-looking landing page like this:
1555498416184.png
 

Ericloewe

Not-very-passive-but-aggressive
Moderator
Joined
Feb 15, 2014
Messages
16,261
Quick note: The forum upgrade a while back removed the plugin we used to manage resource threads. I'll try to circle back and fix this once we have that working again.
 

jgreco

Resident Grinch
Moderator
Joined
May 29, 2011
Messages
12,390
Quick note: The forum upgrade a while back removed the plugin we used to manage resource threads. I'll try to circle back and fix this once we have that working again.
Sorry, I busted the resource thread tryin' to fix it. :-(
 

ByteNick

Member
Joined
Jan 24, 2015
Messages
77
No matter what I do, it give me a message like:
Code:
Starting caddy.
eval: 1: Syntax error: "(" unexpected
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325

ByteNick

Member
Joined
Jan 24, 2015
Messages
77
What did you do to get to that point?
More specifically, the following sequence:
Code:
iocage destroy caddy

echo '{"pkgs":["curl","bash","nano","caddy"]}' > /tmp/pkg.json
iocage create -n "caddy" -p /tmp/pkg.json -r 11.2-RELEASE ip4_addr="vnet0|192.168.100.14/24" defaultrouter="192.168.100.1" vnet="on" allow_raw_sockets="1" boot="on" host_hostname="caddy"
rm /tmp/pkg.json

mkdir -p /mnt/tank/apps/caddy
iocage exec caddy mkdir -p /config
iocage fstab -a caddy /mnt/tank/apps/caddy /config nullfs rw 0 0
iocage exec caddy pkg lock caddy

iocage exec caddy "curl https://getcaddy.com | bash -s personal tls.dns.cloudflare"
iocage exec caddy mkdir -p  /usr/local/www
iocage exec caddy mkdir -p  /usr/local/html
iocage exec caddy nano /usr/local/www/Caddyfile

#paste this>
nas.my.domain {
gzip
tls {
        dns cloudflare
}
root /usr/local/www/html/
proxy /nzbget http://192.168.100.207:6789/ {
        transparent
}
proxy /tautulli http://192.168.100.212:8181 {
        transparent
        header_upstream X-Forwarded-For {remote}
}

### EOF

#iocage exec caddy cp -a /usr/local/www/Caddyfile /config/Caddyfile
#iocage exec caddy rm /usr/local/www/Caddyfile
iocage exec caddy ln -s /config/Caddyfile /usr/local/www/Caddyfile
iocage exec caddy ln -s /config/html /usr/local/www/html

iocage exec caddy sysrc caddy_cert_email="my@email.com"
iocage exec caddy sysrc caddy_env="CLOUDFLARE_EMAIL=(my@email.com) CLOUDFLARE_API_KEY=(my_cloudflare_api_key)"
iocage exec caddy sysrc "caddy_enable=YES"
iocage exec caddy service caddy start
iocage exec caddy service caddy status
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
More specifically, the following sequence:
...which is nowhere close to "follow[ing] to the letter the instructions above". In fact, pretty much every step is different--all reasonable adaptations, yes, but not a single step is identical to what I posted. But with that said, I'm wondering if it's something simple--you didn't include the parentheses in the sysrc caddy_env="CLOUDFLARE_EMAIL=(my@email.com) CLOUDFLARE_API_KEY=(my_cloudflare_api_key)" command, did you? Because they weren't intended to be included; they were intended to denote "(insert key here)" -> "fhqo4fhaivluaqap789h4".

As a side note, there's a much simpler way to put the Caddyfile in /config/ if you want to do that: sysrc caddy_config_path="/config/Caddyfile". You can similarly have the server's root there by changing the root /usr/local/www/html/ in the Caddyfile to root /config/html/.

Edit: and if you're trying to store configuration outside of the jail, you should deal with the /.caddy/ directory as well--it stores, among other things, any certs/keys.
 

ByteNick

Member
Joined
Jan 24, 2015
Messages
77
Dan, I am sorry. This morning I was in a hurry, and I did not offered all explanations.
First, I followed "to the letter" all the steps, and it did not worked.
Secondly, in a hurry, I wrote the sequence above, mainly to keep some of the config files somewhere I can easily edit and preserve in case I have to reinstall the jail (which happened several times). You are absolutely right, I should amend it to include all configuration files.
It did not worked either.
But, as always, being a living hero, you are right. It was indeed my stupidity in keeping those parentheses.
Many, many, many thanks.
 

danb35

Wizened Sage
Joined
Aug 16, 2011
Messages
11,325
...and I'm certainly not saying your changes were wrong or ill-advised (they make a lot of sense), and they weren't what caused the problem. But glad it's working
 

ByteNick

Member
Joined
Jan 24, 2015
Messages
77
Many thanks, once again.

Still have a long way to go here. I need to configure the proxy for two machines:
- a FreeNAS box, with the usual, or not, depends on the preferences jails: Organizr, Plex, Emby, Tautulli, Radarr, Sonarr, Lidarr, Headphones, Nextcloud (thank you again for your beautiful script), Calibre, Jacket, Deluge, Transmission, SabNZBD, Duplicatti, Urbackup, and Resilio, plus a VM running Ubuntu Server, for the time being just for Ombi v3, and maybe some others in the future that cannot run in a FN jail
- An Intel NUC, with Hass.io, with different AddOns, driving my flat (and my 3-rd wife crazy).

All of the above are functioning well for now, but I want to secure the entire installation. Your resource on Caddy comes in very handy, also because it is offering a way to work with Cloudflare where my domain is.

So far, I have been trying (only partially successful) to use a jail with a NGINX reverse proxy, but the configuration is hell, and the failure rate is high.

Plus, it would be great for everything to be accessible from Organizr (or something equivalent) to be used as landing page.

If you have any tips for me, it would be greatly appreciated. I am pretty sure this sounds familiar, but for me the learning curve has been difficult. I do railways for a living (nothing related to software), and all the above are a night hobby, sure, a very catchy and fulfilling one, reminding my youth.
 
Top