# WireGuard — Lean, Modern VPN on the Command Line

> Hands-on guide to WireGuard: generate key pairs, configure peers and AllowedIPs, manage tunnels with wg and wg-quick, and verify connections.

Source: https://www.jpkc.com/db/en/cheatsheets/security/wireguard/

<!-- PROSE:intro -->
WireGuard is a modern, lean VPN protocol that runs directly inside the Linux kernel and gets by with just a few thousand lines of code – a fraction of OpenVPN or IPsec. Instead of negotiating ciphers, it relies on fixed, state-of-the-art cryptography (Curve25519, ChaCha20, Poly1305), which keeps the configuration remarkably simple. You manage keys, peers, and tunnel status with `wg`, and bring an interface up or down in seconds from a config file with `wg-quick`. Each node has a Curve25519 key pair; peers are linked by their public key, their AllowedIPs, and an endpoint. This guide takes you from key generation through peer management to troubleshooting a running tunnel.
<!-- PROSE:intro:end -->

## Key Generation

`wg genkey` — Generate a private key (Curve25519). Never share the private key – lock the file down with `chmod 600`.

```bash
wg genkey > private.key
```

`wg pubkey < <private-key-file>` — Derive the matching public key from a private key; the public key can safely be shared with peers.

```bash
wg pubkey < private.key > public.key
```

`wg genkey | tee private.key | wg pubkey > public.key` — Generate both keys in one command.

```bash
wg genkey | tee private.key | wg pubkey > public.key
```

`wg genpsk` — Generate a pre-shared key for an additional symmetric layer of security.

```bash
wg genpsk > preshared.key
```

## wg-quick (Easy Setup)

`wg-quick up <interface>` — Bring up a WireGuard interface using its config file.

```bash
wg-quick up wg0
```

`wg-quick down <interface>` — Tear down a WireGuard interface.

```bash
wg-quick down wg0
```

`wg-quick strip <interface>` — Show the config with wg-quick extras removed (pure wg format).

```bash
wg-quick strip wg0
```

`systemctl enable wg-quick@<interface>` — Enable WireGuard to start at boot.

```bash
systemctl enable wg-quick@wg0
```

`systemctl start wg-quick@<interface>` — Start WireGuard via systemd.

```bash
systemctl start wg-quick@wg0
```

## wg Interface Management

`wg show` — Show the status of all WireGuard interfaces.

```bash
wg show
```

`wg show <interface>` — Show the status of a specific interface.

```bash
wg show wg0
```

`wg show <interface> dump` — Show the status in machine-readable format.

```bash
wg show wg0 dump
```

`wg showconf <interface>` — Show the running configuration.

```bash
wg showconf wg0
```

`wg set <interface> listen-port <port>` — Set the listening port.

```bash
wg set wg0 listen-port 51820
```

`wg set <interface> private-key <file>` — Set the private key for an interface.

```bash
wg set wg0 private-key /etc/wireguard/private.key
```

## Peer Management

`wg set <interface> peer <pubkey> allowed-ips <cidr> endpoint <host:port>` — Add a peer to an interface. The AllowedIPs decide which destination IPs are routed through the tunnel – set them carefully, as they control both routing and security.

```bash
wg set wg0 peer ABC123...= allowed-ips 10.0.0.2/32 endpoint 203.0.113.1:51820
```

`wg set <interface> peer <pubkey> remove` — Remove a peer from an interface.

```bash
wg set wg0 peer ABC123...= remove
```

`wg set <interface> peer <pubkey> persistent-keepalive <seconds>` — Set the keepalive interval for NAT traversal.

```bash
wg set wg0 peer ABC123...= persistent-keepalive 25
```

`wg set <interface> peer <pubkey> preshared-key <file>` — Set a pre-shared key for a peer.

```bash
wg set wg0 peer ABC123...= preshared-key /etc/wireguard/psk.key
```

`wg show <interface> latest-handshakes` — Show when each peer last completed a handshake.

```bash
wg show wg0 latest-handshakes
```

`wg show <interface> transfer` — Show data transfer statistics per peer.

```bash
wg show wg0 transfer
```

## Troubleshooting

`wg show <interface> endpoints` — Show the current endpoints for all peers.

```bash
wg show wg0 endpoints
```

`ping -c 4 <peer-ip>` — Test connectivity to a peer through the tunnel.

```bash
ping -c 4 10.0.0.2
```

`ip addr show <interface>` — Show the WireGuard interface IP configuration.

```bash
ip addr show wg0
```

`ip route | grep <interface>` — Check which routes go through the WireGuard tunnel.

```bash
ip route | grep wg0
```

`journalctl -u wg-quick@<interface>` — View the WireGuard systemd service logs.

```bash
journalctl -u wg-quick@wg0 -f
```

<!-- PROSE:outro -->
## Conclusion

WireGuard proves a VPN doesn't have to be complicated: one key pair per node, a short config file, and two commands are enough for an encrypted tunnel. Pay attention to two things above all – keep the private key locked down (`chmod 600`, never share it) and set AllowedIPs deliberately, since they decide routing and therefore the security of your tunnel. Once you manage more than a handful of peers, pair WireGuard with systemd (`wg-quick@`) and a version-controlled config under `/etc/wireguard/`.

## Further Reading

- [WireGuard – official website](https://www.wireguard.com/) – concept, protocol, and downloads
- [WireGuard Quick Start](https://www.wireguard.com/quickstart/) – step-by-step getting started guide
- [WireGuard – Wikipedia](https://en.wikipedia.org/wiki/WireGuard) – background and context
<!-- PROSE:outro:end -->

## Related Commands

- [age](https://www.jpkc.com/db/en/cheatsheets/security/age/) – modern file encryption with simple keys
- [clamav](https://www.jpkc.com/db/en/cheatsheets/security/clamav/) – open-source virus scanner for files and mail
- [fail2ban](https://www.jpkc.com/db/en/cheatsheets/security/fail2ban/) – bans IPs after repeated failed logins

