Crmgo Блог

Об'єднання пропускної здатності двох інтернет-каналів і проста відмовостійкість

Об'єднання пропускної здатності двох інтернет-каналів і проста відмовостійкість

Для початку визначимо змінні: $ cat /etc/balance/vars #!/bin/bash # LAN interface IF0= "eth1" # WAN interface 1 IF1= "eth0" # WAN interface 2 IF2= "ppp0" IP1= "194.9.xx.xx" IP2= "`ip addr show $IF2 | grep inet | awk '{print $2}'`" #…

Об'єднання пропускної здатності двох інтернет-каналів і проста відмовостійкість

Для початку визначимо змінні:
$ cat /etc/balance/vars

  1. #!/bin/bash
  2. # LAN interface
  3. IF0="eth1"
  4. # WAN interface 1
  5. IF1="eth0"
  6. # WAN interface 2
  7. IF2="ppp0"
  8. IP1="194.9.xx.xx"
  9. IP2="`ip addr show $IF2 | grep inet | awk '{print $2}'`"
  10. # gateway 1
  11. P1="194.9.xx.xx"
  12. # gateway 2
  13. P2="195.5.xx.xx"
  14. # LAN netmask
  15. P0_NET="192.168.0.0/24"
  16. # WAN1 netmask
  17. P1_NET="194.9.xx.xx/xx"
  18. # WAN2 netmask
  19. P2_NET="195.5.xx.xx/xx"
  20. TBL1="provider1"
  21. TBL2="provider2"
  22. # Realtive weight of channels bandwidth
  23. W1="2"
  24. W2="1"


Додамо у файл /etc/iproute2/rt_tables дві додаткові таблиці маршрутизації:
echo "1 provider1" >> /etc/iproute2/rt_tables
echo "2 provider2" >> /etc/iproute2/rt_tables

Тепер напишемо скрипт, який буде прописувати всі необхідні маршрути та правила файрвола:

cat /etc/balance/routing.sh

  1. #!/bin/bash
  2. . /etc/balance/vars
  3. echo "1" > /proc/sys/net/ipv4/ip_forward
  4. ip route add $P1_NET dev $IF1 src $IP1 table $TBL1 > /dev/null 2>&1
  5. ip route add default via $P1 table $TBL1 > /dev/null 2>&1
  6. ip route add $P2_NET dev $IF2 src $IP2 table $TBL2 > /dev/null 2>&1
  7. ip route add default via $P2 table $TBL2 > /dev/null 2>&1
  8. ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
  9. ip route add $P2_NET dev $IF2 src $IP2
  10. ip route add default via $P1 > /dev/null 2>&1
  11. ip rule add from $IP1 table $TBL1 > /dev/null 2>&1
  12. ip rule add from $IP2 table $TBL2 > /dev/null 2>&1
  13. ip route add $P0_NET dev $IF0 table $TBL1 > /dev/null 2>&1
  14. ip route add $P2_NET dev $IF2 table $TBL1 > /dev/null 2>&1
  15. ip route add 127.0.0.0/8 dev lo table $TBL1 > /dev/null 2>&1
  16. ip route add $P0_NET dev $IF0 table $TBL2 > /dev/null 2>&1
  17. ip route add $P1_NET dev $IF1 table $TBL2 > /dev/null 2>&1
  18. ip route add 127.0.0.0/8 dev lo table $TBL2 > /dev/null 2>&1
  19. iptables -t nat -F POSTROUTING
  20. iptables -t nat -A POSTROUTING -s $P0_NET -o $IF1 -j MASQUERADE
  21. iptables -t nat -A POSTROUTING -s $P0_NET -o $IF2 -j MASQUERADE

Цей набір команд забезпечує маршрутизацію відповідей через інтерфейс, на якому було отримано запит, а також маскарадинг на обох інтерфейсах.

Тепер напишемо скрипт, який визначатиме, чи працює той чи інший канал, і відповідно змінюватиме записи шлюзу за замовчуванням.

$ cat /etc/balance/check.sh

  1. #!/bin/bash
  2. . /etc/balance/vars
  3. OLDIF1=0
  4. OLDIF2=0
  5. . /etc/balance/routing.sh
  6. while true; do
  7. ping -c 3 -s 100 $P1 -I $IF1 > /dev/null
  8. if [ $? -ne 0 ]; then
  9. echo "Failed IF1!"
  10. NEWIF1=0
  11. else
  12. NEWIF1=1
  13. fi
  14. ping -c 3 -s 100 $P2 -I $IF2 > /dev/null
  15. if [ $? -ne 0 ]; then
  16. echo "Failed IF2!"
  17. NEWIF2=0
  18. else
  19. NEWIF2=1
  20. fi
  21. if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then
  22. echo "Changing routes"
  23. if (( ($NEWIF1==1) && ($NEWIF2==1) )); then
  24. echo "Both channels"
  25. ip route delete default
  26. ip route add default scope global nexthop via $P1 dev $IF1 weight $W1 \
  27. nexthop via $P2 dev $IF2 weight $W2
  28. elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then
  29. echo "First channel"
  30. ip route delete default
  31. ip route add default via $P1 dev $IF1
  32. elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then
  33. echo "Second channel"
  34. ip route delete default
  35. ip route add default via $P2 dev $IF2
  36. fi
  37. else
  38. echo "Not changed"
  39. fi
  40. OLDIF1=$NEWIF1
  41. OLDIF2=$NEWIF2
  42. sleep 3
  43. done

Роботу каналу перевіряємо, пінгуючи шлюз, і якщо немає відповіді на 3 пінги поспіль — ми вважаємо, що канал впав, і відповідно виключаємо його з таблиці маршрутизації.

Таким чином, якщо працюють обидва канали:

$ ip route
195.5.xx.xx dev ppp0 proto kernel scope link src 95.133.xx.xx
194.9.xx.xx/xx dev eth0 proto kernel scope link src 194.9.xx.xx
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.75
default
nexthop via 194.9.xx.xx dev eth0 weight 2
nexthop via 195.5.xx.xx dev ppp0 weight 1

Отже, маємо два default gw, перший з вагою 2 і другий з вагою 1. Тобто через перший канал піде вдвічі більше трафіку, ніж через другий.

Для того, щоб кастомізувати ці скрипти під ваші потреби, необхідно налаштувати значення у файлі vars, решта скриптів практично не потребують налаштування.

Примітка: матеріал міг бути створений за підтримки ШІ з подальшою людською редакцією. Відповідальний за зміст: Dmytro Lomaka, Kaltenkirchen.