Building Safe Remote Homelab Access with WireGuard

· Rack Notes


Remote access should create a narrow, authenticated path into the homelab—not publish every management interface to the internet. WireGuard provides a small VPN building block, but the surrounding routing, firewall, keys, and recovery process determine whether the result is safe.

This example connects one roaming laptop to a dedicated Linux gateway. It uses documentation ranges and placeholder keys. Adapt interface names and firewall commands to the actual platform.

Define the access boundary #

Decide what the remote peer needs before generating configuration. A laptop may need SSH to two servers and HTTPS to internal applications. It probably does not need access to every client, storage interface, and switch management page.

Choose a separate tunnel subnet, such as 198.51.100.0/24, that does not overlap the home LAN, common hotel networks, or other VPNs. In the example, the gateway uses 198.51.100.1 and the laptop uses 198.51.100.10.

The home router forwards one UDP port to the WireGuard gateway. Do not forward Proxmox, SSH, or application ports alongside it. If the internet connection is behind carrier-grade NAT, inbound forwarding may not be possible; a small external relay or an overlay service is then a different architecture, not a firewall workaround.

Generate keys on each peer #

Create each private key on the device that will use it and protect the output:

1umask 077
2wg genkey | tee privatekey | wg pubkey > publickey

The private key stays on that peer. Exchange only public keys. Do not paste real keys into tickets, documentation, or shell history. The placeholders below are labels, not valid WireGuard key material.

Configure the gateway #

A basic /etc/wireguard/wg0.conf on the home gateway can look like this:

1[Interface]
2Address = 198.51.100.1/24
3ListenPort = 51820
4PrivateKey = GATEWAY_PRIVATE_KEY
5
6[Peer]
7PublicKey = LAPTOP_PUBLIC_KEY
8AllowedIPs = 198.51.100.10/32

On the gateway, AllowedIPs associates the laptop's public key with exactly one tunnel address. Giving two peers the same address creates ambiguous routing.

Enable forwarding through the operating system's persistent configuration, not only with a temporary command. Then add firewall rules that allow the WireGuard UDP port from the internet and permit only the intended traffic from wg0 to the lab network. The exact syntax depends on nftables, firewalld, a router appliance, or cloud firewall policy.

A policy sketch is more portable than a copy-paste firewall blob:

1allow UDP 51820 from internet to WireGuard gateway
2allow 198.51.100.10 to 192.0.2.31 TCP 22
3allow 198.51.100.10 to 192.0.2.80 TCP 443
4deny other traffic from WireGuard tunnel to internal networks

Return traffic needs a route back to the tunnel subnet. The clean option is a static route on the lab router pointing 198.51.100.0/24 to the WireGuard gateway's LAN address. Masquerading on the gateway is an alternative when the router cannot add routes, but internal systems then see all VPN traffic as the gateway rather than the actual peer address.

Configure the roaming client #

The laptop configuration identifies the gateway and selects which destinations enter the tunnel:

 1[Interface]
 2Address = 198.51.100.10/32
 3PrivateKey = LAPTOP_PRIVATE_KEY
 4DNS = 192.0.2.53
 5
 6[Peer]
 7PublicKey = GATEWAY_PUBLIC_KEY
 8Endpoint = vpn.example.net:51820
 9AllowedIPs = 198.51.100.0/24, 192.0.2.0/24
10PersistentKeepalive = 25

This is a split tunnel: only the VPN and lab networks use WireGuard. A full tunnel would include the default routes and would require deliberate internet forwarding and DNS behavior on the gateway.

PersistentKeepalive = 25 is useful for a roaming peer behind NAT that must remain reachable after idle periods. It is not required for every peer; omit it when ordinary traffic maintains the mapping or the peer does not need inbound reachability.

The broad 192.0.2.0/24 route makes the example readable, but routing does not replace firewall policy. Narrow it to specific subnets when possible and enforce the actual service permissions at the gateway.

Bring up and inspect the tunnel #

On a system using wg-quick, start the interface with:

1sudo wg-quick up wg0
2sudo wg show

wg show reports configured peers, the latest handshake, endpoints, and traffic counters. A recent handshake proves that encrypted packets were exchanged; it does not prove that forwarding, DNS, and internal firewall policy are correct.

Test in layers:

  1. Reach the gateway's tunnel address.
  2. Reach one explicitly allowed internal address by IP.
  3. Resolve an internal DNS name through the intended resolver.
  4. Open the allowed service.
  5. Confirm that a forbidden management address or port remains unreachable.

Run the test from a genuinely external network, such as a phone hotspot. Testing from the home Wi-Fi can hide router hairpin and DNS differences.

Diagnose common partial failures #

No handshake usually points to the endpoint, port forwarding, public firewall, or keys. A handshake with no internal connectivity usually points to forwarding, routes, or firewall policy. Working IP connections with failed names point to DNS distribution or access. Separating those layers prevents random edits to a configuration that may already be correct.

Path MTU problems are less obvious. Small pings may work while larger HTTPS or SSH transfers stall because encapsulated packets exceed a link's usable size. Confirm the path and adjust the WireGuard interface MTU only when evidence shows fragmentation or black-hole behavior. A smaller value copied from a forum can hide the symptom while wasting capacity on every healthy path.

On Linux, these read-only checks provide a useful snapshot:

1ip address show dev wg0
2ip route get 192.0.2.31
3sudo wg show

The route lookup confirms which interface the kernel chose. Compare counters before and after one test instead of assuming that a configured peer is active.

Decide how DNS should behave #

The client's DNS setting is convenient, but operating systems differ in how they combine interface-specific resolvers. A split tunnel ideally sends only the private zone to the lab resolver while leaving public lookups on the local network. Some clients instead replace the resolver for the duration of the tunnel.

Test both private and public names, and decide what should happen when the lab resolver is unavailable. Sending every query home increases privacy from the local network but makes browsing depend on the tunnel. Sending only the private zone reduces that dependency but requires split-DNS support on the client.

Maintain the gateway #

The VPN gateway is an internet-facing system even though it exposes a small surface. Keep its operating system and WireGuard tools updated, restrict administrative access, back up the minimal configuration, and monitor failed service starts after reboot. Confirm the UDP forward after replacing the home router or changing its address reservation.

Review peers periodically. Remove devices that no longer exist and rotate a key when its private half may have been copied or exposed. Routine rotation for its own sake can create more distribution risk than it removes, so make revocation simple and use it when the credential's trust changes.

Handle endpoints and changing addresses #

Most residential connections do not have a permanent public address. Publish a dynamic DNS name and place that name in Endpoint. WireGuard resolves it while bringing up the interface, but clients may need to reconnect after a long-lived endpoint address changes.

The server does not need an Endpoint for a roaming client. It learns the client's current source after authenticated traffic arrives. This roaming behavior is one of WireGuard's useful properties.

Operate keys like credentials #

Give each device its own key pair and peer entry. Shared client keys make it impossible to revoke one lost device without interrupting the others. Name peer records in the surrounding inventory, since WireGuard itself identifies peers by public key.

When a device is lost, remove its peer from the gateway and reload the configuration. When a gateway key changes, distribute the new public key to every client through a trusted channel. Keep a local-console recovery path in case an incorrect firewall rule blocks remote administration.

Back up the gateway configuration securely, but consider whether private keys belong in the same general backup as application data. Whatever the decision, document how an authorized operator recovers or replaces them.

Monitor without collecting secrets #

Monitor interface state, handshake age for expected always-on peers, and tunnel traffic. Never export private keys. A laptop may be offline for days, so alerting on its handshake age would be noise; a site-to-site peer needs a different threshold.

Review firewall logs for denied tunnel traffic during setup, then reduce noisy logging once policy is stable. Logs should help explain a failure without recording application payloads.

WireGuard keeps the cryptographic tunnel intentionally small. A safe remote access design keeps everything around it equally understandable: one exposed UDP port, one key per device, explicit routes, restrictive firewall policy, and a tested revocation and recovery procedure.

last updated: