Reaching Yourself Over the Internet
As I’ve started hosting more and more services on my home network, I’ve increasingly found the need to contact myself over the internet.
For example, I host Forgejo locally at git.mami2.moe. The problem is that from
my computer, I can’t type git.mami2.moe
in the address bar and get on
Forgejo, I need something like localhost:8080
on my computer or
10.0.0.2:8080
on my laptop.
The problems become compounded with some services like Cvat, which only
allowlist a specific set of domains in the header. This means I can’t even reach
Cvat on localhost:8080
from my own computer, as Cvat will deny that request.
Additionally, it’s important to make sure your DNS settings are correct, so
people on the internet can reach Cvat, but that’s not possible to test on your
home network.
In this article I’ll go over my solutions to this problem. Hopefully you learn some networking on the way!
/etc/hosts
The easiest way to go about this is the most basic DNS possible: /etc/hosts
.
Simply add a line to redirect to the loopback, and your reverse proxy should
handle it from there. Systemd-resolved reads /etc/hosts
without even needing
to reload!
127.0.0.1 git.mami2.moe
SOCKS
SOCKet Secure is a widely-available TCP/UDP proxy, which is even baked into OpenSSH! This means any computer you can SSH into can become your SOCKS proxy. In my case, I found this to be by far the easiest solution.
Start by adding dynamic forwarding to your ~/.ssh/config
. Below we specify
9042, but this can be any open port:
Connect to your proxy ssh orca
. Now start chromium with this proxy:
However, I often find I also want to still be able to use a browser without this proxy. In this case, I start up two distinct chromium sessions. For example:
From this, my first browser can reach Forgejo only on localhost:8080
, while the
second one will only reach it on git.mami2.moe
, allowing me to develop locally
but still test changes from an external user’s perspective!
Cellular Connection
This one is a bit silly, but also the least technical option. If you need to help someone with limited technical expertise, this is the best option to suggest.
You can access your website (git.mami2.moe) from your phone when wifi is turned off! Throw up a hotspot and any computer connected through this hotspot has access too!
The major limitations are that you still can’t access git.mami2.moe on the computer actually hosting git.mami2.moe and you’re now using more expensive data.
Hairpin NAT
If you have access to your router/modem and it has Hairpin NAT support, enable it and everything should just work. Hairpin NAT makes the router analyse where an outbound request is being sent. If the request is trying to reach that router’s IP address, it’ll simply reflect the packet, acting as if it came over the internet.
While this seems like the ideal solution, most residential internet service providers do not provide Hairpin NAT on their modems. I don’t know why… Additionally, most commercial networks have moved away from this solution replacing it instead with Split-horizon DNS.
Split-horizon DNS
Split-horizon DNS allows for multiple layers of DNS resolution to be present on your network. This is the most complicated setup, but also the most flexible, as it allows us to become the DNS resolver for the entire network.
We’ll go through a simple setup, which will function similarly to the
/etc/hosts
solution, then step it up to work on all devices on this network.
Local Setup
We’ll use dnsmasq
as it’s the easiest to deal with. Place the following in
/etc/dnsmasq.conf
, modifying as needed
There’s a good chance you have systemd-resolved
or some other sort of DNS
resolver running (NetworkManager does something along these lines too). Kill all
competing DNS resolvers:
Now you should be able to resolve external domains example.com
as well as
override the resolution for your local domains git.mami2.moe
. Try both in
chromium, it should just work.
Full Network
Let’s first modify our /etc/dnsmasq.conf
a little bit. We want to replace the
loopback with your LAN interface’s IP. Often, eth0
will hold this address. You
need both the static IPv4 address and the link-local IPv6. In these examples, my
static IPv4 is 10.0.0.2
and my linklocal is fe80::200:ff:fe00:40
:
You may need to open up your firewall (see firewall-cmd
), but it’s often
already open to the local network.
Login to your router and set the IPv4/6 DNS servers to point to the IPs of your server. You could also add a fallback DNS server, but I’ve found that one might take precedence, circumventing the whole split-horizon.
DHCP leases are held for several hours usually, so to test it, “forget” the network and reconnect. Try accessing git.mami2.moe and something like example.com, which isn’t in your dnsmasq records.
For devices using systemd-resolved
, you must accept DNS records from DHCP. You
can do this by explicitly leaving DNS
and FallbackDNS
blank: