Updating to allow for getting info from external wireguard servers
Continuous Integration / docker (push) Successful in 23s

This commit is contained in:
2026-05-06 11:13:35 -04:00
parent 26c7087183
commit 634fe3fde6
3 changed files with 101 additions and 84 deletions
+3 -1
View File
@@ -1,9 +1,11 @@
FROM alpine:3.22 FROM alpine:3.22
ENV LOCAL_IPV4_SUBNETS="192.168.0.0/16" ENV LOCAL_IPV4_SUBNETS="192.168.0.0/16"
ENV MANAGE_WIREGUARD="true"
ENV TZ="UTC" ENV TZ="UTC"
ENV WEBUI_HOST="http://localhost:8080" ENV WEBUI_HOST="http://localhost:8080"
ENV WIREGUARD_INTERFACE="wg0" ENV WIREGUARD_INTERFACE="wg0"
ENV GATEWAY_IP="10.2.0.1"
RUN apk add --update --no-cache \ RUN apk add --update --no-cache \
bash ca-certificates curl iproute2 iptables ip6tables jq libnatpmp tzdata wireguard-tools \ bash ca-certificates curl iproute2 iptables ip6tables jq libnatpmp tzdata wireguard-tools \
@@ -13,6 +15,6 @@ RUN apk add --update --no-cache \
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
HEALTHCHECK --start-period=15s --interval=60s --timeout=10s --retries=3 \ HEALTHCHECK --start-period=15s --interval=60s --timeout=10s --retries=3 \
CMD ping -c 1 10.2.0.1 || exit 1 CMD ping -c 1 "${GATEWAY_IP:-10.2.0.1}" || exit 1
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
+11 -7
View File
@@ -13,10 +13,14 @@ Tools
### Recommended Environment Variables ### Recommended Environment Variables
| Variable | Default | Examples | Description | | Variable | Default | Examples | Description |
| -------- | ------- | ----- | ---------- | |-----------------------|-------------------------|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `TZ` | `UTC` | `America/Denver` | Set your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to make sure logs rotate at local midnight instead of at UTC midnight. | `TZ` | `UTC` | `America/Denver` | Set your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to make sure logs rotate at local midnight instead of at UTC midnight. |
| `WIREGUARD_INTERFACE` | `wg0` | `wg0`, `wg1`, ... | Set the wireguard interface name to use. | `MANAGE_WIREGUARD` | `true` | `false` | Set to `false` when this container should only manage Proton NAT-PMP and qBittorrent while sharing another WireGuard container's network namespace. |
| `LOCAL_IPV4_SUBNETS` | `192.168.0.0/16` | `192.168.0.0/16, 10.0.0.0/8` | Comma separated list of local subnet CIDRs to be allowed outside the wireguard tunnel. | `WIREGUARD_INTERFACE` | `wg0` | `wg0`, `wg1`, ... | Set the wireguard interface name to use. |
| `WEBUI_HOST` | `http://localhost:8080` | <URL to qBittorrent Web UI> | URL to the qBittorrent Web UI. Authentication must be disabled to localhost connections unless `WEBUI_USERNAME` and `WEBUI_PASSWORD` are set. | `GATEWAY_IP` | `10.2.0.1` | `10.2.0.1` | Proton VPN NAT-PMP gateway IP. |
| `WEBUI_USERNAME` | | `admin` | Optional qBittorrent Web UI username. Use this if localhost authentication bypass is not enabled. | `LOCAL_IPV4_SUBNETS` | `192.168.0.0/16` | `192.168.0.0/16, 10.0.0.0/8` | Comma separated list of local subnet CIDRs to be allowed outside the wireguard tunnel. |
| `WEBUI_PASSWORD` | | `adminadmin` | Optional qBittorrent Web UI password. Use this if localhost authentication bypass is not enabled. | `WEBUI_HOST` | `http://localhost:8080` | <URL to qBittorrent Web UI> | URL to the qBittorrent Web UI. Authentication must be disabled to localhost connections unless `WEBUI_USERNAME` and `WEBUI_PASSWORD` are set. |
| `QBITTORRENT_HOST` | | `localhost` | Alternative way to set the qBittorrent Web UI host. Used with `QBITTORRENT_PORT`. |
| `QBITTORRENT_PORT` | | `8088` | Alternative way to set the qBittorrent Web UI port. Used with `QBITTORRENT_HOST`. |
| `WEBUI_USERNAME` | | `admin` | Optional qBittorrent Web UI username. Use this if localhost authentication bypass is not enabled. |
| `WEBUI_PASSWORD` | | `adminadmin` | Optional qBittorrent Web UI password. Use this if localhost authentication bypass is not enabled. |
+62 -51
View File
@@ -11,93 +11,104 @@ fatal() {
exit 1 exit 1
} }
iptables-save | tee /tmp/rules.v4.$$.conf MANAGE_WIREGUARD="${MANAGE_WIREGUARD:-true}"
ip6tables-save | tee /tmp/rules.v6.$$.conf
default_route_ip=$(ip route | grep '^default' | awk '{print $3}')
if [[ -z "${default_route_ip}" ]]; then
fatal "Error: No default route configured"
fi
if [[ "$(cat /proc/sys/net/ipv4/conf/all/src_valid_mark)" != "1" ]]; then
fatal "Error: sysctl net.ipv4.conf.all.src_valid_mark=1 is not set"
fi
# sysctl is set by container, wg-quick will then error
sed -i "s:sysctl -q net.ipv4.conf.all.src_valid_mark=1:echo Skipping setting net.ipv4.conf.all.src_valid_mark:" /usr/bin/wg-quick
WIREGUARD_INTERFACE="${WIREGUARD_INTERFACE:-wg0}" WIREGUARD_INTERFACE="${WIREGUARD_INTERFACE:-wg0}"
GATEWAY_IP="${GATEWAY_IP:-10.2.0.1}"
if [ ! -f "/etc/wireguard/${WIREGUARD_INTERFACE}.conf" ]; then if [[ "${MANAGE_WIREGUARD}" == "true" ]]; then
iptables-save | tee /tmp/rules.v4.$$.conf
ip6tables-save | tee /tmp/rules.v6.$$.conf
default_route_ip=$(ip route | grep '^default' | awk '{print $3}')
if [[ -z "${default_route_ip}" ]]; then
fatal "Error: No default route configured"
fi
if [[ "$(cat /proc/sys/net/ipv4/conf/all/src_valid_mark)" != "1" ]]; then
fatal "Error: sysctl net.ipv4.conf.all.src_valid_mark=1 is not set"
fi
# sysctl is set by container, wg-quick will then error
sed -i "s:sysctl -q net.ipv4.conf.all.src_valid_mark=1:echo Skipping setting net.ipv4.conf.all.src_valid_mark:" /usr/bin/wg-quick
if [ ! -f "/etc/wireguard/${WIREGUARD_INTERFACE}.conf" ]; then
fatal "Error: Configuration file /etc/wireguard/${WIREGUARD_INTERFACE}.conf does not exist" fatal "Error: Configuration file /etc/wireguard/${WIREGUARD_INTERFACE}.conf does not exist"
fi fi
info "Bringing up wireguard interface: ${WIREGUARD_INTERFACE}..." info "Bringing up wireguard interface: ${WIREGUARD_INTERFACE}..."
wg-quick up ${WIREGUARD_INTERFACE} wg-quick up ${WIREGUARD_INTERFACE}
shutdown () { shutdown () {
info "shutting down wireguard interface: ${WIREGUARD_INTERFACE}..." info "shutting down wireguard interface: ${WIREGUARD_INTERFACE}..."
wg-quick down ${WIREGUARD_INTERFACE} wg-quick down ${WIREGUARD_INTERFACE}
info "restoring iptables..." info "restoring iptables..."
iptables-restore -n < /tmp/rules.v4.$$.conf iptables-restore -n < /tmp/rules.v4.$$.conf
info "restoring ip6tables..." info "restoring ip6tables..."
ip6tables-restore -n < /tmp/rules.v6.$$.conf ip6tables-restore -n < /tmp/rules.v6.$$.conf
} }
trap shutdown EXIT trap shutdown EXIT
wg show wg show
WIREGUARD_FWMARK=$(wg show ${WIREGUARD_INTERFACE} fwmark) WIREGUARD_FWMARK=$(wg show ${WIREGUARD_INTERFACE} fwmark)
# allow connections from container subnets # allow connections from container subnets
for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet / {print $4}') for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet / {print $4}')
do do
iptables -I INPUT -s ${container_subnet} -j ACCEPT iptables -I INPUT -s ${container_subnet} -j ACCEPT
iptables -I OUTPUT -d ${container_subnet} -j ACCEPT iptables -I OUTPUT -d ${container_subnet} -j ACCEPT
done done
# allow connections to local subnets specified by user, need to add routes since wireguard interface has 0.0.0.0/0 allowed ips # allow connections to local subnets specified by user, need to add routes since wireguard interface has 0.0.0.0/0 allowed ips
for local_subnet in ${LOCAL_IPV4_SUBNETS//,/$IFS} for local_subnet in ${LOCAL_IPV4_SUBNETS//,/$IFS}
do do
iptables -I INPUT -s ${local_subnet} -j ACCEPT iptables -I INPUT -s ${local_subnet} -j ACCEPT
iptables -I OUTPUT -d ${local_subnet} -j ACCEPT iptables -I OUTPUT -d ${local_subnet} -j ACCEPT
ip route add ${local_subnet} via ${default_route_ip} ip route add ${local_subnet} via ${default_route_ip}
done done
# established connections # established connections
iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# kill switches for ipv4 -- @see wg-quick(8) # kill switches for ipv4 -- @see wg-quick(8)
iptables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp-admin-prohibited iptables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp-admin-prohibited
for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet6 / {print $4}') for container_subnet in $(ip -o addr show | awk '/^(\d)+: eth(.+)inet6 / {print $4}')
do do
ip6tables -I INPUT -s ${container_subnet} -j ACCEPT ip6tables -I INPUT -s ${container_subnet} -j ACCEPT
ip6tables -I OUTPUT -d ${container_subnet} -j ACCEPT ip6tables -I OUTPUT -d ${container_subnet} -j ACCEPT
done done
# established connections # established connections
ip6tables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ip6tables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ip6tables -I OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# kill switches for ipv6 -- @see wg-quick(8) # kill switches for ipv6 -- @see wg-quick(8)
ip6tables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp6-adm-prohibited ip6tables -A OUTPUT ! -o ${WIREGUARD_INTERFACE} -m mark ! --mark ${WIREGUARD_FWMARK} -m addrtype ! --dst-type LOCAL -j REJECT --reject-with icmp6-adm-prohibited
iptables-save | tee /tmp/rules.v4.${WIREGUARD_INTERFACE}.$$.conf iptables-save | tee /tmp/rules.v4.${WIREGUARD_INTERFACE}.$$.conf
ip6tables-save | tee /tmp/rules.v6.${WIREGUARD_INTERFACE}.$$.conf ip6tables-save | tee /tmp/rules.v6.${WIREGUARD_INTERFACE}.$$.conf
else
info "Using externally managed wireguard interface: ${WIREGUARD_INTERFACE}"
wg show ${WIREGUARD_INTERFACE} || true
fi
sleep 8 & sleep 8 &
wait ${!} wait ${!}
# check to see if tunnel allows port forwarding # check to see if tunnel allows port forwarding
natpmpc -g 10.2.0.1 natpmpc -g "${GATEWAY_IP}"
# give some delay until qbittorrent container launches # give some delay until qbittorrent container launches
sleep 5 & sleep 5 &
wait ${!} wait ${!}
# qbittorrent webui host # qbittorrent webui host
WEBUI_HOST="${WEBUI_HOST:-http://localhost:8080}" if [[ -n "${QBITTORRENT_HOST:-}" || -n "${QBITTORRENT_PORT:-}" ]]; then
WEBUI_HOST="http://${QBITTORRENT_HOST:-localhost}:${QBITTORRENT_PORT:-8080}"
else
WEBUI_HOST="${WEBUI_HOST:-http://localhost:8080}"
fi
WEBUI_USERNAME="${WEBUI_USERNAME:-}" WEBUI_USERNAME="${WEBUI_USERNAME:-}"
WEBUI_PASSWORD="${WEBUI_PASSWORD:-}" WEBUI_PASSWORD="${WEBUI_PASSWORD:-}"
WEBUI_COOKIE_JAR="/tmp/qbittorrent-webui.$$.cookie" WEBUI_COOKIE_JAR="/tmp/qbittorrent-webui.$$.cookie"
@@ -138,10 +149,10 @@ fi
# loop now forever keeping port forward up to date (protonvpn) # loop now forever keeping port forward up to date (protonvpn)
# https://protonvpn.com/support/port-forwarding-manual-setup # https://protonvpn.com/support/port-forwarding-manual-setup
while true; do while true; do
tcp_output=$(natpmpc -a 1 0 tcp 60 -g 10.2.0.1) tcp_output=$(natpmpc -a 1 0 tcp 60 -g "${GATEWAY_IP}")
tcp_port=$(echo "${tcp_output}" | sed -n 's/.*Mapped public port \([0-9]\+\).*/\1/p') tcp_port=$(echo "${tcp_output}" | sed -n 's/.*Mapped public port \([0-9]\+\).*/\1/p')
udp_output=$(natpmpc -a 1 0 udp 60 -g 10.2.0.1) udp_output=$(natpmpc -a 1 0 udp 60 -g "${GATEWAY_IP}")
udp_port=$(echo "${udp_output}" | sed -n 's/.*Mapped public port \([0-9]\+\).*/\1/p') udp_port=$(echo "${udp_output}" | sed -n 's/.*Mapped public port \([0-9]\+\).*/\1/p')
if ! [[ "${tcp_port}" =~ ^[0-9]+$ && "${udp_port}" =~ ^[0-9]+$ ]]; then if ! [[ "${tcp_port}" =~ ^[0-9]+$ && "${udp_port}" =~ ^[0-9]+$ ]]; then