Чому UDP-відповідь OpenVPN виходить із неправильної адреси
UDP-сервер із кількома локальними адресами може відповісти клієнту з іншої адреси, не тієї, до якої той звертався. multihome виправляє джерело на підтримуваних платформах.
Клієнт OpenVPN звертається до однієї адреси, сервер відповідає з іншої, і тунель так і не піднімається. Журнал сервера показує надходження пакета, а запис показує вихід відповіді, тому провину покладають на клієнта. На хості з кількома інтерфейсами або кількома адресами на одному інтерфейсі сторони просто не сходяться в тому, яка адреса використовується. Відповідь коректна на рівні IP, але багато клієнтів відкидають датаграму, джерело якої не збігається з адресою, до якої вони зверталися.
Що клієнт бачить, коли джерело змінюється
UDP-сокет, не прив'язаний до конкретної локальної адреси, не має фіксованого джерела, тому ядро вибирає його під час надсилання. Цей вибір походить із пошуку маршруту до адреси клієнта, і джерелом стає адреса того інтерфейсу, який вибере пошук. На машині з одним інтерфейсом вибір непомітний; на хості з адресою керування, публічною адресою та додатковою адресою на тій самій мережевій карті він залежить від метрик і політики маршрутизації. Маршрутизація за політиками робить невідповідність імовірнішою, а не менш імовірною, бо правило може вибрати вихідний канал, до якого клієнт ніколи не доходив. Достатньо маршруту за замовчуванням, отриманого від одного провайдера, і правила джерела, що вказує на іншого.
Клієнти, які фільтрують відповіді, і відстеження з'єднань, яке очікує точну четвірку та джерело, відкинуть відповідь без корисного повідомлення. Тоді тунель спливає, наче нічого не надійшло, і саме тому це помилково вважають проблемою міжмережевого екрана на боці клієнта. Запис, зроблений лише на сервері, підтверджує помилку, а не пояснює її, бо відповідь справді виходить. Порівняйте джерело відповіді з адресою, до якої звертався клієнт, перш ніж змінювати будь-що інше.
Що насправді робить параметр multihome
Директива записується як multihome у файлі конфігурації та як --multihome у командному рядку, і вона змушує UDP-сервер відповідати з адреси, до якої дійшов пакет клієнта. Ядро під час приймання передає початкову адресу призначення як додаткові дані, і OpenVPN використовує це значення як джерело відповіді. Так сервер, що слухає на загальній адресі, local 0.0.0.0 для IPv4 або його еквівалент для IPv6, поводиться так, ніби кожен клієнт дійшов до окремого слухача. Клієнти, що прийшли через публічну адресу, отримують відповіді з публічної адреси, а клієнти на внутрішній адресі — з неї. Ніщо інше на шляху пакета не рухається: маршрут, правила фільтрації та конфігурація тунелю залишаються точно такими, якими були.
Саме ця остання властивість робить параметр безпечним для додавання на інакше робочий сервер, і вона ж пояснює, чому він не може виправити фільтр, що дозволяє лише одну адресу. Пакет усе одно має бути прийнятий на тому шляху, яким іде, тому виправлення джерела змінює походження відповіді й нічого більше. Він також лише для UDP: у TCP-слухача такої проблеми в тій самій формі немає, бо з'єднання визначається четвіркою, а не адресою джерела відповіді.
Коли фіксована локальна адреса є неправильним значенням за замовчуванням
Перш ніж братися за параметр, перевірте, чи прив'язує сервер одну конкретну локальну адресу, бо прив'язаний слухач завжди відповідає з цієї адреси. Це правильно для розгортання з одним інтерфейсом і неправильно, щойно клієнти законно використовують більше ніж одну адресу. Якщо прив'язка була навмисною, вирішіть, чи має сервер узагалі приймати трафік на додаткових адресах. Видалення прив'язки збільшує експозицію, тому дозволені інтерфейси та мережі-джерела мають забезпечувати служба й фільтр, а не лише адреса прив'язки.
Довідник OpenVPN обмежує параметр UDP-серверами, відзначає додаткову обробку на шляху пакета і фіксує, які платформи його підтримують. Підтвердьте це на встановленій версії, перш ніж планувати з розрахунком на нього. Там, де він не підтримується, альтернативою є прив'язка конкретної адреси або виправлення зворотного маршруту, і обидва варіанти — вужчі зміни, ніж здаються на перший погляд. Прослуховування на загальній адресі має наслідки й поза відповідями: сервер на всіх адресах доступний з кожної мережі, до якої підключений хост, і це, можливо, не та експозиція, яку хтось мав на думці.
Доведіть джерело відповіді ззовні
Перевіряйте ззовні сервера і запишіть точну адресу й транспорт, які використав клієнт, перш ніж щось перехоплювати. Три перевірки нижче відповідають на три різні питання, і порядок має значення.
tcpdump -ni any udp port 1194
ss -lunp 'sport = :1194'
ip route get 203.0.113.10 from 198.51.100.20
Запис показує адресу джерела у відповіді, і на цьому факті тримається вся стаття. Список сокетів показує, до чого сервер справді прив'язаний, бо загальний і конкретний слухачі виглядають однаково у файлі конфігурації та поводяться по-різному в мережі. Пошук маршруту показує джерело, яке ядро вибрало б для цього потоку, і це пояснює запис до того, як ви щось зміните. Повторіть усі три для IPv4 і IPv6 окремо, бо це окремі слухачі й окремі пошуки, а запис для загальної адреси однієї родини нічого не говорить про іншу.
Маршрутизація, виявлення та фільтрація залишаються окремими
Збереження джерела відповіді не встановлює вихідний маршрут, не оновлює динамічний DNS і не змушує одну родину адрес приймати іншу. На сервері з кількома висхідними каналами зворотний шлях для кожного джерела потрібно узгодити навмисно, інакше відповіді виходять через інтерфейс, якого фільтр клієнта ніколи не дозволяв. Так само нова адреса після зміни префікса має доходити до клієнтів через виявлення та підтримуваний потік перепідключення, а не через старий запис.
Залиште перевірки автентичності сервера й перевірку сертифікатів рівно такими, якими вони є, бо змінена адреса не виправдовує приймання неперевіреного партнера. Якщо відповідь тепер виходить із потрібного джерела, а тунель усе одно не працює, вважайте проблему джерела вирішеною і йдіть далі. Наступна помічена помилка належить маршрутизації, фільтрації або автентифікації, і чергова зміна слухача до неї не дістанеться. Запишіть джерело відповіді в тікет поруч з адресою, до якої звертався клієнт, щоб наступна людина могла перевірити той самий факт однією командою.