Using Wireguard to expose a public IPv4 subnet to VMs behind a LAN

Summary

I want to use Wireguard to allow VMs on my home network to each have one unique public IP from a /27 pool (32 IPs) that I have routed to a dedicated server with a hosting provider.

My goal is to avoid using SNAT/DNAT, and instead just use static routes whenever possible, so that the WAN-facing interface of each VM can claim a public IP.

What Works

  • My laptop ==> Proxmox servers and VMs using private IPs on a few different VLANs (so, inter-VLAN routing is working fine)
  • Proxmox servers ==> Internet through my local gateway's NAT
  • Cloud-hosted dedicated server ==> Internet

What Doesn't Work

The problem I'm facing is that I can't send/receive ping or ssh (or any traffic that I've tried) across the Wireguard tunnel (just from one end of the tunnel to the other), suggesting I have some configuration wrong.


High-Level Config

Datacenter Hosted

Server

  • Ubuntu 20.04 LTS x86_64
  • Network config is done using systemd-networkd 245
  • Firewall is ufw (currently wide open for testing)
  • Server has multiple public IP subnets allocated to it - including a dedicated /32 for management that won't be getting exposed to VMs
  • One of the public subnets, hereafter represented as "44.44.44.0/27" is what I want to expose to the VMs on my home network.
  • Has Wireguard IP 10.10.10.1

Home Network

Gateway

  • RHEL8 x86_64
  • Network config is done using systemd-networkd v239
  • Firewall is Shorewall (currently wide open for testing)
  • Wireguard tools and kernel module are installed
  • Has a 4-port Intel I350-T4 NIC, with one port connected to the ISP and one connected to Managed Switch
  • Configured systemd-networkd and Shorewall to NAT on VLAN 1 ("untagged"), VLAN 70 ("Proxmox Management VLAN"), and VLAN 80 ("VM private VLAN")
  • Has Wireguard IP 10.10.10.2

Cisco Managed Switch (CMS)

  • Cisco RV345 in switch mode (no WAN port use, no IPv4 routing, no NAT)
  • VLAN port mapping is as follows: VLAN 1 => all ports untagged except the port to Dumb Switch for Proxmox (DSP). VLAN 70 => all ports Excluded except the port to Gateway = Tagged, and the port to DSP = Untagged. VLAN 80 => all ports Excluded except the port to Gateway = Tagged, and the port to DSP = Tagged. VLAN 90 => all ports Excluded except the port to Gateway = Tagged, and the port to DSP = Tagged.
  • Devices connected to the CMS other than the DSP and Gateway are on VLAN 1 and do not need routed public IPs; they just go through Gateway's NAT and use my home network's public IP.

Dumb Switch for Proxmox (DSP)

  • Netgear GS308v3
  • Ports occupied by several Proxmox Hosts (PHs) and one connection to CMS
  • No on-device configuration, but it does preserve 802.1Q VLAN tags that are passed to it

Proxmox Hosts (PHs)

  • Running Proxmox VE 6.3 x86_64
  • Each box has one GbE NIC connected to DSP
  • Sends untagged traffic on private subnet 10.0.0.128/25 as the Proxmox Management VLAN (CMS tags the traffic when sending it to Gateway)
  • Has a vmbr0 (virtual Layer 2 bridge) connecting VMs to the network. The nice part about this is I can test out my layer 3 IP config settings on a VM without potentially breaking the networking of the Proxmox host.

Proxmox VM (PVM)

  • Running Ubuntu 20.04 LTS
  • Network config is done using systemd-networkd 245
  • Two virtual NICs....
  • One on VLAN 80 on private subnet 10.0.1.0/24 that works for outbound Internet traffic (via my local ISP) when the default gateway is set to 10.0.1.1 (Gateway's VLAN 80 IP). Also works for inbound LAN traffic (including from other VLANs, like VLAN 1 where my laptop is) for SSH access.
  • One on VLAN 90 intended to be on public subnet 44.44.44.0/27; when the default gateway is set to Gateway's VLAN 90 IP, or the Wireguard IP of Gateway, or the Wireguard IP of Server, the box has no functioning networking. It can't ping any of these boxes with the default gateway set on the VLAN 90 NIC. I don't expect this to work until I solve the problem with Wireguard though.

Config Dump

IPv6 is trimmed from printouts since it isn't in the picture. All routing, etc. that I'm doing is exclusively IPv4.

Representative IPs

I "anonymized" some public IPs within these configs to hide my actual identity.

  • 44.44.44.0/27: Represents the public /27 I want my VMs to be able to claim, via Wireguard and clever routing.
  • 55.55.55.0/24: Represents the public "management interface" of Server. This is NOT being routed to my local network, and is just used to SSH to Server and for connecting the WG tunnel.
  • 71.71.71.0/24: Represents the public IP of my home Internet. I have one dynamic IP obtained via DHCP from the ISP's gateway. Gateway's public IP is represented here by 71.71.71.200, and the ISP's infrastructure gateway is represented by 71.71.71.1.

Server

╭─root@server /etc/systemd/network ╰─# wg show all interface: wg0 public key: (public key) private key: (hidden) listening port: 12345 peer: (peer) preshared key: (hidden) endpoint: 71.71.71.200:35795 allowed ips: 10.10.10.0/24, 44.44.44.0/27 latest handshake: 23 seconds ago transfer: 143.44 KiB received, 115.30 MiB sent ╭─root@server /etc/systemd/network ╰─# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 12:34:(some MAC) brd 12:34:(some MAC) 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) # VFs used for existing VMs on the server vf 0 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking off, link-state auto, trust off vf 1 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking off, link-state auto, trust off vf 2 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking off, link-state auto, trust off vf 3 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking on, link-state auto, trust off vf 4 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking on, link-state auto, trust off vf 5 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking on, link-state auto, trust off vf 6 link/ether 12:34:(some MAC) brd 12:34:(some MAC) spoof checking on, link-state auto, trust off 3: eno2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 4: enp2s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 5: enp2s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 6: lxdbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 12: eno1v3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 13: eno1v4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 14: eno1v5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 15: eno1v6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 29: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 30: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 61: tap15ad56cf: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master lxdbr0 state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 74: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/none ╭─root@server /etc/systemd/network ╰─# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 12:34:(some MAC) brd 12:34:(some MAC) inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 55.55.55.1/24 brd 55.55.55.255 scope global eno1 valid_lft forever preferred_lft forever 3: eno2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 4: enp2s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 5: enp2s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 6: lxdbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 10.231.114.1/24 scope global lxdbr0 valid_lft forever preferred_lft forever 12: eno1v3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 13: eno1v4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 14: eno1v5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 15: eno1v6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 29: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 30: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 61: tap15ad56cf: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master lxdbr0 state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 74: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none inet 10.10.10.1/32 scope global wg0 valid_lft forever preferred_lft forever ╭─root@server /etc/systemd/network ╰─# ip route default via 55.55.55.254 dev eno1 proto static 10.231.114.0/24 dev lxdbr0 proto kernel scope link src 10.231.114.1 44.44.44.0/27 via 10.10.10.1 dev wg0 proto static 55.55.55.0/24 dev eno1 proto kernel scope link src 55.55.55.1 192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown ╭─root@server /etc/systemd/network ╰─# for i in $(ls *.net*); do echo '----'"${i}"'----'; cat "${i}"; done ----50-default.network---- [Match] MACAddress=12:34:(some MAC) [Network] Description=network interface on public network, with default route DHCP=no Address=55.55.55.1/24 Gateway=55.55.55.254 IPv6AcceptRA=no NTP=pool.ntp.org DNS=127.0.0.1 DNS=1.1.1.1 ----wg0.netdev---- [NetDev] Name = wg0 Kind = wireguard Description = wg server to expose 44.44.44.0/27 [WireGuard] # For systemd >= 242 PrivateKeyFile = /etc/systemd/network/wg-private.key ListenPort = 12345 [WireGuardPeer] PublicKey = (public key) AllowedIPs = 44.44.44.0/27,10.10.10.0/24 # For systemd >= 242 PresharedKeyFile = /etc/systemd/network/wg-preshared.key ----wg0.network---- [Match] Name = wg0 [Network] Address = 10.10.10.1/32 [Route] Gateway = 10.10.10.1 Destination = 44.44.44.0/27 

Gateway

[root@gateway network]# wg show all interface: wg0 public key: (public key) private key: (hidden) listening port: 35795 peer: (public key) preshared key: (hidden) endpoint: 55.55.55.1:12345 allowed ips: 10.10.10.0/24, 44.44.44.0/27 latest handshake: 2 minutes, 1 second ago transfer: 3.18 MiB received, 2.17 KiB sent persistent keepalive: every 25 seconds [root@gateway network]# systemctl --version systemd 239 (239-41.el8_3.2) +PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy [root@gateway network]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 12:34:(some MAC) brd 12:34:(some MAC) 2: wan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 3: eno1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 4: lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 5: enp2s0f2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 6: enp2s0f3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/none 8: lan0.70@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 9: lan0.80@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 10: lan0.90@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) [root@gateway network]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 12:34:(some MAC) brd 12:34:(some MAC) inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: wan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 71.71.71.200/24 brd 71.71.71.255 scope global dynamic wan0 valid_lft 4925sec preferred_lft 4925sec 3: eno1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 4: lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 10.0.0.1/25 brd 10.0.0.127 scope global lan0 valid_lft forever preferred_lft forever 5: enp2s0f2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 6: enp2s0f3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) 7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none inet 10.10.10.2/32 scope global wg0 valid_lft forever preferred_lft forever 8: lan0.70@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 10.0.0.129/25 brd 10.0.0.255 scope global lan0.70 valid_lft forever preferred_lft forever 9: lan0.80@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 10.0.1.1/24 brd 10.0.1.255 scope global lan0.80 valid_lft forever preferred_lft forever 10: lan0.90@lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 12:34:(some MAC) brd 12:34:(some MAC) inet 44.44.44.3/27 brd 44.44.44.254 scope global lan0.90 valid_lft forever preferred_lft forever [root@gateway network]# ip route show table all default via 44.44.44.1 dev lan0.90 table 47 proto static onlink 10.0.0.0/25 dev lan0.90 table 47 proto static scope link 10.0.1.0/24 dev lan0.90 table 47 proto static scope link 10.0.2.0/24 dev lan0.90 table 47 proto static scope link default via 71.71.71.1 dev wan0 proto dhcp src 71.71.71.200 metric 1024 10.0.0.0/25 dev lan0 proto kernel scope link src 10.0.0.1 10.0.0.128/25 dev lan0.70 proto kernel scope link src 10.0.0.129 10.0.1.0/24 dev lan0.80 proto kernel scope link src 10.0.1.1 44.44.44.0/27 via 10.10.10.1 dev wg0 proto static onlink 71.71.71.0/24 dev wan0 proto kernel scope link src 71.71.71.200 71.71.71.1 dev wan0 proto dhcp scope link src 71.71.71.200 metric 1024 broadcast 10.0.0.0 dev lan0 table local proto kernel scope link src 10.0.0.1 local 10.0.0.1 dev lan0 table local proto kernel scope host src 10.0.0.1 broadcast 10.0.0.127 dev lan0 table local proto kernel scope link src 10.0.0.1 broadcast 10.0.0.128 dev lan0.70 table local proto kernel scope link src 10.0.0.129 local 10.0.0.129 dev lan0.70 table local proto kernel scope host src 10.0.0.129 broadcast 10.0.0.255 dev lan0.70 table local proto kernel scope link src 10.0.0.129 broadcast 10.0.1.0 dev lan0.80 table local proto kernel scope link src 10.0.1.1 local 10.0.1.1 dev lan0.80 table local proto kernel scope host src 10.0.1.1 broadcast 10.0.1.255 dev lan0.80 table local proto kernel scope link src 10.0.1.1 local 10.10.10.2 dev wg0 table local proto kernel scope host src 10.10.10.2 broadcast 44.44.44.0 dev lan0.90 table local proto kernel scope link src 44.44.44.3 local 44.44.44.3 dev lan0.90 table local proto kernel scope host src 44.44.44.3 broadcast 44.44.44.254 dev lan0.90 table local proto kernel scope link src 44.44.44.3 broadcast 71.71.71.0 dev wan0 table local proto kernel scope link src 71.71.71.200 local 71.71.71.200 dev wan0 table local proto kernel scope host src 71.71.71.200 broadcast 71.71.71.255 dev wan0 table local proto kernel scope link src 71.71.71.200 broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1 local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1 broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1 ::1 dev lo proto kernel metric 256 pref medium local ::1 dev lo table local proto kernel metric 0 pref medium [root@gateway network]# for i in $(ls *.net*); do echo '----'"${i}"'----'; cat "${i}"; done ----lan0.70.netdev---- [NetDev] Name=lan0.70 Kind=vlan [VLAN] Id=70 ----lan0.70.network---- [Match] Name=lan0.70 [Network] DHCP=no Address=10.0.0.129/25 DHCPServer=yes IPMasquerade=ipv4 [DHCPServer] PoolOffset=100 PoolSize=20 EmitDNS=yes DNS=1.1.1.1 DNS=8.8.8.8 ----lan0.80.netdev---- [NetDev] Name=lan0.80 Kind=vlan [VLAN] Id=80 ----lan0.80.network---- [Match] Name=lan0.80 [Network] DHCP=no Address=10.0.1.1/24 DHCPServer=yes IPMasquerade=ipv4 [DHCPServer] PoolOffset=100 PoolSize=20 EmitDNS=yes DNS=1.1.1.1 DNS=8.8.8.8 ----lan0.90.netdev---- [NetDev] Name=lan0.90 Kind=vlan [VLAN] Id=90 ----lan0.90.network---- [Match] Name=lan0.90 [Network] DHCP=no Address=44.44.44.3/27 DHCPServer=no [RoutingPolicyRule] Table=47 From=44.44.44.0/27 #Not sure if needed - tried with and without #[Route] #Table=47 #Scope=link #Type=unicast #Destination=44.44.44.0/27 #Also not sure if needed - tried with and without [Route] Table=47 GatewayOnLink=true Gateway=44.44.44.1 Destination=0.0.0.0/0 Scope=global [Route] Table=47 Scope=link Type=unicast Destination=10.0.0.0/25 [Route] Table=47 Scope=link Type=unicast Destination=10.0.1.0/24 [Route] Table=47 Scope=link Type=unicast Destination=10.0.2.0/24 ----lan0.network---- [Match] Name=lan0 [Network] Address=10.0.0.1/25 VLAN=lan0.70 VLAN=lan0.80 VLAN=lan0.90 DHCPServer=yes IPMasquerade=ipv4 [DHCPServer] PoolOffset=2 PoolSize=100 EmitDNS=yes DNS=1.1.1.1 DNS=8.8.8.8 ----wan0.network---- [Match] Name=wan0 [Network] DHCP=yes DNS=1.1.1.1 8.8.8.8 ----wg0.netdev---- [NetDev] Name = wg0 Kind = wireguard Description = wg client for 44.44.44.0/27 [WireGuard] # For systemd < 242 PrivateKey = (private key) [WireGuardPeer] PublicKey = (public key) AllowedIPs = 44.44.44.1/27,10.10.10.0/24 Endpoint = 55.55.55.1:12345 # If running systemd >= 242 #PresharedKeyFile = /etc/systemd/network/wg-preshared.key # If running systemd < 242 PresharedKey = (preshared key) PersistentKeepalive = 25 ----wg0.network---- [Match] Name = wg0 [Network] Address = 10.10.10.2/32 [Route] Gateway = 10.10.10.1 Destination = 44.44.44.0/27 GatewayOnlink = true [root@gateway network]# for i in $(ls *.link); do echo '----'"${i}"'----'; cat "${i}"; done ----10-lan0.link---- [Match] MACAddress=12:34:(some MAC) [Link] Name=lan0 ----10-wan0.link---- [Match] MACAddress=12:34:(some MAC) [Link] Name=wan0 # Shorewall config [root@gateway shorewall]# for i in zones interfaces policy rules snat; do echo '----'"${i}"'----'; cat "${i}"; done ----zones---- #ZONE TYPE OPTIONS IN_OPTIONS OUT_OPTIONS fw firewall lan ip wan ip lan80 ip wan90 ip wg ip ----interfaces---- ?FORMAT 2 #ZONE INTERFACE OPTIONS lan lan0 dhcp wan wan0 lan lan0.70 dhcp lan80 lan0.80 wan90 lan0.90 wg wg0 ----policy---- #SOURCE DEST POLICY LOGLEVEL RATE CONNLIMIT wan all REJECT info wg all ACCEPT all wg ACCEPT all wan ACCEPT all lan80 ACCEPT lan80 all ACCEPT all wan90 ACCEPT wan90 all ACCEPT all all REJECT info ----rules---- #ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK CONNLIMIT TIME HEADERS SWITCH HELPER ?SECTION ALL ?SECTION ESTABLISHED ?SECTION RELATED ?SECTION INVALID ?SECTION UNTRACKED ?SECTION NEW Ping(ACCEPT) all all ACCEPT lan $FW tcp ssh ----snat---- #ACTION SOURCE DEST PROTO PORT IPSEC MARK USER SWITCH ORIGDEST PROBABILITY MASQUERADE lan0 wan0 MASQUERADE lan0.70 wan0 MASQUERADE lan0.80 wan0 

PHs and PVM config omitted because I can't even get the two ends of the WG tunnel to talk yet.

3

1 Answer

The problem I'm facing is that I can't send/receive ping or ssh (or any traffic that I've tried) across the Wireguard tunnel (just from one end of the tunnel to the other), suggesting I have some configuration wrong.

The tutorial that you're following designates a /24 for the WireGuard network. It configures each endpoint's wg0 interface with a /32 prefix, then manually defines a route for the remaining /24, which is an (unnecessarily) verbose equivalent of just configuring the actual address as a /24 prefix.

Either way, the tutorial's configuration leads to each peer having a direct route to the other peer's address – the client knows that 10.213.213.2 (the server) is reachable through wg0 because it matches the 10.213.213.0/24 route. In other words, it works pretty much like a normal /24 subnet.

However, when you adapted the tutorial to your configuration, you only kept the /32 address assignment but did not keep the /24 route for the remaining WireGuard range. As a result, whenever your client tries to ping 10.10.10.1 (the server), the only matching route it has (in main table) is "default via 71.71.71.1 dev wan0" – not leading anywhere useful.

Both your server and your client should have:

 [Network] Address = 10.10.10.2/32 [Route] # It is normally pointless to specify a gateway for one's own subnet, and it's also # pointless to specify a gateway when routing through a "layer-3 tunnel" interface # such as tun0 or wg0. #Gateway = 10.10.10.1 Destination = 10.10.10.0/24 #GatewayOnlink = true 

or alternatively:

 [Network] Address = 10.10.10.2/24 

After configuring everything, ip route get 10.10.10.2 on the server should be choosing wg0 as the nexthop interface, and likewise on the client.


You shouldn't have specified the 44.44.44.0/27 network there – it's a separate thing from the the WireGuard subnet. Because you want to route it through the client, it only needs a custom route on your server (in addition to the above):

 [Route] # You can specify the client as gateway, technically, but it'll mean nothing # because wg0 is a "layer-3" interface and the gateway field only influences # layer-2 addressing. Instead, WireGuard uses the "AllowedIPs" parameter to # choose which peer to send the packets to. #Gateway = 10.10.10.2 Destination = 44.44.44.0/27 

On the client, 44.44.44.0/27 should be routed through your VM bridge interface, not through WireGuard.

On the server, depending on how your datacenter's gateway is configured, the 44.44.44.0/27 prefix might be either routed through one of your server's other IP addresses (in which case everything is fine), or it might be configured as an "on-link" prefix (in which case you'll need to set up Proxy-ARP on the server).


  • ip route get 10.10.10.2
  • ip route show match 10.10.10.2
  • echo "module wireguard +p" > /sys/kernel/debug/dynamic_debug/control
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like