windows 反向SSH隧道监视器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/372462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:44:41  来源:igfitidea点击:

Reverse SSH tunnel monitor

windowssshmonitoringtunnel

提问by wburke

I've setup a reverse ssh tunnel, using PuTTY, to allow me to VNC into a home computer without having to enable NAT port forwarding. Works great, no problem.

我已经使用 PuTTY 设置了一个反向 ssh 隧道,以允许我将 VNC 连接到家用计算机,而无需启用 NAT 端口转发。效果很好,没问题。

I would like to set the tunnel up as a "persistent service" that will connect on boot up and reconnect when dropped. PS. this is on Windows.

我想将隧道设置为“持久服务”,它将在启动时连接并在掉线时重新连接。附注。这是在 Windows 上。

Exhaustive googling found a few products but many seem to have been abandoned and none appear to have major "street cred."

详尽的谷歌搜索发现了一些产品,但许多产品似乎已被放弃,而且似乎都没有主要的“街头信誉”。

Does anyone have experience with this type of thing or with any of these products? I don't need all the bells and whistles, just reliability.

有没有人有过这种类型的东西或这些产品的经验?我不需要所有的花里胡哨,只需要可靠性。

回答by Colin Pickard

wikipedia's comparison of ssh clientshas columns for tunnelling, SOCKS etc. may help you find something suitable

维基百科对 ssh 客户端的比较有关于隧道、SOCKS 等的列。可能会帮助您找到合适的东西

回答by Igal Serban

Have you considered using plink and making it a service with srvany?

您是否考虑过使用 plink 并将其作为srvany的服务?

回答by Simon B.

Use plink from PuTTY and run in a batch file. When connection really dies, plink will exit, which means that you can run plink in a loop.

使用 PuTTY 中的 plink 并在批处理文件中运行。当连接真的挂掉时,plink 会退出,这意味着您可以循环运行 plink。

Like this:

像这样:

  :: This is a batch file. Save with file name: plink_forever.bat
  :restart
  plink saved_session_name
  goto restart

And finally wrap that with srvany to get it to start on logon.

最后用 srvany 包装它以使其在登录时开始。

Or maybe easier: put the .bat in windows scheduler and set to run once on every boot.

或者更简单:将 .bat 放入 Windows 调度程序并设置为在每次启动时运行一次。

Docs: http://the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter7.html

文档:http: //the.earth.li/~sgtatham/putty/0.58/htmldoc/Chapter7.html

回答by Tony

I use ssh tunnels a lot, but all managers were not convinient to me (too many UI screens, not that stable). I wanted to have a script which can be easily cnfigurable and maintainable, so I came up with a PowerShell script for that. Posted here. SO rules dictates me to publish solution in answer as well, so happy to do that:

我经常使用 ssh 隧道,但所有的管理人员都不适合我(UI 屏幕太多,不太稳定)。我想要一个易于配置和维护的脚本,所以我想出了一个 PowerShell 脚本。贴在这里。SO 规则也要求我发布解决方案作为答案,很高兴这样做:

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:

将其另存为 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();
    }
  }
}

Then just run it with:

然后只需运行它:

powershell -File autossh.ps1

To start it automatically with windows boot please use windows scheduler.

要使用 Windows 引导自动启动它,请使用 Windows 调度程序。

回答by Tony

you can just set-up any application to start with windows and auto-connect your tunnel on startup. I personnally use Easytunnel... just checked the option to connect all tunnels on startup, and set-up windows to start Easytunnel on bootup. It works great, tho you'll need to set-up your server's inactivity timeout, or you will be disconnected every 10 minutes or so.

您可以设置任何应用程序以从 Windows 启动并在启动时自动连接您的隧道。我个人使用 Easytunnel ......刚刚选中了在启动时连接所有隧道的选项,并设置窗口以在启动时启动 Easytunnel。它工作得很好,但您需要设置服务器的不活动超时,否则您将每 10 分钟左右断开一次连接。

Hope you get it working!

希望你能成功!