Setting Up a Home Server: Static IP and Port Exposure with WireGuard on Linux
Have you ever wished to run your own email server from the comfort of your home but were held back by the need for a reliable static IP? There is a solution! Whether it's hosting a personal website, gaming server, or a specialized application, this guide will show you how to set up a static IP and port exposure using Wireguard on Linux.
"What if I already have a static IP?" If you already have a static IP address, you may not need this guide. However, you can still use WireGuard to secure your connection and hide your home IP address from the internet.
Prerequisites
- 🖥️ A hosted Linux server with a public IPv4 address
- 💻 A linux server at your home (e.g. Raspberry Pi)
- 🤔 A basic understanding of Linux and networking
Overview
The basic idea is to set up a VPN server on your hosted Linux server and a VPN client on your home Linux server. The
VPN client will connect to the VPN server and expose the VPN server's IP address to the internet. This will allow you
to access your home server from the internet using the VPN server's IP address.
A nice side effect of this setup is that your actual home IP address will be hidden from the internet.
🖥️ Setting up the VPN Server
This process is fairly straightforward. We will be using WireGuard to set up the VPN server.
- SSH into your hosted Linux server
- Install WireGuard
sudo apt update && sudo apt install wireguard -y
- Generate server and client keys
umask 077; wg genkey | tee server_private_key | wg pubkey > server_public_key umask 077; wg genkey | tee client_private_key | wg pubkey > client_public_key
- Configure the WireGuard server
Create the configuration file/etc/wireguard/wg0.conf
with the following content:[Interface] PrivateKey = <server_private_key> Address = 12.0.0.1/24 ListenPort = 51820 [Peer] PublicKey = <client_public_key> AllowedIPs = 12.0.0.2/32
- Start the WireGuard server
sudo wg-quick up wg0
- Enable WireGuard to start on boot
sudo systemctl enable wg-quick@wg0
💻 Setting up the VPN Client
- SSH into your home Linux server and install WireGuard:
sudo apt update && sudo apt install wireguard -y
- Configure the WireGuard client
Create the configuration file/etc/wireguard/wg0.conf
with the following content:[Interface] PrivateKey = <client_private_key> Address = 12.0.0.2/24 [Peer] PublicKey = <server_public_key> Endpoint = <hosted-server-ip>:51820 AllowedIPs = 0.0.0.0/0
- Start the WireGuard client:
sudo wg-quick up wg0
- Enable WireGuard to start on boot
sudo systemctl enable wg-quick@wg0
- Check your public IP address:
You should see the IP address of your hosted Linux server. This means that your home Linux server is now connected to your hosted Linux server via the VPN server.curl ifconfig.me
🔀 Setting up port forwarding
Now that your home Linux server is connected to your hosted Linux server via the VPN server, you can expose any port on your home Linux server to the internet. This is done by setting up port forwarding on your hosted Linux server.
First, you need to find out the IP address of your home Linux server. You can do this by running the following command on your hosted Linux server:
cat /etc/wireguard/wg0.conf | grep Address | cut -d '=' -f 2
This is the IP address of your home Linux server. You can now set up port forwarding on your hosted Linux server to expose any port on your home Linux server to the internet.
To make the setup easier, we are going to set an environment variable with the IP address of your home Linux server:
export HOME_IP=<home-server-ip> # Replace <home-server-ip> with the IP address of your home Linux server
export STATIC_IP=<static-ip> # Replace <static-ip> with the static IP address of your hosted Linux server
First, you need to enable IP forwarding on your hosted Linux server. Replace eth0
with the name of your network
interface:
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
You can use the following commands to set up port forwarding on your hosted Linux server:
🌐 Exposing a TCP port
PORT=<port>; sudo iptables -t nat -d $STATIC_IP -A PREROUTING -p tcp --dport $PORT -j DNAT --to-destination $HOME_IP:$PORT
🌐 Exposing a UDP port
PORT=<port>; sudo iptables -t nat -d $STATIC_IP -A PREROUTING -p udp --dport $PORT -j DNAT --to-destination $HOME_IP:$PORT
🌍 Exposing a range of TCP ports
START_PORT=<start-port> END_PORT=<end-port>; sudo iptables -t nat -d $STATIC_IP -A PREROUTING -p tcp --dport $START_PORT:$END_PORT -j DNAT --to-destination $HOME_IP:$START_PORT-$END_PORT
🌍 Exposing a range of UDP ports
START_PORT=<start-port> END_PORT=<end-port>; sudo iptables -t nat -d $STATIC_IP -A PREROUTING -p udp --dport $START_PORT:$END_PORT -j DNAT --to-destination $HOME_IP:$START_PORT-$END_PORT
ℹ️ Example: Exposing a web server on port 80
PORT=80; sudo iptables -t nat -d $STATIC_IP -A PREROUTING -p tcp --dport $PORT -j DNAT --to-destination $HOME_IP:$PORT
💾 Making the iptables rules persistent
The iptables rules are not persistent by default. This means that if you reboot your hosted Linux server, the iptables
rules will be lost. To make the iptables rules persistent, you need to install the iptables-persistent
package:
sudo apt update && apt install iptables-persistent -y
During the installation, you will be asked if you want to save the current iptables rules. Type yes
and press Enter
to save the rules. The iptables rules will now be loaded automatically on boot.
🎉 Conclusion
Congratulations! You have successfully set up a static IP and port exposure using WireGuard on Linux. You can now access any service on your home Linux server from the internet using the IP address of your hosted Linux server.