LINUX.ORG.RU
решено ФорумAdmin

исключить несколько интерфейсов в iptables

 


0

2

Есть маршрутизатор на основе линус с несколькими интерфейсами (пусть 6, от eth0 до eth5) Нужно по критерию протокол-порт (пусть tcp, destination port 12345) маркировать трафик, входящий с нескольких из них. Пусть c eth1,eth2,eth4,eth5, с eth0 и eth3 - не надо.

Вроде все просто. Пишем соотвествующее количество правил в таблицу mangle:

-A PREROUTING -i eth1 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff
-A PREROUTING -i eth2 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff
-A PREROUTING -i eth4 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff
-A PREROUTING -i eth5 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

Вопрос - как заменить эти 4 записи на одну? Т.е. не 4 раза «маркировать с порта ethХ» а один раз «маркировать со всех портов кроме eth0, eth3»

Если бы было нужно со всех портов, кроме eth0, то опять все просто

-A PREROUTING ! -i eth0 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

а вот как сформулировать для iptables «не с порта eth0 и не с порта eth3» ? Вроде как-то можно использовать and в правилах, но синтаксис не очевиден. Примеры пытался погуглить - не нашел.



Последнее исправление: mik73 (всего исправлений: 1)

Если у тебя 6 интерфейсов (eth0-eth5) - то особо не выиграешь по количеству правил. А если значительно больше, то можно вот как-то так:
Для eth0 и eth3 ничего не делаем, для остальных eth* - маркируем

iptables -t mangle -N MY_MARK_SET
iptables -t mangle -N MY_MARK_PASS
iptables -t mangle -A PREROUTING -i eth0 -j MY_MARK_PASS
iptables -t mangle -A PREROUTING -i eth3 -j MY_MARK_PASS
iptables -t mangle -A PREROUTING -i eth+ -j MY_MARK_SET
iptables -t mangle -A MY_MARK_SET -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

DiMoN ★★★
()
Последнее исправление: DiMoN (всего исправлений: 1)

Вопрос - как заменить эти 4 записи на одну?

никак. можно лишь укоротить немного с помощью цепочек:

-A mark_pkt -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff
-A mark_pkt -j ACCEPT

-A PREROUTING -i eth1 -j mark_pkt
-A PREROUTING -i eth2 -j mark_pkt
-A PREROUTING -i eth4 -j mark_pkt
-A PREROUTING -i eth5 -j mark_pkt

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

только AND и можно, т.е. target выполняется когда все match-и соблюдены. вы наверное имели ввиду OR то увы, такого в iptables нет, и не нужно - оно только усложнит все

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

Если у тебя 6 интерфейсов (eth0-eth5) - то особо не выиграешь по количеству правил. А если значительно больше

Ну я написал пример, в реальности у меня всё гораздо хуже :-) Хуже всего, что интерфейсы могут иногда добавляться/меняться и каждый раз переписывать правила не хочется.

А «выделенные» интерфейсы (с которых не надо маркировать) как раз заранее известны.

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

-i eth*
и она означает «все eth»

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

только and и можно, т.е. target выполняется когда все match-и соблюдены

Как работает - я понимаю. Но правило написать не могу (как та собака).

А какой-то такой вариант допустим? С использованием and в правиле:

-A PREROUTING ! -i eth0 and ! eth3 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

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

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

Конечно

-A PREROUTING ! -i eth0 and ! -i eth3 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

сначала -i пропустил

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

Ну я написал пример, в реальности у меня всё гораздо хуже :-) Хуже всего, что интерфейсы могут иногда добавляться/меняться и каждый раз переписывать правила не хочется.

А «выделенные» интерфейсы (с которых не надо маркировать) как раз заранее известны.

тогда все намного проще. я бы сделал как-то так:

-A mark_pkt -i eth11 -j RETURN
-A mark_pkt -i eth7 -j RETURN
-A mark_pkt -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

-A PREROUTING -j mark_pkt

где eth11 и eth7 -иэто интерфейсы которые не нужно обрабатывать.

-i eth*

и она означает «все eth»

верно.

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

честно говоря не знаю. раньше на википедии была хорошая статейка, но её зачем-то обрезали. а так, в принципе, и мана iptables достаточно :)

А какой-то такой вариант допустим? С использованием and в правиле:

-A PREROUTING ! -i eth0 and ! eth3 -p tcp -m tcp --dport 12345 -j MARK --set-xmark 0x10/0xffffffff

к сожалению, нельзя больше 1 раза использовать -i

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

Спасибо! Все гениальное просто. И красиво. Так получается даже нагляднее - если потребуется что-то менять в списке «исключений». А я тупил, поскольку зациклился на идее впихнуть все в одну запись.

а так, в принципе, и мана iptables достаточно

в принципе - да... и первым делом его лезу читать, но вот тонкости типа

к сожалению, нельзя больше 1 раза использовать -i

познаются только на практике.

mik73
() автор топика

Проще пареной репы. В удаве именуешь интерфейсы, с которых надо маркировать, как-нибудь вроде «eimX», которые не надо - «einX». Дальше, как очевидно, в iptables пишешь одну строчку:

iptables -t mangle -A PREROUTING -i eim* -j MY_MARK_PASS
Именовать можно по любым критериям, доступным udev'у, как-то:

- встроенные в материнку и 2 левых (или верхних) - etiX, остальные - etoX;

- все реалтеки - rtlX, броадкомы - bcmX;

- и так далее...

berrywizard ★★★★★
()

я бы посмотрел на man ipset типа hash:net,iface

в набор добавлял с сетью 0.0.0.0/0

ipset create XX hash:net,iface
ipset -A XX 0.0.0.0/0,eth0

iptables ... -m set --match-set XX src,src ...
vel ★★★★★
()
Ответ на: комментарий от berrywizard

В удаве именуешь интерфейсы, с которых надо маркировать, как-нибудь вроде «eimX», которые не надо - «einX».

не здорово. Если один интерфейс eth0, другой eth5.10, третий tunnel_tuda, четвертый a_eto_vasya. Переименовать их без перезапуска сервиса, как минимум, не выйдет. А это обычно нежелательно - сервис перезапускать.

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

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

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