Рубрики
network \ сеть

debian 11 / gateway / два шлюза / два провайдера / запасной шлюз / ip route / ip rule / nftable

Ссылки:

#route
https://habr.com/ru/post/49137/
https://forum.altlinux.org/index.php?topic=45177.0
https://tokmakov.msk.ru/blog/item/508

#nftables
https://wiki.archlinux.org/title/Nftables_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)
https://habr.com/ru/company/ruvds/blog/580648/
https://wiki.nftables.org/wiki-nftables/index.php/Moving_from_iptables_to_nftables

#ubuntu balamcing 
https://help.ubuntu.ru/wiki/ip_balancing

Пример резервного провайдера

0. Добавляем правила:
echo "101 T1" >> /etc/iproute2/rt_tables
echo "102 T2" >> /etc/iproute2/rt_tables

1. vim /etc/network/interfaces
------------------------------
# The loopback network interface
auto lo
iface lo inet loopback


# The primary network interface
auto ens4
iface ens4 inet static
           address 10.10.10.10/24
           up ip route add default via 10.10.10.1 table T1
           up ip route add default via 10.10.10.1 metric 10
           up ip rule add from 10.10.10.1 table T1

auto ens5
iface ens5 inet static
           address 10.20.20.20/24
           up ip route add default via 10.20.20.1 table T2
           up ip route add default via 10.20.20.1 metric 5
           up ip rule add from 10.20.20.1 table T2

auto ens6
iface ens6 inet static 
           address 192.168.1.1/24
------------------------------

Скрипты переключения на запасной шлюз:

vim /etc/iptables/test_internet
-------------------------------
#!/bin/bash
#При пропадании канала у основного провайдера автоматически переключаемся
#на резервного и переодически проверяем наличие канала у первого
#провайдера. Как только интернет появляется у первого провайдера сразу
#переключаемся на него. Трафик идет по шлюзу с меньшей метрикой по этому
#меняем только метрику основного канала.

#GW1=IP_шлюза_основного_провайдера_первый_запуск metric 5
# ip route default via 10.10.10.1 dev ether1 metric 5
GW1=10.20.20.1

#GW2=IP_шлюза_резервного_провайдера_первый_запуск metric 10
# ip router default via 192.168.8.1 dev ether0 metric 10
GW2=10.10.10.1

# Interfaces
#iface..=основного_провайдера
iface1=ens4

#iface..=резервного_провайдера
iface2=ens5

# Удаленный адрес для проверки на доступность
srctest=10.20.20.1

# Шлюз установленный по умолчанию
ROUTESTR1=$(ip r s | grep "default via $GW1" | sed -n '/metric/p')
ROUTESTR2=$(ip r s | grep "default via $GW2" | sed -n '/metric/p')

if [ -z "$ROUTESTR1" ] || [ -z "$ROUTESTR2" ]; then
echo "${iface1}_metric=$DEFMETRIC1 ${iface2}_metric=$DEFMETRIC2"
echo "Метрика шлюза не определена, проверте наличие правильного роутинга 'ip r s'"
exit 1
fi

# ${ROUTESTR1##*"metric "} - Удаление с начала строки, до последнего совпадения
DEFMETRIC1=$((${ROUTESTR1##*"metric "} | cut -f1 -d " "))
DEFMETRIC2=$((${ROUTESTR2##*"metric "} | cut -f1 -d " "))

# Пинг тест через сетевой интерфейс основного провайдера
result1=$(ping -c 3 -I $iface1 $srctest -W 1  2<&1 | grep -icE 'unknown|expired|unreachable|time out|100% packet loss')

if [ ${result1} != 0 ] && [ $DEFMETRIC1 -lt $DEFMETRIC2 ]; then
        echo "Перейти на резервный канал"
        #/sbin/ip route change default via $GW2
        /sbin/ip route del default via $GW1
        /sbin/ip route del default via $GW2
        /sbin/ip route add default via $GW1 metric 10
        /sbin/ip route add default via $GW2 metric 5
        ip route flush cache
        #/etc/init.d/bind restart >> /dev/null
        #service openvpn restart
fi

if [ ${result1} = 0 ] && [ $DEFMETRIC1 -gt $DEFMETRIC2 ]; then
        echo "Перейти на основной канал"
        /sbin/ip route del default via $GW1
        /sbin/ip route del default via $GW2
        /sbin/ip route add default via $GW1 metric 5
        /sbin/ip route add default via $GW2 metric 10
        ip route flush cache
        #/etc/init.d/bind restart >> /dev/null
        #service openvpn restart
fi

-------------------------------

Добавить задание в cron, запускаем каждую минуту, проверяем доступность интернета.

vim /etc/cron.d/test_internet
------------------------------- 
* * * * * root /etc/iptables/test_internet
-------------------------------

NAT в iptables

iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE
iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE

NAT в nftable

0. vim /etc/nftables.conf
----------------------
table inet my_nat1 {
  chain my_masquerade {
    type nat hook postrouting priority srcnat;
    oifname "ens4" masquerade
  }
}

table inet my_nat2 {
  chain my_masquerade {
    type nat hook postrouting priority srcnat;
    oifname "ens5" masquerade
  }
}

----------------------

1. включаем nftable
systemctl start nftables.service 
systemctl enable  nftables.service 

P.S. Команды iptables-translate и iptables-restore-translate позволяет конвертировать правила из iptables в nftables:
% iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 ct state new counter accept
% ip6tables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111,222 -j ACCEPT
nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept
% iptables-save > save.txt
% iptables-restore-translate -f save.txt > ruleset.nft

nft list ruleset - показать действующие правила
nft -f /etc/nftables.conf - применить правила

nft <команда> <объект> <путь к объекту> <параметры>
Команда — add, insert, delete, replace, rename, list, flush…
Объект — table, chain, rule, set, ruleset…
Путь к объекту зависит от типа. Например, у таблицы это <семейство> <название>.
У правила — гораздо длиннее: <семейство таблицы> <название таблицы> <название цепочки>. 
А иногда ещё добавляются handle или index (будут описаны дальше).
Параметры зависят от типа объекта. Для правила это условие отбора пакетов и действие, применяемое к отобранным пакетам
nft insert rule inet filter input iif eth0 tcp dport { ssh, telnet } drop - блокируем ssh и telnet
nft -a list chain ip filter input - проверяем что у нас получилось

Разрешаем forward:

0. редактируем vim /etc/sysctl.conf
----------------------------
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
----------------------------
1. Применяем без перезагрузки: 
sysctl -p