@swinster
Here's as far as I've gotten so far. It's "seemingly" doing everything right, and not returning any errors, but then it also fails to create a new peer, and I haven't figured out where to go from here.
Mind that this is an interactive script that expects you to press Y, but should be easy to adopt to say take an email address as parameter instead and then email the config to that address.
It also assumes that you have a /24 subnet for your wireguard clients (for now).
#!/bin/sh
DNS="10.2.10.10, mydomain.com"
ALLOWEDIPS="10.2.10.0/24"
ENDPOINT="wireguard.mydomain.com:51820"
## Usage
#./wg-add-peer.sh <username>
# check that only 1 argument is given
if [ $# -ne 1 ]; then
echo "illegal number of parameters\nUsage\n$0 <username>"
exit 1
fi
# Get tunnel name
tunnel=`xmllint --xpath "string(/pfsense/installedpackages/wireguard/tunnels/item/name)" /conf/config.xml`
# Get the first 3 actets
subnet=`xmllint --xpath 'string(/pfsense/installedpackages/wireguard/tunnels/item/addresses/row/address)' /conf/config.xml | cut -f-3 -d'.'`
# Get count of existing peers
peer_count=`xmllint --xpath "count(/pfsense/installedpackages/wireguard/peers/item)" /conf/config.xml`
find_next_ip() {
# Assume the first integer in last octet belongs to our tunnel interface ip
seq=2
# Find next available integer
for i in `xmllint --xpath "//pfsense/installedpackages/wireguard/peers/item//allowedips/row/address" /conf/config.xml | sed 's/<*.address>//g' | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | cut -f4 -d'.'`; do
if [ $i != $seq ]; then
echo $i
return $i
fi
seq=$((seq+1))
done
echo $seq
return $seq
}
next_ip="$subnet.$(find_next_ip)"
#Generate keys
private_key=$(wg genkey)
public_key=$(echo "$private_key" | wg pubkey)
cat > /tmp/pfSsh_script.tmp << EOF
\$newPeer['enabled'] = 'yes';
\$newPeer['tun'] = '$tunnel';
\$newPeer['descr'] = '$1';
\$newPeer['persistentkeepalive'] = '';
\$newPeer['publickey'] = '$public_key';
\$newPeer['presharedkey'] = '';
\$newPeerIP['address'] = '$next_ip';
\$newPeerIP['mask'] = '32';
\$newPeerIP['descr'] = '';
\$config['installedpackages']['wireguard']['peers']['item']][] = \$newPeer;
\$config['installedpackages']['wireguard']['peers']['item']['$peer_count']['allowedips']['row'][] = \$newPeerIP
pfSense shell: parse_config(true);
pfSense shell: write_config();
pfSense shell: exec;
playback svc restart WireGuard
exit
EOF
cat > "$1-wg.conf" << EOL
[Interface]
PrivateKey = $private_key
Address = $next_ip/32
DNS = $DNS
[Peer]
PublicKey = $(wg|grep "public key"|rev|cut -d' ' -f1|rev)
AllowedIPs = $ALLOWEDIPS
Endpoint = $ENDPOINT
PersistentKeepalive = 15
EOL
echo "About to run the following pfSsh.php script:"
cat /tmp/pfSsh_script.tmp
read -r -p $'Confirm by pressing y... ' key
if [ "$key" == 'y' ] || [ "$key" == 'Y' ]; then
/usr/local/sbin/pfSsh.php < /tmp/pfSsh_script.tmp
rm -f /tmp/pfSsh_script.tmp
echo "$1-wg.conf:"
cat "$1-wg.conf"
else
# Anything else pressed, do whatever else.
echo User input not y...
exit 1
fi