LINUX.ORG.RU
ФорумAdmin

TCP bind определенный интерфейс

 , , ,


0

1

Доброй ночи!

На сервере есть несколько сетевых интерфейсов, и только первый из них является шлюзом по умолчанию.

Если я создаю сокет и делаю ему bind с IP адресом определенного интерфейса - могу слушать на нем и UDP пакет ответа уходит именно с указанного интерфейса. Как задумано.

Кроме того, я хочу чтобы один php скрипт осуществлял подключения также с выбранного интерфейса, не являющегося шлюзом по умолчанию.

Для этого вызываю stream_context_create() со значением socket-bindto равным ‘1.2.3.4:0’ (тут адрес выбранного интерфейса) и далее file_get_contents(), но получаю ошибку таймаута на любом интерфейсе кроме первого. Очевидно какие-то проблемы с маршрутизацией SYN / ACK пакетов. Дампы не писал.

После

iptables -t nat -A POSTROUTING -j MASQUERADE`

у меня тот же код подключается нормально, но на запрашиваемом узле отображается IP адрес шлюза по умолчанию.

Как решить эту проблему чтобы и TCP и UDP шло с выбранного интерфейса, не являющегося шлюзом по умолчанию?

Как альтернативу, дайте пожалуйста команды для iptables которые будут маршрутизировать весь трафик на определенный IP адрес через выбранный интерфейс.

Вы tcpdump'ом пробовали смотреть что происходит с исходящими пакетами? Попробуйте, посмотрите

Команды iptable не занимаются маршрутизацией пакетов. Ими можно только исправить ip-адреса (NAT), но пакет пойдёт по маршруту, выбираемом отдельно от iptables.

Читайте про ″ip rule″ и несколько таблиц маршрутизации, гуглится полно примеров/статей по нескольким подключениям к интернету линукс сервера/маршрутизатора.

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

tcpdump говорит следующее Отправка с 1го интерфейса: SYN - SYN ACK - ACK - GET запрос - ответ - несколько пакетов нормального завершения соединения.

Отправка с любого другого интерфейса: SYN - SYN ReTransmit - SYN ReTransmit - ошибка таймаута.

Ищу информацию про ip rule.

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

Может быть тот хост, к которому ты пытаешься подключиться по tcp, не знает, куда посылать пакеты на IP адрес твоего второго интерфейса. Знает только куда посылать пакеты на IP адрес твоего первого интерфейса.

iliyap ★★★★★ ()

Как альтернативу, дайте пожалуйста команды для iptables которые будут маршрутизировать весь трафик на определенный IP адрес через выбранный интерфейс.

Если такой адрес только один, то можно будет добавить маршрут до него через другой шлюз. Но стоит помнить, что пакеты с этого адреса возможно не будут доходить до основного адреса сервера (как это сейчас происходит с доп. адресом). Делается это так:

ip route add $addr via $gateway

где $addr - удаленный адрес, $gateway - второй шлюз.

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

ip route add $addr via $gateway

Формально работает. А как вместо адреса (via) указать имя девайса (eth21)? Адрес динамический.

Попробовал

iptables -t mangle -A OUTPUT -p tcp -m tcp -d 12.34.56.78 –dport 80 -j MARK –set-mark 0x2

ip route add default dev MYDEVICE table 102

ip rule add fwmark 0x2/0x2 lookup 102

(из статьи на Хабре), получил отсутствие подключения на выбранный IP. Адрес не один, но если задачу нельзя решить другим способом то да, можно десяток адресов куда-то прописать.

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

Отправка с любого другого интерфейса: SYN - SYN ReTransmit

но правило iptables:

iptables -t nat -A POSTROUTING -j MASQUERADE

не меняет исходящий интерфейс. Вы tcpdump на интерфес запускаете (опция -i)? Почему с MASQUERADE у вас начинает работать не смотрели?

И на хосте вы смотрели, доходят ли до него пакеты, отвечает ли он на них, или хост далеко?

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

А как вместо адреса (via) указать имя девайса (eth21)? Адрес динамический.

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

В частных случаях вас может быть ppp-интерфейсы (там не нужен адрес другой стороны) и сегменты ethernet (там можно писать маршрут с припиской ″on-link″). src-адрес пакета можно «исправить» iptables -o eth21 -j MASQUERADE.

У вас сейчас ваши хосты, с которым вы пытаетесь соединяться в одной локальной сети (arp broadcast сегменте)?

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

Вот понятия не имею почему начинает работать. В сервере 2 сетевых и 2 туннеля, один из которых - платный VPN сервис, выдающий динамический IP клиенту (то есть мне) и на него я повлиять не могу. Второй туннель - обе стороны под моим контролем, но надо это делать с тем внешним сервисом.

Можно конечно для теста стучаться на какой-то другой свой сервер и смотреть, что теряется (запрос или ответ) но я до этого не додумался.

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

Тунель это ppp-интерфейс, там в маршруте не нужно указывать ″via″, достаточно ″dev″.

В запускаете по экземпляру ″tcpdump -i″ на каждый интерфейс?

получил отсутствие подключения на выбранный IP

Вы всё время описываете конечный результат, но не даёте подробностей. tcpdump показывает, что пакеты уходят? src-адрес исходящего пакета совпадет с адресом на интерфейсе? Ответные пакеты приходят? rp_filter отключен?

В сервере 2 сетевых

Одна в локалку, другая в инет? Или там уже до вас настроена сложная маршрутизация (policy based routing) и уже есть правила (ip rule) маршрутизации?

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

Выше описывал что tcpdump показывает, SYN уходит с нужного интерфейса (если без MASQUARADE), потом syn retransmit несколько раз и обрыв по таймауту потому что ничего в ответ на этот интерфейс не поступает.

не нужно указывать ″via″, достаточно ″dev″.

Понял. Но именно так и сделал -

ip route add default dev MYDEVICE table 102

коннект пропал. Попробую

ip route add $addr dev eth21

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

Если у вас SYN пакет с нужным адресами уходит через нужный интерфейс, а ответа нет, то либо проблемы не на вашей стороне. Либо тунель режет, либо принимающая сторона. Если у вас есть ещё какой-нибудь сервер в инете, на котором вы можете запустить tcpdump, потренеруйтесь на нём, чтобы с двух сторон смотреть прохождение пакетов.

Вы tcpdump с опциями ″-n -nn″ запускаете или он у вас показывает не ip-адреса, а DNS-имена?

mky ★★★★★ ()