Работа одновременно с двумя выделенными линиями. Часть 2. Локальные сети и интернет
В первой части речь шла о первичной настройке одновременной работы с двумя локальными сетями, к которым присоединен ваш компьютер. Несмотря на достаточно сырое изложение материала, рекомендую прочитать сначала её — там как минимум описаны нюансы конфигурирования ядра Linux, которые надо учесть при работе с утилитами расширенного роутинга пакета iproute2.
Сейчас речь пойдёт об одновременной работе как двух локальных сетей, так и двух шлюзов в интернет, предоставляемых этими двумя сетями.
Построение маршрутов в локальные сети
Для начала сконфигурируем dhcp клиентов для обоих интерфейсов, запретив им перезаписывать /etc/resolv.conf и устанавливать маршруты по умолчанию.
Первая выдержка из /etc/conf.d/net:
modules=(”iproute2″)
config_eth0=( “dhcp” )
dhcp_eth0=”nodns nogateway”config_eth1=( “dhcp” )
dhcp_eth1=”nodns nogateway”
Убедитесь, что оба интерфейса запускаются при старте системы:
testcomp # rc-status
Runlevel: default
…
net.eth0 [ started ]
net.eth1 [ started ]
…
Я переписал скрипт /etc/conf.d/local.start, отрабатывающий при старте системы после всех остальных сервисов. Основную часть кода, строящую статические маршруты в обе локальные сети, я обобщил на случай произвольного числа локальных сетей, присоединенных к сетевым интерфейсам eth0, eth1, …, ethN. Первоначальную версию можно найти в первой части данной статьи.
Подразумевается, что все сетевые интерфейсы получают свои ip по dhcp и сети не пересекаются по диапазонам ip.
Рекомендуется внимательно прочесть и изменить необходимые параметры под свои нужды.
Выдержка из /etc/conf.d/local.start:
# Функция build_local_routing строит статические роутинги в заданную локальную сеть и
# доступные через неё сети.
# Входные параметры:
# interface -- имя сетевого интерфейса, к которому присоединена
# локальная сеть.
# routing_table -- имя или номер таблицы маршрутизации. К моменту запуска
# скрипта должны быть прописаны в /etc/iproute2/rt_tables.
# local_nets -- локальная сеть/сети, доступные через интерфейс $interface.
# Перечисляются списком через пробел, например
# "10.72.0.0/16 85.21.0.0/16"
# Для работы функции необходимо наличие:
# dhcp -- интерфейс $interface должен получать адрес по DHCP,
# а информация об адресах и прочем иметься в файле
# /var/lib/dhcpcd/dhcpcd-$interface.info, создаваемом
# клиентом dhcp.
# iproute2 -- маршруты прописываются только в ту таблицу маршрутизации,
# что отвечает за связь с локальной сетью. Также определяются
# правила использования этой таблицы маршрутизации.
# Обычная команда route ничего не знает ни про раздельные
# таблицы маршрутизации, ни про правила их использования.
# ipcalc -- эта утилита применяется для вычисления сегмента сети,
# выданного по DHCP.
function build_local_routing()
{
interface=$1
routing_table=$2
local_nets=$3
. /var/lib/dhcpcd/dhcpcd-$interface.info
network=`ipcalc $IPADDR/$NETMASK | grep Network | awk '{print $2}'`
ip route flush table $routing_table >/dev/null 2>&1
# Прописываем правила маршрутизации для DNS
for DNS in $DNSSERVERS; do
ip rule add to $DNS lookup $routing_table
done;
ip rule add from $IPADDR lookup $routing_table
ip rule add to $network lookup $routing_table
# Определяем статические маршруты в таблице маршрутизации $routing_table
# и правила их выбора
ip route add $network dev $interface src $IPADDR table $routing_table
for net in $local_nets; do
[ "$net" != "$network" ] && ip route add $net via $GATEWAYS table $routing_table
[ "$net" != "$network" ] && ip rule add to $net lookup $routing_table
done
ip route add default via $GATEWAYS table $routing_table
ip route add 127.0.0.0/8 dev lo table $routing_table
}
# Функция write_resolv_conf определяет порядок использования DNS серверов,
# доступныых через локальные сетевые интерфейсы.
# Входные параметры:
# interfaces -- локальные интерфейсы. Перечисляются списком через пробел, например
# "eth1 eth0" или "eth0 eth1". Записи о DNS заносятся
# в /etc/resolv.conf в порядке перечисления интерфейсов.
function write_resolv_conf()
{
interfaces=$*
rm -f /etc/resolv.conf
for int in $interfaces; do
. /var/lib/dhcpcd/dhcpcd-$int.info
for i in $DNSSERVERS; do
echo "nameserver $i" >> /etc/resolv.conf
done;
done;
}
build_local_routing "eth0" "local_golnet" "192.168.0.0/16"
build_local_routing "eth1" "local_corbina" "10.72.0.0/16 85.21.0.0/16"
# Прописываем нужный порядок DNS серверов в /etc/resolv.conf
write_resolv_conf "eth1 eth0"
# Обращения к VPN Корбины маршрутизировать согласно local_corbina
. /var/lib/dhcpcd/dhcpcd-eth1.info
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
ip route flush cache
После сохранения всех изменений в скриптах стартапа перезагрузим систему (редкая для Linux операция в данном случае совершенно оправдана). Если всё нормально (см. первую часть статьи), можно приступить к настройке интерфейсов интернета.
Конфигурация интерфейсов интернета
Интернет как от GolNet, так и от Corbina я получаю посредством pptp.
Вторая выдержка из /etc/conf.d/net:
config_ppp0=( “ppp” )
mtu_ppp0=”1400″
link_ppp0=”pty ‘pptp 192.168.0.3 –nobuffer –loglevel 0 –nolaunchpppd’”
username_ppp0=’user1′
password_ppp0=’passwd1′
pppd_ppp0=(
“lock”
“asyncmap 0″
“crtscts”
“nodefaultroute”
“persist”
“noauth”
“nobsdcomp”
“nodeflate”
“require-mppe”
“lcp-echo-failure 10″
“lcp-echo-interval 10″
“:172.1.1.1″
)config_ppp1=( “ppp” )
mtu_ppp1=”1400″
link_ppp1=”pty ‘pptp vpn.corbina.net –nobuffer –loglevel 0 –nolaunchpppd’”
username_ppp1=’user2′
password_ppp1=’passwd2′
pppd_ppp1=(
“noauth”
“persist”
“refuse-eap”
“refuse-pap”
“refuse-chap”
“refuse-mschap”
“nodefaultroute”
“nobsdcomp”
“nodeflate”
“:172.1.1.2″
)
Обратите особое внимание на две выделенные строчки. Я указываю для обоих интерфейсов установить заданный ip-адрес шлюза на другом конце ppp туннеля. Значения выбраны так, чтобы не пересекаться ни с одной из имеющихся у меня на машине сетей.
Подъём ppp-соединения
Сразу после подъёма любого ppp соединения у меня на машине отрабатываются скрипты /etc/ppp/ip-up.d/*, в частности, /etc/ppp/ip-up.d/90-local.sh, задающие таблицы маршрутизации, правила их выбора и маршрут по умолчанию. На других системах аналогичную роль выполняет скрипт /etc/ppp/ip-up.local. Обратитесь к документации на pptp, чтобы узнать, где находится подобный скрипт на вашей машине.
Выдержка из /etc/ppp/ip-up.d/90-local.sh:
#!/bin/sh # This script is run by pppd after the link is established. # It executes all the scripts available in /etc/ppp/ip-up.d directory, # with the following parameters: # $1 = interface name (e.g. ppp0) # $2 = tty device # $3 = speed # $4 = local IP address # $5 = remote IP address # $6 = ipparam (user specified parameter, see man pppd) if [ "$1" == "ppp0" ]; then ip rule add from $4 lookup internet_golnet ip route add 192.168.5.0/24 via 192.168.5.7 dev eth0 table internet_golnet ip route add 192.168.0.0/16 via 192.168.5.7 dev eth0 table internet_golnet ip route add 127.0.0.0/8 dev lo table internet_golnet ip route add default via $5 dev ppp0 table internet_golnet fi; if [ "$1" == "ppp1" ]; then ip rule add from $4 lookup internet_corbina ip route add 10.72.0.0/16 via 10.72.0.17 dev eth1 table internet_corbina ip route add 85.21.0.0/16 via 10.72.0.17 dev eth1 table internet_corbina ip route add 127.0.0.0/8 dev lo table internet_corbina ip route add default via $5 dev ppp1 table internet_corbina fi ip route del default ip route add default via $5
Как видим, скрипт заполняет соответствующие каждому из провайдеров таблицы маршрутизации и добавляет правило его выбора. Правило обеспечивает ответ с того же интернетного ip-адреса, на какой пришёл запрос “извне”, из интернета.
Таблицы маршрутизации internet_golnet и internet_corbina, естественно, должны быть прописаны в /etc/iproute2/rt_tables.
Параметр $5, упоминающийся в скрипте, как раз и есть тот ip-адрес шлюза на другом конце туннеля, что был в конфигурации ppp интерфейсов установлен в удобные на моей системе значения. Значение ip-адреса шлюза, не принадлежащее ни к одной из доступных на данной машине сетей, избавляет от хлопот по разведению траффика разных интерфейсов ppp и локальных сетей. В случае же автоматического назначения адресов шлюза подобное разведение траффика может являться весьма нетривиальной задачей, что хорошо известно пользователям Корбины, работающим в Linux.
Опускание ppp-соединения
При опускании любого ppp соединения у меня на машине отрабатываются скрипты /etc/ppp/ip-down.d/*, в частности, /etc/ppp/ip-down.d/90-local.sh:
#!/bin/bash ip route del default if [ $1 == "ppp0" ]; then ip rule del from $4 lookup internet_golnet ip route flush table internet_golnet ip rule flush table internet_golnet fi; if [ $1 == "ppp1" ]; then ip rule del from $4 lookup internet_corbina ip route flush table internet_corbina ip rule flush table internet_corbina fi
Как видим, здесь, в зависимости от того, какой интерфейс опущен, чистится соответствующая таблица маршрутизации и удаляется правило её выбора.
Проверка обоих ppp соединений
Поднимем оба ppp-интерфейса:
/etc/init.d/net.ppp0 start
/etc/init.d/net.ppp1 start
Секунд через десять убедимся в их наличии и функционировании:
testcomp # ip address show up
17: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast qlen 3
link/ppp
inet 11.22.33.44 peer 172.1.1.1/32 scope global ppp0
18: ppp1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast qlen 3
link/ppp
inet 55.66.77.88 peer 172.1.1.2/32 scope global ppp1
Убедимся, что ya.ru (к примеру) пингуется с обоих интерфейсов:
testcomp # ping -c2 -I ppp0 ya.ru PING ya.ru (213.180.204.8) from 11.22.33.44 ppp0: 56(84) bytes of data. 64 bytes from ya.ru (213.180.204.8): icmp_seq=1 ttl=60 time=20.6 ms 64 bytes from ya.ru (213.180.204.8): icmp_seq=2 ttl=60 time=11.5 ms --- ya.ru ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1004ms rtt min/avg/max/mdev = 11.588/16.103/20.618/4.515 ms testcomp # ping -c2 -I ppp1 ya.ru PING ya.ru (213.180.204.8) from 55.66.77.88 ppp1: 56(84) bytes of data. 64 bytes from ya.ru (213.180.204.8): icmp_seq=1 ttl=58 time=2.68 ms 64 bytes from ya.ru (213.180.204.8): icmp_seq=2 ttl=58 time=2.81 ms --- ya.ru ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 2.682/2.747/2.812/0.065 ms
Пропингуем с какого-либо компа, где у вас есть доступ в шелл, оба ваших ip:
guest $ ping -c2 11.22.33.44 PING 11.22.33.44 (11.22.33.44) 56(84) bytes of data. 64 bytes from 11.22.33.44: icmp_seq=0 ttl=38 time=209 ms 64 bytes from 11.22.33.44: icmp_seq=1 ttl=38 time=209 ms --- 11.22.33.44 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 209.514/209.553/209.592/0.039 ms, pipe 2 guest $ ping -c2 55.66.77.88 PING 55.66.77.88 (55.66.77.88) 56(84) bytes of data. 64 bytes from 55.66.77.88: icmp_seq=0 ttl=53 time=205 ms 64 bytes from 55.66.77.88: icmp_seq=1 ttl=53 time=200 ms --- 55.66.77.88 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 200.857/203.083/205.309/2.226 ms, pipe 2
Версии использованного программного обеспечения и ссылки
При отладке использовалось:
- Операционная система GNU/Linux Gentoo
- Версия ядра 2.6.17
- iproute2 2.6.22.20070710
- ipcalc 0.41
- ppp 2.4.4-r13
- pptp 1.7.1
- dhcpcd 3.1.5
Неоценимую помощь в поиске глюков pptp оказала ссылка на
PPTP Client: Diagnosis HOWTO.

Write a Comment