Remote Access
Allowing remote access is just a matter of setting up a new Wireguard interface, allowing incoming traffic to that interface, and making sure the firewall allows that traffic to connect to the rest of the network.
Create Interface
# cd /etc/wireguard
# umask 077
# wg genkey | tee guard.key | wg pubkey > guard.pub
# printf "[Interface]\PrivateKey = %s\n" `cat guard.key`
Then I modified my file to finish configuring the interface and allow a [Peer]
for my laptop.
# /etc/wireguard/guard.conf
[Interface]
PrivateKey = ****
+ Address = 10.10.20.59/19,0.2.1/28, 2a03:4012:4021:80af:2001:db8:2ebf:2::1f3c/1/64
DNS+ ListenPort = 10.10.0.1,51820
2a03:4012:4021:80af::1+
Table = 9
PostUp = ip rule add iif eth1.9 lookup 9; ip -6 rule add iif eth1.9 lookup 9
PreDown = ip rule del iif eth1.9 lookup 9; ip -6 rule del iif eth1.9 lookup 9+ [Peer]
+ PublicKey = T28Qn5VFzT4wiwEPd7DscwcP3Rsmq23QcnjH1N5G/wc=Iz5ceR0+tCN3BLTWehZxSplzdbABRT8geqifFxubHUA=
Endpoint = wireguard.vpn-provider.example:51820+ AllowedIPs = 10.0.0.0.0/0,2.4, 2001:db8:2ebf:1:::0/0...4/128
+ PresharedKey = ***
A preshard key can be generated by running wg genpsk
and must be set on both the [Peer]
block on the server and the [Interface]
block on the client.
Line 5: All rules/routes should be applied to a custom route table 9
. I could have also named my custom route table by running echo "9 warp" > /etc/iproute2/rt_tables
and then say Table = warp
for improved readability.
Line 6: Adds rules for IPv4 and IPv6 that all traffic coming in interface eth1.9
should use custom route table 9
. Because I defined a peer with AllowedIPs = 0.0.0.0/0
a default route will be setup on custom route table 9
that redirects all traffic to the Wireguard interface. If I named my custom route like shown above I could have said lookup warp
inplace of lookup 9
.
Line 7: Just the inverse of line 5 to clean up after ourselves when taking down the Wireguard interface.
Setup IP Masquerading
IP Masquerading is a technique that hides an entire IP address space, usually consisting of private IP addresses, behind a single IP address in another, usually public address space.
Source: Wikipedia
Configuration
The easiest way to set this up are to append some netfilter rules to the PostUp
and PreDown
parameters.
...
PostUp = ...; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PreDown = ...; iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
[Peer]
...
Although this works you risk the iptables/netfilter rules getting squashed by Shorewall when if it is restarted while the Wireguard interface exists. It is best to have Shorewall setup the masquerading by making a simple declaration in /etc/shorewall/snat
. I've included the other Shorewall configuration files that would be necessary to make this setup work.
First I define the wg
zone…
# /etc/shorewall/zones
#ZONE TYPE OPTIONS IN OUT
# OPTIONS OPTIONS
warp ipv4
+ wg ipv4
Then I define the interface WG_IF
and put it in the wg
zone…
# /etc/shorewall/interfaces
#ZONE INTERFACE OPTIONS
warp WARP_IF tcpflags,nosmurfs,routefilter=2,logmartians,physical=eth1.9
+ wg WG_IF physical=wg0
This tells Shorwall to masquerade all IPs going out on WG_IF
…
# /etc/shorewall/snat
#ACTION SOURCE DEST
+ MASQUERADE 0.0.0.0/0 WG_IF
Then I allow the warp
zone to send packets to the wg
zone. The warp
zone isn't allowed to send packets to any other subnet or the wan
. This prevents any data/privacy spills from happening if the Wireguard interface ever goes down. It is always best to fail into a state that protects security and privacy.
# /etc/shorewall/policy
#SOURCE DEST POLICY LOGLEVEL RATE CONNLIMIT
- warp $FW ACCEPT $LOG_LEVEL
+ warp $FW,wg ACCEPT $LOG_LEVEL