WireGuard on an internal system
Sometimes it’s not possible to install WireGuard on the home router itself. Perhaps it’s a closed system to which you do not have access, or there is no easy build for that architecture, or any other of the many possible reasons.
But you do have a spare system inside your network that you could use. Here we are going to show one way to make this work. There are others, but we believe this to be the one less involved as it only requires a couple of (very common) changes in the router itself: NAT port forwarding, and DHCP range editing.
To recap, our home network has the
10.10.10.0/24 address, and we want to connect to it from a remote location and be “inserted” into that network as if we were there:
public internet 10.10.10.3/24 home0│ xxxxxx ppp0 ┌────────┐ ┌─┴──┐ xx xxxxx ──────┤ router │ │ ├─ppp0 xxx xx └───┬────┘ home network, .home domain │ │ xx x │ 10.10.10.0/24 │ │ xxx xxx └───┬─────────┬─────────┐ └────┘ xxxxxx │ │ │ ┌─┴─┐ ┌─┴─┐ ┌─┴─┐ wg0 ──┤ │ │ │ │ │ 10.10.10.10/32 │pi4│ │NAS│ │...│ │ │ │ │ │ │ └───┘ └───┘ └───┘ Reserved for VPN users: 10.10.10.2-9
Since in this scenario we don’t have a new network dedicated to our VPN users, we need to “carve out” a section of the home network and reserve it to the VPN.
The easiest way to reserve IPs for the VPN is to change the router configuration (assuming it’s responsible for DHCP in this network) and tell its DHCP server to only hand out addresses from a specific range, leaving a “hole” for our VPN users.
For example, in the case of the
10.10.10.0/24 network, the DHCP server on the router might already be configured to hand out IP addresses from
10.10.10.254. We can carve out a “hole” for our VPN users by reducing the DHCP range, like below:
Or any other layout that is better suited for your case. In that way, the router will never hand out a DHCP address that conflicts with one that we selected for a VPN user.
The second change we need to do in the router is to port forward the WireGuard traffic to the internal system that will be the endpoint. In the diagram above, we selected the
10.10.10.10 system to be the internal WireGuard endpoint, and we will run it on the 51000/udp port. Therefore, you need to configure the router to forward all 51000/udp traffic to
10.10.10.10 on the same 51000/udp port.
Finally, we also need to allow hosts on the internet to send traffic to the router on the 51000/udp port we selected for WireGuard. This is done in the firewall rules of the device. Sometimes just doing the port forwarding from before also configures the firewall to allow that traffic, but better check.
Now we are ready to configure the internal endpoint.
Configuring the internal WireGuard endpoint
$ sudo apt install wireguard
Generate the keys for this host:
$ umask 077 $ wg genkey > internal-private.key $ wg pubkey < internal-private.key > internal-public.key
And create the
/etc/wireguard/wg0.conf file with these contents:
[Interface] Address = 10.10.10.10/32 ListenPort = 51000 PrivateKey = <contents of internal-private.key> [Peer] # laptop PublicKey = <contents of laptop-public.key> AllowedIPs = 10.10.10.11/32 # any available IP in the VPN range
Just like in the Peer to Site scenario with WireGuard on the router, there is no
Endpointconfiguration here for the laptop peer, because we don’t know where it will be connecting from beforehand.
The final step is to configure this internal system as a router for the VPN users. For that, we need to enable a couple of settings:
ip_forward: to enable forwarding (aka, routing) of traffic between interfaces.
proxy_arp: to reply to arp requests on behalf of the VPN systems, as if they were locally present on the network segment.
To do that, and make it persist across reboots, create the file
/etc/sysctl.d/70-wireguard-routing.conf file with this content:
net.ipv4.ip_forward = 1 net.ipv4.conf.all.proxy_arp = 1
Then run this command to apply those settings:
$ sudo sysctl -p /etc/sysctl.d/70-wireguard-routing.conf -w
Now the WireGuard interface can be brought up:
$ sudo wg-quick up wg0
Configuring the peer
The peer configuration will be very similar to what was done before. What changes will be the address, since now it won’t be on an exclusive network for the VPN, but have an address carved out of the home network block.
Let’s call this new configuration file
[Interface] ListenPort = 51000 Address = 10.10.10.11/24 PrivateKey = <contents of the private key for this system> [Peer] PublicKey = <contents of internal-public.key> Endpoint = <home-ppp0-IP-or-hostname>:51000 AllowedIPs = 10.10.10.0/24
And bring up this WireGuard interface:
$ sudo wg-quick up home_internal
There is no need to add an index number to the end of the interface name. That is a convention, but not strictly a requirement.
With the WireGuard interfaces up on both peers, traffic should flow seamlessly in the
10.10.10.0/24 network between remote and local systems.
More specifically, it’s best to test the non-trivial cases, that is, traffic between the remote peer and a host other than the one with the WireGuard interface on the home network.