Настройка двух внешних каналов (DualWan) в OPENWRT.
Само по себе поднятие каналов, производится стандартными средствами OS, которые в разных дистрибутах могут отличаться.
Для OpenWrt, может вызвать какието проблемы только поднятие 3G, хотя на самом деле это делается достаточно просто, через вэб интерфейс управления. Но на всякий случай привожу секции конфига, связанные с 3G каналом для OPENWRT:
В файл /etc/config/network добавлена секция:
config interface 'CDMADnepr'
option proto '3g'
option device '/dev/ttyACM0'
option service 'evdo'
option username 'IT'
option password 'IT'
option dns '8.8.8.8 8.8.4.4'
option peerdns '0'
option metric '50'
В /etc/ppp/options у меня сейчас:
debug
#logfile /dev/null
logfile /var/log/ppp.log
noipdefault
noaccomp
nopcomp
nocrtscts
lock
maxfail 0
lcp-echo-failure 5
lcp-echo-interval 1
Отладку понятно можно отключить. А lcp-echo-interval и lcp-echo-failure, особенно если Вы находитесь в месте, где 3G не очень стабильно (плохое покрытие) - рекомендую увеличить. Это в частности касается массива теремки-2 в Киеве :)
После подьема обеих каналов (один у Вас вероятно для OPENWRT будет на интерфейсе eth0.2, и второй на интерфейсе CDMADnepr (или как Вы его назовете в /etc/config/network), проверьте что они работают каждый по отдельности - выключите оба, потом включите один из них - проверьте что связь есть. Потом снова выключите оба, потом включите другой и тоже проверьте. PS На других дистрибутах имена интерфейсов могут быть другими.
Итак - два канала подняли. Убедились что каждый из них работает по отдельности.
А теперь самое интересное и вкусное - скрипт, который обеспечивает тестирование каналов и автоматическое переключение на резервные и назад, в случае отказа основного канала, или первого резервного.root@Dnepr_Root:/etc/config# cat /usr/sbin/ChanCheck
#!/bin/bash
LogFile="/var/log/ChanCheck.log"
#Ifaces name
NOIF='NONE'
IFM=eth0.2
IFR1=3g-CDMADnepr
IFR2=$NOIF
IFMA=wan
IFR1A=CDMADnepr
IFR2A=$NOIF
#Ifaces status. 1 - down, 0 - OK
MOK=0
R1OK=0
R2OK=0
#Ifaces exist. 1 - not exist, 0 - exist
MEX=0
R1EX=0
R2EX=0
#IP addresses VIA for ifaces for default routing
MIP=''
R1IP=''
R2IP=''
#Metrics for interfaces
MM='1'
MR1='20'
MR2='20'
#Default for interface exist 1 - not exist, 0 - exist
MDEF=0
R1DEF=0
R2DEF=0
#Current interface in use. 0 - none, 1 - Main, 2 - Res1, 3 - Res2
CURIF=0
CURIFN=$IFM
#Which interface may be in use. 0 - none, 1 -Main, 2 - Res1, 3 - Res2
WORKIF=0
StopScript=0
#External programs, starting after changing to each interface
NOPROG='NONE'
PROGME='YES'
PROGM='/usr/sbin/ChanIPSecM'
PROGR1E='YES'
PROGR1='/usr/sbin/ChanIPSecR1'
PROGR2E=$NOPROG
PROGR2=$NOPROG
function checkdefault {
ip ro li | grep default | grep $IFM > /dev/null 2>&1
MDEF=$?
ip ro li | grep default | grep $IFR1 > /dev/null 2>&1
R1DEF=$?
ip ro li | grep default | grep $IFR2 > /dev/null 2>&1
R2DEF=$?
if [ $IFM != $NOIF ]
then
ifconfig $IFM | grep UP > /dev/null 2>&1
MEX=$?
else
MEX=1
fi
if [ $IFR1 != $NOIF ]
then
ifconfig $IFR1 | grep UP > /dev/null 2>&1
R1EX=$?
else
R1EX=1
fi
if [ $IFR2 != $NOIF ]
then
ifconfig $IFR2 | grep UP > /dev/null 2>&1
R2EX=$?
else
R2EX=1
fi
if [ $MEX -eq 0 ]
then
if [ $MDEF -ne 0 ]
then
ifdown $IFMA > /dev/null 2>&1
ifup $IFMA > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Restore from fault for interface: $IFM"
date >> $LogFile
echo "Restore from fault for interface: $IFM" >> $LogFile
CURIF=0
sleep 2
fi
fi
if [ $R1EX -eq 0 ]
then
if [ $R1DEF -ne 0 ]
then
ifdown $IFR1A > /dev/null 2>&1
ifup $IFR1A > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Restore from fault for interface: $IFR1"
date >> $LogFile
echo "Restore from fault for interface: $IFR1" >> $LogFile
CURIF=0
sleep 2
fi
fi
if [ $R2EX -eq 0 ]
then
if [ $R2DEF -ne 0 ]
then
ifdown $IFR2A > /dev/null 2>&1
ifup $IFR2A > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Restore from fault for interface: $IFR2"
date >> $LogFile
echo "Restore from fault for interface: $IFR2" >> $LogFile
CURIF=0
sleep 2
fi
fi
}
function checkchan {
ping -c 4 -I $IFM 8.8.8.8 > /dev/null 2>&1
MOK=$?
ping -c 4 -I $IFR1 8.8.4.4 > /dev/null 2>&1
R1OK=$?
ping -c 4 -I $IFR2 8.8.8.8 > /dev/null 2>&1
R2OK=$?
ifconfig $IFM > /dev/null 2>&1
MEX=$?
ifconfig $IFR1 > /dev/null 2>&1
R1EX=$?
ifconfig $IFR2 > /dev/null 2>&1
R2EX=$?
MIP=$(ip ro li | grep default | grep $IFM | cut -d' ' -f3) > /dev/null 2>&1
R1IP=$(ip ro li | grep default | grep $IFR1 | cut -d' ' -f3) > /dev/null 2>&1
R2IP=$(ip ro li | grep default | grep $IFR2 | cut -d' ' -f3) > /dev/null 2>&1
if [ $MOK -eq 0 ]
then
WORKIF=1
CURIFN=$IFM
MM=1
MR1=20
MR2=20
elif [ $R1OK -eq 0 ]
then
WORKIF=2
CURIFN=$IFR1
MM=20
MR1=1
MR2=20
elif [ $R2OK -eq 0 ]
then
WORKIF=3
CURIFN=$IFR2
MM=20
MR1=20
MR2=1
else
WORKIF=0
CURIFN='All channels BAD !'
MM=1
MR1=20
MR2=20
fi
if [ $WORKIF -ne $CURIF ]
then
date >> $LogFile
ip ro del default dev $IFM > /dev/null 2>&1
ip ro del default dev $IFR1 > /dev/null 2>&1
ip ro del default dev $IFR2 > /dev/null 2>&1
if [ $MEX -eq 0 ]
then
if [ -n $MIP ]
then
ip ro add default dev $IFM via $MIP metric $MM
fi
fi
if [ $R1EX -eq 0 ]
then
if [ -n $R1IP ]
then
ip ro add default dev $IFR1 via $R1IP metric $MR1
fi
fi
if [ $R2EX -eq 0 ]
then
if [ -n $R2IP ]
then
ip ro add default dev $IFR2 via $R2IP metric $MR2
fi
fi
CURIF=$WORKIF
ip ro flush cache
logger -p user.warning -t Channel_Switch "Current channel interface is: $CURIFN"
echo "Current channel interface is: $CURIFN" >> $LogFile
if [ $MM -eq 1 ]
then
if [ $PROGME != $NOPROG ]
then
$PROGM > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Ipsec restart script $PROGM, executed"
echo "Ipsec restart script $PROGM, execute" >> $LogFile
fi
fi
if [ $MR1 -eq 1 ]
then
if [ $PROGR1E != $NOPROG ]
then
$PROGR1 > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Ipsec restart script $PROGR1, executed"
echo "Ipsec restart script $PROGR1, execute" >> $LogFile
fi
fi
if [ $MR2 -eq 1 ]
then
if [ $PROGR2E != $NOPROG ]
then
$PROGR2 > /dev/null 2>&1
logger -p user.warning -t Channel_Switch "Ipsec restart script $PROGR2, executed"
echo "Ipsec restart script $PROGR2, execute" >> $LogFile
fi
fi
fi
}
echo "ChanCheck started" > $LogFile
date >> $LogFile
echo "==========================================================================" >> $LogFile
while [ $StopScript -ne 1 ]; do
checkdefault
checkchan
sleep 10
done
===============================
Запуск скрипта прописывается в /etc/rc.local строкой:
/usr/sbin/ChanCheck&
Настройки соединения 3G CDMA приведены для оператора InterTeleCom Ukraine
Коротко об настройке скрипта и принципе его работы.
Для тестирования каналов, необходимо чтобы все они были включены - это понятно. При этом для каждого в таблицу роутинга вписан "default". Чтобы реальный траффик шел по нужному нам каналу, скрипт изменяет только метрики интерфейсов каждого из каналов (точнее метрики записей default route для каждого из нитерфейсов). В переменных MM, MR1, MR2 - вписаны метрики, присваемые каналам, MM - основного, и далее двух резервных. ВАЖНО - Метрика основного канала должна быть установлена в 1 - в нее же устанавливается метрика активного, если основной "падает" - это необходимо для правильного вызова программ, срабатывающих при смене канала (необходимых для работы L2TP/IPSec).
В переменных
IFM=eth0.2
IFR1=3g-CDMADnepr
IFR2=$NOIF
IFMA=wan
IFR1A=CDMADnepr
IFR2A=$NOIF
Вписаны имена интерфейсов. Почему они вписаны дважды. В прошивке OpenWrt, для использования команд типа "ip ro li...", используется одно имя интерфейса (они в переменных IFM, IFR1, IFR2), а для использования в коммандах ipup, ifdown - другие - они в переменных IFMA, IFR1A, IFR2A. У Вас на других дистрибутивах эти имена могут и совпадать. Тогда соответственно вторые 3 переменных будут повторять значения первых 3х. Если соответствущего интерфейса нет (у меня напр сча 2 канала), то переменные имени соответствующего интерфейса утсанавливаются в "$NOIF" как в примере для IFR2, IFR2A.
Остальные переменные рабочие, их менять не надо, кроме
NOPROG='NONE'
PROGME='YES'
PROGM='/usr/sbin/ChanIPSecM'
PROGR1E='YES'
PROGR1='/usr/sbin/ChanIPSecR1'
PROGR2E=$NOPROG
PROGR2=$NOPROG
Эти переменные отвечают за запуск программ настройки (в моем случае туннеля L2Tp/IPSec) на новые параметры, при смене активного интерфейса. Соотв при переходе напр на "первый резервный", запускается программа, указанная в переменной PROGR1=. Если для какого то канала (или для всех) никаких доп программ запускать не нужно, обе переменные для этого канала ставятся в значение "$NOPROG". Как для второго резервного канала в приведенном примере.
Да. а как же я обеспечил тестирование работоспособности каналов, по которым в данный момен траффик не идет ? Ну например того что "основной встал", когда у нас трафик идет по резервному ? Очень просто. В примерах что я видел это делали сложным "source routing", и кучей доп таблиц. Но по моему этот путь излишен сложен и соотв излишен глюкав (достаточно попробвовать штатный скрипт MULTIWAN входящий в OpenWRT, чтобы это понять). Есть куда более простой:
ping -c 4 -I $IFM 8.8.8.8 > /dev/null 2>&1
MOK=$?
Обычный пинг, с задаванием ему имени интерфейса, роутинг через который хотим протестить.
Продолжение следует. напомню, что нас еще ждет скрипт для динамического DNS, а также настройка L2TP/IPSec, настройка L2TP/IPSec в условиях возможной смены рабочего канала "на лету", а также описание как настроить клиентов в Android и Windows7 для L2TP/IPSec, и особенности. Ну а потом может еще какие нюансы работы с OPENWRT, которые мне показались крайне полезными. также, если когото заинтересует и будут просьбы - могу описать настройку ASTERISK (SIP телефонии) на рутере OPENWRT, с шифрованием (фик кто подслушает - перехватит).
Комментариев нет:
Отправить комментарий