From 83e92571e24527d3459d0168965e763da0ea62e3 Mon Sep 17 00:00:00 2001 From: Cristian Gauxachs Date: Wed, 19 Aug 2020 00:33:52 +0200 Subject: [PATCH] Allow to specify a list of names as PEERS and add ALLOWEDIPS environment variable --- readme-vars.yml | 10 ++++---- root/app/show-peer | 17 ++++++++------ root/defaults/peer.conf | 6 ++--- root/etc/cont-init.d/30-config | 43 ++++++++++++++++++++++------------ 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/readme-vars.yml b/readme-vars.yml index 30da6ea..dc930f4 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -44,9 +44,10 @@ opt_param_usage_include_env: true opt_param_env_vars: - { env_var: "SERVERURL", env_value: "wireguard.domain.com", desc: "External IP or domain name for docker host. Used in server mode. If set to `auto`, the container will try to determine and set the external IP automatically"} - { env_var: "SERVERPORT", env_value: "51820", desc: "External port for docker host. Used in server mode."} - - { env_var: "PEERS", env_value: "1", desc: "Number of peers to create confs for. Required for server mode."} + - { env_var: "PEERS", env_value: "1", desc: "Number of peers to create confs for. Required for server mode. Can be a list of names too: myPC,myPhone,myTablet..."} - { env_var: "PEERDNS", env_value: "auto", desc: "DNS server set in peer/client configs (can be set as `8.8.8.8`). Used in server mode. Defaults to `auto`, which uses wireguard docker host's DNS via included CoreDNS forward."} - { env_var: "INTERNAL_SUBNET", env_value: "10.13.13.0", desc: "Internal subnet for the wireguard and server and peers (only change if it clashes). Used in server mode."} + - { env_var: "ALLOWEDIPS", env_value: "192.168.1.0/24,192.168.2.0/24", desc: "The IPs/Ranges that the peers will be able to reach using the VPN connection. If not specified the default value is: '0.0.0.0/0, ::0/0'"} optional_block_1: false optional_block_1_items: "" @@ -63,13 +64,13 @@ app_setup_block: | This can be run as a server or a client, based on the parameters used. ## Server Mode - If the environment variable `PEERS` is set to a number, the container will run in server mode and the necessary server and peer/client confs will be generated. The peer/client config qr codes will be output in the docker log. They will also be saved in text and png format under `/config/peerX`. + If the environment variable `PEERS` is set to a number or a list of strings separated by comma, the container will run in server mode and the necessary server and peer/client confs will be generated. The peer/client config qr codes will be output in the docker log. They will also be saved in text and png format under `/config/peerX` in case `PEERS` is a variable and an integer or `/config/peer_X` in case a list of names was provided instead of an integer. Variables `SERVERURL`, `SERVERPORT`, `INTERNAL_SUBNET` and `PEERDNS` are optional variables used for server mode. Any changes to these environment variables will trigger regeneration of server and peer confs. Peer/client confs will be recreated with existing private/public keys. Delete the peer folders for the keys to be recreated along with the confs. - To add more peers/clients later on, you increment the `PEERS` environment variable and recreate the container. + To add more peers/clients later on, you increment the `PEERS` environment variable or add more elements to the list and recreate the container. - To display the QR codes of active peers again, you can use the following command and list the peer numbers as arguments: `docker exec -it wireguard /app/show-peer 1 4 5` (Keep in mind that the QR codes are also stored as PNGs in the config folder). + To display the QR codes of active peers again, you can use the following command and list the peer numbers as arguments: `docker exec -it wireguard /app/show-peer 1 4 5` or `docker exec -it wireguard /app/show-peer myPC myPhone myTablet` (Keep in mind that the QR codes are also stored as PNGs in the config folder). The templates used for server and peer confs are saved under `/config/templates`. Advanced users can modify these templates and force conf generation by deleting `/config/wg0.conf` and restarting the container. @@ -87,6 +88,7 @@ app_setup_block: | # changelog changelogs: + - { date: "19.08.20:", desc: "Allow to specify a list of names as PEERS and add ALLOWEDIPS environment variable. Also, add peer name/id to each one of the peer sections in wg0.conf. Important: Existing users need to delete `/config/templates/peer.conf` and restart" } - { date: "06.08.20:", desc: "Replace resolvconf with openresolv due to dns issues when a client based on this image is connected to a server also based on this image. Add IPv6 info to readme. Display kernel version in logs." } - { date: "29.07.20:", desc: "Update Coredns config to detect dns loops (existing users need to delete `/config/coredns/Corefile` and restart)." } - { date: "27.07.20:", desc: "Update Coredns config to prevent issues with non-user-defined bridge networks (existing users need to delete `/config/coredns/Corefile` and restart)." } diff --git a/root/app/show-peer b/root/app/show-peer index b283464..a4523f9 100755 --- a/root/app/show-peer +++ b/root/app/show-peer @@ -5,14 +5,17 @@ if [ ! $# -gt 0 ]; then exit 0 fi -INTERNAL_SUBNET=${INTERNAL_SUBNET:-10.13.13.0} -INTERFACE=$(echo "$INTERNAL_SUBNET" | awk 'BEGIN{FS=OFS="."} NF--') - for i in "$@"; do - if grep -q "AllowedIPs = ${INTERFACE}.$(( $i + 1 ))/32" /config/wg0.conf; then - echo "PEER $i QR code:" - qrencode -t ansiutf8 < /config/peer${i}/peer${i}.conf + if [[ "${i}" =~ ^[0-9]+$ ]]; then + PEER_ID="peer${i}" + else + PEER_ID="peer_${i//[^[:alnum:]_-]/}" + fi + + if grep -q "# ${PEER_ID}" /config/wg0.conf; then + echo "PEER ${i} QR code:" + qrencode -t ansiutf8 < /config/${PEER_ID}/${PEER_ID}.conf else - echo "PEER $i is not active" + echo "PEER ${i} is not active" fi done \ No newline at end of file diff --git a/root/defaults/peer.conf b/root/defaults/peer.conf index 2b5c170..57222d5 100644 --- a/root/defaults/peer.conf +++ b/root/defaults/peer.conf @@ -1,10 +1,10 @@ [Interface] -Address = ${INTERFACE}.$(( $i + 1 )) -PrivateKey = $(cat /config/peer${i}/privatekey-peer${i}) +Address = ${INTERFACE}.${CLIENT_IP_IDX} +PrivateKey = $(cat /config/${PEER_ID}/privatekey-${PEER_ID}) ListenPort = 51820 DNS = ${PEERDNS} [Peer] PublicKey = $(cat /config/server/publickey-server) Endpoint = ${SERVERURL}:${SERVERPORT} -AllowedIPs = 0.0.0.0/0, ::/0 \ No newline at end of file +AllowedIPs = ${ALLOWEDIPS} \ No newline at end of file diff --git a/root/etc/cont-init.d/30-config b/root/etc/cont-init.d/30-config index 4da95f8..197ec94 100644 --- a/root/etc/cont-init.d/30-config +++ b/root/etc/cont-init.d/30-config @@ -172,25 +172,33 @@ generate_confs () { `cat /config/templates/server.conf` DUDE" - for i in $(seq 1 $PEERS); do - mkdir -p /config/peer${i} - if [ ! -f "/config/peer${i}/privatekey-peer${i}" ]; then + CLIENT_IP_IDX=2 + for i in ${PEERS_ARRAY[@]}; do + if [[ "${i}" =~ ^[0-9]+$ ]]; then + PEER_ID="peer${i}" + else + PEER_ID="peer_${i//[^[:alnum:]_-]/}" + fi + mkdir -p /config/${PEER_ID} + if [ ! -f "/config/${PEER_ID}/privatekey-${PEER_ID}" ]; then umask 077 - wg genkey | tee /config/peer${i}/privatekey-peer${i} | wg pubkey > /config/peer${i}/publickey-peer${i} + wg genkey | tee /config/${PEER_ID}/privatekey-${PEER_ID} | wg pubkey > /config/${PEER_ID}/publickey-${PEER_ID} fi eval "`printf %s` - cat < /config/peer${i}/peer${i}.conf + cat < /config/${PEER_ID}/${PEER_ID}.conf `cat /config/templates/peer.conf` DUDE" cat <> /config/wg0.conf [Peer] -PublicKey = $(cat /config/peer${i}/publickey-peer${i}) -AllowedIPs = ${INTERFACE}.$(( $i + 1 ))/32 +# ${PEER_ID} +PublicKey = $(cat /config/${PEER_ID}/publickey-${PEER_ID}) +AllowedIPs = ${INTERFACE}.${CLIENT_IP_IDX}/32 DUDE + CLIENT_IP_IDX=$(( $CLIENT_IP_IDX + 1 )) echo "PEER ${i} QR code:" - qrencode -t ansiutf8 < /config/peer${i}/peer${i}.conf - qrencode -o /config/peer${i}/peer${i}.png < /config/peer${i}/peer${i}.conf + qrencode -t ansiutf8 < /config/${PEER_ID}/${PEER_ID}.conf + qrencode -o /config/${PEER_ID}/${PEER_ID}.png < /config/${PEER_ID}/${PEER_ID}.conf done } @@ -201,15 +209,18 @@ ORIG_SERVERPORT=$SERVERPORT ORIG_PEERDNS=$PEERDNS ORIG_PEERS=$PEERS ORIG_INTERFACE=$INTERFACE +ORIG_ALLOWEDIPS=$ALLOWEDIPS DUDE } if [ -n "$PEERS" ]; then echo "**** Server mode is selected ****" - if ! [[ "$PEERS" =~ ^[0-9]+$ ]]; then - echo "**** PEERS is not set to an integer, setting it to 1 ****" - PEERS="1" + if [[ "$PEERS" =~ ^[0-9]+$ ]] && ! [[ "$PEERS" =~ *,* ]]; then + PEERS_ARRAY=($(seq 1 $PEERS)) + else + PEERS_ARRAY=($(echo "$PEERS" | tr ',' ' ')) fi + PEERS_COUNT=$(echo "${#PEERS_ARRAY[@]}") if [ -z "$SERVERURL" ] || [ "$SERVERURL" = "auto" ]; then SERVERURL=$(curl icanhazip.com) echo "**** SERVERURL var is either not set or is set to \"auto\", setting external IP to auto detected value of $SERVERURL ****" @@ -221,6 +232,8 @@ if [ -n "$PEERS" ]; then INTERNAL_SUBNET=${INTERNAL_SUBNET:-10.13.13.0} echo "**** Internal subnet is set to $INTERNAL_SUBNET ****" INTERFACE=$(echo "$INTERNAL_SUBNET" | awk 'BEGIN{FS=OFS="."} NF--') + ALLOWEDIPS=${ALLOWEDIPS:-0.0.0.0/0, ::/0} + echo "**** AllowedIPs for peers $ALLOWEDIPS ****" if [ -z "$PEERDNS" ] || [ "$PEERDNS" = "auto" ]; then PEERDNS="${INTERFACE}.1" echo "**** PEERDNS var is either not set or is set to \"auto\", setting peer DNS to ${INTERFACE}.1 to use wireguard docker host's DNS. ****" @@ -228,15 +241,15 @@ if [ -n "$PEERS" ]; then echo "**** Peer DNS servers will be set to $PEERDNS ****" fi if [ ! -f /config/wg0.conf ]; then - echo "**** No found wg0.conf found (maybe an initial install), generating 1 server and $PEERS peer/client confs ****" + echo "**** No wg0.conf found (maybe an initial install), generating 1 server and ${PEERS} peer/client confs ****" generate_confs save_vars else echo "**** Server mode is selected ****" [[ -f /config/.donoteditthisfile ]] && \ . /config/.donoteditthisfile - if [ "$SERVERURL" != "$ORIG_SERVERURL" ] || [ "$SERVERPORT" != "$ORIG_SERVERPORT" ] || [ "$PEERDNS" != "$ORIG_PEERDNS" ] || [ "$PEERS" != "$ORIG_PEERS" ] || [ "$INTERFACE" != "$ORIG_INTERFACE" ]; then - echo "**** Server related environment variables changed, regenerating 1 server and $PEERS peer/client confs ****" + if [ "$SERVERURL" != "$ORIG_SERVERURL" ] || [ "$SERVERPORT" != "$ORIG_SERVERPORT" ] || [ "$PEERDNS" != "$ORIG_PEERDNS" ] || [ "$PEERS" != "$ORIG_PEERS" ] || [ "$INTERFACE" != "$ORIG_INTERFACE" ] || [ "$ALLOWEDIPS" != "$ORIG_ALLOWEDIPS" ]; then + echo "**** Server related environment variables changed, regenerating 1 server and ${PEERS} peer/client confs ****" generate_confs save_vars else