Alt Linux как простой маршрутизатор с Multiwan

Настройка несколько провайдеров в Alt Linux, простой маршрутизатор

Первая статья по теме Alt Linux и я решил не сильно напрягаться, а начать с чего-то простого для меня и наверняка для вас, это настройка нескольких провайдеров и превращением Alt-Linux в маршрутизатор.

Попробуем сделать из Alt-Linux простой маршрутизатор с минимальным функционалом, настроем простой фаервол и настроим несколько провайдеров. Данная статься будет как затравочная для будущих статей.

Alt Linux напоминает мне CentOS, а я в свою очередь не сильно знаком с данной ОС, приходилось с ней работать, только тогда, когда наличие CentOS было обусловлено требованием заказчика или другой необходимостью. Сам же я предпочитаю использовать Debian или Ubuntu, но “Лиха беда начало” будем разбираться.

MikroTik

Я не буду описывать почему и для чего делается именно так, так как я уже описывал дынный подход в настройки нескольких провайдеров в данной статье. Так как RouterOS основана на Linux многие настройки схожи. Если вы некогда не настраивали netfilter, но хорошо понимаете и знаете RouterOS … “О сколько нам открытий чудных…”

Схема сети

Так как мы будем делать маршрутизатор, то к нашему будущем маршрутизатору будет подключено несколько провайдеров, а также несколько компьютеров в локальной сети. Нам необходимо обеспечить выход каждого компьютера через своего провайдера.

Васильев Кирилл altliknux multiwan

Настройка интерфейсов

Получить список интерфейсов в Alt Linux просто использую команду ip link

[root@vasilevkirill.ru ~]# ip link |grep ens
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
3: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
4: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000

Как видите в моём случае три интерфейса ens3, ens4 и ens5

ens3, ens4 - это интерфейсы подключенные к оборудованию провайдера.

ens5 - смотрит в локальную сеть.

Назначим IPv4 адреса

Всё просто, необходимо записать в необходимый файл, адресация с коротким типом записи сети.

echo 1.1.1.2/30 > /etc/net/ifaces/ens3/ipv4address
echo 2.2.2.2/30 > /etc/net/ifaces/ens4/ipv4address
echo 192.168.100.1/24 > /etc/net/ifaces/ens5/ipv4address

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

Создадим именованные таблицы

echo 10 Next-Hop/1.1.1.1 >> /etc/iproute2/rt_tables
echo 20 Next-Hop/2.2.2.1 >> /etc/iproute2/rt_tables

Обратите внимания номера должны быть уникальны, и номера 0,253,254,255 использовать нельзя, так как они заняты дефолтными таблицами, изменять и удалять которые не рекомендуется.

Создадим теперь маршруты по умолчанию в наших именованных таблицах маршрутизации.

echo 0.0.0.0/0 via 1.1.1.1 table Next-Hop/1.1.1.1 >> /etc/net/ifaces/ens3/ipv4route
echo 0.0.0.0/0 via 2.2.2.1 table Next-Hop/2.2.2.1 >> /etc/net/ifaces/ens4/ipv4route

Так же нам потребуется добавить дефолтные маршруты с разной метрикой в таблице по умолчанию (main).

echo 0.0.0.0/0 via 1.1.1.1 metric 10 >> /etc/net/ifaces/ens3/ipv4route
echo 0.0.0.0/0 via 2.2.2.1 metric 20 >> /etc/net/ifaces/ens4/ipv4route

netfilter

Ну что же дело за малым, необходимо подготовить конфигурацию для применения. Создадим файл /etc/nftables.conf.

Все дальнейшие настройки связанные с netfilter будем, делать в данном файл, да мы можем разнести части конфигураций по разным файлам и дальше собрать в единый конфиг. Наша конфигурация будет небольшая и ознакомительная поэтому чтобы не усложнять соберём в одном файле.

#!/usr/sbin/nft -f
flush ruleset

Следующие содержимое, при применении файла первая строка указывает на то, что все текущие (в памяти) правила будут очищены. Другими словами мы описываем полностью конфигурацию, а не дополняем текущую.

BOGON

Прежде всего создадим всеми любимыми список адресов BOGON нам понадобиться создать define.

Первой командой создаём лист, последующими заполняем набор сетями BOGON.

После flush ruleset

define BOGONS = {
    0.0.0.0/8
    10.0.0.0/8
    100.64.0.0/10
    127.0.0.0/8
    169.254.0.0/16
    172.16.0.0/12
    192.0.0.0/24
    192.0.2.0/24
    192.168.0.0/16
    198.18.0.0/15
    198.51.100.0/24
    203.0.113.0/24
    224.0.0.0/3
}

netfilter таблицы

Возьмём и сделаем так же как и у RouterOS

Ниже в конфиге

table ip filter {
    chain FORWARD {
        type filter hook forward priority 0; policy accept;
    }
    chain INPUT {
        type filter hook input priority 0; policy accept;
    }
    chain OUTPUT {
        type filter hook output priority 0; policy accept;
    }
}

table ip mangle {
    chain PREROUTING {
        type filter hook prerouting priority -150; policy accept;

    }
    chain INPUT {
        type filter hook input priority -150; policy accept;

    }
    chain FORWARD {
        type filter hook forward priority -150; policy accept;

    }
    chain OUTPUT {
        type route hook output priority -150; policy accept;
    }
    chain POSTROUTING {
        type filter hook postrouting priority -150; policy accept;

    }
}

table ip nat {
    chain DSTNAT {
        type nat hook prerouting priority -100; policy accept;
    }
    chain SRCNAT {
        type nat hook postrouting priority 100; policy accept;
    }
}

Мы определили три таблицы, навешали хуки, не буду объяснять зачем они нужны, скажу так что это особенность netfilter. Указали приоритеты и указали поведение по умолчанию.

Создали chain-ы, в том числе SRCNAT и DSTNAT.

Mangle

Создаём необходимые правила для всех провайдеров.

В отличие от RouterOS в голом netfilter маркировкам что соединений что маршрутным, доступен только числовой диапазон, для первого провайдера будем использовать 1, а для второго 2.

У netfilter есть два способа описания конфигураций, первый простой и не самый удобный это построчное последовательное выполнение команд и второй описание таблиц во вложенной структуре. Мне же больше нравиться второй, так как вы можете повторно использовать те же таблицы, при выполнении netfilter сам сделает merge. Я покажу как описывать конфигурацию сразу двумя способами для наглядности.

Все дальнейшие настройки, которые мы будем выполнять для конкретного провайдера будем выполнять между комментариями.

Блоки кода обрамлённые комментариями, четко указывают на места в коде, которые однозначно относятся ТОЛЬКО для определённого провайдера или шлюза.

#FOR ISP ens3 NEXT-HOP 1.1.1.1 Start --->

#FOR ISP ens3 NEXT-HOP 1.1.1.1 End <---

Для второго провайдера

#FOR ISP ens4 NEXT-HOP 2.2.2.1 Start --->

#FOR ISP ens4 NEXT-HOP 2.2.2.1 End <---

Ну и сами конфигурации

#FOR ISP ens3 NEXT-HOP 1.1.1.1 Start --->
add rule ip mangle PREROUTING iifname ens3 ip daddr 1.1.1.0/30 ct state new ct mark set 1
add rule ip mangle PREROUTING iifname != ens3 ct mark 1 mark set 1

add rule ip mangle OUTPUT ct mark 1 counter meta mark set 1
add rule ip mangle OUTPUT ip saddr 1.1.1.0/30 ip daddr != $BOGONS counter meta mark set 1
#FOR ISP ens3 NEXT-HOP 1.1.1.1 End <---
#FOR ISP ens4 NEXT-HOP 2.2.2.1 Start --->
add rule ip mangle PREROUTING iifname ens4 ip daddr 2.2.2.0/30 ct state new ct mark set 2
add rule ip mangle PREROUTING iifname != ens4 ct mark 2 mark set 2

add rule ip mangle OUTPUT ct mark 2 counter meta mark set 2
add rule ip mangle OUTPUT ip saddr 2.2.2.0/30 ip daddr != $BOGONS counter meta mark set 2
#FOR ISP ens4 NEXT-HOP 2.2.2.1 End <---

Обратите внимание на переменную $BOGONS, оно как раз раскрывает список сетей BOGON которую мы указали в define BOGONS.

NAT

Тут всё просто, так как у нас статические адреса, будет использовать статический NAT или “чистый” NAT.

Добавим в наши блоки для каждого провайдера, необходимые строки

insert rule ip nat SRCNAT position 0 ip saddr 1.1.1.0/30 counter accept
add rule ip nat SRCNAT oifname ens3 counter snat to 1.1.1.2

и сразу для второго

insert rule ip nat SRCNAT position 0 ip saddr 2.2.2.0/30 counter accept
add rule ip nat SRCNAT oifname ens4 counter snat to 2.2.2.2

Надеюсь тут нет смысла, что-либо объяснять. Всё просто и понятно.

Filter

Естественно, так как наша машинка торчит “попой” наружу, необходимо нашу стыдобы прикрыть фильтром. За образец полузакрытого фаервола я возьму свой набор из RouterOS.

Скажу честно я даже и не искал, как создать набор интерфейсов он же лист, поэтому просто сделаем Jump и несколько правил.

С начало для первого провайдера и сразу для второго, а также для цепочки forward.

add rule ip filter INPUT iifname ens3 jump ISP-Input
add rule ip filter FORWARD iifname ens3 jump ISP-Forward
add rule ip filter INPUT iifname ens4 jump ISP-Input
add rule ip filter FORWARD iifname ens4 jump ISP-Forward

Если мы продолжим дописывать в конец файла конфигурацию, то у нас будет ошибка, так как в правилах выше мы ссылаемся на не существующий chian ISP-Input. Когда вы ссылаетесь на кастомный chain на этот момент он уже должен быть объявлен.

Не отходя от кассы, сразу FORWARD. Тут я приведу пример как описывать конфигурацию уже в виде синтаксиса nft.

table ip filter {
    chain ISP-Input-Allow {
        ip protocol icmp accept
        tcp dport 22 accept
    }
    chain ISP-Input {
        ct state established accept
        ct state related accept
        ct state invalid drop
        jump ISP-Input-Allow
        drop
    }
    chain ISP-Forward {
        ct state established accept
        ct state related accept
        ct state invalid drop
        ct status dnat accept
        drop
    }
}

Это стандартные “для меня” набор правил которые открывают icmp и ssh на сам маршрутизатор, а также разрешают только трафик за маршрутизатор. Трафик за маршрутизатор может попасть только если попадет под правила dnat “проброс портов”. У нас пока нет правил dnat, но это задел на будущее.

Загрузка

Осталось дело за малым, по умолчанию в alt-linux конфигурация которая загружается при запуске системы находиться в файле /etc/nftables/nftables.nft.

Скопируйте свой файл конфига и перезагрузите машинку, убедитесь что при загрузке все ваши правила загрузились

[root@vasilevkirill.ru ~]# nft -s list ruleset
table ip filter {
        chain FORWARD {
                type filter hook forward priority filter; policy accept;
                iifname "ens3" jump ISP-Forward
                iifname "ens4" jump ISP-Forward
        }

        chain INPUT {
                type filter hook input priority filter; policy accept;
                iifname "ens3" jump ISP-Input
                iifname "ens4" jump ISP-Input
        }

        chain ISP-Input-Allow {
                ip protocol icmp accept
                tcp dport 22 accept
        }

        chain ISP-Input {
                ct state established accept
                ct state related accept
                ct state invalid drop
                jump ISP-Input-Allow
                drop
        }
...

PBR Policy-based routing

Дело за малым, осталось указать что различный марки трафика маршрут должен искаться в определённой таблице маршрутизации.

echo fwmark 1 table Next-Hop/1.1.1.1 >> /etc/net/ifaces/ens3/ipv4rule
echo fwmark 2 table Next-Hop/2.2.2.1 >> /etc/net/ifaces/ens4/ipv4rule

sysctl

Так как мы делаем маршрутизатор, то нам необходимо разрешить проходить трафику через хост, по умолчанию forward запрещён.

Так же нам необходимо отключить rp_filter – такая штука, которая фильтрует входящий трафик на основе таблицы маршрутизации, в случае если наш хост маршрутизатор, то такая настройка будет нам только мешать, так как есть существенные ограничения в работе с таблицей маршрутизации.

В файле /etc/net/sysctl.conf необходимо изменить значения параметра net.ipv4.ip_forward на единицу.

rp_filter Может быть настроен как глобально так и для каждого интерфейса, так как это удобно защититься от ip spoofing из локального интерфейса ens5, то на нём отключать его не будем.

echo rp_filter=0 >> /etc/net/ifaces/ens3/sysctl.conf
echo rp_filter=0 >> /etc/net/ifaces/ens4/sysctl.conf

Применение конфигурации

Для того чтобы netfilter подхватил конфигурацию выполните следующую команду

nft -f /etc/nftables/nftables.nft

Проверка

Васильев Кирилл altliknux multiwan
altliknux multiwan

Без пруфов жизнь не мила.

Проверка правил маршрутизации

[root@vasilevkirill.ru ~]# ip rule
0:      from all lookup local
32764:  from all fwmark 0x2 lookup Next-Hop/2.2.2.1
32765:  from all fwmark 0x1 lookup Next-Hop/1.1.1.1
32766:  from all lookup main
32767:  from all lookup default

Как видим наши марки должны маршрутизироваться в своей таблице.

Проверка таблицы маршрутизации

[root@vasilevkirill.ru ~]# ip route show table all
default via 1.1.1.1 dev ens3 table Next-Hop/1.1.1.1
default via 2.2.2.1 dev ens4 table Next-Hop/2.2.2.1
default via 1.1.1.1 dev ens3 metric 10
default via 2.2.2.1 dev ens4 metric 20
1.1.1.0/30 dev ens3 proto kernel scope link src 1.1.1.2
2.2.2.0/30 dev ens4 proto kernel scope link src 2.2.2.2
192.168.100.0/24 dev ens5 proto kernel scope link src 192.168.100.1
...

Урезал вывод, чтобы не захломлять и из того большой материал.

Трафик

Я делал данную схему в лабе чтобы не показывать ненужную информация, установил ttl = 2, главное чтобы было понятно, что наши настройки правильно выбрали и отправили на нужный шлюз трафик.

Для первого провайдера адрес источника 1.1.1.2

[root@vasilevkirill.ru ~]# mtr --no-dns --report -m 2 --address 1.1.1.2 8.8.8.8
HOST: vasilevkirill.ru             Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 1.1.1.1                    0.0%    10    0.7   0.6   0.5   0.9   0.1
  2.|-- 192.168.100.254            0.0%    10    1.2   1.2   0.9   1.4   0.2

Для второго провайдера адрес источника 2.2.2.2

[root@vasilevkirill.ru ~]# mtr --no-dns --report -m 2 --address 2.2.2.2 8.8.8.8
HOST: vasilevkirill.ru             Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 2.2.2.1                    0.0%    10    0.5   0.7   0.5   0.9   0.2
  2.|-- 192.168.100.254            0.0%    10    1.3   1.4   1.2   2.1   0.3

Так же с этого момента вы можете подключаться одновременно по всем IP адресам на сам хост.

PBR Forward

Сильно перегружать не буду, задача одна хост 192.168.100.101 отправить через первого провайдера, а 192.168.100.102 хост через второго провайдера.

Для наглядности сделаю в структурном синтаксисе nft

#PBR FOR LOCAL
table ip mangle {
    chain PREROUTING {
         iifname ens5 ip saddr 192.168.100.101 ip daddr != $BOGONS counter meta mark set 1
         iifname ens5 ip saddr 192.168.100.102 ip daddr != $BOGONS counter meta mark set 2
    }
}
#PBR FOR LOCAL

и тут же проверяем с хостов

[admin@c1] > /tool/traceroute max-hops=3 8.8.8.8
Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
#  ADDRESS          LOSS  SENT  LAST   AVG  BEST  WORST  STD-DEV
1  192.168.100.1    0%      16  0.4ms  0.6  0.4   0.9    0.1
2  1.1.1.1          0%      16  0.9ms  0.9  0.7   1.3    0.2
3  192.168.100.254  0%      16  1.1ms  1.4  1.1   2.9    0.4
[admin@с2] > /tool/traceroute max-hops=3 8.8.8.8
Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
#  ADDRESS          LOSS  SENT  LAST   AVG  BEST  WORST  STD-DEV
1  192.168.100.1    0%      46  0.5ms  0.6  0.4   1.1    0.1
2  2.2.2.1          0%      46  0.8ms  0.9  0.6   1.5    0.2
3  192.168.100.254  0%      46  1.2ms  1.5  1.1   3.4    0.4

Как видите всё замечательно арбайтен

Поделиться

Обсуждение