Open lehmanju opened 1 year ago
I don't think this will work, though I would desperately want it too.
Assuming you're torrenting, clients will report to the tracker the port your client is using. If your client is using 1000 for example, and you've mapped it to the true outbound port of 47209, clients trying to connect with you will try using port 1000, not the outbound port that was forwarded. But at that time no one would be able to connect.
I had the same idea as @lehmanju but can confirm that what probably @BastionNtB says is true. Was trying to set QBittorrent's port to a static one and forward the forwarded port there, but couldn't work...
This is the script I made to set the QB port after a successful connection. Not sure if this helps, cause the original question was port related, but not necessarily attempting to set the port.
I have a volume bind with this script and call "PORT_SCRIPT" environment variable in the docker-wireguard config.
PORT_SCRIPT='/pia-shared/setqbtport.sh'
The script itself will have multiple attempts to connect, so it will essentially wait till it is able to connect; should QB take longer to load. It will also keep track of the original and new port so it won't keep changing it if it's not needed for whatever reason. Do keep in mind I planned for this to work with authentication, but ended up with auth bypass. Not sure if that was because it wouldn't work or whatnot (been awhile since I've had to mess with it), but you may need to bypass auth as well unless the script can be fixed. If you do end up using it as is, the script will work out of the box assuming the environment is similar (and QB has bypass auth for localhost/127.0.0.1 enabled). I didn't share it before because I was unhappy with how I ended up making the script to function, and wanted to make it more cleaner, but alas, never got around to it... Hope it helps someone.
#!/bin/bash
# Check if the correct number of arguments is provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <new_port>"
exit 1
fi
# Output Variables
cookie_file="/tmp/qb-cookies.txt"
logging_path="/pia-shared"
logging_name="qbiport-$(date '+%Y-%m-%d').log"
log_file="/${logging_path}/${logging_name}"
# Set qBittorrent web server URL and API endpoint
QBT_URL="http://127.0.0.1:8080/"
QBT_API="${QBT_URL}api/v2/"
QBT_LOGINENDPOINT="auth/login"
QBT_SETPFENDPOINT="app/setPreferences"
QBT_GETPFENDPOINT="app/preferences"
# Set qBittorrent web server credentials - comment out if qbittorrent is set to bypass auth.
#QBT_WEBUIUSER="your_username"
#QBT_WEBUIPASS="your_password"
# Set the new port number from the command-line argument
NEW_PORT=$1
# Function to log messages
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$log_file"
}
log "Port Script has started, will attempt to change port to ${NEW_PORT}"
# Check if QBT_WEBUIUSER and QBT_WEBUIPASS are undefined
if [ -z "$QBT_WEBUIUSER" ] && [ -z "$QBT_WEBUIPASS" ]; then
AUTHREQUIRED=false
log "No authentication will be used for connection."
else
AUTHREQUIRED=true
log "Authentication will be used for connection."
fi
# Function to check status of qBittorrent web server
check_qbit_status() {
local max_time=60
curl --location "${QBT_URL}" \
--include \
--silent \
--max-time $max_time \
| sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p'
}
# Function to authenticate with qBittorrent web server
new_auth_qbit() {
local max_time=10
curl --location "${QBT_API}${QBT_LOGINENDPOINT}" \
--include \
--silent \
--max-time $max_time \
--header "Referer: ${QBT_URL}"\
--cookie-jar $cookie_file \
--data "username=${QBT_WEBUIUSER}&password=${QBT_WEBUIPASS}" \
| sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p'
}
# Function to get the current port from qBittorrent web server
get_qbit_port() {
local max_time=10
curl --location "${QBT_API}${QBT_GETPFENDPOINT}" \
--silent \
--max-time $max_time \
--header "Referer: ${QBT_URL}"\
--cookie-jar $cookie_file \
| jq '.listen_port'
}
# Function to set the new port in qBittorrent web server
set_qbit_port() {
local max_time=10
curl --location "${QBT_API}${QBT_SETPFENDPOINT}" \
--include \
--silent \
--max-time $max_time \
--header "Referer: ${QBT_URL}"\
--cookie-jar $cookie_file \
--data "json={\"listen_port\":${NEW_PORT}}" \
| sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p'
}
log "Attempting connection with ${QBT_URL}..."
retry_count=0
max_retry=300
while true; do
response=$(check_qbit_status)
if [[ $response -eq 200 ]]; then
log "Connection successful. (http: ${response})"
break
elif ((retry_count++ == $max_retry)); then
log "Failed to reach ${QBT_URL} within ${max_retry} tries. Exiting . . ."
exit 1
else
log "${QBT_URL} responded with \"${response}\" expected '200', retrying (${retry_count}/${max_retry}) . . ."
sleep 10
fi
done
# Authenticate with qBittorrent web server
if $AUTHREQUIRED; then
retry_count=0
max_retry=3
while true; do
log "Attempting authentication ${QBT_API}${QBT_SETPFENDPOINT}"
response=$(new_auth_qbit)
if [[ $response -eq 200 ]]; then
log "Authentication successful. (http: ${response})"
break
elif ((retry_count++ == $max_retry)); then
log "Failed to reach ${QBT_URL} within ${max_retry} tries. Exiting . . ."
exit 1
else
log "${QBT_URL} responded with \"${response}\" expected '200', retrying (${retry_count}/${max_retry}) . . ."
sleep 10
fi
done
fi
log "Fetching current port for confirmation of change . . ."
retry_count=0
max_retry=6
while true; do
CURRENT_PORT=$(get_qbit_port)
if [[ $CURRENT_PORT =~ ^[0-9]+$ ]]; then
log "Detected port number: ${CURRENT_PORT}"
else
log "${QBT_URL} responded with ${CURRENT_PORT} expected a number pattern . . ."
sleep 10
fi
if [[ $CURRENT_PORT != $NEW_PORT ]]; then
log "Attempting to change port from ${CURRENT_PORT} to ${NEW_PORT} . . ."
response=$(set_qbit_port)
if [[ $response -eq 200 ]]; then
log "Port change request successful, checking for port change.. (http: ${response})"
sleep 10
elif ((retry_count++ == $max_retry)); then
log "Failed to set port from ${CURRENT_PORT} to ${NEW_PORT} within ${max_retry} tries. Exiting . . ."
exit 1
else
log "${QBT_URL} responded with http \"${response}\" expected 200, retrying (${retry_count}/${max_retry}) . . ."
sleep 10
fi
else
log "Listen port is correctly set."
break
fi
done
# Clean up temporary files
rm -f $cookie_file
This is the script I made to set the QB port after a successful connection. Not sure if this helps, cause the original question was port related, but not necessarily attempting to set the port.
I have a volume bind with this script and call "PORT_SCRIPT" environment variable in the docker-wireguard config.
PORT_SCRIPT='/pia-shared/setqbtport.sh'
The script itself will have multiple attempts to connect, so it will essentially wait till it is able to connect; should QB take longer to load. It will also keep track of the original and new port so it won't keep changing it if it's not needed for whatever reason. Do keep in mind I planned for this to work with authentication, but ended up with auth bypass. Not sure if that was because it wouldn't work or whatnot (been awhile since I've had to mess with it), but you may need to bypass auth as well unless the script can be fixed. If you do end up using it as is, the script will work out of the box assuming the environment is similar (and QB has bypass auth for localhost/127.0.0.1 enabled). I didn't share it before because I was unhappy with how I ended up making the script to function, and wanted to make it more cleaner, but alas, never got around to it... Hope it helps someone.
#!/bin/bash # Check if the correct number of arguments is provided if [ "$#" -ne 1 ]; then echo "Usage: $0 <new_port>" exit 1 fi # Output Variables cookie_file="/tmp/qb-cookies.txt" logging_path="/pia-shared" logging_name="qbiport-$(date '+%Y-%m-%d').log" log_file="/${logging_path}/${logging_name}" # Set qBittorrent web server URL and API endpoint QBT_URL="http://127.0.0.1:8080/" QBT_API="${QBT_URL}api/v2/" QBT_LOGINENDPOINT="auth/login" QBT_SETPFENDPOINT="app/setPreferences" QBT_GETPFENDPOINT="app/preferences" # Set qBittorrent web server credentials - comment out if qbittorrent is set to bypass auth. #QBT_WEBUIUSER="your_username" #QBT_WEBUIPASS="your_password" # Set the new port number from the command-line argument NEW_PORT=$1 # Function to log messages log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$log_file" } log "Port Script has started, will attempt to change port to ${NEW_PORT}" # Check if QBT_WEBUIUSER and QBT_WEBUIPASS are undefined if [ -z "$QBT_WEBUIUSER" ] && [ -z "$QBT_WEBUIPASS" ]; then AUTHREQUIRED=false log "No authentication will be used for connection." else AUTHREQUIRED=true log "Authentication will be used for connection." fi # Function to check status of qBittorrent web server check_qbit_status() { local max_time=60 curl --location "${QBT_URL}" \ --include \ --silent \ --max-time $max_time \ | sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p' } # Function to authenticate with qBittorrent web server new_auth_qbit() { local max_time=10 curl --location "${QBT_API}${QBT_LOGINENDPOINT}" \ --include \ --silent \ --max-time $max_time \ --header "Referer: ${QBT_URL}"\ --cookie-jar $cookie_file \ --data "username=${QBT_WEBUIUSER}&password=${QBT_WEBUIPASS}" \ | sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p' } # Function to get the current port from qBittorrent web server get_qbit_port() { local max_time=10 curl --location "${QBT_API}${QBT_GETPFENDPOINT}" \ --silent \ --max-time $max_time \ --header "Referer: ${QBT_URL}"\ --cookie-jar $cookie_file \ | jq '.listen_port' } # Function to set the new port in qBittorrent web server set_qbit_port() { local max_time=10 curl --location "${QBT_API}${QBT_SETPFENDPOINT}" \ --include \ --silent \ --max-time $max_time \ --header "Referer: ${QBT_URL}"\ --cookie-jar $cookie_file \ --data "json={\"listen_port\":${NEW_PORT}}" \ | sed -n -E 's/HTTP\/.+ ([0-9]+).*/\1/p' } log "Attempting connection with ${QBT_URL}..." retry_count=0 max_retry=300 while true; do response=$(check_qbit_status) if [[ $response -eq 200 ]]; then log "Connection successful. (http: ${response})" break elif ((retry_count++ == $max_retry)); then log "Failed to reach ${QBT_URL} within ${max_retry} tries. Exiting . . ." exit 1 else log "${QBT_URL} responded with \"${response}\" expected '200', retrying (${retry_count}/${max_retry}) . . ." sleep 10 fi done # Authenticate with qBittorrent web server if $AUTHREQUIRED; then retry_count=0 max_retry=3 while true; do log "Attempting authentication ${QBT_API}${QBT_SETPFENDPOINT}" response=$(new_auth_qbit) if [[ $response -eq 200 ]]; then log "Authentication successful. (http: ${response})" break elif ((retry_count++ == $max_retry)); then log "Failed to reach ${QBT_URL} within ${max_retry} tries. Exiting . . ." exit 1 else log "${QBT_URL} responded with \"${response}\" expected '200', retrying (${retry_count}/${max_retry}) . . ." sleep 10 fi done fi log "Fetching current port for confirmation of change . . ." retry_count=0 max_retry=6 while true; do CURRENT_PORT=$(get_qbit_port) if [[ $CURRENT_PORT =~ ^[0-9]+$ ]]; then log "Detected port number: ${CURRENT_PORT}" else log "${QBT_URL} responded with ${CURRENT_PORT} expected a number pattern . . ." sleep 10 fi if [[ $CURRENT_PORT != $NEW_PORT ]]; then log "Attempting to change port from ${CURRENT_PORT} to ${NEW_PORT} . . ." response=$(set_qbit_port) if [[ $response -eq 200 ]]; then log "Port change request successful, checking for port change.. (http: ${response})" sleep 10 elif ((retry_count++ == $max_retry)); then log "Failed to set port from ${CURRENT_PORT} to ${NEW_PORT} within ${max_retry} tries. Exiting . . ." exit 1 else log "${QBT_URL} responded with http \"${response}\" expected 200, retrying (${retry_count}/${max_retry}) . . ." sleep 10 fi else log "Listen port is correctly set." break fi done # Clean up temporary files rm -f $cookie_file
Cheers tbh later on I found: https://github.com/thrnz/docker-wireguard-pia/issues/26#issuecomment-925874550 Which actually works great... Cheers :)
Glad you got it working! I found that one too, but I didn't like that it wouldn't wait long enough, didn't have logic to detect certain conditions, or have more robust logging to show what was going on, which is why mine ended up being longer.
Glad you got it working! I found that one too, but I didn't like that it wouldn't wait long enough, didn't have logic to detect certain conditions, or have more robust logging to show what was going on, which is why mine ended up being longer.
Fair, though to be honest, I just tried, but although when no authenication it is fine, it fails to authenicate with user/pass provided for some reason.... I modified the script to "echo" the user and the pass that I pass through env variables and they seem correct :(
FWIW, I ended up just making another tiny Docker container that runs alongside PIA and qBittorrent, using inotifywait
to watch for the port changes. Seems to work reliably for me.
To further simplify automatic reconfiguration of incoming ports, consider adding following snippet to one of the scripts:
This would allow other containers to listen on a fixed port while PIA changes the remote port dynamically.