wireguard Module¶
WireGuard VPN server and peer configuration.
Import¶
Requirements¶
- WireGuard installed on the system
jinja2package for template rendering
Classes¶
Server¶
Dataclass representing a WireGuard server.
from fscm.modules.wireguard import Server
server = Server(
address="10.0.0.1/24",
listen_port=51820,
private_key="server_private_key",
public_key="server_public_key"
)
Attributes:
| Name | Type | Description |
|---|---|---|
address |
str | Server VPN address with CIDR |
listen_port |
int | UDP port to listen on |
private_key |
str | Server's private key |
public_key |
str | Server's public key |
dns |
str | DNS server for clients |
post_up |
str | Commands to run after interface up |
post_down |
str | Commands to run after interface down |
Peer¶
Dataclass representing a WireGuard peer.
from fscm.modules.wireguard import Peer
peer = Peer(
name="laptop",
address="10.0.0.2/32",
private_key="peer_private_key",
public_key="peer_public_key",
allowed_ips="10.0.0.2/32"
)
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str | Peer identifier |
address |
str | Peer VPN address |
private_key |
str | Peer's private key |
public_key |
str | Peer's public key |
allowed_ips |
str | IPs the peer can access |
endpoint |
str | Peer's public endpoint |
persistent_keepalive |
int | Keepalive interval |
Functions¶
server¶
Create server and peer configurations.
from fscm.modules.wireguard import server, Server, Peer
srv = Server(
address="10.0.0.1/24",
listen_port=51820,
private_key="...",
public_key="..."
)
peers = [
Peer(name="laptop", address="10.0.0.2/32", public_key="...", private_key="..."),
Peer(name="phone", address="10.0.0.3/32", public_key="...", private_key="..."),
]
# Generate configs
server(
srv,
peers,
endpoint="vpn.example.com:51820",
interface="wg0"
)
This creates:
- /etc/wireguard/wg0.conf — Server config
- /etc/wireguard/clients/laptop.conf — Client configs
configure_server¶
Low-level server configuration.
from fscm.modules.wireguard import configure_server
configure_server(
interface="wg0",
address="10.0.0.1/24",
listen_port=51820,
private_key="...",
peers=[...]
)
Key Generation¶
Generate WireGuard keys using the CLI:
# Generate private key
wg genkey > private.key
# Derive public key
wg pubkey < private.key > public.key
Or in Python:
import fscm
# Generate on the server
private_key = fscm.getstdout("wg genkey")
public_key = fscm.getstdout(f"echo '{private_key}' | wg pubkey")
Examples¶
Complete VPN Setup¶
#!/usr/bin/env python3
"""Set up a WireGuard VPN server."""
import fscm
from fscm.modules.wireguard import Server, Peer, server
# Server configuration
VPN_NETWORK = "10.100.0.0/24"
VPN_PORT = 51820
VPN_ENDPOINT = "vpn.example.com"
def generate_keys():
"""Generate a keypair."""
private = fscm.getstdout("wg genkey").strip()
public = fscm.getstdout(f"echo '{private}' | wg pubkey").strip()
return private, public
def setup_vpn():
# Install WireGuard
fscm.s.pkgs_install("wireguard", "wireguard-tools")
# Generate server keys
srv_private, srv_public = generate_keys()
# Define server
srv = Server(
address="10.100.0.1/24",
listen_port=VPN_PORT,
private_key=srv_private,
public_key=srv_public,
post_up="iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE",
post_down="iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE"
)
# Define peers
peers = []
for i, name in enumerate(["laptop", "phone", "tablet"], start=2):
peer_private, peer_public = generate_keys()
peers.append(Peer(
name=name,
address=f"10.100.0.{i}/32",
private_key=peer_private,
public_key=peer_public,
allowed_ips="0.0.0.0/0" # Route all traffic
))
# Generate configurations
server(srv, peers, endpoint=f"{VPN_ENDPOINT}:{VPN_PORT}")
# Enable IP forwarding
fscm.lineinfile(
"/etc/sysctl.conf",
line="net.ipv4.ip_forward=1",
regexp=r"^#?net\.ipv4\.ip_forward"
)
fscm.run("sysctl -p", sudo=True)
# Enable and start WireGuard
fscm.run("systemctl enable wg-quick@wg0", sudo=True)
fscm.run("systemctl start wg-quick@wg0", sudo=True)
print("\nClient configs saved to /etc/wireguard/clients/")
if __name__ == "__main__":
setup_vpn()
Add Peer to Existing Server¶
import fscm
from fscm.modules.wireguard import Peer
def add_peer(name: str, address: str):
"""Add a new peer to the VPN."""
# Generate keys
private = fscm.getstdout("wg genkey").strip()
public = fscm.getstdout(f"echo '{private}' | wg pubkey").strip()
# Add to server config
peer_config = f"""
[Peer]
# {name}
PublicKey = {public}
AllowedIPs = {address}
"""
fscm.run(f"echo '{peer_config}' >> /etc/wireguard/wg0.conf", sudo=True)
# Reload WireGuard
fscm.run("wg syncconf wg0 <(wg-quick strip wg0)", sudo=True)
# Generate client config
client_config = f"""[Interface]
PrivateKey = {private}
Address = {address}
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
"""
print(f"\nClient config for {name}:")
print(client_config)
add_peer("new-device", "10.100.0.10/32")