Решение не универсальное, но, как мне кажется, очень простое и на его основе неискушенные пользователи смогут, если не создать свое, то просто расширить свой кругозор и понимание этой популярной прошивки.
Я использую роутер asus rt-n16 и прошивку от тов. Kong 22000++. Интернет от основного провайдера приходит ко мне по кабелю, все настройки получаются роутером по dhcp. В интерфейса dd-wrt это выглядит как-то так:
Фактически, все по умолчанию. Адрес роутера во внутренней сети сменен на 192.168.199.1.
Переключение каналов интернета будет выполняться скриптом, который мы создадим во внутренней памяти роутера JFFS2, соответственно, нужно эту внутреннюю память включить. Для этого в разделе Administration-Mangement интерфейса dd-wrt включим соответствующую опцию:
После включения JFFS2 память нужно очистить. Для этого выберем «Clean JFFS2» и нажмем применить. Возможно, нужно будет перезагрузить роутер. Наша задача — добиться того, чтобы появилось свободное место в этой памяти.
Теперь зайдем на роутер при помощи telnet. Я использую для этого putty:
putty -telnet 192.168.199.1
Имя пользователя root, даже если для логина в вебинтерфейс dd-wrt вы используете другое имя. Пароль — тот, который вы используете для логина в вебинтерфейс.
root@DD-WRT:~# nvram show >/dev/null
size: 29978 bytes (2790 left)
Как видите, свободных байт в nvram немного и именно поэтому мы там не станет хранить наши скрипты. Если эта память исчерпается, то роутер перезагрузиться и восстановит все конфиги dd-wrt по умолчанию. Поэтому же, не стоит, например, загружать сертификаты openvpn в вебинтерфейсе, потому как сохраненные через вебинтерфейс сертификаты будут храниться в переменных nvram. Сертификаты openvpn можно хранить в памяти jffs2 и подключать их в переменной «additional config» настроек openvpn таким образом:
Следующий шаг. Мы подключаем резервный кабель в порт LAN1 роутера. В моем случае резервный кабель идет от оборудования GPON, которое поставил МГТС. Это оборудование раздает интернет в своей локальной сети 192.168.100.0/255.255.255.0. Нам нужно будет «оторвать» необходимый порт нашего роутера от остальных портов и назначить ему адрес из сети оборудования GPON, например, 192.168.100.200.
Теперь информация специфичная для конкретной железки, а именно asus rt-n16. Наберем в терминале следующие команды и посмотрим ответ:
root@DD-WRT:~# nvram show | grep vlan.*port
vlan2ports=0 8
vlan0ports=1 2 3 4 5*
vlan1ports=4 3 2 1 8*
size: 29978 bytes (2790 left)
root@DD-WRT:~# nvram show | grep vlan.*hw
vlan2hwname=et0
vlan1hwname=et0
vlan0hwname=et0
size: 29978 bytes (2790 left)
Группы портов объединенны в вэланы. Порт 0 — это WAN порт роутера, порты 1234 — это порты роутера, которые соответствуют (внимание!) портам LAN4,LAN3,LAN2,LAN1 роутера, то есть порт 4 подписан на корпусе роутера LAN1. Порт 8 и порт 8* — это порты процессора, через них мы будем видеть интерфейсы в роутере. Я не хочу вдаваться в подробности, принципиально то, что любой вэлан должен замыкаться на процессор роутера. Давайте «оторвем» 4-ый порт:
root@DD-WRT:~# nvram set vlan0ports="1 2 3 5*"
root@DD-WRT:~# nvram set vlan1ports="3 2 1 8*"
а теперь назначим 4 порт в 3-ий вэлан
root@DD-WRT:~# nvram set vlan3ports="4 8"
для того, чтобы новый вэлан был виден, нужно ввести команду
root@DD-WRT:~# nvram set vlan3hwname=et0
сохраним изменения
root@DD-WRT:~# nvram commit
По аналогии, можно сделать для других роутеров с прошивкой dd-wrt.
Теперь нелирическое отступление. В вебинтерфейсе ddwrt есть настройки вэланов. Но если попробовать с ними поиграть, то мало того, что ничего не получится, но может случиться, что дальше поможет только сброс роутера.
root@DD-WRT:~# erase nvram
root@DD-WRT:~# reboot
Если вы «поиграли» с вэланами и все перестало работать, то вышеприведенные полный сброс «30 30 30» может помочь.
Адрес нашему новому интерфейсу, который связан с 4-ым портом, мы будем назначать из скрипта при старте. Поэтому, давайте начнём этот скрипт писать. Но прежде, где он будет храниться. Как учит нас
/jffs/etc/config/
с расширением .startup выполняется при запуске системы до того, как файрвол будет сконфигурирован. Назовём наш скрипт vlan3.startup и напишем следующие строки:#!/bin/sh
WAN2_IFNAME=vlan3
WAN2_IPADDR=192.168.100.200
WAN2_GATEWAY=192.168.100.1
WAN2_NETMASK=255.255.255.0
if [ "$(nvram get wan2_ipaddr)" != "$WAN2_IPADDR" ]; then
nvram set wan2_ifname=$WAN2_IFNAME
nvram set wan2_ipaddr=$WAN2_IPADDR
nvram set wan2_gateway=$WAN2_GATEWAY
nvram set wan2_netmask=$WAN2_NETMASK
nvram commit
fi
ifconfig $(nvram get wan2_ifname) up $(nvram get wan2_ipaddr) netmask $(nvram get wan2_netmask)
В этих строках всё просто. Мы завели в nvram 4-ре новые переменные и занесли в них название интерфейса, адрес, маску и шлюз для нашего резервного порта интернет. Каждый раз при старте мы проверяем, что адрес именно тот, который задан в переменной скрипта, это на случай, если потребуется поменять настройки резервного интернета. Далее кофигурируем порт заданными значениями. С текущими переменными это выглядело бы так:
ifconfig vlan3 up 192.168.100.200 netmask 255.255.255.0
Добавим к нашему скрипту бесконечный цикл, в котором и будем переключать интернет канал на резервный и обратно:
INTERVAL=30
while sleep $INTERVAL
do
WAN1ALIVE=0
WAN2USING=0
WAN1GW=`nvram get wan_gateway`
echo "check"
if [ "$WAN1GW" != "0.0.0.0" ]; then
if [ "1" = `ping -c 1 $WAN1GW 2>/dev/null | awk '/packets received/ {print $4}'` ]; then
WAN1ALIVE=1
echo "wan1alive"
fi
fi
TARGET=`ip -4 route list 0/0 | awk -v gate="via "$WAN2_GATEWAY '$0 ~ gate {print $3}'`
if [ ! -z "$TARGET" ]; then
WAN2USING=1
echo "wan2using"
fi
if [ "$WAN1ALIVE" = "1" ] && [ "$WAN2USING" = "1" ]; then
/jffs/etc/config/wan1.up
echo "Changed active WAN port to 1!"
fi
if [ "$WAN1ALIVE" = "0" ] && [ "$WAN2USING" = "0" ]; then
if [ "1" = `ping -c 1 $WAN2_GATEWAY 2>/dev/null | awk '/packets received/ {print $4}'` ]; then
/jffs/etc/config/wan2.up
echo "Changed active WAN port to 2!"
fi
fi
done;
Словами этот длинный кусок кода можно описать так. Каждые n-цать секунд мы проверяем:
- Текущий адрес шлюза основного канала. Он хранится в переменной wan_gateway в nvram и назначается автоматически, когда основной шлюз получает параметры по dhcp от основного провайдера. Если этот адрес не равен «0.0.0.0», а «0.0.0.0» он равен тогда, когда адрес не может быть получен, то есть провайдер лежит, мы его пингуем и в случае ответа устанавливаем флаг WAN1ALIVE в единицу, то есть основной канал предполагается рабочим.
- Присутствует ли адрес резервного шлюза в таблице роутинга. Если присутствует, то устанавливаем флаг WAN2USING=1, то есть в данный момент используется резервный интернет канал.
- Если основной канал работает и используется резервный канал, то переключаемся на основной канал интернет.
- Если основной канал не работает и не используется резервный канал, то тестируем доступность шлюза резервного канала и переключаемся на рабочий резерв.
Скрипт включения основного канала wan1.up:
#!/bin/sh
# WAN1
DEV=vlan2
GATEWAY=`nvram get wan_gateway`
DNS1=8.8.8.8
DNS2=8.8.4.4
nvram set wan_dns="$DNS1 $DNS2"
while ip route del default; do :; done
ip route add default via $GATEWAY dev $DEV
echo "nameserver $DNS1" >/tmp/resolv.dnsmasq
echo "nameserver $DNS2" >>/tmp/resolv.dnsmasq
pr="$(ps|awk '/dnsmasq/ {print $1}')"
kill -9 $pr
dnsmasq --conf-file=/tmp/dnsmasq.conf
Здесь все просто. Удалили все шлюзы по умолчанию. Да-да, их может быть несколько: если после перезагрузки роутера был недоступен основной канал, то включается резервный интернет и мы имеем один шлюз по умолчанию. Если затем начинает работать основной канал, dd-wrt добавляет ещё один шлюз по умолчанию. Тут уж ничего не поделать. Не хотелось долго думать и появился «грязный хак»:
while ip route del default; do :; done
, а именно удалять все шлюзы по умолчанию, пока не случится ошибка из-за того, что шлюзов больше нет. Некрасиво, придумайте, как лучше.После того, как удалили все шлюзы по умолчанию, добавим новый шлюз, который записан в переменную wan_gateway nvram (его туда записала логика dd-wrt при получения параметров от основного провайдера). Заменим dns на dns гугл, убьем процесс dnsmasq и запустим этот процесс вновь.
Скрипт для включения резервного канала wan2.up устроен таким-же образом, но адрес шлюза берётся из пременной wan2_gateway nvram и используется интерфейс связанный с 4-ым портом роутера.
#!/bin/sh
# WAN2
DEV=vlan3
GATEWAY=`nvram get wan2_gateway`
DNS1=8.8.8.8
DNS2=8.8.4.4
nvram set wan_dns="$DNS1 $DNS2"
while ip route del default; do :; done
ip route add default via $GATEWAY dev $DEV
echo "nameserver $DNS1" >/tmp/resolv.dnsmasq
echo "nameserver $DNS2" >>/tmp/resolv.dnsmasq
pr="$(ps|awk '/dnsmasq/ {print $1}')"
kill -9 $pr
dnsmasq --conf-file=/tmp/dnsmasq.conf
Остался маленький скриптик vlan3.wanup, который выполняется после поднятия WAN, сразу после того, как включится файрволл:
#!/bin/sh
iptables -t nat -A POSTROUTING -o $(nvram get wan2_ifname) -j SNAT --to $(nvram get wan2_ipaddr)
Назначение скриптика — добавить правило для ната через резервный интерфейс.
Теперь можно перезагрузить роутер и тестировать. Все скрипты были взяты из моего роутера который живёт своей жизнь и тестирует полученную конфигурацию продолжительное время.
nvram set vlan0ports="1 2 3 5*"
nvram set vlan1ports="3 2 1 8*"
nvram set vlan3ports="4 8"
nvram set vlan3hwname=et0
nvram commit
mkdir -p /jffs/etc/config
cat << 'EOF' > /jffs/etc/config/vlan3.startup
#!/bin/sh
WAN2_IFNAME=vlan3
WAN2_IPADDR=192.168.100.200
WAN2_GATEWAY=192.168.100.1
WAN2_NETMASK=255.255.255.0
if [ "$(nvram get wan2_ipaddr)" != "$WAN2_IPADDR" ]; then
nvram set wan2_ifname=$WAN2_IFNAME
nvram set wan2_ipaddr=$WAN2_IPADDR
nvram set wan2_gateway=$WAN2_GATEWAY
nvram set wan2_netmask=$WAN2_NETMASK
nvram commit
fi
ifconfig $(nvram get wan2_ifname) up $(nvram get wan2_ipaddr) netmask $(nvram get wan2_netmask)
INTERVAL=30
while sleep $INTERVAL
do
WAN1ALIVE=0
WAN2USING=0
WAN1GW=`nvram get wan_gateway`
echo "check"
if [ "$WAN1GW" != "0.0.0.0" ]; then
if [ "1" = `ping -c 1 $WAN1GW 2>/dev/null | awk '/packets received/ {print $4}'` ]; then
WAN1ALIVE=1
echo "wan1alive"
fi
fi
TARGET=`ip -4 route list 0/0 | awk -v gate="via "$WAN2_GATEWAY '$0 ~ gate {print $3}'`
if [ ! -z "$TARGET" ]; then
WAN2USING=1
echo "wan2using"
fi
if [ "$WAN1ALIVE" = "1" ] && [ "$WAN2USING" = "1" ]; then
/jffs/etc/config/wan1.up
echo "Changed active WAN port to 1!"
fi
if [ "$WAN1ALIVE" = "0" ] && [ "$WAN2USING" = "0" ]; then
if [ "1" = `ping -c 1 $WAN2_GATEWAY 2>/dev/null | awk '/packets received/ {print $4}'` ]; then
/jffs/etc/config/wan2.up
echo "Changed active WAN port to 2!"
fi
fi
done;
EOF
chmod +x /jffs/etc/config/vlan3.startup
cat << 'EOF' > /jffs/etc/config/vlan3.wanup
#!/bin/sh
iptables -t nat -A POSTROUTING -o $(nvram get wan2_ifname) -j SNAT --to $(nvram get wan2_ipaddr)
EOF
chmod +x /jffs/etc/config/vlan3.wanup
cat << 'EOF' > /jffs/etc/config/wan1.up
#!/bin/sh
# WAN1
DEV=vlan2
GATEWAY=`nvram get wan_gateway`
DNS1=8.8.8.8
DNS2=8.8.4.4
nvram set wan_dns="$DNS1 $DNS2"
#`ip -4 route list 0/0 | awk '/default via/ {print "ip route delete default"}'` | sh
# ip route delete default
while ip route del default; do :; done
ip route add default via $GATEWAY dev $DEV
echo "nameserver $DNS1" >/tmp/resolv.dnsmasq
echo "nameserver $DNS2" >>/tmp/resolv.dnsmasq
pr="$(ps|awk '/dnsmasq/ {print $1}')"
kill -9 $pr
dnsmasq --conf-file=/tmp/dnsmasq.conf
EOF
chmod +x vi /jffs/etc/config/wan1.up
cat << 'EOF' > /jffs/etc/config/wan2.up
#!/bin/sh
# WAN2
DEV=vlan3
GATEWAY=`nvram get wan2_gateway`
DNS1=8.8.8.8
DNS2=8.8.4.4
nvram set wan_dns="$DNS1 $DNS2"
#`ip -4 route list 0/0 | awk '/default via/ {print "ip route delete default"}'`|sh
# ip route delete default
while ip route del default; do :; done
ip route add default via $GATEWAY dev $DEV
echo "nameserver $DNS1" >/tmp/resolv.dnsmasq
echo "nameserver $DNS2" >>/tmp/resolv.dnsmasq
pr="$(ps|awk '/dnsmasq/ {print $1}')"
kill -9 $pr
dnsmasq --conf-file=/tmp/dnsmasq.conf
EOF
chmod +x /jffs/etc/config/wan2.up
Безусловно, можно и нужно многое поправить\добавить, но моя цель, а именно быстро прикрутить дома резервный канал — выполнена. Главная неприятность — это файрволл и проброс портов при работе с резервным каналом, мне они были не нужны, поэтому я не настраивал. Для тех, кому надо — дополняйте скрипт vlan3.wanup. Желаю удачи в ваших продолжениях!
Идеи статьи были почерпнуты из dd-wrt wiki.
Комментарии (18)
EminH
21.07.2015 11:54А есть устройства с такой возможностью «из коробки»?
kharlashkin
21.07.2015 12:08Это же устройство но с другой прошивкой для DualWan «из коробки» (AsusWRT-Merlin) ссылка на форум «прошивок от Олега».
(Upd. Может не туда написал)
frizzyH
21.07.2015 13:05Есть Asus RT-N66U у которого заявлен Dual Link support. На сколько я понял, можно переназначить один из ethernet портов как WAN
D1abloRUS
21.07.2015 13:03А вот такой вопрос, устройство такое же прошивка та же, есть linux машина на ней vlan интерфейс(id 100) на нем поднят dhcp, есть гостевой ssid wl0.1, нужно к этому ssid привязать тэг, чтобы адреса раздавались с linux машины, настраивал кто подобное?
Ivan_83
21.07.2015 22:22Давно уже заменил dnsmasq на unbound для работы в качестве кеша+рекурсера, с тех пор больше нет необходимости прописывать днс, тк unbound сам обновляет список корневых серверов, и сам резолвит рекурсивно начиная с корневых.
dnsmasq остался для DHCP и иногда tftp.
8.8.8.8 — это слив всех своих похождений гуглу. Нафига это делать непонятно.kacang
22.07.2015 14:46А можно поподробнее? Очень интересно…
Ivan_83
24.07.2015 06:53unbound это кеширущий DNS сервер со своим рекурсером.
Свой рекурсер означает что unbound нуждается только в списке корневых DNS серверов, дальше он рекурсивно (по цепочке) опрашивает сервера пока не находит то что ищет.
Те провайдеры по сути ставят себе тоже самое, у кого то bind, у кого то powerdns а кто то на ubound, и адреса этих серверов они дают пользователям.
Когда находит — складывает в кеш.
Умеет IPv6, DNSSEC (включая эцп по ГОСТ), умеет сам отдавать простенькие записи, пересылать запросы к определённым зонам на указанные сервера, какие то там скрипты выполнять… Создан чтобы работать под большой нагрузкой.
Если прописать пересылку запросов к. на какой то другой рекурсер с кешем то фактически рекурсия перестанет работать и он будет как dnsmasq только кешировать.
Обычно собираю с поддержкой тредов и без libevent, поддержку ГОСТ включаю, хотя DNSSEC у меня отключён.
Я не рекомендую использовать рекурсер тем кто ходит в нет через 2/3/4G, и скорее всего через вайфай (не дома а радио до дома), потому что если провайдерский DNS не падает, то он будучи на жирном канале и с горячим кешем способен быстрее выдавать результат.
А вот когда провайдерский DNS часто тормозит и падает, или когда приходится часто менять провайдера то это будет по лучше, чем всякие левые рекурсеры с кешем.
Кстати, когда я ещё не поставил unbound то прописывал в dnsmasq кучу чужих днс серверов, и помимо 8.8.8.8 от гугла, чего то там от яндекса и opendns существует ещё куча всяких открытых серверов (или была, года 4 назад).
Например, для сектантов из цыски: 64.102.255.44 и 128.107.241.185.
Вот мой старый список (который я кусками нагуглил в инете), я им ещё пользовался в начале 2011 года в unbound, уже не помню почему, скорее всего по инерции перенёс из dnsmasq и только потом осознал что оно не нужно теперь.
# recursive resolvers
forward-zone:
name: "."
##forward-addr: 195.46.116.1 #* NS.IRTEL.RU
##forward-addr: 195.46.96.1 #* NS2.IRTEL.RU
#forward-addr: 217.150.35.129 # NS1.TRANSTELECOM.NET
#forward-addr: 82.204.218.100 # NS2.RBC.RU
# Cisco (San Jose, CA, US)
#forward-addr: 64.102.255.44 #* NS2.CISCO.COM
#forward-addr: 128.107.241.185 #* NS1.CISCO.COM
# GTE (Irving, TX, US)
forward-addr: 206.124.64.1 # bigguy.gte.net
# SpeakEasy (Seattle, WA, US)
forward-addr: 66.93.87.2 #* dns.sea1.speakeasy.net
forward-addr: 216.231.41.2 #* ns-legacy.speakeasy.net
forward-addr: 216.254.95.2 #* dns.nyc1.speakeasy.net
forward-addr: 64.81.45.2 #* dns.lax1.speakeasy.net
forward-addr: 64.81.111.2 # den.speakeasy.net
forward-addr: 64.81.127.2 #* dns.dfw1.speakeasy.net
forward-addr: 64.81.79.2 #* dns.sfo1.speakeasy.net
forward-addr: 64.81.159.2 # dns.chi1.speakeasy.net
forward-addr: 66.92.64.2 # bos.speakeasy.net
forward-addr: 66.92.224.2 # phl.speakeasy.net
forward-addr: 66.92.159.2 #* dns.wdc1.speakeasy.net
forward-addr: 64.81.79.2 #* dns.sfo1.speakeasy.net
forward-addr: 216.27.175.2 #* dns.atl1.speakeasy.net
forward-addr: 66.93.87.2 #* dns.sea1.speakeasy.net
# Sprintlink (Overland Park, KS, US)
forward-addr: 199.2.252.10 # ns2.sprintlink.net
forward-addr: 204.97.212.10 # ns3.sprintlink.net
forward-addr: 204.117.214.10 # ns1.sprintlink.net
# OpenDNS (San Francisco, CA, US)
#forward-addr: 208.67.222.222 #* resolver1.opendns.com
#forward-addr: 208.67.220.220 #* resolver2.opendns.com
# Google
#forward-addr: 8.8.8.8 #* google-public-dns-a.google.com
#forward-addr: 8.8.4.4 #* google-public-dns-b.google.com
2 Muzzy0:
Принципиально тем что:
1. Провайдер и так пишет твой netflow и хранит их ХХ месяцев. По закону или для разбирательств (особенно если помегабайтная оплата).
2. Провайдеру ты платишь деньги и у вас договорные отношения в рамках местного законодательства, это как минимум охрана тайны переписки — те на лево он сливать не может, как и сам там подглядывать, и за это он отвечает по местному закону.
3. Гугл тебе ничего не должен и может делать всё что угодно. В том числе и начать отдавать не то что запрашивали.
4. Даже если гугл сам белый и пушистый на самом деле, то «добрый люди» могут снифать трафик к 8.8.8.8 по пути для своих целей, это крайне удобно.
Что можно узнать из днс запросов?
Куда ты и когда ходишь, где у тебя почта и тп.
Так же при неправильных настройках впн/тор запросы к днс опять же могут уйти к гуглу.
Гуглу это всё нужно чтобы знать о новых и популярных доменах, как минимум.
Но не долго это привязать к профилю юзера, тем самым ощутимо его дополнив.
Те даже если кто то будет ходить на сайты на которых нет гугловских счётчиков, рекламы, скриптов, шрифтов и вообще ничего от гугла, и с браузера который совсем не хром то гугл всё равно узнает. И примет меры :)
На его месте OpenDNS монетизирует свои днс, отвечая на все несуществующие домены IP адресом со своим поисковиком с рекламой.kacang
24.07.2015 10:48Спасибо за подробный ответ! А откуда берутся корневые сервера в списке? Побежал пробовать…
kacang
24.07.2015 16:57Настроил. Про корневые сервера тоже понял (пред. вопрос можно не отвечать). Теперь не могу понять почему NXDOMAIN перехватывается провайдером? Я же вроде провайдерские серверы не использую — иду сразу в корневые?
Muzzy0
27.07.2015 10:26А если я настрою провайдерский DNS, как первичный, а гугловский — как вторичный?
Дело в том, что у моего провайдера DNS периодически падает.grumbler66rus
28.07.2015 13:48Так можно.
А ещё можно настроить три и больше серверов DNS
А ещё можно использовать любое количество серверов DNS проекта OpenNICMuzzy0
28.07.2015 14:18Я понимаю, что можно :)
Больше 2 DNS веб-морда роутера ввести не даёт, я там всё настраиваю.
Хочу, чтобы по умолчанию использовался провайдерский DNS, а если он недоступен — то гугловский или ещё какой внешний.
И то, если снимаешь галку «получать DNS автоматически», даже провайдерский DNS приходится вводить руками… Хоть скрипт не пиши для выбора DNS :)
grumbler66rus
28.07.2015 13:55Спасибо за «изобретение велосипеда», он вполне качественный.
Некогда я тоже писал собственный скрипт changeroute для переключения маршрута, причём он рассчитан на произвольное число подключений. Перестал им пользоваться, когда наткнулся на Multiwan, теперь типичная конфигурация для нового маршрутизатора — OpenWRT с Multiwan3. Причём, если собрать OpenWRT самому, на томе JFFS хранятся только конфиги
norlin
Спасибо! Хотел себе такую штуку настроить в домашний офис, но, т.к. живу в Туле, просто-напросто не нашёл второго работающего провайдера…
Одни – спамеры, другие – тупо подключить не могут, предлагают только нестандартные типы коннекта, третьи – «не принимает сейчас новых заявок» и т.д.
Пришлось считать «резервным каналом» мобильник с симкой, а т.к. ловит он только на подоконнике (а роутер стоит в коридоре, на противоположной стороне квартиры), такой «резервный канал» получается только с ручным переключением… :D