Работа одновременно с двумя выделенными линиями. Часть 1.
<a href="http://www.linuxetc.ru/?p=12" class="forlinuxetc">(Оригинал написан для linuxetc.ru)</a> По ряду причин я решил купить домой вторую выделенную линию. Пришли монтажники из Корбины, провели мне вторую линию, воткнули во вторую сетевую карту, проверили на работоспособность и ушли. А я остался настраивать оба интернета :-).
Поднял вчерне оба интернета -- от районной сети GolNet и от Корбины -- и решил пропинговать извне одновременно оба своих ip. Результат: корбиновский ip пингуется, голнетовский нет. Через минуту я понял, что так и должно быть -- ответ на пакет от GolNet уходил по дефолтному роутингу на корбиновский интерфейс и, естественно, не получался тем, кто пингует голнетовский ip-адрес.
Поскольку одна из задач второй выделенной линии заключалась как раз в возможности доступа к моему компьютеру с <strong>любого из двух ip из интернета</strong>, такое поведение меня ни капли не устроило и я стал искать решение.
Поиск в интернете в конце концов вывел меня на пакет iproute2 -- подсистема расширенного роутинга под Linux.
<!--break-->
Изучив <a HREF="http://www.opennet.ru/docs/RUS/LARTC/x348.html">главу из Linux Advanced Routing & Traffic Control HOWTO</a>, я решил для начала построить нечто аналогичное для интерфейсов в локальные сети GolNet и Corbina соответственно. Вот что получилось в итоге.
Всё проверено на системе на базе Gentoo, в других системах расположение системных файлов и их содержимое может сегка различаться.
<h3>Необходимые условия</h3>
Убедитесь, что в ядре включены все необходимые опции. Это опция
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 может понадобиться выполнить команды
<pre>
emerge dhcpcd
emerge iproute2</pre>
<h3>Конфигурирование</h3>
Выдержка из /etc/conf.d/net:
<blockquote> modules=("iproute2")
config_eth0=( "dhcp" )
dhcp_eth0="nodns nogateway"
config_eth1=( "dhcp" )
dhcp_eth1="nodns nogateway"</blockquote>
Здесь важно обратить внимание на опции dhcp для обоих интерфейсов -- /etc/resolv.conf <strong>не</strong> перезаписывается и роутинги на шлюзы в локалки автоматом не прописываются. Всё это происходит чуть позднее, в /etc/conf.d/local.start (в других unix-системах это, возможно, надо писать куда-то вроде /etc/rc.local).
Однако, прежде чем вносить записи о роутингах, надо указать системе iproute2 имена таблиц роутинга, по которым мы разложим правила роутинга.
Выдержка из /etc/iproute2/rt_tables:
<blockquote> 1 local_golnet
2 local_corbina</blockquote>
Главное, чтобы номера таблиц нигде больше в /etc/iproute2/rt_tables не повторялись.
Теперь можно заполнить таблицы <strong>локальных</strong> роутингов.
Выдержка из /etc/conf.d/local.start:
<blockquote># функция write_resolv_conf просто заполняет /etc/resolv.conf записями относительно dns-серверов
# локалок в указанном порядке интерфейсов.
<pre>
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;
}</pre>
# перечисляем параметры сети GolNet
<pre>
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</pre>
# очищаем таблицу маршрутизации local_golnet
<pre>
ip route flush table local_golnetecho Определяем статические маршруты в таблице маршрутизации local_golnet</pre>
# прописываем в таблицу local_golnet путь к моему сегменту...
<pre>
ip route add $LOCAL_GOLNET_MY_SEGMENT dev $IF1 src $MY_LOCAL_IP_GOLNET table local_golnet && echo OK</pre>
# ...и шлюз для всего сегмента...
<pre>
ip route add $LOCAL_GOLNET_MY_SEGMENT via $LOCAL_GW_GOLNET table local_golnet && echo OK</pre>
# а также шлюз по умолчанию для таблицы local_golnet
<pre>
ip route add default via $LOCAL_GW_GOLNET table local_golnet && echo OK</pre>
# следующие две строки укажут ядру, в каком случае использовать таблицу local_golnet
# в данном случае -- при всех обращениях с адресом источника $MY_LOCAL_IP_GOLNET.
# <strong>именно эта строка ответственна за уход ответа по тому же интерфейсу</strong>
# <strong>по которому пришёл запрос!</strong>
<pre>
ip rule add from $MY_LOCAL_IP_GOLNET table local_golnet</pre>
# ...и при всех обращениях в локалку Golnet
<pre>
ip rule add to $LOCAL_GOLNET table local_golnet && echo OK</pre>
# перечисляем параметры сети Corbina
<pre>
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</pre>
# очищаем таблицу маршрутизации local_corbina
<pre>
ip route flush table local_corbinaecho Определяем маршруты в таблице маршрутизации local_corbina</pre>
# прописываем в таблицу local_corbina путь к локалке Corbina...
<pre>
ip route add $LOCAL_CORBINA dev $IF2 src $MY_LOCAL_IP_CORBINA table local_corbina && echo OK</pre>
# ...и шлюз для всего сегмента...
<pre>
ip route add $LOCAL_CORBINA via $LOCAL_GW_CORBINA table local_corbina && echo OK</pre>
# а также шлюз по умолчанию для таблицы local_corbina
<pre>
ip route add default via $LOCAL_GW_CORBINA table local_corbina && echo OK</pre>
# следующие две строки укажут ядру, в каком случае использовать таблицу local_golnet
# в данном случае -- при всех обращениях с адресом источника $MY_LOCAL_IP_GOLNET.
# <strong>именно эта строка ответственна за уход ответа по тому же интерфейсу</strong>
# <strong>по которому пришёл запрос!</strong>
<pre>
ip rule add from $MY_LOCAL_IP_CORBINA table local_corbina</pre>
# ...и при всех обращениях в локалку Golnet
<pre>
ip rule add to $LOCAL_CORBINA table local_corbina && echo OK</pre>
# Все оставшиеся строчки -- дань особенностям построения сети корбины.
# Они заполняют таблицу правилами (ip rule, НЕ ip route!) для
# dns и vpn серверов корбины, причем сначала для dns.
# Вообще настройка интернета от Корбины под Linux-- это совсем другая история,
# об этом немного подробнее будет рассказано в другом месте.
<pre>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</pre>
</blockquote>
<h3>Заключительная проверка</h3>
Если всё прошло нормально, то после перезагрузки можно будет наблюдать примерно следующее:
<blockquote>
<pre>
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</pre>
</blockquote>
Но хосты обеих локалок чудесно пингуются:
<blockquote> 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</blockquote>
Вы просто не там смотрите. Помните, iproute2 позволяет задавать не только маршруты, но и правила их выбора:
<blockquote>
<pre>
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</pre>
</blockquote>
<h3>Источники информации</h3>
Следующие ссылки могут оказать помощь в понимании механизма работы iproute2
<ul>
<li><a HREF="http://www.opennet.ru/docs/RUS/LARTC/">Linux Advanced Routing & Traffic Control HOWTO</a>.</li>
<li><a HREF="http://www.opennet.ru/base/net/iproute2.txt.html">http://www.opennet.ru/...
<li><a HREF="http://www.indi.snc.ru/bbtopic5100">http://www.indi.snc.ru/bbtopic5100</...
</ul>
Add new comment