Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
PrivateInternetAccess Port Forwarding Script
#!/usr/bin/env python3
#original script by Hanashi from PIA forums, mods to update transmission by Doonze
#converted to python3 and Deluge support added by Rastan
import requests
import json
import sys
import netifaces
import os
import getopt
import hashlib
#Which Action to take. Currently supported are:
# print : Print your public IP address and port
# portonly : Return only the port number. Useful for piping to another program
# deluge : Configure Deluge's incoming port.
# transmission : Configure Transmission's incoming port
action = "print"
#Fetch the password from file. Specify the path to your pialogin.txt file you use for openvpn
#First line should be your PIA login
#Second line should be your PIA password
piaPasswordFilePath = '/etc/openvpn/pialogin.txt'
#If you don't want to use a file, put your VPN username and password below instead
#If the file path is set to anything but "", it overrides this setting
YOUR_USERNAME = "p11223344"
# This should be a long random string, or something that no one else is going
# to be able to guess. Don't share this amongst multiple computers on the
# same VPN account. If you have more than one computer, use a different client
# ID for each. I recommend the output of the Linux "uuidgen" command, but
# you can really just use whatever.
# Default is the SHA1 hash of your username and password.
# The interface your VPN uses. We use this to look up your local IP, as
# required by the port forwarding API. Probably you won't have to change this
# unless you really know what you're doing (e.g., if you have more than one
# VPN tunnel on the same system or something)
VPN_IFACE = "tun0"
# This is the API URL. Don't change this.
API_URL = ""
# This is the path to the deluge config directory. Used to log into deluge
delugeConfigPath = '/var/lib/deluged/config'
# Look up the local IP from the VPN interface
local_ip = netifaces.ifaddresses(VPN_IFACE)[netifaces.AF_INET][0]["addr"]
except ValueError:
print ("No such interface. Are you connected to the VPN?")
#Retrieve the username/password from file if path is specified
if piaPasswordFilePath != "":
pwfile = open(piaPasswordFilePath, 'r')
YOUR_USERNAME = pwfile.readline().rstrip('\n')
YOUR_PASSWORD = pwfile.readline().rstrip('\n')
#Generate a client ID from username/password hash if one hasn't been specified
if YOUR_CLIENT_ID == "":
YOUR_CLIENT_ID = hashlib.sha1((YOUR_USERNAME + YOUR_PASSWORD).encode('utf-8')).hexdigest()
# Make the port forward request to the PIA web API
portresponse =, data =
except ValueError:
print(("Error While Fetching PIA Public Port: {}".format(portresponse["error"])))
#Perform the requested action
if portresponse.json()["port"]:
port = portresponse.json()["port"]
if action == "portonly":
elif action == "print":
publicip = requests.get('').text
print('Public Port Assigned: {}:{}'.format(publicip,port))
elif action == "deluge":
print('Configuring Deluge Public Port')
cmdstring = 'deluge-console -c {} \"config -s listen_ports ({},{})\"'.format(delugeConfigPath,port,port)
elif action == "transmission":
print('Configuring Transmission Public Port')
cmdstring = 'transmission-remote -n "{}:{}" -p {}'.format(YOUR_USERNAME,YOUR_PASSWORD,port)
print ("Error: no idea what failed!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment