Следим за своей статистикой OpenVPN

в 11:00, , рубрики: openvpn, vpn, Сетевые технологии, системное администрирование

За последние пару недель я встретил огромное количество статей с заголовками "Поднимаем свой VPN" или "Настройка OpenVPN в N шагов". На этой волне я тоже решил попробовать сделать VPN для себя и близких - лишним такой опыт (да и сам VPN) точно не будет. Для этого я прикупил один из самых дешевых VPS с заграничным IP и минимальными характеристиками. Такое удовольствие мне обошлось в ~250р за месяц.

Саму приватную сеть было решено развернуть посредством OpenVPN. На тот момент я не слышал ничего про другие сервисы, а инструкций по настройке OpenVPN было более чем предостаточно (как узнал позже, развернуть все можно буквально в пару строчек).

Уже после пары часов возни с конфигами и сертификатами и полной настройки VPN, в панели управления сервером я обнаружил, что максимальная скорость канала - 10Мбит/с (это было написано ещё на странице заказа, но я проглядел этот момент). В техподдержке пояснили, что это ограничение становится активным при превышении скорости трафика в 10Мбит/с за час (значит, что нужно прогнать примерно 4,5Гб за это время). Получилось неловко, конечно, но я не планировал использовать VPN даже в таком объеме. Тем не менее, мне стала интересна задача мониторинга трафика и возможность предупредить себя, если вдруг скорость трафика через VPN приблизится к пороговому значению.

Что уже есть

Первым делом я попытался найти готовые решения для мониторинга OpenVPN, все-таки это довольно популярная реализация, вокруг которой должно быть большое сообщество.

Я выделил для себя 2 решения:

  • OpenVPN-Admin - целый комбайн, который служит не только для мониторинга, но и для управления сертификатами и самим сервером OpenVPN

  • OpenVPN-Monitor - просто live-time мониторинг с географической картой, на которой отображаются подключенные клиенты

Первое решение в моем случае было бы чересчур избыточно, мне никогда не пригодилось бы 80% функционала. Во втором же случае оказалось, что мониторинг ведется только на текущий момент, при этом статистика не собирается - нет возможности посмотреть, сколько клиент загрузил/выгрузил за последний час, а именно ради этого я искал решение.

Помимо двух этих вариантов мне не удалось найти ничего, что отвечало бы моим требованиями или что я сумел бы переделать под свои нужды.

Формулировка задачи

Так что я решил за пару выходных набросать свое решение и заодно попрактиковаться в некоторых вещах. Что конкретно я хотел:

  • Собирать статистику использования VPN по каждому пользователю

  • Отслеживать общее потребление трафика

  • Предупреждать, если трафик за последний час переваливает за 8-9Мбит/с

  • А ещё смотреть за всем этим делом в веб-интерфейсе (в эстетических целях) и попробовать запаковать все в Docker (в образовательных целях)

Парсим, парсим, парсим

Чтобы анализировать статистику, нужно сначала собрать статистику. OpenVPN предоставляет довольно удобный интерфейс для получения статистики об использовании трафика. В конфигурации сервера по умолчанию уже включена соответствующая директива:

status openvpn-status.log

Она позволяет указать файл, в который будет записываться статистика об использовании трафика подключенными клиентами. После имени файла можно дополнительно указать число - интервал в секундах, через который файл будет автоматически обновляться (по умолчанию это 60 секунд).

Для комплексного подхода и, по-моему, более гуманного, чем парсинг файла, можно использовать management-server, для этого в конфиге нужно указать следующую директиву:

management localhost 7505

Дополнительно можно указать пароль для подключения к интерфейсу (подробнее).

После этого появится возможность подключиться к серверу OpenVPN посредством telnet:

Интерфейс управления OpenVPN
Интерфейс управления OpenVPN

Собираем статистику

OpenVPN любезно отдает статистику в настоящем времени, но, увы, не собирает и не хранит её. Можно получить только подключенных клиентов и количество их трафика за последнюю сессию, так что ответственность за сбор придется взять на себя.

Для сбора статистики я выбрал вариант с использованием management-interface и для этого написал небольшой скрипт на Python. Раз в N секунд он обращается к интерфейсу управления, запрашивает статус и создает/обновляет записи в MongoDB для каждого пользователя:

Схема хранения данных
Схема хранения данных
Можно лучше

Уже при написании статьи я заметил некоторые свои ошибки. Да, хранить данные можно было гораздо оптимальнее и обойтись всего одной коллекцией - только segments. По ней можно провести весь анализ, практически не добавляя новых полей, а поля с разностью (d_received и d_send) можно вычислять динамически, если не планируется анализ слишком больших отрезков времени

Для получения общего потребления трафика за час достаточно просто выбрать все записи, время которых попадает в этот промежуток, и просуммировать трафик по ним (вернее, их разницы в трафике по сравнению с предыдущими записями). Для клиентов нужно то же самое, но с фильтрацией по имени.

Теперь статистика собирается, остается наращивать функционал! В моем случае нужно было только отображать её в вебе и выдавать предупреждения, если скорость трафика будет превышена!

Делаем удобно

Для отображения в вебе я сделал простое веб-приложение на Vue и API для него на Flask. Ничего необычного в нём нет - одна страничка, на которой отображается общая статистика и карточки для каждого из пользователей:

Так выглядит веб-интерфейс для мониторинга трафика
Так выглядит веб-интерфейс для мониторинга трафика
Упс, забыл округлить
Упс, забыл округлить

Веб-интерфейс - здорово, но как быть с уведомлением о превышении скорости трафика? Изначально у меня были мысли о том, чтобы отправлять уведомления прямо в браузер, но до них я так и не добрался, потому что в голову пришло другое решение - сделать бота в ТГ и слать сообщения из него!

Пакуем в Докер

В качестве практики я решил упаковать всё в Docker. Так как MongoDB у меня уже была развернута на другом сервере, её я не стал разворачивать и обошелся двумя Dockerfile - один для веба и один для парсера. Так как оба из микросервисов сделаны на Питоне, то и Dockerfile у них отличаются не сильно

# Dockerfile для веба
# Билдим фронтенд
FROM node:16.14-alpine3.14 AS builder

WORKDIR /usr/app/client
COPY ./client /usr/app/client

RUN npm i
RUN npm run build

# Собираем фронтенд и сервер
FROM python:3.10.4-alpine3.14

COPY app.py app.py
COPY requirements.txt requirements.txt
COPY --from=builder /usr/app/client/dist /client/dist

RUN pip install -r requirements.txt

EXPOSE 5000

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0" ]
# Dockerfile для парсера
FROM python:3.8.13-buster

COPY main.py main.py
COPY OVPNInterface.py OVPNInterface.py
COPY requirements.txt requirements.txt


RUN pip install -r requirements.txt

EXPOSE 5555

CMD [ "python3", "-m", "main" ]

В заключение

Спасибо, что прочитали! В этой статье я хотел просто поделиться опытом в сборе статистики трафика и "интеграции" OpenVPN в реальную жизнь. Вряд ли конкретно мое решение может быть использовано кем-то ещё, но возможности того же management-interface гораздо шире, а следовательно, есть где разгуляться!

Автор:
siailya

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js