Script to port forward port to Transmission plugin (in jail)

Status
Not open for further replies.

denist

Contributor
Joined
Jan 28, 2013
Messages
188
i have installed bash and it is asking that i need to mount it do i have to?

bash requires fdescfs(5) mounted on /dev/fd

If you have not done it yet, please do the following:

mount -t fdescfs fdesc /dev/fd

To make it permanent, you need the following lines in /etc/fstab:

fdesc /dev/fd fdescfs rw 0 0
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
The file is excecutable and i instralled bash and still getting the below error.

root@transmission_1:/usr/local/etc/pia_openvpn # sh /usr/local/etc/pia_openvpn/port_forward.sh
: not foundetc/pia_openvpn/port_forward.sh:
: not foundetc/pia_openvpn/port_forward.sh:
: not foundetc/pia_openvpn/port_forward.sh:
Transmission Port Forward 2016-12-18-09:28:28
: not foundetc/pia_openvpn/port_forward.sh:
: not foundetc/pia_openvpn/port_forward.sh: {
/usr/local/etc/pia_openvpn/port_forward.sh: 32: Syntax error: "elif" unexpected (expecting "then")
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Hi i got the script to run but it restarts the vpn where it kills the internet as i have a cron job that runs every 5 mins that rewrites the ipfw_rules so when you script restarts the openvpn service there is no connection for 5 min. you script exits saying not subscription.
is there a way to stop the restart or if i can show you my py script that i run for the kill switch.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
#!/usr/local/bin/python2.7
import sys
import socket
import subprocess
url = 'Sweden.privateinternetaccess.com'
try:
# Raise if it can't ping the server or openvpn isn't running
subprocess.check_output(['service', 'openvpn', 'status'])
subprocess.check_output(['ping', '-c', '1', url])
except subprocess.CalledProcessError:
pass
else:
sys.exit()
hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex(url)
content = '''
add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
'''
rule_number = 2001
for ip in ipaddrlist:
content += '''
add {} allow ip from 192.168.2.0/24 to {} keep-state
add {} allow ip from {} to 192.168.2.0/24 keep-state
'''.format(rule_number, ip, rule_number + 1, ip)
rule_number += 2
content += '''
add 04000 allow ip from 127.0.0.1 to any
add 05000 allow ip from 10.0.0.0/8 to any
add 05002 allow ip from any to 10.0.0.0/8
add 65534 deny ip from any to any
'''
# Stop ipfw
subprocess.call(['service', 'openvpn', 'stop'])
subprocess.call(['service', 'ipfw', 'stop'])
f = open('/sabnzbd/scripts/ipfw_rules', 'w')
f.write(content)
f.close()
# Start ipfw
subprocess.call(['service', 'ipfw', 'start'])
# Check if running
if 'ipfw' in subprocess.check_output(['service', '-e']):
subprocess.call(['service', 'openvpn', 'start'])
sys.exit()
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Code:
#!/usr/local/bin/python2.7
import sys
import socket
import subprocess
url = 'Sweden.privateinternetaccess.com'
try:
  # Raise if it can't ping the server or openvpn isn't running
  subprocess.check_output(['service', 'openvpn', 'status'])
  subprocess.check_output(['ping', '-c', '1', url])
except subprocess.CalledProcessError:
  pass
else:
  sys.exit()
hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex(url)
content = '''
add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
'''
rule_number = 2001
for ip in ipaddrlist:
  content += '''
add {} allow ip from 192.168.2.0/24 to {} keep-state
add {} allow ip from {} to 192.168.2.0/24 keep-state
'''.format(rule_number, ip, rule_number + 1, ip)
  rule_number += 2
content += '''
add 04000 allow ip from 127.0.0.1 to any
add 05000 allow ip from 10.0.0.0/8 to any
add 05002 allow ip from any to 10.0.0.0/8
add 65534 deny ip from any to any
'''
# Stop ipfw
subprocess.call(['service', 'openvpn', 'stop'])
subprocess.call(['service', 'ipfw', 'stop'])
f = open('/sabnzbd/scripts/ipfw_rules', 'w')
f.write(content)
f.close()
# Start ipfw
subprocess.call(['service', 'ipfw', 'start'])
# Check if running
if 'ipfw' in subprocess.check_output(['service', '-e']):
  subprocess.call(['service', 'openvpn', 'start'])
sys.exit()

 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
If there is a nicer way for me to use the Kill switch script and the portforward script together it would be great.

The script runs every 5 min so when openvpn goes down the ipfw_rules are still the old ones when openvpn comes back online hence why not internet for the jail. When the script runs next it restarts the openvpn and creates the new ipfw set then internet runs in the jail.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Can I get the openvpn restart removed as it is affecting the script and blocks the internet connection with the Kill switch script which does the restarting. Can I just delete the bottom lines of the script up until where. I think then I should not have a problem.


Sent from my iPhone using Tapatalk
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
I have tested the normal script and it port forwards fine but you script is the one I would like as it will check if the port is opened if not then it will open it and then exit. Which Is what I require. As if I use the normal script on a run every 10 min then the port keeps changing.


Sent from my iPhone using Tapatalk
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Reason is I have a cron that runs the kill switch every 5 min where it checks internet connectivity when there is none it restarts the openvpn services gets the connectivity then rewrites the ipfw_rules with the IP address of the openvpn.


Sent from my iPhone using Tapatalk
 

teema

Cadet
Joined
Mar 30, 2016
Messages
9
The script will not work for me. I get the following error:
Code:
oot@transmission_1:/usr/local/etc/pia_openvpn # sh portforward2.sh
Connection to google.com 80 port [tcp/http] succeeded!
VPN connection up.
portforward2.sh: [[: not found
portforward2.sh: [[: not found
Error: transmission said: Port is open: Yes


I copied and pasted the script into the portforward2.sh file and edited the tun adapter to be tun1 as well as inserted my credentials for PIA.

Not sure what is going down. Seems that the error is coming from the section of code that checks to see if the port is forwarded.

Cheers,

It's a bash script so running it with "sh" isn't going to work.

The first line makes an assumption where your "bash" binary is. It may also be at /usr/bin/bash. Or it may be you don't have it installed at all.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
I know it is a bash script but you can run the latest script via ./ or sh as in the script it has the location of the bash.


Sent from my iPhone using Tapatalk
 

Scharbag

Guru
Joined
Feb 1, 2012
Messages
620
I know it is a bash script but you can run the latest script via ./ or sh as in the script it has the location of the bash.


Sent from my iPhone using Tapatalk
Unfortunately, you need bash so it can understand the syntax of the if statements. sh and csh do not work for that script. Also, I found that I was getting the same errors in the script I downloaded from the GIT link earlier in this thread. I had to make some minor syntax changes for the if statements to evaluate properly ([[ changed to [, some use of quotes etc. which may have inadvertently made bash a non-requirement).

I know that the bash call is correct and that I have bash installed.

Code:
root@transmission_1:/ # where bash
/usr/local/bin/bash
/usr/local/bin/bash
root@transmission_1:/ #


This is the script that I run (I think this code will also run in sh shell too (not in csh though)):

Code:
#! /usr/local/bin/bash
#
# Enable port forwarding for transmission specifically in FreeBSD.
#
# Requirements:
#   this can be executed from cron or from the shell with no arguments.
#   ensure that your PIA credentials are entered in this script.
#   Sudo is required to properly test IPFW rules as the user that runs the transmission plugin.
#
# Packages needed:
#   pkg install -y sudo nano wget openvpn bash
#
# Usage:
#  ./port_forward.sh or sh port_forward.sh or call from cron

PIA_USER='USER'
PIA_PASS='PASS'

# Export path for when you use this in cron
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin"

# echo date/time for logging
echo "Transmission Port Forward $(date +%Y-%m-%d-%H:%M:%S)"

# test to see if the port is already forwarded and if so, exit script
is_port_forwarded( )
{
# -pt tests for open port.
	json=$(transmission-remote -pt)
	if [ "$json" == "Port is open: No" ]; then
		echo "Closed port detected"
			get_new_port
	elif [ "$json" == "Port is open: Yes" ]; then
		echo "Open port detected"
		exit 1
	else
		echo "Error: transmission said: $json"
		exit 0
	fi
}

# if port is not forwarded, get a new port for transmission
get_new_port( )
{
	echo 'Loading port forward assignment information..'
	# dynamically figure out the tunnel adapter name
	tunnel_adapter=`ifconfig | grep "tun" | cut -d ":" -f1`
	local_ip=`ifconfig $tunnel_adapter | grep "inet " | cut -d\  -f2|tee /tmp/vpn_ip`
	client_id=`head -n 100 /dev/urandom | md5 -r | tr -d " -"`
	json=`wget --no-check-certificate -q --post-data="user=$PIA_USER&pass=$PIA_PASS&client_id=$client_id&local_ip=$local_ip" -O - 'https://www.privateinternetaccess.com/vpninfo/port_forward_assignment' | head -1`
	PORTNUM=`echo $json | grep -oE "[0-9]+"`
	# test to make sure that the port is actually a number
	if echo "$PORTNUM" | grep -qE ^\-?[0-9]+$; then
		   # it IS numeric
		echo "New port: $PORTNUM"
		transmission-remote -p $PORTNUM
	else
		# it is NOT numeric.
		echo "Garbled data: $PORTNUM"
		exit 0
	fi
}

re_check_connectivity( )
{
		if sudo -u transmission nc -zw 1 google.com 80; then
				echo "VPN connection restored."
			sleep 10 #this delay seems to be needed for the script to work properly
		echo "Attempting to map port:"
		sleep 10
		is_port_forwarded
	else
				echo "Unable to restore VPN connection. Subscription expired? Exiting."
				exit 0
		fi
}

check_for_connectivity( )
{
	if sudo -u transmission nc -zw 1 google.com 80; then
				echo "VPN connection up."
		is_port_forwarded
		else
				echo "VPN connection down. Restarting..."
				service openvpn restart
		sleep 10 # wait for OpenVPN to start prior to checking for connectivity
				re_check_connectivity
		fi
}

# First check for connectivity using the user that executes Transmission.  If this fails, script will try to relaunch openvpn service and re-check (pause to allow OpenVPN to start)
# If re-check fails, script will exit without any other execution.
#
# Second this will check for port forward status.  If the port forward is enabled, script will exit.  If the port is not properly forwarded, the script will
# call for a new port assignment and if it is valid, will tell transmission to use the new port.

check_for_connectivity

exit 0


Cheers,
 
Last edited:

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Thanx for that.

With you script can I get it not to restart the openvpn what would I need to delete. The script was working for me all night then this morning it started getting the bad fd number and the script stops working so you know why this is happening. Also I used your ubl.sh it works but get commend not found which I don't know why?

Thanks


Sent from my iPhone using Tapatalk
 

Scharbag

Guru
Joined
Feb 1, 2012
Messages
620
Thanx for that.

With you script can I get it not to restart the openvpn what would I need to delete. The script was working for me all night then this morning it started getting the bad fd number and the script stops working so you know why this is happening. Also I used your ubl.sh it works but get commend not found which I don't know why?

Thanks


Sent from my iPhone using Tapatalk
Need a lot more info in order to help.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Your script was working and was checking the logs. This morning when I went to checking how it was going it started to get bad fd number. If I tried ./port_forward.sh it would.m not run. Says can't find command but worked last night. Would you know what happened as nothing changed.


Sent from my iPhone using Tapatalk
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Here is the script i am using which was woking fine then it stops and say command not found not even where bash is working. This is with freenas 9.10

Code:
#! /usr/local/bin/bash
# Cronable port forwarding script for PIA/transmission running on
# FreeNAS
#
# Requires bash, jq (JSON parser) and curl
# pkg install -y jq bash curl
# Assumes tunnel is tun0 if different change below
#

# Your PrivateInternetAccess credentials
PIA_USER=username
PIA_PASS=password

# Export path for when you use this in cron
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin"

# echo date/time for logging
echo "Transmission Port Forward $(date +%Y-%m-%d-%H:%M:%S)"

get_new_port( ) {
  if ! [ -x $(curl)  ]; then
  echo "Curl not installed/not executable"
  exit 0
  fi
   
  # get the local tunnel ip
  local_ip=$(ifconfig tun0 | grep "inet " | cut -d\  -f2)
   
  #client_id seems to want random data
  client_id=$(head -n 100 /dev/urandom | md5 -r | tr -d " -")
   
  port=$(curl --silent --data "user=$PIA_USER&pass=$PIA_PASS&client_id=$client_id&local_ip=$local_ip" https://www.privateinternetaccess.com/vpninfo/port_forward_assignment | jq .port)
   
  if ! [[ $port =~ ^[0-9]+$ ]]; then
  echo "Garbled data: $port"
  exit 0
  fi
   
  transmission-remote -p $port
}

is_port_forwarded( ) {
  # -pt tests for open port.
  json=$(transmission-remote -pt)
   
  if [[ $json == "Port is open: No" ]]; then
  echo "Closed port detected"
  get_new_port
  elif [[ $json == "Port is open: Yes" ]]; then
  echo "Open port detected"
  exit 1

  fi
}

check_for_connectivity( ) {
  if nc -zw 1 google.com 80; then
  echo "VPN connection up."
  else
  echo "VPN connection down. Exiting."
	 exit 0

  fi
}

check_for_connectivity
is_port_forwarded

exit 1

I ahve the above script running as cron @ 5min intervals.

this is the error i am getting now all of a sudden. then it starts to work then it stops anyone know why this is happening.

Code:
/sabnzbd/scripts/port_forward.sh: line 9: $'\r': command not found
/sabnzbd/scripts/port_forward.sh: line 13: $'\r': command not found
/sabnzbd/scripts/port_forward.sh: line 16: $'\r': command not found
Transmission Port Forward 2016-12-20-21:20:00
/sabnzbd/scripts/port_forward.sh: line 19: $'\r': command not found
/sabnzbd/scripts/port_forward.sh: line 20: syntax error near unexpected token `$'{\r''
/sabnzbd/scripts/port_forward.sh: line 20: `get_new_port( ) {


Does it have anything to do with the py script i run with cron gui freenas. the script is below. This is the Kill switch, al;so running in 5 min intervals.

Code:
#!/usr/local/bin/python2.7
import sys
import socket
import subprocess
url = 'Netherlands.privateinternetaccess.com'
try:
  # Raise if it can't ping the server or openvpn isn't running
  subprocess.check_output(['service', 'openvpn', 'status'])
  subprocess.check_output(['ping', '-c', '1', url])
except subprocess.CalledProcessError:
  pass
else:
  sys.exit()
hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex(url)
content = '''
add 01006 allow ip from 192.168.2.0/24 to 192.168.2.0/24 keep-state
'''
rule_number = 2001
for ip in ipaddrlist:
  content += '''
add {} allow ip from 192.168.2.0/24 to {} keep-state
add {} allow ip from {} to 192.168.2.0/24 keep-state
'''.format(rule_number, ip, rule_number + 1, ip)
  rule_number += 2
content += '''
add 04000 allow ip from 127.0.0.1 to any
add 05000 allow ip from 10.0.0.0/8 to any
add 05002 allow ip from any to 10.0.0.0/8
add 65534 deny ip from any to any
'''
# Stop ipfw
subprocess.call(['service', 'openvpn', 'stop'])
subprocess.call(['service', 'ipfw', 'stop'])
f = open('/sabnzbd/scripts/ipfw_rules', 'w')
f.write(content)
f.close()
# Start ipfw
subprocess.call(['service', 'ipfw', 'start'])
# Check if running
if 'ipfw' in subprocess.check_output(['service', '-e']):
  subprocess.call(['service', 'openvpn', 'start'])
sys.exit()



Any help on why the commands cant be found all of sudden even after reboot still not working.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
Need a lot more info in order to help.

Hi Scharbag,

The script im using now is this one

Code:
#!/usr/local/bin/bash
# Cronable port forwarding script for PIA/transmission running on
# FreeNAS
#
# Requires bash, jq (JSON parser) and curl
# pkg install -y jq bash curl
# Assumes tunnel is tun0 if different change below
#

# Your PrivateInternetAccess credentials
PIA_USER=username
PIA_PASS=password

# Export path for when you use this in cron
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/root/bin"

# echo date/time for logging
echo "Transmission Port Forward $(date +%Y-%m-%d-%H:%M:%S)"

get_new_port( ) {
  if ! [ -x $(curl)  ]; then
  echo "Curl not installed/not executable"
  exit 0
  fi
   
  # get the local tunnel ip
  local_ip=$(ifconfig tun0 | grep "inet " | cut -d\  -f2)
   
  #client_id seems to want random data
  client_id=$(head -n 100 /dev/urandom | md5 -r | tr -d " -")
   
  port=$(curl --silent --data "user=$PIA_USER&pass=$PIA_PASS&client_id=$client_id&local_ip=$local_ip" https://www.privateinternetaccess.com/vpninfo/port_forward_assignment | jq .port)
   
  if ! [[ $port =~ ^[0-9]+$ ]]; then
  echo "Garbled data: $port"
  exit 0
  fi
   
  transmission-remote -p $port
}

is_port_forwarded( ) {
  # -pt tests for open port.
  json=$(transmission-remote -pt)
   
  if [[ $json == "Port is open: No" ]]; then
  echo "Closed port detected"
  get_new_port
  elif [[ $json == "Port is open: Yes" ]]; then
  echo "Open port detected"
  exit 1

  fi
}

check_for_connectivity( ) {
  if nc -zw 1 google.com 80; then
  echo "VPN connection up."
  else
  echo "VPN connection down. Exiting."
	exit 0

  fi
}

check_for_connectivity
is_port_forwarded

exit 1


and when the port is closed i get this MSG just wanted to know is this normal. The part "curl: try 'curl --help' or 'curl --manual' for more information" is this an error?

Transmission Port Forward 2016-12-22-16:05:00
Connection to google.com 80 port [tcp/http] succeeded!
VPN connection up.
Closed port detected
curl: try 'curl --help' or 'curl --manual' for more information
localhost:9091/transmission/rpc/ responded: "success"
Transmission Port Forward 2016-12-22-16:10:00
Connection to google.com 80 port [tcp/http] succeeded!

Once i get around this i am going to try an add the code to get the tun adapter dynamically from your script.
 

denist

Contributor
Joined
Jan 28, 2013
Messages
188
I also run it from cron like this.

Code:
*/5 * * * * /usr/local/bin/bash /sabnzbd/scripts/port_forward.sh >> /var/log/pia.log 2>&1
 

Builder

Cadet
Joined
Jan 28, 2017
Messages
2
Hi all.
I'm hoping you might be able to help me..
I am getting the following when i run your script.

root@transmission_1:/ # ./usr/local/etc/openvpn/portforward.sh
Transmission Port Forward 2017-02-08-22:17:01
Connection to google.com 80 port [tcp/http] succeeded!
VPN connection up.
Closed port detected
Loading port forward assignment information..
Garbled data:

It's taken me quite some time to get to this point :) so i'm hoping its something silly i have missed.

All the Best
Adam
 
Status
Not open for further replies.
Top