Разрешить только определенный исходящий трафик на определенных интерфейсах

15

У меня довольно странная проблема. У меня есть сервер с двумя сетевыми интерфейсами eth0и eth1. Каждый из них подключен к другой сети. Каждая сеть имеет интернет-шлюз. Сервер имеет различные исходящие соединения: http (некоторые скрипты на серверах очищают веб-сайты), клиент nfs, клиент samba, клиент dns и сборщик электронной почты, и это лишь некоторые из них.

По причинам, в которые я не буду вдаваться, мне нужно разделить эти исходящие клиенты так, чтобы исходящий трафик http, nfs, samba и dns запрашивался только eth0тогда, когда все остальное проходит eth1.

Я прочитал несколько поисков в Google, и похоже, что iptablesэто то, что мне нужно, но я действительно не понимаю. Я привык только управлять входящими правилами межсетевого экрана ufw.

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

Изменить Я могу разделить клиентов на двух пользователей, если возможно ограничить весь исходящий трафик от учетной записи до одного интерфейса. на бумаге кажется, что это может быть проще.

Oli
источник

Ответы:

12

Я бы настроил отдельную таблицу маршрутизации и политику для маршрутизации помеченных пакетов с использованием этой таблицы, а iptables / netfilter помечал определенные пакеты.

Создать таблицу: echo 1 known >> /etc/iproute2/rt_tables

Создайте правило маршрутизации ( ipкоманда от iproute2 ): ip rule add from all fwmark 1 table known

Мы создали таблицу под названием «известные» и создали правило маршрутизации, которое говорит, что любой пакет с меткой, равной 1, маршрутизируется в соответствии с «известной» таблицей. Я назвал это только известным, потому что это для списка известных протоколов - вы можете назвать это как хотите. Теперь мы настраиваем известную таблицу для правильной маршрутизации.

ip route add default dev eth0 table known

Создайте правила iptables:

iptables -t mangle -I PREROUTING -p tcp --dport 111 -j MARK --set-mark 1
iptables -t mangle -I PREROUTING -p tcp --dport 2049 -j MARK --set-mark 1

В этом примере пакеты на портах NFS (111, 2049) помечаются 1. Мы добавляем это правило в iptable 'mangle'. Это отличается от таблиц маршрутизации и не может быть изменено; таблица mangle специально предназначена для изменения пакетов, кроме NAT.

Теперь, чтобы маршрутизировать все остальное через другой интерфейс, мы добавляем маршрут в стандартную таблицу маршрутизации.

ip route add default dev eth1

Чтобы по-настоящему понять это, прочитайте разделы 4 и 11 инструкции LARTC .

Шон Дж. Гофф
источник
Ну, это на самом деле намного проще, чем я боялся. Сетевой стек Linux действительно красивый зверь, не так ли ?! Я дал это быстрое испытание, и все, кажется, работает как ожидалось. Я наблюдаю за каждым интерфейсом через каждый, iftopи каждый из них показывает правильный тип трафика. Огромное спасибо.
Оли
Я не знаю, как iptables или iproute2 хранят их конфигурацию. Должен ли я запускать эти правила при каждой загрузке?
Оли
@ Оли Они очищаются при перезагрузке. Вы можете сохранить и восстановить правила с помощью iptables-saveи iptables-restore. Если вы используете NetworkManager, вы можете настроить диспетчерские сценарии для автоматизации процесса. К сожалению, на официальной странице NM нет документации об этой функции, но в документации по Ubuntu и Arch Linux об этом упоминается.
Шон Дж. Гофф
5

Что ж, « самый простой » способ должен указывать отдельным программам использовать определенный интерфейс (или ip интерфейса. Например:

ping -I eth1 8.8.8.8

инструктирует ping использовать eth1 в качестве интерфейса источника, а

wget --bind-address 10.0.0.1 http://www.google.it/

инструктирует wget проходить через интерфейс, имеющий 10.0.0.1IP-адрес.

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

Для начала вы должны прочитать это руководство по нескольким интернет-соединениям . Хорошо читать также является одним из тысяч из IPtables учебников, EXPECIALLY на outbound filtering, process/ pid filteringи port filtering.

Мистер Шунц
источник
4

Правильный способ сделать это - привязать () к интерфейсу, который вы хотите использовать для исходящих пакетов. Так как Вы можете настроить маршруты с ip routeи ip ruleкоманды управления , как пакеты направляются на основании их исходящего интерфейса. Для моего примера я буду использовать следующую сеть:

  • eth0:
    • Адрес: 192.168.0.2/24
    • Шлюз по умолчанию: 192.168.0.1
  • eth1:
    • Адрес: 192.168.1.2/24
    • Шлюз по умолчанию: 192.168.1.1

Я создам две таблицы маршрутизации: одну для исходящего трафика для eth0, называемую альтернативой, и одну таблицу для eth1, называемую основной. Таблица маршрутизация магистрали всегда существует и нормальная таблица , которая используется routeи ip routeкомандами. Большинство людей никогда не имеют дело с другими таблицами. Чтобы создать таблицу под названием alternate, мы добавим следующую строку /etc/iproute2/rt_tables:

10    alternate

Основная таблица имеет приоритет по умолчанию 254. Правила, для которых действует таблица маршрутизации, контролируются ip ruleкомандой. По умолчанию эта команда выведет список существующих правил, который должен выглядеть примерно так:

0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 

Это в основном говорит, что он будет искать маршрут в таблице, localкоторая является специальной таблицей, поддерживаемой ядром для локальных маршрутов, таких как мой собственный IP-адрес. Затем он попытается использовать таблицу main и table default. Таблица по умолчанию обычно пуста, поэтому, если в main нет совпадений, нет маршрута к хосту. Во-первых, давайте заполним таблицу чередуя с правилами для eth0.

sudo ip route add table alternate 192.168.0.0/24 dev eth0
sudo ip route add table alternate 192.168.1.0/24 dev eth1
sudo ip route add table alternate default via 192.168.0.1

Обычно вы хотите, чтобы alternateтаблица выглядела аналогично mainтаблице. Разница лишь в том, когда маршрутизация должна быть другой. Вы можете не захотеть включать вторую строку выше, если вы буквально хотите, чтобы весь трафик NFS, HTTP и т. Д. Проходил через шлюз по умолчанию на eth0, даже если он предназначен для сети на eth1. Следующим шагом является добавление правила для использования этой альтернативной таблицы маршрутизации:

sudo ip rule add from 192.168.0.0/24 pref 10 table alternate

Это правило говорит, что любой трафик, приходящий с адреса в сети 192.168.0, будет использовать alternateтаблицу маршрутизации вместо обычной mainтаблицы. Последний шаг - убедиться, что все клиенты, которые должны его использовать, eth0связываются с ним. С wget, например, установить --bind-address=192.168.0.2, для NFS установитьclientaddr=192.168.0.2опция монтирования Если вы используете LibWWW с Perl, вы можете установить опцию localaddr в LWP :: UserAgent для управления локальным интерфейсом, с которым он связан. Если у вас есть клиент, которым вы не можете управлять связыванием, и исходный код компиляции недоступен, вы можете использовать правило iptables для изменения его адреса, но это скорее хак и может не сработать. Вам понадобится правило SNAT, настроенное в цепочке PREROUTING таблицы nat или таблицы mangle. Вам все еще понадобятся измененные таблицы маршрутизации, приведенные выше, чтобы это работало.

penguin359
источник