I was trying to set up Port Forwarding for my router (connected to Private Internet Access (PIA) VPN) and came across this post. Basically, PIA only allows port forwarding on some of their servers, and you have to run either their apps provided, or some script in order to get a port number which you can use for port forwarding.

This article assumes that you have already got your Asus router running RMerlin firmware setup and connected to PIA. If you are looking for how to do that, please see here.

I’m running RMerlin firmware on my ASUS RT-AC66U and wanted to run the script directly off my router, so I figured it should somewhat work. It did, after some minor changes. I had to modify the file available to the following:

#! /bin/sh
#
# Enable port forwarding
#
# Requirements:
#   your Private Internet Access user and password as arguments
#
# Usage:
#  ./port_forward.sh <user> <password>

error( )
{
  echo "$@" 1>&2
  exit 1
}

error_and_usage( )
{
  echo "$@" 1>&2
  usage_and_exit 1
}

usage( )
{
  echo "Usage: `dirname $0`/$PROGRAM <user> <password>"
}

usage_and_exit( )
{
  usage
  exit $1
}

version( )
{
  echo "$PROGRAM version $VERSION"
}


port_forward_assignment( )
{
  echo 'Loading port forward assignment information..'
  if [ "$(uname)" == "Linux" ]; then
    local_ip=`ifconfig tun11|grep -oE "inet addr: *10\.[0-9]+\.[0-9]+\.[0-9]+"|tr -d "a-z :"|tee /tmp/vpn_ip`
    client_id=`head -n 100 /dev/urandom | md5sum | tr -d " -"`
  fi
  if [ "$(uname)" == "Darwin" ]; then
    local_ip=`ifconfig tun11 | grep "inet " | cut -d\  -f2|tee /tmp/vpn_ip`
    client_id=`head -n 100 /dev/urandom | md5 -r | tr -d " -"`
  fi
  json=`wget -q --post-data="user=$USER&pass=$PASSWORD&client_id=$client_id&local_ip=$local_ip" -O - 'https://www.privateinternetaccess.com/vpninfo/port_forward_assignment' --no-check-certificate | head -1`
  echo $json
}

EXITCODE=0
PROGRAM=`basename $0`
VERSION=1.0
USER=$1
PASSWORD=$2

while test $# -lt 2
do
  case $1 in
  --usage | --help | -h )
    usage_and_exit 0
    ;;
  --version | -v )
    version
    exit 0
    ;;
  *)
    error_and_usage "Unrecognized option: $1"
    ;;
  esac
  shift
done

port_forward_assignment

exit 0

The main changes are as follows:

  • /bin/bash to /bin/sh
  • tun0 to tun11, I’m not sure if it varies between different routers running on RMerlin’s firmware
  • Had to add --no-check-certificate in order for the wget command to actually work

You can then run it with ./port_forward.sh <user> <password> and you should get a response similar to { "port": 12345 }. Do make sure that you are connected to one of their servers that allow port forwarding. As it turns out, each time you request for a port number, PIA returns a different result. This also means that each login to PIA would return a new port number as a new request has to be made with each login. I’m not very keen on running the script, getting the result, updating my port forwarding rules and pdating my applications to use the updated port with each restart of my router, even if restarts are rare. In the next part, we will have a look at the steps I did to streamline my setup.

comments powered by Disqus