User Tools

Site Tools


unix:networking:openwrt_routing

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
unix:networking:openwrt_routing [2014/04/30 04:17]
ben created
unix:networking:openwrt_routing [2015/11/17 07:10] (current)
ben [Transmission Update Script]
Line 1: Line 1:
 ====== "​Split"​ VPN routing with OpenWRT/​Tomato ====== ====== "​Split"​ VPN routing with OpenWRT/​Tomato ======
 +
 +This is an explanation of how I route traffic for specific LAN IP addresses (my NAS) through an OpenVPN connection on a router running OpenWRT/​Tomato firmware. ​ I'm also running "​tinyproxy"​ on the NAS so other clients can use the VPN connection on the router as necessary.
 +
 +I've never used awk before and didn't devote a lot of time to these scripts, so save your judgement please.
 +
 +===== Pre-requisite:​ Optware =====
 +
 +Get optware installed and mounting automatically on boot.
 +
 +Set your USB support with the option ''​Automatically mount all partitions to sub-directories in /​mnt.''​
 +
 +Set the USB ''​Run after mounting''​ script:
 +<​code>​
 +if [ -d /​mnt/​optware ]; then
 +  mount -o bind /​mnt/​optware /opt
 +fi
 +</​code>​
 +
 +Contents of Administration->​Scripts->​Init:​ //(I don't use this anymore but figured I'd leave it documented)//​
 +<​code>​
 +#Mount optware
 +echo "​LABEL=optware /opt ext3 defaults 1 1" >> /etc/fstab
 +/bin/mount /opt /opt
 +</​code>​
 +
 +These are the packages I have installed:
 +<​code>​
 +ipkg-opt - 0.99.163-10 - The Itsy Package Manager
 +libcurl - 7.24.0-1 - Curl is a command line tool for transferring files with URL syntax, supporting FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FI
 +libidn - 1.25-1 - GNU Libidn is an implementation of the Stringprep, Punycode and IDNA specifications defined by the IETF Internationalized Domai
 +netcat - 1.10pl32-5 - TCP/IP swiss army knife.
 +openssl - 0.9.7m-6 - Openssl provides the ssl implementation in libraries libcrypto and libssl, and is needed by many other applications and librari
 +uclibc-opt - 0.9.28-13 - micro C library for embedded Linux systems
 +wget-ssl - 1.12-2 - A network utility to retrieve files from the Web
 +zlib - 1.2.5-1 - zlib is a library implementing the '​deflate'​ compression system.
 +</​code>​
 +===== OpenVPN settings =====
 +  * Ensure the option "​Create NAT on tunnel"​ is checked
 +  * Advanced settings:
 +<​code>​
 +persist-key
 +persist-tun
 +tls-client
 +auth-user-pass /​opt/​etc/​pia/​pia.txt
 +comp-lzo
 +verb 1
 +reneg-sec 0
 +route-noexec
 +route-up /​opt/​etc/​scripts/​vpnrouteup.sh ​
 +down /​opt/​etc/​scripts/​vpnroutedown.sh
 +</​code>​
 +
 +Two files are necessary:
 +
 +Contents of pia.txt is VPN username on first line, password on second line.
 +
 +Contents of pia_client_id is a random string: ''​head -n 100 /​dev/​urandom | md5 > pia_client_id''​
 +===== VPN Scripts =====
 +
 +The vpnrouteup.sh script sets a second routing table with ip route to direct traffic for ip's listed in "​vpndhosts"​ (space delimited) through the VPN connection. ​ It then calls a script to get a forwarding port from my VPN provider, which then calls a script to update the transmission client config that's running on the NAS.  ​
 +
 +I don't remember why I needed to use my ISP's DNS servers over the VPN's DNS servers, but there must be a good reason. ​ Maybe it was because I couldn'​t figure out how to dynamically update the /​etc/​resolv.conf file on my NAS.  If you don't need to use your ISPs DNS, comment out the third for loop.
 +
 +Contents of vpnrouteup.sh:​
 +<​code>​
 +#​!/​bin/​sh ​
 +privateinternetaccess=$(nslookup www.privateinternetaccess.com |grep ^A |tail -1 |awk -F ' ' '{ print $3 }')
 +vpndhosts="​192.168.xxx.xxx"​
 +dnsservers="​89.xxx.xxx.xxx 89.xxx.xxx.xxx"​
 +tun_iface=$(ifconfig|grep tun|awk '{ print $1 }')
 +tun_inet=$(ifconfig $tun_iface|grep P-t-P|awk -F ':'​ '{ print $2 }'|awk -F ' ' '{ print $1 }')
 +tun_ptp=$(ifconfig $tun_iface|grep P-t-P|awk -F ':'​ '{ print $3 }'|awk -F ' ' '{ print $1 }')
 +tun_gw=$(echo $tun_inet |awk -F '​.'​ '​{print $1"​."​$2"​."​$3"​.1"​}'​)
 +tun_net=$(echo $tun_inet |awk -F '​.'​ '​{print $1"​."​$2"​."​$3"​.0/​24"​}'​)
 +ip route add 0.0.0.0/1 via $tun_ptp dev $tun_iface table 10
 +ip route add 128.0.0.0/1 via $tun_ptp dev $tun_iface table 10
 +ip route add $tun_gw via $tun_ptp dev $tun_iface metric 1 table 10
 +ip rule add from $tun_net table 10
 +ip rule add to $tun_net table 10
 +for host in $privateinternetaccess;​do ip rule add from $host table 10;ip rule add to $host table 10;done
 +for host in $vpndhosts;​do ip rule add from $host table 10;done
 +for host in $vpndhosts;​do for server in $dnsservers;​do ip rule add from $host to $server lookup main;ip rule add from $server to $host lookup main;​done;​done
 +
 +/​opt/​etc/​scripts/​port_forward_update.sh &
 +
 +</​code>​
 +
 +Contents of vpnroutedown.sh:​
 +<​code>​
 +#!/bin/sh
 +for rule in $(ip rule list |grep -v "all lookup"​|awk -F ":"​ '{ print $1 }');do ip rule delete pref $rule;done
 +</​code>​
 +
 +===== Port-forward Script =====
 +
 +This is specific to Private Internet Access'​s method for getting a port forwarding port via an HTTPS request. ​ It uses iptables PREROUTING with the NAT table to forward the port to the internal LAN address. ​ Once the port is retrieved, if there'​s no forwarding enabled currently, it gets enabled. ​ If it's different from what is currently forwarded, it replaces what's currently in place. ​ Once the ports are setup it calls the script to update the transmission config.
 +
 +Contents of port_forward_update.sh:​
 +<​code>​
 +#!/bin/sh
 +
 +#to-do: get current nat preroute rule and compare port, if it's the same do nothing, if it's different, delete the old and add the new
 +
 +insidehost=192.168.xxx.xxx
 +
 +pia_user=$(head -1 /​opt/​etc/​pia/​pia.txt)
 +pia_pw=$(tail -1 /​opt/​etc/​pia/​pia.txt)
 +pia_client_id=$(head -1 /​opt/​etc/​pia/​pia_client_id)
 +tun_iface=$(ifconfig | grep tun | awk '{ print $1 }')
 +echo $tun_iface
 +tun_inet=$(ifconfig $tun_iface|grep P-t-P|awk -F ':'​ '{ print $2 }'|awk -F ' ' '{ print $1 }')
 +echo $tun_inet
 +
 +#get our forwarding port from PIA
 +forwarded_port=$(/​opt/​bin/​wget --post-data="​user=$pia_user&​pass=$pia_pw&​client_id=$pia_client_id&​local_ip=$tun_inet"​ \
 + --no-check-certificate \
 + -q -O - https://​www.privateinternetaccess.com/​vpninfo/​port_forward_assignment \
 + | awk -F ':'​ '{ print $2 }'| awk -F '​}'​ '{ print $1 }')
 +
 +echo $forwarded_port
 +
 +current_port=$(iptables -t nat -L PREROUTING -vn |grep tun11 |awk -F ':'​ '{ print $2 }'|awk -F ' ' '{ print $1 }'​|tail -1)
 +current_rule=$(iptables -t nat -L PREROUTING -vn --line-numbers|grep tun11 |cut -b1-2)
 +
 +if [ -z "​$current_port"​ ] && [ -z "​$current_rule"​ ]
 +#we have no existing port forward and no existing current rule in place
 +then
 +echo inside 1
 +iptables -t nat -I PREROUTING -p tcp -i tun11 --dport $forwarded_port -j DNAT --to $insidehost:​$forwarded_port
 +else
 +if [ "​$current_port"​ -ne "​$forwarded_port"​ ]
 +#current port forward and port returned by website do not match
 +then 
 +echo inside 2
 +
 +#delet the current rule and set forwarding to our NAS host
 +iptables -t nat -D PREROUTING $current_rule
 +iptables -t nat -I PREROUTING -p tcp -i tun11 --dport $forwarded_port -j DNAT --to $insidehost:​$forwarded_port
 +/​opt/​etc/​scripts/​transmission_port_update.sh $current_port $forwarded_port
 +else echo current and requested ports match
 +fi
 +fi
 +
 +</​code>​
 +
 +===== Transmission Update Script =====
 +
 +Transmission supports updating client configuration settings on the fly via a ''​kill -HUP''​. ​ Open file handles remain open, so if you're like me and you have a download directory that is used only temporarily while something other than transmission moves your files around, no problem.
 +
 +In order to ssh to your NAS from OpenWRT, you need a set of ssh keys.  On OpenWRT that command is ''​dropbearkey -t rsa -f ~/​.ssh/​id_rsa''​. ​ Copy the .pub key file to your nas and append that key to your authorized_keys file.  As always, make sure your .ssh dir is set to 700 and authorized_keys set to 600.
 +
 +Contents of transmission_port_update.sh:​
 +<​code>​
 +#!/bin/sh
 +echo $1 to $2
 +transmissionhost=192.168.33.200 ​                                                                                                   ​
 +settingspath=/​usr/​local/​transmission/​var
 +settingsfile=$settingspath/​settings.json
 +
 +ssh -i /​opt/​etc/​pia/​id_rsa root@$transmissionhost cp $settingsfile $settingsfile.bak ​                        
 +#ssh -i /​opt/​etc/​pia/​id_rsa root@$transmissionhost ls -l $settingsfile $settingsfile.bak
 +ssh -i /​opt/​etc/​pia/​id_rsa root@$transmissionhost 'cat '"'​$settingsfile.bak'"'​ | sed -e s#\ \ \ \"​peer-port\"​\:​\ [0-9][0-9][0-9][0-9][0-9],#​\ \ \ \"​peer-port\"​\:​\ '"'​$2'"',#​g > '"'​$settingsfile'"''​
 +ssh -i /​opt/​etc/​pia/​id_rsa root@$transmissionhost grep peer-port $settingsfile $settingsfile.bak
 +ssh -i /​opt/​etc/​pia/​id_rsa root@$transmissionhost killall -HUP transmission-daemon
 +</​code>​
 +
 +===== Scheduled port forward update =====
 +
 +My VPN provider requires that you routinely refresh the request for a forwarded port.  That is scheduled in OpenWRT via Administration->​Scheduler. ​ Execute ''/​opt/​etc/​scripts/​port_forward_update.sh''​ every 30 minutes to keep the port enabled.
 +
 +===== Appendix =====
  
 [[unix:​networking:​openwrt_routing:​notes|Original on-the-fly Notes]] [[unix:​networking:​openwrt_routing:​notes|Original on-the-fly Notes]]
  
unix/networking/openwrt_routing.1398845826.txt.gz ยท Last modified: 2014/04/30 04:17 by ben