Здравствуйте, jksgfv, Вы писали:
J>Есть задача реализовать прозрачный прокси, причём необходима прозрачность не только для клиентов (обычно этого достаточно), но и для сервера. Т.е. чтобы реальный сервер принимал проксированное соединение как соединение с адреса клиента. J>Другими словами необходимо, чтобы внешне прокси выглядел как роутер как для клиентов, так и для сервера. J>Клиентов много, их список в общем случае постоянно меняется, но серверов немного (возможно, один) и их IP-адреса фиксированы. Проксировать нужно TCP-соединения на один или несколько портов на сервере (серверах) — порты тоже не меняются. Адреса и порты серверов можно рассматривать как конфигурационный параметр. J>Прозрачность для клиентов реализуется под Linux довольно тривиально (iptables, REDIRECT), однако с прозрачностью со стороны сервера всё не так просто. Для её реализации нужно фактически подменять локальный IP (IP spoofing) и желательно и порт (при соединении прокси с реальным сервером).
Чтобы осмыслить это нужно картинку. Потому как желаете Вы странного и единственный вариант, когда это будет работать (если я правильно понял что именно Вы хотите реализовать) — когда маршрутизация для транзитного проксируемого трафика идет через сервер с вашим прокси.
J>Попытка использовать для этого параметр ip_nonlocal_bind = 1 провалилась, поскольку хотя bind() сокета на произвольный адрес проходил успешно, но попытки установить соединение с такого сокета (connect()) заканчивались ошибкой, пока в системе не появлялся сетевой интерфейс с нужным адресом (который был указан в bind()).
По моему, это очевидно — tcp handshake подразумевает в процессе обмен данными, а без соответствующего IP на интерфейсе вы не сможете анонсировать его присутствие нижнему уровню OSI (маршрут для этого ip будет транзитным), соответственно ответа никогда не получите.
J> Отсюда необходимость создавать интерфейс с адресом клиента, что есть не очень хорошее решение (клиентов может быть несколько тысяч).
На время создания такого интерфейса вы будет терять к нему маршрут. Это вообще не решение.
J>Менее болезненным видится вариант динамически добавлять-убирать правила в тот же iptables (SNAT) для каждого исходящего соединения. Но это решение тоже трудно назвать логичным и "правильным" (хотя и рабочим).
Для шлюза это вполне себе рабочее решение, но может быть стоит глянуть в сторону чего-то в духе proxy arp? Точнее можно сказать только имея хоть какое-то подобие картинки.
J>Может есть ещё какие способы подмены/указания локального IP (и порта) в рамках каждого из многих TCP соединений? J>Платформа в общем не играет решающей роли: Linux, *BSD, Windows, etc.
Нарисуйте тут простенькую картинку в asci описывающую взаиморасположение клиентов, серверов и проксирующей программы, проставьте только адреса(не обязательно именно те, что будут в боевой системе). Потому как я не уверен, что описание на словах соответсвует тому, что я представил..