SSHのControlPathにIPv4とIPv6を区別させる方法は?

SSHのControlPathにIPv4とIPv6を区別させる方法は?

私はそれを使用しています

ControlMaster   auto
ControlPath     ~/.ssh/tmp/%l_%r@%h:%p

内部では、~/.ssh/configSSHを介してホストにアクセスすると、同じ接続を使用して複数のセッションが開きます。

これはほとんどのユースケースでうまく機能しますが、IPv4とIPv6を介して同時に同じホスト名に接続することはできません。他のすべての接続はIPv4とIPv6をControlPath区別できないため、最初の接続で作成された制御ソケットを使用します。 IPv6接続。

IPv4およびIPv6接続に別々の制御ソケットを提供する方法はありますか(おそらく、ソケットパスでリモートホスト名の代わりにリモートIPを使用する方法を見つけること)。


編集#1

Match私はちょうどファイルで利用可能なオプションを覚えて、次のことを試しました。ssh_configsshd_config

Match AddressFamily inet
    ControlPath     ~/.ssh/tmp/%l_%r@%h:%p.inet

Match AddressFamily inet6
    ControlPath     ~/.ssh/tmp/%l_%r@%h:%p.inet6

残念ながら、これは失敗します。」一致プロパティ AddressFamily はサポートされていません。「ホストに接続しようとすると、もう一度原点に戻ります...

答え1

これは一般的なユースケースではないため、これを行う直接的な方法はありません。ただし、あまりにも多くのリモートホストが必要ない場合は、ユーザープロファイルを使用してこの問題を解決できます。

Host hostname-4
    Hostname hostname
    AddressFamily inet
    ControlPath ~/.ssh/master4-%l%h%p%r
Host hostname-6
    Hostname hostname
    AddressFamily inet6
    ControlPath ~/.ssh/master6-%l%h%p%r

答え2

「ラッパー」と「パッチ」の方法を個別に承認/反対投票できるように、私の回答を2つの個別の回答に分けました。

解決策1:ラッパー関数の作成

ssh ()
{
    controlpath=""
    for argument in $@
    do
        if [[ "$argument" = "-"*"4"* ]]
        then
            controlpath="~/.ssh/tmp/%l_%r@%h:%p.inet"
        fi
        if [[ "$argument" = "-"*"6"* ]]
        then
            controlpath="~/.ssh/tmp/%l_%r@%h:%p.inet6"
        fi
    done

    if [ -n "$controlpath" ]
    then
        /usr/bin/ssh -o "ControlPath=$controlpath" $@
    else
        /usr/bin/ssh $@
    fi
}

sshこのラッパー関数は、およびに別々の制御ソケットを生成するように指示します。このような内容を正しく解析することはできませんが(技術的に許容される場合でも)、単純なシナリオに対する最も簡単な解決策である必要があります。ssh hostssh -4 hostssh -6 host
ssh -464466 host

答え3

「ラッパー」と「パッチ」の方法を個別に承認/反対投票できるように、私の回答を2つの個別の回答に分けました。

解決策2:ソースを使用して、ルーク!

私の答えの更新で述べたように、OpenSSHはMatch AddressFamily-しかし、。構文解析時に
その句を追加するのは非常に簡単です。Matchconf.cを読む。私の概念証明パッチは機能しますが、ハードコーディングされた文字列がたくさん含まれているので、考慮するためにOpenSSHメンテナンス担当者に送信する前に、より多くの作業が必要です。

%aControlPathたとえば、計算結果をany、またはとして定義するために別のプレースホルダを追加できない場合は、使用されている住所系列に応じてinet見てみることができます。ただし、オプションが評価され保存される順序inet6によっては問題が発生する可能性があるため、この機能を機能させるにはかなり広範な変更が必要になる場合があります。
プレースホルダーを接続に使用される実際のアドレスファミリに拡張したい私の元のアイデアにも同じ問題があります。アドレスファミリは、適切な制御ソケットが存在しても発生しないコールに依存します。AddressFamilyControlPath
gethostbyname()

関連情報