<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Linux Forum &mdash; Routing и policy-routing в Linux при помощи iproute2]]></title>
	<link rel="self" href="https://linuxforum.ru/extern.php?action=feed&amp;tid=8946&amp;type=atom" />
	<updated>2010-12-06T14:07:35Z</updated>
	<generator>PunBB</generator>
	<id>https://linuxforum.ru/viewtopic.php?id=8946</id>
		<entry>
			<title type="html"><![CDATA[Re: Routing и policy-routing в Linux при помощи iproute2]]></title>
			<link rel="alternate" href="https://linuxforum.ru/viewtopic.php?pid=119458#p119458" />
			<content type="html"><![CDATA[<p>+1 zerg</p>]]></content>
			<author>
				<name><![CDATA[Kettler]]></name>
				<uri>https://linuxforum.ru/profile.php?id=11719</uri>
			</author>
			<updated>2010-12-06T14:07:35Z</updated>
			<id>https://linuxforum.ru/viewtopic.php?pid=119458#p119458</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Routing и policy-routing в Linux при помощи iproute2]]></title>
			<link rel="alternate" href="https://linuxforum.ru/viewtopic.php?pid=119298#p119298" />
			<content type="html"><![CDATA[<p>Велосипед. На хабре часто публикую и без того известные всем вещи. Зачем? Красить трафик iptables&#039;ом любой админ учится ещё находясь в утробе матери... Или чуточку по позже, увидев, например, сей материал: <a href="http://opennet.ru/base/net/iproute2_cebka.txt.html">http://opennet.ru/base/net/iproute2_cebka.txt.html</a></p>]]></content>
			<author>
				<name><![CDATA[zerg]]></name>
			</author>
			<updated>2010-12-06T05:14:56Z</updated>
			<id>https://linuxforum.ru/viewtopic.php?pid=119298#p119298</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Routing и policy-routing в Linux при помощи iproute2]]></title>
			<link rel="alternate" href="https://linuxforum.ru/viewtopic.php?pid=119291#p119291" />
			<content type="html"><![CDATA[<p>источник: <a href="http://habrahabr.ru/blogs/linux/108690/#habracut">http://habrahabr.ru/blogs/linux/108690/#habracut</a></p><p>Речь в статье пойдет о роутинге сетевых пакетов в Linux. А конкретно – о типе роутинга под названием policy-routing (роутинг на основании политик). <br />Этот тип роутинга позволяет маршрутизировать пакеты на основании ряда достаточно гибких правил, в отличие от классического механизма маршрутизации<br />destination-routing (роутинг на основании адреса назначения). Policy-routing применяется в случае наличия нескольких сетевых интерфейсов и необходимости<br />отправлять определенные пакеты на определенный интерфейс, причем пакеты определяются не по адресу назначения или не только по адресу назначения.<br />Например, policy-routing может использоваться для: балансировки трафика между несколькими внешними каналами (аплинками), обеспечения доступа к<br />серверу в случае нескольких аплинков, при необходимости отправлять пакеты с разных внутренних адресов через разные внешние интерфейсы, даже для<br />отправки пакетов на разные TCP-порты через разные интерфейсы и т.д.<br />Для управления сетевыми интерфейсами, маршрутизацией и шейпированием в Linux служит пакет утилит iproute2.</p><p>Этот набор утилит лишь задает настройки, реально вся работа выполняется ядром Linux. Для поддержки ядром policy-routing оно должно быть собрано с включенными опциями IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) и IP: policy routing (CONFIG_IP_MULTIPLE_TABLES), находящимися в разделе Networking support -&gt; Networking options -&gt; TCP/IP networking.</p><p><strong>ip route</strong></p><p>Для настройки роутинга служит команда ip route. <br />Выполненная без параметров, она покажет список текущих правил маршрутизации (не все правила, об этом чуть позже):</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip route<br />192.168.12.0/24 dev eth0&nbsp; proto kernel&nbsp; scope link&nbsp; src 192.168.12.101<br />default via 192.168.12.1 dev eth0<br /></div></p><p>Так будет выглядеть роутинг при использовании на интерфейсе eth0 IP-адреса 192.168.12.101 с маской подсети 255.255.255.0 и шлюзом по умолчанию 192.168.12.1.<br />Мы видим, что трафик на подсеть 192.168.12.0/24 уходит через интерфейс eth0. proto kernel означает, что роутинг был задан ядром автоматически при<br />задании IP интерфейса. <br />scope link означает, что эта запись является действительной только для этого интерфейса (eth0). <br />src 192.168.12.101 задает IP-адрес отправителя для пакетов, попадающих под это правило роутинга.<br />Трафик на любые другие хосты, не попадающие в подсеть 192.168.12.0/24 будет уходить на шлюз 192.168.12.1 <br />через интерфейс eth0 (default via 192.168.12.1 dev eth0). <br />Кстати, при отправке пакетов на шлюз, IP-адрес назначения не изменяется, просто в Ethernet-фрейме в качестве MAC-адреса получателя будет указан<br />MAC-адрес шлюза (часто даже специалисты со стажем путаются в этом моменте). <br />Шлюз в свою очередь меняет IP-адрес отправителя, если используется NAT, либо просто отправляет пакет дальше. <br />В данном случае используются приватный адрес (192.168.12.101), так что шлюз скорее всего делает NAT.<br />А теперь залезем в роутинг поглубже. На самом деле, таблиц маршрутизации несколько, а также можно создавать свои таблицы маршрутизации. <br />Изначально предопределены таблицы local, main и default. В таблицу local ядро заносит записи для локальных IP адресов <br />(чтобы трафик на эти IP-адреса оставался локальным и не пытался уходить во внешнюю сеть), а также для бродкастов. <br />Таблица main является основной и именно она используется, если в команде не указано какую таблицу использовать <br />(т.е. выше мы видели именно таблицу main). <br />Таблица default изначально пуста. Давайте бегло взглянем на содержимое таблицы local:</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip route show table local<br />broadcast 127.255.255.255 dev lo&nbsp; proto kernel&nbsp; scope link&nbsp; src 127.0.0.1<br />broadcast 192.168.12.255 dev eth0&nbsp; proto kernel&nbsp; scope link&nbsp; src 192.168.12.101<br />broadcast 192.168.12.0 dev eth0&nbsp; proto kernel&nbsp; scope link&nbsp; src 192.168.12.101<br />local 192.168.12.101 dev eth0&nbsp; proto kernel&nbsp; scope host&nbsp; src 192.168.12.101<br />broadcast 127.0.0.0 dev lo&nbsp; proto kernel&nbsp; scope link&nbsp; src 127.0.0.1<br />local 127.0.0.1 dev lo&nbsp; proto kernel&nbsp; scope host&nbsp; src 127.0.0.1<br />local 127.0.0.0/8 dev lo&nbsp; proto kernel&nbsp; scope host&nbsp; src 127.0.0.1</div></p><p>broadcast и local определяют типы записей (выше мы рассматривали тип default). <br />Тип broadcast означает, что пакеты соответствующие этой записи будут отправлены как broadcast-пакеты, в соответствии с настройками интерфейса. <br />local – пакеты будут отправлены локально. scope host указывает, что эта запись действительная только для этого хоста.<br />Для просмотра содержимого конкретной таблицы используется команда ip route show table TABLE_NAME. <br />Для просмотра содержимого всех таблиц в качестве TABLE_NAME следует указывать all, unspec или 0. <br />Все таблицы на самом деле имеют цифровые идентификаторы, их символьные имена задаются в файле /etc/iproute2/rt_tables и используются лишь для удобства.</p><p><strong>ip rule</strong></p><p>Как же ядро выбирает, в какую таблицу отправлять пакеты? Все логично – для этого есть правила. <br />В нашем случае:</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip rule<br />0:&nbsp; &nbsp; &nbsp; from all lookup local<br />32766:&nbsp; from all lookup main<br />32767:&nbsp; from all lookup default</div></p><p>Число в начале строки – идентификатор правила, from all – условие, означает пакеты с любых адресов, lookup указывает в какую таблицу направлять пакет.<br />Если пакет подпадает под несколько правил, то он проходит их все по порядку возрастания идентификатора. <br />Конечно, если пакет подпадет под какую-либо запись маршрутизации, <br />то последующие записи маршрутизации и последующие правила он уже проходить не будет.<br />Возможные условия:</p><p>&nbsp; &nbsp; * from – мы уже рассматривали выше, это проверка отправителя пакета.<br />&nbsp; &nbsp; * to – получатель пакета.<br />&nbsp; &nbsp; * iif – имя интерфейса, на который пришел пакет.<br />&nbsp; &nbsp; * oif – имя интерфейса, с которого уходит пакет. <br />Это условие действует только для пакетов, исходящих из локальных сокетов, привязанных к конкретному интерфейсу.<br />&nbsp; &nbsp; * tos – значение поля TOS IP-пакета.<br />&nbsp; &nbsp; * fwmark – проверка значения FWMARK пакета. Это условие дает потрясающую гибкость правил. <br />При помощи правил iptables можно отфильтровать пакеты по огромному количеству признаков и установить определенные значения FWMARK. <br />А затем эти значения учитывать при роутинге.</p><p>Условия можно комбинировать, например from 192.168.1.0/24 to 10.0.0.0/8, а также можно использовать префикc not, который указывает, <br />что пакет не должен соответствовать условию, чтобы подпадать под это правило.<br />Итак, мы разобрались что такое таблицы маршрутизации и правила маршрутизации. <br />А создание собственных таблиц и правил маршрутизации это и есть policy-routing, он же PBR (policy based routing). <br />Кстати SBR (source based routing) или source-routing в Linux является частным случаем policy-routing, это использование условия from в правиле маршрутизации.</p><p><em>Простой пример</em><br />У нас есть некий шлюз, на него приходят пакеты с IP 192.168.1.20. Пакеты с этого IP нужно отправлять на шлюз 10.1.0.1. <br />Чтобы это реализовать делаем следующее:<br />Создаем таблицу с единственным правилом</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip route add default via 10.1.0.1 table 120</div></p><p>Создаем правило, отправляющее нужные пакеты в нужную таблицу:</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip rule add from 192.168.1.20 table 120</div></p><p>Как видите, все просто.</p><p><em>Доступность сервера через несколько аплинков</em><br />Теперь более реалистичный пример. Имеется два аплинка до двух провайдеров, необходимо обеспечить доступность сервера с обоих каналов.<br />В качестве маршрута по умолчанию используется один из провайдеров, не важно какой. <br />При этом веб-сервер будет доступен только через сеть этого провайдера. <br />Запросы через сеть другого провайдера приходить будут, но ответные пакеты будут уходить на шлюз по умолчанию и ничего из этого не выйдет.<br />Решается это весьма просто:<br />Определяем таблицы</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip route add default via 11.22.33.1 table 101<br /># ip route add default via 55.66.77.1 table 102</div></p><p>Определяем правила</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip rule add from 11.22.33.44 table 101<br /># ip rule add from 55.66.77.88 table 102</div></p><p>Думаю теперь уже объяснять смысл этих строк не надо. <br />Аналогичным образом можно сделать доступность сервера по более чем двум аплинкам.</p><p><em>Балансировка трафика между аплинками</em><br />Делается одной элегантной командой</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># ip route replace default scope global \<br />&nbsp; nexthop via 11.22.33.1 dev eth0 weight 1 \<br />&nbsp; nexthop via 55.66.77.1 dev eth1 weight 1</div></p><p>Эта запись заменит существующий default-роутинг в таблице main. При этом маршрут будет выбираться в зависимости от веса шлюза (weight). <br />Например, при указании весов 7 и 3, через первый шлюз будет уходить 70% соединений, а через второй – 30%. <br />Есть один момент, который при этом надо учитывать: ядро кэширует маршруты, и маршрут для какого-либо хоста <br />через определенный шлюз будет висеть в таблице еще некоторое время после последнего обращения к этой записи. <br />А маршрут до часто используемых хостов может не успевать сбрасываться и будет все время обновляться в кэше, оставаясь на одном и том же шлюзе. <br />Если это проблема, то можно иногда очищать кэш вручную командой ip route flush cache.</p><p><em>Использование маркировки пакетов при помощи iptables</em><br />Допустим нам нужно, чтобы пакеты на 80 порт уходили только через 11.22.33.1. <br />Для этого делаем следующее</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-mark 0x2<br /># ip route add default via 11.22.33.1 dev eth0 table 102<br /># ip rule add fwmark 0x2/0x2 lookup 102</div></p><p>Первой командой маркируем все пакеты, идущие на 80 порт. <br />Второй командой создаем таблицу маршрутизации. <br />Третьей командой заворачиваем все пакеты с указанной маркировкой в нужную таблицу.<br />Опять же все просто. <br />Рассмотрим также использование модуля iptables CONNMARK. <br />Он позволяет отслеживать и маркировать все пакеты, относящиеся к определенному соединению.<br />Например, можно маркировать пакеты по определенному признаку еще в цепочке INPUT, а затем автоматически маркировать пакеты, <br />относящиеся к этим соединениям и в цепочке OUTPUT. <br />Используется он так</p><p><div class="termtitle" style="font-family: sans-serif; position:relative; height:auto; width:auto; background:#3A4061; color:#FFFFFF; padding: 1px;"><b> Консоль:</b></div>
<div class="termcont" style="font-family: Terminus; position:relative; height:auto; width:auto; overflow-x:scroll; white-space: nowrap ; overflow-y:auto;background:#000000; color:#4EF44E; line-height:1.2; padding: 3px; font-size: 1rem; max-height: 60vh"># iptables -t mangle -A INPUT -i eth0 -j CONNMARK --set-mark 0x2<br /># iptables -t mangle -A INPUT -i eth1 -j CONNMARK --set-mark 0x4<br /># iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark<br /></div></p><p>Пакеты, приходящие с eth0 маркируются 2, а с eth1 – 4 (строки 1 и 2). <br />Правило на третьей строке проверяет принадлежность пакета к тому или иному соединению и восстанавливает маркировки <br />(которые были заданы для входящих) для исходящих пакетов.<br />Надеюсь изложенный материал поможет вам оценить всю гибкость роутинга в Linux. <br />Спасибо за внимание <img src="https://linuxforum.ru/img/smilies/ab.gif" alt="ab" /></p>]]></content>
			<author>
				<name><![CDATA[Termo]]></name>
				<uri>https://linuxforum.ru/profile.php?id=4469</uri>
			</author>
			<updated>2010-12-06T03:12:06Z</updated>
			<id>https://linuxforum.ru/viewtopic.php?pid=119291#p119291</id>
		</entry>
</feed>
