Home

Advertisement

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.

Comments

Advertisement

Customize