多数のホストを備えたイーサネットLAN(192.168.1.0/24)があり、それらはすべてルーターによってDHCPを介してアドレスが割り当てられています。 DHCPの設定方法により、特定のデバイスのIPアドレスが予測できない方法で変更される可能性があります。これは私が制御できないものです。
クライアントホストで実行されているコードがいくつかあり、TCPを介して他の各ホストで実行されているサーバープロセスを定期的にポーリングして、各ホストからいくつかのメトリックを収集します。 クライアントは、通信しているサーバーを確実に識別できる必要があります-動的IP割り当てにより、信頼できる識別はMACアドレスに基づいているだけです。
各ホストのMAC-> IPマッピングを取得するために、通常の手順を実行しました。
これはほとんどの場合機能しますが、ホストによるIPアドレスの切り替えが原因で問題が発生することがあります。
たとえば、しばらくの間、ホストAのIPアドレスは192.168.1.101になり、ホストBのIPアドレスは192.168.1.102になります。 ARPキャッシュとそれらのMACアドレスの知識に基づいて、どれがどれであるかを判断し、それに応じてポーリングすることができます。ただし、DHCPリースが更新されると、IPが再割り当てされることがあり、ホストAは192.168.1.102になり、ホストBは192.168.1.101になります。その時点で、クライアントのARPキャッシュは正しくありません。そして、上記のアプローチに基づいて、クライアントは、実際にはホストBと通信している間、ホストAのメトリックを読み取っていると考えて192.168.1.101に接続します。
私はそのようなケースを排除する必要があります。
次の3つの潜在的なアプローチが私に起こりました:
オプションA:ホストに接続する直前に、ARPを強制的に更新するために、クライアントがオンになっていると思われるIPにpingを実行します。これを使用して、適切なホスト/ MACに接続しようとしていることを確認します。
オプションB:TCP接続と読み出しの後、クライアントにARPテーブルを再度チェックしてもらいます。接続されていると思ったMACアドレスに実際に接続されていることを確認してください(私が見たところ、ARPキャッシュは接続によって更新されているはずです)
オプションC:TCP接続自体を実行するときは、クライアントが接続しているリモートMACを確認してください
これが長々としたイントロであったことを感謝しますが、基本的にオプションCを実装する実用的な方法があるかどうかを知りたいですか?
TCP接続中にホスト間で交換されるデータパケットを検査すると、それぞれのMACアドレスがイーサネットフレームの送信元と宛先として存在します。したがって、理論的には、少なくともある程度は-クライアントデバイスは、通信しているサーバーの特定のMACを認識しています。しかし、これをTCP接続を開始するコードに公開する方法はありますか?
私のコンテキストでは、Linuxホスト上で組み込みのsocket
ライブラリを使用して接続を作成するPythonコードがあります。答えは、実際の環境に大きく依存する可能性があることを理解しています-しかし、MACアドレスがTCP接続を開始するプロセスにどのように公開されるか(または公開されない)か)に関する一般的なガイダンスを聞きたいと思います。実際、 MACアドレスに基づくホスト。
レイヤー3および4のソケットAPIは、レイヤー2のMACアドレスを認識しません。これには、近隣探索キャッシュの調査が必要です。 (そして、ネットワークスタックにはMACアドレスが含まれています。LAN上のLinuxボックスにはおそらく含まれますが、イーサネットはどこにでもあります。)
ARPもIPv6ネットワークには適していません。また、近隣探索キャッシュも確認する必要があります。クエリを実行するインターフェイスが類似している場合でも、別のことです。
また、MACアドレスは、ホストのテーブルで貧弱な主キーを作成します。これらは、最も安定した一意の識別子ではありません。ホストには複数のNICがあります。ハードウェアNICは交換されます。 VMのクローンを作成するときは、ゲストNICの番号を付け直す必要があります。重複がない可能性がありますが、確実ではありません。
むしろ、長いホスト固有の識別子を使用してください。一意である可能性が非常に高いUUIDなど。たとえば、systemdシステムには/etc/machine-id
。