1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-22 15:20:09 +01:00

Modified all files and have a working product, awaiting feedback!

This commit is contained in:
Dselen 2024-08-22 13:38:29 -05:00
parent 47ac438844
commit 8703798ca0
4 changed files with 153 additions and 111 deletions

View File

@ -3,8 +3,9 @@ FROM debian:stable-slim AS build
LABEL maintainer="dselen@nerthus.nl" LABEL maintainer="dselen@nerthus.nl"
# Declaring environment variables, change Peernet to an address you like, standard is a 24 bit subnet. # Declaring environment variables, change Peernet to an address you like, standard is a 24 bit subnet.
ENV wg_net="10.0.0.1" ARG Git_Url="https://github.com/donaldzou/WGDashboard.git"
# wg_net is used functionally as an ARG for its environment variable nature, do not change unless you know what you are doing. ARG wg_net="10.0.0.1"
ARG wg_port="51820"
# Following ENV variables are changable on container runtime because /entrypoint.sh handles that. See compose.yaml for more info. # Following ENV variables are changable on container runtime because /entrypoint.sh handles that. See compose.yaml for more info.
ENV tz="Europe/Amsterdam" ENV tz="Europe/Amsterdam"
@ -12,6 +13,7 @@ ENV global_dns="1.1.1.1"
ENV enable="none" ENV enable="none"
ENV isolate="wg0" ENV isolate="wg0"
ENV public_ip="0.0.0.0" ENV public_ip="0.0.0.0"
ENV update="yes"
# Doing basic system maintenance. Change the timezone to the desired timezone. # Doing basic system maintenance. Change the timezone to the desired timezone.
RUN ln -sf /usr/share/zoneinfo/${tz} /etc/localtime RUN ln -sf /usr/share/zoneinfo/${tz} /etc/localtime
@ -20,8 +22,7 @@ RUN ln -sf /usr/share/zoneinfo/${tz} /etc/localtime
ENV WGDASH=/opt/wireguarddashboard ENV WGDASH=/opt/wireguarddashboard
# Doing package management operations, such as upgrading # Doing package management operations, such as upgrading
RUN apt-get update && \ RUN apt-get update && apt-get install -y --no-install-recommends \
apt-get install -y --no-install-recommends \
curl \ curl \
git \ git \
iproute2 \ iproute2 \
@ -44,13 +45,8 @@ RUN apt-get update && \
# Removing the Linux Image package to preserve space on the image, for this reason also deleting apt lists, to be able to install packages: run apt update. # Removing the Linux Image package to preserve space on the image, for this reason also deleting apt lists, to be able to install packages: run apt update.
# Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example. # Doing WireGuard Dashboard installation measures. Modify the git clone command to get the preferred version, with a specific branch for example.
RUN git clone https://github.com/donaldzou/WGDashboard.git ${WGDASH} \ RUN mkdir -p /setup/conf && mkdir /setup/app && mkdir ${WGDASH} \
&& rm ${WGDASH}/.git -rdf \ && git clone ${Git_Url} /setup/app
&& python3 -m venv ${WGDASH}/src/venv \
&& . ${WGDASH}/src/venv/bin/activate \
&& chmod +x ${WGDASH}/src/wgd.sh \
&& cd ${WGDASH}/src \
&& ./wgd.sh install
# Set the volume to be used for WireGuard configuration persistency. # Set the volume to be used for WireGuard configuration persistency.
VOLUME /etc/wireguard VOLUME /etc/wireguard
@ -60,20 +56,20 @@ VOLUME ${WGDASH}
# Also setting the pipefail option, verbose: https://github.com/hadolint/hadolint/wiki/DL4006. # Also setting the pipefail option, verbose: https://github.com/hadolint/hadolint/wiki/DL4006.
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN wg genkey | tee /etc/wireguard/wg0_privatekey \ RUN wg genkey | tee /etc/wireguard/wg0_privatekey \
&& echo "[Interface]" > /wg0.conf \ && echo "[Interface]" > /setup/conf/wg0.conf \
&& echo "SaveConfig = true" >> /wg0.conf \ && echo "Address = ${wg_net}/24" >> /setup/conf/wg0.conf \
&& echo "Address = ${wg_net}/24" >> /wg0.conf \ && echo "PrivateKey = $(cat /etc/wireguard/wg0_privatekey)" >> /setup/conf/wg0.conf \
&& echo "PrivateKey = $(cat /etc/wireguard/wg0_privatekey)" >> /wg0.conf \ && echo "PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o $(ip -o -4 route show to default | awk '{print $NF}') -j MASQUERADE" >> /setup/conf/wg0.conf \
&& echo "PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o $(ip -o -4 route show to default | awk '{print $NF}') -j MASQUERADE" >> /wg0.conf \ && echo "PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP" >> /setup/conf/wg0.conf \
&& echo "PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP" >> /wg0.conf \ && echo "PreDown = iptables -t nat -D POSTROUTING -s ${wg_net}/24 -o $(ip -o -4 route show to default | awk '{print $NF}') -j MASQUERADE" >> /setup/conf/wg0.conf \
&& echo "PreDown = iptables -t nat -D POSTROUTING -s ${wg_net}/24 -o $(ip -o -4 route show to default | awk '{print $NF}') -j MASQUERADE" >> /wg0.conf \ && echo "PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP" >> /setup/conf/wg0.conf \
&& echo "PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP" >> /wg0.conf \ && echo "ListenPort = ${wg_port}" >> /setup/conf/wg0.conf \
&& echo "ListenPort = 51820" >> /wg0.conf \ && echo "SaveConfig = true" >> /setup/conf/wg0.conf \
#&& echo "DNS = ${global_dns}" >> /wg0.conf \ && echo "DNS = ${global_dns}" >> /setup/conf/wg0.conf \
&& rm /etc/wireguard/wg0_privatekey && rm /etc/wireguard/wg0_privatekey
# 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 login URL.
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ HEALTHCHECK --interval=2m --timeout=1m --start-period=5s --retries=3 \
CMD [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:10086/)" -eq "200" ] || exit 1 CMD [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:10086/)" -eq "200" ] || exit 1

View File

@ -15,7 +15,9 @@ I have tried to embed some new features such as `isolate` and interface startup
## Getting the container running: ## Getting the container running:
To get the container running you either pull the image from the repository, `dselen/wgdashboard:latest`.<br> To get the container running you either pull the image from the repository, `dselen/wgdashboard:latest`.<br>
From there either use the environment variables describe below as parameters or use the Docker Compose file: `compose.yaml`. From there either use the environment variables describe below as parameters or use the Docker Compose file: `compose.yaml`.<br>
Be careful, the default generated WireGuard configuration file uses port 51820/udp. So use this port if you want to use it out of the box.<br>
Otherwise edit the configuration file in `/etc/wireguard/wg0.conf`.
An example of a simple command to get the container running is show below:<br> An example of a simple command to get the container running is show below:<br>

View File

@ -2,22 +2,22 @@ services:
wireguard-dashboard: wireguard-dashboard:
image: dselen/wgdashboard:latest image: dselen/wgdashboard:latest
restart: unless-stopped restart: unless-stopped
container_name: wire-dash container_name: wgdashboard
environment: environment:
#- tz= # <--- Set container timezone, default: Europe/Amsterdam. #- tz= # <--- Set container timezone, default: Europe/Amsterdam.
#- global_dns= # <--- Set global DNS address, default: 1.1.1.1. #- global_dns= # <--- Set global DNS address, default: 1.1.1.1.
- enable=wg0,wg2 # <--- Set the interfaces that will be enabled on startup, default: none. The option "off" is also allowed. - enable=wg0 # <--- Set the interfaces that will be enabled on startup, default: none. The option "off" is also allowed.
- isolate=wg0,wg1 # <--- When set to true, it disallows peers to talk to eachother, setting to false, allows it, default: true. - isolate=wg0 # <--- When set to true, it disallows peers to talk to eachother, setting to false, allows it, default: true.
#- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me. #- public_ip= # <--- Set public IP to ensure the correct one is chosen, defaulting to the IP give by ifconfig.me.
ports: ports:
- 10086:10086/tcp - 10086:10086/tcp
- 51830:51820/udp - 51820:51820/udp
volumes: volumes:
- conf:/etc/wireguard
- app:/opt/wireguarddashboard - app:/opt/wireguarddashboard
- conf:/etc/wireguard
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
volumes: volumes:
conf:
app: app:
conf:

View File

@ -1,9 +1,40 @@
#!/bin/bash #!/bin/bash
echo "------------------------- START ----------------------------"
echo "Starting the WireGuard Dashboard Docker container." echo "Starting the WireGuard Dashboard Docker container."
ensure_installation() {
# When using a custom directory to store the files, this part moves over and makes sure the installation continues.
echo "Checking if everything is present."
if [ -z "$(ls -A ${WGDASH})" ]; then
echo "Detected empty directory, moving over..."
mv /setup/app/* ${WGDASH}
python3 -m venv ${WGDASH}/src/venv
. "${WGDASH}/src/venv/bin/activate"
chmod +x ${WGDASH}/src/wgd.sh
cd ${WGDASH}/src
./wgd.sh install
echo "Looks like the installation succesfully moved over."
else
echo "Looks like everything is present."
fi
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage.
if [ ! -f "/etc/wireguard/wg0.conf" ]; then
echo "Standard wg0 Configuration file not found, grabbing template."
cp "/setup/conf/wg0.conf" "/etc/wireguard/wg0.conf"
else
echo "Standard wg0 Configuration file found, using that."
fi
}
# === CLEAN UP === # === CLEAN UP ===
clean_up() { clean_up() {
echo "--------------------- CLEAN UP -----------------------" printf "\n------------------------ CLEAN UP --------------------------\n"
# Cleaning out previous data such as the .pid file and starting the WireGuard Dashboard. Making sure to use the python venv. # Cleaning out previous data such as the .pid file and starting the WireGuard Dashboard. Making sure to use the python venv.
echo "Looking for remains of previous instances..." echo "Looking for remains of previous instances..."
local pid_file="${WGDASH}/src/gunicorn.pid" local pid_file="${WGDASH}/src/gunicorn.pid"
@ -14,6 +45,7 @@ clean_up() {
echo "No pid remains found, continuing." echo "No pid remains found, continuing."
fi fi
# Also check for Python caches (pycache) inspired by https://github.com/shuricksumy
local pycache="${WGDASH}/src/__pycache__" local pycache="${WGDASH}/src/__pycache__"
if [ -d "$pycache" ]; then if [ -d "$pycache" ]; then
local pycache_filecount=$(find "$pycache" -maxdepth 1 -type f | wc -l) local pycache_filecount=$(find "$pycache" -maxdepth 1 -type f | wc -l)
@ -26,89 +58,22 @@ clean_up() {
else else
echo "No pycaches found, continuing." echo "No pycaches found, continuing."
fi fi
echo "Setting permissions to not be world-accesible."
chmod 640 /etc/wireguard/*
} }
# === CORE SERVICES === #update_checker() {
start_core() { #if [ "$update" = "yes" ]; then
echo "--------------------- STARTING CORE -----------------------" # echo "Activating Python venv and executing the WireGuard Dashboard service."
# . "${WGDASH}/src/venv/bin/activate"
# This first step is to ensure the wg0.conf file exists, and if not, then its copied over from the ephemeral container storage. # cd "${WGDASH}"/src || exit
if [ ! -f "/etc/wireguard/wg0.conf" ]; then # bash wgd.sh update
cp "/wg0.conf" "/etc/wireguard/wg0.conf" #else
echo "Standard WG0 Configuration file not found, grabbing template." # echo "Auto Updater disabled"
else #fi
echo "Standard WG0 Configuration file found, using that." #}
fi
echo "Activating Python venv and executing the WireGuard Dashboard service."
. "${WGDASH}"/src/venv/bin/activate
cd "${WGDASH}"/src || return # If changing the directory fails (permission or presence error), then bash will exist this function, causing the WireGuard Dashboard to not be succesfully launched.
bash wgd.sh start
# Isolated peers feature:
local configurations=(/etc/wireguard/*)
IFS=',' read -r -a do_isolate <<< "${isolate}"
non_isolate=()
for config in "${configurations[@]}"; do
local config=$(echo "$config" | sed -e 's|.*/etc/wireguard/||' -e 's|\.conf$||')
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
for interface in "${do_isolate[@]}"; do
if [ -f "/etc/wireguard/${interface}.conf" ]; then
echo "Isolating:" $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
fi
else
echo "Configuration for $interface does not seem to exist, continuing."
fi
done
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
else
echo "Configuration for $interface does not seem to exist, continuing."
fi
done
# The following section takes care of enabling wireguard interfaces on startup.
IFS=',' read -r -a enable_array <<< "${enable}"
for interface in "${enable_array[@]}"; do
echo "Preference for $interface to be turned on found."
if [ -f "/etc/wireguard/${interface}.conf" ]; then
echo "Found corresponding configuration file, activating..."
wg-quick up $interface
else
echo "No corresponding configuration file found for $interface doing nothing."
fi
done
}
# === SET ENV VARS === # === SET ENV VARS ===
set_envvars() { set_envvars() {
echo "------------- SETTING ENVIRONMENT VARIABLES ----------------" printf "\n------------- SETTING ENVIRONMENT VARIABLES ----------------\n"
# If the timezone is different, for example in North-America or Asia. # If the timezone is different, for example in North-America or Asia.
if [ "${tz}" != "$(cat /etc/timezone)" ]; then if [ "${tz}" != "$(cat /etc/timezone)" ]; then
@ -139,9 +104,86 @@ set_envvars() {
fi fi
} }
# === CORE SERVICES ===
start_core() {
printf "\n---------------------- STARTING CORE -----------------------\n"
echo "Activating Python venv and executing the WireGuard Dashboard service."
. "${WGDASH}"/src/venv/bin/activate
cd "${WGDASH}"/src || return # If changing the directory fails (permission or presence error), then bash will exist this function, causing the WireGuard Dashboard to not be succesfully launched.
bash wgd.sh start
# Isolated peers feature, first converting the existing configuration files and the given names to arrays.
local configurations=(/etc/wireguard/*)
IFS=',' read -r -a do_isolate <<< "${isolate}"
non_isolate=()
# 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$||')
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 [ -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)
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
fi
else
echo "Configuration for $interface does not seem to exist, continuing."
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
else
echo "Configuration for $interface does not seem to exist, continuing."
fi
done
# The following section takes care of enabling wireguard interfaces on startup. Using arrays and given arguments.
IFS=',' read -r -a enable_array <<< "${enable}"
for interface in "${enable_array[@]}"; do
echo "Enabling interface:" $interface
local 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
else
echo "No corresponding configuration file found for $interface doing nothing."
fi
done
}
# === CLEAN UP === # === CLEAN UP ===
ensure_blocking() { ensure_blocking() {
echo "-------------- ENSURING CONTAINER CONTINUATION -------------" printf "\n-------------- ENSURING CONTAINER CONTINUATION -------------\n"
sleep 1s sleep 1s
echo "Ensuring container continuation." echo "Ensuring container continuation."
@ -149,6 +191,7 @@ ensure_blocking() {
if find "/opt/wireguarddashboard/src/log" -mindepth 1 -maxdepth 1 -type f | read -r; then if find "/opt/wireguarddashboard/src/log" -mindepth 1 -maxdepth 1 -type f | read -r; then
latestErrLog=$(find /opt/wireguarddashboard/src/log -name "error_*.log" | head -n 1) latestErrLog=$(find /opt/wireguarddashboard/src/log -name "error_*.log" | head -n 1)
latestAccLog=$(find /opt/wireguarddashboard/src/log -name "access_*.log" | head -n 1) latestAccLog=$(find /opt/wireguarddashboard/src/log -name "access_*.log" | head -n 1)
tail -f "${latestErrLog}" "${latestAccLog}" tail -f "${latestErrLog}" "${latestAccLog}"
fi fi
@ -157,8 +200,9 @@ ensure_blocking() {
} }
# Execute functions for the WireGuard Dashboard services, then set the environment variables # Execute functions for the WireGuard Dashboard services, then set the environment variables
ensure_installation
clean_up clean_up
repair #update_checker
start_core
set_envvars set_envvars
start_core
ensure_blocking ensure_blocking