Як виміряти час роботи клієнта OpenVPN за допомогою хуків up і down
У OpenVPN немає лічильника часу роботи. Збережіть мітку epoch з хука up, видаліть її при down, відніміть і тримайте точною між перезапусками та примірниками.
Панель запитує число, скільки часу з'єднання активне, а OpenVPN його не надає. Клієнт знає, коли піднявся його тунель, але лише якщо щось зафіксує цей момент до втрати стану сеансу. Підтримуване місце — хук up, а значення, яке варто зберігати, — сира секунда epoch, а не форматований рядок. Усе далі — арифметика, плюс кілька правил порядку, які вирішують, чи залишиться число чесним.
Переконайтеся, що хуки справді виконуються
Доведіть, що хук спрацьовує, перш ніж щось довкола нього проєктувати. Мінімальна конфігурація клієнта потребує script-security 2 і явних шляхів up та down; без рядка безпеки OpenVPN відмовляється виконувати скрипт і прямо про це говорить. Додайте up-restart і down-pre одночасно, щоб шляхи перезапуску й розбирання поводилися передбачувано.
Зробіть першу версію хука такою, щоб вона дописувала своє середовище у файл і більше нічого не робила. Так ви побачите назви змінних, які ваша збірка справді експортує, наприклад dev і script_type, замість тих, що пам'ятаєте з іншої версії. Виконайте одне з'єднання й одне від'єднання, потім прочитайте файл. Якщо нічого не з'явилося, зупиніться тут, бо схема з міткою часу поверх хука, який ніколи не запускається, тижнями виглядатиме як збій моніторингу.
Перевірте, від імені якого користувача працює хук. Коли задано user і group, OpenVPN скидає привілеї перед запуском скриптів, тож каталог, у який root може писати, може бути закритий для хука. Обирайте шлях з погляду служби, а не вашої оболонки.
Запишіть одне значення epoch і зітріть його навмисно
Хуку up потрібен один рядок, date +%s > /run/openvpn-client.started, зі шляхом, підправленим під кожен примірник. Значення epoch уникає згодом питань мови, часового поясу й формату, і це те саме число, яке агент моніторингу може порівняти зі своїм годинником.
Стирання так само важливе, як запис. Хук down має спорожнити або видалити файл, а down-pre робить це до закриття інтерфейсу, що прибирає вікно, у якому файл описує вже зниклий тунель. up-restart потім оновлює мітку під час внутрішнього перезапуску замість того, щоб залишити початкове значення на місці. Без цієї пари перезапуск після вичерпання ping дає число, яке продовжує зростати, поки тунель відновлюється.
Оберіть місце з правильним строком життя. Файл під /run зникає під час перезавантаження, що відповідає реальності, тоді як файл під /tmp може бути непередбачувано очищений, а файл у каталозі конфігурації виживає в оманливий спосіб. Налаштуйте права так, щоб читати його могли лише користувач служби й читач моніторингу.
Обчислюйте час роботи, не довіряючи рядкам журналу
Прочитайте збережену секунду, прочитайте поточну секунду, відніміть. Коли файла немає або він порожній, чесна відповідь — активного тунелю немає, а не те, що час роботи дорівнює нулю, бо ці два стани мають піднімати різні оповіщення. Тримайте сирі секунди в даних моніторингу, а дні й години форматуйте на рівні відображення. Форматувальник, який округлює всередині експортера, викидає точність, яка комусь знадобиться під час інциденту.
Розбір часових міток із журналу — спокусливий короткий шлях, і він провалюється трьома способами: формат залежить від заданих опцій, ротація видаляє історію, а перепідключення виглядають як окремі сеанси, а не один безперервний тунель. Хук записує подію один раз, у момент, коли вона відбувається.
Коли перевірка виконується на іншому хості, передавайте мітку часу, а не тривалість, щоб читач застосував свій годинник. Тоді невеликий негативний результат читається як розбіжність годинників, а не як зламаний хук.
Покрийте перепідключення, перезапуски й кілька примірників
Два тунелі на одному хості потребують двох файлів із ключем за назвою примірника, яку служба вже використовує. Спільний шлях означає, що найсвіжіше з'єднання перезаписує час старту кожного профілю, а симптом — число, яке стрибає назад, коли запускається другий тунель.
Поведінка під час перепідключення заслуговує окремого тесту, бо саме там правдоподібна схема тихо повідомляє неправильне. Спровокуйте перезапуск, скинувши партнера або надіславши сигнал процесу, потім порівняйте стан інтерфейсу з файлом. Мітка часу має зсунутися вперед у момент повернення тунелю.
На боці сервера файл стану несе значення connected-since для кожного клієнта, яке відповідає на інше питання: коли сервер востаннє бачив цього партнера. Використовуйте його для перехресної перевірки, а не як заміну, оскільки він зникає разом із сеансом, який описує. Жодне з вимірювань нічого не каже про здоров'я застосунку за тунелем.
Виконайте три перевірки, які ловлять помилки порядку
Перевірте звичайне з'єднання, примусове перепідключення й чисту зупинку, читаючи список інтерфейсів і файл разом після кожного. Мітка, яка залишилася після чистої зупинки, або файл, що стверджує тунель, якого немає в списку інтерфейсів, указує прямо на порядок хуків. Виконуйте перевірки від імені користувача служби й зі шляхами служби, бо оболонка root може бачити інший файл і дати впевнену неправильну відповідь. Потім залиште повільний опитувач читати файл і підтвердіть, що він ніколи до нього не пише.
Опитування що шістдесят секунд покриває оповіщення, і жоден хук не повинен розраховувати на те, що цей опитувач живий. Тримайте ці дві відповідальності окремо, і число залишиться надійним, коли будь-яку зі сторін розгорнуть заново.