Add WireGuard support to qbittorrent addon

This commit is contained in:
Alexandre
2025-11-13 21:02:26 +01:00
parent eac1dba01b
commit d20e9d9052
7 changed files with 139 additions and 12 deletions

View File

@@ -1,5 +1,9 @@
- Added support for configuring extra environment variables via the `env_vars` add-on option alongside config.yaml. See https://github.com/alexbelgium/hassio-addons/wiki/Add-Environment-variables-to-your-Addon-2 for details.
## 5.1.2-8 (19-08-2025)
- FEAT: add first-class WireGuard support with runtime validation and troubleshooting logs
- FEAT: ensure WireGuard port 51820 is exposed and validated via bashio
## 5.1.2-7 (17-08-2025)
- Minor bugs fixed
## 5.1.2-6 (31-07-2025)

View File

@@ -33,7 +33,7 @@ This addons has several configurable options :
- [alternative webUI](https://github.com/qbittorrent/qBittorrent/wiki/List-of-known-alternate-WebUIs)
- usage of ssl
- ingress
- optional openvpn support
- optional OpenVPN or WireGuard support
- allow setting specific DNS servers
## Configuration
@@ -70,10 +70,16 @@ Network disk is mounted to `/mnt/<share_name>`. You need to map the exposed port
| `openvpn_username` | str | | OpenVPN username |
| `openvpn_password` | str | | OpenVPN password |
| `openvpn_alt_mode` | bool | `false` | Bind at container level instead of app level |
| `wireguard_enabled` | bool | `false` | Enable WireGuard tunnel |
| `wireguard_config` | str | _(empty)_ | WireGuard config file name (in `/config/wireguard/`) |
| `qbit_manage` | bool | `false` | Enable qBit Manage integration |
| `run_duration` | str | | Run duration (e.g., `12h`, `5d`) |
| `silent` | bool | `false` | Suppress debug messages |
### WireGuard Setup
WireGuard configuration files must be stored in `/config/wireguard`. If several `.conf` files are present, set `wireguard_config` to the file name you want to use (for example `wg0.conf`). Expose UDP port `51820` in the add-on options and forward it from your router to allow inbound tunnel traffic.
### Example Configuration
```yaml
@@ -93,6 +99,7 @@ networkdisks: "//192.168.1.100/downloads"
cifsusername: "username"
cifspassword: "password"
openvpn_enabled: false
wireguard_enabled: false
```
### Mounting Drives
@@ -167,6 +174,15 @@ Delete your nova3 folder in /config and restart qbittorrent
</details>
<details>
<summary>### WireGuard connection fails</summary>
- Verify that the UDP port exposed in the add-on options maps 51820/udp and is forwarded by your router.
- Confirm that the selected configuration file in `/config/wireguard` matches the `wireguard_config` option (or that only one `.conf` file is present).
- Check the add-on logs for the detailed `wg-quick` error message printed by the startup routine.
</details>
<details>
<summary>### Monitored folders (@FaliseDotCom)</summary>

View File

@@ -91,6 +91,8 @@ options:
keyfile: privkey.pem
qbit_manage: false
ssl: false
wireguard_enabled: false
wireguard_config: ""
whitelist: localhost,127.0.0.1,172.30.0.0/16,192.168.0.0/16
panel_admin: false
panel_icon: mdi:progress-download
@@ -100,12 +102,14 @@ ports:
6882/tcp: 6882
6882/udp: 6882
8080/tcp: 8081
51820/udp: 51820
ports_description:
59595/tcp: Peer port, do not change
59595/udp: Peer port, do not change
6882/tcp: Alternative peer port, do not change
6882/udp: Alternative peer port, do not change
8080/tcp: Web UI port (not required for Ingress)
51820/udp: WireGuard tunnel port
privileged:
- SYS_ADMIN
- DAC_READ_SEARCH
@@ -137,8 +141,10 @@ schema:
run_duration: str?
silent: bool?
ssl: bool
wireguard_config: str?
wireguard_enabled: bool?
whitelist: str?
slug: qbittorrent
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: 5.1.2-7
version: 5.1.2-8

View File

@@ -260,10 +260,14 @@ else
# REMOVE OPENVPN #
##################
# Ensure no redirection by removing the direction tag
if [ -f "$QBT_CONFIG_FILE" ]; then
sed -i '/Interface/d' "$QBT_CONFIG_FILE"
if ! bashio::config.true 'wireguard_enabled'; then
# Ensure no redirection by removing the direction tag when no VPN is used
if [ -f "$QBT_CONFIG_FILE" ]; then
sed -i '/Interface/d' "$QBT_CONFIG_FILE"
fi
bashio::log.info "Direct connection without VPN enabled"
else
bashio::log.info "OpenVPN disabled. WireGuard handling network binding."
fi
bashio::log.info "Direct connection without VPN enabled"
fi

View File

@@ -0,0 +1,78 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
WIREGUARD_STATE_DIR="/var/run/wireguard"
QBT_CONFIG_FILE="/config/qBittorrent/qBittorrent.conf"
declare wireguard_config=""
declare configured_name
mkdir -p "${WIREGUARD_STATE_DIR}"
if ! bashio::config.true 'wireguard_enabled'; then
rm -f "${WIREGUARD_STATE_DIR}/config" "${WIREGUARD_STATE_DIR}/interface"
exit 0
fi
if bashio::config.true 'openvpn_enabled'; then
bashio::exit.nok 'OpenVPN and WireGuard cannot be enabled simultaneously. Disable one of them.'
fi
if bashio::config.true 'openvpn_alt_mode'; then
bashio::log.warning 'The openvpn_alt_mode option is ignored when WireGuard is enabled.'
fi
port="$(bashio::addon.port '51820/udp')"
if ! bashio::var.has_value "${port}"; then
bashio::exit.nok 'WireGuard is enabled but UDP port 51820 is not mapped. Please expose 51820/udp in the add-on options.'
fi
bashio::log.info "WireGuard host port ${port}/udp mapped to container port 51820."
if bashio::config.has_value 'wireguard_config'; then
configured_name="$(bashio::config 'wireguard_config')"
configured_name="${configured_name##*/}"
if [[ -z "${configured_name}" ]]; then
bashio::log.info 'wireguard_config option left empty. Attempting automatic selection.'
elif bashio::fs.file_exists "/config/wireguard/${configured_name}"; then
wireguard_config="/config/wireguard/${configured_name}"
else
bashio::exit.nok "WireGuard configuration '/config/wireguard/${configured_name}' not found."
fi
fi
if [ -z "${wireguard_config:-}" ]; then
mapfile -t configs < <(find /config/wireguard -maxdepth 1 -type f -name '*.conf' -print)
if [ "${#configs[@]}" -eq 0 ]; then
bashio::exit.nok 'WireGuard is enabled but no .conf file was found in /config/wireguard.'
elif [ "${#configs[@]}" -eq 1 ]; then
wireguard_config="${configs[0]}"
bashio::log.info "WireGuard configuration not specified. Using ${wireguard_config##*/}."
elif bashio::fs.file_exists '/config/wireguard/config.conf'; then
wireguard_config='/config/wireguard/config.conf'
bashio::log.info 'Using default WireGuard configuration config.conf.'
else
bashio::exit.nok "Multiple WireGuard configuration files detected. Please set the 'wireguard_config' option."
fi
fi
dos2unix "${wireguard_config}" >/dev/null 2>&1 || true
interface_name="$(basename "${wireguard_config}" .conf)"
if [[ -z "${interface_name}" ]]; then
interface_name='wg0'
fi
echo "${wireguard_config}" > "${WIREGUARD_STATE_DIR}/config"
echo "${interface_name}" > "${WIREGUARD_STATE_DIR}/interface"
if bashio::fs.file_exists "${QBT_CONFIG_FILE}"; then
sed -i '/Interface/d' "${QBT_CONFIG_FILE}"
sed -i "/\\[Preferences\\]/ i\\Connection\\\\Interface=${interface_name}" "${QBT_CONFIG_FILE}"
sed -i "/\\[Preferences\\]/ i\\Connection\\\\InterfaceName=${interface_name}" "${QBT_CONFIG_FILE}"
sed -i "/\\[BitTorrent\\]/a \\Session\\\\Interface=${interface_name}" "${QBT_CONFIG_FILE}"
sed -i "/\\[BitTorrent\\]/a \\Session\\\\InterfaceName=${interface_name}" "${QBT_CONFIG_FILE}"
else
bashio::log.warning "qBittorrent config file not found. Bind the client manually to interface ${interface_name}."
fi
bashio::log.info "WireGuard prepared with interface ${interface_name} using configuration ${wireguard_config##*/}."

View File

@@ -10,13 +10,29 @@ fi
if bashio::config.true 'openvpn_enabled'; then
exec /usr/sbin/openvpn --config /config/openvpn/config.ovpn --script-security 2 --up /etc/openvpn/up.sh --down /etc/openvpn/down.sh --pull-filter ignore "route-ipv6" --pull-filter ignore "ifconfig-ipv6" --pull-filter ignore "tun-ipv6" --pull-filter ignore "redirect-gateway ipv6" --pull-filter ignore "dhcp-option DNS6"
else
########################################################
# DRAFT : Start wireguard if needed
if bashio::config.true 'wireguard_enabled'; then
wg-quick up /config/wireguard/config.conf &
true
WIREGUARD_STATE_DIR="/var/run/wireguard"
if ! bashio::fs.file_exists "${WIREGUARD_STATE_DIR}/config"; then
bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
fi
wireguard_config="$(cat "${WIREGUARD_STATE_DIR}/config")"
wireguard_interface="$(cat "${WIREGUARD_STATE_DIR}/interface" 2>/dev/null || echo 'wg0')"
if ip link show "${wireguard_interface}" &> /dev/null; then
bashio::log.warning "WireGuard interface ${wireguard_interface} already exists. Attempting to reset it."
wg-quick down "${wireguard_config}" >/dev/null 2>&1 || true
fi
bashio::log.info "Starting WireGuard interface ${wireguard_interface} using ${wireguard_config##*/}."
if ! output=$(wg-quick up "${wireguard_config}" 2>&1); then
bashio::log.error 'WireGuard failed to establish a connection.'
bashio::log.error "wg-quick output: ${output}"
bashio::log.error 'Troubleshooting steps:'
bashio::log.error ' 1. Confirm the WireGuard configuration file contains valid keys and endpoint information.'
bashio::log.error ' 2. Ensure UDP port 51820 is forwarded from your router and not blocked by your ISP or firewall.'
bashio::log.error " 3. Verify that the configured endpoint is reachable from Home Assistant and credentials are correct."
bashio::exit.nok 'WireGuard start failed. See the log above for details.'
fi
bashio::log.info "WireGuard interface ${wireguard_interface} is up."
fi
########################################################
if bashio::config.true 'silent'; then
exec \

View File

@@ -13,7 +13,10 @@ if [ -f /currentip ]; then
nginx || nginx -s reload &
while true; do
# Get vpn ip
if ! bashio::config.true 'wireguard_enabled' && bashio::config.true 'openvpn_alt_mode'; then
if bashio::config.true 'wireguard_enabled'; then
wireguard_interface="$(cat /var/run/wireguard/interface 2>/dev/null || echo 'wg0')"
curl -s ipecho.net/plain --interface "${wireguard_interface}" > /vpnip
elif bashio::config.true 'openvpn_alt_mode'; then
curl -s ipecho.net/plain > /vpnip
else
curl -s ipecho.net/plain --interface tun0 > /vpnip