From 841ffdf7300e99e976c564d5179ade0d2104d85b Mon Sep 17 00:00:00 2001 From: aptalca Date: Mon, 9 Jan 2023 20:14:25 -0500 Subject: [PATCH 1/2] add persistenkeepalive to server conf for select peers to survive host IP changes when using domain name --- README.md | 8 +++++-- readme-vars.yml | 6 +++-- .../s6-rc.d/init-wireguard-confs/run | 24 +++++++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b9c4c9a..b5cba06 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,9 @@ 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 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. +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 if `LOG_CONFS` is set to `true`. 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. +Variables `SERVERURL`, `SERVERPORT`, `INTERNAL_SUBNET`, `PEERDNS`, `INTERFACE`, `ALLOWEDIPS` and `PERSISTENTKEEPALIVE_PEERS` 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 or add more elements to the list and recreate the container. @@ -159,6 +159,7 @@ services: - PEERDNS=auto #optional - INTERNAL_SUBNET=10.13.13.0 #optional - ALLOWEDIPS=0.0.0.0/0 #optional + - PERSISTENTKEEPALIVE_PEERS= #optional - LOG_CONFS=true #optional volumes: - /path/to/appdata/config:/config @@ -186,6 +187,7 @@ docker run -d \ -e PEERDNS=auto `#optional` \ -e INTERNAL_SUBNET=10.13.13.0 `#optional` \ -e ALLOWEDIPS=0.0.0.0/0 `#optional` \ + -e PERSISTENTKEEPALIVE_PEERS= `#optional` \ -e LOG_CONFS=true `#optional` \ -p 51820:51820/udp \ -v /path/to/appdata/config:/config \ @@ -211,6 +213,7 @@ Container images are configured using parameters passed at runtime (such as thos | `-e PEERDNS=auto` | 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. | | `-e INTERNAL_SUBNET=10.13.13.0` | Internal subnet for the wireguard and server and peers (only change if it clashes). Used in server mode. | | `-e ALLOWEDIPS=0.0.0.0/0` | 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' This will cause ALL traffic to route through the VPN, if you want split tunneling, set this to only the IPs you would like to use the tunnel AND the ip of the server's WG ip, such as 10.13.13.1. | +| `-e PERSISTENTKEEPALIVE_PEERS=` | Set to `all` or a list of comma separated peers (ie. `1,4,laptop`) for the wireguard server to send keepalive packets to listed peers every 25 seconds. Useful if server is accessed via domain name and has dynamic IP. Used only in server mode. | | `-e LOG_CONFS=true` | Generated QR codes will be displayed in the docker log. Set to `false` to skip log output. | | `-v /config` | Contains all relevant configuration files. | | `-v /lib/modules` | Maps host's modules folder. Only required if compiling wireguard modules. | @@ -329,6 +332,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **10.01.23:** - Add new var to add `PersistentKeepalive` to server config for select peers to survive server IP changes when domain name is used. * **26.10.22:** - Better handle unsupported peer names. Improve logging. * **12.10.22:** - Add Alpine branch. Optimize wg and coredns services. * **09.10.22:** - Switch back to iptables-legacy due to issues on some hosts. diff --git a/readme-vars.yml b/readme-vars.yml index f0e4ad8..1638bf3 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -50,6 +50,7 @@ opt_param_env_vars: - { 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: "0.0.0.0/0", 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' This will cause ALL traffic to route through the VPN, if you want split tunneling, set this to only the IPs you would like to use the tunnel AND the ip of the server's WG ip, such as 10.13.13.1."} + - { env_var: "PERSISTENTKEEPALIVE_PEERS", env_value: "", desc: "Set to `all` or a list of comma separated peers (ie. `1,4,laptop`) for the wireguard server to send keepalive packets to listed peers every 25 seconds. Useful if server is accessed via domain name and has dynamic IP. Used only in server mode."} - { env_var: "LOG_CONFS", env_value: "true", desc: "Generated QR codes will be displayed in the docker log. Set to `false` to skip log output."} optional_block_1: false @@ -70,9 +71,9 @@ app_setup_block: | ## Server Mode - 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. + 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 if `LOG_CONFS` is set to `true`. 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. + Variables `SERVERURL`, `SERVERPORT`, `INTERNAL_SUBNET`, `PEERDNS`, `INTERFACE`, `ALLOWEDIPS` and `PERSISTENTKEEPALIVE_PEERS` 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 or add more elements to the list and recreate the container. @@ -126,6 +127,7 @@ app_setup_block: | # changelog changelogs: + - { date: "10.01.23:", desc: "Add new var to add `PersistentKeepalive` to server config for select peers to survive server IP changes when domain name is used." } - { date: "26.10.22:", desc: "Better handle unsupported peer names. Improve logging." } - { date: "12.10.22:", desc: "Add Alpine branch. Optimize wg and coredns services." } - { date: "09.10.22:", desc: "Switch back to iptables-legacy due to issues on some hosts." } diff --git a/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run b/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run index 189f9ce..925caee 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run +++ b/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run @@ -87,16 +87,25 @@ DUDE echo "Adding ${!SERVER_ALLOWEDIPS} to wg0.conf's AllowedIPs for peer ${i}" cat <> /config/wg0.conf AllowedIPs = ${CLIENT_IP}/32,${!SERVER_ALLOWEDIPS} +DUDE + else + cat <> /config/wg0.conf +AllowedIPs = ${CLIENT_IP}/32 +DUDE + fi + # add PersistentKeepalive if the peer is specified + if [ -n "${PERSISTENTKEEPALIVE_PEERS_ARRAY}" ] && ([ "${PERSISTENTKEEPALIVE_PEERS_ARRAY[0]}" = "all" ] || printf '%s\0' "${PERSISTENTKEEPALIVE_PEERS_ARRAY[@]}" | grep -Fxqz -- "${i}"); then + cat <> /config/wg0.conf +PersistentKeepalive = 25 DUDE - else - cat <> /config/wg0.conf -AllowedIPs = ${CLIENT_IP}/32 + else + cat <> /config/wg0.conf DUDE fi if [ -z "${LOG_CONFS}" ] || [ "${LOG_CONFS}" = "true" ]; then - echo "PEER ${i} QR code:" + echo "PEER ${i} QR code (conf file is saved under /config/${PEER_ID}):" qrencode -t ansiutf8 < /config/${PEER_ID}/${PEER_ID}.conf else echo "PEER ${i} conf and QR code png saved in /config/${PEER_ID}" @@ -114,6 +123,7 @@ ORIG_PEERDNS="$PEERDNS" ORIG_PEERS="$PEERS" ORIG_INTERFACE="$INTERFACE" ORIG_ALLOWEDIPS="$ALLOWEDIPS" +ORIG_PERSISTENTKEEPALIVE_PEERS="$PERSISTENTKEEPALIVE_PEERS" DUDE } @@ -125,6 +135,10 @@ if [ -n "$PEERS" ]; then PEERS_ARRAY=($(echo "$PEERS" | tr ',' ' ')) fi PEERS_COUNT=$(echo "${#PEERS_ARRAY[@]}") + if [ "${PERSISTENTKEEPALIVE_PEERS}" = "all" ] || [ "${PERSISTENTKEEPALIVE_PEERS}" =~ *,* ]; then + echo "**** PersistentKeepalive will be set for: ${PERSISTENTKEEPALIVE_PEERS/,/ } ****" + PERSISTENTKEEPALIVE_PEERS_ARRAY=($(echo "$PERSISTENTKEEPALIVE_PEERS" | tr ',' ' ')) + fi if [ -z "$SERVERURL" ] || [ "$SERVERURL" = "auto" ]; then SERVERURL=$(curl -s icanhazip.com) echo "**** SERVERURL var is either not set or is set to \"auto\", setting external IP to auto detected value of $SERVERURL ****" @@ -152,7 +166,7 @@ if [ -n "$PEERS" ]; then 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" ] || [ "$ALLOWEDIPS" != "$ORIG_ALLOWEDIPS" ]; then + if [ "$SERVERURL" != "$ORIG_SERVERURL" ] || [ "$SERVERPORT" != "$ORIG_SERVERPORT" ] || [ "$PEERDNS" != "$ORIG_PEERDNS" ] || [ "$PEERS" != "$ORIG_PEERS" ] || [ "$INTERFACE" != "$ORIG_INTERFACE" ] || [ "$ALLOWEDIPS" != "$ORIG_ALLOWEDIPS" ] || [ "$PERSISTENTKEEPALIVE_PEERS" != "$ORIG_PERSISTENTKEEPALIVE_PEERS" ]; then echo "**** Server related environment variables changed, regenerating 1 server and ${PEERS} peer/client confs ****" generate_confs save_vars From 1fc1cd5f354ddfd424d932471feb487fbc711ea0 Mon Sep 17 00:00:00 2001 From: aptalca Date: Tue, 10 Jan 2023 14:09:40 -0500 Subject: [PATCH 2/2] account for a single peer listed for keepalive --- root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run b/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run index 925caee..f386671 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run +++ b/root/etc/s6-overlay/s6-rc.d/init-wireguard-confs/run @@ -135,7 +135,7 @@ if [ -n "$PEERS" ]; then PEERS_ARRAY=($(echo "$PEERS" | tr ',' ' ')) fi PEERS_COUNT=$(echo "${#PEERS_ARRAY[@]}") - if [ "${PERSISTENTKEEPALIVE_PEERS}" = "all" ] || [ "${PERSISTENTKEEPALIVE_PEERS}" =~ *,* ]; then + if [ -n "${PERSISTENTKEEPALIVE_PEERS}" ]; then echo "**** PersistentKeepalive will be set for: ${PERSISTENTKEEPALIVE_PEERS/,/ } ****" PERSISTENTKEEPALIVE_PEERS_ARRAY=($(echo "$PERSISTENTKEEPALIVE_PEERS" | tr ',' ' ')) fi