Мой домашний сервер имеет два основных интерфейса, eth1
(стандартное подключение к Интернету) и tun0
(туннель OpenVPN). Я бы хотел использовать iptables
заставить все пакеты, сгенерированные локальным процессом, принадлежащим UID 1002, пройти через tun0
, и все остальные пакеты для выхода eth1
.
Я легко могу пометить совпавшие пакеты:
iptables -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11
Теперь я хотел бы добавить какое-то правило в цепочку POSTROUTING (возможно, таблицы mangle), чтобы сопоставить пакеты, отмеченные цифрой 11, и отправить их tun0
, за которым следует правило, которое сопоставляет все пакеты и отправляет их eth1
.
Я нашел цель ROUTE, но она, похоже, только переписывает исходный интерфейс (если я не читаю его неправильно).
На это способны iptables? Надо ли возиться с таблицей маршрутизации (через ip route
или просто наследие route
команд) вместо этого?
Изменить: я подумал, что, возможно, мне следует предоставить дополнительную информацию. В настоящее время у меня нет других правил iptables (хотя я могу создать некоторые правила для выполнения несвязанных задач в будущем). Кроме того, вывод ip route
является:
default via 192.168.1.254 dev eth1 metric 203
10.32.0.49 dev tun0 proto kernel scope link src 10.32.0.50
85.17.27.71 via 192.168.1.254 dev eth1
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.73 metric 203
Таблицу маршрутизации я не трогал - она такая, как сейчас (хотя выглядит довольно грязно). Извини, но у меня нет наследства route
команда установлена на этом компьютере.
И выход ip addr
(конечно, eth0 и eth2 можно игнорировать - это сетевые адаптеры, которые в настоящее время не используются):
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 1c:6f:65:2a:73:3f brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:1b:21:9d:4e:bb brd ff:ff:ff:ff:ff:ff
inet 192.168.1.73/24 brd 192.168.1.255 scope global eth1
inet6 fe80::21b:21ff:fe9d:4ebb/64 scope link
valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 00:1b:21:6a:c0:4b brd ff:ff:ff:ff:ff:ff
5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100
link/none
inet 10.32.0.50 peer 10.32.0.49/32 scope global tun0
Изменить: у меня что-то вроде работает, но он не пересылает помеченные пакеты в tun0. По сути, я добавил таблицу (11) и использовал:
ip route add table 11 via 10.32.0.49 dev tun0
ip rule add priority 10000 fwmark 11 table 11
Когда я просто sudo -u user1000 wget -qO- whatismyip.org
, Я получаю внешний IP-адрес моего дома, но если я это сделаю sudo -u user1002 wget -qO- whatismyip.org
, Я также получаю домашний IP-адрес (но я должен получать IP на другом конце туннеля OpenVPN).
Бег iptables -vL
подтверждает, что пакеты соответствуют правилу маркировки, но, похоже, они не следуют правилу маршрутизации.
РЕДАКТИРОВАТЬ: Я потратил много времени на это, и, хотя это все еще не работает, я думаю, что я немного ближе.
Правило iptables должно быть в mangle
цепочка OUTPUT таблицы. Я думаю, мне также нужно правило MASQUERADE в nat
цепочка POSTROUTING таблицы, чтобы установить адрес источника. Однако перенаправление, которое происходит после искажения OUTPUT, работает некорректно.
Я потратил на это 5 часов сейчас, поэтому беру перерыв и, вероятно, вернусь к этому позже сегодня вечером или когда-нибудь завтра.
Недавно я столкнулся с подобной проблемой, хотя и немного другой. Я хотел проложить маршрут только TCP-порт 25 (SMTP) через интерфейс Tap0 OpenVPN, при этом весь остальной трафик (даже для того же хоста) маршрутизируется через интерфейс по умолчанию.
Для этого мне пришлось пометить пакеты и установить правила их обработки. Во-первых, добавьте правило, которое помечает пакеты маршрутизации ядра значком 2
через стол 3
(объяснено позже):
ip rule add fwmark 2 table 3
Вы могли бы добавить символическое имя к /etc/iproute2/rt_tables
, но я не стал этого делать. Номер 2
и 3
выбираются случайным образом. Фактически, они могут быть одинаковыми, но для ясности я не делал этого в этом примере (хотя я делаю это в своей собственной настройке).
Добавьте маршрут для перенаправления трафика через другой интерфейс, предполагая, что шлюз 10.0.0.1
:
ip route add default via 10.0.0.1 table 3
Очень важно! Очистите кеш маршрутизации, иначе вы не получите ответ и несколько часов просидите, зарываясь руками в волосы:
ip route flush cache
Теперь установите правило брандмауэра для маркировки назначенных пакетов:
iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2
Вышеупомянутое правило применяется только в том случае, если пакеты приходят с локальной машины. Видеть http://inai.de/images/nf-packet-flow.png. Отрегулируйте его в соответствии с вашими требованиями. Например, если вы хотите направить только исходящий HTTP-трафик через tap0
интерфейс, измените 465 на 80.
Чтобы предотвратить пересылку пакетов tap0
получая ваш LAN-адрес в качестве IP-адреса источника, используйте следующее правило, чтобы изменить его на адрес вашего интерфейса (при условии, что 10.0.0.2
как IP-адрес для интерфейса tap0
):
iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to-source 10.0.0.2
Наконец, ослабьте проверку источника обратного пути. Некоторые предлагают вам установить его на 0
, но 2
кажется лучшим выбором согласно https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt. Если вы пропустите это, вы получите пакеты (это можно подтвердить с помощью tcpdump -i tap0 -n
), но пакеты не принимаются. Команда для изменения настройки для приема пакетов:
sysctl -w net.ipv4.conf.tap0.rp_filter=2
Я решил это. Проблема заключалась в правилах маршрутизации в таблице 11. Таблица 11 был попадание, но правила маршрутизации делают его неработоспособным. Этот сценарий - то, что я сейчас использую, и, похоже, он работает хорошо (хотя, очевидно, он специфичен для моей установки). Также я создал новую таблицу 21, посвященную основному восходящему каналу (eth1).
# Add relevant iptables entries.
iptables -t mangle -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
# Flush ALL THE THINGS.
ip route flush table main
ip route flush table 11
ip route flush table 21
ip rule flush
# Restore the basic rules and add our own.
ip rule add lookup default priority 32767
ip rule add lookup main priority 32766
ip rule add fwmark 11 priority 1000 table 11
# This next rule basically sends all other traffic down eth1.
ip rule add priority 2000 table 21
# Restore the main table. I flushed it because OpenVPN does weird things to it.
ip route add 127.0.0.0/8 via 127.0.0.1 dev lo
ip route add 192.168.1.0/24 dev eth1 src 192.168.1.73
ip route add default via 192.168.1.254
# Set up table 21. This sends all traffic to eth1.
ip route add 192.168.1.0/24 dev eth1 table 21
ip route add default via 192.168.1.254 dev eth1 table 21
# Set up table 11. I honestly don't know why 'default' won't work, or
# why the second line here is needed. But it works this way.
ip route add 10.32.0.49/32 dev tun0 table 11
ip route add 10.32.0.1 via 10.32.0.50 dev tun0 table 11
ip route add 0.0.0.0/1 via 10.32.0.50 dev tun0 table 11
ip route flush cache
## MeanderingCode edit (потому что я пока не могу комментировать)
Спасибо за этот ответ! Кажется, что это может стать беспорядочным, поскольку вам придется поддерживать здесь информацию о маршруте (возможно, дублируя или нарушая другие вещи, которые могут захотеть установить маршруты.
Вы можете столкнуться с «странностями» в своей таблице маршрутизации из OpenVPN, потому что сервер настроен на «проталкивание» маршрутов, что позволяет всему трафику маршрутизироваться через сетевой интерфейс VPN, а не через «голый» Интернет. Или ваша конфигурация OpenVPN, или любой другой сценарий / приложение, которое ее настраивает, устанавливает маршруты.
В первом случае вы можете отредактировать конфигурацию OpenVPN и вставить строку, содержащую "route-nopull"
В последнем случае проверьте конфигурацию OpenVPN или любой оболочки (network-manager-openvpn, например, во многих текущих настольных дистрибутивах Linux).
В любом случае устранение конфигурации маршрутизации, в которой она устанавливается, чище и безопаснее, чем очистка таблицы, в зависимости от того, когда вы запускаете этот сценарий и что еще делает ваша система.Ура!
Я думаю, ты хочешь:
/sbin/ip route add default via 10.32.0.49 dev tun0 table 11
/sbin/ip rule add priority 10000 fwmark 11 table 11
http://lartc.org/howto/lartc.netfilter.html
Но я не проверял вышеизложенное.
Это можно сделать без команды iptables. Выполнить простую команду ip.
Для uid 1002:
ip rule add uidrange 1002-1002 table 502
Добавьте маршрут по умолчанию для таблицы 502 через интерфейс, который вы хотите сказать
eth0 ip rule add default via a.b.c.d dev eth0