deletePeer
Removes a peer from a WireGuard configuration file by public key.
Overview
The deletePeer function safely removes a specific peer from an existing WireGuard configuration file. It identifies the peer by their public key and removes the entire peer section from the configuration.
Signature
deletePeer(filepath: string, where: {
publicKey: string
}): Promise<void>Parameters
filepath(string): Path to the WireGuard configuration filewhere(object): Identification criteriapublicKey(string): Public key of the peer to remove
Returns
Returns a Promise that resolves when the peer is successfully removed.
Basic Usage
import { deletePeer } from "@kriper0nind/wg-utils"
// Remove a peer by public key
await deletePeer("/etc/wireguard/wg0.conf", {
publicKey: "client-public-key-to-remove"
})
console.log("Peer removed successfully")Advanced Usage
Safe Peer Removal with Validation
import { deletePeer, parse } from "@kriper0nind/wg-utils"
import { readFile } from "fs/promises"
async function safeDeletePeer(configPath: string, publicKey: string) {
try {
// First, verify the peer exists
const configContent = await readFile(configPath, "utf-8")
const config = parse(configContent)
const peerExists = config.Peers?.some(peer => peer.PublicKey === publicKey)
if (!peerExists) {
throw new Error("Peer not found in configuration")
}
// Remove the peer
await deletePeer(configPath, { publicKey })
console.log("Peer removed successfully")
} catch (error) {
console.error("Failed to remove peer:", error.message)
throw error
}
}Batch Peer Removal
async function removeMultiplePeers(configPath: string, publicKeys: string[]) {
const results = []
for (const publicKey of publicKeys) {
try {
await deletePeer(configPath, { publicKey })
results.push({ publicKey, status: "removed" })
} catch (error) {
results.push({ publicKey, status: "failed", error: error.message })
}
}
return results
}
// Remove multiple peers
const publicKeys = [
"client1-public-key",
"client2-public-key",
"client3-public-key"
]
const results = await removeMultiplePeers("/etc/wireguard/wg0.conf", publicKeys)
console.log("Removal results:", results)Peer Management with Logging
import { deletePeer, parse, stringify } from "@kriper0nind/wg-utils"
import { readFile, writeFile } from "fs/promises"
async function managePeers(configPath: string, action: string, publicKey: string) {
// Backup original configuration
const originalConfig = await readFile(configPath, "utf-8")
const backupPath = `${configPath}.backup.${Date.now()}`
await writeFile(backupPath, originalConfig)
try {
if (action === "remove") {
await deletePeer(configPath, { publicKey })
console.log(`Peer ${publicKey} removed successfully`)
}
// Log the change
console.log(`Configuration updated, backup saved to ${backupPath}`)
} catch (error) {
// Restore from backup on failure
await writeFile(configPath, originalConfig)
console.error("Operation failed, configuration restored from backup")
throw error
}
}Error Handling
The function may throw errors in the following scenarios:
- File not found: Configuration file doesn't exist
- Permission denied: Insufficient write permissions
- Peer not found: Public key doesn't match any peer
- Invalid configuration: Malformed configuration file
try {
await deletePeer("/etc/wireguard/wg0.conf", {
publicKey: "non-existent-key"
})
} catch (error) {
if (error.code === 'ENOENT') {
console.error("Configuration file not found")
} else if (error.code === 'EACCES') {
console.error("Permission denied - run with sudo")
} else {
console.error("Failed to remove peer:", error.message)
}
}Complete Peer Management
import {
deletePeer,
addPeer,
parse,
generateKeys
} from "@kriper0nind/wg-utils"
import { readFile } from "fs/promises"
class PeerManager {
constructor(private configPath: string) {}
async listPeers() {
const configContent = await readFile(this.configPath, "utf-8")
const config = parse(configContent)
return config.Peers || []
}
async addPeer() {
const keys = await generateKeys()
const result = await addPeer(this.configPath, {
publicKey: keys.publicKey
})
return { ...keys, ip: result.ip }
}
async removePeer(publicKey: string) {
await deletePeer(this.configPath, { publicKey })
}
async findPeer(publicKey: string) {
const peers = await this.listPeers()
return peers.find(peer => peer.PublicKey === publicKey)
}
}
// Usage
const manager = new PeerManager("/etc/wireguard/wg0.conf")
// List all peers
const peers = await manager.listPeers()
console.log(`Found ${peers.length} peers`)
// Add a new peer
const newPeer = await manager.addPeer()
console.log("New peer added:", newPeer.ip)
// Remove a peer
await manager.removePeer("old-peer-public-key")
console.log("Peer removed")Configuration Before and After
Before Removal
[Interface]
PrivateKey = server-private-key
Address = 10.0.0.1/24
[Peer]
PublicKey = client1-public-key
AllowedIPs = 10.0.0.2/32
[Peer]
PublicKey = client2-public-key
AllowedIPs = 10.0.0.3/32After Removing client1
[Interface]
PrivateKey = server-private-key
Address = 10.0.0.1/24
[Peer]
PublicKey = client2-public-key
AllowedIPs = 10.0.0.3/32Safety Features
Backup Before Removal
import { copyFile } from "fs/promises"
async function safeRemovePeer(configPath: string, publicKey: string) {
// Create backup
const backupPath = `${configPath}.backup.${Date.now()}`
await copyFile(configPath, backupPath)
try {
await deletePeer(configPath, { publicKey })
console.log("Peer removed, backup created:", backupPath)
} catch (error) {
console.error("Removal failed, backup available:", backupPath)
throw error
}
}Validation Before Removal
async function validateAndRemove(configPath: string, publicKey: string) {
const configContent = await readFile(configPath, "utf-8")
const config = parse(configContent)
// Check if peer exists
const peerIndex = config.Peers?.findIndex(peer => peer.PublicKey === publicKey)
if (peerIndex === -1 || !config.Peers) {
throw new Error("Peer not found")
}
// Check if this is the last peer
if (config.Peers.length === 1) {
console.warn("Warning: This is the last peer in the configuration")
}
// Proceed with removal
await deletePeer(configPath, { publicKey })
}Examples
Remove Inactive Peers
async function removeInactivePeers(configPath: string, inactiveKeys: string[]) {
const results = []
for (const publicKey of inactiveKeys) {
try {
await deletePeer(configPath, { publicKey })
results.push({ publicKey, status: "removed" })
} catch (error) {
results.push({ publicKey, status: "error", message: error.message })
}
}
return results
}
// Remove multiple inactive clients
const inactiveClients = [
"old-client-1-key",
"old-client-2-key"
]
const results = await removeInactivePeers("/etc/wireguard/wg0.conf", inactiveClients)
console.log("Cleanup results:", results)Peer Rotation
async function rotatePeer(oldPublicKey: string) {
// Generate new keys
const newKeys = await generateKeys()
// Add new peer
const result = await addPeer("/etc/wireguard/wg0.conf", {
publicKey: newKeys.publicKey
})
// Remove old peer
await deletePeer("/etc/wireguard/wg0.conf", {
publicKey: oldPublicKey
})
return {
newPrivateKey: newKeys.privateKey,
newPublicKey: newKeys.publicKey,
ip: result.ip
}
}Dependencies
parse: Parses WireGuard configuration filesstringify: Converts configuration objects back to WireGuard formatfs/promises: For file system operations
Notes
- The function only removes peers that match the exact public key
- If the peer is not found, the function completes silently (no error)
- The configuration file is automatically updated and saved
- All other peers and the interface configuration remain unchanged
- Consider creating backups before removing peers in production environments