Домашний резервный канал своими руками

Довольно долго у меня в квартире стоял Стрим. Этим летом в доме появилась оптика от Корбины, к которой я сразу же подключился - поскольку заметно выше скорость и канал симметричный.

Где-то через неделю я осознал что висящий на стене без дела ADSL-модем меня раздражает; кроме того, зная возможности Asus WL500g, я всегда был уверен, что такую несложную вещь как резервный канал на нем реализовать вполне можно.

Итак, исходный расклад:

  • ADSL-модем ZyXEL Omni ADSL LAN в режиме bridge
  • WiFi-роутер ASUS WL500g Deluxe с установленной OpenWRT White Russian 0.9, pptp-сборка
  • Локальная сеть 192.168.1.0/24
  • В WAN-порт на WL500g приходит аплинк от Корбины
  • PPTP-сессия с Корбиной поднимается автоматически при загрузке роутера (сделано на самописных скриптах)

Установленная на момент подъема второго линка конфигурация корбины:

   # cat /etc/ppp/peers/corbina
   pty "pptp vpn.corbina.net --nolaunchpppd"
   unit 0
   name <username>
   remotename corbina
   ipparam corbina
   file /etc/ppp/options.pptp
   logfile /tmp/corbina.log
   maxfail 0
   persist
   usepeerdns
   defaultroute
   replacedefaultroute

   # cat /etc/ppp/options.pptp
   lock 
   noauth 
   nobsdcomp 
   nodeflate
   lcp-echo-failure 5
   lcp-echo-interval 5

   # cat /etc/ppp/chap-secrets
   #USERNAME       PROVIDER        PASSWORD        IPADDRESS
   <username>      corbina         <password>      *
В /etc/ppp/ip-up.d и /etc/ppp/ip-down.d лежат скрипты, отвечающие за проброс портов для торрента и дополнительную фильтрацию на PPP-интерфейсах.

В /etc/init.d лежит подъем статических маршрутов и подъем PPTP-сессии (командой pppd call corbina).

Подробно я здесь их расписывать не буду, все это можно найти в массе открытых источников. Единственное, что стоит отметить: в White Russian 0.9 присутствует баг в ресолвере, из-за которого он не работает нормально, если к доменному имени привязано слишком большое кол-во адресов. Поэтому понравившийся IP-адрес из тех, по которым ресолвится vpn.corbina.net, лучше прописывать в /etc/hosts.

Ethernet-порт модема по умолчанию сконфигурирован на адрес 10.0.0.1 - не годится, т.к. этот диапазон адресов используется для корбиновской локальной сети. Заходим в веб-конфигуратор и меняем основной адрес модема на 192.168.2.1, DHCP выключаем от греха.

Дальше самая интересная часть. WL500g по умолчанию имеет 5 Ethernet-портов, один из которых считается портом для аплинка, и 4 - портами для локальной сети. На самом деле это чистая условность. По умолчанию роутер содержит два VLAN-а: vlan1 - аплинк и vlan0 - локальная сеть. Выглядит это вот так:

   # nvram show | grep vlan | sort
   vlan0hwname=et0
   vlan0ports=1 2 3 4 5*
   vlan1hwname=et0
   vlan1ports=0 5
   wan_device=vlan1
   wan_ifname=vlan1
Для Стрима нужно сделать еще один VLAN, отдав под него один из “локальных” Ethernet-портов. Пусть это будет порт #1 (на корпусе WL500g он физически промаркирован как 4).
   # nvram set vlan2hwname=et0
   # nvram set vlan2ports=1 5
   # nvram set vlan0ports=2 3 4 5*
   # nvram commit
Далее, нужно создать псевдоним сетевого интерфейса, который будет корректно распознан скриптами OpenWRT при загрузке системы. Пусть это будет, например, wan2.
   # nvram set wan2_ifname=vlan2
   # nvram set wan2_ifnames=vlan2
   # nvram set wan2_ipaddr=192.168.2.2
   # nvram set wan2_netmask=255.255.255.0
   # nvram set wan2_proto=static
   # nvram commit
Обратите внимание, что IP-адрес в той же подсети, что и основной адрес модема (на всякий случай - для протокола PPPoE это вообще говоря не обязательно).
Открываем файл /etc/init.d/S40network и находим строчку
   ifup_interfaces=${ifup_interfaces:-"lan wan wifi"}
Меняем ее на
   ifup_interfaces=${ifup_interfaces:-"lan wan wifi wan2"}
NB: того же эффекта можно добиться командами
   
   # nvram set ifup_interfaces="lan wan wifi wan2"
   # nvram commit
После перезагрузки в списке сетевых интерфейсов должен появиться vlan2 в таком примерно виде:
   # ifconfig vlan2
   vlan2     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX  
             inet addr:192.168.2.2  Bcast:192.168.2.255  Mask:255.255.255.0
             UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
             RX packets:0 errors:0 dropped:0 overruns:0 frame:0
             TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
             collisions:0 txqueuelen:0 
             RX bytes:0 (0)  TX bytes:0 (0)
ADSL-модем, если его подключить к сконфигурированному порту (не забываем, что на корпусе он промаркирован как 4), будет нормально пинговаться.

Конфигурируем протокол PPPoE. Поскольку у нас PPTP-сборка, по умолчанию необходимых модулей в системе нет. Ставим их:

   # ipkg install kmod-pppoe
   # ipkg install ppp-mod-pppoe
После этого в Web-интерфейсе даже появится опция для конфигурирования PPPoE-аплинка, но пользоваться ей не нужно - конфигурация нестандартная, поэтому все делаем руками.

В файл /etc/modules добавляем две строчки:
   pppox
   pppoe
Перезагружаем роутер. После перезагрузки эти модули должны присутствовать в выводе команды lsmod:
   
   # lsmod
   ...
   pppoe                   9416   0
   pppox                   1372   1 [pppoe]
   ...
Редактируем конфиги PPPD:
   # vi /etc/ppp/options.pppoe 
   plugin rp-pppoe.so
   connect /bin/true
   mtu 1492
   mru 1492
   lcp-echo-failure 5
   lcp-echo-interval 5

   # vi /etc/ppp/peers/stream
   name pppXXXXXXX@mtu
   unit 1
   remotename stream
   ipparam stream
   file /etc/ppp/options.pppoe
   logfile /tmp/stream.log
   maxfail 0
   persist
   usepeerdns
   defaultroute
   replacedefaultroute
   nic-vlan2          

   # vi /etc/ppp/chap-secrets
   #USERNAME       PROVIDER        PASSWORD        IPADDRESS
   <username>      corbina         <password>      *
   pppXXXXXXX@mtu  stream          <password<      *
Все готово! Проверяем работоспособность второго аплинка, для этого сначала опускаем соединение с корбиной (если оно было поднято):
   # cd /tmp
   # kill `head run/ppp0.pid`
Поднимаем PPPoE-сессию:
   # pppd call stream

Bonus track: протокол L2TP. Этот протокол анонсируется Корбиной как “экспериментальный”, поэтому неизвестно, будет ли он поддерживаться в будущем. Подробно про него можно почитать, например, в Wikipedia. Для того, чтобы запустить этот протокол под OpenWRT, нужно установить соответствующие пакеты. Я по итогам сравнений и экспериментов сделал следующим образом:

    # ipkg install rp-l2tpd
    # ipkg install rp-l2tpd-mod-cmd
    # ipkg install rp-l2tpd-mod-ppp
Можно было бы вместо этого поставить l2tpd из backports, но он работает только в user mode и поэтому менее производительный. rp-l2tpd в большей степени, насколько мне удалось понять, использует ядро. Однако с ним есть нюанс: для того, чтобы l2tpd смог поднять ppp-сессию, ему нужны два kernel-модуля, которые по умолчанию в OpenWRT не собираются. Называются они ppp_synctty.o и n_hdlc.o, и находятся Гуглом достаточно быстро - я брал, например, вот отсюда. Оба модуля, разумеется, нужно добавить в /etc/modules, чтобы они загружались автоматически. Итак, складываем модули в /lib/modules/2.4.30. Далее
    # insmod n_hdlc
    # insmod ppp_synctty
Редактируем /etc/l2tp.conf
    # Global section (by default, we start in global mode)
    global
    load-handler "sync-pppd.so"
    load-handler "cmd.so"

    # Bind address
    listen-port 1701

    # Configure the sync-pppd handler.  You MUST have a "section sync-pppd" line
    # even if you don't set any options.
    section sync-pppd
    lac-pppd-opts "file /etc/ppp/options.l2tp"

    # Peer section
    section peer
    peer 85.21.17.251
    lac-handler sync-pppd
    hide-avps yes

    # Configure the cmd handler.  You MUST have a "section cmd" line
    # even if you don't set any options.
    section cmd
Редактируем /etc/ppp/options.l2tp
    unit 0
    name <username>
    remotename corbina
    ipparam corbina
    usepeerdns
    defaultroute
    replacedefaultroute
    nodeflate
    nobsdcomp
    noauth
    persist
    maxfail 0
    mtu 1250
    mru 1250
Добавляем строчку в /etc/ppp/chap-secrets
    <username>      bras255         <password>      *
Странное слово bras255 - это название, которым идентифицирует себя корбиновский l2tp-сервер. Оно нужно, чтобы все работало. Пароль и логин при этом, естественно, обычные. Все готово. Опускаем текущую сессию
    # killall pppd
Поднимаем l2tpd
    # /usr/bin/l2tpd
Инициируем сессию l2tp
    # l2tp-control 'start-session 85.21.17.251' 
Если все было сделано правильно - интернет будет работать через l2tp.

Удачи!