addPeer – WireGuard Utils
Skip to content

addPeer

Adds a new peer to a WireGuard configuration file with automatic IP address assignment.

Overview

The addPeer function automatically adds a new peer to an existing WireGuard configuration file. It intelligently assigns the next available IP address in the 10.0.0.0/24 subnet, ensuring no conflicts with existing peers.

Signature

addPeer(filepath: string, options: { 
  publicKey: string
  persistentKeepalive?: number
  presharedKey?: string
  allowedIPs?: string
  endpoint?: string
  allowedApps?: string
}): Promise<{ ip: string }>

Parameters

  • filepath (string): Path to the WireGuard configuration file (e.g., /etc/wireguard/wg0.conf)
  • options (object): Configuration options for the new peer
    • publicKey (string): The public key of the peer to add
    • persistentKeepalive (number, optional): Interval in seconds for NAT keepalives
    • presharedKey (string, optional): PSK from generatePresharedKey
    • allowedIPs (string, optional): Custom CIDR list instead of auto /32
    • endpoint (string, optional): Host/IP and port of the peer
    • allowedApps (string, optional): Custom helper metadata (non-standard WireGuard key)

Returns

Returns a Promise that resolves to an object containing:

  • ip (string): The IP address assigned to the new peer

Behavior

IP Address Assignment

  • First peer: Gets 10.0.0.2/32 (10.0.0.1 is typically reserved for the server)
  • Subsequent peers: Gets the next available IP address in sequence
  • Algorithm: Finds the highest IP address among existing peers and increments it by 1
  • Format: All assigned IPs use /32 subnet mask for point-to-point connections

Configuration File Processing

  1. Reads and parses the existing WireGuard configuration file
  2. Analyzes existing peers to find the highest assigned IP address
  3. Calculates the next available IP address
  4. Creates a new peer entry with the provided public key
  5. Writes the updated configuration back to the file
  6. Calls wg syncconf <iface> to apply the change to the running interface without downtime

Optional Peer Fields

  • Persistent Keepalive: Prevents idle UDP mappings from expiring (common for mobile clients)
  • Preshared Key: Adds an extra layer of symmetric encryption per peer
  • Allowed IPs: Override the auto-generated /32 to define specific subnets or multiple CIDRs
  • Endpoint: Pre-configure the client's public endpoint for site-to-site setups
  • Allowed Apps: Extra metadata stored under AllowedApps for downstream tooling (ignored by WireGuard itself)

Example Usage

Basic Usage

import { addPeer, generateKeys, generatePresharedKey } from "@kriper0nind/wg-utils"
 
// Generate new key pair
const keys = await generateKeys()
 
// Add peer to configuration
const { presharedkey } = await generatePresharedKey()
 
const result = await addPeer("/etc/wireguard/wg0.conf", {
    publicKey: keys.publicKey,
    presharedKey: presharedkey,
    persistentKeepalive: 25
})
 
console.log(`New peer added with IP: ${result.ip}`)
// Output: "New peer added with IP: 10.0.0.2"

Adding Multiple Peers

import { addPeer, generateKeys } from "@kriper0nind/wg-utils"
 
const configPath = "/etc/wireguard/wg0.conf"
 
// Add first peer
const keys1 = await generateKeys()
const peer1 = await addPeer(configPath, { publicKey: keys1.publicKey })
console.log(`Peer 1 IP: ${peer1.ip}`) // 10.0.0.2
 
// Add second peer
const keys2 = await generateKeys()
const peer2 = await addPeer(configPath, { publicKey: keys2.publicKey })
console.log(`Peer 2 IP: ${peer2.ip}`) // 10.0.0.3

Using Existing Public Key

import { addPeer } from "@kriper0nind/wg-utils"
 
const existingPublicKey = "your-existing-public-key-here"
 
const result = await addPeer("/etc/wireguard/wg0.conf", {
    publicKey: existingPublicKey,
    allowedIPs: "10.0.0.50/32, 192.168.10.0/24",
    endpoint: "vpn.example.com:51820"
})
 
console.log(`Peer added with IP: ${result.ip}`)

Generated Configuration

The function adds a peer entry in the following format to your WireGuard configuration:

[Peer]
PublicKey = <provided-public-key>
PresharedKey = <optional-psk>
AllowedIPs = <assigned-ip>/32
Endpoint = <optional-endpoint>
PersistentKeepalive = 25
AllowedApps = <optional metadata>

Error Handling

The function may throw errors in the following scenarios:

  • File not found: If the specified configuration file doesn't exist
  • Permission denied: If the file cannot be read or written
  • Invalid configuration: If the existing configuration file is malformed
  • File system errors: If there are issues writing to the file
  • Sync failures: If wg syncconf fails (e.g., interface not running)

Dependencies

  • parse: Parses WireGuard configuration files
  • stringify: Converts configuration objects back to WireGuard format
  • fs/promises: For file system operations

Notes

  • The function automatically creates a Peers array if none exists
  • IP addresses are assigned sequentially starting from 10.0.0.2 unless allowedIPs is provided
  • The function preserves all existing configuration and comments
  • Custom allowedIPs strings are written verbatim, so you can supply multiple CIDRs separated by commas
  • After writing the file the interface is synchronized via wg syncconf, so active tunnels pick up the change immediately
  • AllowedApps is optional metadata for downstream tooling—WireGuard ignores unknown keys