Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wireguard-tools: add netifd protocol helper #3512

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion net/wireguard/Makefile
Expand Up @@ -10,7 +10,7 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=wireguard

PKG_VERSION:=0.0.20161105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might as well be bumped, while we're at it.

PKG_RELEASE:=1
PKG_RELEASE:=2

PKG_SOURCE:=WireGuard-experimental-$(PKG_VERSION).tar.xz
# This is actually SHA256, but OpenWRT/LEDE will figure it out based on the length
Expand Down Expand Up @@ -82,6 +82,7 @@ endef
define Package/wireguard-tools/install
$(INSTALL_DIR) $(1)/usr/bin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/tools/wg $(1)/usr/bin/
$(INSTALL_BIN) ./files/wireguard.sh $(1)/lib/netifd/proto/
endef

define KernelPackage/wireguard
Expand Down
182 changes: 182 additions & 0 deletions net/wireguard/files/wireguard.sh
@@ -0,0 +1,182 @@
#!/bin/sh
# Copyright 2016 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() {
available=1
no_proto_task=1
}

proto_wireguard_setup() {
local config="$1"
local iface="wg-${config}"
local wg_dir="/tmp/wireguard/"
local wg_cfg="${wg_dir}${config}"

local private_key
local listen_port
local addresses
local mtu
local preshared_key

# check for kernel module
if ! grep -q wireguard /proc/modules; then
echo "loading kernel module"
if ! insmod wireguard; then
echo "error: loading kernel module failed"
proto_setup_failed "$config"
exit 1
fi
fi

# load configuration
config_load network

# get interface configuration
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 preshared_key "${config}" "preshared_key"

# create interface
ip link del dev "${iface}" 2>/dev/null
ip link add dev "${iface}" type wireguard
if [ "${mtu}" ]; then
ip link set mtu "${mtu}" dev "${iface}"
fi

# create wireguard configuration
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 [ "${preshared_key}" ]; then
echo "PresharedKey=${preshared_key}" >> "${wg_cfg}"
fi

configure_peer() {
local peer_config="$1"
local public_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 allowed_ips "${peer_config}" "allowed_ips"
config_get route_allowed_ips "${peer_config}" "route_allowed_ips"
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}"
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}" = "enabled" ]; then
for allowed_ip in $allowed_ips; do
proto_init_update "${iface}" 1
proto_set_keep 1
route="$(echo $allowed_ip | tr '/' ' ')"
case "${allowed_ip}" in
*:*/*)
proto_add_ipv6_route $route
;;
*/*)
proto_add_ipv4_route $route
;;
esac
proto_send_update "${config}"
done
fi

# ensure endpoint reachability
if [ "${endpoint_host}" ]; then
added_dependency="false"
for ip in $(resolveip -t 5 "${endpoint_host}"); do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last I checked, resolveip requires a separate package. If this bit of logic is actually needed in the code, then probably the makefile should depend on having that package. I hit this snag twice when setting up my OpenWRT router a few days ago. The first time I just removed this block, and things worked fine. The second time I just installed resolveip, and things worked fine. Probably @zorun is the right man to make the call on what to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, yes, it is needed. Dependency is required for tunnels that add a default route. It is said to take care of creating a route to the endpoint(s) so they remain reachable in case of a new default route (if one endpoint has allowed_ips ::/0 and we create a route for ::/0 through the wg interface).

( proto_add_host_dependency "${config}" "${ip}" )
added_dependency="true"
done
if [ "${added_dependency}" = "false" ]; then
echo "Error resolving ${endpoint_host}!"
sleep 5
proto_setup_failed "${config}"
exit 1
fi
fi
}
config_foreach configure_peer "wireguard_${config}"

# apply configuration
$WG setconf ${iface} "${wg_cfg}"

# delete configuration
rm -f "${wg_cfg}"

# assign addresses
for address in ${addresses}; do
proto_init_update "${iface}" 1
proto_set_keep 1
address_plen="$(echo $address | tr '/' ' ')"
case "${address}" in
*:*)
proto_add_ipv6_address $address_plen
;;
*)
proto_add_ipv4_address $address_plen
;;
esac
proto_send_update "${config}"
done
}

proto_wireguard_teardown() {
local config="$1"
local iface="wg-${config}"
ip link del dev "${iface}" >/dev/null 2>&1
}

[ -n "$INCLUDE_ONLY" ] || {
add_protocol wireguard
}