There are multiple options when trying to access services in the home network. The most obvious option is usually to open a port on your router and allow access from the internet to the services in the home network. This requires either a static IP, use of a dynamic DNS service, or to constantly query the IP of the router whenever needing to access the service. These issues aside, there are big risks to allowing port forwarding on the home router. Assuming that there isn’t a need to make services accessible to the entire internet, then it is much easier to just run a VPN tunnel which would allow access to services on devices within the VPN. Here we will be using Wireguard as our VPN and setup a tunnel between the VPS and a service within the local network.
Setup Link to heading
- VPS with static IP
- Server in the local network
VPS Setup Link to heading
Initial Setup Link to heading
Create a VPS in your chosen cloud provider. Debian will be used here.
Update and upgrade the system and install unattended-upgrades
for security updates.
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Create a sudoer
user to run commands instead of running as root.
adduser <username>
usermod -aG sudo <username>
Update SSH configs to prevent root login by editing /etc/ssh/sshd_config
and setting PermitRootLogin no
and PasswordAuthentication no
.
The ssh port can also be updated if desired.
Add your own pub ssh key to the /home/<username>/.ssh/authorized_keys
and then reload the sshd daemon.
systemctl reload sshd
Exit the root ssh session and open another ssh session using the new user.
Wireguard Installation Link to heading
Install wireguard packages.
sudo apt install -y wireguard wireguard-tools
Add Wireguard User Link to heading
sudo useradd wireguard -d /etc/wireguard
sudo chown wireguard:wireguard /etc/wireguard
sudo chmod 760 /etc/wireguard
Create Server Key Link to heading
Create a Wireguard key for the server. This can be run directly as the wireguard
user.
sudo su wireguard
cd /etc/wireguard
wg genkey | tee server.key | wg pubkey > server.pub
Create the Wireguard Config File Link to heading
Wireguard config files are usually named wg0.conf
.
Create the file /etc/wireguard/wg0.conf
with the following content.
# Server
# This defines this instance at the wireguard server with a static IP and port.
# Other wireguard instances will connect to this one.
[Interface]
# Paste the contents of the private key file here.
PrivateKey = *****
# Address of this wireguard server within the network.
# Change the size of the subnet as required.
# Ensure that this subnet does not overlap with the subnet being used
# in the home network.
Address = 192.168.100.1/24
# Port to listen on for incoming Wireguard connections.
ListenPort = 51820
# Gateway host in home network
[Peer]
# Paste the contents of the public key of the gateway host
# running in the home network.
PublicKey = *****
# This routes connections to the listed IP addresses to/through this gateway.
# The IP 192.168.100.2 will be the wireguard IP of the gateway host
# and 192.168.50.0/24 is the subnet of the home network.
AllowedIPs = 192.168.100.2/32,192.168.50.0/24
PersistentKeepalive = 25
# Clients
[Peer]
PublicKey = *****
AllowedIPs = 192.168.100.3/32
PersistentKeepalive = 25
# Repeat this config for all other relevant clients.
# Keep incrementing the IP address for each client in the AllowedIPs configuration.
Start the Wireguard Server Link to heading
sudo systemctl start [email protected]
Enable the Wireguard Service Link to heading
sudo systemctl enable wg-quick@wg0
Check the IP Address and Network Interfaces Link to heading
Run ip a
to see the network interfaces and check that there is a wg0
interface with the correct IP address configured.
Gateway Setup Link to heading
The machine used in this instance is a Raspberry Pi 4B 4GB set-up with a static local IP address and updated with security updates, etc.
The packages to install and other setup are the same as in the server setup.
The main difference in this case are the public and private keys and the contents of /etc/wireguard/wg0.conf
.
Generate Keys Link to heading
In the /etc/wireguard
directory create the keys.
wg genkey | tee gateway.key | wg pubkey > gateway.pub
Wireguard Config Link to heading
# Gateway
# This is the gateway through which the tunnel will go to allow access to local services.
[Interface]
# This is the IP address of the gateway in the wireguard mesh network
Address = 192.168.100.2/32
# The contents of gateway.key
PrivateKey = *****
[Peer]
Endpoint = [Public Static Server IP Address]:51820
# The contents of server.pub in the wireguard server.
PublicKey = *****
AllowedIPs = 192.168.100.0/24
PersistentKeepalive = 25
Start the Wireguard Gateway Link to heading
sudo systemctl start [email protected]
Enable the Wireguard Service Link to heading
sudo systemctl enable wg-quick@wg0
Configuring the Server to Forward IPv4 Packets Link to heading
Edit /etc/sysctl.conf
and set net.ipv4.ip_forward=1
then run sudo sysctl -w net.ipv4.ip_forward=1
to set the setting on the current running system without rebooting.
Add an iptables
rule to forward traffic to the gateway.
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
Check if the main interface is eth0
, if it is not, change the command accordingly.
Configuring the Gateway Link to heading
Same as before, update /etc/sysctl.conf
with net.ipv4.ip_forward=1
then run sudo sysctl -w net.ipv4.ip_forward=1
.
Set-up the iptables
rules.
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE
Enable Wireguard Access Through the DigitalOceam Firewall Link to heading
Add an inbound rule to the Digitalocean firewall attached to the droplet allowing UDP
traffic over 51820
or whichever port was used to configure wireguard.
Test Link to heading
Ping the server from the gateway and vice versa.
# On the gateway
ping -c 5 192.168.100.1
# On the server
ping -c 5 192.168.100.2
Add a device Link to heading
Install qrencode
Link to heading
On a mobile phone, installing the tunnel via a generated QR code is the simplest way.
# Install qrencode
sudo apt install -y qrencode
Setup Client Config File Link to heading
Similar to the gateway file, set-up the configs for the next device.
Generate the public and private keys.
wg genkey | tee device.key | wg pubkey > device.pub
Create a new config file device.conf
# Device
[Interface]
# This is the IP address of the device in the wireguard mesh network
Address = 192.168.100.3/32
# The contents of device.key
PrivateKey = *****
[Peer]
Endpoint = [Public Static Server IP Address]:51820
# The contents of server.pub in the wireguard server.
PublicKey = *****
AllowedIPs = 192.168.100.0/24
PersistentKeepalive = 25
Add the device as a peer in the server wireguard config.
# Device
[Peer]
PublicKey = *****
# This IP needs to match the IP address assigned to the device.
AllowedIPs = 192.168.100.3/32
PersistentKeepalive = 25
Reload the wg-quick
service on the server.
This must be done whenever there is a change to wg0.conf
that needs to be propagated to the running service.
sudo systemctl restart wg-quick@wg0
Generate the QR Code conf of the device config and use it to setup the Wireguard tunnel on your device.
sudo qrencode -t ansiutf8 < /etc/wireguard/device.conf
Once setup, test with your device connected on a different network, e.g. cellular, that services on the home network can be accessed.
Repeat these steps for every new device to be added.
Troubleshooting Link to heading
Unable to ping hosts in home network from wireguard network Link to heading
Error:
ping -c 5 192.168.50.4
PING 192.168.50.4 (192.168.50.4) 56(84) bytes of data.
From 192.168.100.1 icmp_seq=1 Destination Host Unreachable
ping: sendmsg: Destination address required
Resolution:
Ensure that the POSTROUTING
is set on the Wireguard Gateway.
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE