WSL 2 SSHへのポート転送を設定するスクリプトが失敗する

WSL 2 SSHへのポート転送を設定するスクリプトが失敗する

以前は SSH スクリプトを使用して IP を 127.0.0.2 に設定することで接続できましたが、今では起動するたびに機能しなくなりました。理由はわかりません。localhost または 127.0.0.1 を試しましたが、機能しません。localhost の Web サイトにはアクセスできます。WSL2 をホストしている自分のマシンで、SecureCRT を介して接続できるポート番号と IP を取得するにはどうすればよいですか?

try {
## Port forward WSL virtual machine ports to host firewall for remote access
## !! this script must be run as Administrator !!
##  powershell -executionpolicy bypass -file "c:\docker\WSL-portproxy.ps1"

## ip -o -4 -f inet addr show eth0 | awk '{ split($4, ip_addr, "/"); print ip_addr[1]; }'
##   print out is "4:  eth0  inet  172.20.x.x/20  brd  ..." string
$remoteport = bash.exe -c "ip -o -4 -f inet addr show eth0";
$remoteport = ($remoteport -split "\s+")[3];
$remoteport = $remoteport.substring(0, $remoteport.LastIndexOf("/"));
$found      = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if(!$found){
  echo "WSL ip address not found";
  exit;
}
echo "WSL ip address $remoteport";

# Port forwards from WSL virtual machine to Win10 host firewall
# Bind a specific host ip addr or use 0.0.0.0 default
$ports=@(2222);
$addr='127.0.0.2';

# Remove firewall exception rules, add inbound and outbound rules
$ports_a = $ports -join ",";
echo "Firewall inbound/outbound rules";
iex "Remove-NetFireWallRule -DisplayName 'WSL Firewall Unlock' ";
iex "New-NetFireWallRule -DisplayName 'WSL Firewall Unlock' -Description 'Remote access to WSL services' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL Firewall Unlock' -Description 'Remote access to WSL services' -Direction Inbound  -LocalPort $ports_a -Action Allow -Protocol TCP";

for( $i = 0; $i -lt $ports.length; $i++ ){
  $port = $ports[$i];
  echo "portproxy ${addr}:${port} to ${remoteport}:${port}";
  iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
  iex "netsh interface portproxy add    v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

    # Do your script's stuff
}
catch
{
    Write-Error $_.Exception.ToString()
    Read-Host -Prompt "The above error occurred. Press Enter to exit."
}

これを使用して設定できましたが、動作しなくなりました。

次のエラーが発生します:

C:\Users\admin\Downloads\f.ps1 : System.Management.Automation.RuntimeException: You cannot call a method on a
null-valued expression.
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception
exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
At line:1 char:91
+ ... tionPolicy -Scope Process Bypass }; & 'C:\Users\admin\Downloads\f.ps1'
+                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,f.ps1

答え1

WSL2 をホストしている自分のマシンで SecureCRT 経由で接続できるポート番号と IP を取得するにはどうすればよいですか?

おそらく私はあなたの質問を大きく誤解しているかもしれませんが、これはすべきである非常に簡単で、スクリプトはまったく必要ありません。

接続する場合:

  • からWSL2をホストするマシン上のSecureCRT
  • そのマシン上のWSL2インスタンス

WSL2は「ローカルホスト転送」と呼ばれる機能を提供します(ビルド18945以降、このウェブサイト

あなたが使用しているスクリプトは、どうやら非常に古いようです。もう必要ないというだけでなく、数年前にbash.exeもっと柔軟なコマンドに取って代わられたコマンドを使用しているからですwsl.exe。しばらくの間、Microsoftはこれをbash.exe「歴史的なコマンド」としてリストしていましたが、最新のドキュメントでは非推奨と表示されている

とにかく、あなたの核心的な質問に関しては、WSL ドキュメント:

Linux ディストリビューションでネットワーク アプリ (NodeJS または SQL サーバー上で実行されるアプリなど) を構築している場合は、通常どおり localhost を使用して Windows アプリ (Edge や Chrome インターネット ブラウザーなど) からアクセスできます。

ただし、古いバージョンの Windows (ビルド 18945 以下) を実行している場合は、Linux ホスト VM の IP アドレスを取得する (または最新の Windows バージョンに更新する) 必要があります。

これは「アプリの構築」だけでなく、SSH などの既存のアプリ/サービスにも当てはまります。

つまり、localhostWindows でポートに接続しようとしたときに、そのポートが Windows 自体のアプリ/サービスによってバインドされていない場合は、自動的に WSL2 のそのポート (同じネットワーク スタックを共有しているため、すべてのインスタンス) への接続を転送しようとします。

つまり、WSL2インスタンスがポート2222でSSHを実行している場合、すべきlocalhost:2222追加の作業なしで、SecureCRT からに接続できるようになります。

これにはいくつかの理由がある。ない仕事:

  • %userprofile%\.wslconfigファイルがある場合ローカルホスト転送明示的に設定するfalse(可能性は低い)

  • ローカルホスト転送は、Windows が休止状態になると機能しなくなることが知られています。休止状態は、Windows のデフォルトである「高速スタートアップ」オプションによって、知らないうちにトリガーされることもあります。Stack Overflowでの私の回答詳細については。

それ以外は(また)すべき複雑な転送スクリプトなしで動作します。

関連情報