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

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

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

Неправильна форма виглядає як поганий код. Вставте свіжий код у поле лише для пароля, і сервер прочитає його як частину пароля. На боці клієнта OpenVPN 2.4 і новіші роблять різницю видимою: сервер, що відповідає AUTH_FAILED,CRV1:, очікує відповіді на виклик, тому профілю потрібен static-challenge або файл пароля у формі SCRV1:. Старіший профіль лише з auth-user-pass перевіряє пароль і потім зупиняється, що в журналі виглядає як збій OTP, хоча код не надсилався.

WireGuard варто назвати винятком: він автентифікує пари ключів, а не людей, тому поля для коду немає. Якщо провайдер рекламує такий код, його приймає щось за межами тунелю.

Що сервер робить із шістьма цифрами

Коди на основі часу дотримуються RFC 6238, який обгортає старішу конструкцію з лічильником із RFC 4226: HMAC над рухомим фактором, за замовчуванням усічений до шести цифр. Для TOTP рухомий фактор — поточний час Unix, поділений на крок, 30 секунд, якщо оператор його не змінював. Перевіряч ніколи не порівнює ваші цифри зі збереженим значенням; він перераховує очікуваний код із спільного насіння і зазвичай приймає також сусідні кроки, тож повільний обмін не зриває вхід.

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

Токени на основі лічильника зсувають лічильник при кожному натисканні, тому виходять із синхронізації після того, як коди згенеровано, але так і не надіслано; звичайне виправлення — вікно ресинхронізації, що приймає кілька значень уперед. Якщо оператор зареєстрував HOTP, а ваш застосунок показує TOTP, кожне значення хибне так, що це схоже на проблему з годинником. URI підготовки за QR-кодом називає тип, цифри, період і хеш.

Збої, що виглядають як хибний код

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

Друге — невідповідний набір параметрів. Насіння, зареєстроване з вісьмома цифрами, періодом 60 секунд або SHA-256, дає коди, які перевіряч, що очікує шість цифр, 30 секунд і SHA-1, відхиляє, а на клієнті це не відрізнити від хибного коду. Це з'являється після міграцій, коли запис додавали заново з фотографії QR-коду або коли запис токена перебудовували зі значеннями за замовчуванням.

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

Коротка послідовність, що це звужує

Почніть із найдешевшої перевірки й зупиніться на першому кроці, що не виконується.

  1. Дочекайтеся свіжого коду, надішліть його один раз і занотуйте, чи виклик з'являється до чи після прийняття пароля.
  2. Зіставте мітку в автентифікаторі з іменем користувача, яке зберігає сервер.
  3. Переконайтеся, що профіль узагалі може відповісти на виклик, як у випадку CRV1 вище.
  4. Порівняйте годинник пристрою з відомим джерелом часу; відхилення більш ніж на кілька десятків секунд саме ламає TOTP.
  5. Запитайте оператора, TOTP це чи HOTP і які цифри, період та хеш було зареєстровано.

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

Тримайте насіння й коди відновлення поза циклом

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

Код також не робить сторінку входу гідною довіри: запит OTP на схожому домені збирає дійсний код і повторює його в межах вікна, а сертифікат і досі каже, куди ви вводите.

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

Схожі статті