サーバーがpingに応答しない - ICMPが受信されましたが何も起こりません

サーバーがpingに応答しない - ICMPが受信されましたが何も起こりません

2つの異なるサブネットに接続されている2つのインターフェースを持つサーバーがありますdhcp。これら2つの異なるサブネットは、2つの異なるインターフェイスを介して同じスイッチに接続されます。

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
23: enp10s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether c4:00:ad:a4:e3:38 brd ff:ff:ff:ff:ff:ff
    inet 192.168.201.232/24 brd 192.168.201.255 scope global enp10s0
       valid_lft forever preferred_lft forever
25: enp11s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether c4:00:ad:a4:e3:39 brd ff:ff:ff:ff:ff:ff
    inet 192.168.203.3/24 brd 192.168.203.255 scope global enp11s0
       valid_lft forever preferred_lft forever
    inet6 fe80::c600:adff:fea4:e339/64 scope link 
       valid_lft forever preferred_lft forever

路線:

# ip r
default via 192.168.201.1 dev enp10s0 
192.168.201.0/24 dev enp10s0 proto kernel scope link src 192.168.201.232 
192.168.203.0/24 dev enp11s0 proto kernel scope link src 192.168.203.3 

まず、ノートブックでpingを実行して、そのデバイスのtcpdumpを介して要求と応答を192.168.201.232表示できます。icmp

# tcpdump -s 0 -i any -vvv -nn 'host 192.168.1.30 and not port 22'
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:42:05.240967 IP (tos 0x0, ttl 62, id 53809, offset 0, flags [none], proto ICMP (1), length 84)
    192.168.1.30 > 192.168.201.232: ICMP echo request, id 55768, seq 1, length 64
11:42:05.240994 IP (tos 0x0, ttl 64, id 42288, offset 0, flags [none], proto ICMP (1), length 84)
    192.168.201.232 > 192.168.1.30: ICMP echo reply, id 55768, seq 1, length 64

pingを実行しても192.168.203.3応答がありません。 tcpdump 出力は次のようになります。

# tcpdump -s 0 -i any -vvv -nn 'host 192.168.1.30 and not port 22'
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:43:57.037535 IP (tos 0x0, ttl 62, id 19363, offset 0, flags [none], proto ICMP (1), length 84)
    192.168.1.30 > 192.168.203.3: ICMP echo request, id 55808, seq 1, length 64
11:43:58.060756 IP (tos 0x0, ttl 62, id 19364, offset 0, flags [none], proto ICMP (1), length 84)
    192.168.1.30 > 192.168.203.3: ICMP echo request, id 55808, seq 2, length 64

このパケットはどうなりますか?
なぜicmp答えがないのですか?私のIPは次のよ​​うなので、応答がデフォルトのgw()に移動したいと
思います。icmp192.168.201.1192.168.1.30

何もなくiptables、ステッドも上がりませんnetstat -s

DHCPを削除しましたが、インターフェイスにenp10s0IPが付与されていないため、ルートは1つだけ残ります。

# ip r
default via 192.168.203.1 dev enp11s0 
192.168.203.0/24 dev enp11s0 proto kernel scope link src 192.168.203.3 

私のラップトップからpingを送信すると動作192.168.203.3します。

ベストアンサー1

常に追加のルーティングの複雑さが発生するマルチホームサーバーがあります。

ネットワークは多少複雑な場合がありますが、次のように見えます。

                  ┏━━━━━━┓
                  ┃laptop┃
                  ┗━━━━━━┛
               192.168.1.30/24
                    lan1
               192.168.1.1/24
                 ┌─────────┐
                 │ clients │
                 │ router  │
                 └─────────┘
                   x.x.x.x
                   y.y.y.y 
                 ┌─────────┐
  192.168.201.1/24 servers 192.168.203.1/24
   ╭┄┄┄┄┄┄┄┄┄┄┄┄┄│ router  │┄┄┄┄┄┄┄┄┄┄┄┄┄╮
   ┆             └─────────┘             ┆
   ┆                                     ┆
 lan201                               lan203
   ┆                                     ┆
   ┆             ┏━━━━━━━━━┓             ┆
   ╰┄┄┄┄┄┄┄┄┄┄┄┄┄┃         ┃┄┄┄┄┄┄┄┄┄┄┄┄┄╯
192.168.201.232/24  server 192.168.203.3/24
                 ┃         ┃
                 ┗━━━━━━━━━┛

パケットが無視されるのはなぜですか?

問題は、「なりすまし保護」という機能が有効になっているサーバーによって発生した可能性があります。厳格なリバースパスの転送(SRPF).つまり、着信パケットは、応答が同じインターフェイスを使用して再ルーティングされる場合にのみインターフェイスを通過できます。

両方のインターフェイスが設定され、デフォルトパスが192.168.201.1を使用し、ノートブックで192.168.201.232をpingすると、パケットは「左パス」を介してサーバーに移動し、「左パス」を介してサーバーから返されます。サーバーは、カーネルにルーティング決定が何であるかを尋ねることができます。

ラップトップに行く方法:

# ip route get from 192.168.201.232 192.168.1.30
192.168.1.30 from 192.168.201.232 via 192.168.201.1 dev enp10s0 uid 0 
    cache 

使用enpu10s0

私たちは同じ着信パケットを持っています(enpu10s0)これがサーバーのルーターが何をするのかを知っているからです。

# ip route get from 192.168.1.30 iif enp10s0 192.168.201.232
local 192.168.201.232 from 192.168.1.30 dev lo table local 
    cache <local> iif enp10s0 

発信パケットと同じ側にあるため、着信パケットが許可され、ローカルシステムにルーティングされます。

192.168.203.3をpingすると、パケットがルーティングされ、「正しいパス」に移動し、サーバーのルーティング構成はサーバーを「左パス」に置くようにマークされます。これは非対称パスであり、以前のSRPF検査に失敗しました。別のインターフェイスです。

この状況の決定をカーネルに再要求することができます。応答(存在する場合)は、次のようにルーティングされます。

# ip route get from 192.168.203.3 192.168.1.30
192.168.1.30 from 192.168.203.3 via 192.168.201.1 dev enp10s0 uid 0 
    cache 

デフォルトパスを使用するためenpu10s0、受信データパケット:

# ip route get from 192.168.1.30 iif enp11s0 192.168.203.3
RTNETLINK answers: Invalid cross-device link

着信インターフェイスのためにSRPFによって拒否されました。enpu11s0発信インターフェイスと一致しません。enpu10s0このIPアドレスに応答するために使用されます。

「左パス」を無効にしてデフォルトパスを変更し、「右パス」からDHCPのデフォルトパスを継承すると、すべてが次に変更されます。enpu11s0再び動作します。

どのように機能させるのですか?

  • あまり役に立たないかもしれないもの

    システムに通知できます。障害を負う確認するか安心到着する緩いリバースパスの転送。存在するデフォルトパスの場合、両方の効果は似ていますが(つまり、まったく効果が大きくはありません)、Linuxでこれを軽減する(設定2)ことは、有効にしたときに無効にする(0に設定する)よりも面倒です。このため、他の場所では簡単にこの構成では、最大の値が勝ちます。。システムの起動時に有効にすることができます。/etc/sysctl.d(YMMV)そこから編集できます。だから:

    sysctl -w net.ipv4.conf.enp11s0.rp_filter=2
    

    以前のクエリはもはや失敗しません。

    # ip route get from 192.168.1.30 iif enp11s0 192.168.203.3
    local 192.168.203.3 from 192.168.1.30 dev lo table local 
        cache <local> iif enp11s0 
    

    今2つのtcpdumpがあります。各サーバーインターフェイスに1つずつ着信パケットを表示できる必要があります。enpu11s0と発信応答enpu10s0

    ラップトップが応答を受信すると、作業は完了し、1日で通話できます。

    おそらくそうではありません。パスに沿って次のネットワーク要素であるサーバーのルーター返品SRPFを実装します。あるいは、ファイアウォールとしても使用でき、192.168.201.0/24のパケットのみを許可するインターフェイスからのパケット192.168.203.3を疑わしいと見なすことができます(SRPFの目標でもある偽装防止保護)。したがって、パケットは1ステップ後に廃棄される可能性が高くなります。

  • 仕組み:ポリシールーティング

    マルチホーミングが含まれるたびに、ポリシーベースのルーティング使用する必要があります。これにより、決定セレクタとして、宛先アドレスだけでなく、さまざまなその他の基準(最も一般的にはソースアドレス)を使用してルーティングを選択できます。これにはソースアドレスも必要です。 Linuxでは、追加のルーティングテーブル(通常はターゲットをセレクタとして使用)を使用し、ルールを使用して適切なルーティングテーブルを選択します(ここではソースをセレクタとして使用)。設定はソースアドレスに依存するため、DHCPなどの動的環境に統合することは困難です。確かに可能ですが、デーモンは次のようになります。dhクライアントまたはネットワーク管理者それぞれにスクリプトに挿入する独自のフックセットがあり、静的IPアドレス設定を使用してこれらのアドレスをDHCPサーバーに予約して宣言することで時間を節約できます。

    基本表へのパスは、追加表に部分的にコピーする必要があります。サーバーがルーターでもある場合(たとえば、LXC、Docker、VMの実行など)、より多くのパスを考慮する必要があり、他のルーティングテーブルにコピーすることもできます。もちろん、これらのパスが動的(コンテナの実行中に表示される)の場合、構成はより複雑になります。いつものように、ip route getここにはたくさんの助けがあります。

    したがって、各エンドに対してルーティングテーブルを作成し(このテーブルにはランダムではない値201と203を使用します)、このエンドに関して必要なものだけをコピーします。追加デフォルトパスの1つです。それでも、デフォルトのパスは 1 つしか使用できませんが、パステーブルごとに 1 つしか使用できません。ここにデフォルトルートを追加するだけでルーティングの問題を解決できます(実際にはルーティングテーブル203のみが必要です)。レイアウトが変更された場合(パスコンテナなど)、以前に追加する必要がないと思われたパスを再検討する必要があります。また、常に使用されていなくても、デフォルトのルートはデフォルトのルーティングテーブルに保持する必要があります。これが「デフォルト」のデフォルトパスになります。デフォルトパスは、ソースIPアドレスが定義されていない状態でサーバーがクライアントに接続されたときの自動選択に影響します。

    ip route add table 201 default via 192.168.201.1
    ip route add table 203 default via 192.168.203.1
    

    ソースベースのルールを使用して選択します。

    ip rule add from 192.168.201.232 lookup 201
    ip rule add from 192.168.203.3 lookup 203
    

    結果:

    # ip route get from 192.168.203.3 192.168.1.30
    192.168.1.30 from 192.168.203.3 via 192.168.203.1 dev enp11s0 table 203 uid 0 
        cache 
    

    アウトバウンドインターフェイスが次に切り替わります。enpu11s0ルーティングテーブル203を使用する。

    # ip route get from 192.168.1.30 iif enp11s0 192.168.203.3
    local 192.168.203.3 from 192.168.1.30 dev lo table local 
        cache <local> iif enp11s0 
    

    したがって、同じインターフェイスから着信パケットは同じインターフェイス(SRPF)に失敗しません。

    サーバールーターが複雑になりません。ノートブックのpingは両方のアドレスで動作します。

    サーバーで送信元アドレスを選択できるクライアントアプリケーションは、トラフィックが選択したパスを間接的に変更します(たとえば、通常はcurl --interface 192.168.203.3 192.168.1.30変更ping -I 192.168.203.3 192.168.1.30ping -I enp11s0 192.168.1.30ません)。ただこの設定の理由は、ここで詳しく説明されています。SF Q&A私)それはうまくいくでしょう。


注:UDPサービス

上記の最後の項目の構成により、TCPサービスが正常に機能します。しかし、BSDソケットAPIがデフォルトで動作する方法のため、UDPには十分ではありません。

受信TCPソケットがすべてのアドレス(INADDR_ANY:0.0.0.0)にバインドされ、クライアント接続が許可されているaccept(2)場合(使用新しいTCPソケットが自動的に作成され、照会された(ローカル)宛先がバインディングアドレスとして選択されます。新しいTCPソケットが適切なアドレスにバインドされるため、応答時間にそのアドレスがルーティングスタックに送信元アドレスとして提供され、上記のように適切なルーティングルールを選択します。 TCP Allが適しています。

UDPは、INADDR_ANYにバインドするときには単純ではありません。新しいソケットは自動的に作成されません。基本的にクエリが作成された場所を通知するメカニズムはありません。したがって、応答はTCPなどの正しいソースアドレスを選択できません。 OP の場合、192.168.1.30 から 192.168.203.3 に照会すると、アプリケーションに使用可能な (ローカル) ターゲット 192.168.203.3 情報がありません。ルーティングスタックのソースアドレスの選択を延期するために、ソースアドレスをバインドせずに応答します(例:INADDR_ANY / 0.0.0.0のまま)。上記のルーティングルールは選択されず、デフォルトルーティングテーブルのデフォルトパスが使用されます。無効なパスは、192.168.203.3 ではなく、192.168.201.232 を応答ソースとして選択します。この応答がラップトップに到達しても(ルーティングの観点とSRPFの観点からは問題ありません)、ラップトップ自体はクエリを実行するために選択したアドレスからのものではないため、これを拒否します。

マルチホーム環境のサーバーアプリケーションは複数のピアで使用でき、UDPに対する特別なサポートが必要です。これを行う2つの一般的な方法があります。

  • INADDR_ANYの代わりに各サーバーのアドレスに個別にバインド

    応答はソケットのバインディングアドレスを使用します。クエリが届いたのでこれソケットとは、ソケットが応答元アドレスとして使用するのと同じ宛先アドレス、つまりクライアントがクエリを実行し、アプリケーションソケットがバインドされているアドレスに送信されることを意味します。

    たとえば、DNS サーバーは次のようになります。バインディング9アクション:サーバー上のすべての既存のアドレスに個別にバインドされます。

    socatポート1313での日付提供の例:socatバインドする各アドレスに対して1つずつ3つのコマンドを実行します。

    socat UDP4-LISTEN:1313,bind=127.0.0.1,fork EXEC:date &
    socat UDP4-LISTEN:1313,bind=192.168.201.232,fork EXEC:date &
    socat UDP4-LISTEN:1313,bind=192.168.203.3,fork EXEC:date &
    
  • ソケットオプションの使用IP_PKTINFO(または一部の* BSDではIP_RCVDSTADDR)INADDR_ANYにバインドするとき

    これには特定のアプリケーションサポートが必要です。connect(2)あるいは、read(2)これらのwrite(2)UDPソケットでは使用できなくなりますが、代わりにソケットオプションによって提供されるセカンダリメッセージを処理し、他の方法を使用してクエリアドレスで使用されている実際の(ローカル)宛先を取得するrecvmsg(2)機能sendmsg(2)が必要です。 (に記載されているcmsg(3))。

    例えばこれがDNSサーバーがすることです束縛されていない使用時interface-automaticオプション。

    socatはい(Linux:ip-pktinfo、* BSDでは使用ip-recvdstaddr):

    socat -u \
        UDP4-RECVFROM:1313,ip-pktinfo,reuseport,fork \
        SYSTEM:'exec socat -u EXEC\:date UDP4-DATAGRAM\:$SOCAT_PEERADDR\:$SOCAT_PEERPORT\,bind=$SOCAT_IP_DSTADDR\:1313\,reuseport'
    

    1つ目socatは受信専用、2つ目はエミッション専用、2番目の分岐は、最初の環境変数socatで使用できるIP_PKTINFOソケットオプションで取得された正しいソースアドレスで応答します。 (SO_REUSEPORT)は、2つの「関連していない」ソケットが同じポートを共有することを可能にする回避策です(実際のアプリケーションでは、UDPソケットはコピーまたはまったくコピーされずに直接使用されるため、これは必要ありません)。socatreuseportfork()dup2(2)

おすすめ記事