从Windows自动进行SSH隧道


32

我试图将一台Windows计算机设置为始终有两个通往我的Linux服务器的SSH隧道。

当前,我正在使用PuTTY打开两个SSH隧道:我在PuTTY中登录到服务器,将其最小化,并且永不动手。除SSH连接断开时,此方法工作良好:PuTTY显示错误消息,并且我需要手动关闭错误并重新连接到服务器。

我想要做的是拥有一个可以设置两个SSH隧道并可以自动重新连接的应用程序,而无需手动执行任何操作,包括输入密码。我通过两个隧道发送的数据是VNC连接,因此我经常不在机器上清除错误并输入密码。这两个隧道是一个本地隧道和一个远程隧道。

(是的,我知道自动登录到SSH的危险。我计划让一个没有特权的专门用户并且不允许以交互方式登录并使用它。)

我确实发现了以下问题:如何可靠地保持SSH隧道打开?,但这使用Linux作为SSH客户端,而我使用Windows。


2
如果操作正确,自动登录不会造成危害。查找SSH 公钥身份验证
grawity 2011年

我现在正在手动登录,但是我相信PuTTY不允许密钥输入空白密码。
David Yaw

当然可以。
grawity 2011年

我一定误解了一些PuTTY文档。我可能读过“我们绝不会让PuTTY为您自动键入您的密码”,并假设这意味着密钥上也需要密码。
David Yaw

Answers:


14

试试Bitvise Tunnelier-它对我有用。我将其设置为建立SSH隧道,同时仅作为任务栏图标显示。它会在启动时建立SSH连接,并在切断后或系统进入睡眠状态后立即恢复连接。我仍然更喜欢Putty控制台的外观,因此我继续使用它-但是为了保持隧道畅通,我现在使用Tunnelier。我发现的唯一主要缺点是缺乏IPv6支持,Putty无需用户采取任何措施即可提供支持。


我已经使用了几个月了。没错:坐在系统托盘中,关闭所有抱怨断开连接等问题的弹出窗口,并使隧道保持打开状态。如果要在连接上做很多工作,我仍然会使用PuTTY,但是对于隧道和快速终端设备,Tunnelier效果很好。
David Yaw

2
可能还不清楚,但是您可以在“ C2S”选项卡中设置隧道,并在“ S2C”选项卡中设置反向隧道。它分别代表client2serverserver2client
fracz

@ Jean-Marc Liotier也许您可以帮我。看看这个:superuser.com/questions/1353398/...
成功男人

@SuccessMan-对不起,距我对Microsoft产品的肤浅使用已有多年了。我现在是全Debian,可以
轻松


2

看看Xshell-它比PuTTY更可编写脚本,并且可以免费在家中使用(如果需要的话)。它声称具有自动重新连接功能,但是我还没有尝试过,并且已经在基于Linux的笔记本电脑上使用了好几个月,所以没有任何方法可以立即对其进行测试。


Xshell很棒,我在3-4年前就从SecureCRT切换到它了,并且没有回头
alexeit 2012年


2

我尝试了许多解决方案,例如SSH隧道管理器,但对我而言都不方便:太多的配置屏幕,有时甚至有问题(一次SSH隧道管理器清除了我所有的设置!所以我必须还原所有30个隧道的设置)。所以他们都失去了我的信任。这就是为什么我提出了自定义Powershell脚本的原因,该脚本易于配置,可更改,较小,但是可以运行。发表在这里和下面:

要开始使用它,您需要这样的配置:

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

将其另存为config.csv。使用powershell脚本来保持它是:

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

配置完成后,就可以像这样运行它:

powershell -File autossh.ps1

1

如果您是Putty的粉丝,请尝试Putty Tray

它具有一些其他功能,包括尝试在连接失败后自动重新连接以及在计算机从待机状态唤醒时重新连接。

正如其他人已经提到的那样,我将其与无密码短语的公钥身份验证结合使用。

从理论上讲,这应该是非常可靠的,但是我不是安全专家,所以不能在这方面为您提供建议。


0

我用它搜索了一下,并得到了一些关于您的问题的结果,基本上,您总是可以尝试使用搜索组合automate putty login。这是一个特别有用的结果,应该适合您:

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

它带您逐步了解如何设置腻子。还可以在此处下载Putty连接管理器(因为该链接已从初始链接断开):

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


PuttyCM的SourceForge链接已损坏。看到这个问题
Craig McQueen

@CraigMcQueen,您知道这是在2011年1月19日得到答复的吗?对?
雅各布2012年

1
是的,我知道。我昨天在Google搜索中找到了它,其他人可能会在未来一两年内找到它。
克雷格·麦奎因

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.