Linux : /etc

делимся знанием

Работа одновременно с двумя выделенными линиями. Часть 1.


По ряду причин я решил купить домой вторую выделенную линию. Пришли монтажники из Корбины, провели мне вторую линию, воткнули во вторую сетевую карту, проверили на работоспособность и ушли. А я остался настраивать оба интернета :-).

Поднял вчерне оба интернета — от районной сети GolNet и от Корбины — и решил пропинговать извне одновременно оба своих ip. Результат: корбиновский ip пингуется, голнетовский нет. Через минуту я понял, что так и должно быть — ответ на пакет от GolNet уходил по дефолтному роутингу на корбиновский интерфейс и, естественно, не получался тем, кто пингует голнетовский ip-адрес.

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

Поиск в интернете в конце концов вывел меня на пакет iproute2 — подсистема расширенного роутинга под Linux.

Изучив главу из Linux Advanced Routing & Traffic Control HOWTO, я решил для начала построить нечто аналогичное для интерфейсов в локальные сети GolNet и Corbina соответственно. Вот что получилось в итоге.

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

Необходимые условия

Убедитесь, что в ядре включены все необходимые опции. Это опция

Networking -> Networking options -> TCP/IP networking

и её подопции “IP: advanced router”, “IP: Policy routing”, “IP: use netfilter MARK value as routing key”, “IP: equal cost multipath”. Две последние опции пригодятся позднее при настройке интернета.

Пересоберите ядро.

Убедитесь также, что оба сетевых интерфейса получают свои адреса по DHCP, а клиент dhcpcd сохраняет свою информацию в файлы /var/lib/dhcpcd/dhcpcd-ethN.info (смотрите скрипт ниже, функцию write_resolv_conf).

Убедитесь, что в системе есть iproute2.

Обычно все эти условия выполнены, но для Gentoo может понадобиться выполнить команды

emerge dhcpcd

emerge iproute2

Конфигурирование

Выдержка из /etc/conf.d/net:

modules=(”iproute2″)
config_eth0=( “dhcp” )
dhcp_eth0=”nodns nogateway”
config_eth1=( “dhcp” )
dhcp_eth1=”nodns nogateway”

Здесь важно обратить внимание на опции dhcp для обоих интерфейсов — /etc/resolv.conf не перезаписывается и роутинги на шлюзы в локалки автоматом не прописываются. Всё это происходит чуть позднее, в /etc/conf.d/local.start (в других unix-системах это, возможно, надо писать куда-то вроде /etc/rc.local).

Однако, прежде чем вносить записи о роутингах, надо указать системе iproute2 имена таблиц роутинга, по которым мы разложим правила роутинга.

Выдержка из /etc/iproute2/rt_tables:

1 local_golnet
2 local_corbina

Главное, чтобы номера таблиц нигде больше в /etc/iproute2/rt_tables не повторялись.

Теперь можно заполнить таблицы локальных роутингов.

Выдержка из /etc/conf.d/local.start:

# функция write_resolv_conf просто заполняет /etc/resolv.conf записями относительно dns-серверов
# локалок в указанном порядке интерфейсов.

function write_resolv_conf()

{

 interfaces=$*

 rm -f /etc/resolv.conf

 for int in $interfaces; do

    for i in `grep DNSSERVERS /var/lib/dhcpcd/dhcpcd-$int.info |cut - -c 13- | tr -d "'"`; do

       echo "nameserver $i" >> /etc/resolv.conf

    done;

 done;

}

# перечисляем параметры сети GolNet

IF1="eth0" # сетевая карта GolNet

LOCAL_GOLNET=192.168.0.0/16 # сеть GolNet

LOCAL_GOLNET_MY_SEGMENT=192.168.5.0 # мой сегмент в сети GolNet

MY_LOCAL_IP_GOLNET=192.168.5.47 # мой ip в локалке GolNet

LOCAL_GW_GOLNET=192.168.5.7 # шлюз в локалку GolNetecho Прописываем нужный порядок DNS серверов в /etc/resolv.conf

write_resolv_conf "$IF1 $IF2" && echo OK

echo GOLNET

# очищаем таблицу маршрутизации local_golnet

ip route flush table local_golnetecho Определяем статические маршруты в таблице маршрутизации local_golnet

# прописываем в таблицу local_golnet путь к моему сегменту…

ip route add $LOCAL_GOLNET_MY_SEGMENT dev $IF1 src $MY_LOCAL_IP_GOLNET table local_golnet && echo OK

# …и шлюз для всего сегмента…

ip route add $LOCAL_GOLNET_MY_SEGMENT via $LOCAL_GW_GOLNET table local_golnet && echo OK

# а также шлюз по умолчанию для таблицы local_golnet

ip route add default via $LOCAL_GW_GOLNET table local_golnet && echo OK

# следующие две строки укажут ядру, в каком случае использовать таблицу local_golnet

# в данном случае — при всех обращениях с адресом источника $MY_LOCAL_IP_GOLNET.
# именно эта строка ответственна за уход ответа по тому же интерфейсу
# по которому пришёл запрос!

ip rule add from $MY_LOCAL_IP_GOLNET table local_golnet

# …и при всех обращениях в локалку Golnet

ip rule add to $LOCAL_GOLNET table local_golnet && echo OK

# перечисляем параметры сети Corbina

IF2="eth1" # сетевая карта Corbina

LOCAL_CORBINA=10.72.0.0/16 # сеть Corbina

LOCAL_GW_CORBINA=10.72.0.17 # шлюз в локалку Corbina

MY_LOCAL_IP_CORBINA=10.72.43.81 # мой ip в локалке Corbinaecho Прописываем нужный порядок DNS серверов в /etc/resolv.conf

write_resolv_conf "$IF2 $IF1" && echo OK

echo CORBINA

# очищаем таблицу маршрутизации local_corbina

ip route flush table local_corbinaecho Определяем маршруты в таблице маршрутизации local_corbina

# прописываем в таблицу local_corbina путь к локалке Corbina…

ip route add $LOCAL_CORBINA dev $IF2 src $MY_LOCAL_IP_CORBINA table local_corbina && echo OK

# …и шлюз для всего сегмента…

ip route add $LOCAL_CORBINA via $LOCAL_GW_CORBINA table local_corbina && echo OK

# а также шлюз по умолчанию для таблицы local_corbina

ip route add default via $LOCAL_GW_CORBINA table local_corbina && echo OK

# следующие две строки укажут ядру, в каком случае использовать таблицу local_golnet

# в данном случае — при всех обращениях с адресом источника $MY_LOCAL_IP_GOLNET.
# именно эта строка ответственна за уход ответа по тому же интерфейсу
# по которому пришёл запрос!

ip rule add from $MY_LOCAL_IP_CORBINA table local_corbina

# …и при всех обращениях в локалку Golnet

ip rule add to $LOCAL_CORBINA table local_corbina && echo OK

# Все оставшиеся строчки — дань особенностям построения сети корбины.
# Они заполняют таблицу правилами (ip rule, НЕ ip route!) для
# dns и vpn серверов корбины, причем сначала для dns.
# Вообще настройка интернета от Корбины под Linux– это совсем другая история,
# об этом немного подробнее будет рассказано в другом месте.

echo Обращения к DNS Корбины маршрутизировать согласно local_corbina

for DNS in `grep DNSSERVERS /var/lib/dhcpcd/dhcpcd-$IF2.info |cut - -c 13- | tr -d "'"`; do

   ip rule add to $DNS table local_corbina

done;

echo Обращения к VPN Корбины маршрутизировать согласно local_corbina

HOST_CMD="hostx"

VPN_SERVER="vpn.corbina.net"

IP_LIST="`${HOST_CMD} ${VPN_SERVER} | awk '{print $3}' `"

for ADDRESS in `echo "${IP_LIST}"`

do

   ip rule add to $ADDRESS table local_corbina

done

Заключительная проверка

Если всё прошло нормально, то после перезагрузки можно будет наблюдать примерно следующее:

testcomp # route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

192.168.5.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

10.72.0.0       0.0.0.0         255.255.0.0     U     1      0        0 eth1

127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo

Но хосты обеих локалок чудесно пингуются:

testcomp # ping -c3 192.168.4.5
PING 192.168.4.5 (192.168.4.5) 56(84) bytes of data.
64 bytes from 192.168.4.5: icmp_seq=1 ttl=63 time=12.0 ms

testcomp # ping -c1 10.72.0.17
PING 10.72.0.17 (10.72.0.17) 56(84) bytes of data.
64 bytes from 10.72.0.17: icmp_seq=1 ttl=255 time=0.609 ms

Вы просто не там смотрите. Помните, iproute2 позволяет задавать не только маршруты, но и правила их выбора:

testcomp # ip route show table local_golnet

192.168.5.0 dev eth0  scope link  src 192.168.5.47

192.168.0.0/16 via 192.168.5.7 dev eth0

default via 192.168.5.7 dev eth0testcomp # ip route show table local_corbina

10.72.0.0/16 dev eth1  scope link  src 10.72.43.81

default via 10.72.0.17 dev eth1

testcomp # ip rule

0:      from all lookup local

32753:  from 192.168.5.47 lookup local_golnet

32754:  from all to 85.21.0.0/16 lookup local_corbina

32757:  from all to 85.21.0.6 lookup local_corbina

32758:  from all to 85.21.0.5 lookup local_corbina

32759:  from all to 85.21.0.8 lookup local_corbina

32760:  from all to 85.21.0.7 lookup local_corbina

32761:  from all to 85.21.192.3 lookup local_corbina

32762:  from all to 213.234.192.8 lookup local_corbina

32763:  from all to 10.72.0.0/16 lookup local_corbina

32764:  from 10.72.43.81 lookup local_corbina

32765:  from all to 192.168.0.0/16 lookup local_golnet

32766:  from all lookup main

32767:  from all lookup default

Источники информации

Следующие ссылки могут оказать помощь в понимании механизма работы iproute2





Comments



1
Author:  Gen | Date:  Октябрь 11, 2007 | Time:  21:01

Статья полезная, даже очень, но в ней дикое количество синтаксических ошибок. В таком виде скрипт работать не будет.

2
Author:  kergma | Date:  Октябрь 12, 2007 | Time:  15:38

Все цитаты из файлов конфигурации и скриптов взяты непосредственно из рабочих файлов — изменены лишь реальные ip.

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

3
Author:  fGr | Date:  Февраль 1, 2008 | Time:  01:01

а как сделать тоже самое тока для винды?))

4
Author:  georotor.myopenid.com | Date:  Февраль 2, 2008 | Time:  02:35

Эх…, нашел бы я эту статью чуть пораньше, время бы сэкономил.
Автору респект.

P/S/
Но на счет скрипта Вы не совсем правы.
Для примера стока:

> ip route flush table local_corbinaecho Определяем маршруты в таблице маршрутизации local_corbina



Write a Comment

Or use your OpenID: