Keys, two config files, one forwarded UDP port and a routing setting get a laptop onto a home network. A tutorial, plus a plain-language look at cryptokey routing and AllowedIPs.
Two short text files, one open UDP port, and a handful of commands. That is the shape of a WireGuard link between a laptop on the road and a machine at home, and it is a fair summary of the project’s own pitch: the WireGuard site says it aims to be “as easy to configure and deploy as SSH.”
The tutorial below follows the structure of Ubuntu’s official guide for reaching a network through an internal system, with the keys, config files, forwarding setting and router rule it prescribes. After it comes a plain-language explanation of cryptokey routing, the idea that makes the two files so short. Any always-on Linux machine can play the home role; the Raspberry Pi home server guide shows one way to prepare it.
What you need
- A Linux machine on the home network that stays on, called the home peer here.
- A device to connect from, called the remote peer.
- Access to the router, to forward one UDP port.
- A way for the remote peer to find home: a public IP address or a hostname. The
Endpointfield accepts either.
Installation is one package. The WireGuard install page lists sudo apt install wireguard for Ubuntu and apt install wireguard, run as root, for Debian.
Step 1: Generate a key pair on each peer
Keys come from two commands in the quickstart. Setting umask 077 first keeps the private key readable only by its owner. Run this on the home peer, then repeat on the remote peer with its own file names.
umask 077
wg genkey > internal-private.key
wg pubkey < internal-private.key > internal-public.key
The private key never leaves the machine that made it. Only the public key is copied to the other side.
Step 2: Configure the home peer
Ubuntu’s guide (internal system walkthrough) places the file at /etc/wireguard/wg0.conf. Its sample uses port 51000, the home peer at 10.10.10.10, and 10.10.10.0/24 as the home network; substitute your own ranges. The remote peer gets an address inside that range, 10.10.10.11, and the file lists no endpoint for it because its location is not known in advance.
[Interface]
Address = 10.10.10.10/32
ListenPort = 51000
PrivateKey = <contents of internal-private.key>
[Peer]
# laptop
PublicKey = <contents of laptop-public.key>
AllowedIPs = 10.10.10.11/32
Because the remote peer’s address sits inside the home network, the guide adds a routing file so the home peer can pass traffic along. It enables forwarding and proxy ARP, which answers ARP requests on behalf of the VPN systems. Create /etc/sysctl.d/70-wireguard-routing.conf with these two lines:
net.ipv4.ip_forward = 1
net.ipv4.conf.all.proxy_arp = 1
Apply it without a reboot, then bring the interface up. The config file is found by interface name, so wg0 loads /etc/wireguard/wg0.conf.
sudo sysctl -p /etc/sysctl.d/70-wireguard-routing.conf -w
sudo wg-quick up wg0
Both config files hold a private key, so the guide restricts them to root with chmod 0600 and chown root:.
Step 3: Configure the remote peer
The remote side mirrors the first file but adds an endpoint, since this is the peer that knows where to dial. In the guide it lives at /etc/wireguard/home0.conf.
[Interface]
ListenPort = 51000
Address = 10.10.10.11/24
PrivateKey = <contents of the remote private key>
[Peer]
PublicKey = <contents of internal-public.key>
Endpoint = <home-ip-or-hostname>:51000
AllowedIPs = 10.10.10.0/24
sudo wg-quick up home0
To confirm the tunnel is alive, run wg or wg show. Per the quickstart, calling wg with no arguments does the same as wg show on all interfaces.
Port forwarding, NAT and keepalives
The router needs one rule. The guide says to forward all 51000/udp traffic to the home peer, 10.10.10.10, on the same port, and to confirm that the router’s firewall allows inbound 51000/udp. WireGuard sends everything over UDP, so a rule for TCP will not help.
Router menus differ widely, and a mesh system may hide port forwarding inside its app; the mesh Wi-Fi guide is a starting point for finding the controls. Whatever the brand, the two things to get right are the protocol (UDP) and the destination (the home peer’s fixed address).
A peer behind NAT or a stateful firewall can lose its mapping when traffic goes quiet. The remedy is PersistentKeepalive, an interval in seconds between 1 and 65535 at which an authenticated empty packet is sent. It is off by default. The quickstart calls 25 seconds “a sensible interval that works with a wide variety of firewalls” (quickstart). Add PersistentKeepalive = 25 to the peer entry that needs it.
Home addresses change. Because Endpoint takes a hostname as well as an IP, a dynamic DNS name can stand in for a fixed address. The sources fetched for this guide do not cover dynamic DNS setup or ISP address sharing, so check with the provider if the home connection does not have a reachable public address.
Cryptokey routing, in plain language
WireGuard folds peer identity and routing into one list. Each interface has a private key and a list of peers, and each peer is a public key plus a list of allowed IP addresses. The project calls the result a Cryptokey Routing Table: “the simple association of public keys and allowed IPs” (cryptokey routing).
That one list is used twice. Going out, it works as a routing table: the destination address of a packet is matched against each peer’s allowed IPs, and the packet is encrypted to the matching peer’s key and sent to that peer’s latest endpoint. Coming in, it works as an access list. A packet that decrypts and authenticates is accepted only if its source address falls inside the sending peer’s allowed IPs; otherwise it is dropped.
Read the two sample files above with that in mind. On the home peer, AllowedIPs = 10.10.10.11/32 means the laptop can send as that one address and nothing else, and anything addressed to it goes to the laptop’s key. On the remote peer, AllowedIPs = 10.10.10.0/24 sends the whole home range through the tunnel. A value of 0.0.0.0/0 matches every IPv4 address and would route all traffic home, a choice the Ubuntu guide treats separately as a default-gateway setup.
There is also a roaming consequence. The endpoint of a peer, per the manual, “will be updated automatically to the most recent source IP address and port” of authenticated packets from it. That is why the home side needs no endpoint line for a laptop that changes networks.
Why it is small and fast
The following comes from the project’s own materials, so it describes the authors’ design goals rather than independent measurements. WireGuard says it is “meant to be easily implemented in very few lines of code” and “intends to be considerably more performant than OpenVPN.” It lives inside the Linux kernel, and it uses a fixed set of modern primitives: ChaCha20 with Poly1305 for authenticated encryption, Curve25519 for key agreement, BLAKE2s for hashing, SipHash24 for hashtable keys and HKDF for key derivation (protocol page).
Two documented traits stand out. The primitive list is short and fixed, which fits the stated goal of a small code base (that link between the two is an inference, not something the authors spell out). And the protocol is quiet: the protocol page describes a server that stays “silent and invisible” to unauthorized clients and allocates no state for unauthenticated messages. Everything travels over UDP.
If the tunnel will not come up
Nothing in the sources above promises a diagnosis from one symptom, so treat this as a checklist built from the steps already covered rather than a troubleshooting guarantee.
- Each side holds its own private key and the other side’s public key. Swapping a public and private key between files is an easy slip.
- The router forwards UDP, not TCP, on the same port the home peer lists under
ListenPort, and points at the home peer’s fixed address. - The
Endpointon the remote peer matches the home network’s current public address or hostname. AllowedIPson each side covers the addresses the other side will send from, since packets outside the list are dropped on arrival.- The sysctl file was applied on the home peer, so forwarding is on.
The tunnel protects traffic between peers. It does not protect accounts on the services behind it, so passwords and sign-ins still deserve the basics in the two-factor authentication guide.
