За последние пару недель я встретил огромное количество статей с заголовками "Поднимаем свой 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 гораздо шире, а следовательно, есть где разгуляться!

Комментарии (17)


  1. BDI
    03.04.2022 15:50
    +2

    Когда сам озадачивался учётом трафика(у меня был вариант когда было ограничение на месячный объём), мне хватило возможностей vnstat с указанием vpn интерфейса.

    Автоматизацией на основании собранных данных не занимался, но с ключом --xml или --json
    vnstat выдаёт вполне «машиночитаемый» результат, который можно использовать в своих нуждах.


    1. siailya Автор
      04.04.2022 15:11

      Если правильно понял, получится получить только общий трафик интерфейса OpenVPN? То есть анализ по каждому клиенту отдельно не провести?


      1. BDI
        04.04.2022 15:31
        +1

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


  1. Barnaby
    03.04.2022 16:09
    +2

    В Outline можно выставить лимит на 30 дней. Зачем брать vps с таким странным ограничением?


    1. siailya Автор
      04.04.2022 15:48

      Сам впервые столкнулся с таким ограничением и сперва, когда проверил скорость через speedtest-cli, подумал, что оно вовсе не работает (тест показал 500/120 Мбит на загрузку и отправку соответственно). Только ТП и разъяснила механизм работы. Но по сути из этого родилась идея сделать то, что я сделал, так что только рад этому странному ограничению :)


  1. aborouhin
    03.04.2022 16:18
    +2

    OpenVPN мониторить - это, конечно, дело нужное, но на той же самой VPS надо бы мониторить заодно загрузку CPU / памяти / место на диске (самая мерзкая засада, по моему опыту, когда какой-то ранее неведомый лог решает разрастись на весь диск...) / SSH сессии и т.п. Ну и мониторить это логично из одного места. Посему - zabbix (ну или что-то аналогичное на вкус), веб-интерфейс и алерты куда надо в комплекте, - ну а решений, как openvpn к нему прикрутить, хватает готовых.


  1. Harwest
    03.04.2022 18:19
    +1

    «прикупил один из самых дешевых VPS с заграничным IP и минимальными характеристиками»
    Прикупил vps в ЦОДе РТ в городе Н-ске: очень удивился когда через VPN этого vps заработал LinkedIn, Insta, и простигосподи PornHub o_O


    1. aborouhin
      03.04.2022 19:20

      Лотерея. На VPS от reg.ru длительное время никакие блокировки не действовали, потом в один прекрасный момент без предупреждения поменялся аплинк (то ли с РТ на ТТК, то ли наоборот, уже не помню) - и всё оказалось зарезано.


  1. NikaLapka
    03.04.2022 19:02
    +5

    развернуть все можно буквально в пару строчек).

    curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
    chmod +x openvpn-install.sh

    Здесь Паша Эмильевич, обладавший сверхъестественным чутьем, понял, что сейчас его будут бить, может быть, даже ногами. (с)

    Пример правильных пары строчек для первоначальной настройки(debian 11.3) openvpn: apt install openvpn && cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server

    Для параноиков, перфекционистов, выпускников Академии Звёздного Флота и т.п. единственно верный путь: https://openvpn.net/community-resources/creating-configuration-files-for-server-and-clients/


  1. ogost
    04.04.2022 06:08

    А почему не wireguard? Мне он показался проще в настройке, и оверхед небольшой.


    1. Tarakanator
      04.04.2022 13:53

      Когда я выбирал.
      wireguard-прошивка моего роутера не умела.
      openvpn-можно конечно, но он не особо шустрый. и вопрос маршрутов.
      zerotier-тогда я про него не знал, но в плюс запишу лёгкую смен VPN сервера. минусы не знаю т.к. не пробовал. В первую очередь вопрос маршрутов
      ipsec+gre мой выбор. Можно выбрать только нужные маршруты, есть доступ по сертификатам. Недостатки: если хочется накрутить побольше безопасности, то родной виндовый и андроидовский клиенты работать не будут (виндовый вроде как можно пролечить, но я не смог, и он сертификаты ставит на комп, а не на пользователя)


    1. siailya Автор
      04.04.2022 15:30

      До него просто-напросто не успел докопаться в поисках решения, разум затуманил OpenVPN
      Сейчас мельком посмотрел на wireguard, в некоторых моментах он мне тоже показался проще (например та же статистика, которую я собираю через management-interface достается просто просто командой wg), так что попробую и его пощупать на досуге


  1. newyorkin
    04.04.2022 06:54

    Коли уж у нас есть Докер, вот так можно было развернуть и сам OpenVPN, в пару строчек без установки его на хостовую машину:

    https://github.com/kylemanna/docker-openvpn

    https://github.com/kylemanna/docker-openvpn/blob/master/docs/docker-compose.md


    1. siailya Автор
      04.04.2022 14:59

      Об этом, честно говоря, у меня даже мыслей не было - видимо недостаточно "контейнерное" мышление :)
      В идеале, наверное, нужно абсолютно всё упаковать в контейнеры (в т.ч. БД) и поднимать одним docker-compose up

      Спасибо за наводку, обязательно попробую!


    1. nuBacuk
      04.04.2022 18:54
      +1

      Только не обновляется он, сделал форк и сделал сборку для arm и мелочи поправил https://github.com/nuBacuk/docker-openvpn-arm64.


  1. Rebeiro1976
    04.04.2022 08:45
    -1

    6 лет vps в Германии, скорость по тарифу опсоса, пинг конечно больше, ну это не критично, я в игры не играю, тут купил vps в России, попробовать, это ппц, ничему меня жизнь не учит, вся парнуха забанена, зато кавказцентр открывается))) это как? я обычно впн проверяю, кавказ врубаю, если открылся значит норм, а тут коллизия какая то, деньги хоть вернули, пару лет назад, тоже покупал vps не помню у кого, написано было безлимит и скорость 100 мегабит, в результате было 10 мегабит, написал в поддержку, мне ответили типа, за каждые еще 10 мегабит надо 100 р доплачивать))) пять баллов))) извините я не совсем трезв, душа поет


  1. Amihailov
    04.04.2022 09:50
    +1

    Ищущим могу посоветовать вот такой комбайн VPN-сервера (wireguard, web-интерфейс, статистика, pihole, firewall и прочее) от ИБшника энтузиаста https://gitlab.com/cyber5k/mistborn