web-dev-qa-db-ja.com

SSHクライアントが複数のネットワークインターフェースを持つSSHサーバーにフリーズ接続する

ケース1:SSHホストに1つのネットワークインターフェイスがある

ホストSSHのルーティングテーブル:

[SSH] $ ip route
default via 192.168.211.1 dev eth0
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119

SSH_ClientLAN_0からホストSSHへのssh接続を開始すると、スムーズに機能します。

[SSH_CLIENT] $ ssh [email protected] -p 22

ケース2:SSHホストに2つのネットワークインターフェイスがある

ホストSSHのルーティングテーブル:

[SSH] $ ip route
default via 192.168.0.1 dev eth1
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.113
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119

SSH_ClientからLAN_0上のホストSSHへのssh接続を開始すると正常に機能します。

[SSH_Client] $ ssh [email protected]

SSH_ClientからホストSSHへのssh接続を開始し、LAN_211で数秒間動作し、その後フリーズします。

[SSH_Client] $ ssh [email protected]
2
Chau Chee Yang

これは、Linuxで使用される weak Host model によって引き起こされる非対称ルーティングの場合です。ホストに属する任意のIPに任意のインターフェイスを使用できます。

  • ホストclientは、自身のLANの外部のアドレスにパケットを送信するため、pfSenseルーター経由でルーティングします。
  • ホスト[〜#〜] ssh [〜#〜]eth0で192.168.0.136から192.168.211.119へのパケットを受信します
  • ホスト[〜#〜] ssh [〜#〜]返信はルーティングテーブルに従うため、eth1を使用して返信しますclientを使用してソースIP 192.168.211.119:clientは接続が確立されたと見なします。
  • 推測:ルーターpfSense、これはトラフィックの半分のみを参照します(clientから[〜# 〜] ssh [〜#〜]、ただし[〜#〜] ssh [〜#〜]からclient)、ウィンドウ外のACKされていないTCPトラフィックを検出し、しばらくしてさらにパケットをドロップします。

ホスト[〜#〜] ssh [〜#〜]enabledStrict Reverse Path Forwarding があった場合、これは行われません[〜#〜] ssh [〜#〜]はLANからIPを持つすべてのパケットをドロップするため、現在の結果を考慮したほうがよいでしょう。 LAN 211のインターフェースで0を受信しました。

解決策は、ホスト[〜#〜] ssh [〜#〜]でポリシールーティングを使用して、このマルチホームLinuxシステムの動作を修正することです。 IPが割り当てられる側。これは、意図的に、メインテーブルの部分的な(そしておそらく単純化された)コピーのみが存在する追加のルーティングテーブルを作成することによって行われます。これにより、各テーブルは使用すべきでないインターフェイスを無視します。通常、これを機能させるために必要な追加のテーブルは1つだけですが、2つのテーブルで対称設計を使用する方がきれいです。

また、デフォルトルート(pfSenseを介して)がLAN 211固有のテーブルに追加されます。

次に、IPルールは、デフォルトでメインテーブルになる前に、これらのルーティングテーブルを呼び出します。

LAN 0とLAN 211の処理にそれぞれ任意に選択した値10000と10211のテーブルを使用してみましょう。

# ip route add table 10000 192.168.0.0/24 dev eth1
# ip route add table 10000 default via 192.168.0.1 dev eth1
# ip route add table 10211 192.168.211.0/24 dev eth0
# ip route add table 10211 default via 192.168.211.1 dev eth0

# ip rule add from 192.168.0.113 lookup 10000
# ip rule add from 192.168.211.119 lookup 10211

これで、選択するパスをカーネルに尋ねることにより、各ソースIPアドレスが正しいパスを使用することを確認できます。

# ip rule
0:      from all lookup local
32764:  from 192.168.211.119 lookup 10211
32765:  from 192.168.0.113 lookup 10000
32766:  from all lookup main
32767:  from all lookup default

# ip route get 192.168.0.136 from 192.168.0.113
192.168.0.136 from 192.168.0.113 dev eth1 table 10000 uid 0 
    cache 
# ip route get 192.168.0.136 from 192.168.211.119
192.168.0.136 from 192.168.211.119 via 192.168.211.1 dev eth0 table 10211 uid 0 
    cache 

[〜#〜] ssh [〜#〜]ホストは、2つのサイドからの接続を同時に受け入れることができます。2つのIPアドレスのそれぞれへの接続でも、正しいインターフェース。

補足として、IPアドレスがソケットにまだバインドされていない場合、これらのルールは一致しません(例:ホストから開始された送信接続[〜#〜] ssh [〜#〜]標準クライアントとして)。 mainテーブルは引き続き使用されます。

# ip route get 192.168.0.136
192.168.0.136 dev eth1 src 192.168.0.113 uid 0 
    cache 

特定のシステムで使用しているネットワークマネージャーにこれらの設定を統合する方法を理解する必要があります。多くの場合、配布やツールに依存します。 IPアドレスが削除された(その後追加された)か、インターフェースがダウンした(その後、アップした)場合、テーブル10000および10211がフラッシュされます。これらのイベントが発生した後は、カーネルがLANルートを自動的に処理するメインテーブル(ただし、デフォルトルートはまだです)。

セットアップが修正されたので、おそらく、原則として、厳密なリバースパス転送を有効にするときです(以前に値が0ではなく2に設定されている場合は、最後の2つのコマンドが必要です: rp_filter は、高い値が低い値を克服することを示します):

# sysctl -w net.ipv4.conf.all.rp_filter=1
# sysctl -w net.ipv4.conf.eth0.rp_filter=1
# sysctl -w net.ipv4.conf.eth1.rp_filter=1
2
A.B