Пометить пакеты ответов так же, как и входящие пакеты с помощью nftables.

Вопрос или проблема

Ранее

У нас есть сервер, который также является клиентом VPN.
У него есть 2 интерфейса: eth0 (физический) и tun0 (vpn).
VPN используется только для внешних запросов: он направляется на другой сайт, который направляет запросы из Интернета на сервер через VPN.
** Оба стороны обращаются с локальным IP-адресом сервера.

Цель

В настоящее время на сервере установлена опция openvpn redirect-gateway.
Однако мы хотели бы, чтобы маршрут по умолчанию для сервера был локальным шлюзом, а не VPN.

** Использование простого правила iproute src невозможно, так как сервер доступен через VPN через внутренний и vps интерфейсы **

Пробовали

Итак, мы удалили опцию redirect-gateway.
Однако запросы через VPN, приходящие от публичных адресов, не проходят через VPN.
Это верно, так как маршрут по умолчанию для интернет-клиентов проходит через шлюз, а не через VPN (больше).

Поэтому нам нужно маркировать входящие пакеты из VPN и обеспечить, чтобы пакеты ответов направлялись обратно через тот же (виртуальный) интерфейс.

Правило маршрутизации:
/usr/sbin/ip rule add fwmark 4 table 4000
/usr/sbin/ip route add default dev tun0 table 4000

Файл nftables:

table inet vpn
delete table inet vpn
table inet vpn {
        chain entry {
                type filter hook input priority -500;
        iifname "tun0" ct mark set 4
        iifname "tun0" meta mark set 4
        }

        chain exit {
                type route hook output priority -500;
        ct mark 4 nftrace set 1
        ct mark 4 meta mark set ct mark
        }
}

Проблема

Смотрю с помощью nft monitor, я вижу, что входящие пакеты сопоставлены и маркированы.
Я предположил, что пакеты ответа будут иметь тот же “ct mark”.
Но это оказалось не так просто…

Как сделать так, чтобы пакеты ответа имели ту же метку, что и пакеты запроса, чтобы их захватывало правило маршрутизации?

Ответ или решение

Для решения проблемы маршрутизации ответных пакетов через тот же виртуальный интерфейс, по которому они были получены, необходимо использовать механизм маркировки пакетов с помощью nftables и conntrack. В приведённой ситуации у нас есть сервер с двумя сетевыми интерфейсами: физическим (eth0) и виртуальным (tun0), который подключен к сети через VPN. Основная цель — обеспечить, чтобы ответные пакеты, отправленные на запросы, пришедшие через VPN, маршрутизировались обратно через туннельный интерфейс tun0.

Теория

В Linux система маршрутизации определяет путь пакета на основе таблиц маршрутизации. В обычных условиях, когда пакет приходит на интерфейс, ядро Linux использует таблицу маршрутизации для определения пути отправки этого пакета. Однако в случае взаимодействия с VPN возникает задача, где пакеты должны возвращаться тем же путём, которым они пришли, чтобы избежать нарушения сессий и других проблем связанных с динамическим изменением IP-адресов и маршрутов.

Пример

Для решения описанной задачи мы используем conntrack — подсистему ядра Linux, которая ведёт учёт состояния сетевых соединений, натурализуя их для дальнейшего анализа и обработки. При помощи nftables мы можем маркировать пакеты определённым образом, используя контекст conntrack, который позволяет идентифицировать входящие и исходящие потоки относящиеся к одному и тому же соединению.

Конфигурация правила nftables, предоставленная в вопросе, задаёт соответствие пакетов из интерфейса tun0 с меткой 4, однако проблема заключается в том, что метка conntrack (ct mark) исходящих пакетов не автоматически соответствует метке, установленной для входящих пакетов.

Применение

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

Вот пример, как можно модифицировать конфигурацию для вашего случая:

table inet vpn
delete table inet vpn
table inet vpn {
    chain input {
        type filter hook input priority 0; policy accept;
        iifname "tun0" ct mark set 4
        iifname "tun0" meta mark set 4
    }

    chain output {
        type route hook output priority 0; policy accept;
        oifname "tun0" ct mark set 4
        ct mark 4 meta mark set ct mark
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        ip protocol tcp ct state related,established ct mark 4 meta mark set ct mark
    }
}

Объяснение:

  1. Цепь Input: Маркирует входящие пакеты на интерфейсе tun0 с помощью меток conntrack. Здесь важно правильно использовать метку conntrack, чтобы соединения автоматически учитывались при ответных передачах.

  2. Цепь Output: Помечает исходящие пакеты с меткой conntrack и применяет те же метки для маршрутизации пакетов через требуемый интерфейс.

  3. Цепь Postrouting: Используется для того, чтобы сохранить связку метки conntrack в процессе маршрутизации, таким образом, она применяется и на шаге postrouting, чтобы обеспечить, что после выполнения NAT операции метки корректно сохранились.

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

Заключение

Использование conntrack и правил nftables — эффективное средство для управления сложными сценариями маршрутизации, такими как те, которые связаны с использованием VPN. Важно понимать базовые принципы работы сетевых подсистем Linux и взаимодействие между различными уровнями сетевой стеки, чтобы корректно настраивать и управлять сетевыми соединениями в соответствии с заданными требованиями.

Оцените материал
Добавить комментарий

Капча загружается...