Merge pull request #302 from linuxserver/multi

Add support for multiple WireGuard interfaces
pull/310/head
aptalca 8 months ago committed by GitHub
commit 62f11730a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -44,6 +44,8 @@ RUN \
sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash && \ sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash && \
make -C src -j$(nproc) && \ make -C src -j$(nproc) && \
make -C src install && \ make -C src install && \
rm -rf /etc/wireguard && \
ln -s /config/wg_confs /etc/wireguard && \
echo "**** clean up ****" && \ echo "**** clean up ****" && \
apk del --no-network build-dependencies && \ apk del --no-network build-dependencies && \
rm -rf \ rm -rf \

@ -44,6 +44,8 @@ RUN \
sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash && \ sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' src/wg-quick/linux.bash && \
make -C src -j$(nproc) && \ make -C src -j$(nproc) && \
make -C src install && \ make -C src install && \
rm -rf /etc/wireguard && \
ln -s /config/wg_confs /etc/wireguard && \
echo "**** clean up ****" && \ echo "**** clean up ****" && \
apk del --no-network build-dependencies && \ apk del --no-network build-dependencies && \
rm -rf \ rm -rf \

@ -85,11 +85,13 @@ To add more peers/clients later on, you increment the `PEERS` environment variab
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` or `docker exec -it wireguard /app/show-peer myPC myPhone myTablet` (Keep in mind that the QR codes are also stored as PNGs in the config folder). 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` or `docker exec -it wireguard /app/show-peer myPC myPhone myTablet` (Keep in mind that the QR codes are also stored as PNGs in the config folder).
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. 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/wg_confs/wg0.conf` and restarting the container.
The container managed server conf is hardcoded to `wg0.conf`. However, the users can add additional tunnel config files with `.conf` extensions into `/config/wg_confs/` and the container will attempt to start them all in alphabetical order. If any one of the tunnels fail, they will all be stopped and the default route will be deleted, requiring user intervention to fix the invalid conf and a container restart.
## Client Mode ## Client Mode
Do not set the `PEERS` environment variable. 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(s) into the config folder as `/config/wg_confs/<tunnel name>.conf` and start the container. If there are multiple tunnel configs, the container will attempt to start them all in alphabetical order. If any one of the tunnels fail, they will all be stopped and the default route will be deleted, requiring user intervention to fix the invalid conf and a container restart.
If you get IPv6 related errors in the log and connection cannot be established, edit the `AllowedIPs` line in your peer/client wg0.conf to include only `0.0.0.0/0` and not `::/0`; and restart the container. If you get IPv6 related errors in the log and connection cannot be established, edit the `AllowedIPs` line in your peer/client wg0.conf to include only `0.0.0.0/0` and not `::/0`; and restart the container.
@ -330,6 +332,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64
## Versions ## Versions
* **03.10.23:** - **Potentially Breaking Change:** Support for multiple interfaces added. Wireguard confs moved to `/config/wg_confs/`. Any file with a `.conf` extension in that folder will be treated as a live tunnel config and will be attempted to start. If any of the tunnels fail, all tunnels will be stopped. Tunnels are started in alphabetical order. Managed server conf will continue to be hardcoded to `wg0.conf`.
* **28.06.23:** - Rebase master to Alpine 3.18 again. * **28.06.23:** - Rebase master to Alpine 3.18 again.
* **26.06.23:** - Revert master to Alpine 3.17, due to issue with openresolv. * **26.06.23:** - Revert master to Alpine 3.17, due to issue with openresolv.
* **24.06.23:** - Rebase master to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf). * **24.06.23:** - Rebase master to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf).

@ -78,11 +78,13 @@ app_setup_block: |
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` or `docker exec -it wireguard /app/show-peer myPC myPhone myTablet` (Keep in mind that the QR codes are also stored as PNGs in the config folder). 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` or `docker exec -it wireguard /app/show-peer myPC myPhone myTablet` (Keep in mind that the QR codes are also stored as PNGs in the config folder).
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. 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/wg_confs/wg0.conf` and restarting the container.
The container managed server conf is hardcoded to `wg0.conf`. However, the users can add additional tunnel config files with `.conf` extensions into `/config/wg_confs/` and the container will attempt to start them all in alphabetical order. If any one of the tunnels fail, they will all be stopped and the default route will be deleted, requiring user intervention to fix the invalid conf and a container restart.
## Client Mode ## Client Mode
Do not set the `PEERS` environment variable. 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(s) into the config folder as `/config/wg_confs/<tunnel name>.conf` and start the container. If there are multiple tunnel configs, the container will attempt to start them all in alphabetical order. If any one of the tunnels fail, they will all be stopped and the default route will be deleted, requiring user intervention to fix the invalid conf and a container restart.
If you get IPv6 related errors in the log and connection cannot be established, edit the `AllowedIPs` line in your peer/client wg0.conf to include only `0.0.0.0/0` and not `::/0`; and restart the container. If you get IPv6 related errors in the log and connection cannot be established, edit the `AllowedIPs` line in your peer/client wg0.conf to include only `0.0.0.0/0` and not `::/0`; and restart the container.
@ -126,6 +128,7 @@ app_setup_block: |
# changelog # changelog
changelogs: changelogs:
- { date: "03.10.23:", desc: "**Potentially Breaking Change:** Support for multiple interfaces added. Wireguard confs moved to `/config/wg_confs/`. Any file with a `.conf` extension in that folder will be treated as a live tunnel config and will be attempted to start. If any of the tunnels fail, all tunnels will be stopped. Tunnels are started in alphabetical order. Managed server conf will continue to be hardcoded to `wg0.conf`." }
- { date: "28.06.23:", desc: "Rebase master to Alpine 3.18 again." } - { date: "28.06.23:", desc: "Rebase master to Alpine 3.18 again." }
- { date: "26.06.23:", desc: "Revert master to Alpine 3.17, due to issue with openresolv." } - { date: "26.06.23:", desc: "Revert master to Alpine 3.17, due to issue with openresolv." }
- { date: "24.06.23:", desc: "Rebase master to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf)." } - { date: "24.06.23:", desc: "Rebase master to Alpine 3.18, deprecate armhf as per [https://www.linuxserver.io/armhf](https://www.linuxserver.io/armhf)." }

@ -13,7 +13,7 @@ for i in "$@"; do
PEER_ID="peer_${i//[^[:alnum:]_-]/}" PEER_ID="peer_${i//[^[:alnum:]_-]/}"
fi fi
if grep -q "# ${PEER_ID}" /config/wg0.conf; then if grep -q "# ${PEER_ID}" /config/wg_confs/wg0.conf; then
echo "PEER ${i} QR code:" echo "PEER ${i} QR code:"
qrencode -t ansiutf8 < /config/${PEER_ID}/${PEER_ID}.conf qrencode -t ansiutf8 < /config/${PEER_ID}/${PEER_ID}.conf
else else

@ -2,10 +2,15 @@
# shellcheck shell=bash # shellcheck shell=bash
# shellcheck disable=SC2016,SC1091,SC2183 # shellcheck disable=SC2016,SC1091,SC2183
# prepare symlinks mkdir -p /config/wg_confs
rm -rf /etc/wireguard
mkdir -p /etc/wireguard # migration to subfolder for wg confs
ln -s /config/wg0.conf /etc/wireguard/wg0.conf if [[ -z "$(ls -A /config/wg_confs)" ]] && [[ -f /config/wg0.conf ]]; then
echo "**** Performing migration to new folder structure for confs. Please see the image changelog 2023-10-03 entry for more details. ****"
cp /config/wg0.conf /config/wg_confs/wg0.conf
rm -rf /config/wg0.conf || :
fi
# prepare templates # prepare templates
if [[ ! -f /config/templates/server.conf ]]; then if [[ ! -f /config/templates/server.conf ]]; then
cp /defaults/server.conf /config/templates/server.conf cp /defaults/server.conf /config/templates/server.conf
@ -25,7 +30,7 @@ generate_confs () {
wg genkey | tee /config/server/privatekey-server | wg pubkey > /config/server/publickey-server wg genkey | tee /config/server/privatekey-server | wg pubkey > /config/server/publickey-server
fi fi
eval "$(printf %s) eval "$(printf %s)
cat <<DUDE > /config/wg0.conf cat <<DUDE > /config/wg_confs/wg0.conf
$(cat /config/templates/server.conf) $(cat /config/templates/server.conf)
DUDE" DUDE"
@ -65,7 +70,7 @@ DUDE"
$(cat /config/templates/peer.conf) $(cat /config/templates/peer.conf)
DUDE" DUDE"
# add peer info to server conf with presharedkey # add peer info to server conf with presharedkey
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
[Peer] [Peer]
# ${PEER_ID} # ${PEER_ID}
PublicKey = $(cat "/config/${PEER_ID}/publickey-${PEER_ID}") PublicKey = $(cat "/config/${PEER_ID}/publickey-${PEER_ID}")
@ -79,7 +84,7 @@ DUDE
$(sed '/PresharedKey/d' "/config/templates/peer.conf") $(sed '/PresharedKey/d' "/config/templates/peer.conf")
DUDE" DUDE"
# add peer info to server conf without presharedkey # add peer info to server conf without presharedkey
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
[Peer] [Peer]
# ${PEER_ID} # ${PEER_ID}
PublicKey = $(cat "/config/${PEER_ID}/publickey-${PEER_ID}") PublicKey = $(cat "/config/${PEER_ID}/publickey-${PEER_ID}")
@ -89,22 +94,22 @@ DUDE
# add peer's allowedips to server conf # add peer's allowedips to server conf
if [[ -n "${!SERVER_ALLOWEDIPS}" ]]; then if [[ -n "${!SERVER_ALLOWEDIPS}" ]]; then
echo "Adding ${!SERVER_ALLOWEDIPS} to wg0.conf's AllowedIPs for peer ${i}" echo "Adding ${!SERVER_ALLOWEDIPS} to wg0.conf's AllowedIPs for peer ${i}"
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
AllowedIPs = ${CLIENT_IP}/32,${!SERVER_ALLOWEDIPS} AllowedIPs = ${CLIENT_IP}/32,${!SERVER_ALLOWEDIPS}
DUDE DUDE
else else
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
AllowedIPs = ${CLIENT_IP}/32 AllowedIPs = ${CLIENT_IP}/32
DUDE DUDE
fi fi
# add PersistentKeepalive if the peer is specified # add PersistentKeepalive if the peer is specified
if [[ -n "${PERSISTENTKEEPALIVE_PEERS_ARRAY}" ]] && ([[ "${PERSISTENTKEEPALIVE_PEERS_ARRAY[0]}" = "all" ]] || printf '%s\0' "${PERSISTENTKEEPALIVE_PEERS_ARRAY[@]}" | grep -Fxqz -- "${i}"); then if [[ -n "${PERSISTENTKEEPALIVE_PEERS_ARRAY}" ]] && ([[ "${PERSISTENTKEEPALIVE_PEERS_ARRAY[0]}" = "all" ]] || printf '%s\0' "${PERSISTENTKEEPALIVE_PEERS_ARRAY[@]}" | grep -Fxqz -- "${i}"); then
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
PersistentKeepalive = 25 PersistentKeepalive = 25
DUDE DUDE
else else
cat <<DUDE >> /config/wg0.conf cat <<DUDE >> /config/wg_confs/wg0.conf
DUDE DUDE
fi fi
@ -161,7 +166,7 @@ if [[ -n "$PEERS" ]]; then
else else
echo "**** Peer DNS servers will be set to $PEERDNS ****" echo "**** Peer DNS servers will be set to $PEERDNS ****"
fi fi
if [[ ! -f /config/wg0.conf ]]; then if [[ ! -f /config/wg_confs/wg0.conf ]]; then
echo "**** No wg0.conf found (maybe an initial install), generating 1 server and ${PEERS} peer/client confs ****" echo "**** No wg0.conf found (maybe an initial install), generating 1 server and ${PEERS} peer/client confs ****"
generate_confs generate_confs
save_vars save_vars
@ -180,10 +185,6 @@ if [[ -n "$PEERS" ]]; then
fi fi
else else
echo "**** Client mode selected. ****" echo "**** Client mode selected. ****"
if [[ ! -f /config/wg0.conf ]]; then
echo "**** No client conf found. Provide your own client conf as \"/config/wg0.conf\" and restart the container. ****"
sleep infinity
fi
USE_COREDNS="${USE_COREDNS,,}" USE_COREDNS="${USE_COREDNS,,}"
printf %s "${USE_COREDNS:-false}" > /run/s6/container_environment/USE_COREDNS printf %s "${USE_COREDNS:-false}" > /run/s6/container_environment/USE_COREDNS
fi fi

@ -1,4 +1,12 @@
#!/usr/bin/with-contenv bash #!/usr/bin/with-contenv bash
# shellcheck shell=bash # shellcheck shell=bash
wg-quick down wg0 if [[ -f "/app/activeconfs" ]]; then
. /app/activeconfs
for tunnel in $(printf '%s\n' "${WG_CONFS[@]}" | tac | tr '\n' ' '; echo); do
echo "**** Disabling tunnel ${tunnel} ****"
wg-quick down "${tunnel}" || :
done
echo "**** All tunnels are down ****"
rm -rf /app/activeconfs
fi

@ -1,4 +1,46 @@
#!/usr/bin/with-contenv bash #!/usr/bin/with-contenv bash
# shellcheck shell=bash # shellcheck shell=bash
wg-quick up wg0 unset WG_CONFS
rm -rf /app/activeconfs
# Enumerate interfaces
for wgconf in $(ls /config/wg_confs/*.conf); do
if grep -q "\[Interface\]" "${wgconf}"; then
echo "**** Found WG conf ${wgconf}, adding to list ****"
WG_CONFS+=("${wgconf}")
else
echo "**** Found WG conf ${wgconf}, but it doesn't seem to be valid, skipping. ****"
fi
done
if [[ -z "${WG_CONFS}" ]]; then
echo "**** No valid tunnel config found. Please create a valid config and restart the container ****"
ip route del default
exit 0
fi
unset FAILED
for tunnel in ${WG_CONFS[@]}; do
echo "**** Activating tunnel ${tunnel} ****"
if ! wg-quick up "${tunnel}"; then
FAILED="${tunnel}"
break
fi
done
if [[ -z "${FAILED}" ]]; then
declare -p WG_CONFS > /app/activeconfs
echo "**** All tunnels are now active ****"
else
echo "**** Tunnel ${FAILED} failed, will stop all others! ****"
for tunnel in ${WG_CONFS[@]}; do
if [[ "${tunnel}" = "${FAILED}" ]]; then
break
else
echo "**** Disabling tunnel ${tunnel} ****"
wg-quick down "${tunnel}" || :
fi
done
ip route del default
echo "**** All tunnels are now down. Please fix the tunnel config ${FAILED} and restart the container ****"
fi

Loading…
Cancel
Save