Thursday, April 9, 2015

Building OpenVPN on Solaris 11.2 for use with PIA VPN

I recently had a desire to get OpenVPN working on Solaris 11.2, to allow me to connect to a Private Internet Access (PIA) VPN. For more information on using a VPN for general internet access, as well as some insight into why you might want to look into it for yourself, see:

A quick Google turned up a blog post from Stefan Reuter detailing how to set up OpenVPN on OpenSolaris 2008.11.

For Solaris 11.2 the basic steps are still pretty much the same, but some of the minor details have changed. We still need the TAP driver for solaris, and we obviously need to download and build OpenVPN, but we don't need to edit the TUN/TAP Makefile anymore, and we don't need any patches for OpenVPN. One step I added was to download and compile the LZO compression library for OpenVPN.

Step 1: Install the TAP driver.

# git clone https://github.com/kaizawa/tuntap.git
# ./configure 
# gmake
# sudo gmake install
  • The full output of running those commands, if you are in any way possibly curious.

Step 2: Install the LZO compression library.

# wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.09.tar.gz
# tar -zxvf lzo-2.09.tar.gz
# cd lzo-2.09
# ./configure 
# gmake
# gmake check
# sudo gmake install
  • More full output of running those commands, if you are in any way possibly curious.

Step 3: Install OpenVPN.

For OpenVPN, we modify CFLAGS and LDFLAGS, to let OpenVPN find the LZO library we just installed, and we add '--enable-password-save', which will allow us to store the username and password for the VPN in a file.
# wget https://swupdate.openvpn.org/community/releases/openvpn-2.3.6.tar.gz
# tar -zxvf openvpn-2.3.6.tar.gz
# cd openvpn-2.3.6
# CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" ./configure --with-gnu-ld --enable-password-save
# gmake
# sudo gmake install
  • Yet again, even more full output of running those commands, if you are in any way possibly curious.

Once OpenVPN is installed, configuring it for use with Solaris is relatively straight forward. PrivateInternetAccess have a bunch of OpenVPN configuration files, with some very useful defaults. Since I'm on the East coast of the US, I started with the "US East.ovpn" file:
client
dev tun
proto udp
remote us-east.privateinternetaccess.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
tls-client
remote-cert-tls server
auth-user-pass
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.pem
To which I added a few options of my own:
auth-user-pass .pia.login
script-security 2
route-delay 2
route-up route-up.sh
route-noexec
The auth-user-pass .pia.login line tells the OpenVPN client to read your username and from a file in the current directory called '.pia.login' (Make sure your path is correct if you have issues). The contents of that file are your username by itself on line 1, and your password by itself on line 2.
supertim
MySup3rS3cr3tP@ssw0rd
The rest of the lines all affect how routing is done for the VPN. Left to it's own devices, OpenVPN doesn't have the code necessary to automatically manage routes. For example, it can't automatically determine the default gateway, and modify that route to update the default gateway to the VPN's default gateway.
Wed Apr  8 00:54:10 2015 NOTE: unable to redirect default gateway -- Cannot read current default gateway from system
The solution for that is to use a route-up script to handle the routing. In order for OpenVPN to use the script, you need to set script-security 2, or you see show-stopping warnings such as:
Wed Apr  8 01:09:00 2015 WARNING: External program may not be called unless '--script-security 2' or higher is enabled. See --help text or man page for detailed info.
Wed Apr  8 01:09:00 2015 WARNING: Failed running command (--route-up): external program fork failed
With script-security set to a reasonable level to allow OpenVPN client to run scripts, we use route-delay 2 to tell the client to give the client 2 full seconds to get the VPN tunnel set up before doing anything with routing, and route-noexec tells the client not to make any direct changes to the routing tables, and the route-up route-up.sh tells the client to run a script, which I very imaginatively called route-up.sh, during the route-up phase of client activity. The contents of the script look like:
#!/usr/bin/env ksh

# OpenVPN passes the remote gateway in as $route_vpn_gateway.
/usr/sbin/route add 0.0.0.0/1 $route_vpn_gateway
/usr/sbin/route add 128.0.0.0/1 $route_vpn_gateway
Since more specific routes are always preferred over less specific routes, setting these two routes allows us to route everything over the VPN without having to make any changes to the default route, thereby bypassing OpenVPN's lack of ability to manage Solaris routes. If the VPN goes down, the routes are removed, and you still have access to the internet via your existing default route. You also maintain access to your local LAN because that route will be even more specific, and it's directly connected. You will just not have the same amount of privacy at that point.

Monday, April 6, 2015

pyTivo on Solaris 11.2

We are a TiVo household, so a quest has been underway to build a suitable place for long term storage of the family's favorite TV shows and movies. One indisputable requirement is that the shows and movies have to be visible via the TiVo menu. pyTivo (the William McBrine fork) is the logical tool to do this (in my house). William McBrine has been maintaining his fork of pyTivo more regularly than the original package (sourceforge).

To get pyTivo working on Solaris 11.2, only 2 dependencies needed to be resolved.
  • I needed to build ffmpeg to support on-the-fly video transcoding. and,
  • ffmpeg wanted yasm(an open source rewrite of the nasm assembler) or nasm itself.
This is what happened when I tried to build ffmpeg without yasm:
bash-[121]$ ./configure --prefix=/usr/local
yasm/nasm not found or too old. Use --disable-yasm for a crippled build.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help
solve the problem.


Both were very simple and straight forward to build and install:

  • Yasm
  • [tim@tank]-[117]$ ./configure --prefix=/usr/local
    <snip>
    [tim@tank]-[118]$ gmake -j4
    <snip>
    [tim@tank]-[119]$ sudo gmake install
    <snip>
    
  • ffmpeg
  • [tim@tank]-[127]$ ./configure --prefix=/usr/local
    <snip>
    [tim@tank]-[128]$ gmake -j4
    <snip>
    [tim@tank]-[129]$ sudo gmake install
    <snip>
    

Once ffmpeg was installed, I updated the pyTivo.conf file and set the location of the ffmpeg binary, and pyTivo worked beautifully after that.

[tim@tank]-[136]$ vim TIVO/pyTivo/pyTivo.conf
<snip>
# FFmpeg is a required tool but downloaded separately.  See pyTivo wiki 
# for help.
# Full path to ffmpeg including filename
# For windows: ffmpeg=C:\pyTivo\bin\ffmpeg.exe
# For linux:   ffmpeg=/usr/bin/ffmpeg
#ffmpeg=C:\pyTivo\bin\ffmpeg.exe
ffmpeg=/usr/local/bin/ffmpeg

<snip>

For more information on pyTivo, including installation, configuration, and other tasks outside the purpose of this post: