openwrtv4/package/network/services/wireguard/files/wireguard.sh
Jason A. Donenfeld 699c6fcc31 wireguard: add wireguard to base packages
Move wireguard from openwrt/packages to base a package.

This follows the pattern of kmod-cake and openvpn. Cake is a fast-moving
experimental kernel module that many find essential and useful. The
other is a VPN client. Both are inside of core. When you combine the two
characteristics, you get WireGuard. Generally speaking, because of the
extremely lightweight nature and "stateless" configuration of WireGuard,
many view it as a core and essential utility, initiated at boot time
and immediately configured by netifd, much like the use of things like
GRE tunnels.

WireGuard has a backwards and forwards compatible Netlink API, which
means the userspace tools should work with both newer and older kernels
as things change. There should be no versioning requirements, therefore,
between kernel bumps and userspace package bumps.

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Acked-by: Felix Fietkau <nbd@nbd.name>
2017-10-16 14:01:21 +03:00

192 lines
4.8 KiB
Bash

#!/bin/sh
# Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
# Licensed to the public under the Apache License 2.0.
WG=/usr/bin/wg
if [ ! -x $WG ]; then
logger -t "wireguard" "error: missing wireguard-tools (${WG})"
exit 0
fi
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_wireguard_init_config() {
proto_config_add_string "private_key"
proto_config_add_int "listen_port"
proto_config_add_int "mtu"
proto_config_add_string "fwmark"
available=1
no_proto_task=1
}
proto_wireguard_setup_peer() {
local peer_config="$1"
local public_key
local preshared_key
local allowed_ips
local route_allowed_ips
local endpoint_host
local endpoint_port
local persistent_keepalive
config_get public_key "${peer_config}" "public_key"
config_get preshared_key "${peer_config}" "preshared_key"
config_get allowed_ips "${peer_config}" "allowed_ips"
config_get_bool route_allowed_ips "${peer_config}" "route_allowed_ips" 0
config_get endpoint_host "${peer_config}" "endpoint_host"
config_get endpoint_port "${peer_config}" "endpoint_port"
config_get persistent_keepalive "${peer_config}" "persistent_keepalive"
# peer configuration
echo "[Peer]" >> "${wg_cfg}"
echo "PublicKey=${public_key}" >> "${wg_cfg}"
if [ "${preshared_key}" ]; then
echo "PresharedKey=${preshared_key}" >> "${wg_cfg}"
fi
for allowed_ip in $allowed_ips; do
echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}"
done
if [ "${endpoint_host}" ]; then
case "${endpoint_host}" in
*:*)
endpoint="[${endpoint_host}]"
;;
*)
endpoint="${endpoint_host}"
;;
esac
if [ "${endpoint_port}" ]; then
endpoint="${endpoint}:${endpoint_port}"
else
endpoint="${endpoint}:51820"
fi
echo "Endpoint=${endpoint}" >> "${wg_cfg}"
fi
if [ "${persistent_keepalive}" ]; then
echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}"
fi
# add routes for allowed ips
if [ ${route_allowed_ips} -ne 0 ]; then
for allowed_ip in ${allowed_ips}; do
case "${allowed_ip}" in
*:*/*)
proto_add_ipv6_route "${allowed_ip%%/*}" "${allowed_ip##*/}"
;;
*.*/*)
proto_add_ipv4_route "${allowed_ip%%/*}" "${allowed_ip##*/}"
;;
*:*)
proto_add_ipv6_route "${allowed_ip%%/*}" "128"
;;
*.*)
proto_add_ipv4_route "${allowed_ip%%/*}" "32"
;;
esac
done
fi
}
proto_wireguard_setup() {
local config="$1"
local wg_dir="/tmp/wireguard"
local wg_cfg="${wg_dir}/${config}"
local private_key
local listen_port
local mtu
# load configuration
config_load network
config_get private_key "${config}" "private_key"
config_get listen_port "${config}" "listen_port"
config_get addresses "${config}" "addresses"
config_get mtu "${config}" "mtu"
config_get fwmark "${config}" "fwmark"
# create interface
ip link del dev "${config}" 2>/dev/null
ip link add dev "${config}" type wireguard
if [ "${mtu}" ]; then
ip link set mtu "${mtu}" dev "${config}"
fi
proto_init_update "${config}" 1
# generate configuration file
umask 077
mkdir -p "${wg_dir}"
echo "[Interface]" > "${wg_cfg}"
echo "PrivateKey=${private_key}" >> "${wg_cfg}"
if [ "${listen_port}" ]; then
echo "ListenPort=${listen_port}" >> "${wg_cfg}"
fi
if [ "${fwmark}" ]; then
echo "FwMark=${fwmark}" >> "${wg_cfg}"
fi
config_foreach proto_wireguard_setup_peer "wireguard_${config}"
# apply configuration file
${WG} setconf ${config} "${wg_cfg}"
WG_RETURN=$?
# delete configuration file
rm -f "${wg_cfg}"
# check status
if [ ${WG_RETURN} -ne 0 ]; then
sleep 5
proto_setup_failed "${config}"
exit 1
fi
# add ip addresses
for address in ${addresses}; do
case "${address}" in
*:*/*)
proto_add_ipv6_address "${address%%/*}" "${address##*/}"
;;
*.*/*)
proto_add_ipv4_address "${address%%/*}" "${address##*/}"
;;
*:*)
proto_add_ipv6_address "${address%%/*}" "128"
;;
*.*)
proto_add_ipv4_address "${address%%/*}" "32"
;;
esac
done
# endpoint dependency
wg show "${config}" endpoints | \
sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \
while IFS=$'\t ' read -r key address port; do
[ -n "${port}" ] || continue
proto_add_host_dependency "${config}" "${address}"
done
proto_send_update "${config}"
}
proto_wireguard_teardown() {
local config="$1"
ip link del dev "${config}" >/dev/null 2>&1
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol wireguard
}