31

I'm trying to set up a Windows computer to always have two SSH tunnels to my Linux server.

Currently, I'm using PuTTY to open the two SSH tunnels: I log in to the server in PuTTY, leave it minimized, and never touch it. This works well, except when the SSH connection drops: PuTTY displays an error message, and I need to manually close the error and reconnect to the server.

What I'd like to do is have an application that can set up the two SSH tunnels, and can automatically reconnect, without needing to manually do anything, including enter a password. The data I'm sending across the two tunnels is VNC connections, so I often won't be at the machine to clear errors and enter passwords. The two tunnels are one local tunnel, and one remote tunnel.

(Yes, I am aware of the hazards of automatically logging in to SSH. I'm planning on making a dedicated user with no privileges and not allowed to interactively log in, and use that.)

I did find this question: How to reliably keep an SSH tunnel open?, but that's using Linux as the SSH client, and I'm using Windows.

  • 2
    Automatic login is not a hazard if done right. Look up SSH public-key authentication. – grawity Jan 19 '11 at 21:15
  • I am doing that for the manual logins now, but I believe PuTTY doesn't allow the key to have a blank password. – David Yaw Jan 19 '11 at 21:26
  • Of course it does. – grawity Jan 19 '11 at 22:57
  • I must have misunderstood some of the PuTTY documentation. I probably read "we will never make PuTTY auto-type your password for you", and assumed that meant passwords were required on the key as well. – David Yaw Jan 20 '11 at 0:13
14

Try Bitvise Tunnelier - it works for me. I set it to establish SSH tunnels while only being visible as a tray icon. It establishes the SSH connection on startup and re-establishes it as soon as connectivity is restored after a cut or after the system went to sleep. I still prefer the looks of the Putty console, so I keep using it - but for keeping tunnels up I now use Tunnelier. The only major downside I have found is the lack of IPv6 support, which Putty provides with no user action needed.

  • I've been using this for a few months now. It's just right: sits in the system tray, turn off any popups complaining about disconnects and such, and it keeps the tunnels open. I still use PuTTY if I'm going to be doing much work over the connection, but for tunnels & quick terminal stuff, Tunnelier works good. – David Yaw Nov 15 '11 at 17:27
  • 2
    It may not be clear, but you set up tunnels in the C2S tab and reverse tunnels in S2C tab. It stands for client2server and server2client, respectively. – fracz Jul 28 '16 at 22:47
  • @Jean-Marc Liotier Maybe you can help me. Look at this : superuser.com/questions/1353398/… – Success Man Sep 1 '18 at 4:02
  • @SuccessMan - I'm sorry, it has been years since I have used any Microsoft product more than superficially. I'm now all-Debian, where this sort of problem is solved trivially... – Jean-Marc Liotier Sep 12 '18 at 13:32
11

Try MyEnTunnel. It can reconnect at connections failures.

enter image description here

2

Have a look at Xshell - it's more scriptable than PuTTY and is free for home use (if that's where you need to use it). It claims to have an auto-reconnect feature but I haven't tried it and have been on a Linux-based laptop for a good few months now so don't have any means to test it at the mo.

  • Xshell is awesome, i have switched to it from SecureCRT 3-4 years ago and haven't looked back – alexeit Feb 7 '12 at 2:23
1

If your a fan of Putty, try out Putty Tray.

It has a few additional functions, including attempting to auto-reconnect after a connection failure and reconnecting when your computer wakes from standby.

As already mentioned by someone else, I'd combine this with public-key authentication with no pass-phrase.

In theory this should be pretty reliable, but i'm no security expert so can't advise you on that front.

1

Two great tools :

Both have those features :

  • Could be automated at boot
  • Opensource
  • Manage many tunnels at the same time
  • Could reside in the system tray
  • Free of charge (Mobaxterm have a free version)
  • Encrypt stored password

1. Mobaxterm

Site : http://mobaxterm.mobatek.net/

Capture :

enter image description here

2. SSH Tunnel Manager

Site : https://code.google.com/archive/p/ssh-tunnel-manager/

Capture :

enter image description here

1

I tried many solutions like SSH tunnel managers, but all were inconvinient for me: too many configuration screens, sometimes buggy (one time SSH tunnel manager purged all! settings I had! So I had to restore settings for all 30 tunnels). So they all lost my trust. That's why I come up with custom Powershell script, easy configurable, changeable, small, but works. Posted here and below:

To start using it you need a config like this:

# LocalPort TargetHost  TargetPort  SshHost SshUsername SshKeyPath 
18080   google.com  80  bastion.example.com User    D:\secure\path\to\private_key.ppk

Save it as a config.csv. And use a powershell script to keep it up is:

<#
.SYNOPSIS
  Powershell script for keeping ssh tunnel up and running

.DESCRIPTION
  This script uses configuration of tunnels located in config.csv. For more information visit http://tsherlock.tech/2019/03/13/simple-ssh-tunnel-auto-reconnect-using-putty-and-powershell/

.NOTES
  Version:        1.0
  Author:         Anton Shkuratov
  Creation Date:  2019-03-13
  Purpose/Change: Initial script development

#>

$currentDir = $PSScriptRoot
if (-not $env:PATH.Contains($currentDir)) {
  $env:PATH="$env:PATH;$currentDir"
}

# Check plink is accessible
try {
  Start-Process plink.exe -WindowStyle Hidden
} catch {
  Write-Host Error running plink.exe Please make sure its path is in PATH environment variable
  EXIT 1
}

# Parse config
$config = [System.IO.File]::ReadAllLines("$currentDir\config.csv");
$bindings = New-Object System.Collections.ArrayList
$regex = New-Object System.Text.RegularExpressions.Regex("(\d)+\s([^ ]+)\s(\d+)\s([^ ]+)\s([^ ]+)\s([^ ]+)", [System.Text.RegularExpressions.RegexOptions]::IgnoreCase);
$keyPasswords = @{}
$procs = @{}

foreach($line in $config) {
  $match = $regex.Match($line)

  if ($match.Success) {
    $sshKey = $match.Groups[6];

    $bindings.Add(@{
      LocalPort = $match.Groups[1];
      TargetHost = $match.Groups[2];
      TargetPort = $match.Groups.Groups[3];
      SshHost = $match.Groups[4];
      SshUser = $match.Groups[5];
      SshKey = $match.Groups[6];
    });

    if (-not $keyPasswords.ContainsKey($sshKey)) {
      $pass = Read-Host "Please enter password for key (if set): $sshKey" -AsSecureString
      $keyPasswords.Add($sshKey, $pass);
    }
  }
}

# Starting Processes
function EnsureRunning($procs, $keyPasswords, $binding) {

  if ($procs.ContainsKey($binding) -and $procs[$binding].HasExited) {

    $proc = $procs[$binding]
    $sshKey = $binding.sshKey
    $out = $proc.StandardError.ReadToEnd()

    if ($out.Contains("Wrong passphrase")) {
      Write-Host "Wrong pass phrase for $sshKey, please re-enter"
      $pass = Read-Host "Please enter password for key: $sshKey" -AsSecureString
      $keyPasswords[$sshKey] = $pass;
    } else {
      $exitCode = $proc.ExitCode
      $tHost = $binding.sshHost

      Write-Host "Connection to $tHost is lost, exit code: $exitCode"
    }
  }

  if (-not $procs.ContainsKey($binding) -or $procs[$binding].HasExited) {
    $sshUser = $binding.SshUser
    $sshHost = $binding.SshHost
    $sshKey = $binding.SshKey
    $lPort = $binding.LocalPort
    $tPort = $binding.TargetPort
    $tHost = $binding.TargetHost
    $sshKeyPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($keyPasswords[$sshKey]))

    $psi = New-Object System.Diagnostics.ProcessStartInfo;
    $psi.FileName = "plink.exe";
    $psi.UseShellExecute = $false;

    $psi.CreateNoWindow = $true;
    $psi.RedirectStandardInput = $true;
    $psi.RedirectStandardError = $true;

    $psi.Arguments = "-ssh $sshUser@$sshHost -i `"$sshKey`" -batch -pw $sshKeyPass -L $lPort`:$tHost`:$tPort"

    $proc = [System.Diagnostics.Process]::Start($psi);

    Start-Sleep 1

    if (-not $proc.HasExited) {
      Write-Host Connected to $sshUser@$sshHost
    }

    $procs[$binding] = $proc;
  }
}

function EnsureAllRunning($procs, $keyPasswords, $bindings) {
  while($true) {
    foreach($binding in $bindings) {
      EnsureRunning $procs $keyPasswords $binding
    }
    Start-Sleep 1
  }
}


try {
  # Waiting for exit command
  Write-Host Working... Press Ctrl+C to stop execution...
  EnsureAllRunning $procs $keyPasswords $bindings
} finally {
  # Clean up
  Write-Host Clean up

  foreach($proc in $procs.Values) {
    if ($proc -ne $null -and -not $proc.HasExited) {
      $proc.Kill();
    }
  }
}

After it is configured just run it like:

powershell -File autossh.ps1
0

I googled it and gota a few results for your question, basically you could always try a search combo of automate putty login which I did. Here is a particularly useful result that should suit you:

http://www.neox.net/w/2008/04/22/putty-auto-login-macro-putty-connection-manager/

It walks you through how to setup a macro for putty. Also download Putty connection manager here (as the link is broken from initial link):

http://sourceforge.net/projects/puttycm/

  • The SourceForge link for PuttyCM is broken. See this question. – Craig McQueen Jul 24 '12 at 7:06
  • @CraigMcQueen, you do realize that this was answered in 01/19/2011!? right? – Jakub Jul 25 '12 at 0:18
  • 1
    Yes, I do realise. And I found it in a Google search yesterday, and other people may do so for a year or two to come. – Craig McQueen Jul 25 '12 at 4:50
0

I used Putty as well and had the same problem until I found a better solution - Try ADVSoft Persistent SSH https://persistentssh.com works as a Windows service and keeps SSH tunnels in run state. Free for personal use, no need to install anything else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.