Вы НЕ МОЖЕТЕ использовать подход TCP-прокси для имитации отсутствия обслуживания («соединение отклонено») в точке входа прокси (host2), потому что:
- it (прокси-сервис) не может знать, остановлена ли служба на цели (host1) или нет, пока она не попытается подключиться.
- прокси работает на гораздо более высоком уровне, чем требуется для такой симуляции
Ваш клиент уже установил соединение к прокси-серверу, поэтому единственный возможный способ для прокси-сервера завершить соединение - это сбросить соединение (в то время как реальная цель будет «в соединении отказано» или «истекло время ожидания»).
Таким образом, с этим ничего нельзя сделать смоделировать отсутствие обслуживания, используя подход TCP-прокси.
поведение прокси в реальном мире (что у вас есть)
Client Proxy target
----HND-F1-SYN-->| |
<---HND-F2-------| |
----HND-F3------>| |
|---second hop connectopn-->|
идеальное поведение прокси (которое вы хотите)
Client Proxy target
----HND-F1-SYN-->| |
|---second hop connectopn-->|
<---HND-F2-------| |
----HND-F3------>| |
Ну, конечно вы можете создать решение для имитации отсутствия целевого сервиса , сохранив два прослушивающих сокета (сырые + общие * 10 56 *) при использовании брандмауэра для специальной обработки входящего кадра SYN, например:
- iptables перенаправляет кадр SYN в службу прослушивателя сырых сокетов
- необработанный прослушиватель сокетов sv c устанавливает соединение на втором этапе с целевой службой
- [при сбое соединения] необработанный прослушиватель отвечает созданным кадром RST на имитацию CONNREFUSED - то есть при отсутствии службы.
- [при успешном соединении] необработанный прослушиватель повторно вводит SYN кадр, который должен быть доставлен прослушивателю прокси-службы, и связывает уже установленное соединение второго перехода с клиентским соединением (которое все еще находится в фазе подтверждения)
Как видите, такое решение может быть легко реализовать, но это было бы не будет популярным, поскольку требует использования случайных сокетов и дополнительной нагрузки на ЦП. Что ж, это было объяснение того, почему это невозможно.
И вот как вы можете сделать это так, как хотите:
- Вы можете построить виртуальный мост (используйте openvswitch)
- и используйте iptables для маршрутизации всех фреймов на целевой хост.
Таким образом, соединение между host1 и host2 будет безопасным, и ваш клиент увидит абсолютно идентичные рукопожатия на Уровень TCP и, следовательно, он будет точно знать, запущена служба (успешное соединение) или нет (connrefused или timedout).