Túnel SSH automático desde Windows


32

Estoy tratando de configurar una computadora con Windows para que siempre tenga dos túneles SSH en mi servidor Linux.

Actualmente, estoy usando PuTTY para abrir los dos túneles SSH: inicio sesión en el servidor en PuTTY, lo dejo minimizado y nunca lo toco. Esto funciona bien, excepto cuando la conexión SSH se cae: PuTTY muestra un mensaje de error, y necesito cerrar el error manualmente y volver a conectarme al servidor.

Lo que me gustaría hacer es tener una aplicación que pueda configurar los dos túneles SSH, y que pueda reconectarse automáticamente, sin necesidad de hacer nada manualmente, incluso ingresar una contraseña. Los datos que envío a través de los dos túneles son conexiones VNC, por lo que a menudo no estaré en la máquina para borrar errores e ingresar contraseñas. Los dos túneles son un túnel local y un túnel remoto.

(Sí, soy consciente de los peligros de iniciar sesión automáticamente en SSH. Estoy planeando crear un usuario dedicado sin privilegios y sin permiso para iniciar sesión de forma interactiva y usarlo).

Encontré esta pregunta: ¿Cómo mantener confiablemente abierto un túnel SSH? , pero eso está usando Linux como el cliente SSH, y yo estoy usando Windows.


2
El inicio de sesión automático no es un peligro si se hace correctamente. Busque la autenticación de clave pública SSH .
Grawity

Estoy haciendo eso para los inicios de sesión manuales ahora, pero creo que PuTTY no permite que la clave tenga una contraseña en blanco.
David Yaw

Claro que lo hace.
Grawity

Debo haber entendido mal parte de la documentación de PuTTY. Probablemente leí "nunca haremos que PuTTY escriba automáticamente su contraseña por usted", y asumí que eso significaba que también se requerían contraseñas en la clave.
David Yaw

Respuestas:


14

Prueba Bitvise Tunnelier : funciona para mí. Lo configuré para establecer túneles SSH mientras solo era visible como un icono de bandeja. Establece la conexión SSH en el inicio y la restablece tan pronto como se restablece la conectividad después de un corte o después de que el sistema se durmió. Todavía prefiero el aspecto de la consola Putty, así que sigo usándola, pero para mantener los túneles en funcionamiento ahora uso Tunnelier. El único inconveniente importante que he encontrado es la falta de soporte de IPv6, que Putty proporciona sin necesidad de acción del usuario.


He estado usando esto por unos meses ahora. Es justo: se sienta en la bandeja del sistema, apaga cualquier ventana emergente quejándose de desconexiones y demás, y mantiene los túneles abiertos. Todavía uso PuTTY si voy a trabajar mucho en la conexión, pero para túneles y terminales rápidas, Tunnelier funciona bien.
David Yaw

2
Puede que no esté claro, pero configura túneles en la pestaña C2S y túneles inversos en la pestaña S2C . Significa client2server y server2client , respectivamente.
fracz

@ Jean-Marc Liotier Quizás puedas ayudarme. Mira esto: superuser.com/questions/1353398/…
Success Man

@SuccessMan: lo siento, han pasado años desde que usé cualquier producto de Microsoft más que superficialmente. Ahora soy todo Debian, donde este tipo de problema se resuelve trivialmente ...
Jean-Marc Liotier


2

Eche un vistazo a Xshell : es más programable que PuTTY y es gratuito para uso doméstico (si es allí donde debe usarlo). Afirma tener una función de reconexión automática, pero no la he probado y he estado en una computadora portátil basada en Linux durante unos buenos meses, así que no tengo ningún medio para probarla en el momento.


Xshell es increíble, lo cambié desde SecureCRT hace 3-4 años y no he mirado atrás
alexeit


2

Probé muchas soluciones, como los administradores de túneles SSH, pero no me convencieron: demasiadas pantallas de configuración, a veces con errores (¡una vez que el administrador de túneles SSH purgó todos los ajustes que tenía! Así que tuve que restaurar la configuración de los 30 túneles). Entonces todos perdieron mi confianza. Es por eso que se me ocurrió un script Powershell personalizado, fácil de configurar, cambiante, pequeño, pero funciona. Publicado aquí y a continuación:

Para comenzar a usarlo, necesita una configuración como esta:

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

Guárdelo como config.csv. Y usar un script de PowerShell para mantenerlo es:

<#
.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();
    }
  }
}

Después de configurarlo, simplemente ejecútelo como:

powershell -File autossh.ps1

1

Si eres fanático de Putty, prueba Putty Tray .

Tiene algunas funciones adicionales, incluido el intento de reconexión automática después de una falla de conexión y la reconexión cuando la computadora se activa desde el modo de espera.

Como ya lo mencionó otra persona, combinaría esto con la autenticación de clave pública sin frase de contraseña.

En teoría, esto debería ser bastante confiable, pero no soy un experto en seguridad, así que no puedo aconsejarlo en ese frente.


0

Lo busqué en Google y arrojé algunos resultados para tu pregunta, básicamente siempre puedes probar un combo de búsqueda automate putty loginque hice. Aquí hay un resultado particularmente útil que debería adaptarse a usted:

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

Le guía a través de cómo configurar una macro para masilla. También descargue el administrador de conexión Putty aquí (ya que el enlace está roto desde el enlace inicial):

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


El enlace de SourceForge para PuttyCM está roto. Ver esta pregunta .
Craig McQueen

@CraigMcQueen, ¿te das cuenta de que esto fue respondido el 19/01/2011? ¿Derecha?
Jakub

1
Sí, me doy cuenta. Y lo encontré en una búsqueda en Google ayer, y otras personas pueden hacerlo durante un año o dos por venir.
Craig McQueen

0

También utilicé Putty y tuve el mismo problema hasta que encontré una solución mejor: pruebe ADVSoft Persistent SSH https://persistentssh.com funciona como un servicio de Windows y mantiene los túneles SSH en estado de ejecución. Gratis para uso personal, no es necesario instalar nada más.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.