Кожній кінцевій точці тунелю потрібні адреса й порт, до яких може дістатися інша сторона, і маршрутизатор, яким ви не керуєте, — звичайна причина, чому ця вимога не виконується. Цікаве не те, що існують хитрощі, а те, що кожна з них залежить від властивості таблиці відображення, якої ви не бачите з клієнта. Дві такі властивості вирішують майже все: як створюється відображення і чи приймає воно пакети з адреси, з якою внутрішня частина ніколи не контактувала. Упорядкуйте середовище за цими властивостями, і обхідні рішення перестануть бути фольклором.

Таблиця відображення вирішує все

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

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

Що може і чого не може служба зустрічі

Пробивання UDP-отворів використовує вихідний запис як тимчасовий отвір, а не перемагає фільтр. Обидві сторони звертаються до служби зустрічі, яка дізнається про кожну публічну кінцеву точку й повідомляє іншій стороні її точку. Потім обидві надсилають назустріч одна одній, і кожен вихідний пакет створює або оновлює запис, що пропускає відповідь усередину. Порядок — те, що змушує це працювати, і порядок — те, що робить це крихким: сторона, яка надіслала раніше, ніж інша створила свій запис, просто відкидається, а повторна спроба за мить вдається. Сама служба не несе VPN-трафіку, тож її єдиний важіль — час, який вона координує.

Поведінка відображення вирішує решту, і RFC 4787 називає три форми: незалежну від кінцевої точки, залежну від адреси та залежну від адреси й порту. За останньої порт, на який має цілитися сторона, змінюється з кожним призначенням, тому прогноз перестає бути надійним. Тут техніка сягає глухого кута, адже NAT операторського рівня й суворий корпоративний міжмережевий екран обидва усувають передбачуваність, потрібну схемі, і жодна кількість повторів її не повертає.

Keepalive, перезавантаження й кінцева точка, що рухається

Пробитий шлях — це потік, а не слухач, тож усе, що працює поверх нього, має пережити зміну. Воно повинно підтримувати відображення живим періодичним трафіком, помічати, коли публічна кінцева точка зміщується, і відновлюватися після перезавантаження маршрутизатора чи перепризначення адреси. Mesh VPN продукти кладуть цю логіку у власну площину керування, а звичайний сервер залишає її вам. Keepalive допомагають лише доки виживає те саме відображення, і вони витрачають батарею на мобільному клієнті, тому агресивний інтервал не безкоштовний.

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

Три способи обійти відсутнє переспрямування

Перший спосіб просить маршрутизатор сам створити запис, через UPnP IGD, NAT-PMP або PCP, коли функція є й увімкнена. Другий передає трафік релею з публічною адресою, що завжди працює і завжди коштує пропускної здатності плюс іншої межі довіри. Третій перевертає напрямок: внутрішній хост відкриває вихідний тунель до публічного сервера, і все інше їде всередині нього.

[Peer]
PublicKey = 6yGj3kQ2wVb8sTn1pLx4dRc7hZa9mKf2uYe5oNq0iXw=
Endpoint = relay.corp.internal:51820
PersistentKeepalive = 25
AllowedIPs = 10.44.0.0/24

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

Узгодьте обхідне рішення з тим, хто володіє маршрутизатором

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

Зауважте, чи шлях, до якого ви дійшли, був прямим або через релей, адже цей єдиний факт передбачає і затримку, і поведінку під час збою. RFC 4787 залишається довідкою щодо поведінки відображення під усім цим, і читати його розділ про відображення швидше, ніж послідовно тестувати три обхідні рішення. Таблиці байдуже, який варіант ви обрали; вона фіксує лише те, що дозволено наступному пакету.

Схожі статті