Automagic SSH Tunneling

Date June 23, 2008 by Isaac

SSH never ceases to amaze me. It's like the swiss army knife of network connections and firewall busting. For years I've used SSH tunneling to overcome barriers (read firewalls) stuck into my path. I've never been one to be malicious, but there are times when I need a certain connection that is "prohibited."

For example, during my lunch break at work I will often work on personal projects. One of my projects right now is a suite of programs and libraries generically called Mr. Morse. These projects are all related to Morse Code in some way. What's strange is that my employer blocks outbound SSH (port 22) connections, but not telnet (port 23) connections. Don't ask, because the answer is weird. Anyway, I use github.com to host my source code and Sourceforge to host the software releases and bug tracking. Because I am blocked at work from outgoing SSH connections I can't directly connect to github and push/pull my source code.

SSH to the rescue! Fortunately, a solution exists that once set up is totally transparent to you. Unfortunately, this requires access to another machine outside of the firewall that you control. In my case I have a machine running at home with the SSH daemon running on port 23 instead of the normal port 22. My employer does not block outbound port 23 connections, so this works. From work I can SSH to this machine.

Once this machine was set up there were two options for bouncing a SSH connection through this machine to github. One, I could create a SSH tunnel and leave it running on my machine. This is the "typical" way I see it done on the internet, which works fine, but if your machine is rebooted you need to remember to start the tunnel again. It also makes the remote server look like it is attached to your local machine ports, which may or may not be desirable. For reference, here is how I would do this tunnel to github through my personal remote machine.

#!/bin/sh
# Explanation of command:
# * Disable TCP Keep Alive.  This can be spoofed.
# * Send an encrypted message to the other end every 60 seconds. This
#   should keep the tunnel open
# * The -L creates the tunnel. How this reads is open a tunnel from
#   localhost port 65321 through remote.machine.com to github.com
#   port 22.  Strange, I know.  But, it works.
# * -p 23 because the ssh server at remote.machine.com is on port 23
# * -N don't execute a shell at the other end
# * -f fork into background
# The combination of -N and -f will open the tunnel but we won't
# get a shell and the tunnel will just sit in the background.
ssh -o TCPKeepAlive=no -o ServerAliveInterval=60 -L 65321:github.com:22 \
  -l user remote.machine.com -p 23 -N -f

That's not too bad, but like I said, you need to remember to open the tunnel every time you reboot. Also, the remote machine looks like it is attached to your local machine at port 65321 with this command. The second and preferred method for remote github connection is a SSH config item. This has the advantages of working transparently and still looking like the machine is remote, not local. Simply add this to your .ssh/config file:

Host github.com
     ProxyCommand ssh -p 23 -l user remote.machine.com exec nc %h %p

That's it. Now all git pulls/pushes will automagically be routed through the remote machine without you having to do a thing. So, when you clone my repository all you will have to do is:

git clone git://github.com/wg3i/dit-n-dah.git

and things will just work.

RPM Commands

Date June 4, 2008 by Isaac

I am a Ubuntu (Debian based distro) user, so I sometimes have a hard time remembering RPM commands. Today I found this great reference of RPM commands.

SSH not setting DISPLAY variable

Date May 27, 2008 by Isaac

This morning I did a bare bones CentOS 5.1 installation onto a machine. I don't need Gnome, KDE, or any other window manager. However, I did need to forward the display over SSH for one of the programs that I need to run. For the life of me I could not figure out the correct libraries to install to get the DISPLAY environment variable set when doing "ssh -X". Finally, I ran "ssh -X -v" and that revealed what I needed. A simple

yum install xauth

fixed the problem and now my SSH happily sets the DISPLAY variable.

Using Mercurial on SourceForge

Date May 20, 2008 by Isaac

Lately I've been working on resurrecting a project, called Kollektor, that I have on SourceForge. Kollektor is a personal book collection manager that can fetch information from Amazon. It's been a few years since I worked on it and in the mean time the Amazon interface has changed significantly. A couple days ago I also started a new project called Mr. Morse.

With both of these programs I want to try a distributed version control system. I've used CVS, Subversion, and Perforce for years, but this talk by Linus Torvalds convinced me to try something different.

Since SourceForge natively supports CVS and Subversion it is necessary to install a distributed version control system, such as Mercurial. This article explains the steps necessary to perform the installation of Mercurial on SourceForge.

Keep an eye on my projects and good luck setting up your own distributed source control system.

Identifying the Hard Drives in Your System Under Solaris

Date May 19, 2008 by Isaac

As someone coming from Linux I find working in Solaris completely backwards. Case in point: Today I needed to get the drive information from a Solaris machine. Of all commands the one to use is "format." Go figure. Anyway, here's how to do it, thanks to this article:

bash-3.00# format
Searching for disks...done

AVAILABLE DISK SELECTIONS:
       0. c1t0d0 <SUN72G cyl 14087 alt 2 hd 24 sec 424>
          /pci@1c,600000/scsi@2/sd@0,0
       1. c1t1d0 <SUN72G cyl 14087 alt 2 hd 24 sec 424>
          /pci@1c,600000/scsi@2/sd@1,0
Specify disk (enter its number): 0
selecting c1t0d0
[disk formatted]
Warning: Current Disk has mounted partitions.
/dev/dsk/c1t0d0s0 is currently mounted on /. Please see umount(1M).
/dev/dsk/c1t0d0s1 is currently used by swap. Please see swap(1M).
/dev/dsk/c1t0d0s6 is currently mounted on /var. Please see umount(1M).
/dev/dsk/c1t0d0s7 is currently mounted on /sdh_home. Please see umount(1M).

FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        save       - save new disk/partition definitions
        inquiry    - show vendor, product and revision
        volname    - set 8-character volume name
        !<cmd>     - execute <cmd>, then return
        quit
format> inquiry
Vendor:   SEAGATE
Product:  ST373207LSUN72G
Revision: 045A
format>

Now that you have the disk info you can go to the manufacturers web site and look up the drive information. In this case the model number is ST373207L, which turns out to be a 10k RPM 73GB SCSI drive.

Good luck drive hunting. :)

Idea for Logging Tool

Date May 16, 2008 by Isaac

The piece of software that I test at work has an option to enable debug logging to a file. Normally, I run with this enabled so that I have a record of what I did and any errors that I encounter. However, this file can become extremely bloated and if often hundreds of megabytes by the time I give it to the developer to fix a problem that I found. I was thinking today about a solution that would be useful for any program that can dump logs to a file. In Linux, you can create a named pipe, that other programs can write to. Would it be possible to have one program create this pipe, then have the program under test write to this pipe instead of a file? I haven't tested this, but I imagine it's possible.

Where this would be useful is your "log interceptor" program could do a multitude of different things with this stream of log data. For example, it could push it into a database which could later be searched by developers to narrow down time windows or look for specific error messages. Another really useful thing to do would be to have the log interceptor do basic log rotation. This could keep the log file size manageable. Or, maybe you want the log file emailed somewhere every 100k or whatever. There are a lot of uses I could see for something like this.

Has anyone written or seen such a program? Am I the only one that thinks this would be useful? Post a comment and let me know what you think.

VMWare Workstation 6.0 and Ubuntu Hardy

Date May 14, 2008 by Isaac

I just finished installing VMWare Workstation 6.0.3 under Ubuntu Hardy (8.04) and ran into some issues.  During the configuration, when VMWare is compiling drivers for the system, I got an error saying "include/asm/bitops_32.h:9:2: error: #error only <linux/bitops.h> can be included directly"

From my reading this seems to be related to version 2.6.24 of the Linux kernel. The solution to this problem is actually quite easy...if you are willing to edit one of the VMWare header files. A blog post pointed me to the solution. Here is what you need to do:

  1. cd /usr/lib/vmware/modules/source
  2. sudo cp vmmon.tar vmmon.tar.orig
  3. sudo tar xvf vmmon.tar
  4. cd vmmon-only/include/
  5. sudo vi vcpuset.h
    • Line 74 needs to be changed from: #include "asm/bitops.h" to: #include "linux/bitops.h"
  6. cd ../../
  7. sudo rm vmmon.tar
  8. sudo tar cvf vmmon.tar vmmon-only/
  9. sudo rm -rf vmmon-only/
  10. sudo vmware-config.pl

Things should work now. Good luck.

Enable Mouse Wheel Scrolling in Ubuntu Hardy 8.04 Under VMWare

Date April 29, 2008 by Isaac

I recently installed Ubuntu Hardy (8.04) into a VMWare image on my WIndows machine.  I know, that's backwards, Linux should be the host not the guest.  It's actually my wife's computer, so I dare not remove Windows.

Anyway, the mouse wheel was not scrolling properly.  After some searching I found the answer here.  Basically, you need to edit your /etc/X11/xorg.conf file.  Find the following section:

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
...
EndSection

Replace that section with this:

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
Option "CorePointer"
Option "Device" "/dev/input/mice"
Option "Protocol" "ImPS/2"
Option "Buttons" "5"
Option "ZAxisMapping" "4 5"
EndSection

You will need to reboot or restart your X server and mouse scrolling should now work.

Cloning a List in Python

Date April 14, 2008 by Isaac

As far as I know there is no official way to clone a list in Python. This is desirable at times because normal variable assignment of lists is just a reference copy. For example:

 
>>> listA = ['A', 'B', 'C', 'D']
>>> listB = listA
>>> listA
['A', 'B', 'C', 'D']
>>> listB
['A', 'B', 'C', 'D']
>>> listA.remove('C')
>>> listA
['A', 'B', 'D']
>>> listB
['A', 'B', 'D']
 

As you can see, B was assigned to reference the same list as A and removing something from A also removed it from B.

At times that is fine, however, sometimes you need a clone of the list so that changes in A do not reflect in B. A very simple way to accomplish that is by using slicing. Our example now becomes:

 
>>> listA = ['A', 'B', 'C', 'D']
>>> listB = listA[:]
>>> listA
['A', 'B', 'C', 'D']
>>> listB
['A', 'B', 'C', 'D']
>>> listA.remove('C')
>>> listA
['A', 'B', 'D']
>>> listB
['A', 'B', 'C', 'D']
 

There we go, problem solved.

Adding Emacs to Windows Right Click Menu

Date April 13, 2008 by Isaac

First of all, if you don't have Emacs installed on Windows then you should download it now. :)

Once you have Emacs installed then you'll naturally want to add "Open With Emacs" to your Windows right-click menu. To do this you'll need to make a registry entry. The easiest way is to copy the following text into a file, call it emacs.reg or something similar, and then double click the file.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell]

[HKEY_CLASSES_ROOT\*\shell\Open With Emacs]

[HKEY_CLASSES_ROOT\*\shell\Open With Emacs\command]
@="C:\\progs\\emacs-22.2\\bin\\runemacs.exe \"%1\""

Of course you should substitute the path to emacs with wherever you have it installed on your system.

That's it. Enjoy using Emacs in Windows.