Accessing a subnet that is behind a WireGuard client using a site-to-site setup
We want to access a local subnet remotely, but it is behind a NAT firewall and we can't setup port forwarding. Outgoing connections work, but all incoming connections get DROPPED by the ISP's routing policy.
We'll create a site-to-site connection with WireGuard allowing us to access the local subnet on a remote device (smartphone, in this example) by connecting through a cloud server in the middle.
First let's define our three hosts. They all have WireGuard installed.
A
the Linux machine on the local subnet, behind the NAT/firewall
B
the Linux cloud server (VPS, like an Amazon EC2 instance)
C
a third WireGuard client; a smartphone in this example
The Host A's /etc/wireguard/wg0-client.conf
:
[Interface]
Address = 10.200.200.5/24
PrivateKey = <HOST 'A' PRIVATE-KEY>
ListenPort = 27836 # optional; will be randomly assigned otherwise
DNS = 1.1.1.1 # or your own DNS server if you're running one
[Peer]
PublicKey = <PUBLIC KEY OF HOST 'B'>
Endpoint = host-b-fqdn.tld:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25 # to keep connections alive across NAT
Here's what we need to add to Host A's iptables
rules, expressed as the commands you would use to ADD them:
# iptables -A FORWARD -i wg0-client -j ACCEPT
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Finally, we need to make sure IP forwarding is enabled in Host A's kernel:
$ sysctl net.ipv4.ip_forward=1
Host B's /etc/wireguard/wg0.conf
:
[Interface]
Address = 10.200.200.1/24
PrivateKey = <HOST 'B' PRIVATE KEY>
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
# This is the peer that is on the private subnet that we want to access.
#
# Notice the AllowedIPs... without this part, WireGuard will drop the
# packets destined for the HOST 'A' subnet. AllowedIPs is acting like
# a routing table and ACL here.
[Peer]
PublicKey = <HOST 'A' PUBLIC KEY>
AllowedIPs = 10.200.200.5/32, 100.10.202.0/24
# The smartphone
[Peer]
PublicKey = <HOST 'C' PUBLIC KEY>
AllowedIPs = 10.200.200.3/32
# An additional peer...
[Peer]
PublicKey = <Additional peer pubkey>
AllowedIPs = 10.200.200.4/32
Like we did with Host A, IP forwarding must also be enabled on Host B:
$ sysctl net.ipv4.ip_forward=1
Host C's configuration file:
[Interface]
PrivateKey = <HOST 'C' PRIVATE KEY>
Address = 10.200.200.3/24
DNS = 1.1.1.1
[Peer]
PublicKey = <HOST 'B' PUBLIC KEY>
AllowedIPs = 0.0.0.0/0
Endpoint = host-b-fqdn.tld:51820
PersistentKeepalive = 25
You're finished.
Make sure WireGuard is running on both HOSTS A and B, and then on the smartphone (HOST C), after connecting to HOST B with WireGuard you should be able to ping 10.200.200.5
.
Hi everyone, I have a similar situation to all of the above but with some exceptions. Basically I'm trying to get to a web site hosted on a Arduino (MicroA) connected to a Rasperry Pi Access Point (RpiAP) which is WireGuard connected to a Rasberry Pi WireGuard VPN Server (RpiVPN) to my home network. The RpiAP is behind a Public WiFi router. All of this is working and I can VNC to the RpiVPN and then VNC to from there to the RpiAP and then browse the MicroA.
So understanding all this, I would like to setup a port on my home firewall (aaa.aaa.aaa.aaa:xxx) which if accessed (the easy part), will forward to the RpiVPN (192.168.1.22)(wireguard 10.6.0.1) which will then route to the RpiAP (10.6.0.2) subnet(10.10.10.1) which with then route to the MicroA (10.10.10.180).
Allowing me to get to the MicroA from anywhere Public.
This All seems doable but I lack the skill to setup all the tables (ipTables and Wireguard).
Can anyone offer some help.
Thanks.