HTTPS for Homelab
When I wanted to install bitwarden_rs (now vaultwarden), i read their wiki and got struck with an idea to setup my homelab apps behind https.
Then the hunt for reverse proxies started and i settled down with caddy after trying out nginx and traefik (both are good, but not suitable for my usecase). Caddy is a simple configurable reverse proxy and webserver. I use it as reverse proxy and HTTPS provider for all my homelab apps. I have found the configuration is much easier compared to other reverse proxies out there.
Caddy will serve all content using HTTPS by default with its self signed SSL certificates. But i have found that all browsers do not play well and throw a warning. To make the browsers trust the self-signed SSL, you need to add the root certificate to the respective OS and browser cert store. It is very difficult to do it manually, especially for mobile devices. So I use letsencrypt wilcard certificate from my unused domain for homelab.
Letsencrypt will issue a free ssl certificate which is trusted by all browsers. You have to prove the domain ownership to letsencrypt, that’s where http and DNS challenge comes into play. Read more about it here.
By default the caddy binary does not have cloudflare-dns plugin for acme DNS challenge. This is important because all my homelab services are not exposed to internet and there is no way http challenge will work.
xcaddy is tool for compiling and installing caddy from source. (please note that this tool is still under development, but i have found it to be working without any issue)
Please note that to proceed you should have a VM or Container for playing around. I have a dedicated ubuntu container running for reverse proxy.
Downoad and Install Go
Go language is needed for compiling and installing caddy.
## download go https://golang.org/doc/install
wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
## extract
sudo tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz
## add PATH env variable
export PATH=$PATH:/usr/local/go/bin
## reboot check if go is installed
go version
Version is 1.16.3
as of writing this, so please change accordingly.
Download and install xcaddy
Proceed to latest xcaddy releases page and download the *.deb
package. Version is 0.1.9
as of writing this, so please change accordingly.
wget https://github.com/caddyserver/xcaddy/releases/download/v0.1.9/xcaddy_0.1.9_linux_arm64.deb
sudo dpkg -i xcaddy_0.1.9_linux_arm64.deb
Other install methods are also listed in the github page.
Build Caddy with optional plugins
We have downloaded pre-requesites and now we will build caddy with cloudflare-dns plugin. I have added webdav just for this tutorial purpose, feel free to delete it if you are not using it. There are many other plugins, please search and feel free to include the ones you like.
xcaddy build \
--with github.com/caddy-dns/cloudflare
--with github.com/mholt/caddy-webdav
The above command will download the caddy source and compile and create a caddy
binary in the folder where you run the command.
Starting caddy service
The compiled binary file needs to be moved to correct location and a service files needs to be created.
Create a file /etc/systemd/system/caddy.service
with the following contents.
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Be sure to chmod 644
the above file. create a user and group named caddy
sudo chmod 644 /etc/systemd/system/caddy.service
sudo groupadd --system caddy
sudo useradd --system --gid caddy caddy
Move the compiled binary to /usr/local/bin/caddy
sudo chown root:root /usr/local/bin/caddy
sudo chmod 755 /usr/local/bin/caddy
Caddyfile
Create a Caddyfile
in /etc/caddy/Caddyfile
. The following is an example configuration, and complete options and configuration can be checked in official docs.
*.homelab.tld {
tls YOUR_EMAIL
tls {
dns cloudflare API_KEY
}
@app1 host app1.homelab.tld
@app2 host app2.homelab.tld
handle @app1 {
reverse_proxy 192.168.1.10:4000
}
handle @app2 {
reverse_proxy 192.168.1.11:3000
}
log {
output file /var/log/caddy/access.log {
roll_size 10mb
roll_keep 5
roll_keep_for 24h
}
}
}
The above example assumes homelab.tld domain DNS records are managed by cloudflare. When starting caddy it does ACME DNS challenge using the cloudflare DNS plugin to verify the domain ownership and then gets a wildcard SSL certificate from letsencrypt automatically.
Reference
- https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148
- https://www.digitalocean.com/community/tutorials/how-to-host-a-website-with-caddy-on-ubuntu-18-04
- https://www.linode.com/docs/guides/compile-caddy-from-source/
- https://caddyserver.com/docs/caddyfile/directives/tls
For more adventure, try your own CA.
https://smallstep.com/blog/build-a-tiny-ca-with-raspberry-pi-yubikey/