VPN обірвався посеред сторінки: чи ще виходять фонові запити?
Залишена відкритою сторінка продовжує опитувати, перепідключатися й синхронізуватися після смерті тунелю. Подивіться, які спроби ще виходять і як це довести.
Вкладка досі показує панель керування з часів, коли тунель був живий. Цифри стану завмирають, маленький індикатор продовжує крутитися, а в адресному рядку досі те застосунок, який ви відкрили годину тому. Після обриву ви нічого не торкалися, і все ж сторінка, можливо, досі намагається дістатися до свого сервера за власним розкладом. Саме це люди проґавлять: сторінка, яка лише видима, і сторінка, яка ще надсилає запити, зовні виглядають однаково, і лише одна з них потрапляє до мережевого журналу.
Робота, яку сторінка починає без вас
Чотири механізми тримають завантажений документ зайнятим. Повторюваний таймер може знову запускати виклик стану кожні кілька секунд. Fetch може спрацювати, коли вкладка знову стає видимою після повернення до неї. Живий канал на основі WebSocket або подій, які надсилає сервер, може намагатися перепідключитися за власним графіком відступу. Service worker, зареєстрований сайтом, може прокинутися для синхронізації в черзі навіть тоді, коли перед вами немає жодної вкладки.
Жоден із них не потребує кліку, і жоден не перезавантажує документ. Адресний рядок, позиція прокрутки та відображені значення залишаються на місці. Змінюється лише мережевий бік: кожна нова спроба — це свіже рішення, ухвалене в момент її початку.
Ця різниця важлива, бо видима сторінка зберігається локально. Уже намальовані пікселі нічого не говорять про те, чи вдався наступний запит. Заморожений графік з індикатором — звичний вигляд сторінки, чиї запити тепер зазнають невдачі. Читання екрана каже вам, що сервер сказав кілька хвилин тому, а не що браузер робить зараз.
Чому попереднє завантаження сторінки не утримує маршрут
Ніщо в завантаженні сторінки не прив'язує документ до тунелю. Маршрутизація вирішується для кожного пакета в момент надсилання з таблиці, яка існує, коли пакет виходить. Коли інтерфейс тунелю зникає, цей пошук більше не відповідає маршруту тунелю. Він або провалюється на фізичний адаптер, або нічого не знаходить, залежно від того, що залишив клієнт.
Повторювані зворотні виклики — звичайні заплановані завдання. Розділ стандарту HTML про таймери описує, як їх ставлять у чергу, і трактує інтервал як мінімальну затримку, а не обіцянку точного ритму, тож фонова вкладка може опитувати значно рідше, ніж просить її код. Менше спроб — це не те саме, що жодної спроби, а повернення вкладки наперед — звичний момент для їхнього спалаху.
Куди приземляється політика відмови
Блокування клієнта оцінюється тоді, коли роблять спробу з'єднання, а не тоді, коли сторінку було отримано. Якщо звичайний доступ ще дозволено, повторна спроба може вийти через фізичний канал у відкритому вигляді. Якщо політика утримує цей трафік до повернення тунелю, спроба зазнає невдачі в момент підключення, і сторінка показує помилку, яку можна повторити за кілька секунд.
Дві деталі вирішують, що саме ви отримаєте. Перша — обсяг застосування, який підтримує клієнт: блокування всього пристрою, блокування лише адаптера тунелю або набір правил з винятками. Друга — чи потрапляє адресат у виняток, доданий раніше для локального принтера, полоненого порталу чи стрімінгового сервісу.
Шифрування на рівні застосунку нічого з цього не змінює. HTTPS захищає байти між браузером і сервером; він нічого не каже про те, який інтерфейс їх несе. Сторінка може бути ідеально зашифрованою і все одно виходити не тим шляхом, і саме це дозволяє вузьке блокування.
Контрольована перевірка на одноразовій сторінці
Візьміть хост, який ви контролюєте, і сторінку, яка не робить нічого, крім виклику до нього, щоб у грі не було реальних даних. З термінала зніміть зразок шляху до й після обриву:
curl -sS --max-time 5 -o /dev/null -w '%{http_code} %{remote_ip}\n' https://probe.example.net/pingЗапустіть це з піднятим тунелем, потім опустіть тунель і запустіть знову. Відповідь із публічної адреси при опущеному тунелі каже, що прямий шлях відкритий. Вичерпання часу або відмова в з'єднанні каже, що політика тримає. Повторіть ще раз після того, як клієнт перепідключиться, щоб побачити повернення шляху через тунель, а не припускати його.
У браузері панель «Мережа» розділяє ці два питання. Відфільтруйте за Fetch/XHR, потім прочитайте стовпець ініціатора: запис, запущений таймером або скриптом, без зафіксованого перед ним переходу, — це фонова спроба, а не перезавантаження. Порівняйте час її початку з моментом обриву тунелю. Якщо запис усе ще в очікуванні, коли тунель зник, запит чекає на шлях, якого більше немає.
Докази на боці сервера сильніші за все, що показує браузер. Журнал запитів із позначкою часу та адресою джерела доводить, що пакет прийшов. Записи браузера можуть нести cookie, токени й повні URL-адреси, тож залиште лише поля, потрібні вашому питанню, і приховайте решту, перш ніж кудись їх вставляти.
Що робити з відповіддю
Якщо фонові спроби продовжують вдаватися при опущеному тунелі, блокування вужче, ніж ви припускали, і цю щілину варто закрити, перш ніж довіряти клієнту чутливу роботу. Якщо вони зазнають невдачі, політика робить свою роботу, а заморожена сторінка — лише оформлення. Так чи інакше, закриття однієї вкладки не є контролем на рівні всього пристрою: інші вкладки, інші браузери й інші застосунки кожен планує свою роботу.
Кроки, які варто зробити: перелічте, які винятки ви додали і чому, підтвердьте, чи клієнт блокує лише трафік в обсязі тунелю, чи весь трафік, і простежте один фоновий запит від початку до кінця з відкритим журналом сервера. Ці три відповіді охоплюють більшість того, що насправді містить звіт «VPN обірвався, а щось досі підключене».