Вопрос или проблема
У меня есть приложение A и приложение B, которые общаются через tcp. Я не имею контроля над A, но B – это мое приложение (C++ с asio). Я хочу протестировать коммуникацию между ними на localhost, однако приложение A, похоже, обрабатывает трафик, приходящий с localhost, иначе. Я хочу сделать так, чтобы, когда A получит запрос от B, оно думало, что он не с localhost, чтобы не применять свою специальную логику для localhost.
Вот что я пробовал:
- Я пытался добавить другой IP следующим образом:
sudo ip addr add 192.168.1.10/32 dev lo
, а затем в моем приложении использовать привязку на сокете к этому IP. Судя по логам из приложения B, похоже, что я запрашиваю с 192.168.1.10. - Аналогично, я пробовал ту же команду, но с моим сетевым интерфейсом eth0 вместо lo.
Однако как приложение A, так и Wireshark все еще видят запрос, исходящий из 127.0.0.1.
Что еще я могу попробовать?
Я люблю сетевые пространства имен и veth для таких вещей, аналогичная изоляция, как у контейнеров (docker и другие движки контейнеризации используют пространства имен), но немного более легковесная и проще для быстрой настройки.
Вы можете создать пространство имен с помощью ip netns
, как в ip netns add memorable_name
, создавайте столько, сколько хотите, но одно решит задачу.
Затем вы можете связать ваши пространства имен с помощью veth интерфейсов. ip link add type veth
создает пару виртуальных Ethernet интерфейсов, которые связаны вместе, и один из них можно переместить в ваше пространство имен с помощью ip link set veth1 netns memorable_name
.
Вы можете настроить интерфейсы обычным способом, за исключением того, что вам нужно использовать -n memorable_name
, если ваша оболочка работает в другом пространстве имен, чем интерфейс, который вы хотите настроить. ip a a 192.168.0.1/24 dev veth0
и ip -n memorable_name a a 192.168.0.2/24
. Поднимите интерфейсы с помощью ip link set veth0 up
и ip -n memorable_name link set veth1 up
, и вы готовы.
Чтобы запустить программу в новом интерфейсе, вы можете использовать ip netns exec
, как в ip netns exec memorable_name ./my_app
или ip netns exec memorable_name bash
.
Ответ или решение
Эмуляция трафика между несколькими хостами на локальном хосте: Подробное руководство
Вопрос, который вы поднимаете, касается тестирования взаимодействия между двумя приложениями — A и B — в среде localhost, где приложение A неправильно обрабатывает трафик, исходящий из localhost. Ваша задача заключается в том, чтобы заставить приложение A воспринимать трафик из приложения B как поступающий не с localhost. Ниже представлен исчерпывающий подход к решению этой проблемы с использованием пространств имен сети (network namespaces) и виртуальных Ethernet-интерфейсов (veth) для эмуляции многохостного окружения.
Основные шаги:
-
Создание пространства имен сети: Используйте команду
ip netns add
для создания нового пространства имен, которое позволит изолировать сетевые интерфейсы и маршруты. Например:ip netns add testing_ns
-
Создание виртуальных Ethernet-интерфейсов: Создайте пару виртуальных интерфейсов, используя команду
ip link add
. Эти интерфейсы будут связаны друг с другом, обеспечивая связь между пространствами имен.ip link add veth0 type veth peer name veth1
-
Настройка интерфейсов: Переместите один из интерфейсов во вновь созданное пространство имен. После этого вам нужно будет присвоить IP-адреса обоим интерфейсам.
ip link set veth1 netns testing_ns ip addr add 192.168.0.1/24 dev veth0 ip -n testing_ns addr add 192.168.0.2/24 dev veth1 ip link set veth0 up ip -n testing_ns link set veth1 up
-
Запуск приложений в пространстве имен: Теперь, когда ваши интерфейсы настроены, вы можете запустить приложение B внутри созданного пространства имен. Это гарантирует, что все сетевые запросы будут рассматриваться как исходящие от отдельного "хоста", а не от localhost.
ip netns exec testing_ns ./app_B
Дополнительные настройки
- Настройка маршрутизации и NAT: В зависимости от вашей конфигурации может потребоваться настроить маршрутизацию и NAT, чтобы трафик правильно проходил между интерфейсами. Используйте
iptables
для настройки правил, если это необходимо. - Мониторинг трафика: Вы можете использовать
tcpdump
илиwireshark
для проверки трафика, чтобы убедиться, что приложение A видит запросы не как localhost.
Заключение
Использование пространств имен делает тестирование сетевых приложений более гибким и удобным. Это позволяет изолировать тестируемые приложения и создать среду, максимально приближенную к многохостовой, не прибегая к сложной конфигурации полноценного сетевого окружения или контейнеризации. Вы сможете успешно эмулировать трафик между приложениями A и B с помощью методов, описанных выше, что значительно упростит процесс тестирования и улучшит вашу продуктивность в разработке.
Если у вас возникли дополнительные вопросы или необходима помощь в настройке, не стесняйтесь обращаться!