Accessing Home Server From External Networks
January 22, 2023
How Home Network Traffic Works
Every device you use in your home has a private IP address, which means it can only be accessed via that address in its local network (your home). The private IP will not be accessible via external networks (the internet). So how is your laptop which has a private IP able to talk to internet (which can only reach public IPs)? The short answer: Your router has a public IP address (reachable via internet) and uses NAT to forward traffic to the correct private device (your computer). With this knowledge, let’s discuss the steps to make services (ex: web applications) running on your home server accessible from the internet.
Setting Up External Access To Home Server
Step 1: Configure Local Router Settings
As mentioned before, your router has a public IP and is the entry point to all incoming traffic to your home. To be able to route traffic from a specific port on your router to your home server, you have to update your router settings to port forward port 80 and 443 on your router to your home server. This way when port 80 (HTTP) or 443 (HTTPS) is hit on your home router, it will forward the request to your home server hosting your web applications.
The process to update your router settings differs by router but generally you can find the router login page at http://192.168.1.1 and the login information on the back of your router. You can always reset your router settings if you break anything.
Example of Verizon fios router process: https://www.verizon.com/support/knowledge-base-53181/
Step 2: Configure Nginx Virtual Server Proxying
By default, you would only be able to run a single process (i.e web application) on port 80 or 443. If you want to be able to forward to port 80 and hit multiple web applications on your home server then you would need to run some reverse proxy like Nginx or Apache. A reverse proxy can take traffic coming in on port 80, check the host name (or other fields) and route to the appropriate service accordingly. In this example I will be showing a sample nginx configuration but a similar thing can be done with Apache.
Sample Nginx Configuration
user nginx;worker_processes 1;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events {worker_connections 1024;}http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;sendfile on;keepalive_timeout 65;# Increase hash bucket size - https://gist.github.com/muhammadghazali/6c2b8c80d5528e3118613746e0041263server_names_hash_bucket_size 128;# FOCUS HERE: Server blocks responsible for routing from port 80 to correct service by server name #server {listen 80;# Execute this block if incoming request matches this domain nameserver_name myservice1.ddns.com;location / {proxy_set_header X-Forwarded-Host $host:$server_port;proxy_set_header X-Forwarded-Server $host;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# Pass to service running on localhost port 8080proxy_pass http://localhost:8080;}}server {listen 80;# Execute this block if incoming request matches this domain nameserver_name myservice2.ddns.com;location / {proxy_set_header X-Forwarded-Host $host:$server_port;proxy_set_header X-Forwarded-Server $host;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# Pass to service running on localhost port 3001proxy_pass http://localhost:3001;}}}
Explanation - The focus is on the server
blocks. Each server block contains a server_name
that will be the incoming hostname to check against, if the hostname matches then the block will be executed. The block matches all paths by with location /
and the uses proxy pass
to route the request to a local port the application is running in.
Step 3: Creating and Keeping Domain Name Updated
At this point, your home server and its services should be accessible from the internet (assuming you don’t have any firewalls configured that block ports 80/443). There are two key things we need.
1) A domain name to make accessing services easier and also to be able to route on via nginx server_name
.
2) A way to keep the ever changing router IP synced to our domain name.
Creating a domain name
I will not go in depth on this, as there are many resources for it, but you can use AWS or any other registrar to register a domain. Note that these domains names are what will go into the nginx configuration to route services.
Ways to keep IP Address Synced
Dynamic DNS (DDNS)
DDNS is a way to automatically update DNS records for ever changing IP address (think home private IP addresses). This is built into most routers and there should be a section for it in the router settings. Using this, the router itself will keep its IP address updated with the DDNS provider.
Dynu is an example a free DDNS provider. A benefit of using Dynu is they provide you with a free domain name (from a list) if you are testing or don’t care about the actual name. Dynu also has client software you can install on your home server to keep the IP address updated if you cannot configure it via the router.
Here are some Dynu getting started links: Dynu Website Tutorial / Dynu Getting Started.
Custom
If you are not using a DDNS provider or just want an agnostic solution you can use cron and any tools your domain provider exposes. For AWS R53, you can create a cron that regularly updates the IP address using aws cli commands.
I personally prefer this option since of how straightforward it is to implement (assuming your domain provider has update tools) and doesn’t rely on any other external services besides your domain provider and cron.
Congratulations, you now have a home server running services accessible via the internet using regularly updated domain names!
Other Important Home Server Tips
- Configure a firewall (ufw or iptables for linux).
- Change default ssh port or uninstall sshd altogether.
- Configure redundant hard drive setup using ZFS and external backups.
More Reading:
- Networking
- Public vs. Private IPs: https://www.youtube.com/watch?v=po8ZFG0Xc4Q
- NAT: https://www.ipxo.com/blog/what-is-nat/
- Dynu: https://www.dynu.com/en-US/