mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-12-15 16:06:17 +00:00
Compare commits
10 Commits
v4.3.0.3
...
v4.3.2-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7c9d62e80 | ||
|
|
f5ccbdf9d3 | ||
|
|
a09342ed2a | ||
|
|
d6a930c04b | ||
|
|
6fe257fa4a | ||
|
|
e5d1a64d7d | ||
|
|
da4cec60e5 | ||
|
|
a4d471df4f | ||
|
|
f00940b73c | ||
|
|
cb9cb4a0b6 |
@@ -96,9 +96,10 @@ LABEL maintainer="dselen@nerthus.nl"
|
|||||||
|
|
||||||
# Install only the runtime dependencies
|
# Install only the runtime dependencies
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
iproute2 iptables openresolv \
|
iproute2 iptables \
|
||||||
bash curl procps openrc \
|
bash curl procps openrc \
|
||||||
tzdata wireguard-tools
|
tzdata wireguard-tools envsubst
|
||||||
|
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||||
|
|
||||||
# Copy only the final binaries from the AWG builder stages
|
# Copy only the final binaries from the AWG builder stages
|
||||||
COPY --from=awg-go /usr/bin/amneziawg-go /usr/bin/amneziawg-go
|
COPY --from=awg-go /usr/bin/amneziawg-go /usr/bin/amneziawg-go
|
||||||
@@ -107,6 +108,7 @@ COPY --from=awg-tools /workspace/awg-tools/src/wg-quick/linux.bash /usr/bin/awg-
|
|||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
ARG wg_net="10.0.0.1"
|
ARG wg_net="10.0.0.1"
|
||||||
|
ARG wg_subn="24"
|
||||||
ARG wg_port="51820"
|
ARG wg_port="51820"
|
||||||
ENV TZ="Europe/Amsterdam" \
|
ENV TZ="Europe/Amsterdam" \
|
||||||
global_dns="9.9.9.9" \
|
global_dns="9.9.9.9" \
|
||||||
@@ -117,32 +119,23 @@ ENV TZ="Europe/Amsterdam" \
|
|||||||
# Create directories needed for operation
|
# Create directories needed for operation
|
||||||
RUN mkdir /data /configs -p ${WGDASH}/src /etc/amnezia/amneziawg
|
RUN mkdir /data /configs -p ${WGDASH}/src /etc/amnezia/amneziawg
|
||||||
|
|
||||||
# Copy the python virtual environment from the pip-builder stage
|
# Copy the venv and source files from local compiled locations or repos
|
||||||
COPY ./src ${WGDASH}/src
|
COPY ./src ${WGDASH}/src
|
||||||
COPY --from=pip-builder /opt/wgdashboard/src/venv /opt/wgdashboard/src/venv
|
COPY --from=pip-builder /opt/wgdashboard/src/venv /opt/wgdashboard/src/venv
|
||||||
|
COPY ./docker/wg0.conf.template /tmp/wg0.conf.template
|
||||||
|
# Copy in the runtime script, essential.
|
||||||
|
COPY ./docker/entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
# First WireGuard interface template
|
# First WireGuard interface template
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
RUN export out_adapt=$(ip -o -4 route show to default | awk '{print $NF}') \
|
||||||
RUN out_adapt=$(ip -o -4 route show to default | awk '{print $NF}') \
|
&& envsubst < /tmp/wg0.conf.template > /configs/wg0.conf.template \
|
||||||
&& echo -e "[Interface]\n\
|
&& chmod 600 /configs/wg0.conf.template \
|
||||||
Address = ${wg_net}/24\n\
|
&& cat /configs/wg0.conf.template
|
||||||
PrivateKey =\n\
|
|
||||||
PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE\n\
|
|
||||||
PostUp = iptables -I FORWARD -i wg0 -o wg0 -j DROP\n\
|
|
||||||
PreDown = iptables -t nat -D POSTROUTING -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE\n\
|
|
||||||
PreDown = iptables -D FORWARD -i wg0 -o wg0 -j DROP\n\
|
|
||||||
ListenPort = ${wg_port}\n\
|
|
||||||
SaveConfig = true\n\
|
|
||||||
DNS = ${global_dns}" > /configs/wg0.conf.template \
|
|
||||||
&& chmod 600 /configs/wg0.conf.template
|
|
||||||
|
|
||||||
# Set a healthcheck to determine the container its health
|
# Set a healthcheck to determine the container its health
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1
|
CMD sh -c 'pgrep gunicorn > /dev/null && pgrep tail > /dev/null' || exit 1
|
||||||
|
|
||||||
# Copy in the runtime script, essential.
|
|
||||||
COPY ./docker/entrypoint.sh /entrypoint.sh
|
|
||||||
|
|
||||||
# Expose ports on the container
|
# Expose ports on the container
|
||||||
EXPOSE 10086
|
EXPOSE 10086
|
||||||
WORKDIR $WGDASH/src
|
WORKDIR $WGDASH/src
|
||||||
|
|||||||
@@ -191,7 +191,11 @@ start_and_monitor() {
|
|||||||
echo "Starting WGDashboard directly with Gunicorn..."
|
echo "Starting WGDashboard directly with Gunicorn..."
|
||||||
|
|
||||||
[[ ! -d ${WGDASH}/src/log ]] && mkdir ${WGDASH}/src/log
|
[[ ! -d ${WGDASH}/src/log ]] && mkdir ${WGDASH}/src/log
|
||||||
|
[[ ! -d ${WGDASH}/src/download ]] && mkdir ${WGDASH}/src/download
|
||||||
${WGDASH}/src/venv/bin/gunicorn --config ${WGDASH}/src/gunicorn.conf.py
|
${WGDASH}/src/venv/bin/gunicorn --config ${WGDASH}/src/gunicorn.conf.py
|
||||||
|
|
||||||
|
resolvconf -u
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Loading WGDashboard failed... Look above for details."
|
echo "Loading WGDashboard failed... Look above for details."
|
||||||
fi
|
fi
|
||||||
|
|||||||
8
docker/wg0.conf.template
Normal file
8
docker/wg0.conf.template
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[Interface]
|
||||||
|
Address = ${wg_net}/24
|
||||||
|
PrivateKey =
|
||||||
|
PostUp = iptables -t nat -I POSTROUTING 1 -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE; iptables -I FORWARD -i wg0 -o wg0 -j DROP
|
||||||
|
PreDown = iptables -t nat -D POSTROUTING -s ${wg_net}/24 -o ${out_adapt} -j MASQUERADE; iptables -D FORWARD -i wg0 -o wg0 -j DROP
|
||||||
|
ListenPort = ${wg_port}
|
||||||
|
SaveConfig = true
|
||||||
|
DNS = ${global_dns}
|
||||||
@@ -1238,8 +1238,9 @@ def API_ping_getAllPeersIpAddress():
|
|||||||
ip = ipaddress.ip_network(x, strict=False)
|
ip = ipaddress.ip_network(x, strict=False)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
app.logger.error(f"Failed to parse IP address of {p.id} - {c.Name}")
|
app.logger.error(f"Failed to parse IP address of {p.id} - {c.Name}")
|
||||||
if len(list(ip.hosts())) == 1:
|
host = list(ip.hosts())
|
||||||
parsed.append(str(ip.hosts()[0]))
|
if len(host) == 1:
|
||||||
|
parsed.append(str(host[0]))
|
||||||
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
|
endpoint = p.endpoint.replace(" ", "").replace("(none)", "")
|
||||||
if len(p.name) > 0:
|
if len(p.name) > 0:
|
||||||
cips[f"{p.name} - {p.id}"] = {
|
cips[f"{p.name} - {p.id}"] = {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from .DashboardAPIKey import DashboardAPIKey
|
|||||||
|
|
||||||
|
|
||||||
class DashboardConfig:
|
class DashboardConfig:
|
||||||
DashboardVersion = 'v4.3.0.3'
|
DashboardVersion = 'v4.3.1'
|
||||||
ConfigurationPath = os.getenv('CONFIGURATION_PATH', '.')
|
ConfigurationPath = os.getenv('CONFIGURATION_PATH', '.')
|
||||||
ConfigurationFilePath = os.path.join(ConfigurationPath, 'wg-dashboard.ini')
|
ConfigurationFilePath = os.path.join(ConfigurationPath, 'wg-dashboard.ini')
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,18 @@ def GetRemoteEndpoint() -> str:
|
|||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
import socket
|
import socket
|
||||||
|
try:
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
||||||
s.connect(("1.1.1.1", 80)) # Connecting to a public IP
|
s.connect(("1.1.1.1", 80)) # Connecting to a public IP
|
||||||
wgd_remote_endpoint = s.getsockname()[0]
|
wgd_remote_endpoint = s.getsockname()[0]
|
||||||
return str(wgd_remote_endpoint)
|
return str(wgd_remote_endpoint)
|
||||||
|
except (socket.error, OSError):
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return socket.gethostbyname(socket.gethostname())
|
||||||
|
except (socket.error, OSError):
|
||||||
|
pass
|
||||||
|
return "127.0.0.1"
|
||||||
|
|
||||||
|
|
||||||
def StringToBoolean(value: str):
|
def StringToBoolean(value: str):
|
||||||
|
|||||||
@@ -404,6 +404,7 @@ class WireguardConfiguration:
|
|||||||
try:
|
try:
|
||||||
if "[Peer]" not in content:
|
if "[Peer]" not in content:
|
||||||
current_app.logger.info(f"{self.Name} config has no [Peer] section")
|
current_app.logger.info(f"{self.Name} config has no [Peer] section")
|
||||||
|
self.Peers = []
|
||||||
return
|
return
|
||||||
|
|
||||||
peerStarts = content.index("[Peer]")
|
peerStarts = content.index("[Peer]")
|
||||||
@@ -665,9 +666,8 @@ class WireguardConfiguration:
|
|||||||
|
|
||||||
if not self.__wgSave():
|
if not self.__wgSave():
|
||||||
return False, "Failed to save configuration through WireGuard"
|
return False, "Failed to save configuration through WireGuard"
|
||||||
|
self.getRestrictedPeers()
|
||||||
self.getPeers()
|
self.getPeers()
|
||||||
|
|
||||||
if numOfRestrictedPeers == len(listOfPublicKeys):
|
if numOfRestrictedPeers == len(listOfPublicKeys):
|
||||||
return True, f"Restricted {numOfRestrictedPeers} peer(s)"
|
return True, f"Restricted {numOfRestrictedPeers} peer(s)"
|
||||||
return False, f"Restricted {numOfRestrictedPeers} peer(s) successfully. Failed to restrict {numOfFailedToRestrictPeers} peer(s)"
|
return False, f"Restricted {numOfRestrictedPeers} peer(s) successfully. Failed to restrict {numOfFailedToRestrictPeers} peer(s)"
|
||||||
@@ -783,9 +783,7 @@ class WireguardConfiguration:
|
|||||||
)
|
)
|
||||||
).mappings().fetchone()
|
).mappings().fetchone()
|
||||||
if cur_i is not None:
|
if cur_i is not None:
|
||||||
# print(cur_i is None)
|
|
||||||
total_sent = cur_i['total_sent']
|
total_sent = cur_i['total_sent']
|
||||||
# print(cur_i is None)
|
|
||||||
total_receive = cur_i['total_receive']
|
total_receive = cur_i['total_receive']
|
||||||
cur_total_sent = float(data_usage[i][2]) / (1024 ** 3)
|
cur_total_sent = float(data_usage[i][2]) / (1024 ** 3)
|
||||||
cur_total_receive = float(data_usage[i][1]) / (1024 ** 3)
|
cur_total_receive = float(data_usage[i][1]) / (1024 ** 3)
|
||||||
@@ -1226,7 +1224,6 @@ class WireguardConfiguration:
|
|||||||
def __validateOverridePeerSettings(self, key: str, value: str | int) -> tuple[bool, None] | tuple[bool, str]:
|
def __validateOverridePeerSettings(self, key: str, value: str | int) -> tuple[bool, None] | tuple[bool, str]:
|
||||||
status = True
|
status = True
|
||||||
msg = None
|
msg = None
|
||||||
print(value)
|
|
||||||
if key == "DNS" and value:
|
if key == "DNS" and value:
|
||||||
status, msg = ValidateDNSAddress(value)
|
status, msg = ValidateDNSAddress(value)
|
||||||
elif key == "EndpointAllowedIPs" and value:
|
elif key == "EndpointAllowedIPs" and value:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.3.0.3",
|
"version": "4.3.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "es2022",
|
"module": "es2022",
|
||||||
|
|||||||
Reference in New Issue
Block a user