From 3ac9c23573ddaf81ea4e525fb0105dde95b29226 Mon Sep 17 00:00:00 2001 From: Daan Date: Thu, 24 Oct 2024 10:13:33 +0200 Subject: [PATCH] Removed the default value: wg0 in isolate and enable. Removed clean_up() function because persistency is done differently. Overal tried to make readability better in entrypoint.sh Fixed bug where local config variable causes issues. Applied ShellCheck recommendations. --- Dockerfile | 8 +--- docker/README.md | 4 +- docker/compose.yaml | 8 ++-- entrypoint.sh | 98 +++++++++++++++++++-------------------------- 4 files changed, 49 insertions(+), 69 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5f37723..c3bd8d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ARG wg_port="51820" ENV TZ="Europe/Amsterdam" ENV global_dns="1.1.1.1" ENV enable="none" -ENV isolate="wg0" +ENV isolate="none" ENV public_ip="0.0.0.0" # Doing package management operations, such as upgrading @@ -29,10 +29,6 @@ RUN mkdir /data \ && mkdir -p ${WGDASH}/src COPY ./src ${WGDASH}/src -# Set the volume to be used for WireGuard configuration persistency. Can be ignored so it does not create volumes when not specified. -#VOLUME /etc/wireguard -#VOLUME /data - # Generate basic WireGuard interface. Echoing the WireGuard interface config for readability, adjust if you want it for efficiency. # Also setting the pipefail option, verbose: https://github.com/hadolint/hadolint/wiki/DL4006. SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -49,7 +45,7 @@ SaveConfig = true\n\ DNS = ${global_dns}" > /configs/wg0.conf.template \ && chmod 600 /configs/wg0.conf.template -# Defining a way for Docker to check the health of the container. In this case: checking the login URL. +# Defining a way for Docker to check the health of the container. In this case: checking the gunicorn process. HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1 diff --git a/docker/README.md b/docker/README.md index 349424c..541581b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -79,7 +79,7 @@ So go to the assign TCP port in this case HTTP, like the default 10086 one in th | tz | Europe/Amsterdam or any confirming timezone notation. | `Europe/Amsterdam` | `America/New_York` | Sets the timezone of the Docker container. This is to timesync the container to any other processes which would need it. | | global_dns | Any IPv4 address, such as my personal recommendation: 9.9.9.9 (QUAD9). | `1.1.1.1` | `8.8.8.8` or any IP-Address that resolves DNS-names, and of course is reachable | Set the default DNS given to clients once they connect to the WireGuard tunnel, and for new peers, set to Cloudflare DNS for reliability. | enable | Anything, preferably an existing WireGuard interface name. | `none` | `wg0,wg2,wg13` | Enables or disables the starting of the WireGuard interface on container 'boot-up'. -| isolate | Anything, preferably an existing WireGuard interface name. | `wg0` | `wg1,wg0` | For security premade `wg0` interface comes with this feature enabled by default. Declaring `isolate=none` in the Docker Compose file will remove this. The WireGuard interface itself IS able to reach the peers (Done through the `iptables` package). +| isolate | Anything, preferably an existing WireGuard interface name. | `none` | `wg1,wg0` | The Wireguard interface itself IS able to reach the peers (Done through the `iptables` package). | public_ip | Any IPv4 (public recommended) address, such as the one returned by default | Default uses the return of `curl ifconfig.me` | `89.20.83.118` | To reach your VPN from outside your own network, you need WG-Dashboard to know what your public IP-address is, otherwise it will generate faulty config files for clients. This happends because it is inside a Docker/Kubernetes container. In or outside of NAT is not relevant as long as the given IP-address is reachable from the internet or the target network. ## Be careful with: @@ -104,4 +104,4 @@ dselen/wgdashboard latest c96fd96ee3b3 42 minutes ago 314MB ## Closing remarks: -For feedback please submit an issue to the repository. Or message dselen@nerthus.nl. \ No newline at end of file +For feedback please submit an issue to the repository. Or message dselen@nerthus.nl. diff --git a/docker/compose.yaml b/docker/compose.yaml index f06461f..e5c7b6e 100644 --- a/docker/compose.yaml +++ b/docker/compose.yaml @@ -5,10 +5,10 @@ services: container_name: wgdashboard environment: #- tz= # <--- Set container timezone, default: Europe/Amsterdam. - - global_dns=9.9.9.9 # <--- Set global DNS address, default: 1.1.1.1. - - enable=wg0 # <--- Set the interfaces that will be enabled on startup, default: none. The option "off" is also allowed. - - isolate=wg0 # <--- Set the interfaces that will disallow peer communication, default: wg0. - #- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me. + #- global_dns= # <--- Set global DNS address, default: 1.1.1.1. + #- enable= # <--- Set the interfaces that will be enabled on startup, default: 'none'. + #- isolate= # <--- Set the interfaces that will disallow peer communication, default: 'none'. + #- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me. ports: - 10086:10086/tcp - 51820:51820/udp diff --git a/entrypoint.sh b/entrypoint.sh index e64e8dc..08ed769 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -34,7 +34,8 @@ ensure_installation() { echo "Setting a secure private key." # SORRY 4 BE4 - Daan - local privateKey=$(wg genkey) + local privateKey + privateKey=$(wg genkey) sed -i "s|^PrivateKey *=.*$|PrivateKey = ${privateKey}|g" /etc/wireguard/wg0.conf echo "Done setting template." @@ -43,42 +44,6 @@ ensure_installation() { fi } -clean_up() { - printf "\n------------------------ CLEAN UP --------------------------\n" - - local pid_file="${WGDASH}/src/gunicorn.pid" - local pycache="${WGDASH}/src/__pycache__" - local logdir="${WGDASH}/src/log" - - echo "Looking for remains of previous instances..." - - # Handle the .pid file cleanup - if [ -f "$pid_file" ]; then - echo "Found old pid file, removing." - rm -f "$pid_file" - else - echo "No pid remains found, continuing." - fi - - # Remove Python caches (__pycache__) - echo "Looking for remains of pycache..." - if [ -d "$pycache" ]; then - if find "$pycache" -type f -print -quit | grep -q .; then - echo "Found old pycaches, removing." - rm -rf "$pycache" - else - echo "No pycaches found, continuing." - fi - else - echo "No pycaches directory found, continuing." - fi - - # Clean up log files - echo "Cleaning log directory..." - find "$logdir" -type f -name 'access_*.log' -o -name 'error_*.log' -exec rm -f {} + - echo "Removed unneeded logs!" -} - set_envvars() { printf "\n------------- SETTING ENVIRONMENT VARIABLES ----------------\n" @@ -97,7 +62,7 @@ set_envvars() { } > "$config_file" else - echo "Config file is not empty" + echo "Config file is not empty, enforcing environment variables." # Check and update the DNS if it has changed current_dns=$(grep "peer_global_dns = " "$config_file" | awk '{print $NF}') @@ -111,12 +76,15 @@ set_envvars() { # Determine the public IP and update if necessary if [ "${public_ip}" = "0.0.0.0" ]; then default_ip=$(curl -s ifconfig.me) + echo "Trying to fetch the Public-IP using ifconfig.me: ${default_ip}" sed -i "s/^remote_endpoint = .*/remote_endpoint = ${default_ip}/" "$config_file" else current_ip=$(grep "remote_endpoint = " "$config_file" | awk '{print $NF}') + if [ "${public_ip}" != "$current_ip" ]; then echo "Setting the Public-IP using given variable: ${public_ip}" + sed -i "s/^remote_endpoint = .*/remote_endpoint = ${public_ip}/" "$config_file" fi @@ -125,8 +93,6 @@ set_envvars() { fi } - - # === CORE SERVICES === start_core() { printf "\n---------------------- STARTING CORE -----------------------\n" @@ -148,49 +114,64 @@ start_core() { # Checking if there are matches between the two arrays. for config in "${configurations[@]}"; do - local config=$(echo "$config" | sed -e 's|.*/etc/wireguard/||' -e 's|\.conf$||') + config=$(echo "$config" | sed -e 's|.*/etc/wireguard/||' -e 's|\.conf$||') + + local found found=false + for interface in "${do_isolate[@]}"; do + if [[ "$config" == "$interface" ]]; then found=true break fi + done + if [ "$found" = false ]; then non_isolate+=("$config") fi + done # Isolating the matches. for interface in "${do_isolate[@]}"; do - if [ "$interface" = "none" ]; then + + if [ "$interface" = "none" ] || [ "$interface" = "" ]; then echo "Found: $interface, stopping isolation checking." break else if [ -f "/etc/wireguard/${interface}.conf" ]; then - echo "Isolating interface:" $interface - upblocking=$(grep -c "PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/${interface}.conf) - downblocking=$(grep -c "PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/${interface}.conf) + echo "Isolating interface:" "$interface" + + upblocking=$(grep -c "PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf) + downblocking=$(grep -c "PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf) if [ "$upblocking" -lt 1 ] && [ "$downblocking" -lt 1 ]; then - sed -i "/PostUp =/a PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/${interface}.conf - sed -i "/PreDown =/a PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/${interface}.conf + sed -i "/PostUp =/a PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf + sed -i "/PreDown =/a PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP" /etc/wireguard/"${interface}".conf fi + else - echo "Configuration for $interface does not seem to exist, continuing." + echo "Configuration for $interface in enforce isolation does not seem to exist, continuing." fi + fi + done # Removing isolation for the configurations that did not match. for interface in "${non_isolate[@]}"; do + if [ -f "/etc/wireguard/${interface}.conf" ]; then - echo "Removing Isolation if present for:" $interface - sed -i "/PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/${interface}.conf - sed -i "/PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/${interface}.conf + echo "Removing isolation, if isolation is present for:" "$interface" + + sed -i "/PostUp = iptables -I FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/"${interface}".conf + sed -i "/PreDown = iptables -D FORWARD -i ${interface} -o ${interface} -j DROP/d" /etc/wireguard/"${interface}".conf else - echo "Configuration for $interface does not seem to exist, continuing." + echo "Configuration for $interface in removing isolation does not seem to exist, continuing." fi + done # The following section takes care of enabling wireguard interfaces on startup. Using arrays and given arguments. @@ -201,24 +182,28 @@ start_core() { IFS=',' read -r -a enable_array <<< "${enable}" for interface in "${enable_array[@]}"; do + if [ "$interface" = "none" ]; then echo "Found: $interface, stopping enabling checking." break else - echo "Enabling interface:" $interface + echo "Enabling interface:" "$interface" - local fileperms=$(stat -c "%a" /etc/wireguard/${interface}.conf) - if [ $fileperms -eq 644 ]; then + local fileperms + fileperms=$(stat -c "%a" /etc/wireguard/"${interface}".conf) + if [ "$fileperms" -eq 644 ]; then echo "Configuration is world accessible, adjusting." chmod 600 "/etc/wireguard/${interface}.conf" fi if [ -f "/etc/wireguard/${interface}.conf" ]; then - wg-quick up $interface + wg-quick up "$interface" else echo "No corresponding configuration file found for $interface doing nothing." fi + fi + done } @@ -246,6 +231,5 @@ ensure_blocking() { # Execute functions for the WireGuard Dashboard services, then set the environment variables ensure_installation set_envvars -clean_up start_core ensure_blocking \ No newline at end of file