New PIA Port Forwarding API

Hi everyone!

We've recently introduced a new port forwarding API. This one's simpler, more reliable, and will be replacing the port forwarding API all of you fine folks currently use.

Here is a shell script that retrieves a port using this new API:
https://privateinternetaccess.com/installer/port_forwarding.sh

To run this script, simply download, make sure it has the correct permissions, and then you should be free to run it. Or, these commands in your terminal:

wget https://privateinternetaccess.com/installer/port_forwarding.sh
chmod +x port_forwarding.sh
./port_forwarding.sh

Essentially, to use this API you send a request to the URL below, where client_id is a unique 256-bit ID in Base36 format:
http://209.222.18.222:2000/?client_id=$client_id

For an easy way to calculate the client ID, take a look at the script above.

Once you've sent this request, the API should return json containing the port number: {"port":49645}

Then, this port should be available for you to use!


Keep in mind that this new API will be replacing the old one, and that the old API located at vpninfo/port_forward_assignment will be discontinued sometime soon.

I've also got some considerations to remember while using this API:

  • This request is handled locally by the gateway you're connected to.
  • You can only request one port per connection.
  • With the new API, you no longer need to 'poll' the API periodically to keep the forwarded port open. As such, you only need to query the API once to open up the port.
  • When a port is forwarded, you will not be able to connect to that port from the public IP that initiated the OpenVPN connection.
    To confirm port forwarding is working, retrieve a port using the API and run a command like this to listen on it:
    ncat -l <port>
    After this, you can use an online testing site to confirm that port's open on your VPN gateway.

Hopefully this lets you update your scripts to use the new API and interoperate nicely with it! For more guidance on error-handling, feel free to dig into the script above, and if there are any issues feel free to post in here and I can take a look.

«13

Comments

  • Posts: 135
    Additional note: the port must be requested within 2 minutes of connecting to the VPN. Past this point the API is no longer available and will just refuse connection.
  • Posts: 181
    How is this new API better than the old one? What's the difference? Please explain.
  • Posts: 135
    @OpenVPN: A lot easier to use and safer, mostly. The previous API required to call the website, which had to be done on the VPN so that the API could see which server you're on. You also had to pass it your local address too which usually involved parsing `ifconfig` or `ip addr`, and you had to call it once every hour to keep your port. Overall it required a bit of effort. Now you can just slap it as your `--up`script on stock OpenVPN and be done with it :)
  • "Once you've sent this request, the API should return json containing the port number: {"port":49645}" I've run the script and it returns: "Loading port forward assignment information... Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding" But no information as to which port to use. Is there something that I'm missing?
  • Posts: 4
    I also receive only "Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding". I'm definitely calling the example script within two minutes of establishing the connection, and it doesn't seem to matter which gateway I'm trying. I can't seem to use the old API either. Is the roll-out of the new API not actually completed yet?
  • Posts: 4
    zzzasdf said:
    I also receive only "Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding". I'm definitely calling the example script within two minutes of establishing the connection, and it doesn't seem to matter which gateway I'm trying. I can't seem to use the old API either. Is the roll-out of the new API not actually completed yet?
    Okay- in my case the issue was my older route up scripts for openvpn needed updating. I use ip route/rule commands for split tunneling, so needed to add an "ip rule add from all to 209.222.18.222 lookup 10" to ensure the curl connection goes through the VPN'd interface. Once that change was made I successfully got a port... Thanks!
  • Posts: 4
    zzzasdf said:
    zzzasdf said:
    I also receive only "Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding". I'm definitely calling the example script within two minutes of establishing the connection, and it doesn't seem to matter which gateway I'm trying. I can't seem to use the old API either. Is the roll-out of the new API not actually completed yet?
    Okay- in my case the issue was my older route up scripts for openvpn needed updating. I use ip route/rule commands for split tunneling, so needed to add an "ip rule add from all to 209.222.18.222 lookup 10" to ensure the curl connection goes through the VPN'd interface. Once that change was made I successfully got a port... Thanks!
    In the example script, I also had to escape the "?" in the curl request. I.e. /\?client_id...
  • Posts: 6
    zzzasdf said:
    zzzasdf said:
    I also receive only "Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding". I'm definitely calling the example script within two minutes of establishing the connection, and it doesn't seem to matter which gateway I'm trying. I can't seem to use the old API either. Is the roll-out of the new API not actually completed yet?
    Okay- in my case the issue was my older route up scripts for openvpn needed updating. I use ip route/rule commands for split tunneling, so needed to add an "ip rule add from all to 209.222.18.222 lookup 10" to ensure the curl connection goes through the VPN'd interface. Once that change was made I successfully got a port... Thanks!
    If you are using split tunneling, then a solution would be to run the script as the user routed over VPN. You can configure a Cron Job for the user and set it to run with a delay of 30 seconds on boot, then VPN is already up, and you are still within the 2 minutes time frame.
  • edited February 5 Posts: 14
    Thanks for the update. I've got some additional questions. I'm not using OpenVPN, but instead use your windows client. I'm doing this because I've never been able to get the same speeds using OpenVPN, the client is always considerably faster. What I do at present is run two powershell scripts, launch and update. The launch script runs at login, waits until the VPN interface is up, gets the local IP and then queries for the port number (for client ID I'm using the value in "C:\Program Files\pia_manager\data\client_id.txt"). It then passes these values to a program it launches. The update script runs every hour, and just checks if the local IP address has changed; if it has then it passes that to my program. With these changes: Do I need to query for the port number within 2 minutes when using the PIA client? Is that port number locked in so that it does not change as long as I'm connected? In the event of a disconnect, will I get the same port number when the client reconnects? Usually the connection is pretty stable, but every once in a while I notice the connection may drop and immediately reconnect? What about the local IP (10.x.x.x) ? When I first wrote the script, it changed occasionally, though I notice that now it seems keep the same IP for days on end. Does it still update, and does it change if there is a disconnect/connect sequence? Thanks for all the help! edit: how do I get this stupid message to show line feeds????
    Post edited by BobP19454 on
  • Posts: 135
    @BobP19454 If you use the PIA client, you don't need to do anything. The client handles it all for you. The port will show up on the tooltip of the PIA icon in your system tray.
  • Posts: 14
    Max-P said:
    @BobP19454 If you use the PIA client, you don't need to do anything. The client handles it all for you. The port will show up on the tooltip of the PIA icon in your system tray.
    Max, I know that, I want it to update my torrent client programmatically :smile:
  • edited February 5 Posts: 135
    @BobP19454 Oh sorry, I misread it. I don't think you can call the API twice so that's not very helpful...

    If you send {"cmd": "status"} to 127.0.0.1:31743 over plain TCP it will return you the PIA status, including the forwarded port. I think that's the only way to do it while using the PIA client.

    Alternatively, if you pass the same arguments to OpenVPN as the PIA client does you should be able to get the same speeds and then have much more flexibility for scripting.
    Post edited by Max-P on
  • edited February 5 Posts: 14
    Max-P said:
    @BobP19454 Oh sorry, I misread it. I don't think you can call the API twice so that's not very helpful...

    If you send {"cmd": "status"} to 127.0.0.1:31743 over plain TCP it will return you the PIA status, including the forwarded port. I think that's the only way to do it while using the PIA client.

    Alternatively, if you pass the same arguments to OpenVPN as the PIA client does you should be able to get the same speeds and then have much more flexibility for scripting.
    I know, you think that would be simple. I tried the suggested OpenVPN settings, and then manual settings as shown here: https://helpdesk.privateinternetaccess.com/hc/en-us/articles/225274288-Which-encryption-auth-settings-should-I-use-for-ports-on-your-gateways-
    None of them gave the same results as the client. I have a 75/75 connection, with the client I usually see 65/65, and with OpenVPN I've never seen more than 30/30. Weird, huh? Looking at the running client, I see it's using UDP on port 500, which isn't even listed in your table
    Post edited by BobP19454 on
  • Posts: 6
    Did anyone manage to run the script with OpenVPN up at system start? OpenVPN refuses to start if I call the script with up. Any ideas how to automate getting the port number?
  • Posts: 1
    Max-P said:
    If you send {"cmd": "status"} to 127.0.0.1:31743 over plain TCP it will return you the PIA status, including the forwarded port. I think that's the only way to do it while using the PIA client.
    @Max-P So this should work with the normal OSX PIA client (version 65)? I see the port number when hovering my cursor over the tray icon but when I try to get the port via BASH script using cURL, it fails with curl: (52) Empty reply from server. The cURL commands I've tried are /usr/bin/curl http://127.0.0.1:31743 -d '{"cmd": "status"}' -H "Content-Type: application/json" -X POST and /usr/bin/curl http://127.0.0.1:31743 -d '{"cmd": "status"}' Currently I'm parsing the pia_manager.log for the port but it isn't 100% accurate so I'd love to be able to query the client directly. Thanks
  • Posts: 135
    @Smudge It's not an HTTP API, that's the internal API and it's a raw socket. I found it with Wireshark while troubleshooting something else.

    echo '{"cmd": "status"}' | nc 127.0.0.1 31743
  • Posts: 3
    szimat said:
    Did anyone manage to run the script with OpenVPN up at system start? OpenVPN refuses to start if I call the script with up. Any ideas how to automate getting the port number?
    ive got the exact same issue, basically curl cannot connect when used via a openvpn "up" script, any solutions to this?
  • Posts: 4
    binhex said:
    szimat said:
    Did anyone manage to run the script with OpenVPN up at system start? OpenVPN refuses to start if I call the script with up. Any ideas how to automate getting the port number?
    ive got the exact same issue, basically curl cannot connect when used via a openvpn "up" script, any solutions to this?
    I don't have a problem calling curl as part of the up script, BUT I'm doing so in sub-scripts and sub-shells. So at the end of my "up" script I call another script to get the forwarded port and update that port in a client configuration file. In the port forward update script I call, I use the following two commands (from PIA's example): pia_client_id=`head -n 100 /dev/urandom | sha256sum | tr -d " -"` forwarded_port=$(curl "http://209.222.18.222:2000/\?client_id=$pia_client_id" 2>/dev/null | awk -F ':' '{ print $2 }'| awk -F '}' '{ print $1 }') I can then use the $forwarded_port variable however needed.
  • edited February 14 Posts: 3
    thanks zzzasdf!, i did come to the same conclusion over the weekend and can now grab a port, HOWEVER ive discovered the port im allocated isnt open :-(, have you tested the port your port forward, and if so what was your outcome?. update - turned out it was an application issue, the port is indeed open.
    Post edited by binhex on
  • Hi all, how can I get additional ports forwarded instead of one (?). I on latest built-in client and Win 10.
  • edited February 19 Posts: 1
    So I manage to run this script on my DD-WRT router and thought i could share some details:

    1. Modify the script, since i couldn't get the sha256sum command to run
    Download https://privateinternetaccess.com/installer/port_forwarding.sh
    Edit only section or :port_forward_assignment( ) to something like this, (remove client id generation if statements and specify client_id by yourself)
    # Edit only this part of the script

    port_forward_assignment( )
    {
      echo 'Loading port forward assignment information...'

      json=`curl "http://209.222.18.222:2000/?client_id=YOURsha256HERE" 2>/dev/null`
      if [ "$json" == "" ]; then
        json='Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding'
      fi

      echo $json
    }

    # Don't edit script below
    The SHA sum should be generated with some unique characteristics
    http://www.xorbin.com/tools/sha256-hash-calculator
    or on windows use CMD , certUtil -hashfile \some_personal_file.txt SHA256
    place it in json command and save script.
    It should look something like this
      json=`curl "http://209.222.18.222:2000/?client_id=9b7ecc6eeb83abf9ade10fe38865df4499be3568dcc507ae2ec3b44989cb0093" 2>/dev/null`



    2. Use WinSCP to transfer the script to your router, chmod (F9 change permission to XXX)

    3. From the terminal putty or built in from WinSCP , run:(make sure y are in right dir ect. )
    sh /port_forwarding.sh

    Loading port forward assignment information...
    {"port":XXxXX}

    Note: This must be done 2 min after router reboot or VPN connection is established  and problems must be investigated from
    1. DD-WRT Port forwarding
    2. PC firewall i.e Norton Internet Security software ect.
    3. DD-WRT router is behind a 1st primary router in network ect.



    Post edited by gvci614 on
  • Posts: 5
    Max-P said:
    @OpenVPN: A lot easier to use and safer, mostly. The previous API required to call the website, which had to be done on the VPN so that the API could see which server you're on. You also had to pass it your local address too which usually involved parsing `ifconfig` or `ip addr`, and you had to call it once every hour to keep your port. Overall it required a bit of effort. Now you can just slap it as your `--up`script on stock OpenVPN and be done with it :)

  • Posts: 5
    Hello everybody,

    I have an Apache web server running on Linux Debian 8. OpenVPN is installed and configured.
    PIA VPN TCP connection is established with a server port 80 open.
    The script Portforwarding.sh I also use.
    If I now from the Internet my webserver via the public VPN IP reach I can only do this if I enter the "VPN Public IP:Port" and the web server on the Portforwarding.sh port list.
    But I would like to reach the web server on port 80 without having to enter the port extra behind the IP.
    Who has a solution?
  • edited February 20 Posts: 14
    Should any of these OpenVPN (using Viscosity) commands be removed or changed with this new port forwarding method?
    I only ask because this morning the old and new way to get port forwarding isn't working.

    tls-client
    resolv-retry infinite
    auth-nocache 
    mute-replay-warnings 
    disable-occ 
    auth sha256
    remote-cert-tls server
    cipher aes-256-cbc
    reneg-sec 0
    script-security 2
    crl-verify crl.rsa.4096.pem


    Post edited by thisoldwhorehouse007 on
  • Posts: 6
    zzzasdf said:
    binhex said:
    szimat said:
    Did anyone manage to run the script with OpenVPN up at system start? OpenVPN refuses to start if I call the script with up. Any ideas how to automate getting the port number?
    ive got the exact same issue, basically curl cannot connect when used via a openvpn "up" script, any solutions to this?
    I don't have a problem calling curl as part of the up script, BUT I'm doing so in sub-scripts and sub-shells. So at the end of my "up" script I call another script to get the forwarded port and update that port in a client configuration file. In the port forward update script I call, I use the following two commands (from PIA's example): pia_client_id=`head -n 100 /dev/urandom | sha256sum | tr -d " -"` forwarded_port=$(curl "http://209.222.18.222:2000/\?client_id=$pia_client_id" 2>/dev/null | awk -F ':' '{ print $2 }'| awk -F '}' '{ print $1 }') I can then use the $forwarded_port variable however needed.
    Still not working for me, I don't know what I'm missing here. Can you post the full up script you use? Maybe add logging to the script, to print the port number to a log file, just for troubleshooting, once I know it works, I can easily use the $port variable in my scripts.
  • Can someone please help me out here? In September, started to use the PIA client on my Macbook. This caused my imessages to not work with an Authentication error. I uninstalled PIA and used tunnelblick since, but still, no iMessage. Same error. http://i.imgur.com/I423rAn.png

    I've done normal troubleshooting - deleting plists, even reinstalling the OS. All but a fresh install. I believe there is a setting somewhere that is preventing Messages from receiving incoming info. 

    Please help! I've been going back and forth with Apple Senior Support staff since October.

    Thanks!
  • edited March 1 Posts: 9
    I am using an older DD-WRT router and using the older OpenVPN startup script located here: https://www.privateinternetaccess.com/forum/discussion/345/setting-up-dd-wrt-openvpn-client

    For the life of me I can NOT get the forward to work in iptables. Well I get a correct response that the new PIA script that a port has been forwarded and provided a port number.

    Can anyone test this with 1194 OpenVPN? I notice the new setup for DD_WRT OpenVPN uses 1198 for the PIA server port. I wonder if port 1194 has been neglected and does not forward ports with this new forward script.
    Post edited by bunklung on
  • edited March 3 Posts: 7
    When will the old script stop working?

    I'll attempt to try this new method on my older QNAP at some point, but would like to have an idea of exacrly how much time I've got so I can plan it in.

    Also, any plans to change the 2 minute limit? I'm sure i'm not alone in saying majority of us leave our connections on, and for those of us using private trackers we're obviously trying to seed back. If the connection drops or resets for whatever reason it can be hours before I've noticed it. The old way I just SSH in, run the script again, get my port number and change it.

    This new way looks as if I'm going to have to also go into my QNAP Web gui, disconnect, reconnect, then run the script. Which is anything but simpler, especially if I'm not at home.
    Post edited by ensignvorik on
  • Posts: 9
    It's me again. I figured this out. At first I was using nc with telnet and this works over a local LAN, but the behavior is completely different over the Internet. I also had to install Cygwin on the Windows PC connected to DD-WRT since my DD-WRT firmware does not have curl. I did have to modify the script slightly since it was adding an asterisk to the SHA-256/client_id AND uname does not work correctly and report Linux, it reports CYGWIN_NT-5.1.

    if [ "$(uname)" == "CYGWIN_NT-5.1" ]; then
    client_id=`head -n 100 /dev/urandom | sha256sum | tr -d " *-"`

    Maybe someone with some serious magic can help with the curl limitation on DD-WRT. I think there are ways to us nc instead of curl.

    I connect to CA Toronto. I ran the script within two minutes of connecting and got a proper port forward response. I use that port and place it in the two commands below where xxxxx is the port and PCIP is the LAN IP address of my Windows PC connected to DD-WRT.

    The iptables rule I must run after running the PIA script in DD-WRT was this:

    iptables -I INPUT -i tun0 -p tcp --dport xxxxx -j ACCEPT
    iptables -t nat -I PREROUTING -p tcp --dport xxxxx -j DNAT --to-destination PCIP:22222

    Port 22222 is something I use contantly so I don't have to modify the port on my PC software. I did not have to use a FORWARD rule.

    I then run nc -l xxxxx on my Windows PC (withing Cygwin)
    and use the website: http://www.yougetsignal.com/tools/open-ports/

    The nc command should exit and the website should report that the port is open.

    I did the same testing on a Raspberry PI 3 and only had to issue the INPUT iptables rule above. However, the nc command was "nc -l -p xxxxx". The difference is that my Raspberry PI does not have NAT or act as a router in anyway. I will at some point turn it into a full router and have to issue the PREROUTING rule from above. I will say that I was surprised at how fast the PI 3 was. I could get a full 50mbps over the VPN. Bye bye DD-WRT...

  • edited March 6 Posts: 9
    If you forward the external port (ex. 44444) to a different internal port (ex. 22222) will your local client announce the WRONG port to external remote connecting clients? It seems like this would break some clients as the client needs to know the true external port. Can any experts chime in? 
    Post edited by bunklung on
Sign In or Register to comment.