Настройка системы Linux

Чтобы была возможность раздавать интернет внутри VPN сети, необходимо разрешить перенаправление пакетов внутри ядра Linux. Без этих параметров не получится настроить маршрутизацию.

Открываем файл /etc/sysctl.conf

nano /etc/sysctl.conf

Добавляем следующие строки в конец файла (или их можно раскомментировать внутри файла, если они там есть)

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Выполняем команду применения изменений в файле sysctl.conf

sysctl -p

добовляем таблицы маршрутизации

echo "1001 isp1_table" >> /etc/iproute2/rt_tables
echo "1002 isp2_table" >> /etc/iproute2/rt_tables

Настраиваем сетевые интерфейсы ip адреса получаются автоматически

#isp1
auto ens19
iface ens19 inet dhcp
metric 5

#isp2
auto ens20
iface ens20 inet dhcp
metric 10

post-up ip route add default via 10.0.23.1 dev ens19 table isp1_table
post-up ip route add default via 10.0.17.1 dev ens20 table isp2_table
post-up ip rule add fwmark 0x1 lookup isp1_table
post-up ip rule add fwmark 0x2 lookup isp2_table

настраиваем nftables что бы он отвечал с интерфейса на который пришол пакет

table inet mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;

        # Маркировка соединений
        iifname "ens19" ct mark set 1
        iifname "ens20" ct mark set 2

        # Применение маршрутной метки
        ct mark 1 meta mark set 1
        ct mark 2 meta mark set 2
    }

    chain output {
        type filter hook output priority mangle; policy accept;

        # Для WireGuard что бы он шёл через второго провайдера
        udp dport 55625 ip daddr (ip адрес филиала) meta mark set 2
    }
}

table ip nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname "ens20" masquerade
        oifname "ens19" masquerade
    }
}

Скрипт перелючение каналов

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

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

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

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

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

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

ROUTESTR1=$(ip r  | grep "default via $GW1" )
ROUTESTR2=$(ip r  | grep "default via $GW2" )

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

запускаем скрипт через cron раз в минуту crontab -e

* * * * * /usr/script/test_internet.sh

Дальше расмотрим такую схему сети что бы у нас филиалы продолжали работать при недоступности первого провайдера

Установка WireGuard

На всех узлах выполните:

sudo apt update && sudo apt install wireguard -y

Настройка WireGuard

Пример для Node1 соеденяется через isp1 (10.0.0.1/30):

# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/30
PrivateKey = <Node1_private_key>
ListenPort = 51820

[Peer]
PublicKey = <Node2_public_key>
AllowedIPs = 10.0.0.2/32
Endpoint = <Node2_public_IP>:51820
PersistentKeepalive = 25

Пример для соеденяется через isp1 Node2 (10.0.0.2/30):

# /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.2/30
PrivateKey = <Node2_private_key>
ListenPort = 51820

[Peer]
PublicKey = <Node1_public_key>
AllowedIPs = 10.0.0.1/32
Endpoint = <Node1_public_IP_isp1>:51820
PersistentKeepalive = 25

Пример для Node1 соеденяется через isp2 (10.0.1.1/30):

# /etc/wireguard/wg1.conf
[Interface]
Address = 10.0.1.1/30
PrivateKey = <Node1_private_key>
ListenPort = 55625

[Peer]
PublicKey = <Node2_public_key>
AllowedIPs = 10.0.1.2/32
Endpoint = <Node2_public_IP>:55625
PersistentKeepalive = 25

Пример для соеденяется через isp2 Node2 (10.0.1.2/30):

# /etc/wireguard/wg1.conf
[Interface]
Address = 10.0.0.2/30
PrivateKey = <Node2_private_key>
ListenPort = 55625

[Peer]
PublicKey = <Node1_public_key>
AllowedIPs = 10.0.0.1/32
Endpoint = <Node1_public_IP_isp2>:55625
PersistentKeepalive = 25

Запуск WireGuard

На всех узлах:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

sudo systemctl enable wg-quick@wg1
sudo systemctl start wg-quick@wg1

Установка FRRouting (OSPF)

На всех узлах:

sudo apt install frr -y

Включите OSPF в /etc/frr/daemons:

ospfd=yes

Перезапустите FRR:

sudo systemctl restart frr

Настройка OSPF

Используйте vtysh для настройки OSPF.

Пример через провайдера isp1 для Node1:

vtysh

configure terminal
interface wg0
 ip ospf cost 1000
 ip ospf dead-interval 40
exit
router ospf
 network 10.0.0.0/24 area 0  # Туннельная сеть
 network <LAN_Node1_подсеть> area 0  # Например, 192.168.1.0/24
exit
exit
write

Пример через провайдера isp1 для Node2:

vtysh

configure terminal
interface wg0
 ip ospf cost 1000
 ip ospf dead-interval 40
exit
router ospf
 network 10.0.0.0/24 area 0  # Туннельная сеть
 network <LAN_Node2_подсеть> area 0  # Например, 192.168.2.0/24
exit
exit
write

Пример через провайдера isp2 для Node1:

vtysh

configure terminal
interface wg1
 ip ospf cost 2000
 ip ospf dead-interval 40
exit
router ospf
 network 10.0.0.0/24 area 0  # Туннельная сеть
 network <LAN_Node1_подсеть> area 0  # Например, 192.168.1.0/24
exit
exit
write

Пример через провайдера isp2 для Node2:

vtysh

configure terminal
interface wg1
 ip ospf cost 2000
 ip ospf dead-interval 40
exit
router ospf
 network 10.0.0.0/24 area 0  # Туннельная сеть
 network <LAN_Node2_подсеть> area 0  # Например, 192.168.2.0/24
exit
exit
write

Проверка OSPF

Проверьте соседей:

vtysh -c "show ip ospf neighbor"

Посмотрите таблицу маршрутизации:

vtysh -c "show ip route ospf"