Skip to content

Instantly share code, notes, and snippets.

@JustinGrote
Last active June 8, 2024 22:30
Show Gist options
  • Save JustinGrote/9983ad3def74e6e0c5cd9bc91ebdd7b4 to your computer and use it in GitHub Desktop.
Save JustinGrote/9983ad3def74e6e0c5cd9bc91ebdd7b4 to your computer and use it in GitHub Desktop.
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
### IMPORTS
import requests
import json
import sys
import netifaces
import os
import getopt
import hashlib
###VARIABLES
#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"
YOUR_PASSWORD = "oiuaweEXAMPLEwer"
# 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.
YOUR_CLIENT_ID = ""
# 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 = "https://www.privateinternetaccess.com/vpninfo/port_forward_assignment"
# This is the path to the deluge config directory. Used to log into deluge
delugeConfigPath = '/var/lib/deluged/config'
### BEGIN SCRIPT
# Look up the local IP from the VPN interface
try:
local_ip = netifaces.ifaddresses(VPN_IFACE)[netifaces.AF_INET][0]["addr"]
except ValueError:
print ("No such interface. Are you connected to the VPN?")
sys.exit(-1)
#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
try:
portresponse = requests.post(API_URL, data =
{
"user":YOUR_USERNAME,
"pass":YOUR_PASSWORD,
"client_id":YOUR_CLIENT_ID,
"local_ip":local_ip
}
)
except ValueError:
print(("Error While Fetching PIA Public Port: {}".format(portresponse["error"])))
sys.exit(-1)
#Perform the requested action
if portresponse.json()["port"]:
port = portresponse.json()["port"]
if action == "portonly":
print(port)
elif action == "print":
publicip = requests.get('https://ipapi.co/ip/').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)
os.system(cmdstring)
elif action == "transmission":
print('Configuring Transmission Public Port')
cmdstring = 'transmission-remote -n "{}:{}" -p {}'.format(YOUR_USERNAME,YOUR_PASSWORD,port)
os.system(cmdstring)
sys.exit(0)
else:
print ("Error: no idea what failed!")
sys.exit(-2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment