From 4f6eb60a53667f88714aea3a8a80654bd928788d Mon Sep 17 00:00:00 2001 From: aptalca Date: Sun, 5 Apr 2020 22:13:28 -0400 Subject: [PATCH] Add templates, add subnet interface var --- README.md | 20 ++++--- readme-vars.yml | 19 ++++--- root/defaults/peer.conf | 10 ++++ root/defaults/server.conf | 6 +++ root/etc/cont-init.d/30-config | 97 ++++++++++++++++++++++++---------- 5 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 root/defaults/peer.conf create mode 100644 root/defaults/server.conf diff --git a/README.md b/README.md index 0f50c91..0995679 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ docker create \ -e SERVERPORT=51820 `#optional` \ -e PEERS=1 `#optional` \ -e PEERDNS=8.8.8.8 `#optional` \ + -e INTERNAL_SUBNET=10.13.13.0 `#optional` \ -p 51820:51820/udp \ -v /path/to/appdata/config:/config \ -v /lib/modules:/lib/modules \ @@ -101,6 +102,7 @@ services: - SERVERPORT=51820 #optional - PEERS=1 #optional - PEERDNS=8.8.8.8 #optional + - INTERNAL_SUBNET=10.13.13.0 #optional volumes: - /path/to/appdata/config:/config - /lib/modules:/lib/modules @@ -122,10 +124,11 @@ Container images are configured using parameters passed at runtime (such as thos | `-e PUID=1000` | for UserID - see below for explanation | | `-e PGID=1000` | for GroupID - see below for explanation | | `-e TZ=Europe/London` | Specify a timezone to use EG Europe/London | -| `-e SERVERURL=wireguard.domain.com` | External IP or domain name for docker host. Required for server mode. | -| `-e SERVERPORT=51820` | External port for docker host. Required for server mode. | +| `-e SERVERURL=wireguard.domain.com` | 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 | +| `-e SERVERPORT=51820` | External port for docker host. Used in server mode. | | `-e PEERS=1` | Number of peers to create confs for. Required for server mode. | -| `-e PEERDNS=8.8.8.8` | DNS server set in peer/client configs. | +| `-e PEERDNS=8.8.8.8` | DNS server set in peer/client configs. Used in server mode. | +| `-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. | | `-v /config` | Contains all relevant configuration files. | | `-v /lib/modules` | Maps host's modules folder. | | `--sysctl=` | Required for client mode. | @@ -166,16 +169,18 @@ If you're on a debian/ubuntu based host with a custom or downstream distro provi This can be run as a server or a client, based on the parameters used. ## Server Mode -Pass the environment variables `SERVERURL`, `SERVERPORT`, `PEERS` and `PEERDNS`, and the container will generate all necessary confs for both the server and the clients. The 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, 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 there is an existing `/config/wg0.conf`, the above environment variables won't have any affect. To add more peers/clients later on, you can run `docker exec -it wireguard /app/add-peer` while the container is running. +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 can run `docker exec -it wireguard /app/add-peer` while the container is running. 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 recreate all server and client confs, set the above env vars, delete `/config/wg0.conf` and restart the container. Client confs will be recreated with existing private/public keys. Delete the peer folders for the keys to be recreated along with the confs. +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. ## Client Mode -Drop your client conf into the config folder as `/config/wg0.conf` and start the container. +Do not set the `PEERS` environment variable. Drop your client conf into the config folder as `/config/wg0.conf` and start the container. @@ -243,5 +248,6 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **05.04.20:** - Add `INTERNAL_SUBNET` variable to prevent subnet clashes. Add templates for server and peer confs. * **01.04.20:** - Add `show-peer` script and include info on host installed headers. * **31.03.20:** - Initial Release. diff --git a/readme-vars.yml b/readme-vars.yml index c547c2d..7d756dd 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -40,10 +40,11 @@ custom_params: # optional container parameters 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. Required for server mode."} - - { env_var: "SERVERPORT", env_value: "51820", desc: "External port for docker host. Required for server mode."} + - { 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: "PEERDNS", env_value: "8.8.8.8", desc: "DNS server set in peer/client configs."} + - { env_var: "PEERDNS", env_value: "8.8.8.8", desc: "DNS server set in peer/client configs. Used in server mode."} + - { 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."} optional_block_1: false optional_block_1_items: "" @@ -65,6 +66,7 @@ custom_compose: | - SERVERPORT=51820 #optional - PEERS=1 #optional - PEERDNS=8.8.8.8 #optional + - INTERNAL_SUBNET=10.13.13.0 #optional volumes: - /path/to/appdata/config:/config - /lib/modules:/lib/modules @@ -84,18 +86,21 @@ app_setup_block: | This can be run as a server or a client, based on the parameters used. ## Server Mode - Pass the environment variables `SERVERURL`, `SERVERPORT`, `PEERS` and `PEERDNS`, and the container will generate all necessary confs for both the server and the clients. The 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, 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 there is an existing `/config/wg0.conf`, the above environment variables won't have any affect. To add more peers/clients later on, you can run `docker exec -it wireguard /app/add-peer` while the container is running. + 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 can run `docker exec -it wireguard /app/add-peer` while the container is running. 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 recreate all server and client confs, set the above env vars, delete `/config/wg0.conf` and restart the container. Client confs will be recreated with existing private/public keys. Delete the peer folders for the keys to be recreated along with the confs. + 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. ## Client Mode - Drop your client conf into the config folder as `/config/wg0.conf` and start the container. + Do not set the `PEERS` environment variable. Drop your client conf into the config folder as `/config/wg0.conf` and start the container. # changelog changelogs: + - { date: "05.04.20:", desc: "Add `INTERNAL_SUBNET` variable to prevent subnet clashes. Add templates for server and peer confs." } - { date: "01.04.20:", desc: "Add `show-peer` script and include info on host installed headers." } - { date: "31.03.20:", desc: "Initial Release." } diff --git a/root/defaults/peer.conf b/root/defaults/peer.conf new file mode 100644 index 0000000..2b5c170 --- /dev/null +++ b/root/defaults/peer.conf @@ -0,0 +1,10 @@ +[Interface] +Address = ${INTERFACE}.$(( $i + 1 )) +PrivateKey = $(cat /config/peer${i}/privatekey-peer${i}) +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 diff --git a/root/defaults/server.conf b/root/defaults/server.conf new file mode 100644 index 0000000..9255d38 --- /dev/null +++ b/root/defaults/server.conf @@ -0,0 +1,6 @@ +[Interface] +Address = ${INTERFACE}.1 +ListenPort = 51820 +PrivateKey = $(cat /config/server/privatekey-server) +PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE diff --git a/root/etc/cont-init.d/30-config b/root/etc/cont-init.d/30-config index 5b80044..29f5639 100644 --- a/root/etc/cont-init.d/30-config +++ b/root/etc/cont-init.d/30-config @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bash -mkdir -p /config +mkdir -p /config/templates # install headers and wireguard apt-get update @@ -53,59 +53,100 @@ else wireguard fi +# prepare symlinks rm -rf /etc/wireguard mkdir -p /etc/wireguard ln -s /config/wg0.conf /etc/wireguard/wg0.conf +# prepare templates +[[ ! -f /config/templates/server.conf ]] && \ + cp /defaults/server.conf /config/templates/server.conf +[[ ! -f /config/templates/peer.conf ]] && \ + cp /defaults/peer.conf /config/templates/peer.conf -if [ ! -f /config/wg0.conf ] && [ -n "$PEERS" ] && [ -n "$SERVERURL" ]; then - SERVERPORT=${SERVERPORT:-51820} - PEERDNS=${PEERDNS:-8.8.8.8} +generate_confs () { mkdir -p /config/server if [ ! -f /config/server/privatekey-server ]; then umask 077 wg genkey | tee /config/server/privatekey-server | wg pubkey > /config/server/publickey-server fi + eval "`printf %s` cat < /config/wg0.conf -[Interface] -Address = 10.13.13.1 -ListenPort = 51820 -PrivateKey = $(cat /config/server/privatekey-server) -PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE -PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE +`cat /config/templates/server.conf` -DUDE - if ! [[ $PEERS =~ ^[0-9]+$ ]]; then - echo "PEERS is not set to an integer, setting it to 1" - PEERS="1" - fi +DUDE" for i in $(seq 1 $PEERS); do mkdir -p /config/peer${i} - if [ ! -f /config/peer${i}/privatekey-peer${i} ]; then + if [ ! -f "/config/peer${i}/privatekey-peer${i}" ]; then umask 077 wg genkey | tee /config/peer${i}/privatekey-peer${i} | wg pubkey > /config/peer${i}/publickey-peer${i} fi + eval "`printf %s` cat < /config/peer${i}/peer${i}.conf -[Interface] -Address = 10.13.13.$(( $i + 1 )) -PrivateKey = $(cat /config/peer${i}/privatekey-peer${i}) -ListenPort = 51820 -DNS = ${PEERDNS} - -[Peer] -PublicKey = $(cat /config/server/publickey-server) -Endpoint = ${SERVERURL}:${SERVERPORT} -AllowedIPs = 0.0.0.0/0, ::/0 -DUDE +`cat /config/templates/peer.conf` +DUDE" cat <> /config/wg0.conf [Peer] PublicKey = $(cat /config/peer${i}/publickey-peer${i}) -AllowedIPs = 10.13.13.$(( $i + 1 ))/32 +AllowedIPs = ${INTERFACE}.$(( $i + 1 ))/32 DUDE 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 done +} + +save_vars () { + cat < /config/.donoteditthisfile +ORIG_SERVERURL=$SERVERURL +ORIG_SERVERPORT=#SERVER_PORT +ORIG_PEERDNS=$PEERDNS +ORIG_PEERS=$PEERS +ORIG_INTERFACE=$INTERFACE +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" + fi + 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" + else + echo "External server address is set to $SERVERURL" + fi + SERVERPORT=${SERVERPORT:-51820} + echo "External server port is set to ${SERVERPORT}. Make sure that port is properly forwarded to port 51820 inside this container" + PEERDNS=${PEERDNS:-8.8.8.8} + echo "DNS server is set to $PEERDNS" + 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--') + if [ ! -f /config/wg0.conf ]; then + echo "No found 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" + generate_confs + save_vars + else + echo "No changes to parameters. Existing configs are used." + fi + fi +else + echo "Client mode selected." + if [ !-f /config/wg0.conf ]; then + "No client conf found. Provide your own client conf as \"/config/wg0.conf\" and restart the container." + sleep infinity + fi fi # permissions