Skip to content
Saphira Linux

VPN

Saphira Linux vpnDragon

Run WireGuard on infrastructure you control, connect your devices to it, and remove the unnecessary mystery from secure remote connectivity.

In testing, functionality present — helpers missing
Saphira Linux vpnDragon, the WireGuard VPN mascot

Keys, interfaces and peers

Each WireGuard interface has one private key and a derived public key. A [Peer] identifies the other end by its public key. The [Interface] section describes the local end: its addresses, private key and optional listening port. A [Peer] describes a remote end: its public key, the addresses and networks reachable through it, and, for a client, the server endpoint.

AllowedIPs is especially important. It is both WireGuard's map of which peer owns which tunnel addresses or routed networks and, on a wg-quick client, a route selection. On the server, give every peer precise addresses or prefixes; do not use an overly broad range that overlaps another peer. On a client, choose only the networks that should use the tunnel, or deliberately use 0.0.0.0/0 and ::/0 when your design calls for a full tunnel.

Forwarding and nftables

A peer-to-peer tunnel needs only WireGuard's UDP port allowed in. Reaching a LAN, another routed network or the Internet through the server also requires IP forwarding and an explicit nftables forwarding policy. Enable forwarding deliberately rather than assuming a VPN may route everywhere.

# Enable forwarding now; make the equivalent sysctl setting persistent
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1

# Inspect the active nftables policy before changing it
nft list ruleset

Integrate rules with your existing nftables configuration rather than replacing its complete ruleset. Adapt the public interface name, addresses and permitted destinations to your machine. This minimal example accepts WireGuard's endpoint and permits traffic from wg0 only to an internal LAN; return traffic is allowed by the established/related rule.

table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    iifname "lo" accept
    udp dport 51820 accept
  }

  chain forward {
    type filter hook forward priority filter; policy drop;
    ct state established,related accept
    iifname "wg0" oifname "lan0" ip daddr 192.168.50.0/24 accept
  }
}
NoteIf VPN clients need IPv4 Internet access through the server, add a carefully scoped postrouting masquerade rule on the server's public interface. IPv6 normally does not need NAT: route an appropriate prefix and set the firewall policy instead.

Phones and everyday clients

WireGuard's mobile clients import the same client configuration shown in Start here. Transfer it through a method appropriate for the secret it contains, then remove the temporary copy. QR import is convenient for a phone: existing management work can produce QR output, but that tooling is not yet part of public Saphira. A QR code representing a client configuration is sensitive for the same reason the file is.