У меня есть локальная сеть Ethernet (192.168.1.0/24) с несколькими хостами, которым маршрутизатор назначает адреса через DHCP. Из-за способа настройки DHCP IP-адреса конкретных устройств могут изменяться непредсказуемым образом; это то, что я не могу контролировать.
На клиентском хосте работает некоторый код, который регулярно опрашивает серверные процессы, запущенные на каждом из других хостов, через TCP, чтобы собрать некоторые метрики с каждого хоста. Клиент должен иметь возможность надежно идентифицировать, с каким из серверов он обращается, а из-за динамического назначения IP единственная надежная идентификация основана на их MAC-адресах.
Я предпринял обычные шаги для получения сопоставления MAC-> IP для каждого из хостов:
Это работает в большинстве случаев, но я все еще сталкиваюсь с периодическими проблемами из-за переключения IP-адресов хостами.
Например, какое-то время у хоста A будет IP-адрес 192.168.1.101, а у хоста B - 192.168.1.102. Основываясь на кэше ARP и знании их MAC-адресов, я могу сказать, какие из них есть, и провести соответствующий опрос. Но иногда будет происходить переназначение IP-адреса по мере обновления аренды DHCP, и хост A окажется на 192.168.1.102, а хост B теперь на 192.168.1.101. В тот момент, когда это произойдет, клиентский кеш ARP будет неправильным. И на основе вышеупомянутого подхода клиент по-прежнему будет подключаться к 192.168.1.101, думая, что он считывает метрики хоста A, в то время как на самом деле он теперь разговаривает с хостом B.
Мне нужно устранить такие случаи.
Мне пришли в голову следующие три возможных подхода:
Вариант А: Непосредственно перед подключением к хосту попросите клиента проверить IP-адрес, который, по его мнению, он использует, чтобы принудительно обновить ARP. Используйте это, чтобы убедиться, что он собирается подключиться к правильному хосту / MAC.
Вариант Б: После TCP-соединения и считывания попросите клиента снова проверить таблицу ARP, чтобы убедиться, что он действительно подключен к тому MAC-адресу, к которому, по его мнению, был подключен. (из того, что я видел, кеш ARP должен был быть обновлен при подключении)
Вариант C: При выполнении самого TCP-соединения проверьте удаленный MAC, к которому подключается клиент.
Я понимаю, что это было длинное вступление, но в основном я хотел бы знать есть ли практический способ реализовать вариант C?
Если я проверю пакеты данных, которыми обмениваются узлы во время TCP-соединения, соответствующие MAC-адреса присутствуют в качестве источника и назначения кадра Ethernet. Итак, теоретически - по крайней мере, на некотором уровне - клиентское устройство действительно знает конкретный MAC-адрес сервера, с которым оно разговаривает. Но есть ли способ показать это коду, запускающему TCP-соединение?
В моем контексте у меня есть код Python, создающий соединения с использованием встроенного socket
библиотека на хосте Linux. Я понимаю, что ответ может сильно зависеть от фактической среды, но мне было бы интересно услышать какие-либо общие указания о том, как MAC-адреса доступны (или нет) процессам, инициирующим TCP-соединения. И действительно, любое руководство по надежному способу подключения к хосту на основе его MAC-адреса.
API-интерфейсы сокетов на уровне 3 и 4 не видят MAC-адрес уровня 2. Это требует исследования кеша обнаружения соседей. (И что ваш сетевой стек вообще включает MAC-адреса. Хотя Linux-машины в локальной сети, вероятно, будут, Ethernet повсеместен.)
ARP также не подходит для сетей IPv6. Вы также должны посмотреть кеш обнаружения соседей. Другое дело, даже если интерфейсы для его запроса похожи.
И MAC-адреса являются плохими первичными ключами в таблице хостов, они не самые стабильные или уникальные идентификаторы. Хосты имеют несколько сетевых адаптеров. Аппаратные сетевые карты заменяются. При клонировании виртуальной машины следует изменить нумерацию гостевых сетевых адаптеров. Отсутствие дубликатов вероятно, но не обязательно.
Скорее используйте длинный идентификатор хоста. Например, UUID, который, скорее всего, будет уникальным. Например, в системах systemd есть /etc/machine-id
.