прозрачный со стороны сервера прокси
От: jksgfv  
Дата: 22.03.11 12:08
Оценка:
Есть задача реализовать прозрачный прокси, причём необходима прозрачность не только для клиентов (обычно этого достаточно), но и для сервера. Т.е. чтобы реальный сервер принимал проксированное соединение как соединение с адреса клиента.

Другими словами необходимо, чтобы внешне прокси выглядел как роутер как для клиентов, так и для сервера.

Клиентов много, их список в общем случае постоянно меняется, но серверов немного (возможно, один) и их IP-адреса фиксированы. Проксировать нужно TCP-соединения на один или несколько портов на сервере (серверах) — порты тоже не меняются. Адреса и порты серверов можно рассматривать как конфигурационный параметр.

Прозрачность для клиентов реализуется под Linux довольно тривиально (iptables, REDIRECT), однако с прозрачностью со стороны сервера всё не так просто. Для её реализации нужно фактически подменять локальный IP (IP spoofing) и желательно и порт (при соединении прокси с реальным сервером).

Попытка использовать для этого параметр ip_nonlocal_bind = 1 провалилась, поскольку хотя bind() сокета на произвольный адрес проходил успешно, но попытки установить соединение с такого сокета (connect()) заканчивались ошибкой, пока в системе не появлялся сетевой интерфейс с нужным адресом (который был указан в bind()). Отсюда необходимость создавать интерфейс с адресом клиента, что есть не очень хорошее решение (клиентов может быть несколько тысяч).

Менее болезненным видится вариант динамически добавлять-убирать правила в тот же iptables (SNAT) для каждого исходящего соединения. Но это решение тоже трудно назвать логичным и "правильным" (хотя и рабочим).

Может есть ещё какие способы подмены/указания локального IP (и порта) в рамках каждого из многих TCP соединений?

Платформа в общем не играет решающей роли: Linux, *BSD, Windows, etc.
proxy transparent proxy spoofing ip spoofing socket unix linux iptables
Re: прозрачный со стороны сервера прокси
От: grey_olli http://grey-olli.livejournal.com
Дата: 22.03.11 22:13
Оценка:
Здравствуйте, 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 описывающую взаиморасположение клиентов, серверов и проксирующей программы, проставьте только адреса(не обязательно именно те, что будут в боевой системе). Потому как я не уверен, что описание на словах соответсвует тому, что я представил..
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
Re[2]: прозрачный со стороны сервера прокси
От: jksgfv  
Дата: 22.03.11 23:32
Оценка:
Здравствуйте, grey_olli, Вы писали:

J>>Есть задача реализовать прозрачный прокси, причём необходима прозрачность не только для клиентов (обычно этого достаточно), но и для сервера...

_>Чтобы осмыслить это нужно картинку. Потому как желаете Вы странного и единственный вариант, когда это будет работать (если я правильно понял что именно Вы хотите реализовать) — когда маршрутизация для транзитного проксируемого трафика идет через сервер с вашим прокси.
Именно в качестве транзитного маршрутизатора я и хочу фигурировать в сети (при этом в действительности проксировать трафик)

J>> Отсюда необходимость создавать интерфейс с адресом клиента, что есть не очень хорошее решение (клиентов может быть несколько тысяч).

_>На время создания такого интерфейса вы будет терять к нему маршрут. Это вообще не решение.
Действительно. Так углубился, что не обратил внимание на поверхностный факт

А картинка довольно простая:

клиент (C)      роутер (R)     прокси (P)     сервер (S)
 10.0.0.4 ------ 10.0.0.3 ----- 10.0.0.2 ----- 10.0.0.1


Разумеется, подсети могут быть (и вероятно и будут) разными.
Если предположить, что клиентов за роутером (R) много, то пустить весь трафик через прокси (P) можно только лишь немного скорректировав маршруты на роутере (R) и сервере (S). Важно, что конфигурация клиентов останется прежней. Для пущей простоты роутер (R) можно спрятать:

клиент (C)      прокси (P)     сервер (S)
 10.0.0.4 ------ 10.0.0.2 ----- 10.0.0.1


В итоге:

обычный прокси:    клиент (C) соединяется с прокси (P),   сервер (S) видит соединение с прокси (P) (не подходит - надо перенастраивать клиентов)
прозрачный прокси: клиент (C) соединяется с сервером (S), сервер (S) видит соединение с прокси (P) (плохо подходит - сервер может использовать адрес клиента)
нужный прокси:     клиент (C) соединяется с сервером (S), сервер (S) видит соединение с клиентом (C)


Т.е. прокси (P) становится вообще невидимым. Вернее, он ведёт себя как роутер, что позволяет оказать минимальное влияние на функционирование сети. Что и требуется достичь.
Re[3]: прозрачный со стороны сервера прокси
От: grey_olli http://grey-olli.livejournal.com
Дата: 23.03.11 06:44
Оценка:
Здравствуйте, jksgfv, Вы писали:

J>>>Есть задача реализовать прозрачный прокси,

J>А картинка довольно простая:
клиент (C)      роутер (R)     прокси (P)     сервер (S)
10.0.0.4         ------ 10.0.0.3        ----- 10.0.0.2        ----- 10.0.0.1

J>Разумеется, подсети могут быть (и вероятно и будут) разными.
то есть картинка
клиент (C)          роутер (R)                    сервер (S)
10.0.0.4         ------ 10.0.0.3,10.0.1.1,10.0.2.2         -----    10.0.2.1
                            \
                             ----- 10.0.1.2
                                    прокси (P)

не рассматривается и трафик к прокси всегда в тот же интерфейс что и к серверу?


J>Если предположить, что клиентов за роутером (R) много, то пустить весь трафик через прокси (P) можно только лишь немного скорректировав маршруты на роутере (R) и сервере (S).

по моему достаточно корректировки маршртов (+ NAT) на шлюзе. В какой ситуации вы считает, что нужно трогать еще и сервер?

J>Важно, что конфигурация клиентов останется прежней.



Для пущей простоты роутер (R) можно спрятать:

J>
J>клиент (C)      прокси (P)     сервер (S)
J> 10.0.0.4 ------ 10.0.0.2 ----- 10.0.0.1
J>


J>В итоге:

прозрачный прокси: клиент (C) соединяется с сервером (S), сервер (S) видит соединение с прокси (P) (плохо подходит - сервер может использовать адрес клиента)
нужный прокси:     клиент (C) соединяется с сервером (S), сервер (S) видит соединение с клиентом (C)

J>Т.е. прокси (P) становится вообще невидимым.

J>Вернее, он ведёт себя как роутер, что позволяет оказать минимальное влияние на функционирование сети.

фраза которая все запутывает )

нужный прокси:     клиент (C) соединяется с сервером (S), сервер (S) видит соединение с клиентом (C)

Без iptables или реализации части его функционала в своем коде вам не обойтись.
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
Re[4]: прозрачный со стороны сервера прокси
От: jksgfv  
Дата: 23.03.11 07:45
Оценка:
Здравствуйте, grey_olli, Вы писали:

J>>>>Есть задача реализовать прозрачный прокси,

J>>А картинка довольно простая:
_>
_>клиент (C)      роутер (R)     прокси (P)     сервер (S)
_> 10.0.0.4 ------ 10.0.0.3 ----- 10.0.0.2 ----- 10.0.0.1
_>

J>>Разумеется, подсети могут быть (и вероятно и будут) разными.
_>то есть картинка
_>
_>клиент (C)              роутер (R)               сервер (S)
_> 10.0.0.4 ------ 10.0.0.3,10.0.1.1,10.0.2.2 ----- 10.0.2.1
_>                            \
_>                             ----- 10.0.1.2
_>                                  прокси (P) 
_>

_>не рассматривается и трафик к прокси всегда в тот же интерфейс что и к серверу?
J>>...
_>по моему достаточно корректировки маршртов (+ NAT) на шлюзе. В какой ситуации вы считает, что нужно трогать еще и сервер?

Роутер (R) не принадлежит нам, и мы можем рассчитывать только лишь на простейший его функционал (маршрутизацию на наш прокси), NAT'а там может и не быть (и не быть возможности его установить). Т.е. рассчитывать на какую бы то ни было топологию сети мы не можем, тем более навязывать свои изменения (добавление NAT и изменение IP-адреса и подсети сервера).

Наша же задача — внедрением своего прокси (P) как можно меньше повлиять на систему и сохранить максимум информации о существующей топологии в трафике (т.е. как раз избежать добавления NAT).

_>Без iptables или реализации части его функционала в своем коде вам не обойтись.

На своей машине (прокси (P)) я могу вытворять что угодно — хоть ядро со своими патчами, не говоря об использовании iptables. Но от других машин я могу ожидать лишь простейших изменений конфигурации (добавление маршрута, например), основывать архитектуру на добавлении правил iptables или функций NAT где-то на роутере (R) или тем более сервере (S) нет никакой возможности.

Отсюда и требование, чтобы сети казалось, что прокси (P) просто форвардит весь трафик (что и наводит на мысль о роутере). Хотя с другой стороны переконфигурацией своего прокси мы должны поддержать и описанную вами схему, когда вся наша связь с сетью проходит через "их" роутер с NAT'ом. Но это лишь один из возможных вариантов, реализация которого не вызывает вопросов. Меня же интересует "худший случай", когда топология прямолинейная и сервер использует IP-адреса клиентов, скажем, для реализации како-либо политики безопасности.
Re[5]: прозрачный со стороны сервера прокси
От: grey_olli http://grey-olli.livejournal.com
Дата: 23.03.11 09:19
Оценка:
Здравствуйте, jksgfv, Вы писали:

J>Здравствуйте, grey_olli, Вы писали:


J>>>>>Есть задача реализовать прозрачный прокси,

J>>>А картинка довольно простая:
клиент (C)      роутер (R)     прокси (P)     сервер (S)
 10.0.0.4 ------ 10.0.0.3 ----- 10.0.0.2 ----- 10.0.0.1

J>>>Разумеется, подсети могут быть (и вероятно и будут) разными.
_>>то есть картинка
клиент (C)              роутер (R)               сервер (S)
10.0.0.4 ------ 10.0.0.3,10.0.1.1,10.0.2.2 ----- 10.0.2.1
                            \
                             ----- 10.0.1.2
                                  прокси (P)

_>>не рассматривается и трафик к прокси всегда в тот же интерфейс что и к серверу?
_>>по моему достаточно корректировки маршртов (+ NAT) на шлюзе. В какой ситуации вы считает, что нужно трогать еще и сервер?
J>Роутер (R) не принадлежит нам, и мы можем рассчитывать только лишь на простейший его функционал (маршрутизацию на наш прокси),
По первой схеме: добавляете в R маршрут на S через P, в P реализуете не только свою прокси функцию, но и функционал router (для всего трафика) + NAT
конкретно вашего проксируемого трафика в postrouting. Видимо Вам достаточно будет написать модуль к iptables помимо собственно прокси-функций (может готовое что приспособите — это уже вам виднее по деталям протокола и функционала вашего прокси application). На S добавляете маршрут в сеть C через P .

> NAT'а там может и не быть (и не быть возможности его установить). Т.е. рассчитывать на какую бы то ни было топологию сети мы не можем, тем более навязывать свои изменения (добавление NAT и изменение IP-адреса и подсети сервера).

J>Наша же задача — внедрением своего прокси (P) как можно меньше повлиять на систему и сохранить максимум информации о существующей топологии в трафике (т.е. как раз избежать добавления NAT).
См. выше.

>>Без iptables или реализации части его функционала в своем коде вам не обойтись.


J>На своей машине (прокси (P)) я могу вытворять что угодно — хоть ядро со своими патчами, не говоря об использовании iptables. Но от других машин я могу ожидать лишь простейших изменений конфигурации (добавление маршрута, например), основывать архитектуру на добавлении правил iptables или функций NAT где-то на роутере (R) или тем более сервере (S) нет никакой возможности.

cм. выше.

J>Отсюда и требование, чтобы сети казалось, что прокси (P) просто форвардит весь трафик (что и наводит на мысль о роутере).

Не путайте мягкое и гибкое. Функции прокси на tcp вам нужны на application level OSI, роутинг осуществляется гораздо ниже — на сетевом уровне OSI.

J> Меня же интересует "худший случай", когда топология прямолинейная и сервер использует IP-адреса клиентов, скажем, для реализации како-либо политики безопасности.

см. выше.
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
Re[6]: прозрачный со стороны сервера прокси
От: jksgfv  
Дата: 23.03.11 10:10
Оценка:
Здравствуйте, grey_olli, Вы писали:

_>Видимо Вам достаточно будет написать модуль к iptables помимо собственно прокси-функций (может готовое что приспособите — это уже вам виднее по деталям протокола и функционала вашего прокси application).

Собственно я тут и вижу 2 альтернативы — либо на P добавлять SNAT в POSTROUTING для каждого исходящего соединения на S (а потом удалять соответствующее правило по разрыву соединения), либо и правда писать свой модуль к iptables, который сможет как-то разрулить эту ситуацию одним правилом — типа автоматического SNAT (пока правда не совсем представляю как). И главный вопрос как раз в том и заключается, что, возможно, уже есть готовое решение, чтобы прокси P мог представиться серверу S, будто он клиент C
Re[7]: прозрачный со стороны сервера прокси
От: grey_olli http://grey-olli.livejournal.com
Дата: 23.03.11 17:11
Оценка:
Здравствуйте, jksgfv, Вы писали:
_>>Видимо Вам достаточно будет написать модуль к iptables помимо собственно прокси-функций (может готовое что приспособите — это уже вам виднее по деталям протокола и функционала вашего прокси application).
J>Собственно я тут и вижу 2 альтернативы — либо на P добавлять SNAT в POSTROUTING для каждого исходящего соединения на S (а потом удалять соответствующее правило по разрыву соединения), либо и правда писать свой модуль к iptables, который сможет как-то разрулить эту ситуацию одним правилом — типа автоматического SNAT (пока правда не совсем представляю как). И главный вопрос как раз в том и заключается, что, возможно, уже есть готовое решение, чтобы прокси P мог представиться серверу S, будто он клиент C
Я, на вскидку, готовых решений именно такой степени прозрачности как Вам нужно не знаю, но можете помимо transparent proxy задавать ключи hack, tamper data, посмотреть на реализацию dnsiff (хоть это и не прокси) и прочих инструментов двойного назначения — может что почерпнете, возможно найдете ссылку на готовое решение на securityfocus или в анонсах софта в рассылке penetration tester'ов — Ваша задача может пересекаться с указанной тематикой. Если найдете что-то конкретное — просьба поделиться ссылками в рамках треда или в личку.

Удачи в гуглении.
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
Re[8]: прозрачный со стороны сервера прокси
От: jksgfv  
Дата: 28.03.11 08:02
Оценка:
А ларчик просто открывался. Есть в ядре документ: /usr/src/linux/Documentation/networking/tproxy.txt
И там как раз рассказывается, как можно принять соединение на нелокальный адрес, а также как установить соединение с нелокального адреса. Без кучи правил в iptables и без прочих некрасивостей. Единственное, что для использования IP_TRANSPARENT нужны права рута, хотя может получится разрулить это назначением прав группе.

На всякий случай вот текст этого дока:

Transparent proxy support
=========================

This feature adds Linux 2.2-like transparent proxy support to current kernels.
To use it, enable NETFILTER_TPROXY, the socket match and the TPROXY target in
your kernel config. You will need policy routing too, so be sure to enable that
as well.


1. Making non-local sockets work
================================

The idea is that you identify packets with destination address matching a local
socket on your box, set the packet mark to a certain value, and then match on that
value using policy routing to have those packets delivered locally:

# iptables -t mangle -N DIVERT
# iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
# iptables -t mangle -A DIVERT -j MARK --set-mark 1
# iptables -t mangle -A DIVERT -j ACCEPT

# ip rule add fwmark 1 lookup 100
# ip route add local 0.0.0.0/0 dev lo table 100

Because of certain restrictions in the IPv4 routing output code you'll have to
modify your application to allow it to send datagrams _from_ non-local IP
addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
option before calling bind:

fd = socket(AF_INET, SOCK_STREAM, 0);
/* - 8< -*/
int value = 1;
setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
/* - 8< -*/
name.sin_family = AF_INET;
name.sin_port = htons(0xCAFE);
name.sin_addr.s_addr = htonl(0xDEADBEEF);
bind(fd, &name, sizeof(name));

A trivial patch for netcat is available here:
http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch


2. Redirecting traffic
======================

Transparent proxying often involves "intercepting" traffic on a router. This is
usually done with the iptables REDIRECT target; however, there are serious
limitations of that method. One of the major issues is that it actually
modifies the packets to change the destination address -- which might not be
acceptable in certain situations. (Think of proxying UDP for example: you won't
be able to find out the original destination address. Even in case of TCP
getting the original destination address is racy.)

The 'TPROXY' target provides similar functionality without relying on NAT. Simply
add rules like this to the iptables ruleset above:

# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
  --tproxy-mark 0x1/0x1 --on-port 50080

Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
IP_TRANSPARENT) for the listening socket.


3. Iptables extensions
======================

To use tproxy you'll need to have the 'socket' and 'TPROXY' modules
compiled for iptables. A patched version of iptables is available
here: http://git.balabit.hu/?p=bazsi/iptables-tproxy.git


4. Application support
======================

4.1. Squid
----------

Squid 3.HEAD has support built-in. To use it, pass
'--enable-linux-netfilter' to configure and set the 'tproxy' option on
the HTTP listener you redirect traffic to with the TPROXY iptables
target.

For more information please consult the following page on the Squid
wiki: http://wiki.squid-cache.org/Features/Tproxy4


grey_olli, спасибо за участие
Re[9]: прозрачный со стороны сервера прокси
От: grey_olli http://grey-olli.livejournal.com
Дата: 05.04.11 22:30
Оценка:
Здравствуйте, jksgfv, Вы писали:

J>А ларчик просто открывался. Есть в ядре документ: /usr/src/linux/Documentation/networking/tproxy.txt

J>И там как раз рассказывается, как можно принять соединение на нелокальный адрес, а также как установить соединение с нелокального адреса. Без кучи правил в iptables и без прочих некрасивостей. Единственное, что для использования IP_TRANSPARENT нужны права рута, хотя может получится разрулить это назначением прав группе.

J>На всякий случай вот текст этого дока:

<skip>
J>grey_olli, спасибо за участие
А Вам спасибо за линк на решение — буду иметь ввиду — мож пригодится когда.
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.