Home

Advertisement

Apr. 19th, 2008

Seashore

Fun with SSH tunnels...

Originally, I was one of the few people that had to run around between the various physical locations that my employer maintains. Now that there has been an expansion of that group, I have begun to look for ways to minimize the annoyance and cost, of maintaining this situation. Like with nearly everything in the last couple of months, this problem was solved with scripting.

In this particular case, there are a couple of guys that don't really want to travel 1.5 hours in order to pick up a document off a computer on the remote site. This can be readily solved by using VNC but security needs to be maintained and thus some use of SSH would be required. I also don't have access to the external firewall at the remote site and thus will need to reverse the SSH tunnel.

In this case, I originally went with TightVNC but it didn't work like I had thought it would, thus I went to UltraVNC. On Windows, there isn't any other solution for SSH than the venerable PuTTY.

Local Script

Summary: The following code tests if Putty and VNC are loaded, if not it will start those programs with the appropriate options.

Details: First, I disable spurious output to the command prompt. Then, I limit the scope of the "Environmental Variables" to the current script (which is probably a waste of time). Next, I re-write the PATH variable to load the minimum needed for this script to work correctly. Then I set a bunch of "Environmental Variables" to shorten the code that I need to write. Subsequently, I test if Putty has been loaded. Then I test if it has an active connection to an SSH capable server that serves as an endpoint for the various tunnels. If any of these conditions is false, it attempts to kill off Putty and then reload it with the variables specified below. (It opens port 25901 on the end point and connects it to port 5901 on the local machine.) Next, VNC is tested in similiar ways and opens a connection to port 5901 (which gets funnelled over to the endpoint at port 25901). Then we kill the command prompts that may have been loaded.

NOTES: Ping is used to delay or "sleep" the execution of the command for a period of time required to complete the various pings. I route most of the command prompt output to the various log files declared in the "Environmental Variables". The start command is used to launch the program while letting the rest of the script continue along (it is also the reason that I had to re-write the PATH "Environmental Variable").
@echo off
setLocal

::  Set Environmental variables.

set PATH=%WINDIR%\system32;%WINDIR%\system32\wbem;%PROGRAMFILES%\Putty;%PROGRAMFILES%\TightVNC Viewer;
set PATHEXT=.exe;

::  Set Putty variables.

set KEYFILE=[Key Location]
set SSHUSER=[Account Name]
set SSHHOST=[URL | IP Address]

::  Set Logging variables.

set MAINLOG="%TMP%\mainlog.txt"
set PINGLOG="%TMP%\pinglog.txt"
set VNCLOG="%TMP%\VNClog.txt"

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

::  If Putty is open and running, skip to "vncstart".

tasklist /FI "IMAGENAME eq putty.exe" | findstr /c:putty.exe >> %MAINLOG% 2>&1
  if %ERRORLEVEL% equ 0 (netstat -n -p TCP | findstr /c:":22" | findstr /c:"ESTABLISHED")
  if %ERRORLEVEL% equ 0 (goto vncstart)

::  Kill existing Putty sessions, start new session and write date to log file.

taskkill /f /IM putty.exe >> %MAINLOG% 2>&1
start putty -ssh -C -i %KEYFILE% -L 5901:localhost:25901 -N -T %SSHUSER%@%SSHHOST%
echo SSH Connected @ >> %MAINLOG% 2>&1
date /t >> %MAINLOG% 2>&1
time /t >> %MAINLOG% 2>&1

::  Use Ping to cause script to pause for a few seconds for the tunnel to be established.

ping -n 16 127.0.0.1 >> %PINGLOG% 2>&1

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

:vncstart

::  If VNC is open and connected, skip to "endscript".

tasklist /FI "IMAGENAME eq uvncviewer.exe" | findstr /c:uvncviewer.exe >> %MAINLOG% 2>&1
  if %ERRORLEVEL% equ 0 (netstat -n | findstr /c:":5901" | findstr /c:"ESTABLISHED")
  if %ERRORLEVEL% equ 0 (goto endscript)

::  Kill existing VNC sessions, start a new sesson.

taskkill /f /IM uvncviewer.exe >> %MAINLOG% 2>&1
start uvncviewer /autoreconnect 60 /autoscaling /password [password] /shared localhost:1 

::  Use Ping to cause script to pause for a few seconds before closing the CMD window.

ping -n 6 127.0.0.1 >> %PINGLOG% 2>&1

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

:endscript

::  If CMD is open, kill all existing sessions.

tasklist /FI "IMGAGENAME eq cmd.exe" | findstr /c:cmd.exe >> %MAINLOG% 2>&1
  if %ERRORLEVEL% equ 0 (taskkill /IM cmd.exe)

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

endLocal
@echo on
exit


Remote Script
Summary: The biggest difference between this script and the previous is the construction of the Putty command and the restarting of uvnc_service.

Details: Putty opens port 25901 on the remote machine and then funnels that to port 5901 on the local machine. You will have to do some configuration on the VNC server so that it listens on port 5901.
@echo off
setLocal

::  Set Environmental variables.

set PATH=%WINDIR%\system32;%WINDIR%\system32\wbem;%PROGRAMFILES%\Putty;%PROGRAMFILES%\UltraVNC;
set PATHEXT=.exe;

::  Set Putty variables.

set KEYFILE=[Key Location]
set SSHUSER=[Account Name]
set SSHHOST=[URL | IP Address]

::  Set Logging variables.

set MAINLOG="%TMP%\mainlog.txt"
set PINGLOG="%TMP%\pinglog.txt"
set VNCLOG="%TMP%\VNClog.txt"

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

::  If Putty is open and running, skip to "endscript".

tasklist /FI "IMAGENAME eq putty.exe" | findstr /c:putty.exe >> %MAINLOG% 2>&1
  if %ERRORLEVEL% equ 0 (netstat -n -p TCP | findstr /c:":[SSH Port]" | findstr /c:"ESTABLISHED")
  if %ERRORLEVEL% equ 0 (goto endscript)

::  Kill existing Putty sessions, start new session and write date to log file.

taskkill /f /IM putty.exe >> %MAINLOG% 2>&1
start putty -ssh -C -i %KEYFILE% -N -P [SSH Port] -R 25901:localhost:5901 -T %SSHUSER%@%SSHHOST%
echo SSH Connected @ >> %MAINLOG% 2>&1
date /t >> %MAINLOG% 2>&1
time /t >> %MAINLOG% 2>&1

::  Restart VNC service...

echo Reload VNC >> %MAINLOG% 2>&1 
net stop uvnc_service
ping -n 16 127.0.0.1 > %PINGLOG% 2>&1
net start uvnc_service

::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

:endscript

::  If CMD is open, kill all existing sessions.

tasklist /FI "IMAGENAME eq cmd.exe" | findstr /c:cmd.exe >> %MAINLOG% 2>&1
  if %ERRORLEVEL% equ 0 (taskkill /IM cmd.exe)
  
::  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ::

endLocal
@echo on
exit

I created a "Scheduled Task" to cause this script to execute every 15 minutes during the working day. Although, I did have to modify the task after establishing it to minimize the distraction it can cause. I created a "shortcut" to the actual script and set it's properties to load in a "minimized window" and then re-write the scheduled task to execute the link. The effect is that every 15 minutes the command prompt will show up in the taskbar and then dissappear.

On the SSH endpoint server, I limit the keys to DNS names, ports and TTY access through various options added to the authorized_keys file.

Jan. 31st, 2008

Seashore

The Scriptorium and Linux

Well for the last week or so, my life has been full of typing. A few dozen Windows command scripts here and a dozen *nix shell scripts there. Most of this is an attempt to reduce the unorganized largessness of working where I do to something more managable.

On Windows, they have a CMS application which requires about 4 other applications to be installed before you can use it. I have a nifty script that starts each installer, waits until completion, continues to the next installer (rinse and repeat), it copies over an icon and another script that sets an environmental variable (required for licensing), and finally, if necessary, edits an INI file to allow managerial access to the application. Another set of scripts allows a specific application to be run with "Administrator" priviledges so that it can update it's data files. Still another series of scripts set's up a kind of backup scheme using "xcopy" for some of their departments.

On the Unix front, I've made a nifty script that allows me to easily log into the various *nix systems that I use on a daily basis.

Script 1

#! /bin/bash

# This little script is designed to allow me to quickly switch between the
# various Linux boxes on the network without causing me any problems with
# the normal use of the SSH command.

SSH=/usr/bin/ssh

if [ $# -lt 2 ]; then
SSHADDR=$(printf $1 | tr [:upper:] [:lower:])
fi

case $SSHADDR in
"home" )
$SSH ME@my-imac.local;
;;
"wlo" )
$SSH -i $HOME/.ssh/KEY2 ME@111.93.84.115;
;;
"wlo2" )
$SSH -i $HOME/.ssh/KEY2 ME@111.93.84.15;
;;
"cp" )
$SSH -i $HOME/.ssh/KEY2 ME@111.110.93.50;
;;
* )
$SSH $*;
;;
esac


Now, instead of writing over 24 characters, I type 7 or 8 characters and I don't forget to remember the "-i" option for my alternative key. If necessary, it also allows the normal functioning of the ssh command. Although, I do wish there was a better way of lower casing just the custom options. (i.e. I also have the following loading with my shell (zsh) alias ssh='sh $HOME/Applications/ssh.sh'.)

The company I work for finally decided to spring for an actual server box (rather than using my brother's Compaq PC) to run the necessary network services. The new box is a Dell SC1430 with: 2x 1.6Ghz Xeon Dual Core CPU's, 4Gb of RAM (SME is 32bit only), and an 80Gb HD. To that we added some equipment from Newegg: 2x 1Tb Hitachi HD's, 1 Intel Dual port PCI-Express card and an 3.5 to 5.25 HD bracket. The initial setup of SME Server was nearly trivial but that may be because I didn't initially connect the additional two drives. After setup, I put in the two terrabyte drives and attempted to RAID-1 them together. Thus, I got to meet the brick wall head first. Apparently, no one on the community site has ever attempted to add more drives as a RAID array. I thought, at one point, that I got it working but at least some of the SME software wasn't detecting it correctly and I decided to start over.

The end result of my tinkering and research has revealed that the following commands seem to correctly create the array in SME Server.

Script 2?

NOTE: Not yet feature complete.

mdadm --create --verbose /dev/md3 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1
mdadm --detail /dev/md3
printf "EJECT THE CD-ROM\!\!\!\a\n"
pvcreate /dev/md3
vgcreate -s 16M lvm-raid /dev/md3
vgchange -a y lvm-raid
vgdisplay /dev/md3 | grep "Total PE"


Total PE / Size XXXXXX / YYYY

lvcreate -l XXXXXX lvm-raid -n bigdisk
mkfs.ext3 /dev/lvm-raid/bigdisk
mkdir /user_files
mount /dev/lvm-raid/bigdisk /user_files

mv /etc/mdadm.conf /etc/mdadm.conf.bak
printf "DEVICE partitions\n" > /etc/mdadm.conf
printf "DEVICE /dev/s[bc]1\n" >> /etc/mdadm.conf
printf "ARRAY /dev/md2\n" >> /etc/mdadm.conf
printf "ARRAY /dev/md1\n" >> /etc/mdadm.conf
printf "ARRAY /dev/md3 devices=/dev/sdb1,/dev/sdc1\n" >> /etc/mdadm.conf


Now you have to edit /etc/fstab to add /dev/lvm-raid/bigdisk /user_files SOME TEXT 1 2 .

In closing, I've found an interesting book that deals with shell scripting by O'Reilly, obviously, called Classic Shell Scripting. Microsoft has also been kind enough to enable me to purchase "Super Mario Galaxy" and thus I may be joining the RSI club.

Updates:Code tweaking.

Advertisement

Customize