mikrotik-wiki.ru
Главная
Загрузка...

Селективная маршрутизация — трафик через VPN

RouterOS 7.xVPN11 мин230 мар. 2026 г.
TelegramVK

Селективная маршрутизация на MikroTik — определённый трафик через VPN

Селективная маршрутизация (policy-based routing) позволяет направлять через VPN-туннель только определённый трафик, а остальной отправлять напрямую через основного провайдера. Это полезно, когда нужно использовать VPN для конкретных устройств, доменов или сервисов, не снижая скорость остальной сети. В этой статье разберём три метода реализации, предотвращение DNS Leak, автоматическое обновление списков IP-адресов и типичные ошибки.

Описание

Задача

Типичные сценарии селективной маршрутизации:

  • Определённые устройства через VPN — рабочий ноутбук через корпоративный VPN, остальные устройства напрямую
  • Определённые сайты через VPN — заблокированные ресурсы через VPN, остальной трафик напрямую
  • Определённые порты через VPN — HTTPS-трафик через VPN, остальное напрямую
  • Комбинация — конкретные устройства + конкретные сайты + конкретные порты

Принцип работы

Селективная маршрутизация на MikroTik реализуется через связку:

  1. Mangle — маркировка трафика, который должен идти через VPN
  2. Routing Table — отдельная таблица маршрутизации для VPN-трафика
  3. Route — маршрут по умолчанию через VPN в этой таблице
  4. NAT — masquerade для VPN-интерфейса

Поток обработки пакета:

code
Пакет от устройства
    → Mangle (prerouting) — проверяет src/dst/port
    → Если совпадение → mark-routing = "vpn-route"
    → Routing decision — ищет маршрут в таблице "vpn-route"
    → Route "vpn-route" → gateway = VPN-интерфейс
    → NAT (masquerade) → пакет уходит через VPN

Предварительные требования

Предполагается, что у вас уже настроен VPN-туннель (WireGuard, OpenVPN, L2TP/IPsec или другой). Проверьте:

[admin@MikroTik] >
# Для WireGuard
/interface/wireguard/print
/interface/wireguard/peers/print

# Для OpenVPN
/interface/ovpn-client/print

# Для L2TP
/interface/l2tp-client/print

VPN-интерфейс должен быть активен (running=yes). Проверьте связность:

[admin@MikroTik] >
/ping 10.0.0.1 src-address=10.0.0.2 count=5

Где 10.0.0.1 — адрес VPN-сервера на его стороне туннеля, 10.0.0.2 — ваш адрес в VPN.

Настройка

Шаг 0: Создание routing table

В RouterOS 7 маршрутные таблицы создаются явно:

[admin@MikroTik] >
/routing/table/add name=vpn-route fib comment="Routing table for VPN traffic"

Параметр fib означает, что таблица будет использоваться для реальной пересылки пакетов (а не только для BGP/OSPF).

Шаг 1: Маршрут по умолчанию через VPN

Добавьте default route в таблицу vpn-route:

[admin@MikroTik] >
# Для WireGuard
/ip/route/add dst-address=0.0.0.0/0 gateway=wireguard1 \
    routing-table=vpn-route comment="Default route via VPN"

# Для OpenVPN
/ip/route/add dst-address=0.0.0.0/0 gateway=ovpn-client \
    routing-table=vpn-route comment="Default route via VPN"

# Для L2TP
/ip/route/add dst-address=0.0.0.0/0 gateway=l2tp-client \
    routing-table=vpn-route comment="Default route via VPN"

Шаг 2: NAT для VPN-интерфейса

Добавьте masquerade для VPN:

[admin@MikroTik] >
/ip/firewall/nat/add chain=srcnat \
    out-interface=wireguard1 \
    action=masquerade \
    comment="Masquerade VPN traffic"

Замените wireguard1 на имя вашего VPN-интерфейса.

Метод 1: Маршрутизация по устройству (src-address)

Направляем весь трафик конкретного устройства (или подсети) через VPN:

[admin@MikroTik] >
# Один компьютер через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address=192.168.88.100 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="PC-work via VPN"

# Несколько устройств через address-list
/ip/firewall/address-list
add list=vpn-devices address=192.168.88.100 comment="Рабочий ноутбук"
add list=vpn-devices address=192.168.88.101 comment="Рабочий телефон"
add list=vpn-devices address=192.168.88.102 comment="Smart TV"

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="VPN devices via address-list"

Для исключения локального трафика (чтобы обращения к локальной сети не шли через VPN):

[admin@MikroTik] >
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN from VPN routing" \
    place-before=0

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="VPN devices via address-list"

Важно: правило accept для LAN должно стоять выше правила mark-routing.

Метод 2: Маршрутизация по домену (dst-address-list)

Направляем трафик к определённым доменам/IP через VPN. Это сложнее, потому что MikroTik работает с IP-адресами, а не с доменами. Нужно предварительно разрешить домены в IP-адреса.

Шаг 2.1: Ручное добавление IP-адресов

Для сервисов с известными IP-диапазонами:

[admin@MikroTik] >
/ip/firewall/address-list
add list=vpn-destinations address=157.240.0.0/16 comment="Facebook"
add list=vpn-destinations address=31.13.24.0/21 comment="Facebook"
add list=vpn-destinations address=31.13.64.0/18 comment="Facebook"
add list=vpn-destinations address=69.171.224.0/19 comment="Facebook"
add list=vpn-destinations address=69.63.176.0/20 comment="Facebook"
add list=vpn-destinations address=173.252.64.0/18 comment="Facebook"
add list=vpn-destinations address=204.15.20.0/22 comment="Facebook"

Шаг 2.2: Автоматическое разрешение доменов через скрипт

Создайте скрипт, который периодически разрешает домены в IP и обновляет address-list:

[admin@MikroTik] >
/system/script/add name=vpn-dns-resolve source={
    :local domains {
        "www.example.com";
        "api.example.com";
        "cdn.example.com";
        "streaming.example.com"
    }
    :local listName "vpn-destinations"
    :local listComment "auto-resolved"

    # Удаляем старые автоматические записи
    :local oldEntries [/ip/firewall/address-list/find where list=$listName comment=$listComment]
    :if ([:len $oldEntries] > 0) do={
        /ip/firewall/address-list/remove $oldEntries
    }

    # Разрешаем домены и добавляем IP
    :foreach domain in=$domains do={
        :do {
            :local ip [:resolve $domain]
            :log info "VPN-route: $domain -> $ip"
            /ip/firewall/address-list/add list=$listName address=$ip \
                comment=$listComment timeout=1d
        } on-error={
            :log warning "VPN-route: не удалось разрешить $domain"
        }
    }

    :log info "VPN-route: обновление DNS завершено"
}

Настройте автоматический запуск каждые 30 минут:

[admin@MikroTik] >
/system/scheduler/add name=vpn-dns-update \
    interval=30m \
    on-event="/system/script/run vpn-dns-resolve" \
    comment="Update VPN destination IPs"

Шаг 2.3: Mangle-правило для dst-address-list

[admin@MikroTik] >
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Route specific destinations via VPN"

Метод 3: Маршрутизация по порту

Направляем определённые протоколы/порты через VPN:

[admin@MikroTik] >
# Весь HTTPS через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=443 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="HTTPS via VPN"

# Торренты (типичные порты) через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=6881-6889 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Torrent TCP via VPN"

/ip/firewall/mangle/add chain=prerouting \
    protocol=udp dst-port=6881-6889 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Torrent UDP via VPN"

Комбинирование методов

Можно комбинировать все три метода. Порядок правил в mangle имеет значение:

[admin@MikroTik] >
# 1. Исключаем локальный трафик (всегда первое!)
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN" \
    place-before=0

# 2. Конкретные устройства — всё через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="All traffic from VPN devices"

# 3. Конкретные сайты — со всех устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="Specific sites via VPN"

# 4. Конкретные порты — со всех устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=443 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="HTTPS via VPN"

Обратите внимание на passthrough=no — после совпадения с правилом пакет не проверяется следующими правилами в mangle. Это важно, если вы хотите, чтобы устройства из vpn-devices не проверялись правилами по dst-address-list.

Предотвращение DNS Leak

DNS Leak — одна из главных проблем селективной маршрутизации. Даже если трафик идёт через VPN, DNS-запросы могут уходить через основного провайдера, раскрывая, какие сайты вы посещаете.

Решение 1: Перенаправление DNS для VPN-устройств

[admin@MikroTik] >
# DNS-запросы от VPN-устройств → через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    protocol=udp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="DNS from VPN devices via VPN" \
    place-before=0

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    protocol=tcp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="DNS TCP from VPN devices via VPN" \
    place-before=1

Решение 2: Split DNS — разные DNS-серверы для разного трафика

Настройте MikroTik так, чтобы он использовал DNS-сервер на стороне VPN для определённых доменов:

[admin@MikroTik] >
# DNS-сервер VPN-провайдера (на стороне туннеля)
/ip/dns/static/add name=example.com type=FWD forward-to=10.0.0.1 comment="via VPN DNS"
/ip/dns/static/add name=api.example.com type=FWD forward-to=10.0.0.1 comment="via VPN DNS"

Где 10.0.0.1 — DNS-сервер на стороне VPN.

Решение 3: Принудительный DNS через VPN для всех

Если хотите, чтобы все DNS-запросы шли через VPN:

[admin@MikroTik] >
/ip/dns/set servers=10.0.0.1

Но это замедлит DNS-разрешение для всей сети. Используйте только если VPN быстрый и стабильный.

Скрипт автообновления address-list из файла

Для больших списков доменов удобнее хранить их в файле и обновлять через скрипт:

[admin@MikroTik] >
/system/script/add name=vpn-update-destinations source={
    :local listName "vpn-destinations"
    :local listComment "auto-resolved"

    # Список доменов для разрешения
    :local domains [:toarray ""]
    :set ($domains->[:len $domains]) "www.example1.com"
    :set ($domains->[:len $domains]) "www.example2.com"
    :set ($domains->[:len $domains]) "api.example3.com"
    :set ($domains->[:len $domains]) "cdn.example4.com"
    :set ($domains->[:len $domains]) "stream.example5.com"

    :log info "VPN destinations: начало обновления"

    # Удаляем устаревшие записи
    :foreach entry in=[/ip/firewall/address-list/find where list=$listName comment=$listComment] do={
        /ip/firewall/address-list/remove $entry
    }

    :local count 0

    :foreach domain in=$domains do={
        :do {
            :local resolvedIP [:resolve $domain]
            /ip/firewall/address-list/add list=$listName address=$resolvedIP \
                comment=$listComment timeout=2h
            :set count ($count + 1)
            :log info "VPN destinations: $domain -> $resolvedIP"
        } on-error={
            :log warning "VPN destinations: ошибка разрешения $domain"
        }
    }

    :log info "VPN destinations: обновлено $count записей"
}
[admin@MikroTik] >
/system/scheduler/add name=vpn-destinations-update \
    interval=1h \
    on-event="/system/script/run vpn-update-destinations" \
    comment="Hourly update of VPN destination IPs"

Отказоустойчивость: проверка VPN-туннеля

Если VPN-туннель падает, трафик с routing-mark vpn-route перестанет ходить. Добавьте проверку через Netwatch:

[admin@MikroTik] >
/tool/netwatch/add host=10.0.0.1 \
    type=icmp interval=30s timeout=2s \
    up-script="/ip/route/enable [find where routing-table=vpn-route comment~\"VPN\"]" \
    down-script={
        /ip/route/disable [find where routing-table=vpn-route comment~"VPN"]
        :log warning "VPN tunnel is down, disabling VPN routing"
    } \
    comment="Monitor VPN tunnel"

При падении VPN маршрут в таблице vpn-route отключается, и трафик пойдёт по обычному маршруту (через основного провайдера). При восстановлении VPN маршрут включается обратно.

Проверка

Проверка routing table

[admin@MikroTik] >
/routing/table/print

Должна быть таблица vpn-route.

Проверка маршрутов

[admin@MikroTik] >
/ip/route/print where routing-table=vpn-route

Должен быть default route через VPN-интерфейс.

Проверка mangle-правил

[admin@MikroTik] >
/ip/firewall/mangle/print stats

Посмотрите счётчики packets и bytes — если они растут, правила работают.

Проверка address-list

[admin@MikroTik] >
/ip/firewall/address-list/print where list=vpn-destinations
/ip/firewall/address-list/print where list=vpn-devices

Traceroute для проверки маршрута

С устройства, которое должно ходить через VPN:

code
tracert 8.8.8.8

Первые хопы должны показывать адреса из VPN-туннеля, а не адреса провайдера.

С устройства, которое должно ходить напрямую — в traceroute должны быть адреса провайдера.

Проверка из RouterOS (с указанием routing-table):

[admin@MikroTik] >
/tool/traceroute address=8.8.8.8 routing-table=vpn-route count=1

Проверка DNS Leak

Используйте сайт dnsleaktest.com с устройства, маршрутизируемого через VPN. Результат должен показывать DNS-серверы на стороне VPN, а не вашего провайдера.

Из RouterOS проверьте, через какой DNS разрешается домен:

routeros
:put [:resolve "whoami.akamai.net"]

Мониторинг нагрузки на VPN

[admin@MikroTik] >
/interface/monitor-traffic wireguard1 once

Это покажет текущую скорость tx/rx через VPN-интерфейс.

Типичные ошибки

1. DNS Leak — DNS-запросы идут мимо VPN

Самая частая ошибка. Вы настроили маршрутизацию HTTP/HTTPS через VPN, но забыли про DNS. DNS-запросы (порт 53) уходят через основного провайдера, раскрывая домены, которые вы посещаете.

Решение: добавьте mangle-правила для DNS-трафика (описано выше в разделе «Предотвращение DNS Leak»).

2. Routing loop — трафик к VPN-серверу тоже идёт через VPN

Если VPN-сервер находится в интернете и его IP попадает под mangle-правило (например, dst-port=443), трафик к самому VPN-серверу тоже пойдёт через VPN, создавая петлю. VPN-туннель разорвётся.

Решение: добавьте исключение для IP VPN-сервера:

[admin@MikroTik] >
/ip/firewall/mangle/add chain=prerouting \
    dst-address=<VPN_SERVER_IP> \
    action=accept \
    comment="Exclude VPN server from policy routing" \
    place-before=0

Замените <VPN_SERVER_IP> на реальный IP вашего VPN-сервера.

3. Забыли masquerade для VPN-интерфейса

Без NAT на VPN-интерфейсе пакеты уйдут с локальным src-address (192.168.88.x), и VPN-сервер не сможет вернуть ответ.

Решение:

[admin@MikroTik] >
/ip/firewall/nat/add chain=srcnat out-interface=wireguard1 action=masquerade

4. Локальный трафик идёт через VPN

Если mangle-правило маркирует весь трафик от устройства (src-address=192.168.88.100), то обращения к локальным ресурсам (NAS, принтер, другие ПК) тоже пойдут через VPN и не будут работать.

Решение: добавьте исключение для LAN перед правилом маркировки:

[admin@MikroTik] >
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN" \
    place-before=0

5. VPN упал — трафик не ходит

Если VPN-туннель разрывается, маршрут в таблице vpn-route становится unreachable, и маркированный трафик просто пропадает.

Решения:

  • Используйте Netwatch для мониторинга VPN (описано выше)
  • Добавьте fallback-маршрут с большей distance:
[admin@MikroTik] >
/ip/route/add dst-address=0.0.0.0/0 gateway=192.168.88.1 \
    routing-table=vpn-route distance=10 \
    comment="Fallback route if VPN is down"

Где 192.168.88.1 — шлюз вашего провайдера в основной таблице. Distance=10 означает, что этот маршрут будет использоваться только если VPN-маршрут (distance=1 по умолчанию) недоступен.

6. passthrough=yes вместо passthrough=no

При passthrough=yes пакет продолжает проверяться следующими mangle-правилами и может быть перемаркирован. Если у вас несколько правил и вы хотите, чтобы первое совпавшее было финальным:

[admin@MikroTik] >
# Правильно: passthrough=no — после маркировки пакет выходит из mangle
/ip/firewall/mangle/set [find where comment="All traffic from VPN devices"] passthrough=no

7. Address-list для домена содержит устаревшие IP

CDN-сервисы (Cloudflare, Akamai, AWS) часто меняют IP-адреса. Статический address-list быстро устаревает.

Решение: используйте скрипт автообновления с коротким timeout (1–2 часа) и частым запуском через scheduler (каждые 30–60 минут).

8. Неправильный порядок правил в mangle

Mangle обрабатывает правила сверху вниз. Если правило accept для LAN стоит ниже правила mark-routing, локальный трафик будет маркирован и пойдёт через VPN.

Проверьте порядок:

[admin@MikroTik] >
/ip/firewall/mangle/print

Правильный порядок:

  1. accept — исключения (LAN, VPN-сервер)
  2. mark-routing — маркировка VPN-трафика

Используйте place-before=0 или drag-and-drop в WinBox для перемещения правил.

9. Не работает с FastTrack

FastTrack обходит mangle. Если у вас включён FastTrack для established/related-соединений, mangle-правила не будут применяться к этим соединениям.

Решение: для connection-mark работа с FastTrack возможна, но routing-mark через mangle несовместим с FastTrack. Если селективная маршрутизация не работает, проверьте:

[admin@MikroTik] >
/ip/firewall/filter/print where action=fasttrack-connection

Для соединений, маршрутизируемых через VPN, FastTrack нужно отключить или добавить исключение:

[admin@MikroTik] >
/ip/firewall/filter/add chain=forward \
    src-address-list=vpn-devices \
    action=accept \
    comment="Skip FastTrack for VPN devices" \
    place-before=[find where action=fasttrack-connection]

Полный пример: устройства + сайты через WireGuard

[admin@MikroTik] >
# === Routing Table ===
/routing/table/add name=vpn-route fib

# === Route ===
/ip/route/add dst-address=0.0.0.0/0 gateway=wireguard1 routing-table=vpn-route

# === NAT ===
/ip/firewall/nat/add chain=srcnat out-interface=wireguard1 action=masquerade

# === Address Lists ===
/ip/firewall/address-list
add list=vpn-devices address=192.168.88.100 comment="Рабочий ноутбук"
add list=vpn-devices address=192.168.88.101 comment="Рабочий телефон"
add list=vpn-destinations address=157.240.0.0/16 comment="Facebook"

# === Mangle ===
# 1. Исключение VPN-сервера
/ip/firewall/mangle/add chain=prerouting \
    dst-address=203.0.113.1 action=accept \
    comment="Exclude VPN server"

# 2. Исключение LAN
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 action=accept \
    comment="Exclude LAN"

# 3. DNS от VPN-устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices protocol=udp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="DNS via VPN"

# 4. Все VPN-устройства через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="VPN devices"

# 5. Конкретные сайты через VPN (для всех)
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="VPN destinations"

# === Netwatch ===
/tool/netwatch/add host=10.0.0.1 type=icmp interval=30s \
    down-script="/ip/route/disable [find where routing-table=vpn-route]" \
    up-script="/ip/route/enable [find where routing-table=vpn-route]"

Заключение

Селективная маршрутизация — мощный инструмент MikroTik, позволяющий гибко управлять потоками трафика. Ключевые принципы: правильный порядок mangle-правил, обязательные исключения для LAN и VPN-сервера, предотвращение DNS Leak и мониторинг состояния VPN-туннеля. Комбинация методов (по устройству + по домену + по порту) покрывает большинство практических сценариев.

[admin@MikroTik] >
Пакет от устройства
    → Mangle (prerouting) — проверяет src/dst/port
    → Если совпадение → mark-routing = "vpn-route"
    → Routing decision — ищет маршрут в таблице "vpn-route"
    → Route "vpn-route" → gateway = VPN-интерфейс
    → NAT (masquerade) → пакет уходит через VPN
# Для WireGuard
/interface/wireguard/print
/interface/wireguard/peers/print

# Для OpenVPN
/interface/ovpn-client/print

# Для L2TP
/interface/l2tp-client/print
/ping 10.0.0.1 src-address=10.0.0.2 count=5
/routing/table/add name=vpn-route fib comment="Routing table for VPN traffic"
# Для WireGuard
/ip/route/add dst-address=0.0.0.0/0 gateway=wireguard1 \
    routing-table=vpn-route comment="Default route via VPN"

# Для OpenVPN
/ip/route/add dst-address=0.0.0.0/0 gateway=ovpn-client \
    routing-table=vpn-route comment="Default route via VPN"

# Для L2TP
/ip/route/add dst-address=0.0.0.0/0 gateway=l2tp-client \
    routing-table=vpn-route comment="Default route via VPN"
/ip/firewall/nat/add chain=srcnat \
    out-interface=wireguard1 \
    action=masquerade \
    comment="Masquerade VPN traffic"
# Один компьютер через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address=192.168.88.100 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="PC-work via VPN"

# Несколько устройств через address-list
/ip/firewall/address-list
add list=vpn-devices address=192.168.88.100 comment="Рабочий ноутбук"
add list=vpn-devices address=192.168.88.101 comment="Рабочий телефон"
add list=vpn-devices address=192.168.88.102 comment="Smart TV"

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="VPN devices via address-list"
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN from VPN routing" \
    place-before=0

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="VPN devices via address-list"
/ip/firewall/address-list
add list=vpn-destinations address=157.240.0.0/16 comment="Facebook"
add list=vpn-destinations address=31.13.24.0/21 comment="Facebook"
add list=vpn-destinations address=31.13.64.0/18 comment="Facebook"
add list=vpn-destinations address=69.171.224.0/19 comment="Facebook"
add list=vpn-destinations address=69.63.176.0/20 comment="Facebook"
add list=vpn-destinations address=173.252.64.0/18 comment="Facebook"
add list=vpn-destinations address=204.15.20.0/22 comment="Facebook"
/system/script/add name=vpn-dns-resolve source={
    :local domains {
        "www.example.com";
        "api.example.com";
        "cdn.example.com";
        "streaming.example.com"
    }
    :local listName "vpn-destinations"
    :local listComment "auto-resolved"

    # Удаляем старые автоматические записи
    :local oldEntries [/ip/firewall/address-list/find where list=$listName comment=$listComment]
    :if ([:len $oldEntries] > 0) do={
        /ip/firewall/address-list/remove $oldEntries
    }

    # Разрешаем домены и добавляем IP
    :foreach domain in=$domains do={
        :do {
            :local ip [:resolve $domain]
            :log info "VPN-route: $domain -> $ip"
            /ip/firewall/address-list/add list=$listName address=$ip \
                comment=$listComment timeout=1d
        } on-error={
            :log warning "VPN-route: не удалось разрешить $domain"
        }
    }

    :log info "VPN-route: обновление DNS завершено"
}
/system/scheduler/add name=vpn-dns-update \
    interval=30m \
    on-event="/system/script/run vpn-dns-resolve" \
    comment="Update VPN destination IPs"
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Route specific destinations via VPN"
# Весь HTTPS через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=443 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="HTTPS via VPN"

# Торренты (типичные порты) через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=6881-6889 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Torrent TCP via VPN"

/ip/firewall/mangle/add chain=prerouting \
    protocol=udp dst-port=6881-6889 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=yes \
    comment="Torrent UDP via VPN"
# 1. Исключаем локальный трафик (всегда первое!)
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN" \
    place-before=0

# 2. Конкретные устройства — всё через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="All traffic from VPN devices"

# 3. Конкретные сайты — со всех устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="Specific sites via VPN"

# 4. Конкретные порты — со всех устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    protocol=tcp dst-port=443 \
    src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="HTTPS via VPN"
# DNS-запросы от VPN-устройств → через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    protocol=udp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="DNS from VPN devices via VPN" \
    place-before=0

/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    protocol=tcp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route \
    passthrough=no \
    comment="DNS TCP from VPN devices via VPN" \
    place-before=1
# DNS-сервер VPN-провайдера (на стороне туннеля)
/ip/dns/static/add name=example.com type=FWD forward-to=10.0.0.1 comment="via VPN DNS"
/ip/dns/static/add name=api.example.com type=FWD forward-to=10.0.0.1 comment="via VPN DNS"
/ip/dns/set servers=10.0.0.1
/system/script/add name=vpn-update-destinations source={
    :local listName "vpn-destinations"
    :local listComment "auto-resolved"

    # Список доменов для разрешения
    :local domains [:toarray ""]
    :set ($domains->[:len $domains]) "www.example1.com"
    :set ($domains->[:len $domains]) "www.example2.com"
    :set ($domains->[:len $domains]) "api.example3.com"
    :set ($domains->[:len $domains]) "cdn.example4.com"
    :set ($domains->[:len $domains]) "stream.example5.com"

    :log info "VPN destinations: начало обновления"

    # Удаляем устаревшие записи
    :foreach entry in=[/ip/firewall/address-list/find where list=$listName comment=$listComment] do={
        /ip/firewall/address-list/remove $entry
    }

    :local count 0

    :foreach domain in=$domains do={
        :do {
            :local resolvedIP [:resolve $domain]
            /ip/firewall/address-list/add list=$listName address=$resolvedIP \
                comment=$listComment timeout=2h
            :set count ($count + 1)
            :log info "VPN destinations: $domain -> $resolvedIP"
        } on-error={
            :log warning "VPN destinations: ошибка разрешения $domain"
        }
    }

    :log info "VPN destinations: обновлено $count записей"
}
/system/scheduler/add name=vpn-destinations-update \
    interval=1h \
    on-event="/system/script/run vpn-update-destinations" \
    comment="Hourly update of VPN destination IPs"
/tool/netwatch/add host=10.0.0.1 \
    type=icmp interval=30s timeout=2s \
    up-script="/ip/route/enable [find where routing-table=vpn-route comment~\"VPN\"]" \
    down-script={
        /ip/route/disable [find where routing-table=vpn-route comment~"VPN"]
        :log warning "VPN tunnel is down, disabling VPN routing"
    } \
    comment="Monitor VPN tunnel"
/routing/table/print
/ip/route/print where routing-table=vpn-route
/ip/firewall/mangle/print stats
/ip/firewall/address-list/print where list=vpn-destinations
/ip/firewall/address-list/print where list=vpn-devices
tracert 8.8.8.8
/tool/traceroute address=8.8.8.8 routing-table=vpn-route count=1
:put [:resolve "whoami.akamai.net"]
/interface/monitor-traffic wireguard1 once
/ip/firewall/mangle/add chain=prerouting \
    dst-address=<VPN_SERVER_IP> \
    action=accept \
    comment="Exclude VPN server from policy routing" \
    place-before=0
/ip/firewall/nat/add chain=srcnat out-interface=wireguard1 action=masquerade
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 \
    action=accept \
    comment="Exclude LAN" \
    place-before=0
/ip/route/add dst-address=0.0.0.0/0 gateway=192.168.88.1 \
    routing-table=vpn-route distance=10 \
    comment="Fallback route if VPN is down"
# Правильно: passthrough=no — после маркировки пакет выходит из mangle
/ip/firewall/mangle/set [find where comment="All traffic from VPN devices"] passthrough=no
/ip/firewall/mangle/print
/ip/firewall/filter/print where action=fasttrack-connection
/ip/firewall/filter/add chain=forward \
    src-address-list=vpn-devices \
    action=accept \
    comment="Skip FastTrack for VPN devices" \
    place-before=[find where action=fasttrack-connection]
# === Routing Table ===
/routing/table/add name=vpn-route fib

# === Route ===
/ip/route/add dst-address=0.0.0.0/0 gateway=wireguard1 routing-table=vpn-route

# === NAT ===
/ip/firewall/nat/add chain=srcnat out-interface=wireguard1 action=masquerade

# === Address Lists ===
/ip/firewall/address-list
add list=vpn-devices address=192.168.88.100 comment="Рабочий ноутбук"
add list=vpn-devices address=192.168.88.101 comment="Рабочий телефон"
add list=vpn-destinations address=157.240.0.0/16 comment="Facebook"

# === Mangle ===
# 1. Исключение VPN-сервера
/ip/firewall/mangle/add chain=prerouting \
    dst-address=203.0.113.1 action=accept \
    comment="Exclude VPN server"

# 2. Исключение LAN
/ip/firewall/mangle/add chain=prerouting \
    dst-address=192.168.88.0/24 action=accept \
    comment="Exclude LAN"

# 3. DNS от VPN-устройств через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices protocol=udp dst-port=53 \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="DNS via VPN"

# 4. Все VPN-устройства через VPN
/ip/firewall/mangle/add chain=prerouting \
    src-address-list=vpn-devices \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="VPN devices"

# 5. Конкретные сайты через VPN (для всех)
/ip/firewall/mangle/add chain=prerouting \
    dst-address-list=vpn-destinations src-address=192.168.88.0/24 \
    action=mark-routing new-routing-mark=vpn-route passthrough=no \
    comment="VPN destinations"

# === Netwatch ===
/tool/netwatch/add host=10.0.0.1 type=icmp interval=30s \
    down-script="/ip/route/disable [find where routing-table=vpn-route]" \
    up-script="/ip/route/enable [find where routing-table=vpn-route]"
VPN / Селективная маршрутизация — трафик через VPN