SSH の各ホストに 2 つの異なる IP アドレスを使用します。

SSH の各ホストに 2 つの異なる IP アドレスを使用します。

gamma私は職場で継続的に実行されているサーバーを持っています。時には自宅で接続しますが、この場合はパブリックIPアドレスを使用します55.22.33.99。時には職場でパケットが不必要にバウンスされるのではなく、ローカルIPアドレスを介して接続されます192.168.1.100

現在、私はそれらを2つの異なる項目に分けています。~/.ssh/conf

Host gamma-local
        HostName 192.168.1.100
        Port 22
        User andreas

Host gamma-remote
        HostName 55.22.33.99
        Port 12345
        User andreas

したがって、職場にいる場合はを入力しssh gamma-local、家にいる場合は(または世界のどこでも)を実行しますssh gamma-remote

サーバーに接続するときは、場所に応じて別の名前を入力する必要はなく、その部分を自動的に実行したいと思います。たとえば、場合によっては、そうでない人をリンクする自動化されたスクリプトがあります。私がどこにいるか知っています。

持つこの問題を解決するには、Bash スクリプトを使用します。まず、ローカルで接続を「試行」して接続できない場合は、リモートIPアドレスに接続してみてください。これは問題ありませんが、(1)非効率的なようです(特に常にエラーをすぐに再送信するわけではないため、接続がタイムアウトするまで「待機」する必要があるため)。 (2) Bashとスクリプトのドラッグが必要です。

Bashスクリプトを使用しない場合、または接続が最初に機能するかどうかを「テスト」せずにこれを達成する別の方法はありますか?

答え1

現在接続されているネットワークを識別する方法がある場合は、Matchキーワードを使用できます。~/.ssh/configあなたが欲しいものをしてください。これにはOpenSSH ≥6.5が必要です。

私は次のようなものを使用します

Match originalhost gamma exec "[ x$(/sbin/iwgetid --scheme) != xMyHomeESSID ]"
  HostName 192.168.1.100
  Port 22

Host gamma
  User andreas
  Port 12345
  HostName 55.22.33.99

だから私はSSH接続のために自宅にいることを確認するために使用しているWi-Fiネットワークの識別子を使います。ただし、コンピュータに割り当てられているIPアドレスまたは2つのネットワークを区別できる他のものを確認することもできます。

答え2

職場にプライベートネームサーバーがあり、職場と自宅で同じラップトップを使用している場合は、次の目的で利用できます。

  1. nsswitch.confDNSを最初に確認するようにコンピュータを変更してください
  2. gamma192.168.1.100 として確認されるように、オフィスのプライベート DNS に DNS エントリを作成します。
  3. gamma55.22.33.99と確認されるように、コンピュータの/ etc / hostsファイルにエントリを作成します。

これにより、ssh gammaオフィスにいるときはオフィスDNSで192.168.1.100と確認され、自宅で接続するとホストファイルで55.22.33.99と確認されます。

ポリスチレン:この答えは、ガンマがパブリックDNSエントリを持つことを望まないと仮定しています。また、WindowsシステムからサーバーにSSHを接続している場合は、ホストファイルエントリを上書きするにはnssswitch.confファイルと同等のファイルが必要です。

答え3

数年前に私が書いたことがあります。プログラム同様の目的で。これはあなたのニーズに適している可能性があります。このプログラムを使用すると、SSH 構成は次のようになります。

Host gamma
    ProxyCommand ssh-multipath-proxy 192.168.1.100:22 55.22.33.99:12345
    User andreas

答え4

~/.ssh/configIPアドレスをホスト名として使用する場合は不可能です。他のIPアドレスだけでなく、他のポートにも接続するという事実は、DNSリゾルバの調整をほとんど排除するので、追加の複雑さをもたらします。

Match originalhost ... exec ...修正しました - 組み合わせが利用可能です~/.ssh/config- 参照@MichałPolitowskiの返信。しかし、OpenSSHでは完全に動作しますが、他のSSHクライアントでは同様の機能を必ずしも見つけることはできません。

ssh現在のネットワークを確認し、適切なエントリを使用する単純なラッパー(さまざまなシェルで使用する必要がある場合はシェル関数またはスクリプト)を使用してこの問題を解決できますHost。最大の問題は、現在使用されているネットワークを確実に検出できることです。ローカルIPアドレスを考えますが、会社のネットワークと同じサブネットを使用してLANから接続している可能性が高いため、これは信頼できません。

ローカルネットワークとリモートネットワークの両方で同じポートを使用できる場合は、/etc/resolv.conf現在使用しているネットワークに合わせて編集できます。もちろん、自動的に実行する必要があります(通常はDHCPクライアント用のフックスクリプトを介して)。または - より良い - ローカルネームサーバーを実行します(例:dnsmasq) 適切な構成を提供します。しかし、これはこの質問の範囲外です。

別のオプション(対話型接続のみが必要な場合)は、スキャン可能なコマンド補完機能を使用することです~/.ssh/config。これにより、入力時間が節約されます(特に入力内容が十分に多い場合Host)。次のもの(bash初期化用):

# complete session names for ssh
declare -g _ssh_complete_hostlist 2> /dev/null
function _ssh_complete_init () {
    _ssh_complete_hostlist=$( \
        sed -nr '/^\s*Host\s*=/{s/^[^=]+= *//;s/ /\n/g;p}' ~/.ssh/config \
        | sort )
}
_ssh_complete_init

function _ssh_complete () {
    local match=${COMP_WORDS[${COMP_CWORD}]}
    local hosts=
    local default=
    for h in $_ssh_complete_hostlist; do
        if [[ $h =~ ^$match ]]; then
            hosts="$hosts $h"
        fi
    done
    if ! (( ${COMP_CWORD} == ${#COMP_WORDS[@]}-1 )); then
        default=$( compgen -f ${COMP_WORDS[${COMP_CWORD}]} )
    fi
    COMPREPLY=($hosts $default)
}
complete -F _ssh_complete ssh

最初の関数はホスト完了リストを生成し(通常は各シェルで一度だけ実行するだけで十分です)、2番目の関数はやや不器用ですが実際の完了を実行します。ホスト名が次の場合にのみホスト名を入力します。コマンドラインの最後のトークンです。

要約すると、この問題を解決する正しい方法は、VPNを介して会社のネットワークに接続して、オフィスと同様にローカルの会社のIPアドレスにアクセスできるようにすることです。その後、必要なレイヤー~/.ssh/configまたは/etc/resolv.conf(IMHOが最良のオプション)オフィス名サーバーにアドレスを直接接続できます。

関連情報