WireGuard topologies for self-hosting at home September 23, 2025 Contents I recently migrated my self-hosted services from a VPS (virtual private server) at a remote data center to a physical server at home. This change was motivated by wanting to be in control of the hardware and network where said services run, while trying to keep things as simple as possible. What follows is a walk-through of how I reasoned through different WireGuard toplogies for the VPN (virtual private network) in which my devices and services reside. Before starting, it’s worth emphasizing that using WireGuard (or a VPN altogether) is ont strictly required for self-hosting. WireGuard implies one more moving part in your system, the cost of which is justified only by what it affords you to do. The constraints that I outline below should provide clarity as to why using WireGuard is appropriate for my needs. It goes without saying that not everyone has the same needs, resources, and threat model, all of which a design should account for. That said, there isn’t anything particularly special about what I’m doing. There is likely enough overlap here for this to be useful to individuals or small to medium-sized organizations looking to host their services. I hope that this review helps others build a better mental model of WireGuard, and the sorts of networks that you can build up to per practical considerations. Going through this exercise proved to be an excellent learning experience, and that is worthwhile on its own. This post assumes some familiarity with networking. This is a subject in which acronyms are frequently employed, so I’ve made sure to spell these out wherever introduced. Constraints The constraints behind the design of my network can be categorized into first-order and second-order constraints. Deploying WireGuard responds to the first-order constraints, whereas the specifics of how WireGuard is deployed responds to the second-order constraints. First-order constraints There should be no dependencies to services or hardware outside of the physical network. I should be able to connect to my self-hosted services while I’m at home as long as there’s electricity in the house and the hardware involved is operating without problems. Borrow elements of the Zero Trust Architecture where appropriate. Right now that means treating all of my services and devices as resources, securing all communications (i.e not trusting the underlying network), and enforcing least-privileged access. Provisions made to connect to a device from outside the home network should be secondary and optional. While I do wish to use to my services while I’m away, satisfying this should not compromise the fundamental design of my setup. For example, I shouldn’t rely on tunneling services provided by third-parties. Choosing to deploy WireGuard is motivated by constraints two and three. Constraint one is not sufficient on its own to necessitate using WireGuard because everything can run on the local area network (LAN). Once deployed, I should be able to connect all of my devices using hardware, software, and keys that I control within the boundaries of my home office. These devices all exist in the same physical network, but may reside in separate virtual LANs (VLANs) or subnets. Regardless, WireGuard is used to establish secure communications within and across these boundaries, while working in tandem with network and device firewalls for access control. I cannot connect to my home network directly from the wide area network (WAN, e.g the Internet) because it is behind Carrier-Grade Network Address Translation (CGNAT). A remote host is added to the WireGuard network to establish connections from outside. This host runs on hardware that I do not control, which goes against the spirit of the first constraint. However, an allowance is made considering that the role of this peer is not load-bearing in the overarching design, and can be removed from the network as needed. Second-order constraints Assuming WireGuard is now inherent in this design, its use should adhere to the following constraints: Use WireGuard natively as opposed to software that builds on top of WireGuard. I choose to favor simplicity and ease of understanding rather than convenience or added features, ergo, complexity. Use of a control plane should not be required. All endpoints are first-class citizens and managed individually, regardless of using a network topology that confers routing responsibilities to a given peer. Satisfying these constraints preclude the use of solutions such as Tailscale, Headscale, or Netbird. Using WireGuard natively has the added benefit that I can rely on a vetted and stable version as packaged by my Linux distribution of choice, Debian. Non-constraints Lastly, it is worth stating requirements or features that are often found in designs such as these, but that are not currently relevant to me. Mesh networking and direct peer-to-peer connections. It’s ok to have peers act as gateways if connections need to be established across different physical or logical networks. The size, throughput, and bandwidth of the network is small enough that prioritizing performance is not strictly necessary. Automatic discovery or key distribution. It’s ok for nodes in the network to be added or reconfigured manually. Resources Let’s look at the resources in the network, and how these connect with each other. Consider the following matrix. Each row denotes whether the resource in the first column connects to the resources in the remaining columns, either to consume a service or perform a task. For example, we can tell that the server does not connect to any device, but all devices connect to the server. Server Desktop Laptop Phone Tablet Server No No No No Desktop Yes Yes Yes No Laptop Yes Yes No No Phone Yes Yes No No Tablet Yes No No No Said specifically: The desktop computer connects to the server to access a calendar, git repositories, etc The tablet connects to the server to download RSS feeds The laptop and desktop connect with each other to sync files The purpose of this matrix is to determine which connections between devices ought to be supported, regardless of the network topology. This informs how WireGuard peers are configured, and what sort of firewall rules need to be established. Before proceeding, let’s define the networks and device IP addresses that will be used. Network Protocol Address Netmask Gateway LAN IPv4 192.168.1.0 255.255.255.0 192.168.1.1 WireGuard IPv4 10.55.2.0 255.255.255.0 - Device LAN IP address WireGuard IP address Desktop computer 192.168.1.6 10.55.2.11 Laptop 192.168.1.7 10.55.2.12 Phone 192.168.1.8 10.55.2.13 Tablet 192.168.1.9 10.55.2.14 Server 192.168.1.10 10.55.2.20 The name of the WireGuard network interface will be wg-home , where applicable. For purposes of this explanation, port 48192 will be used in all of the devices when a port needs to be defined. Topologies I’ll explore different topologies as I build to up to the design that I currently employ. By starting with the simplest topology, we can appreciate the benefits and trade-offs involved in each step, while strengthening our conceptual model of WireGuard. Each topology below is accompanied by a simple diagram of the network. In it, the orange arrow denotes a device connecting to another device. Where two devices connect to each other, a bidirectional arrow is employed. Later on, green arrows denote a device forwarding packets to and from other resources. Connecting all devices in the same physical network using point-to-point networking The basic scenario, and perhaps the most familiar to someone looking to start using WireGuard to self-host at home, is hosting in the network that is established by the router provided by an Internet service provider (ISP). Let’s assume its configuration has not been modified other than changing the Wi-Fi and admin passwords. A topology that can be used here is point-to-point, where each device lists every other device it connects to as its peer. In WireGuard terminology, “peers” are endpoints configured to connect with each other to establish an encrypted “tunnel” through which packets are sent and received. According to the connections matrix, the desktop computer and the server are peers, but the desktop computer and tablet aren’t. The WireGuard configuration for the desktop computer looks as follows: [Interface] Address = 10.55.2.11/32 ListenPort = 48192 PrivateKey = kJdAdg2G5sh+BcusDTPYv/nZOscXW5kuh5wILkOC63Q= # Server [Peer] PublicKey = 5vj58uZIALlPwhelXQilQgCY0jSN6iOpBZOcZj2shEU= AllowedIPs = 10.55.2.20/32 Endpoint = 192.168.1.10:48192 # Laptop [Peer] PublicKey = Aa+dFAg5CWQ3U/ZLJbxfhYiJcW9lJP+tuWZ0ElHuY14= AllowedIPs = 10.55.2.12/32 Endpoint = 192.168.1.7:48192 # Phone [Peer] PublicKey = Ri10a7gcZ+sbFc44HvZVOvpTqWydi6OYQWZMMzAo3Eo= AllowedIPs = 10.55.2.13/32 Endpoint = 192.168.1.8:48192 Note that the LAN IP address of each peer is specified under Endpoint . This is used to find the peer’s device and establish the WireGuard tunnel. AllowedIPs specifies the IP addresses used within the WireGuard network. In other words, the phone is the desktop’s peer, it can be found at 192.168.1.8:48192 to establish the tunnel. Let’s assume each of these devices have firewalls that allow UDP traffic through port 48192 and all subsequent traffic through the WireGuard wg-home interface. Once the WireGuard configurations of the server, laptop, and phone include the corresponding peers, secure communication is established through the WireGuard network interface. Let’s try sending a packet from the desktop computer to the phone. $ traceroute 10.55.2.13 traceroute to 10.55.2.13 ( 10.55.2.13 ) , 30 hops max, 60 byte packets 1 10.55.2.13 ( 10.55.2.13 ) 950.434 ms 950.550 ms 950.493 ms The packet was routed directly to the phone and echoed back. At this point access control is enforced in each device’s firewall. Allowing everything that comes through the wg-home interface is convenient, but it should be limited to the relevant ports and protocols for least-privileged access. Fixing an issue with moving targets An obvious problem with this scenario is that the Dynamic Host Configuration Protocol (DHCP) server in the router likely allocates IP addresses dynamically when devices connect to the LAN network. The IP address for a device may thus change over time, and WireGuard will be unable to find a peer to establish a connection to it. For example, I’m at home and my phone dies. The LAN IP address 192.168.1.8 is freed and assigned to another device that comes online. WireGuard will attempt to connect to 192.168.1.8 (per Endpoint ) and fail for any of the following reasons: Said device is not running WireGuard Said device is using a different Address or ListenPort , in which case the peer’s AllowedIPs or port in Endpoint does not match Said device is using a different PrivateKey , in which case the peer’s PublicKey does not match Fortunately, most routers support configuring static IP addresses for a given device in the network. Doing so for all devices in our WireGuard network fixes this problem as the IP address used in Endpoint will be reserved accordingly. Connecting from the outside Suppose I want to work at a coffee shop, but still need access to something that’s hosted on my home server. As mentioned in the constraints, my home network is behind CGNAT. This means that I cannot connect directly to it using whatever WAN IP address my router is using at the moment. What I can do instead is use a device that has a publicly routable IP address and make that a WireGuard peer of our server. In this case that’ll be a VPS in some data center. How is the packet ultimately relayed to and from the server at home? Both the server and laptop established direct encrypted tunnels with the VPS. WireGuard on the VPS will receive the encrypted packets from the laptop, decrypt them, and notice that they’re meant for the server. It will then encrypt these packets with the server’s key and send them through the server’s tunnel. It’ll do same thing with the server’s response, except towards the laptop using the laptop’s tunnel. A device that forwards packets between peers needs to be configured for IPv4 packet forwarding. I will not cover the specifics of this configuration because it depends on what operating system and firewall are used. Adding a remote peer The VPS has a public IP address of 162.231.77.9 , and its WireGuard IP address will be 10.55.2.2 . The laptop and server are listed as peers in its WireGuard configuration: [Interface] Address = 10.55.2.2/32 ListenPort = 48192 PrivateKey = wMKvhMa7BSJvRe9+t7fiymFMqcHlxeI64uhjoLEKPWo= # Server [Peer] PublicKey = 5vj58uZIALlPwhelXQilQgCY0jSN6iOpBZOcZj2shEU= AllowedIPs = 10.55.2.20/32 # Laptop [Peer] PublicKey = Aa+dFAg5CWQ3U/ZLJbxfhYiJcW9lJP+tuWZ0ElHuY14= AllowedIPs = 10.55.2.12/32 Note that Endpoint is omitted for each peer. The publicly routable IP addresses of the laptop and the home router are not known to us. Even if they were, they cannot be reached by the VPS. However, they will be known to the VPS when these connect to it. Now, the server at home adds the VPS as its peer, using the VPS public IP address as its Endpoint : # VPS [Peer] PublicKey = 7vXZGWpHp1PimrlbvwQ3sEOFUPx+1kq8Fdq4dv950m0= AllowedIPs = 10.55.2.2/32 Endpoint = 162.231.77.9:48192 PersistentKeepalive = 25 We also make use of PersistentKeepalive to send an empty packet every 25 seconds. This is done to establish the tunnel ahead of time, and to keep it open. This is necessary because otherwise the tunnel may not exist when I’m at the coffee shop trying to access the server at home. Remember, the VPS doesn’t know how to reach the server unless the server is connected to it. Routing packets through the remote peer Let’s take a careful look at the laptop’s configuration, and what we’re looking to achieve. When the laptop is at home, it connects to the server using an endpoint address that is routable within the home LAN network. This endpoint address is not routable when I’m outside, in which case I want the connection to go through the VPS. To achieve this, the laptop maintains two mutually-exclusive WireGuard interfaces: wg-home and wg-remote . The former is active only while I’m in the home network, and the latter while I’m on the go. Unlike the server, the VPS does not need to be added as a peer to the laptop’s wg-home interface because it doesn’t need connect to it while at home. Instead, the VPS is added to the wg-remote configuration: [Interface] Address = 10.55.2.12/32 PrivateKey = EAuj44uBRPWyV6d9I4NKT8WmRQP+a73X/ce+58ZrPVs= # VPS [Peer] PublicKey = 7vXZGWpHp1PimrlbvwQ3sEOFUPx+1kq8Fdq4dv950m0= AllowedIPs = 10.55.2.2/32, 10.55.2.20/32 Endpoint = 162.231.77.9:48192 The [Interface] section for both wg-home and wg-remote is mostly the same. The laptop should have the same adress and key, regardless of where it is. Only ListenPort is omitted in wg-remote because no other device will look to connect to it, in which case we can have WireGuard set a port dynamically. What differs is the peer configuration. In wg-remote the VPS is set as the only peer. However, the home server’s IP address 10.55.2.20 is added to the VPS’ list of AllowedIPs . WireGuard uses this information to route any packets for the VPS or the server through the VPS. Unlike the server’s peer configuration for the VPS, PersistentKeepalive is not needed because the laptop is always the one initiating the tunnel when it reaches out to the server. We can verify that packets are being routed appropriately to the server through the VPS: $ traceroute 10.55.2.20 traceroute to 10.55.2.20 ( 10.55.2.20 ) , 30 hops max, 60 byte packets 1 10.55.2.2 ( 10.55.2.2 ) 314.556 ms 314.482 ms 314.469 ms 2 10.55.2.20 ( 10.55.2.20 ) 320.954 ms 320.821 ms 320.870 ms Introducing hub-and-spoke We solved for outside connectivity using a network topology called hub-and-spoke. The laptop and home server are not connecting point-to-point. The VPS acts as a hub or gateway through which connections among members of the network (i.e the spokes) are routed. If we scope down our network to just the laptop and the home server, we see how this hub is not only a peer of every spoke, but also just its only peer. Yet, how exactly is the packet routed back to the laptop? Mind you, at home the laptop is a peer of the server. When the server responds to the laptop, it will attempt to route the response directly to the laptop’s peer endpoint. This fails because the laptop is not actually reachable via that direct connection when I’m on the go. This makes the laptop a “roaming client”; it connects to the network from different locations, and its Endpoint may change. This all works because the hub has been configured to do Network Address Translation (NAT); it is replacing the source address of each packet for its own as it is being forwarded. The spokes at end of each hub accept the packets because they appear to originate from its peer. In other words, when the laptop is reaching out to the home server, the server sees traffic coming from the VPS and returns it there. The hub is forwarding packets among the spokes without regards to access control. Thus, its firewall should be configured for least-privilege access. For example, if the laptop is only accessing git repositories in the home server over SSH, then the hub firewall should only allow forwarding from the laptop’s peer connection to the home server’s IP address and SSH port. Let’s reiterate. If I now wish to sync my laptop with my desktop computer from outside the network, I would be adding yet another spoke to this hub. The desktop computer and the VPS configure each other as peers, while the desktop’s IP address is included in the VPS’ AllowedIPs list of the laptop’s wg-remote configuration. + AllowedIPs = 10.55.2.2/32, 10.55.2.20/32, 10.55.2.11/32 - AllowedIPs = 10.55.2.2/32, 10.55.2.20/32 Rethinking the home network topology Our topology within the home network is still point-to-point. As soon as I return home, my laptop will connect directly to the server when I toggle wg-remote off and wg-home on. But now that we know about hub-and-spoke, it might make sense to consider using it at home as well. According to the connection matrix, the server can assume the role of a hub because all other devices already connect to it. Likewise, the server runs 24/7, so it will always be online to route packets. This topology simplifies the WireGuard configurations for all of the spokes. The desktop computer, phone, laptop, and tablet can now list the server as its only peer in wg-home . This is convenient because now only one static address in the LAN network needs to be allocated by the DHCP server – the server’s. Consider the changes to the WireGuard configuration of the desktop computer. [Interface] Address = 10.55.2.11/32 ListenPort = 48192 PrivateKey = kJdAdg2G5sh+BcusDTPYv/nZOscXW5kuh5wILkOC63Q= # Server [Peer] PublicKey = 5vj58uZIALlPwhelXQilQgCY0jSN6iOpBZOcZj2shEU= - AllowedIPs = 10.55.2.20/32 + AllowedIPs = 10.55.2.20/32, 10.55.2.12/32, 10.55.2.13/231 Endpoint = 192.168.1.10:48192 - - # Laptop - [Peer] - PublicKey = Aa+dFAg5CWQ3U/ZLJbxfhYiJcW9lJP+tuWZ0ElHuY14= - AllowedIPs = 10.55.2.12/32 - Endpoint = 192.168.1.7:48192 - - # Phone - [Peer] - PublicKey = Ri10a7gcZ+sbFc44HvZVOvpTqWydi6OYQWZMMzAo3Eo= - AllowedIPs = 10.55.2.13/32 - Endpoint = 192.168.1.8:48192 - -# VPS -[Peer] -PublicKey = 7vXZGWpHp1PimrlbvwQ3sEOFUPx+1kq8Fdq4dv950m0= -AllowedIPs = 10.55.2.2/32 -Endpoint = 162.231.77.9:48192 All peers are removed except the server, and the IPs of the phone and laptop are added to the server’s of AllowedIPs . WireGuard will route packets for these other hosts through the server. We could also use Classless Inter-Domain Routing (CIDR) notation to state that packets for all hosts in the WireGuard network go through the server peer: + AllowedIPs = 10.55.2.0/24 - AllowedIPs = 10.55.2.20/32, 10.55.2.12/32, 10.55.2.13/231 The server, in turn, keeps listing every device at home as its peer but no longer needs an Endpoint for each. The peers will initiate the connection to the server. [Interface] Address = 10.55.2.20/32 ListenPort = 48192 PrivateKey = qFu8xkaA69wnX8aWURUUNAf9Ll1yU8RvjXczCiXbMGM= # Desktop [Peer] PublicKey = doTWOdYC8hwpKVrc6tK4UHEXspO4CuajPORLHOeri2c= AllowedIPs = 10.55.2.11/32 - Endpoint = 192.168.1.6:48192 # Laptop [Peer] PublicKey = Aa+dFAg5CWQ3U/ZLJbxfhYiJcW9lJP+tuWZ0ElHuY14= AllowedIPs = 10.55.2.12/32 - Endpoint = 192.168.1.7:48192 # Phone [Peer] PublicKey = Ri10a7gcZ+sbFc44HvZVOvpTqWydi6OYQWZMMzAo3Eo= AllowedIPs = 10.55.2.13/32 - Endpoint = 192.168.1.8:48192 # Tablet [Peer] PublicKey = dcRjeKjoDujcH/Ziy4stHIzCXSr+tlaeeyP6IEcc+EY= AllowedIPs = 10.55.2.14/32 - Endpoint = 192.168.1.9:48192 # VPS [Peer] PublicKey = 7vXZGWpHp1PimrlbvwQ3sEOFUPx+1kq8Fdq4dv950m0= AllowedIPs = 10.55.2.2/32, 10.55.2.20/32 Endpoint = 162.231.77.9:48192 Once again, let’s test sending a packet from the desktop computer to the phone. $ traceroute 10.55.2.13 traceroute to 10.55.2.13 ( 10.55.2.13 ) , 30 hops max, 60 byte packets 1 10.55.2.20 ( 10.55.2.20 ) 1.190 ms 1.328 ms 1.528 ms 2 10.55.2.13 ( 10.55.2.13 ) 49.954 ms 50.142 ms 50.104 ms The packet was hops once through the server ( 10.55.2.20 ), is received by the phone, and is echoed back. The downside to this topology is that the server is now a single point of failure. If the server dies then the spokes won’t be able to connect with each other through WireGuard. There’s also an added cost to having every packet flow through the hub. As for access control, much like we saw in the VPS, the hub now concentrates firewalling responsibilities. It knows which peer is looking to connect to which peer, thus it should establish rules for which packets can be forwarded. This is not mutually exclusive with input firewall rules on each device; those should exist as well. Two hubs and one compromise We’ve seen that home hub will route packets between the spokes. Furthermore, because it is peer of the VPS, the server can be used to route connections coming from outside the LAN network. Effectively, these are two hubs that connect to each other so that packets can flow across separate physical networks. If the laptop wants to sync with the desktop while it is outside the LAN network, then the packets make two hops: once through the VPS, and another through the server. If the laptop is within the LAN network, the packets hop only once through the server. Yet, there’s a subtle caveat to this design. The laptop can initiate a sync with the desktop from outside the LAN network and receive the response that it expects. However, the desktop can only initiate a sync with the laptop while the latter is within the LAN network. Why? Similar to our previous example of the laptop communicating with the server, the laptop is configured as a peer of the home hub. When the desktop initiates a sync, the server will attempt to route the packet to the laptop. Per our last change, the laptop doesn’t have a fixed Endpoint and there is no established tunnel because the laptop is outside the network. Additionally, the home hub is not configured to route packets destined for the laptop through the VPS peer. The packet is thus dropped by the hub. One could look into making the routing dynamic such that the packets are delivered through other means, perhaps through mesh networking. But herein lies a compromise that I’ve made. In this design, a spoke in the home hub cannot initiate connections to a roaming client. It can only receive connections from them, because the roaming client uses NAT through the remote hub. I’m perfectly fine with this compromise as I don’t actually need this bidirectionality, and I don’t want the additional complexity from solving this issue. The remote hub facilitates tunneling into the home hub, not out of. My needs call for allowing my mobile devices (e.g laptop, phone, tablet) to communicate with the non-mobile devices at home (e.g server, desktop), and this has been solved. Reconsidering the hub at home At this point we’re done insofar the overarching topology of our WireGuard network, but there is an improvement that can be made to make our home hub less brittle. Consider the case where I’m using a router that can run WireGuard. Making the router the hub of our home network poses some benefits over the previous setup. First, the router is already a single point of failure by way of being responsible for the underlying LAN network. Making the router the hub isn’t as costly as it is with some other device in the network. Second, all devices in the network are already connected to the router. This simplifies the overall configuration because it is no longer necessary to configure static IP addresses in the DHCP server. Instead, each spoke can use the network gateway address to reach the hub. Let’s the assume that the gateway for the LAN network is 192.168.1.1 , and the WireGuard IP address for the router is 10.55.2.1 . Each spoke replaces the server peer with the router’s, and uses the gateway address for its Endpoint . For example, in the desktop computer: [Interface] Address = 10.55.2.11/32 ListenPort = 48192 PrivateKey = kJdAdg2G5sh+BcusDTPYv/nZOscXW5kuh5wILkOC63Q= + # Router + [Peer] + PublicKey = bGDvNVfFvSsZtku3vXZx2xzgLIC8mtfQLCfcVy/gajs= + AllowedIPs = 10.55.2.0/24 + Endpoint = 192.168.1.1:48192 - # Server - [Peer] - PublicKey = 5vj58uZIALlPwhelXQilQgCY0jSN6iOpBZOcZj2shEU= - AllowedIPs = 10.55.2.0/24 - Endpoint = 192.168.1.10:48192 The server is demoted to a spoke and is configured like all other spokes. In turn, the router lists all peers like the server previously did: [Interface] Address = 10.55.2.1/32 ListenPort = 48192 PrivateKey = UN8CdQKylNzjP7LpB+nSmMoeBxvmPtvtDKG2RylZZ10= # Server [Peer] PublicKey = 5vj58uZIALlPwhelXQilQgCY0jSN6iOpBZOcZj2shEU= AllowedIPs = 10.55.2.20/32 # Desktop [Peer] PublicKey = doTWOdYC8hwpKVrc6tK4UHEXspO4CuajPORLHOeri2c= AllowedIPs = 10.55.2.11/32 # Laptop [Peer] PublicKey = Aa+dFAg5CWQ3U/ZLJbxfhYiJcW9lJP+tuWZ0ElHuY14= AllowedIPs = 10.55.2.12/32 # Phone [Peer] PublicKey = Ri10a7gcZ+sbFc44HvZVOvpTqWydi6OYQWZMMzAo3Eo= AllowedIPs = 10.55.2.13/32 # Tablet [Peer] PublicKey = dcRjeKjoDujcH/Ziy4stHIzCXSr+tlaeeyP6IEcc+EY= AllowedIPs = 10.55.2.14/32 # VPS [Peer] PublicKey = 7vXZGWpHp1PimrlbvwQ3sEOFUPx+1kq8Fdq4dv950m0= AllowedIPs = 10.55.2.2/32, 10.55.2.20/32 Endpoint = 162.231.77.9:48192 Again, the firewall in the router is now responsible for enforcing access control between spokes. Our final design For the sake of illustrating how much further the underlying networks can evolve without interfering with the WireGuard network, consider the final design. I’ve broken apart the LAN network into separate VLANs to isolate network traffic. The server resides in its own VLAN, and client devices in another. The router keeps on forwarding packets in WireGuard network regardless of where these devices are. The only change that is necessary to keep things working is to update Endpoint address for the router peer in each spoke. The spoke now uses the corresponding VLAN gateway address, rather than that of the LAN network: [Interface] Address = 10.55.2.11/32 ListenPort = 48192 PrivateKey = kJdAdg2G5sh+BcusDTPYv/nZOscXW5kuh5wILkOC63Q= # Router [Peer] PublicKey = bGDvNVfFvSsZtku3vXZx2xzgLIC8mtfQLCfcVy/gajs= AllowedIPs = 10.55.2.1/32, 10.55.2.0/24 + Endpoint = 10.2.0.1:48192 - Endpoint = 192.168.1.1:48192 Parting thoughts I’ve been using this setup for some months now and it’s been working without issues. A couple of thoughts come to mind having gone through this exercise and written about it. Running WireGuard on the router simplifies things considerably. If the home network were not behind CGNAT then I could do away with the VPS hub altogether. I would still need separate WireGuard interfaces for when I’m on the go, but that’s not a big deal. Nonetheless, within the LAN network, configuration is simpler by using a hub-and-spoke topology with the router as hub. Centralizing access control on the router’s firewall is also appreciated. WireGuard is simple to deploy and it just works. Nonetheless, some knowledge of networking is required to think through how to deploy WireGuard appropriately for a given context. Being comfortable with configuring interfaces and firewalls is also necessary to troubleshoot the inevitable connectivity issues. One can appreciate why solutions that abstract over WireGuard exist. I used Tailscale extensively before this and did not have think through things as much as I did here. This was all solved for me. I just had to install the agent on each device, authorize it, and suddenly packets moved securely and efficiently across networks. And yet, WireGuard was there all along and I knew that I could unearth the abstraction. Now I appreciate its simplicity even more, and take relish in having a stronger understanding of what I previously took for granted. Lastly, I purposefully omitted other aspects of my WireGuard setup for self-hosting, particularly around DNS. This will be the subject of another article, which is rather similar to the one I wrote on using Tailscale with custom domains. Furthermore, a closer look at access control in this topology might be of interest to others considering that there are multiple firewalls that come into play. Further reading