Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions readme-vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ param_usage_include_env: true
param_env_vars:
- {env_var: "WEBUI_PORT", env_value: "8080", desc: "for changing the port of the web UI, see below for explanation"}
- {env_var: "TORRENTING_PORT", env_value: "6881", desc: "for changing the port of tcp/udp connection, see below for explanation"}
opt_param_env_vars:
- {env_var: "WEBUI_USER", env_value: "", desc: "Set the WebUI username. If unset, defaults to 'admin'."}
- {env_var: "WEBUI_PASS", env_value: "", desc: "Set the WebUI password. If unset, a random password is generated on startup."}
opt_param_usage_include_vols: true
opt_param_volumes:
- {vol_path: "/downloads", vol_host_path: "/path/to/downloads", desc: "Location of downloads on disk."}
Expand Down Expand Up @@ -99,6 +102,7 @@ init_diagram: |
"qbittorrent:latest" <- Base Images
# changelog
changelogs:
- {date: "23.09.25:", desc: "Add optional WEBUI_USER and WEBUI_PASS environment variables."}
- {date: "17.07.24:", desc: "Restore qbittorrent-cli as it now supports openssl 3."}
- {date: "25.05.24:", desc: "Remove qbittorrent-cli as it still requires openssl 1.1 which is EOL."}
- {date: "14.02.24:", desc: "Only set/override torrenting port if the optional env var is set."}
Expand Down
55 changes: 53 additions & 2 deletions root/etc/s6-overlay/s6-rc.d/init-qbittorrent-config/run
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
# make our folder
mkdir -p /config/qBittorrent

CONFIG_FILE="/config/qBittorrent/qBittorrent.conf"

# copy default config
if [[ ! -f /config/qBittorrent/qBittorrent.conf ]]; then
cp /defaults/qBittorrent.conf /config/qBittorrent/qBittorrent.conf
if [[ ! -f "$CONFIG_FILE" ]]; then
cp /defaults/qBittorrent.conf "$CONFIG_FILE"
fi

if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
Expand All @@ -19,3 +21,52 @@ if [[ -z ${LSIO_NON_ROOT_USER} ]]; then
lsiown -R abc:abc \
/config
fi

# function to generate PBKDF2 hash exactly like qBittorrent source code
generate_pbkdf2_hash() {
local password="$1"
echo "$password" | python3 -c "
import hashlib
import os
import base64
import sys

# Read password from stdin
password = sys.stdin.read().rstrip('\n')

# Generate 16 bytes of random salt
salt = os.urandom(16)

# Generate PBKDF2 hash with exactly qBittorrent's parameters
hash_bytes = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), salt, 100000, 64)

# Format exactly like qBittorrent: saltView.toBase64() + ':' + outBufView.toBase64()
salt_b64 = base64.b64encode(salt).decode('ascii')
hash_b64 = base64.b64encode(hash_bytes).decode('ascii')

print(f'{salt_b64}:{hash_b64}')
"
}

# ensure [Preferences] section exists if WebUI credentials are being configured
if [[ -n ${WEBUI_USER} ]] || [[ -n ${WEBUI_PASS} ]]; then
if ! grep -q "^\s*\[\s*Preferences\s*\]" "$CONFIG_FILE"; then
echo "" >> "$CONFIG_FILE"
echo "[Preferences]" >> "$CONFIG_FILE"
fi
fi

# configure WebUI password
if [[ -n ${WEBUI_PASS} ]]; then
echo "setting WebUI password using WEBUI_PASS"
PBKDF2_HASH=$(generate_pbkdf2_hash "$WEBUI_PASS")
sed -i '/^\s*WebUI\\Password_PBKDF2\s*=/d' "$CONFIG_FILE"
sed -i '/^\s*\[\s*Preferences\s*\]/a WebUI\\Password_PBKDF2="@ByteArray('"$PBKDF2_HASH"')"' "$CONFIG_FILE"
fi

# configure WebUI username
if [[ -n ${WEBUI_USER} ]]; then
echo "setting WebUI username using WEBUI_USER"
sed -i '/^\s*WebUI\\Username\s*=/d' "$CONFIG_FILE"
sed -i '/^\s*\[\s*Preferences\s*\]/a WebUI\\Username="'"$WEBUI_USER"'"' "$CONFIG_FILE"
fi