From 87c43b042d2fdf3a4ef315b1939cdec90150a1fd Mon Sep 17 00:00:00 2001 From: sparrowhawk Date: Wed, 9 Jun 2021 16:37:05 +0200 Subject: [PATCH] newtype: __wireguard. --- type/__wireguard/files/interface.conf.sh | 10 +++ type/__wireguard/files/wireguard.conf.sh | 18 +++++ type/__wireguard/gencode-remote | 8 +++ type/__wireguard/man.rst | 53 ++++++++++++++ type/__wireguard/manifest | 56 +++++++++++++++ type/__wireguard/parameter/optional | 1 + type/__wireguard/parameter/required | 2 + type/__wireguard_peer/files/wg-peer.sh | 30 ++++++++ type/__wireguard_peer/gencode-remote | 10 +++ type/__wireguard_peer/man.rst | 70 +++++++++++++++++++ type/__wireguard_peer/manifest | 60 ++++++++++++++++ type/__wireguard_peer/parameter/optional | 4 ++ .../parameter/optional_multiple | 1 + type/__wireguard_peer/parameter/required | 2 + 14 files changed, 325 insertions(+) create mode 100755 type/__wireguard/files/interface.conf.sh create mode 100755 type/__wireguard/files/wireguard.conf.sh create mode 100644 type/__wireguard/gencode-remote create mode 100644 type/__wireguard/man.rst create mode 100644 type/__wireguard/manifest create mode 100644 type/__wireguard/parameter/optional create mode 100644 type/__wireguard/parameter/required create mode 100755 type/__wireguard_peer/files/wg-peer.sh create mode 100644 type/__wireguard_peer/gencode-remote create mode 100644 type/__wireguard_peer/man.rst create mode 100644 type/__wireguard_peer/manifest create mode 100644 type/__wireguard_peer/parameter/optional create mode 100644 type/__wireguard_peer/parameter/optional_multiple create mode 100644 type/__wireguard_peer/parameter/required diff --git a/type/__wireguard/files/interface.conf.sh b/type/__wireguard/files/interface.conf.sh new file mode 100755 index 0000000..e6b7e82 --- /dev/null +++ b/type/__wireguard/files/interface.conf.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +cat <<- EOF + auto ${WG_IFACE:?} + iface ${WG_IFACE:?} inet6 static + address ${WG_ADDRESS:?} + pre-up ip link add dev ${WG_IFACE:?} type wireguard + pre-up wg setconf ${WG_IFACE:?} /etc/wireguard/${WG_IFACE:?}.conf + post-down ip link delete dev ${WG_IFACE:?} +EOF diff --git a/type/__wireguard/files/wireguard.conf.sh b/type/__wireguard/files/wireguard.conf.sh new file mode 100755 index 0000000..2712d07 --- /dev/null +++ b/type/__wireguard/files/wireguard.conf.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +if [ $# -ne 1 ]; +then + echo "The WG private key must be passed to the script as an argument," >&2 + echo "as we do not consider the environment to be private. Aborting." >&2 + exit 1; +fi + +cat <<- EOF + [Interface] + PrivateKey = ${1:?} +EOF + +if [ -n "$WG_PORT" ]; +then + echo "ListenPort = ${WG_PORT:?}" +fi diff --git a/type/__wireguard/gencode-remote b/type/__wireguard/gencode-remote new file mode 100644 index 0000000..7a06fb4 --- /dev/null +++ b/type/__wireguard/gencode-remote @@ -0,0 +1,8 @@ +#!/bin/sh + +if grep -q "^__block/${__object_id:?}" "${__messages_in:?}"; then + cat <<- EOF + wg syncconf ${__object_id:?} /etc/wireguard/${__object_id:?}.conf + EOF +fi + diff --git a/type/__wireguard/man.rst b/type/__wireguard/man.rst new file mode 100644 index 0000000..ef08f12 --- /dev/null +++ b/type/__wireguard/man.rst @@ -0,0 +1,53 @@ +cdist-type__wireguard(7) +======================== + +NAME +---- +cdist-type__wireguard - Configure a wireguard interface + +DESCRIPTION +----------- + +This type creates a wireguard interface named using the `${__object_id}`. It +generates a configuration file for wireguard and a configuration file for +ifconfig, and then brings the interface up. + +Additional peers for the created wireguard interface can be added using +`cdist-type__wireguard_peers(7)`. + +Currently, this type is only implemented for Alpine Linux. + +Currently, this type only supports setting an IPv6 address to assign to the +wireguard interface. + +REQUIRED PARAMETERS +------------------- + +privkey + The private key for this wireguard instance. + +address + The IPv6 address to assign to the wireguard interface, optionally with a CIDR + mask. + +OPTIONAL PARAMETERS +------------------- + +port + The port to listen on. If not specified, wireguard will choose one randomly. + +SEE ALSO +-------- + +`wg(8)`, `wg-quick(8)`, `cdist-type__wireguard(7)`, `cdist-type__block(7)` + +AUTHORS +------- +Joachim Desroches + +COPYING +------- +Copyright \(C) 2020 Joachim Desroches. You can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. diff --git a/type/__wireguard/manifest b/type/__wireguard/manifest new file mode 100644 index 0000000..1b977de --- /dev/null +++ b/type/__wireguard/manifest @@ -0,0 +1,56 @@ +#!/bin/sh + +os="$(cat "${__global:?}"/explorer/os)" + +case $os in + 'alpine') + : + ;; + *) + echo "This type has no implementation for $os. Aborting." >&2 + exit 1; + ;; +esac + +__package "wireguard-tools-wg" + +# Template configuration +private_key="$(cat "${__object:?}/parameter/privkey")" + +WG_ADDRESS="$(cat "${__object:?}/parameter/address")" +WG_IFACE="${__object_id:?}" + +export WG_IFACE +export WG_ADDRESS + +WG_PORT= +if [ -f "${__object:?}/parameter/port" ]; +then + WG_PORT="$(cat "${__object:?}/parameter/port")" +fi +export WG_PORT + +mkdir -p "${__object:?}/files/" +"${__type:?}/files/wireguard.conf.sh" "$private_key" > "${__object:?}/files/wg-${__object_id:?}.conf" + +# Wireguard configuration. Configured using a block as it is also edited by +# cdist-type__wireguard_peer(7). +__directory "/etc/wireguard/" +require='__directory/etc/wireguard' \ + __file "/etc/wireguard/${__object_id:?}.conf" --state exists + +require="__file/etc/wireguard/${__object_id:?}.conf" \ + __block "${__object_id:?}" --file "/etc/wireguard/${__object_id:?}.conf" \ + --text - <"${__object:?}/files/wg-${__object_id:?}.conf" + +# Network configuration +__directory '/etc/network/interfaces.d' +__line source-interfaces \ + --line 'source-directory /etc/network/interfaces.d/' \ + --file '/etc/network/interfaces' + +"${__type:?}/files/interface.conf.sh" > "${__object:?}/files/iif-${__object_id:?}.conf" +require="__directory/etc/network/interfaces.d __line/source-interfaces __block/${__object_id:?}" \ + __file "/etc/network/interfaces.d/${__object_id:?}.conf" \ + --source "${__object:?}/files/iif-${__object_id:?}.conf" \ + --onchange "ifup -a" diff --git a/type/__wireguard/parameter/optional b/type/__wireguard/parameter/optional new file mode 100644 index 0000000..20e6f14 --- /dev/null +++ b/type/__wireguard/parameter/optional @@ -0,0 +1 @@ +port diff --git a/type/__wireguard/parameter/required b/type/__wireguard/parameter/required new file mode 100644 index 0000000..753d5ce --- /dev/null +++ b/type/__wireguard/parameter/required @@ -0,0 +1,2 @@ +address +privkey diff --git a/type/__wireguard_peer/files/wg-peer.sh b/type/__wireguard_peer/files/wg-peer.sh new file mode 100755 index 0000000..ac30f07 --- /dev/null +++ b/type/__wireguard_peer/files/wg-peer.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# We expect the pre-shared key, if it exists, as an argument because we do not +# consider the environment to be secure. + +cat << EOF +[Peer] +PublicKey = ${PKEY:?} +EOF + +if [ -n "$1" ]; +then + echo "PresharedKey = ${1:?}" +fi + +for ip in $ALLOWED_IPS; +do + echo "AllowedIPs = ${ip:?}" +done + +if [ -n "$ENDPOINT" ]; +then + echo "Endpoint = ${ENDPOINT:?}" +fi + +if [ -n "$PERSISTENT_KA" ]; +then + echo "PersistentKeepalive = ${PERSISTENT_KA:?}" +fi + +echo diff --git a/type/__wireguard_peer/gencode-remote b/type/__wireguard_peer/gencode-remote new file mode 100644 index 0000000..92c80c6 --- /dev/null +++ b/type/__wireguard_peer/gencode-remote @@ -0,0 +1,10 @@ +#!/bin/sh + +iface="$(cat "${__object:?}/parameter/iface")" + +if grep -q "^__block/${__object_id:?}" "${__messages_in:?}"; +then + cat <<- EOF + wg syncconf ${iface:?} /etc/wireguard/${iface:?}.conf + EOF +fi diff --git a/type/__wireguard_peer/man.rst b/type/__wireguard_peer/man.rst new file mode 100644 index 0000000..f0d1712 --- /dev/null +++ b/type/__wireguard_peer/man.rst @@ -0,0 +1,70 @@ +cdist-type__wiregurad_peer(7) +============================= + +NAME +---- +cdist-type__wiregurad_peer - Add an authorized peer to a wireguard interface. + +DESCRIPTION +----------- + +This type configures a peer to be authorized on a wireguard interface. The +`${__object_id}` is used to differentiate the `cdist-type__block(7)` where each peer is +defined. See `wg(8)` for details on the options. + +Note that this type **requires** a configuration file named after the `iface` +parameter to add and remove the peers from. The recommended way to accomplish +this is to call `cdist-type__wireguard(7)`, and set it as a requirement for +calls to this type adding peers to that interface. + +Currently, this type is only implemented for Alpine Linux. + +REQUIRED PARAMETERS +------------------- + +iface + The name of the wireguard interface to add the peer to. + +public-key + The peer's public key. + +OPTIONAL PARAMETERS +------------------- + +endpoint + The endpoint for this peer. + +persistent-keepalive + Send a keepalive packet every n seconds, expects an integer. + +preshared-key + A pre-shared symmetric key. Used for "post-quantum resistance". + +state + Directly passed on the `cdist-type__block(7)`, to enable removing a user. + +OPTIONAL MULTIPLE PARAMETERS +---------------------------- + +allowed-ip + A comma-separated list of IP (v4 or v6) addresses with CIDR masks from which + incoming traffic for this peer is allowed and to which outgoing traffic + for this peer is directed. The catch-all 0.0.0.0/0 may be specified for + matching all IPv4 addresses, and ::/0 may be specified for matching all IPv6 + addresses. + +SEE ALSO +-------- + +`wg(8)`, `wg-quick(8)`, `cdist-type__wireguard(7)`, `cdist-type__block(7)` + +AUTHORS +------- +Joachim Desroches + +COPYING +------- +Copyright \(C) 2020 Joachim Desroches. You can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. diff --git a/type/__wireguard_peer/manifest b/type/__wireguard_peer/manifest new file mode 100644 index 0000000..c5584a9 --- /dev/null +++ b/type/__wireguard_peer/manifest @@ -0,0 +1,60 @@ +#!/bin/sh +# expected to be run with a required='__wireguard/ifname' + +os="$(cat "${__global:?}"/explorer/os)" + +case "$os" in + alpine) + : + ;; + *) + echo "This type has no implementation for $os. Aborting." >&2; + exit 1; +esac + +iface="$(cat "${__object:?}/parameter/iface")" + +PKEY="$(cat "${__object:?}/parameter/public-key")" +export PKEY + +ALLOWED_IPS= +if [ -f "${__object:?}/parameter/allowed-ip" ]; +then + ALLOWED_IPS="$(cat "${__object:?}/parameter/allowed-ip")" +fi +export ALLOWED_IPS + +ENDPOINT= +if [ -f "${__object:?}/parameter/endpoint" ]; +then + ENDPOINT="$(cat "${__object:?}/parameter/endpoint")" +fi +export ENDPOINT + +PERSISTENT_KA= +if [ -f "${__object:?}/parameter/persistent-keepalive" ]; +then + PERSISTENT_KA="$(cat "${__object:?}/parameter/persistent-keepalive")" +fi +export PERSISTENT_KA + +state=present +if [ -f "${__object:?}/parameter/state" ]; +then + state="$(cat "${__object:?}/parameter/state")" +fi + +presharedkey= +if [ -f "${__object:?}/parameter/preshared-key" ]; +then + presharedkey="$(cat "${__object:?}/parameter/preshared-key")" +fi + + +mkdir -p "${__object:?}/files" +"${__type:?}/files/wg-peer.sh" "$presharedkey" > "${__object:?}/files/wg-peer" + +required="__file/etc/wireguard/$iface.conf" \ + __block "${__object_id:?}" --file "/etc/wireguard/$iface.conf" \ + --text - <"${__object:?}/files/wg-peer" \ + --state "$state" diff --git a/type/__wireguard_peer/parameter/optional b/type/__wireguard_peer/parameter/optional new file mode 100644 index 0000000..ae643b1 --- /dev/null +++ b/type/__wireguard_peer/parameter/optional @@ -0,0 +1,4 @@ +endpoint +persistent-keepalive +preshared-key +state diff --git a/type/__wireguard_peer/parameter/optional_multiple b/type/__wireguard_peer/parameter/optional_multiple new file mode 100644 index 0000000..f6477ad --- /dev/null +++ b/type/__wireguard_peer/parameter/optional_multiple @@ -0,0 +1 @@ +allowed-ip diff --git a/type/__wireguard_peer/parameter/required b/type/__wireguard_peer/parameter/required new file mode 100644 index 0000000..9bfa644 --- /dev/null +++ b/type/__wireguard_peer/parameter/required @@ -0,0 +1,2 @@ +iface +public-key