LINUX.ORG.RU
ФорумAdmin

Каким образом без виртуальных машин выполнить такой хитрый NAT?

 , ,


0

1

Изначально схема такая:
ISP [7.7.7.1] - [7.7.7.2] Client
Нужно включиться в схему так, чтобы на клиенте ничего не менять (ну вы поняли почему ;) ), при этом иметь возможность не только быть сниффером, но иметь собственные соединения. Клиент всегда инициирует соединения, кроме одного (для примера, реально абсолютно всегда инициирует) порта, К которому подключаются из все (допустим, tcp 80).

Задача сделать так:
ISP [7.7.7.1] - [7.7.7.2] Alice [7.7.7.1] - [7.7.7.2] Client

Я не нашел как в линуксе можно реализовать такой хитрый план без network namespaces или виртуальных машин (в первом неймспейсе [7.7.7.2] и [192.168.2.1], во втором [192.168.2.2] и [7.7.7.2] ) через промежуточные трансляции (маскарадинг) и внутренние интерфейсы [192.168.2.1]+[192.168.2.2], соединенные через бридж.

Таким образом схема получилась такая:
ISP [7.7.7.1] - [7.7.7.2] Alice N1 [192.168.2.1] - br0 - [192.168.2.2] Alice N2 [7.7.7.1] - [7.7.7.2] Client

В данном случае схема такая: client инициирует подключение к 5.5.5.5 через default gw 7.7.7.1 . Alice N2 говорит клиенту, что он 7.7.7.1. Client шлет на Alice N2 пакет, Alice N2 (default gw 192.168.2.1) маскарадит и роутит пакет на 192.168.2.1 (поле отправителя теперь 192.168.2.2), далее Alice N1 маскарадит и роутит пакет на ISP [7.7.7.1] (поле отправителя теперь 7.7.7.2).

В случае проброса порта 80 на Client делаем проброс порта на Alice N1 с 7.7.7.2 на 192.168.2.2, а на Alice N2 с 192.168.2.2 на 7.7.7.2.

Скажите, насколько работоспособно данное решение и можно ли сделать красивее?

У клиента defalult gw, конечно же 7.7.7.1 .

Зачет)) Похоже, что твое решение верное. На счет «по красивее» - не уверен. Только учти, что твое решение будет «изничтожено» при первой же попытке наладить arp-фильтры. По этому, до кучи постарайся убедиться, что свитчи у клиента управляемые и незапароленные (как часто бывает) и создай в них статическую arp-таблицу, куда пропиши уже все необходимое. Немного палевно, но будет гарантия, что твоя таблица пойдет по сети и метод будет работать.

zerropull ()
Ответ на: комментарий от zerropull

Ты не понял. Я не включаюсь в свитч, я разрываю соединение между клиентом и ISP, одним портом подключаюсь к ISP, другим к Client.

ktulhu666 ☆☆☆ ()

обычно, когда такие схемы возникают, это значит вы изобретаете велосипед.

Поэтому лучше скажите, чего вы хотите добиться - т.е. зачем вам все это?

zgen ★★★★★ ()
Ответ на: комментарий от ktulhu666

а что будет показывать трасероут с клиента? он ничего подозрительного не увидет?

nerve ★★ ()
Ответ на: комментарий от nerve

В данном случае это не важно. Но вопрос интересный. Нужно отключить icmp-сообщения к клиенту от Alice N1 и N2, а также поправить ttl на N1 и N2.

ktulhu666 ☆☆☆ ()

Не уверен, но подозреваю, что такое можно сделать при помощи policy-based routing + iptables.

Deleted ()

Если у вас ethernet, то вам всего лишь надо, чтобы Alice отвечала на arp-запросы от ISP и Client своими mac-адресами. Это можно сделать через «ip neig add proxy» или proc...proxy_arp.

src-адрес исходящих с Alice соединений меняйте через SNAT.

А клиент не должен взаимодействовать с остальными компьютерами в сети 7.7.7.0/24 ?

mky ★★★★★ ()
Ответ на: комментарий от mky

Если у вас ethernet, то вам всего лишь надо, чтобы Alice отвечала на arp-запросы от ISP и Client своими mac-адресами. Это можно сделать через «ip neig add proxy» или proc...proxy_arp.

Проблема то не в том, чтобы подменить arp (как я уже писал выше, тут вообще можно в разрыв включиться, а не в свитч), а в том, что ядро линукс (Alice) (в случае, когда у нас нет отдельных пространств имён сетей) не может (насколько я знаю) общаться с клиентом (или gw), адрес которого имеет само на другом интерфейсе. Или, таки, можно хитрым образом это реализовать? И как тогда оно различит, где маскарадинг к такому же айпи, а где его собственные соединения?

А клиент не должен взаимодействовать с остальными компьютерами в сети 7.7.7.0/24 ?

Нет, не должен. Хотя у него и внешний IP, его подсеть куда меньше, чем /24, поэтому данный вопрос не важен.

ktulhu666 ☆☆☆ ()
Ответ на: комментарий от zgen

обычно, когда такие схемы возникают, это значит вы изобретаете велосипед.
Поэтому лучше скажите, чего вы хотите добиться - т.е. зачем вам все это?

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

ktulhu666 ☆☆☆ ()
Ответ на: комментарий от ktulhu666

не может (насколько я знаю) общаться с клиентом (или gw), адрес которого имеет само на другом интерфейсе.

Alice не нужны адреса 7.7.7.1 и 7.7.7.2 на интерфейсах. Пусть у неё будут 192.168.2.1 и 192.168.2.2. Маршруты к 7.7.7.1 и 7.7.7.2 прописываются просто на интерфейсы. Единственное, что alice будет слать arp-запросы от адресов 192.168.2.x, и может ISP или Client не будут отвечать на эти запросы. Но можно прописать статические arp-записи или ещё подумать, если такая проблема возникнет.

И как тогда оно различит, где маскарадинг к такому же айпи, а где его собственные соединения?

Пока таблица записей conntrack не переполнится, проблем быть не должно. При выполнении SNAT правила проверяется список всех проходящих через сервер соединений и если что при SNAT меняется порт, чтобы новое соединение отличалось от уже установленных. Понятно, что если протокол не имеет портов (или аналогичных полей в заголовке), то ничего не получится, например, если Client установит GRE-тунель с хостом 1.2.3.4, то вам с Alice ещё один тунель с 1.2.3.4 не установить. Но, если на Alice открывать только udp/tcp соединения, то проблем возникнуть не должно.

Ваша схема с network namespaces мне не очень нравится, в ней вы делаете NAT пакетов от ISP к Client и обратно, при условии что это основной трафик, это как-то не правильно.

А может вобще получится на Alice сделать интерфейсы в бридж и SNAT к нему прикрутить, надо бы попробовать такое самому сделать.

mky ★★★★★ ()
Ответ на: комментарий от mky

Alice не нужны адреса 7.7.7.1 и 7.7.7.2 на интерфейсах. Пусть у неё будут 192.168.2.1 и 192.168.2.2. Маршруты к 7.7.7.1 и 7.7.7.2 прописываются просто на интерфейсы. Единственное, что alice будет слать arp-запросы от адресов 192.168.2.x, и может ISP или Client не будут отвечать на эти запросы. Но можно прописать статические arp-записи или ещё подумать, если такая проблема возникнет.

Про возможность прописать маршрут (т.е. просто выкинуть в интерфейс и не думать о последствиях) на любой ip (даже не из данной подсети) на интерфейс я знаю. Только ни провайдер, ни клиент не имеют маршрутов к 192.168.2.1 и 192.168.2.2 (хотя, может и имеют, но явно не на нужном интерфейсе :) ). Т.е. провайдер видит только 7.7.7.2, а клиент только 7.7.7.1. При учете, что ни там ни там ничего менять нельзя (по условию моей задачи), то как Вы собираетесь заставить отвечать Вам ISP и клиента, мне непонятно. Как делать NAT клиента в этом случае мне тоже не понятно. Разве что Вы будете каким-то хитрым образом (типа ebtables или какого-нибудь raw-модуля) в iptables менять ip-адреса источника у Alice на выходе (в зависимости от интерфейса (к провайдеру или клиенту), я думал над такой схемой, она должно работать, но я не уверен в плане имплементации. Насколько я знаю, сначала происходит смена ip, а только затем уже маршрутизация. В принципе, может и получиться схема, где Alice с eth1(к ISP, 192.168.1.1, маршрут через eth1 7.7.7.1) и eth2(к Client, 192.168.2.1, маршрут через eth2 7.7.7.2) и с iptables SNAT, работающей в зависимости от того, на какой eth* уходит пакет.

А может вобще получится на Alice сделать интерфейсы в бридж и SNAT к нему прикрутить, надо бы попробовать такое самому сделать.

С ebtables, что ли? В случае обычного бриджа клиенту будет отвечать провайдер.

ktulhu666 ☆☆☆ ()
Последнее исправление: ktulhu666 (всего исправлений: 1)
Ответ на: комментарий от ktulhu666

Только ни провайдер, ни клиент не имеют маршрутов к 192.168.2.1 и 192.168.2.2

Им и не нужны эти маршруты. Я же присал про создание «левых» arp-записей на Alice с помощью «ip neig add proxy». Аlice на запросы MAC-адресов соответсвующих ip-адресам 7.7.7.1 и 7.7.7.2 должна отвечать своими MAC-адресами.

IP-адрес будет меняться SNAT'ом. Можно делать SNAT на любой ip-адрес, даже не назначенный на интерфейс (во всяком случае раньше так можно было). Определение маршрута пакета происходит до SNAT. То есть программа на Alice решает установить соединение с ISP или с кем ещё в Инете. Она открвает соединение от адреса 192.168.1.1 и формируется пакет src = 192.168.1.1, dst = 7.7.7.1 (или другой адрес Инета). Этот пакет по таблице маршрутизации определяется как идущий через eth1 и перед тем как он уйдёт в сетевую карточку, SNAT заменяет ему src-адрес (и делает запись в conntrack).

С ebtables, что ли?

Не знаю. Я мало работал с бриджами, это надо пробовать, что можно сделать. У меня сейчас дома 3 машины с Линуксом есть, может в выходные поковыряю бридж...

Тут в общем то, ещё вопрос «невидимости» этой схемы. То есть client может знать, что трафик идёт через Alice, или Alice должна быть абсолютно невидимой? Потому что в arp-записях могут засветится ip-адреса 192.168.1.x, для client изменится MAC-адрес ISP, не IP ethernet протоколы (допустим, pppoe) перестанут работать, возможны проблемы с прохождением пакетов при переполнении conntrack на Alice. И ещё куча нюансов, в которых маршрутизатор Аlice будет отличатся от неуправляемого двухпортового свича.

mky ★★★★★ ()

Policy based routing-а должно хватить - просто надо вручную разрулить что откуда приходит и с какими адресами. Это геморрой, но возможно

Pinkbyte ★★★★★ ()
Ответ на: комментарий от mky

Первый опыт с обычной маршрутизацией. На Alice дистрибутив SL 6.2. Конфигурация Alice:

# eth0 к ISP, eth1 к Client

ip addr flush dev eth0
ip route add 7.7.7.1 dev eth0
ip route add default via 7.7.7.1 dev eth0
ip addr flush dev eth1
ip route add 7.7.7.2 dev eth1
ip addr add 10.1.1.1 dev lo

iptables -t mangle -I PREROUTING -i eth+ -j MARK --set-mark 1
iptables -t nat -A POSTROUTING -m mark --mark 1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 7.7.7.2
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 7.7.7.1

echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
echo 1 > /proc/sys/net/ipv4/ip_forward 

Всё работает, единственное, что arp-запросы ходят от 10.1.1.1. Можно назначить любые другие адреса, допустим 7.7.7.255/32 на eth0 и eth1, чтобы arp-запросы выглядели более правдоподобно, тогда 10.1.1.1 на lo не нужен. Или прописать на Alice статические arp-записи для ISP и Client, но нужно как-то отслеживать смену MAC-адреса на них.

Можно добавить инкрементирование TTL в iptables, чтобы не было видно Alice в выводе traceroute. Alice обязательно хотя бы один маршрутизируемый ip-адрес (не 127.0.0.0/8).

mky ★★★★★ ()
Ответ на: комментарий от mky

Небольшое уточнение вышеприведённой схемы. Сейчас потыкал arp-запросами в железяку своего провайдера. Она не отвечает на arp-запросы от «левой» ip-сети, ЕМНИП, это нормальное поведение Cisco. Она не отвечает на arp-запросы от broadcast-адреса сети, но отвечает на arp-запросы от адреса сети.

Допустим, если сеть 7.7.7.0/30, то на eth0 нужно назначить ip-адрес 7.7.7.0/32. Адреса 7.7.7.1 и 7.7.7.2 назначать нельзя, на arp-запросы от 7.7.7.3, как и на arp-запросы от 10.1.1.1 маршрутизатор Cisco не ответит.

Это нужно будет проверять «по месту». Назначать на eth0 различные адреса и делать он них "arping" и смотреть, чтобы ISP отвечал на arp-запросы.

mky ★★★★★ ()

Подключение к удаленному хоста с нелокального IP - это transparent-proxy. Оно есть в ядре. squid умеет tproxy.

vel ★★★★★ ()
Ответ на: комментарий от mky

О, оказывается arp-запросы можно править с помощью arptables. То есть на Alice добавляем следующее:

arptables -I OUT -o eth0 -s 10.1.1.1 -j mangle --mangle-ip-s 7.7.7.2
arptables -I OUT -o eth1 -s 10.1.1.1 -j mangle --mangle-ip-s 7.7.7.1

и тогда на eth0 и eth1 ip-адреса назначать не надо.

mky ★★★★★ ()
Ответ на: комментарий от mky

Сейчас помучал вариант с мостом. В принципе, если сделать:

# eth0 к ISP, eth1 к Client

ip addr flush dev eth0
ip addr flush dev eth1
brctl addbr br0
brctl addif br0 eth0
brctl addif br0 eth1
ip link set up dev eth0
ip link set up dev eth1
ip link set up dev br0

ip route add 7.7.7.1 dev br0
ip route add default via 7.7.7.1 dev br0
ip route add 7.7.7.2 dev br0
ip addr add 10.1.1.1 dev lo

iptables -t mangle -I OUTPUT -j MARK --set-mark 2
iptables -t nat -A POSTROUTING -o br0 -m mark --mark 2  '!' -d 7.7.7.2 -j SNAT --to-source 7.7.7.2
iptables -t nat -A POSTROUTING -o br0 -m mark --mark 2  -d 7.7.7.2 -j SNAT --to-source 7.7.7.1

echo 1 > /proc/sys/net/ipv4/ip_forward 
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables 

то интернет на Alice работает, но в сети ethernet полный бардак. Каждый комп генерит пакеты со своим mac-адресом. Alice использует mac-адрес eth0 (как первый добавленный в мост интерфейсе). И получается, что на ISP приходят пакеты с src-адресом 7.7.7.2, но разными mac-адресами.

Если с помощью ″ebtables″ сделать ″snat″ адресов, и указать, что для уходящих через eth1 пакетов использовать MAC такой же как у Client, то Alice перестаёт видить пакеты от ISP.

В arp-запросах Alice использует ip-адрес 10.1.1.1 и arptables его не исправить, так как arptables видят arp-запрос как один пакет, идущий через интерфейс br0, а на деле Alice кидает два запроса — через eth0 и через eth1.

Возможно, что если в роли ISP будет не Linux (как у меня), а реальный маршрутизатор провайдера, то этот вариант работать не будет, из-за бардака с MAC-адресами пакетов. Получается, что вариант с маршрутизацией лучше, особенно если назначить на eth0 MAC-адрес Client, а на eth1 MAC-адрес ISP.

mky ★★★★★ ()
Ответ на: комментарий от mky

А на кой ж хрен ты используешь неконтролируемый мост? Очевидно, что нужно либо блочить ARP-запросы (и вообще все запросы не от куда надо) на мосте, либо вообще все исходящие маки подменять, либо отключить бридж-форвардинг и юзать netfilter.

то Alice перестаёт видить пакеты от ISP.

Вероятно, потому что ebtables не такие умные, чтобы не принадлежащий интерфейсу мак далее в ip-стек загонять. Либо, опять же, проблема с тем, что не все MACи источника подменяются из-за использования прямого брижда. Может просто отключить бридж-форвардинг (опция самого моста, если не изменяет память)?

И вообще, на моей памяти, ebtables никогда не был «умным» инструментом, как iptables, netfilter которого доделывает кучу работы. ebtables работает кондомно и четко так, как сказано, что может приводить к непоняткам после удобного нетфильтра.

ktulhu666 ☆☆☆ ()
Последнее исправление: ktulhu666 (всего исправлений: 2)
Ответ на: комментарий от mky

Ааа, сорри. Не увидел bridge-nf-call-iptables.
bridge-nf-call-arptables
Логическая переменная bridge-nf-call-arptables управляет передачей трафика ARP в цепочку FORWARD пакетного фильтра arptables. Установленное по умолчанию значение 1 разрешает передачу пакетов фильтрам, 0 – запрещает.
bridge-nf-call-iptables
Логическая переменная bridge-nf-call-iptables управляет передачей проходящего через мост трафика IPv4 в цепочки iptables. Используемое по умолчанию значение 1 разрешает передачу пакетов для фильтрации, 0 – запрещает.

ktulhu666 ☆☆☆ ()
Ответ на: комментарий от mky

Интересная вещь эта bridge-nf-call-iptables, много юзкейсов для неё можно придумать. И проверь, реально ли в форвардинг iptables пакеты попадают. А то на некоторых форумах писали, что им так и не удалось заставить все пакеты, через L3 идти. И ещё: http://ebtables.sourceforge.net/examples/real.html Third try: use brouting + MAC snat + MAC dnat

ktulhu666 ☆☆☆ ()
Ответ на: комментарий от ktulhu666

неконтролируемый мост

Просто для интереса, посмотреть что получается и что сейчас может «мост». Рассмотрел два случая, в одном Alice маршрутизатор и для того, чтобы встать между client и ISP, заранее требует настройки адресов/маршрутов. А в другом случае Alice — коммутатор и может быть просто включена (после создания моста), а маршруты, адреса, SNAT-правила, bridge-nf-call-iptables могут быть прописаны позже.

И проверь, реально ли в форвардинг iptables пакеты попадают.

Да я уже «стенд» разобрал, поэтому про форвардинг ничего сказать не могу. Компы по разным комнатам стоят и в стене по одной ethernet-розетке, поэтому пришлось бросать «соплю», чтобы из обычного компа сделать Alice, что мешало закрывать двери.

Но, когда я на Alice делал SNAT правило на произвольный адрес (7.7.7.35) и для всех пакетов в POSTROUTING (без mark), то у пакетов, новых соединений, идущих от client на ISP менялся src-адрес. То есть бриджевые пакеты в таблицу nat попадали, и в mangle PREROUTING счётчик у правила накручивался, наверное, и filter FORWARD проходили.

Правда, ещё мне вылезло такое сообщение:

″physdev match: using --physdev-out in the OUTPUT, FORWARD and POSTROUTING chains for non-bridged traffic is not supported anymore″.

Как-бы логично, но затрудняет написание правил.

mky ★★★★★ ()
Ответ на: комментарий от mky

Да я уже «стенд» разобрал

Лучше бы использовал виртуализацию.

Я так и не понял, получилось ли что-то или нет? Как я понял, получилось сделать так, что либо alice работает, либо клиент?

ktulhu666 ☆☆☆ ()
Ответ на: комментарий от ktulhu666

Лучше бы использовал виртуализацию.

Кому лучше? Тебе надо, ты и используй, хоть виртуализацию, хоть что ещё. Мой интерес к этой теме исчерпан.

mky ★★★★★ ()
Ответ на: комментарий от mky

Кому лучше? Тебе надо, ты и используй, хоть виртуализацию, хоть что ещё. Мой интерес к этой теме исчерпан.

Это не оскорбление, это лишь совет, не пойми неправильно. Просто из своего опыта могу сказать, что в виртуализированном окружении всё проще, а логические ресурсы (например, создание нескольких десятком компов или предоставление 10G-линков) не ограничены (только возможностями хардвара). А поводу сетевых исследований я бы порекомендовал бы:
http://code.google.com/p/coreemu/ (спец эмуляция wlan)
The NETwork emulation toolKIT (+ TORLab) ( http://wiki.netkit.org/index.php/Download_Official )
xentaur (xenomips, dynamips)
http://www.marionnet.org/EN/ (Очень красивый интерфейс)
https://neweb.dit.upm.es/vnumlwiki/index.php/Main_Page
http://sourceforge.net/apps/mediawiki/mpls-linux/index.php?title=Main_Page
http://clownix.net/

Ну и wireshark на virbr* на хосте.

ktulhu666 ☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.