Long time no see! For the past several months, I’ve been pre-occupied with school, work, andctf. Today, however, I finally address something that I’ve been meaning to do for a very long time: enable HTTPS and use local domains for my services. To do so, I leverage DNS rewrites using AdGuard and auto-HTTPS from Caddy.
Preface
Due to the complexities of networking with rootless containers (at the time of writing), this probably could have been a lot easier had I used Docker instead of Podman. I simply could not get this working (nicely) using a purely containerized setup, so I ended up violating one of my requirements and installing Caddy on bare metal. It made life a lot simpler and I don’t see any consequences from doing so. Sue me.
Setup
Step 1: DNS Rewrites
DNS rewrites tell AdGuard: “hey, when you receive DNS queries for <URL or domain wildcard goes here>, please actually return <IP goes here>“. Since AdGuard already operates as my DNS server, this is pretty trivial. Just go to “Filters” > “DNS rewrites”, then set the URL/wildcard and the IP address to route to. Now, when AdGuard receives DNS queries for that domain, it will directly forward requests to the specified IP address rather than querying an upstream DNS provider.
I want all requests with the top level domain .lab
to be handled internally. So, I set a wildcard like so:
Now, all requests to, say, test.lab
are rewritten by AdGuard:
Note
If requests from a client are not being rewritten, try:
- Clearing AdGuard’s DNS cache: “Settings” > “DNS settings” > “DNS cache configuration” > “Clear cache”
- Restarting your AdGuard container
- Running
nslookup @<ip-running-adguard> <rewrite-URL>
to force AdGuard as the DNS server, thereby verifying that it is an issue with AdGuard and not the client
Step 2: Install Caddy
Since I am installing Caddy on bare metal, I opted to use the official package for my distro, Debian. Apart from installing Caddy’s GPG keys, this is as simple as sudo apt install caddy
. The caddy
service will start automatically. To verify that Caddy is running, navigate to http://localhost
(port 80 by default), and see if you’re served an HTML file containing something along the lines of “Your web server is working. Now make it work for you. 💪“.
Step 3: Configuring Caddy
Caddy will install a config file at /etc/caddy/Caddyfile
. By default (ignoring the comments), this looks something like:
:80 {
root * /usr/share/caddy
file_server
}
I removed everything and started fresh. All I intend on routing for now is AdGuard and Seafile, so I need only 2 rules. Quite simply:
adguard.lab {
reverse_proxy localhost:8080
tls internal
}
seafile.lab {
reverse_proxy localhost:8081
tls internal
}
reverse_proxy
tells Caddy where to proxy requests to and tls internal
tells it to use its internal, local certificate authority. That is, all certificates are self-signed. This isn’t a problem for me, so I plan to leave it as-is for now.
Navigating to http://adguard.lab
, for example, the connection is upgraded to HTTPS! However, since the certificates are self-signed, I had to set an exception for the domain:
It’s as simple as that! With very little work, I now have HTTPS and nice local domains for my internal services.
Step 4: Fixing Weird Bugs
AdGuard cooperated without any real troubles; Seafile, on the other hand, didn’t play quite so nice. It would let me get as far as the login page, but after logging in, displayed a Django error stating “CSRF Verification Failed. Request aborted.”. This seems to be a known issue, which was resolved by setting the new domain as a CSRF trusted origin in Seafile’s config. The file, seafile/data/seafile/conf/seahub_settings.py
, was in a bind mount for my Seafile containers; so I simply appended CSRF_TRUSTED_ORIGINS = ["https://seafile.lab"]
and restarted the container. No issues now!
Summary
Configuring local domains with HTTPS is extremely simple using AdGuard and Caddy. AdGuard handles DNS rewrites, allowing one to use domains locally without the need to purchase one. Caddy handles the (reverse) proxying between requests to the internal domain and its intended destination, adding HTTPS in the process.
Previous | Next |
---|---|
part 5 | null |