Правильний NAT Loopback / Hairpin NAT у MikroTik

29.10.2023 19:08

Трохи теорії

NAT

Технологія NAT (Network Address Translation), а точніше один із її різновидів — PAT (Port Address Translation), дозволяє використовувати одну зовнішню IP-адресу для встановлення з’єднань кількома пристроями у локальній мережі. Давайте розглянемо, як це працює.

Спрощена схема проходження пакетів у Linux/MikroTik (PacketFlow)

Розглянемо стандартну мережу та маршрутизатор MikroTik

Схема мережі для прикладів
Коли комп’ютер у локальній мережі хоче отримати доступ до ресурсу і надсилає запит в інтернет, маршрутизатор створює новий запис у таблиці трансляції адрес (NAT connections table), присвоює мітку new на етапі connection tracking. Далі слідує етап routing decision, де маршрутизатор присвоює пакету вихідний інтерфейс (як правило WANether1). Після проходження ланцюжка forward, у post routing відбувається заміна адреси джерела на адресу вихідного інтерфейсу динамічно (action: masquerade) або заздалегідь задано статично (action: src-nat — to-address).Таким чином, пакет виходить в інтернет із зовнішньою IP-адресою маршрутизатора зі збереженою початковою адресою призначення.У вигляді правил MikroTik механізм виглядає приблизно так:

Перший етап проходження NAT: запит з LAN до WAN

Для того щоб ідентифікувати це з’єднання в таблиці трансляції адрес, створюється запис, де містяться параметри з’єднання: адреса джерела (у локальній мережі), адреса призначення, порт призначення, порт джерела. У MikroTik цю таблицю можна переглянути в IP → Firewall → Connections. Ці записи містять додаткові поля, такі як: наявність fasttrack, чи є відповідні пакети, активність правил ланцюжків src-nat і dst-nat та інші. Якщо NAT у MikroTik не ввімкнено (відсутні робочі правила таблиці NAT), то connection tracking автоматично вимикається за непотрібністю.Таким чином, коли надходить відповідь від сервера, маршрутизатор перевіряє таблицю трансляції адрес і, якщо знаходить відповідний запис, то на етапі connection tracking замінює адресу призначення із зовнішньої IP-адреси маршрутизатора на локальну адресу пристрою, яка була збережена раніше в таблиці трансляції. Завдяки цьому механізму пристрій у локальній мережі отримує доступ до інтернету.

Другий етап проходження NAT: відповідь з WAN до LAN

Перекидання портів

Ключовою особливістю є те, що нові запити можуть створюватися тільки в одному напрямку: з локальної мережі в інтернет, але не навпаки. «NAT не є брандмауером», однак у стандартній конфігурації через специфіку роботи він забороняє всі нові з’єднання із зовнішнього інтерфейсу в локальну мережу. При відсутності відповідного правила для зворотної трансляції, пакет переходить у ланцюжок input — тобто до пакетів, які адресовані самому маршрутизатору. Якщо не знайдена відповідна служба на маршрутизаторі, що прослуховує з’єднання на порту, пакет відкидається.

Іноді виникає потреба приймати нові з’єднання з інтернету на комп’ютері в локальній мережі за NAT. Для цього знадобиться правило «зворотного NAT», яке спрацює у ланцюжку prerouting і замінить адресу призначення на потрібну.

Як видно з правила, воно спрацює на всі пакети, що проходять через роутер, у яких порт призначення 80 або 443, і перепише їхню адресу на 192.168.88.5. Але оскільки дія цього правила поширюється і на пакети, що йдуть із локальної мережі, то пристрої в локальній мережі більше не зможуть отримувати доступ до web-ресурсів інтернету, тому що маршрутизатор почне замінювати адресу призначення на 192.168.88.5 для всіх пакетів, що відповідають умові. Щоб цього не сталося, необхідно додати умови адреси призначення або інтерфейсу призначення.

Це правило буде повноцінно працювати і перенаправляти нові з’єднання з інтернету на пристрій у локальній мережі.

NAT Loopback / Hairpin NAT

Проблема

З новими з’єднаннями з Інтернету розібралися, але що буде, якщо пристрій намагатиметься звернутися на зовнішню адресу маршрутизатора з локальної мережі? Залежно від умови можливі такі варіанти:

  • Якщо за умови використовувався зовнішній інтерфейс, правило не спрацює і пакет буде відкинуто маршрутизатором — з’єднання не відбудеться.
  • Якщо використовується зовнішня адреса маршрутизатора, правило спрацює, але з’єднання не встановиться. Розглянемо цей сценарій докладніше..

Пакет буде відкинуто ініціатором з’єднання

Запит успішно дійде до пристрою призначення, проте відповідь буде повернутися безпосередньо на пристрій, без маршрутизатора. В результаті при перевірках на пристрої-ініціаторі з’єднання пакет буде відкинутий, тому що від цієї адреси джерела він не чекає відповіді. З’єднання не встановиться.

Варіанти розв’язання

Підміна на рівні DNS

Якщо програма використовує DNS для визначення IP адреси сервісу призначення (наприклад, сайт), то правильним способом буде використання в локальній мережі DNS-сервера, який буде віддавати внутрішню IP адресу для домену. У разі використання MikroTik DNS-сервера правило буде виглядати приблизно так:

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

Дане рішення не буде працювати у разі використання DNS-over-HTTPS або аналогів на кінцевих пристроях або у випадку, якщо програма не використовує доменні імена.

Офіційний

Багато ресурсів, включаючи wiki.mikrotik.com, пропонують приблизно одні й самі варіанти рішення:

Цим правилом задаємо, що: всім пакетам, що йдуть з локальної мережі, на адресу 192.168.88.5, на порти 80 і 443 і виходять з інтерфейсу LAN ми змінюємо адресу джерела на адресу маршрутизатора локальної мережі.

Таким чином, з’єднання успішно встановлюється, проте є кілька обмежень:

  • На кожне правило прокидання порту потрібно ще одне правило для підтримки NAT Loopback
  • Можна легко потрапити на граблю, не вказавши фільтр джерела пакетів (src-address = 192.168.88.0/24). Всі запити (включаючи ті, що йдуть з інтернету) на сервер призначення будуть йти від адреси маршрутизатора, що може зламати фільтрацію на базі адрес джерела на сервері призначення.
  • Серверу призначення, якому в результаті прийде запит, не буде видно IP адресу джерела, оскільки ним буде маршрутизатор

Доповнений офіційний спосіб

Офіційний спосіб не найкращие насамперед тим, що потрібно створювати кілька правил для одного прокидання портів. Про це легко забути чи помилитися у складанні другого правила.

Суть цього рішення полягає в тому, щоб на вході в маршрутизатор ми маркуємо пакети, що прийшли на зовнішню адресу з локальної мережі, а після проходження процедури маршрутизації підставляти IP-адресу маршрутизатора окремими правилами, відмінними від правил прокидання портів.

Першим етапом потрібно промаркувати (new-packet-mark=nat-loopback) ті пакети, які прийшли на зовнішню адресу маршрутизатора (dst-address=203.0.113.5) з локальної мережі (in-interface=LAN) та є новими з’єднаннями (connection-state=new).

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

Далі можна писати правила прокидання у класичному вигляді. Цією схемою ми позбулися двох із трьох недоліків попереднього способу.

Таким чином, з’являється можливість писати правила прокидання портів у звичайному вигляді по одному на порт або кілька портів. Вони працюватимуть як і в класичному сценарії (при надходженні ззовні), так і у разі надходження запитів із локальної мережі.

Залишити відповідь

Вгору