We all know the feeling, You’ve finally set up all of
the stuff on your home server Plex, Sonarr, Paperless, Home Assistant And it all works fine! Except every time you access your
applications, you get this ugly SSL warning! Look, I know that that’s a first-world problem. And I know that there are
already a ton of solutions for it Self-signed certificates with
a local signing authority. Adding an exception in the browser, And of course, the good ol’
“just live with the pain”. But self-signed certificates
are a pain in the butt, Adding a browser exception only
works on one browser and one device, And ignoring the warnings only works if you’re a completely sane and
stable human being with no OCD. But what if I told you that there’s way to get
pretty domain names for your homelab applications With valid SSL certificates, and with no need
to expose your services to the outside world. And the best part is that it’s absolutely free. I’m talking, of course, about using a reverse
proxy and DNS validation for our certificates. When you register a public domain name, you
usually point it to a public IP address. However, there’s nothing stopping
you from pointing it to a private IP address that will only be
accessible on your local network. Then, we can use Let’s Encrypt’s DNS challenge to get a valid SSL certificate for all of
your applications, without making them public. And as an added bonus – you won’t have to run
a custom DNS server like PiHole or Adguard Won’t have it edit hosts
files on any of your machines With one little exception,
which we’ll discuss later And it will basically just work on any
device that’s connected to your home network. Excited? Me too But not as excited as I am about
today’s sponsor, Brilliant.org Brilliant.org features a ton of fun interactive
online courses that help you learn math, computer science, statistics,
and a lot of other subjects. Their courses are made
specifically for busy adults, and just people who have a life, in general So you won’t need to spend hours in front of your
computer every day to learn, say, number theory. Or some other cool topic, like computational
biology, solar energy or quantum mechanics And if you find the recent developments
in AI technology unsettling, well, There’s no better way to protect yourself
from the machines taking over the world, than learning how they work. And Brilliant.org has got you covered
with courses on machine learning, neural networks and computer memory. So if you want to be spared in the
upcoming uprising of sentient AI bots, Go to brilliant.org/wolfgang,
and get your free 30-day trial The first 200 people to sign up with the link
will also get a 20% off their annual subscription. For this tutorial we’ll need a domain name. If you’re looking for a free option,
look no further than DuckDNS. The resulting domain will be kind of long, but since most browsers these
days have autocompletion, I don’t think it’s that much of an issue. If you want a shorter domain name, you can buy one for as little as 90 cents
on websites like Namecheap or GoDaddy, And the renewal fees are usually
somewhere around 5-10€ per year. For my homelab, I chose to go with
goose.party, because why the heck not. But for this tutorial, we’re
gonna be using DuckDNS, because it’s free and very easy to set up. First thing we’ll need to set up for
this tutorial is a reverse proxy. For this example, I’ll be
using the Nginx proxy manager. Obviously, you don’t have to
use the Nginx Proxy Manager, And there’s a lot of other popular
reverse proxy applications, such as Caddy, Traefik, SWAG, and so on. However, Nginx Proxy Manager
is very simple to configure, And if that’s your first time using a reverse
proxy, I think it’s one of the best options. One neat feature that Nginx Proxy Manager has is built-in support for Let’s
Encrypt DNS-01 verification. The way Let’s Encrypt usually works is by
running a temporary web server on the port 80, and then asking the Let’s Encrypt certification
servers to generate a certificate for that server. However, in our case, the server that
we’ll be generating a certificate for, won’t be publicly accessible. So instead, we’re gonna
use a method called DNS-01. DNS verification works by creating a special
DNS record on your DNS registar of choice, and then using it to verify that
the domain actually belongs to you. With DNS verification, you don’t
need to open any ports at all, and it works even if your domain
doesn’t point to a public IP. You also don’t need to use any 3rd
party services like Cloudflare Tunnel. And as an added bonus, none of the
data actually leaves your home network So you don’t need to worry about firewall rules or any kind of misconfiguration
on the part of Cloudflare Tunnel One more cool thing about DNS verification is that it actually lets you create
wildcard records for your domains. Which means that no matter how
many subdomains you’re using, you’ll only have to generate
one certificate for all of them. Nginx Proxy Manager does pretty much all the dirty
work of creating the special DNS records for you, and here’s a list of all DNS
providers that it supports. In case of DuckDNS, the only thing
you’ll need need is the API token, which you can find here after you log in. So I have a fresh Debian 11
VM here on my home server, and I’m gonna show you how to
set up the Nginx Proxy Manager. The best way to run it is with Docker, and
if you don’t have docker installed yet, i’m also gonna show you how to install it. If you do have it installed, feel
free to skip to this timecode. First thing you want to do
is install dependencies. And by the way, if you’re already
running as root on your server, feel free to omit "sudo" in all of these commands. Then, we’re gonna want to add the
official Docker repository key, like so After our key has been added,
let’s add the Docker APT repository And here, make sure you put
the correct architecture. If you’re running this on a
regular x86 PC, amd64 is fine, but in case you’re running this on
a Raspberry Pi or another ARM-based computer, you’ll need to replace
`amd64` with `arm64`, like so. After that’s done, let’s update our
apt cache, by typing `sudo apt update` Now we can finally install
Docker, by typing this command: If you’re running as a non-root user, you’ll
also need to add yourself to the `docker` group, by typing `sudo usermod -aG docker username`
, and then logging out and logging back in. Now we can test if the docker works,
by typing `docker run hello-world` For this example, I’m going
to run nginx-proxy-manager, as well as Nextcloud, Jellyfin and Home Assistant, And I’m gonna put them in
the same docker-compose file. This will make sure that all of our containers are on the same Docker network and can
communicate with each other easily. Aside from the ports 81, 80
and 443 on the Nginx container, we don’t need to forward any other ports
or expose our containers to the host. I’ll leave a link to this docker-compose file in the video description in case
you want to play around with, and there’s also an example compose
in the Proxy manager’s Github repo. That being said, you don’t
have to use docker-compose, or even Docker for your applications,
it’s just that it makes things way easier. For now, I’m just gonna exit the text
editor and type `docker-compose up -d`. After waiting a little bit for
all of our containers to launch, we can now go to our browser and type
server_ip:81 to open the Proxy Manager WebUI. The default login here is admin@example.com,
and the password is “changeme”. First thing we need to do here is set our own
name, login and password, so let’s do that. Next, let’s go to SSL Certificates
and click on “Add SSL Certificate”. Before we go further, I’m actually gonna log in to DuckDNS and create a domain
name for our proxy, like so. After that’s done, we need to point
the domain name to the IP address of our proxy instance. In my case, it’s 192.168.0.105 If you’re using a different domain name provider, you’ll also need to create an additional
CNAME record for all the subdomains, which should look something like this. Now let’s go back to the nginx proxy
manger and put our domain name here. We’ll also add a record for our subdomains, which is the same domain name, plus
an asterisk and a dot in front of it. Then, we’ll click on “Use a DNS challenge”. Here, we need to select DuckDNS, and then
we’ll go back to DuckDNS, copy our Token, and paste it right here, making sure
that there are no trailing spaces. Finally, let’s click on “I agree to Let’s
Encrypt Terms of Service”, and press Save. And if you did everything correctly, after some
time, you should see your generated certificates! If you get an error, like you see here, Don't worry about it!
Not every bad thing in life is your fault. This actually might be because the DNS
changes aren’t getting propagated fast enough. By default, the Let’s Encrypt servers wait 30
seconds for the DNS changes to take effect, and if that’s not enough, you might want
to set it at somewhere around 120 seconds. And as you can see, after
increasing the propagation time, we can finally generate our certificates. Now let’s create our first proxy entry. This will let us access our Admin
WebUI with notthebee.duckdns.org. Let’s go to Hosts, Proxy Hosts,
and then click on “Add Proxy Host”. The domain name is going to be our
root domain, so notthebee.duckdns.org, And for the scheme, we need to choose HTTP. Since we’re using docker-compose, we don’t
actually have to put any IP addresses here. We can just refer to our containers
using their names in the compose file. So in this case, `nginxproxymanager`. If you want to proxy a non-docker service, or
maybe if your service is not on the same Docker network as the Nginx Proxy Manager, you’ll
need to put the IP address here instead. So for example, if your service is running on the same machine as the Nginx Proxy
Manager, that will be localhost. Next, we’re gonna set our port,
in this case it’s port 81. Depending on the application, you also
might want to enable some of these options. For example, Home Assistant uses Websockets,
so you’ll want to enable them in that case. “Block Common Exploits” is not that useful, since we’re running our proxy on the
local network, behind a firewall, And “Cache Assets” also doesn’t make much
of a difference in speed in my opinion. So if you want, you can enable these features
and then see if your app works correctly, But personally I’d leave them off, unless
you really know that you need them. After that’s done, let’s go to SSL, and choose
the SSL certificate that we’ve generated earlier. We’ll also click on Force SSL
and enable HTTP/2 Support. And yeah, that’s it. Now we can press on
Save, and open the URL in the browser. Aaand there you go! A local service
running in your home network, with a pretty domain name
and a valid SSL certificate. Now let’s add another
service. For the domain name, we’ll go with nextcloud.notthebee.duckdns.org. I’m using the Nextcloud image from linuxserverio, which makes Nextcloud run
on the port 443 by default. This means that we’ll need to choose
https here, and 443 for the port. For the hostname, we’ll just put nextcloud, since this is the name we gave our
container in the docker-compose file. Choose our certificate, and
enable the first two options. And now let’s open our new
entry in the browser… and, yeah, there you go :) it’s literally that easy. Okay, so now I’ve added the entries
for Jellyfin and Home Assistant, just to save you guys some time. And as you can see, I can access Jellyfin by
simply going to jellyfin.notthebee.duckdns.org With Home Assistant, you’ll also need to
add the IP address of your Nginx Proxy Manager instance to the configuration file,
otherwise you’ll get an error, like this. But after editing the configuration file
and restarting the Home Assistant container, I can now also access it by going
to home.notthebee.duckdns.org So that’s pretty much it, and one
last thing I want to mention is that this method relies on the Internet
connection to resolve the domains. So if you have frequent Internet outages or
just want your services to work independently of the Internet connection, that’s where
you might want to run your own DNS server. Alternatively, you can also add hosts
entries for your apps on your client machines – but that obviously
won’t work on all client devices. Still, if you already have something like Pi-Hole
and AdGuard, you can just put your domains there, and that will make sure that you can access
your stuff even with no Internet connection. So this is it! In this video we’ve set
up a reverse proxy for our local home lab applications with pretty domain
names and valid SSL certificates. Without exposing our services to the
outside world, and with no need to punch holes in our firewall or rely
on a third party tunneling service. I hope you guys enjoyed this video and as
usual, I would like to thank my Patrons.