Журнал LinuxFormat - перейти на главную

LXF133:Маршрутизация

Материал из Linuxformat
Перейти к: навигация, поиск

Содержание

IP: О по­ли­ти­ке

Это не са­мая под­хо­дя­щая те­ма для свет­ской бе­се­ды, но Ан­д­рей Кон­кин и не со­би­ра­ет­ся за­ни­мать­ся пред­вы­бор­ной аги­та­ци­ей. На по­ве­ст­ке дня: мар­шру­ти­за­ция в осо­бых ус­ло­ви­ях.

Клас­си­че­ские ал­го­рит­мы мар­шру­ти­за­ции, ис­поль­зуе­мые в Ин­тернете, обыч­но осно­вы­ва­ют­ся лишь на ад­ре­се назна­чения па­ке­та. Но бы­ва­ют слу­чаи, когда необ­хо­ди­мо при­нять во внимание, на­при­мер, ад­рес от­пра­ви­те­ля (так на­зывае­мая «мар­шру­ти­за­ция от источника»), тип про­то­ко­ла или порты от­пра­ви­те­ля и по­лу­ча­те­ля. Для это­го су­ще­ству­ет спе­ци­аль­ный ме­ханизм, из­вест­ный как мар­шру­ти­за­ция по по­ли­ти­кам (policy routing). Его основ­ная об­ласть при­менения – пре­достав­ление равно­прав­но­го досту­па, мар­шру­ти­за­ция от источника или по ти­пу про­то­ко­ла. В ра­бо­те ме­ханиз­ма мож­но услов­но мож­но вы­де­лить два эта­па: вы­бор и мар­ки­ров­ку па­ке­тов по неко­то­ро­му кри­те­рию и мар­шру­ти­за­цию ото­бран­ных па­ке­тов в со­от­вет­ствии с оп­ре­делен­ным для них пра­ви­лом.

Как он работает?

рис. 1 В этой се­ти нам не­об­хо­ди­мо на­стро­ить мар­шру­ти­за­цию от ис­точ­ни­ка.

В реа­ли­за­ции Linux ме­ханизм мар­шру­ти­за­ции по по­ли­ти­кам пред­став­ля­ет со­бой на­бор таб­лиц и пра­вил. Ка­ж­дое пра­ви­ло со­сто­ит из кри­те­рия от­бо­ра и дей­ствия, оп­ре­де­ляю­ще­го таб­ли­цу, по ко­то­рой бу­дет вы­пол­нять­ся мар­шру­ти­за­ция. В ка­че­стве кри­те­рия отбо­ра для пра­вил мо­жет ис­поль­зо­вать­ся ад­рес от­пра­ви­те­ля, ад­рес по­лу­ча­те­ля, tos и fwmark (па­ке­ты, мар­ки­ро­ван­ные iptables). Пре­жде чем при­нять ре­шение о мар­шру­ти­за­ции па­ке­та, систе­ма на­чина­ет про­смат­ри­вать пра­ви­ла в по­ряд­ке воз­растания их при­ори­тета, от 0 до 32767. Ес­ли па­кет удов­ле­тво­ря­ет ка­ко­му-ли­бо кри­те­рию от­бо­ра, то дальней­ший по­иск осу­ще­ств­ля­ет­ся по таб­ли­це, за­данной в пра­ви­ле.

Из­на­чаль­но яд­ро ОС соз­да­ет три пра­ви­ла, ко­то­рые ука­зы­вают на три основ­ных таб­ли­цы: local, main и default. Таб­ли­ца local со­дер­жит мар­шру­ты для локаль­ных и ши­ро­ко­ве­ща­тельных ад­ре­сов. Пра­ви­ло от­бо­ра в эту таб­ли­цу име­ет са­мый высо­кий при­ори­тет. Таб­ли­ца main со­дер­жит мар­шру­ты, до­бавляе­мые поль­зо­ва­те­лем. Это основ­ная таб­ли­ца мар­шру­ти­за­ции. Пра­ви­ло, пе­ре­даю­щее па­ке­ты в эту таб­ли­цу, име­ет при­ори­тет 32766. По­сле нее рас­смат­ри­ва­ется толь­ко таб­ли­ца default – обыч­но она пуста. Во­об­ще, Linux может ис­поль­зо­вать 255 таб­лиц мар­шру­ти­за­ции с но­ме­ра­ми (ID) от 1 до 255. Для вы­ше­опи­сан­ных таб­лиц ID вы­гля­дят так: local – ID 255, main – ID 254, default – ID 253.

Все таб­ли­цы оп­ре­де­ля­ют­ся в фай­ле /etc/iproute2/rt_tables. Ка­ж­дая его стро­ка за­да­ет од­ну таб­ли­цу. Сна­ча­ла идет ID таб­ли­цы: он мо­жет быть лю­бым в диа­па­зоне 1–255 и дол­жен быть уникальным. Даль­ше ука­зы­ва­ет­ся имя таб­ли­цы; оно так­же мо­жет быть лю­бым и использу­ет­ся толь­ко для удоб­ства при на­строй­ке.

Что нам потребуется?

Что­бы ме­ханизм мар­шру­ти­за­ции по по­ли­ти­кам за­ра­бо­тал, для на­ча­ла необ­хо­ди­мо, что­бы Linux во­об­ще мог ра­бо­тать в ка­честве мар­шру­ти­за­то­ра и пе­ре­сы­лать па­ке­ты с од­но­го се­те­во­го интер­фей­са на дру­гой. Эту воз­мож­ность обес­пе­чи­ва­ет ядро. В совре­мен­ных ди­ст­ри­бу­ти­вах Linux оп­ция яд­ра IP: advanced router вклю­че­на по умол­чанию, но для пе­ре­сыл­ки па­ке­тов ме­ж­ду ин­терфей­са­ми необ­хо­ди­мо раз­ре­шить ис­поль­зо­вание дан­ной воз­можно­сти. По­следнее дости­га­ет­ся че­рез фай­ло­вую систе­му proc с помо­щью сле­дую­щей коман­ды:

# echo 1 > /proc/sys/net/ipv4/ip_forward

ли­бо с ис­поль­зо­ва­ни­ем sysctl:

# sysctl -w net.ipv4.ip_forward=1

Мар­шру­ти­за­цию от источника мож­но сде­лать несколь­ки­ми спо­со­ба­ми: ис­поль­зо­вать под­держ­ку со сто­ро­ны яд­ра Linux ли­бо мар­ки­ро­вать па­ке­ты с по­мо­щью iptables, осно­вы­ва­ясь на ад­ре­се от­пра­ви­те­ля и мар­шру­ти­зи­ро­вать мар­ки­ро­ван­ные па­ке­ты. Что­бы обес­пе­чить под­держ­ку со сто­ро­ны яд­ра и не ис­поль­зо­вать iptables, необ­хо­ди­мо вклю­чить оп­цию IP: policy routing. Для реали­за­ции мар­шру­ти­за­ции от источника с по­мо­щью iptables необ­хо­ди­мо вклю­чить в яд­ре под­держ­ку iptables и воз­мож­ность мар­киро­вать с его по­мо­щью па­ке­ты (оп­ция яд­ра «MARK» target support).

В ито­ге в яд­ре Linux долж­ны быть вклю­че­ны такие оп­ции:

Networking Support
	 Networking Options
		 [*] IP: advanced router
		 [*] IP: policy routing
		 [*] Network Packet filtering framework (Netfilter)
		 Core Netfilter Configuration
			 [*] “MARK” target support
Скорая помощь

Ста­рые ути­ли­ты, та­кие как ifconfig и route, ра­бо­тают толь­ко с табли­ца­ми local и main. Ути­ли­та ip из па­ке­та iproute2 по умол­ча­нию также ра­бо­та­ет с табли­цей main.

Ес­ли для от­бо­ра и мар­ки­ров­ки па­ке­тов планиру­ет­ся ис­пользо­вать ка­кие-то дру­гие воз­мож­но­сти iptables, их так­же необ­хо­димо вклю­чить в яд­ре. Во­об­ще го­во­ря, луч­ше вклю­чить под­держку iptables пол­но­стью, хо­тя бы в ви­де мо­ду­лей яд­ра. В этом слу­чае ка­кое бы пра­ви­ло вы ни за­хо­те­ли напи­сать в бу­ду­щем, мож­но быть уве­рен­ным, что со сто­ро­ны яд­ра под­держ­ка уже есть.

iproute2 – это ком­плект инст­ру­мен­тов для на­строй­ки пара­мет­ров се­те­вых уст­ройств в Linux. Из все­го на­бо­ра нам по­на­до­бит­ся толь­ко ути­лита ip. Она по­зво­ля­ет управ­лять мар­шру­ти­за­ци­ей, се­те­вы­ми уст­рой­ства­ми, по­ли­ти­ка­ми мар­шру­ти­за­ции и туннеля­ми.

iptables – это ути­ли­та для кон­фи­гу­ри­ро­вания встро­ен­но­го бранд­мау­эра Linux, Netfilter. Все, что он уме­ет де­лать – это фильтровать и мо­ди­фи­ци­ро­вать па­ке­ты.

Далее мы рас­смот­рим два основ­ных при­ме­ра ис­поль­зо­вания мар­шру­ти­за­ции по по­ли­ти­кам: мар­шру­ти­за­цию от источника без ис­поль­зо­вания iptables и мар­шру­ти­за­цию по ти­пу про­то­ко­лов с ис­поль­зо­ванием iptables.

От источника!

Пред­по­ло­жим, что у нас есть Linux-ма­ши­на, на ко­то­рой уста­новле­ны три се­те­вых ин­тер­фей­са со сле­дую­щи­ми ад­ре­са­ми:

eth0: 192.168.0.1/24
eth1: 172.16.0.1/24
eth2: 10.0.0.1/24

К ин­тер­фей­су eth2 под­клю­че­на сеть из че­ты­рех ма­шин:

PC1: 10.0.0.2
PC2: 10.0.0.3
PC3: 10.0.0.4
PC4: 10.0.0.5

Эта схе­ма пред­став­ле­на на рис. 1.

До­пус­тим, весь тра­фик от PC1 и PC2 нуж­но на­пра­вить че­рез eth0 на 192.168.0.2, а от PC3 и PC4 – че­рез eth1 на 172.16.0.2. Бу­дем счи­тать, что шлюз по умол­ча­нию на Linux-ма­ши­не не на­стро­ен.

Для на­ча­ла про­ве­рим, вклю­чен ли ре­жим advanced router:

# sysctl net.ipv4.ip_forward

Или так:

# cat /proc/sys/net/ipv4/ip_forward

Ка­кой бы ко­ман­дой вы ни вос­поль­зо­ва­лись, на вы­хо­де долж­на поя­вить­ся еди­ни­ца. Ес­ли же вы ви­ди­те ноль, ре­жим мар­шру­ти­зато­ра не­об­хо­ди­мо ак­ти­ви­ро­вать, как бы­ло опи­са­но вы­ше.

Те­перь соз­да­дим две до­пол­ни­тель­ных таб­ли­цы и на­зо­вем их, на­при­мер, pc12 и pc34:

# echo '100 pc12' >> /etc/iproute2/rt_tables
# echo '101 pc34' >> /etc/iproute2/rt_tables

ID таб­лиц 100 и 101 мы взя­ли про­из­воль­но; глав­ное, что­бы они не сов­па­да­ли с уже имею­щи­ми­ся.

До­бав­ля­ем в ка­ж­дую из соз­дан­ных таб­лиц свой шлюз по умолча­нию.

# ip route add default via 192.168.0.2 table pc12
# ip route add default via 172.16.0.2 table pc34

Таб­ли­цы го­то­вы, ос­та­лось оп­ре­де­лить политики маршрутизации, вы­би­раю­щие таб­ли­цу для ка­ж­до­го па­ке­та в со­от­вет­ст­вии с его ад­ре­сом от­пра­ви­те­ля.

# ip rule add from 10.0.0.2 table pc12
# ip rule add from 10.0.0.3 table pc12
# ip rule add from 10.0.0.4 table pc34
# ip rule add from 10.0.0.5 table pc34

Ес­ли по­смот­реть на вы­вод ко­ман­ды

# ip rule show

то мы уви­дим, что к трем ос­нов­ным пра­ви­лам у нас до­ба­ви­лись дополнительные, оп­ре­де­лен­ные на­ми пра­ви­ла с при­ори­те­та­ми 32762–32765.

0:	 from all lookup local
32762:	 from 10.0.0.5 lookup pc34
32763:	 from 10.0.0.4 lookup pc34
32764:	 from 10.0.0.3 lookup pc12
32765:	 from 10.0.0.2 lookup pc12
32766:	 from all lookup main
32767:	 from all lookup default

В приведенном при­ме­ре мы для на­гляд­но­сти спе­ци­аль­но соз­да­ли две до­полнитель­ные таб­ли­цы. На са­мом же де­ле мож­но бы­ло обой­тись од­ной. В этом слу­чае необ­хо­ди­мо было про­сто до­ба­вить пра­ви­ла для уз­лов PC1 и PC2 (ли­бо прописать шлюз по умол­чанию), не ука­зы­вая таб­ли­цу. На­ши пра­ви­ла до­ба­ви­лись бы в таб­ли­цу main. А в до­полнитель­ную, соз­данную на­ми, таб­ли­цу мы бы от­би­ра­ли тра­фик от уз­лов PC3 и PC4 с по­мо­щью пра­вил мар­шру­ти­за­ции по по­ли­ти­кам.

По протоколу

рис. 2 Два исходящих интернет-канала: своего рода классика жанра.

Во вто­ром при­ме­ре к на­ше­му Linux-мар­шру­ти­за­то­ру че­рез интер­фейс eth1 бу­дет под­клю­че­на локаль­ная сеть. Для вы­хо­да в Ин­тернет у на­ше­го ро­уте­ра есть два ин­тер­фей­са – бы­ст­рый eth0 и мед­лен­ный ppp0. Те­перь нам необ­хо­ди­мо на­пра­вить весь ICMP, SSH и DNS тра­фик че­рез ppp0, а весь осталь­ной – че­рез eth0 на 192.168.0.2. Как и в про­шлом при­ме­ре, мы счи­та­ем, что шлюз по умол­чанию на Linux-ма­шине не на­стро­ен, но она уме­ет пе­ре­сы­лать па­ке­ты ме­ж­ду ин­тер­фей­са­ми (ре­жим advanced router вклю­чен). Схе­ма пред­став­ле­на на ри­сун­ке 2.

На этот раз мы не бу­дем де­лать две до­полнитель­ные таб­ли­цы: вме­сто это­го ис­поль­зу­ем таб­ли­цу main и од­ну сде­ла­ем са­ми.

Сна­ча­ла до­ба­вим шлюз по умол­чанию в уже су­ще­ствую­щую таб­ли­цу main. По­сле это­го у нас весь тра­фик бу­дет на­прав­ляться че­рез eth0.

# ip route add default via 192.168.0.2

Да­лее, до­ба­вим соб­ст­вен­ную таб­ли­цу – на­зо­вем ее ISD:

# echo '30 ISD' >> /etc/iproute2/rt_tables

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

Мы бу­дем до­бав­лять пра­ви­ла мар­ки­ров­ки па­ке­тов в це­поч­ку PREROUTING таб­ли­цы mangle. Эта це­поч­ка от­ра­ба­ты­ва­ет­ся до приня­тия ре­шения о мар­шру­ти­за­ции.

До­бав­ля­ем в iptables пра­ви­ла для мар­ки­ров­ки ICMP-, SSH- и DNS-тра­фи­ка:

# iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 10 
# iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -p udp --dport 53 -j MARK --set-mark 10

За­да­дим для на­шей но­вой таб­ли­цы шлюз по умол­ча­нию через ppp0:

# ip route add default dev ppp0 table ISD

И, на­ко­нец, на­пи­шем пра­ви­ло для мар­шру­ти­за­ции по по­ли­ти­кам:

# ip rule add fwmark 10 table ISD

Те­перь наш Linux-мар­шру­ти­за­тор бу­дет раз­би­рать мар­ки­ро­ван­ные па­ке­ты в со­от­вет­ст­вии с по­ли­ти­кой мар­шру­ти­за­ции.

Iptables за 5 ми­нут

В iptables есть три таб­ли­цы: mangle, nat и filter. Таб­ли­ца mangle предна­зна­че­на для мар­ки­ров­ки па­ке­тов и со­еди­не­ний, а так­же мо­ди­фика­ции за­го­лов­ков па­ке­тов. Эта таб­ли­ца со­сто­ит из пя­ти це­по­чек: PREROUTING, POSTROUTING, INPUT, OUTPUT, FORWARD.

Таб­ли­ца nat пред­на­зна­че­на для пре­об­ра­зо­ва­ния се­те­вых ад­ре­сов и пор­тов об­ра­ба­ты­вае­мых па­ке­тов. В таб­ли­цу вхо­дят три це­поч­ки: PREROUTING, POSTROUTING, OUTPUT.

Таб­ли­ца filter пред­на­зна­че­на для фильт­ра­ции тра­фи­ка. В эту табли­цу вхо­дят три це­поч­ки: INPUT, OUTPUT, FORWARD.

Персональные инструменты
купить
подписаться
Яндекс.Метрика