Routed OpenVPN HOWTO

This is my OpenVPN HOWTO. There are many like it, but this one is mine.

It seems every few months I get asked the question by one of my friends “How do I set up a VPN?”. Sometimes the person is looking to set up a MS VPN variant, other times, OpenVPN. The principles and concepts seem simple to me, now, however for someone new to VPN architectures and perhaps even routing, it can be confusing. This is my attempt to make the mysterious understandable. Since roadwarrior (individual laptop clients) configs are fairly well documented by the official OpenVPN wiki, I’ll concentrate on a simple routed, LAN-to-LAN VPN networking concept, and cover roadwarrior config as an afterthought.

My weapon of choice distro-wise is CentOS, however these instructions could be applied to any other distro (ie, Ubuntu) with a basic understanding of your particular platform’s networking configuration methods. Really, OpenVPN can run on just about anything, including Windows, if you feel so inclined. However, you’ll probably get the most bang for your buck (free) using Linux. In my test environment, running stock CentOS 6.4, I had the scenario below running on a server with less than 90MB of total system memory usage.

Why CentOS?
I have two main reasons for promoting the use of CentOS:
1) CentOS is based upon RedHat Enterprise Linux (RHEL), which currently enjoys status as the most vendor-supported OS in enterprise environments. Translation? Knowledge of an RHEL derivitaves like CentOS is marketable skill to put on your resume. Yes, Ubuntu is gaining popularity in tech circles, but still doesn’t compare to RHEL for vendor support. There’s a reason both VMWare and Citrix use RHEL derivitaves as their baremetal OS.
2) CentOS has long-term-support (LTS). I’ve used Fedora for years, and I enjoy(ed) playing with some of the bleeding-edge features it offers. But the bleeding edge is on a double-edged sword. Fedora has a relatively aggressive release and support schedule. Install Fedora X, and expect that Fedora Z will replace it in about a year, leaving version X effectively without support. This gets to be a pain when you need to “yum update” your system just a year or so after you installed it. CentOS however has a support schedule that will ensure you likely have updates for far more years than the lifecycle of your hardware. For example CentOS 6, released in 2011, reaches EOL in late 2020. That’s almost 10 years of support, on a free platform!

First, let’s diagram the network we are going to design:

Remote Office 1 (10.101.0.x/24)
VPN Tunnel (
Main Office (10.100.0.x/24)
VPN Tunnel (
Remote Office 2 (10.102.0.x/24)

For this guide, we’re going to assume you want all remote offices to have routing enabled to each other (via the Main office).

Note that the IP addresses above are just for example. You could create your own IP addressing scheme with FAR better utilization of the the private address space. The subnets I have used (ie 10.200.x.x/16) are just for increased clarity.

Each OpenVPN server/endpoint can have one interface (assuming you are doing NAT/firewalling elsewhere on your network), OR you could have dual interfaces: One on the LAN, the other on the WAN/Internet connection. It’s up to you depending on where you want to do your firewalling. For the purposes of this guide, we’re putting the VPN server behind another firewall.

On your firewall
Forward UDP port 1194 for your external internet connection to the internal IP of your VPN servers/endpoints, ie:

Main Office
Remote Office 1
Remote Office 2

If for some reason UDP/1194 were blocked by your ISP, you could switch to something like TCP/80, but for the purposes of this guide, we’ll stick with the default UDP/1194.

On each server/endpoint
Install your base OS. I chose to just install CentOS 6.4 minimal installation with the default options. Once installed, get networking set up and run

yum update

and get everything up-to-date.

Install the EPEL Repo configs

yum install

Turn off the built-in firewall (remember, we’re using a 3rd party device for this). You could leave it on, but then you’d have to configure it to pass traffic to/from your VPN tunnel interface. I’ll leave that up to you to figure out should you choose to do so.

chkconfig iptables off ; service iptables stop

Install the OpenVPN packages and dependencies:

yum install openvpn

Server (Main Office)

Copy the the easy-rsa environment to /etc/openvpn/easy-rsa, do some config prep, and alter the vars file

cp -rp /usr/share/openvpn/easy-rsa/2.0 /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa/
cp -rp vars vars.orig
cp -rp openssl-1.0.0.cnf openssl.cnf
vi vars

Go down to “KEY_COUNTRY” and edit the Country, Province, etc, down to the OU, ie:

export KEY_CITY="Minneapolis"
export KEY_ORG="Muchtall"
export KEY_EMAIL=""
export KEY_NAME=MuchtallOpenVPNServer
export KEY_OU=Muchtall

Now generate your server’s certificate authority:

. ./vars

Accept the defaults for the prompts (we already set them)

Now build the server key


Similar to above, accept the default prompts. You will have to answer “y” to the questions “Sign the certificate? [y/n]:” and “1 out of 1 certificate requests certified, commit? [y/n]”

Now generate certs/keys for each remote site

./build-key remote-office-1
./build-key remote-office-2

Rinse, repeat on the prompts.

And generate the Diffie-Hellman parameters:


Great! Our certificates are all set up!

Next time you want to generate a new client key, just run

cd /etc/openvpn/easy-rsa/
. ./vars
./build-key remote-office-3

Now, let’s set up the configs. There’s a sample config at /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf, however we’re going to set one up using this template, just to keep things simple:

port 1194
proto udp
dev tun
ca easy-rsa/keys/ca.crt
cert easy-rsa/keys/
key easy-rsa/keys/
dh easy-rsa/keys/dh1024.pem
ifconfig-pool-persist ipp.txt
# Tell clients that we can handle routes for these networks
push "route"
push "route"
push "route"
client-config-dir ccd
# Tell OpenVPN that it routes for anything within these subnets
keepalive 10 120
status openvpn-status.log
verb 3

Now create the ccd directory

mkdir /etc/openvpn/ccd

And lets create the client-specific configs to route each individual subnet to the respective site:

# In /etc/openvpn/ccd/remote-office-1


# In /etc/openvpn/ccd/remote-office-2

Good? Good!

Normally, IP subnets for the tunnels are allocated as new tunnels connect to the server. Let’s pre-set the IPs for each tunnel. This part isn’t necessary, however I like to do this to assist with clarity in troubleshooting with traceroutes. In /etc/openvpn/ipp.txt:


And re-set the SELinux permissions on the ipp.txt file

restorecon -v './ipp.txt'

Now we’re ready to start the the OpenVPN service up:

service openvpn restart

Check the syslog to see if anything serious got spit out:

tail -100 /var/log/messages

You should see something similar to this:

May 7 14:54:53 mainoffice openvpn[13362]: OpenVPN 2.2.2 x86_64-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Aug 10 2012
May 7 14:54:53 mainoffice openvpn[13362]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
May 7 14:54:53 mainoffice openvpn[13362]: Diffie-Hellman initialized with 1024 bit key
May 7 14:54:53 mainoffice openvpn[13362]: TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
May 7 14:54:53 mainoffice openvpn[13362]: Socket Buffers: R=[229376->131072] S=[229376->131072]
May 7 14:54:53 mainoffice openvpn[13362]: ROUTE default_gateway=
May 7 14:54:53 mainoffice openvpn[13362]: TUN/TAP device tun0 opened
May 7 14:54:53 mainoffice openvpn[13362]: TUN/TAP TX queue length set to 100
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip link set dev tun0 up mtu 1500
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip addr add dev tun0 local peer
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add via
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add via
May 7 14:54:53 mainoffice openvpn[13362]: /sbin/ip route add via
May 7 14:54:53 mainoffice openvpn[13362]: Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
May 7 14:54:53 mainoffice openvpn[13369]: UDPv4 link local (bound): [undef]:1194
May 7 14:54:53 mainoffice openvpn[13369]: UDPv4 link remote: [undef]
May 7 14:54:53 mainoffice openvpn[13369]: MULTI: multi_init called, r=256 v=256
May 7 14:54:53 mainoffice openvpn[13369]: IFCONFIG POOL: base= size=16382
May 7 14:54:53 mainoffice openvpn[13369]: IFCONFIG POOL LIST
May 7 14:54:53 mainoffice openvpn[13369]: remote-office-1,
May 7 14:54:53 mainoffice openvpn[13369]: remote-office-2,
May 7 14:54:53 mainoffice openvpn[13369]: Initialization Sequence Completed
May 7 14:54:53 mainoffice kernel: tun0: Disabled Privacy Extensions

Once you’ve verified based upon the above output that everything is running fine, go ahead and mark the service to start automatically

chkconfig openvpn on

Client Configs (Remote Offices)
On each server, create the file “/etc/openvpn/”, and populate with the following:

dev tun
proto udp
remote 1194
resolv-retry infinite
ca ca.crt
cert remote-office-1.crt
key remote-office-1.key
verb 3

Be sure to change the cert name as appropriate.

Copy the ca.crt, remote-office-1.key, and remote-office-1.crt to the /etc/openvpn/ directory of the client. Repeat for Office 2.

Set the permissions on the key file so that it can’t be copied by non-root users.

chmod 600 /etc/openvpn/remote-office-1.key

Start the OpenVPN service

service openvpn start

Check the output of syslog for similar output:

May 7 16:26:39 remote-office-1 openvpn[1566]: OpenVPN 2.2.2 x86_64-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Aug 10 2012
May 7 16:26:39 remote-office-1 openvpn[1566]: WARNING: No server certificate verification method has been enabled. See for more info.
May 7 16:26:39 remote-office-1 openvpn[1566]: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
May 7 16:26:39 remote-office-1 openvpn[1566]: LZO compression initialized
May 7 16:26:39 remote-office-1 openvpn[1566]: Control Channel MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
May 7 16:26:39 remote-office-1 openvpn[1566]: Socket Buffers: R=[229376->131072] S=[229376->131072]
May 7 16:26:39 remote-office-1 openvpn[1566]: Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
May 7 16:26:39 remote-office-1 openvpn[1566]: Local Options hash (VER=V4): '41690919'
May 7 16:26:39 remote-office-1 openvpn[1566]: Expected Remote Options hash (VER=V4): '530fdded'
May 7 16:26:39 remote-office-1 openvpn[1567]: UDPv4 link local: [undef]
May 7 16:26:39 remote-office-1 openvpn[1567]: UDPv4 link remote: x.x.x.x:1194
May 7 16:26:39 remote-office-1 openvpn[1567]: TLS: Initial packet from x.x.x.x:1194, sid=f439995e ac9dd302
May 7 16:26:39 remote-office-1 openvpn[1567]: VERIFY OK: depth=1, /C=US/ST=MN/L=Minneapolis/O=Muchtall/OU=Muchtall/
May 7 16:26:39 remote-office-1 openvpn[1567]: VERIFY OK: depth=0, /C=US/ST=MN/L=Minneapolis/O=Muchtall/OU=Muchtall/
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
May 7 16:26:39 remote-office-1 openvpn[1567]: Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
May 7 16:26:39 remote-office-1 openvpn[1567]: Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 1024 bit RSA
May 7 16:26:39 remote-office-1 openvpn[1567]: [] Peer Connection Initiated with
May 7 16:26:41 remote-office-1 openvpn[1567]: SENT CONTROL []: 'PUSH_REQUEST' (status=1)
May 7 16:26:41 remote-office-1 openvpn[1567]: PUSH: Received control message: 'PUSH_REPLY,route,route,route,route,topology net30,ping 10,ping-restart 120,ifconfig'
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: timers and/or timeouts modified
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: --ifconfig/up options modified
May 7 16:26:41 remote-office-1 openvpn[1567]: OPTIONS IMPORT: route options modified
May 7 16:26:41 remote-office-1 openvpn[1567]: ROUTE default_gateway=
May 7 16:26:41 remote-office-1 openvpn[1567]: TUN/TAP device tun0 opened
May 7 16:26:41 remote-office-1 openvpn[1567]: TUN/TAP TX queue length set to 100
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip link set dev tun0 up mtu 1500
May 7 16:26:41 remote-office-1 kernel: tun0: Disabled Privacy Extensions
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip addr add dev tun0 local peer
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add via
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add via
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add via
May 7 16:26:41 remote-office-1 openvpn[1567]: /sbin/ip route add via
May 7 16:26:41 remote-office-1 openvpn[1567]: Initialization Sequence Completed

And verify that the routing is taking place


Set the openvpn service to start automatically

chkconfig openvpn on

Repeat these steps for the Office 2 client. And verify that you can ping across both tunnels to Office 1

Roadwarrior Config (this is optional)
As an afterthought, I said I’d cover Roadwarrior configuration. Here’s a basic rundown:

– Generate a new cert/key pair for your username using the above ./build-key commands
– Install OpenVPN for Windows (if you’re on Mac or Linux, you likely know how to do this already)
– Copy the ca.crt, username.crt, and username.key files to “C:\Program Files\OpenVPN\config\”
– Create a config file named C:\Program Files\OpenVPN\config\ with these contents:

dev tun
proto udp
remote 1194
resolv-retry infinite
ca ca.crt
cert myusername.crt
key myusername.key
verb 3

Right-click on the OpenVPN GUI in the taskbar and click “Connect”.

Muchtall Window Arranger (Save Window Positions and Size)

Over the years, I’ve noticed that there’s one “drawback” to multiple heads/screens on a laptop workstation. I get in the habit of arranging my workspace how I like it, where eventually I have 8-10 windows in positions I would prefer to be permanent whenever I hook up my external 2 heads. When I undock, of course everything collapses back to my main display. When I re-dock, the windows remain in a cluttered pile on my main screen. In addition to this, changes in resolution can result in windows needing to be re-sized as well.

I’ve found one or two utilities over the years that have allowed me to save window positions and sizes, but nothing that handled it for me as automatically as I would have liked. So I wrote my own in AutoHotKey: the Muchtall Window Arranger.

It’s fairly simple, yet powerful if you want it to be. Since it’s written in AutoHotKey, you can write custom filters to apply to your window rules (assuming you know AHK). But, for the casual user, it simply grabs the active window information and allows you to alter the conditions that apply to the window matching before saving those settings.

Downloadfrom GitHub: Muchtall Window Arranger
You must have AutoHotKey installed before using this script.

There’s one setting in the source you’ll probably want to modify before you get started. The variable “NumberOfScreens = 3” should be changed to the number of heads you want to have activate the auto-rearrange feature. If this is set to something higher than you’d ever have installed (say 10), the auto-rearrange feature should never activate. Since version 20200817, you no longer need to specify the number of screens. Instead, the script automatically detects the current screen layout, and generates separate profiles for them!

Task Tray Menu

Capture/Save window settings

I’ll probably clean up the rough edges as I get feedback on it. I know there may be some use for features like re-arranging for multiple head settings, so there’s work to be done.

Edit: Moved code to GitHub repo

Brewblog: Kickoff w/ Northern Brewer Nut Brown Ale

My wonderful wife got me a Northern Brewer Deluxe Brewing Starter Kit (Glass) a couple of Christmases ago, and I’ve been slowly expanding my “brewery” ever since. I’ve made maybe 6 batches of beer using the kit. One of which I royally messed up (NB Bavarian Hefeweizen) when I scorched the malt in my newly-keggle-fied boiling vessel (on high heat of course).

So far, here’s my inventory of equipment:

Northern Brewer Deluxe Starter Kit:
– 6 Gallon Primary Fermentor (Glass), Fermometer, Bung, Airlock, Blowoff Assembly
– 5 Gallon Secondary Fermentor (Glass), Fermometer, Bung, Airlock
– 6.5 Gallon Bottling Bucket, Bottling Spigot, Bottle Filler, Bottling Tubing
– Auto-Siphon, Siphon Tubing
– Beer Bottle Brush, Bottle Capper
– Carboy Brush

I also had a few pieces of equipment from my prior homebrewing adventures of years past:
– Another bottle-capper
– Another 5 gallon secondary glass fermentor
– Airlock (from a Mr. Beer kit)
– One of those common orange dual-vent carboy caps
– ~3 Gallon stainless steel kettle (w/glass lid that I interchange with the keggle below)

And a few new acquisitions and creations:
– 15 gallon boiling “keggle”, modified from an old stainless Miller keg (inherited)
– 10lb. CO2 canister w/ regulator
– 4 ball-lock corny kegs
– 1 set of ball lock inlet/outlet tubing, “foam-free” faucet, and connections (I can tap one keg at a time)
– 4 Perlick 545PC Flow Control Faucets (Xmas gift from Santa/Father-in-Law)
– ~7.x cu ft. Freezer (from grandmother-in-law)
– Johnson Controls A419 Temperature Controller (to convert freezer into kegerator)
– Bayou Classic SP10 High-Pressure Outdoor Gas Cooker
– ~20′ counter-flow chiller w/partial convolution (see:
– ~2′ stainless steel spoon
– 2 reusable hop bags
– Yet-to-be-finished ~56qt mash tun cooler (still have to cut slots in my manifold, otherwise done)

Anyhow, I expect to be posting updates on future brewing exploits, so to kick it off, here’s my 6th-ish brew: the Northern Brewer Nut Brown Ale (extract kit). This is video I took of the fermentation just a mere 24 hours after directly pitching dry yeast into the wort. Not bad I think, considering that Danstar recommends prepping the yeast before pitching it.


Brewed: 4/14
OG: 1.050
FG: 1.012
ABV: 4.9%
Kegged: 5/21

Quick Tip: Identifying Space Consumption in Linux via Command line

Firstly, let me strongly recommend JDiskReport if a GUI is available to you. It’s super easy to use and helps you quickly drill down into the disk and identify disk space usage, on any platform with Java support.

In lieu of that, if you have need to identify disk usage via the command line, run this set of commands:
find / -exec du -ks {} \; 2> /dev/null | sort -n | awk '{printf $1 "\t"; if (system("test -d \""$2"\"")) { print $2 } else { print $2 "/" } }' | tail -1000

This will spit out a list of the largest 1000 individual files and folder sums, sorted by size.

Depending on the size of the disk, this will take a while, as should be expected as it runs a “du” for each path it finds. Caching helps if/when you re-run this.

Excel Formula to Convert Polycom 8020/8440 Serial Number to MAC Address

This is an obscure tip, but it thought it was cool enough to post as it comes in handy when scanning in inventory with a barcode scanner. This works on Polycom 8400’s (8440/8450) and 8000’s (8020/8002)., and probably any other Polycom SIP device.

This formula will take the serial number in the column to the left and convert it to a MAC address.


Export/Import Grindstone XML to Google/iCal/ICS

I recently started using Grindstone to track my daily workload, and I’ve been using a number of calendars on Google to not only share classifications of appointments, but to track historical data (Android call logs, etc). I kind of expected that Grindstone would have iCal/ICS export capability, but sadly it does not appear so. You can, however, export to XML. So I thought I’d write up a Perl script to convert the XML data into an ICS file ready for import into Google Calendars. Feel free to download it and use to to convert your Grindstone XML files into iCal data.

Here’s the Perl script: grindstone2ics.txt (Save as .pl, not .txt)

If you are on Windows with ActivePerl installed, here’s a batch file that you can drag-and-drop your XML file onto. Place it in the same folder as “”: grindstone2ics.bat

Let me know if this helped you!

Simple Script to Mount Disk Image Partitions Looped on Linux

Every so often I have to recover a drive to a disk image on Linux, and before I transfer the data back to a physical drive, I like to mount the disk image check on it’s status. Mounting a partition from a disk image is slightly more complicated than mounting just an image of a partition, so I thought I’d post a shortcut to doing so. This information was derived from the how-to posted here ( You will need to alter three variables: DISKIMAGE, DISKPARTITION, and the mount path at the end of command.

DISKIMAGE=/media/usbdisk/mydiskimage.img ; DISKPARTITON=2 ; mount -o loop,offset=$((`fdisk -lu $DISKIMAGE 2> /dev/null | grep -P "$DISKPARTITON\s+\**\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]+" | sed 's/\*//g' | awk '{print $2}'` * `fdisk -lu $DISKIMAGE 2> /dev/null | grep "^Units" | awk -F"= " '{print $3}' | awk '{print $1}'`)) $DISKIMAGE /media/recovereddisk/

Hope this helps someone else save some time!

Whitelisting Incoming Calls on Asterisk

For some reason, this is a topic that I couldn’t seem to find a simple HOWTO online for, so I had to create my own.

I ran into a situation where I have a large number of auto-answering intercom boxes connected to an Asterisk system. The intercoms are programmed to pick up immediately upon ringing, allowing the caller to communicate with the room’s occupant without any action taken by the occupant. These intercom lines are assigned a DID number from the outside world in a large metro area. See the problem? The occupants were getting a number of calls from locals whom had dialed the wrong number. Sometimes the caller wouldn’t hear a response, so they’d call back repeatedly, to the irritation of the occupant. For our scenario, blacklisting wasn’t a good option. In metro areas, misdialed numbers are common, and rarely from the same person. I needed to only allow a handful (~20-50) of callers that we knew would be calling the intercoms legitimately. Furthermore, it would be useful to have a notice played for a blocked caller to that they knew either to not try calling again, or to contact us to whitelist the number.

Here are the rules I used in Asterisk to achieve this goal. First, in extensions.conf, I created a macro for whitelisting:

; Only allows calls from numbers in the whitelist DB
exten => s,1,GotoIf(${DB_EXISTS(whitelist/${CALLERID(num)})}?:blacklisted,s,1)
exten => s,2,Dial(${ARG1})

Then, if you don’t have a blacklisted context already, create one:

exten => s,1,Playback(not-taking-your-call)
exten => s,3,Hangup

Next, change your inbound call config to use the inbound-whitelist macro:

exten => 5551234567,1,Macro(inbound-whitelist,SIP/123)
exten => 5551234567,2,Hangup

Reload the asterisk config and make a test call. You should get a recording saying that it (Asterisk) is not taking your call.

Now add your number to the whitelist:

asterisk -r
database put whitelist 5551230000 1

And do another test call.

One last word of warning. I did once run into a condition where our telco provider abruptly stopped sending caller ID through our PRI. When this happens, ALL calls show up as null/blank calling numbers. In these instances, ALL calls to your whitelist-protected extensions will be blocked (at least from outside). To temporarily disable whitelisting until the problem is resolved, simply comment out the “exten => s,1,GotoIf …” line and reload asterisk.

Hopefully this saved someone else out there some time.

UPDATE: I found that comparing against two whitelists (a customer whitelist, and our support number whitelist) can be handy. Use this line instead if you want similar logic:

exten => s,1,GotoIf($[ ${DB_EXISTS(whitelist-${ARG2}/${CALLERID(num)})} | ${DB_EXISTS(whitelist-support/${CALLERID(num)})} ]?:blacklisted,s,1)

Also with this option, I can treat the whitelist name as an argument in my macro call:

exten => 5551234567,1,Macro(inbound-whitelist,SIP/123,customername)

In this case, the whitelist DB would be named “whitelist-customername”.

Installing Fedora 16 on XenServer 6

Credit for this procedure goes to Major Hayden at Racker Hacker ( My procedure just uses an alternate, minimal kickstart file that gives you more control over the installation using the Anaconda GUI.

– Start an installation using the RedHat 6.0 64bit template
– In the installation wizard, use these advanced options: console=hvc0 serial ip=dhcp nogpt vnc ks=/”content/f16onxen6.ks
– Connect to the installer GUI using VNC and the IP shown in the console.

Proceed as normal! If you care to see the source of the kickstart: /”content/f16onxen6.ks

Cisco ASDM-IDM Launcher: Stuck on “Contacting the device. Please wait…”

I recently ran into an issue on Windows 7 64-bit where ADSM-ISM Launcher failed to connect to my ASAs. Launching the application from a shortcut, and attempting to connect resulted in the launcher halting on “Contacting the device. Please wait…”. And waiting didn’t help. Opening the java console revealed another error which didn’t get me any useful results on Google:

Exception in thread “AWT-EventQueue-0” java.lang.ClassCastException: cannot be cast to

However, if I “re-installed” ASDM via the “dm-launcher.msi”, the first time it was spawned by the installer, everything worked fine. Subsequent launches from the application shortcuts failed. A quick check with Process Explorer revealed the issue. The dm-launcher installer launched the java app using “C:\Windows\SysWOW64\javaw.exe”, whereas the shortcut would use “C:\Windows\system32\javaw.exe”.

The ultimate fix ended up being updating all my ASDM shortcuts to use “C:\Windows\SysWOW64\javaw.exe”. Now everything is working great!

UPDATE 2/25/2013: So the pain continues with Java 7. If you have upgraded your JRE, you probably saw a recurrence of this issue. In that case, I recommend pointing your shortcut(s) directly to the version 1.6/6 JRE instead:
"C:\Program Files\Java\jre6\bin\javaw.exe"

Hope this helps someone else out there.

If you found this helpful, maybe you’d like to send a thank you from my wishlist?

Forcing RDP Connections Fullscreen on a Specific Monitor (Saving Window Position)

One of the frustrations I have/had with Remote Desktop connections on multi-monitor workstations (with unique display resolutions mind you) is that there’s no way within the RDP GUI to save the position of a fullscreen RDP session. So if your RDP session opens up on display 2 each time, good luck getting it to display properly on display 1 or 3 unless you have identical resolutions on each display. Even then, it’s a hassle to restore the RDP session to windowed mode and move the the preferred display each time you connect.

Hassle no more: There is a solution. All you need is notepad and a little understanding of how display coordinates work (don’t worry, I’ll explain).

First off, save your RDP session to an RDP shortcut (ie, Acme.rdp). Open notepad and drag the RDP file into the window. Notpad should open the source of the RDP file for your perusal. You’ll see some lines similar to this buried within the file:

screen mode id:i:2
use multimon:i:0

Set “screen mod id” and “use multimonitor” as shown above. The settings “desktopwidth”, “desktopheight”, and “winposstr” will vary depending upon the resolution and physical position of the display you iwsh to use as the destination.

First, an explanation of the winposstr variables we are concerned with (in order):
s: Not applicable
0: Not applicable
1: Sets the RDP session to start windowed (screen mode id sets it to be fullscreen after launch)
50: Pixel distance from the left-hand edge of display 1 to the left edge of the RDP window
170: Pixel distance from the upper edge of display 1 to the upper edge of the RDP window
250: Pixel distance from the left-hand edge of display 1 to the RIGHT edge of the RDP window. Difference between this and the left edge must be >= 200! (250 – 50 = 200)
370: Pixel distance from the upper edge of display 1 to the LOWER edge of the RDP window. Difference between this and the upper edge must be >= 200! (370 – 70 = 200)

Note again that the window dimensions MUST be greater than or equal to 200×200. If it is less, RDP will completely ignore your windows placement dimensions and go with defaults, defeating the purpose of this process.

Now that you know what the numbers mean, you need to understand where to place the window (by pixel dimension) in order to get it to come up on the proper display each time. You have two options: The complex/geeky way, or the simple way.

The Complex Way

Screen coordinates are all relative to the upper left edge of display 1. This position is 1,1. So if You have a single display system with a resolution of 800×600, the lower right corner of the screen is position 800,600. If you have two displays at 800×600 positioned like this in display properties:


…the lower right corner of display 2 would be 1600×600

If the displays were physically reversed:


..the lower LEFT corner of display 2 would be -800,600

Based upon this information, and using some simple math, you should be able to estimate window position amongst your displays. Now, this will get slightly more complex if your displays are offset on the Y axis, so what you might prefer is the…

Simple Way
Download and install the free AutoHotKey Basic. It comes with a nice utility called “AutoIt3 Window Spy”. Run this utility and fire up your RDP session in windowed mode. Then, move the RDP window into your desired destination display. Try to keep the Active Window Info screen visible when you do this.
You should see something similar to this in the Active Window Info window:

>>>>>>>>>>( Active Window Position )<<<<<<<<<<
left: 434 top: 700

Now, lets use those numbers to create the winposstr settings:


Note that I added 200 to the window position (634,900) creating a window size of 200×200.

Adjust the display width and height settings to match your destination screen.

Go ahead and save the RDP file and try connecting again. The RDP session should now open on the correct screen each time you use this shortcut.

Authenticating to MS SQL Server on a Different Domain Using Windows Authentication (Windows 7)

When trying to connect to an MSSQL server on another domain (of which you are not a member), you’ll probably run into the issue where selecting the Windows Authentication option in the SQL Server connection dialog grays out the username and password. Here are two workarounds:

SQL Server:
MYDOMAIN Username: joe.user

A) Create Saved Credentials
Go to the Control Panel –> User Accounts –> Manage Your Credentials (in left-hand pane) –> Add a Windows Credential

User Name: MYDOMAIN\joe.user
Password: (password for joe.user on MYDOMAIN)
Click OK

Now, when you fire up SQL Server Management Studio, enter your server name ( and select Windows Authentication. THE USERNAME WILL BE GRAYED OUT but that’s fine. The connection will authenticate properly anyhow. Go ahead and connect.

B) RunAs Command Line (requires user interaction for password)
Open a command line and run this:
runas /netonly /user:MYDOMAIN\joe.user “C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Ssms.exe -S -E”
(You will need to alter the SQL Management Studio exe path as is applicable to your PC)
When prompted on the command line, enter the password for joe.user.
SQL Management Studio should load and automatically connect to the SQL server.

If you are unable to connect with either of these scenarios, check the firewall settings on the remote system.

Credit where credit is due (references):

If you found this helpful, maybe you’d like to send a thank you from my wishlist?

Overcoming the the Zyploit error when using Unrevoked

If when your try rooting your phone with Unrevoked, you encounter the error “process com.unrevoked.zysploit has stopped unexpectedly” during the initial rooting process, you probably have an application interfering with Zysploit, or a bad install of Zysploit itself. Try removing the following apps (from Manage Applications”) in order, and retry between apps:
– Zyploit
– Wireless Tether
– Comcast Xfinity

If someone out there could help confirm what app ultimately fixed this issue, I would appreciate it so I can report the confirmation here. I my case, I started with uninstalling Comcast Xfinity, then with Wireless Tether and Zysploit. Once I did that, Unrevoked worked great.

My Struggle with Android: Stock or Mod?

Since about November of last year, I’ve been running an HTC Evo 4G. I had to leave the WebOS platform due to ongoing (and persisting) uncertainty surrounding it’s future viability in a quickly firming iOS/Android market plurality. I’ve enjoyed a number of features from Android and it’s apps, even though I miss a large number of design features of WebOS. I’ll have to leave that comparison for a future article perhaps.

So after I got used to the features and quirks of the Evo stock ROM, I ventured into the world of ROM modding, specifically Cyanogenmod 7. The feature set of CM7 is very alluring, tweaking away many of those annoyances that come with the stock ROM. However, I notice a number of other quirks that crop up with this Gingerbread-based ROM that constantly make me wish for some of the polish of the HTC-customized Froyo stock ROM. This list is an attempt to document these pros and cons between the two sides of the modding coin.

HTC Evo Stock ROM
Clock App (integrated timer/stopwatch/alarm)
Dialer (functions just seem more intuitive)
Contacts (better contact linking, more intuitive)
Text Selection utility is lacking, missing entirely in some apps

CyanogenMod 7
Improved text selection tool
Universal LED notifications using “WiMax LED”
Better unattended 4G scanning (compared to latest stock ROM)
Notification area quick-toggles (Wifi, 4G, Torch, etc)
No text selection in email
Intermittent signal issues, connectivity loss
Poor Swype integration (conflicts with Gingerbread text selection popup menu)

I will be updating this list periodically as I recall each issue.

HOWTO: Install Mobile Hotspot on a non-Verizon Palm Pre

(Adapted from

Installing and/or using Mobile Hotspot and other tethering methods may violate your wireless contract’s terms of service, and possibly the device warranty as well. You do so at your own risk. In the highly unlikely event that you damage your phone beyond recovery, I am not responsible.

That said, the process is actually pretty simple, and you don’t have a lot of reason to be afraid. If you screw your phone up, Palm provides a tool to recover it called WebOS Doctor which will reset and re-install the software on your phone back to new. Tethering really isn’t a problem either, just as long as you use it within reason and stay under the radar. Most providers don’t pay much attention to your traffic until you consume more than 5GB in a month on your 3G connection. There’s a homebrew utility for the Pre called Netstat that will help you keep an eye on this. Don’t do something stupid like download a bunch of large files as this will probably throw up red flags at your carrier. If you just use Hotspot for web browsing a few times a month for a few hours at a shot, you probably have little to nothing to be concerned about. And, if you follow these instructions, you should have no problem installing and using Hotspot, even if you’ve never done something like this before.

There are the several basic (but detailed) steps involved:

– Turn on developer mode on your Pre
From the main screen, as if you a searching for an application, type:
A hidden application named “Developer Mode Enabler” will show up. Tap it. When the application opens, flip the mode switch to “On”. It will then ask you to restart. Go ahead and restart.

– Obtain and Install WebOS Quick Install
Download WebOS Quick Install from the PreCentral forums. Once you’ve downloaded it, double-click on the file to run it. If in the unlikely event it doesn’t run, you may need to download and install Java. When it first runs, it will ask you to download the WebOS Doctor for your carrier and phone. Just select your option, and proceed. When it’s finished downloading, WebOS Quick Install will finish starting up. Now, with the USB cable that came with your phone, connect your phone to your computer. If windows indicates that it is installing new software, wait until it completes before proceeding. Now go to the Tools menu and select Device Management. After a pause of about 10-20 seconds, you should see a windows showing you details about your Pre. If you don’t see this window, you may need to re-install the phone driver. Only in this case, go to the File menu, select Options, and click “Attempt Novacom re-installation”. After this completes, unplug the USB cable and plug it back in to re-detect the phone.

– Install Preware
Close the Device Management window. Now that you are back on the main screen, click the blue down arrow. When the IPKG Repository Viewer opens, drop down the top combo box and select WebOS-Internals Feed (Pre). Then check the box in the list below next to Preware, and click Download. When it is finished downloading, click Close. Finally, click Install. When the installer finishes, you may proceed.

– Download and Install the FreeTetherd and and Mobile Hotspot ipk files
Download the FreeTetherd and Mobile Hostspot ipk files from the PreCentral forums. You may need to register to download, but registration is free. Once downloaded, drag the files into the WebOS Quick Install window and click Install. Congratulations! Mobile Hotspot is installed and ready to be used!

– Configure Mobile Hostspot
When you first start Mobile Hotspot, it will welcome you with the usual statement about needing a plan from your carrier to support it. Refer to the statements made above, and feel free to continue. By default, the phone will automatically name the wireless network something like “webOS Network 3F:2E:1D”. You may click on the name and rename it whatever you wish, such as “Palm Pre Hotspot”, or you can leave it be as is. Tap Change Passphrase and enter your desired wireless password. This is the password that will keep others from using your hotspot, and allow you to connect to it with your laptop or other WiFi device. When you have clicked done, you are done configuring!

– Connect to your Hotspot!
When you are ready to use your hotspot feature, simply tap the “Off” switch to flip it on. Then just connect to your wireless network with your laptop and enter the password you previously specified. Once it connects, you’re ready to surf! Note that while the Hotspot is running, you can still multitask on your Pre (Listen to music, browse the web, check email, etc.). When you are finished using the Hotspot feature, turn it back off to conserve battery and restore the normal WiFi client connectivity. I should also mention that on non-GSM carriers (such as Verizon and Sprint), when a phone call is placed or received, it will pause your internet connection until the phone call is ended.

– (Optional) Install Netstat

On your phone, you now have an application installed called Preware. This application opens up a whole world of free modifications (patches) and homebrew software for your Pre that isn’t otherwise available in the App Catalog. In this case, we’re going to install Netstat, which allows you to tally up your data usage over the period of a month. This should help you keep an eye on how hard you are on your data plan. To install, launch Preware. After it has finished starting up, just start typing “netstat” and hit enter. Tap “Netstat” and then tap Install. If it asks you to install dependencies, proceed. When it has finished installing, you will probably be asked to restart Luna. Proceed with the restart. When the Pre interface comes back, launch Netstat. You will then see 3 counters: The first is WiFi, which is irrelevant our concern, then 3G/Wireless (looks like a pole with radiating blue lines) which is what we want to watch, and lastly Bluetooth which is irrelevant. As you use your Pre on a daily basis, and as a hotspot, your 3G usages will increase. After a month has passed, you can click on this value to see your historical usage. Make sure you don’t exceed or even come too close to 5Gig or your carrier might have a fit and give you an uncomfortable call.

Lastly, if you ever wish to return your phone, or bring your phone in because of problems following this, I would highly recommend using WebOS doctor to restore your phone to factory default software first. Nobody at your local wireless store likes to hear about device problems potentially created by unsupported software.

So there you have it! Painless, eh?

Finicky: A2DP Bluetooth Stereo on Dell Latitude E6500 w/ Windows 7 64-bit

I thought I’d write up a little bit on my ongoing hassles with A2DP (Bluetooth Stereo Headphones) on Windows 7. I would say it’s a hassle only on Windows 7, but in all honestly, my experiences with A2DP on WinXP weren’t much better, just different.

To start out, a little background: My first success with A2DP was with my Dell D820 with WinXP and the Toshiba Bluetooth stack. This was far from stable, but I could at least get it to work consistently by following a routine involving disabling and re-enabling the Bluetooth adapter and rebooting my headphones. From here, I “upgraded” to Windows 7 RC 32-bit, which worked OK with the Vista drivers for the D820. Audio connectivity was finicky, especially after rebooting, but I could usually get it working again just by removing and re-pairing my headphones. Next was my upgrade to the full release of Windows 7 (32bit). The same problems pretty much stuck around. My biggest issue was with a Windows Update driver that seemed to break A2DP, so I’d have to keep backing it out if I accidentally installed it. Unrelated instability issues with Win7 on the D820 led me to a new PC, the Latitude E6500.

So here I am, with brand-spanking new Dell Latitude E6500 with Windows 7 64-bit and a Dell Wireless 370 Bluetooth mini-card inside. Aside from the topic at hand, this didn’t fix the stability issues, just FYI. The from-factory drivers for the Bluetooth adapter were version A17, IIRC. When I look it up now, it shows up as Vista 64 driver. These drivers simply didn’t work. They would pair with my Insignia NS-BTHDP headphones, create all sorts of devices in Device Manager, but no audio device would show up in the Sound control panel. Needless to say, audio never routed out to my head.

Next I tried downgrading to the A01 drivers, listed on Dell’s support site as being for Win7 64bit. These would pair, work for an hour or so, then apparently crash. The Bluetooth icon would disappear from the taskbar, and audio would get re-routed to my hardwired desktop speakers. This happened multiple times, and re-installing the drivers didn’t seem to help.

Currently I’m using the v6.2.1.800_7a drivers from Gateway’s website ( These seem to work OK, so far.I did notice today that I had to toggle the wireless switch to get the Bluetooth light to activate on my laptop. Once it lit up, it automatically re-connected to my headphones. I can live with this for now. Hopefully I don’t see any more driver crashes.

Note that when re-installing these drivers, you should follow this procedure. Failure to do so can lead to some odd results in Device Manager, and total lack of Bluetooth functionality.

– Delete any paired devices (if possible)
– Clear pairings from your BT device
– Turn off the Wifi/BT switch on your laptop
– From “Programs and Features” control panel, uninstall the WIDCOMM or Dell Bluetooth drivers
– Reboot (DON’T SKIP THIS)
– Run the install for the new Bluetooth driver (v6.2.1.800 is my recommendation)
– When asked, flip the WiFi/BT switch back on.
– Reboot (just to be sure that the new driver takes)
– Pair your headphones

If you reboot/hibernate/suspend and find that the BT light is out, toggle the WiFi/BT switch.

Good luck!

UPDATE 4/2: Grr. It’s still happening. Still looking for a solution…

Fixing Xen Error: (12, ‘Cannot allocate memory’)

I don’t know why this hasn’t already been posted all over the interwebs, so I thought I’d post it here. It’s amazing how some of the simplest answers never seem to make it into prominence in the Google search rankings.

Anyway, after cloning a VM today in Xen, I tried to start the DomU, and got this error:

Error: (12, 'Cannot allocate memory')

I assumed it had something to do with my Dom0 memory cache consuming nearly every last bit of free memory on my system, so I ran this to clear the cache:

echo 3 > /proc/sys/vm/drop_caches

I confirmed that that “free” reported that the cached memory dropped near zero. Great! Except it didn’t help. I then ran “xm info” to check the memory usage in Xen

total_memory : 16378
free_memory : 2

Odd. I checked the Dom0 status to see what’s up, and sure enough, my memory allocation on Dom0 is way high.

xm list Domain-0
Name ID Mem VCPUs State Time(s)
Domain-0 0 10482 4 r—– 3273110.4

But I still didn’t know how to shrink it. I knew it had something to do with memory ballooning. I also knew you could set the memory allocation of a DomU with “xm mem-set”, but I didn’t know anything about how to do it with the Dom0. A quick IRC message to my Xen guru, Jima, and I get this simple command (obvious really) in response:

xm mem-set Domain-0 512

This balloons the Dom0 host system (as well as any domain, really) memory usage down to 512MB. In my case, my Dom0 claimed to be using about 2 Gig already, so I ballooned down to 4G instead. Not sure if that was just due to some bad math or assumptions on my part, as I never run anything of significance in Dom0. After you run this, you should be able to start your DomU just fine.

Something Fun

My wife is pretty fun.

Installing PCL6 Drivers to a Samba/CUPS Print Server

First, a little background…

The classic procedure for installing drivers to a printer shared via CUPS with a raw Samba frontend, usually is roughly something like this:

  1. Create printer in CUPS
  2. Open shared printer properties in Windows
  3. Install drivers via Advanced tab

For me, this worked great, most of the time, assuming that the driver was either PS or PCL5(e). However, PCL6 drivers rarely loaded properly. They crashed upon upload, and the driver rarely ever worked, if point ‘n print even installed the driver. As I understand it, the root of the problem is that the drivers need a valid “form” database specific to the driver to be stored on the server in order to load, but valid form data can only be created by executing the driver. On Windows servers, this isn’t a problem, but Samba servers cannot execute the windows driver code in order to generate this form. PCL6 drivers are particularly finicky about this, and often times will refuse properly copy to the server.

The solution I’ve come up with is to load the driver entirely on a Windows PC first, and tell Samba to copy the drivers and related forms, ACLs, etc over. Some of the values I use here for the printer names, etc, are very generic and only specified to match the naming standards in my environment. Feel free to change your printer setup to suit your needs.

The Procedure
On a Windows PC:

  1. Install the printer as you would normally for TCP/IP printing on a windows PC.
  2. Rename the printer to the share name you will be using (i.e., CopierCP5000)
  3. Open the printer properties
  4. Share the printer using the same name (CopierCP5000)
  5. Set the printer description to the printer name (i.e., Copier CP 5000)
  6. Set the printer location to the office name and city (ACME Abu Dhabi)
  7. Usually under the Accessories/Options tab, update/get information from the printer
         This ensures that we obtain all the correct hardware configuration information for the device (duplexer, trays, hole punch, stapler, etc)
  8. Open the Advanced tab and click the “Printing Defaults” button
  9. Click on each tab and allow the tab to load
         This ensures that the form values for each tab are created.
  10. Still inside the Printing Defaults, change the page orientation to Landscape, hit apply, change the page orientation to Portrait, and hit apply. Click OK.
  11. Close the printer properties by clicking OK

Next, on the server:

### Set up the printer in CUPS, i.e.:
lpadmin -p CopierCP5000 -L "ACME Abu Dhabi" -D "Copier CP 5000" -v lpd://192.168.xx.xx -m raw -E
smbcontrol smbd reload-config
### Copy the drivers, forms, ACLs, etc from the Windows PC
net rpc printer MIGRATE ALL CopierCP5000 -S mypcname -Uusername

Finally, test the driver in Windows:

  1. Open the local Printers control panel (shortcut command below for Win7 users)
         rundll32 shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder
  2. Delete your shared printer
  3. Right-click in the control panel window and select “Server Properties”
  4. Open the Drivers tab
  5. Select your driver and click “Remove”.
  6. Proceed with removal and close the server properties window.
  7. Open \\servername\
  8. Double-click your printer
  9. Print a test page
         If this fails, try restarting the local PC’s Print Spooler service

So far I’ve only tested this on a few of our known-problematic printers that have PCL6 drivers available, and it’s worked perfectly in each case. However it you notice this doesn’t work for you, post a comment and I’ll see what I can do to help.

Palm Pre: Coming Soon to Muchtall?

I just got this email in my inbox this morning (BCC’d to me):

From: (My Boss)
To: (Our Company Sprint Rep)
Subject: Palm Pre
What are the chances of getting our hands on a couple of these when they are released?
(Other Palm User) from (Our Company) and (Muchtall) from my office are waiting patiently for theseā€¦.
(My Boss)

Pretty awesome. Hopefully our Sprint rep can swipe us a couple before the masses clean the stores out.

Update 6/2: Just got an IM from my boss:

(11:17:23 AM) Boss: hey you available for lunch on Thur?
(11:17:32 AM) Muchtall: Sure
(11:17:43 AM) Boss: Im gonna get our Sprint reps to take us out


Update 6/8: So I was greeted by this email earlier this morning:

To: Boss (fwd'ed to Me)
From: Purchasing Dept
Subject: (Muchtall's) Phone
Just received call from Sprint, phone on backorder. Not sure when resupply fulfilled, will keep you in touch.

Which sucks. However, a few hours later, I get this email:

From: Corporate Sprint Rep
To: Purchasing Dept (fwd'ed to Me)
Subject: Pre
Inventory is expected tomorrow so you should have on Wednesday.

Awesome! I can’t wait!