commit 19d3d0922b972a61ba5b23ee6cd98a2ab151c7b1 from: Isaac Meerleo date: Tue Mar 24 01:57:06 2026 UTC Restyle wg_config and replace ifconfig key derivation Replace the ifconfig wg9 create/destroy method for deriving client public keys with openssl X25519 DER construction (RFC 8410). No longer requires root or a running kernel with wg(4) to generate configs. Also bring script in line with wg_gen conventions: - Add usage() function and proper argument validation - Add description/wgdescr to hostname.wg and wgserver outputs - Fix hostname.wg: add missing inet prefix, wgpka 20 -> 25 - Quote all filenames, chmod 600 instead of chown commit - 68860e7a100628b0ffb9d80c5ef48e1c320c06c8 commit + 19d3d0922b972a61ba5b23ee6cd98a2ab151c7b1 blob - 325fe2f319fbbc9fd030c6183648da2b154a6bf5 blob + 8810d2eebbe8cae51b5445ba2263c4ba862395db --- bin/wg_config +++ bin/wg_config @@ -1,84 +1,112 @@ #!/bin/sh -e -# This script creates wireguard Client and Server config files # +# Create WireGuard client and server peer configs for a single host +# against a running wg0 server interface. +# +# Usage: wg_config name client_ip port +# + #### Functions -create_client_pubkey() { - ifconfig wg9 create wgkey $CLIENT_PRIVKEY - ifconfig wg9 | awk '/wgpubkey/ { print $2 }' - ifconfig wg9 destroy + +# Show usage and exit. +usage() { + echo "usage: ${0##*/} name client_ip port" >&2 + exit 1 } +# Derive X25519 public key from a base64-encoded private key using only +# openssl(1). Constructs a PKCS#8 DER-encoded X25519 private key per +# RFC 8410 (OID 1.3.101.110) and extracts the raw 32-byte public key +# from the SubjectPublicKeyInfo DER output. +# +# Reference: RFC 8410, Section 7 — "Algorithm Identifiers for Ed25519, +# Ed448, X25519, and X448 for Use in the Internet X.509 Public Key +# Infrastructure" (https://www.rfc-editor.org/rfc/rfc8410) +# Prior art: +# https://gist.github.com/Aleksanaa/9886c9d7d50f1c815400657578ee9a76 +# https://gist.github.com/yrpeng/0b51f6f91931b70f6523db9c2d3ba835 +get_pubkey() { + { + printf '\x30\x2e\x02\x01\x00\x30\x05\x06\x03\x2b\x65\x6e\x04\x22\x04\x20' + echo "$1" | openssl enc -base64 -d + } | openssl pkey -inform DER -pubout -outform DER 2>/dev/null \ + | tail -c 32 \ + | openssl enc -base64 +} + get_server_pubkey() { ifconfig wg0 | awk '/wgpubkey/ { print $2 }' } -get_server_ip() { - ifconfig wg0 | awk '/inet/ { print $2 }' -} +#### Argument parsing -#### Script - -if [[ $# -eq 0 ]]; then - echo "Usage: $0 ClientName ClientTunnelIP ServerPort" - exit 0 +if [ $# -ne 3 ]; then + usage fi -#### Variables CLIENT_NAME="$1" CLIENT_IP="$2" SERVER_PORT="$3" + + +#### Setup + DNS_SERVER="9.9.9.9" -CLIENT_PRIVKEY="$(openssl rand -base64 32)" -CLIENT_PUBKEY="$(create_client_pubkey)" -SERVER_PUBKEY="$(get_server_pubkey)" -SHARED_KEY="$(openssl rand -base64 32)" +CLIENT_PRIVKEY=$(openssl rand -base64 32) +CLIENT_PUBKEY=$(get_pubkey "$CLIENT_PRIVKEY") +SERVER_PUBKEY=$(get_server_pubkey) +SHARED_KEY=$(openssl rand -base64 32) -# Everything else config ($CLIENT_NAME.conf -cat << EOF > $CLIENT_NAME.conf + +#### Generate configs + +# Standard WireGuard client config. +cat < "${CLIENT_NAME}.conf" [Interface] -# $CLIENT_NAME private key -PrivateKey = $CLIENT_PRIVKEY -Address = $CLIENT_IP/32 -DNS = $DNS_SERVER +# ${CLIENT_NAME} private key +PrivateKey = ${CLIENT_PRIVKEY} +Address = ${CLIENT_IP}/32 +DNS = ${DNS_SERVER} [Peer] # Wireguard server public key -PublicKey = $SERVER_PUBKEY -PresharedKey = $SHARED_KEY +PublicKey = ${SERVER_PUBKEY} +PresharedKey = ${SHARED_KEY} AllowedIPs = 0.0.0.0/0 Endpoint = fugu.farm:${SERVER_PORT} PersistentKeepalive = 25 EOF - -# OpenBSD Client config ($CLIENT_NAME.hostname.wg) -cat << EOF > $CLIENT_NAME.hostname.wg -# Interface -wgkey $CLIENT_PRIVKEY -$CLIENT_IP 255.255.255.0 +# OpenBSD client config. +cat < "${CLIENT_NAME}.hostname.wg" +# ${CLIENT_NAME} +description "${CLIENT_NAME}" +wgkey ${CLIENT_PRIVKEY} +inet ${CLIENT_IP} 255.255.255.0 up # Peer fugu.farm -wgpeer $SERVER_PUBKEY \\ - wgpsk $SHARED_KEY \\ - wgendpoint fugu.farm $SERVER_PORT \\ - wgaip 0.0.0.0/0 wgpka 20 +wgpeer ${SERVER_PUBKEY} \\ + wgdescr "fugu.farm" \\ + wgpsk ${SHARED_KEY} \\ + wgendpoint fugu.farm ${SERVER_PORT} \\ + wgaip 0.0.0.0/0 wgpka 25 EOF - -# Peer config for server ($CLIENT_NAME.hostname.wgserver) -cat << EOF > $CLIENT_NAME.hostname.wgserver - -# Peer $CLIENT_NAME -wgpeer $CLIENT_PUBKEY \\ - wgpsk $SHARED_KEY \\ - wgaip $CLIENT_IP/32 +# Server peer snippet. +cat < "${CLIENT_NAME}.hostname.wgserver" +# Peer ${CLIENT_NAME} +wgpeer ${CLIENT_PUBKEY} \\ + wgdescr "${CLIENT_NAME}" \\ + wgpsk ${SHARED_KEY} \\ + wgaip ${CLIENT_IP}/32 EOF -chown isaac:isaac \ - ${CLIENT_NAME}.hostname.wgserver \ - ${CLIENT_NAME}.hostname.wg \ - ${CLIENT_NAME}.conf \ -exit 0 +#### Permissions — configs contain private keys. + +chmod 600 \ + "${CLIENT_NAME}.conf" \ + "${CLIENT_NAME}.hostname.wg" \ + "${CLIENT_NAME}.hostname.wgserver"