【问题标题】:How do you open an SSH Tunnel from a Windows client as a background program?如何从 Windows 客户端打开 SSH 隧道作为后台程序?
【发布时间】:2008-11-23 12:50:04
【问题描述】:

我希望 Win 机器在机器启动时通过隧道连接到 SSH 服务器。我还希望 win 机器在 SSH 程序崩溃时重新启动它。 SSH程序越轻量级越稳定,我越开心。

我有什么选择?

【问题讨论】:

    标签: windows ssh


    【解决方案1】:

    查看使用 srvany 将 SSH 客户端作为 Windows 服务启动。然后您可以将服务设置为在 Windows 启动时自动启动。

    本质上,srvany.exe 可以让您从 Windows 服务控制管理器启动任何程序。

    http://support.microsoft.com/kb/137890

    【讨论】:

    【解决方案2】:

    PuTTY suite 可能是您最好的选择,IMO。 (免责声明:我有偏见,因为 Simon Tatham 是我的大学朋友。请注意,这意味着我知道他是多么细致......)

    【讨论】:

    • 乔恩·斯基特很棒。 PuTTY 只是一个软件程序
    【解决方案3】:

    如果您希望在断开连接的情况下重新启动程序,我所知道的最好的应该是软件推荐:AlwaysUp(2015 年 5 月不免费)。

    它仍然是轻量级、4.2MB 安装程序和不太大的内存消耗

    C:\>tasklist | find "always" /i
    AlwaysUp.exe                  3112 Console                    1    17.388 KB
    

    当转换为服务时,SrvAnySC稳定性(或只是使服务正常工作)可能是一场噩梦。 AlwaysUp,只要我进行了测试,就可以解决大多数问题,并为您提供额外选项,例如详细的日志、统计信息、电子邮件警报……等等。

    【讨论】:

      【解决方案4】:

      PuTTy 无疑是最佳选择,但它不支持自动重启。我个人经常使用 ssh 隧道,我有 30 多个隧道。我想要一个可以轻松配置和维护的脚本,所以我想出了一个 PowerShell 脚本。发布here。 SO 规则也要求我在答案中发布解决方案,很高兴这样做:

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

      # 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
      

      【讨论】:

        猜你喜欢
        • 2016-01-15
        • 2015-04-02
        • 2017-11-12
        • 2011-05-20
        • 1970-01-01
        • 2021-04-12
        • 2016-02-17
        • 2021-05-11
        • 1970-01-01
        相关资源
        最近更新 更多