Привет, ЛОР. У меня два сетевых интерфейса, eth0 и eth1 с ip-адресами ip0 и ip1 соответсвтеннно. Я хочу, чтобы в основном использовался ip1, а для пользователя user ip0.
В iptables в таблице mangle я с помощью -m owner --uid-owner user я помечаю пакеты меткой:
iptables -t mangle -A OUTPUT -m owner --uid-owner user -j MARK --set-mark 1
Командой ip rule я отправляю пакеты с меткой в соответствующую таблицу. Кроме того, есть правила чтобы пакеты с каждого ip-адресу уходили в соответствующие таблицы:
ip rule add fwmark 1 table table0
ip rule add from ip0 table table0 priority 300
ip rule add from ip1 table table1 priority 300
Наконец, на пакеты, уходящие с интерфейса eth0, я ставлю его ip-адрес:
iptalbes -t nat -A POSTROUTING -o eth0 -j SNAT ip0
Прописал 2 в rp_filter, и всё почти заработало. Теперь начинается самое интересное.
Я пробую подключиться к Яндексу от пользователя user, например, с помощью такого кода:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
(socket.AF_INET, socket.SOCK_STREAM)
С помощью tcpdump я вижу, что пока всё сработало правильно: пакеты для инициации tcp-соединения ушли с интерфейса eth0 с обратным ip-адресом ip0, функция выполнилась прваильно, всё пока работает. При этом сам сокет считает, что его ip-адрес ip1, так и дожно быть:
s.getsockname
(ip1, 36286)
Но вот я закрываю соединение
s.close()
18:17:12.419048 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 2604533824, ack 3747075092, win 229, length 0
18:17:12.625721 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
18:17:13.039056 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
18:17:13.865720 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
18:17:15.522390 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
18:17:18.839054 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
18:17:25.465724 IP ip0.36286 > www.yandex.ru.http: Flags [F.], seq 0, ack 1, win 229, length 0
Почему так может происходить? Ведь есть явное правильно, что пакеты from ip0 должны проходить через table0, где указан им путь вперед.