web-dev-qa-db-ja.com

トラフィックの半分が失われる2つのNIC上の同じIP

少し壊れた科学機器に接続されたマシンがあり、問題を回避しようとしています。リンクはポイントツーポイント、2x25Gイーサネットであり、他のデバイスは関係しません。デバイスはインターフェイスごとに1つのストリームでUDPデータをストリーミングし、宛先IPアドレスとMACアドレスを構成できますが、デバイスの送信元IPアドレスは両方のインターフェイスで同じです。 tcpdumpを使用すると、トラフィックが両方の正しい宛先IPとMAC​​アドレスを使用して適切なインターフェイスに到着していることがわかります。

ただし、一方のIPでのみリッスンしてデータを取得できます。もう一方のIPでリッスンした場合、トラフィックはありません。カーネルは明らかにトラフィックをドロップしており、その理由も、これをデバッグする方法もわかりません。

マシンはubuntu18.04、IP 10.50.5.1/16および10.50.5.129/16を実行しています。デバイスのIPは10.50.1.10です。ルート:

10.50.0.0/16 dev data0 proto kernel scope link src 10.50.5.1 
10.50.0.0/16 dev data1 proto kernel scope link src 10.50.5.129

助言がありますか?

Netstatでパケットがドロップされていないことがわかりますが、どこに行きますか?

Kernel Interface table
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
data0     9600   202320      0      0 0            29      0      0      0 BMRU
data1     9600   203600      0      0 0            31      0      0      0 BMRU
1
Zotan

2つの異なるインターフェースとルートを使用して同じ宛先に到達しようとすると、ルーティングの問題が発生します。デフォルトでは、ルーティングは送信元ごとではなく、宛先ごとに実行されます。デフォルトでは、 弱いホストモデル を使用するLinux(ただし、Ubuntuはリバースパスフィルターも設定します。後述)は同じインターフェイスを選択します。つまり、リストの最初に表示される同等の候補の中の1つです。したがって、ここでは、送信元IPアドレス10.50.5.1と10.50.5.129の両方がdata0を使用して10.50.1.10に到達します。これは、現在、2つの等しいアドレスの中で最初のものであるためです。ルートエントリで。

それ以外の場合は、Linuxでソースベースのルーティング(別名 ポリシールーティング )が必要です。宛先へのルートを決定するためにソースも使用する必要があります。

同様の理由で、現在の構成では、同じIP LAN(10.50.0.0/16)に2つのIPアドレスがあります。Linuxは、任意のMACアドレスを使用して任意のインターフェイスからLAN内のARPクエリに応答します。結局、リクエストを行うのではなく永続的なARPエントリを使用するデバイスを使用したセットアップの場合を除いて、通常は1つのインターフェイスのみがすべての着信トラフィックを受信します(「間違った」インターフェイスである場合もあります)。

そして最後のストローは、機器が正しいIPアドレスの宛先を使用して正しいインターフェースに送信している場合でも、Ubuntuのデフォルトでは Strict Reverse Path が有効になっており、「間違った」インターフェースで受信したパケットをドロップします。これがデータを見逃す理由です。インターフェイス(最新のip -statistics linkコマンドを試してください)はデータを受信しましたが、ルーティングスタックはすぐにデータを削除しました。これを確認するには、カーネルのルーティングスタックにIPパケットの送受信についてどう思うかを尋ねるだけです。

  • 送信

    # ip route get from 10.50.5.1 10.50.1.10
    10.50.1.10 from 10.50.5.1 dev data0 uid 0 
        cache 
    # ip route get from 10.50.5.129 10.50.1.10
    10.50.1.10 from 10.50.5.129 dev data0 uid 0 
        cache 
    

    どちらもdata0を使用して送信され、data1は無視されます。

  • 受信

    # ip route get from 10.50.1.10 iif data0 10.50.5.1
    local 10.50.5.1 from 10.50.1.10 dev lo table local 
        cache <local> iif data0 
    # ip route get from 10.50.1.10 iif data1 10.50.5.129
    RTNETLINK answers: Invalid cross-device link
    

    data1での受信は、厳密なリバースパスフィルターによって禁止されています。

リバースパスを無効にすることもできますが、特定のインターフェイスで送信する必要がある場合は、とにかく役に立ちません。

以下に、よりクリーンな方法を提案します。


まず、ARP設定(および "ARPフラックス" の考慮事項)と混同する必要をなくすために、イーサネット経由で使用されている場合でも、ポイントツーポイントIPインターフェイスとして使用される2つのインターフェイスを検討してください。リンク層。したがって、/ 16LAN全体を使用する必要はありません。ポイントツーポイントルートだけで十分です。

# ip address flush dev data0
# ip address flush dev data1

# ip address add 10.50.5.1 peer 10.50.1.10/32 dev data0
# ip address add 10.50.5.129 peer 10.50.1.10/32 dev data1

上記の2つのコマンドは、ほとんどがip address add 10.50.5.N/32 dev dataX; ip route add 10.50.1.10/32 dev dataXのショートカットです。

/ 16ネットワーク設定を保持することを選択することもできます(たとえば、最終的にそれらが背後にある機器のファームで実際のLANの使用に使用される場合)、これには切り替えも必要になります arp_filter=1 =安全側にとどまるためにインターフェース上。

ソースベースのルーティングの問題を解決するには:追加のルーティングテーブルを指すルールを使用します。これには、メインルーティングテーブルからの一部のルートの部分的なコピーが含まれます。これらのルーティングテーブルには任意の値1000と1001を選択します(必要がない場合でも、任意の固定ルール優先度10000 10001を使用します)。テーブル1000に関するすべてが実際には必要ではありませんが(デフォルトであるため)、とにかくクリーンです。

ip route add table 1000 10.50.1.10/32 dev data0 src 10.50.5.1
ip route add table 1001 10.50.1.10/32 dev data1 src 10.50.5.129

ip rule add pref 10000 from 10.50.5.1 lookup 1000
ip rule add pref 10001 from 10.50.5.129 lookup 1001

メインテーブルは、デフォルトで使用されるインターフェイスを決定します(おそらくdata0):特定のIPアドレスにバインドされていないツールはこれを使用します(したがって、 10.50.5.1)デフォルトとして、10.50.5.1にバインドする場合と同じ。ただし、10.50.5.129にバインドするツールはすべて、data1を使用して双方向トラフィックを適切に持つようになります。

# ip route get 10.50.1.10
10.50.1.10 dev data0 src 10.50.5.1 uid 0 
    cache 
# ip route get from 10.50.5.1 10.50.1.10
10.50.1.10 from 10.50.5.1 dev data0 table 1000 uid 0 
    cache 
# ip route get from 10.50.5.129 10.50.1.10
10.50.1.10 from 10.50.5.129 dev data1 table 1001 uid 0 
    cache 

そして今、data1の着信データはリバースパスフィルターによってドロップされません:

# ip route get from 10.50.1.10 iif data0 10.50.5.1
local 10.50.5.1 from 10.50.1.10 dev lo table local 
    cache <local> iif data0 
# ip route get from 10.50.1.10 iif data1 10.50.5.129
local 10.50.5.129 from 10.50.1.10 dev lo table local 
    cache <local> iif data1 

注意:

追加のルーティングテーブルは、カーネルではなく手動で入力されます。インターフェイスがダウンした場合(またはIPが削除された場合)、次にアップされた場合(またはIPが追加された場合)、対応するテーブル1000または1001がフラッシュされ、再入力されません。手動で追加し直す必要があります(または、これを実行できるネットワーク構成ツールを使用します)。

1
A.B