VPN-плагины
Данная статья описывает процесс реализации поддержки VPN-плагинов для ConnMan в ОС Аврора. Руководство описывает только часть действий, которые необходимо выполнить для реализации VPN-расширения в ОС Аврора.
- Предварительные требования
- Примеры программного кода
- Установка VPN-соединения в ОС Аврора
- Остановка работы VPN-клиента
- Расположение файлов VPN-плагина
- Разработка VPN-плагина
- Настройка VPN-плагина
- Разработка скрипта
- Сборка плагина
Предварительные требования
Для разработки VPN-плагина для ОС Аврора необходимы указанные ниже компоненты:
- ConnMan версии 1.32+git21 или выше;
- библиотеки:
- connman-devel (версии 1.32+git21 или выше);
- glib-2.0;
- dbus-1.
Нужные версии компонентов поставляются в ОС Аврора целевых версий.
Основной задачей VPN-плагина является корректный запуск исполняемого файла VPN-клиента, который должен быть поставлен вместе с VPN-плагином.
Примеры программного кода
Данное руководство использует репозиторий проекта TrifleVpn в качестве базы для описания структуры VPN-плагина и средств управления им через графический интерфейс.
Также полезными для понимания деталей работы VPN-плагинов представляются следующие репозитории:
- Репозиторий с описанием ключевых методов VPN-плагина
- Пример VPN-плагина с реализацией ProtoVPN, основанный на базе OpenVPN
Установка VPN-соединения в ОС Аврора
В общем случае последовательность операций в ОС при установке VPN-соединения следующая:
- Пользователь активирует VPN-соединение в настройках.
- Приложение «Настройки» посылает D-Bus-сигнал connman-vpnd на активацию соответствующего подключения.
- ConnMan активирует VPN-плагин, вызывая метод инициализации плагина.
- ConnMan вызывает метод VPN-плагина для инициализации VPN-соединения. Данному методу передаются параметры подключения, которые необходимо установить.
- VPN-плагин разбирает параметры и формирует задачу (ConnMan Task) на запуск VPN-клиента.
- ConnMan запускает VPN-клиент согласно сформированной задаче.
- VPN-клиент выполняет задачу по установлению соединения и запускает скрипт ConnMan, который оповещает ConnMan об удачном установлении соединения.
- Данное оповещение передаётся в VPN-плагин, который преобразует его в данные конфигурации сети для ConnMan.
Во время инициализации подключения VPN-плагин может запросить дополнительные данные от пользователя, например одноразовый пароль.
Остановка работы VPN-клиента
Остановка работы VPN-клиента происходит в следующих случаях:
- отключение VPN-соединений пользователем через пользовательский интерфейс;
- ошибка в соединении;
- отключение транспортного сервиса;
- изменение транспортного сервиса по умолчанию и т. д.
Процесс завершения работы VPN-клиента выполняется с помощью сигналов и выглядит следующим образом:
- Процессу посылается сигнал SIGTERM в момент времени t;
- Если приложение не завершило работу, то посылается сигнал SIGINT через две секунды (t + 2s);
- Если приложение не завершило работу, то посылается сигнал SIGKILL через три секунды (t + 3s), и работа процесса прерывается.
Для управляемого выключения рекомендуется перехватывать сигналы SIGTERM и SIGINT. Обработка данных сигналов позволит корректно завершить работу процесса.
Подробное описание сигналов завершения приведено в статье Termination Signals.
Расположение файлов VPN-плагина
Директория /usr/lib/connman предназначена для подключаемых модулей ConnMan и плагинов и должна использоваться исключительно для установки плагина и скриптов плагина.
Временные файлы, сокеты и другие артефакты среды выполнения VPN-клиента должны быть расположены в
директории $XDG_RUNTIME_DIR
,
которая определена в соответствии со спецификацией
XDG Base Directory Specificaiton.
Настройка параметров пользователей и групп ConnMan VPN
По умолчанию конфигурационный файл VPN-плагина загружается из /etc/connman/connman-vpn.conf. Поиск конфигурационного файла для конкретного плагина производится в /etc/connman/vpn-plugin/plugin_name.conf.
Наименование конфигурационного файла плагина должно совпадать с наименованием плагина,
которое используется в качестве параметра в функции
vpn_register()
.
Например, плагин TrifleVpn
должен иметь конфигурационный файл
/etc/connman/vpn-plugin/triflevpn.conf.
Параметры VPN-клиента, которые должны быть в конфигурационном файла плагина, добавляются в секцию [VPNBinary].
Поддерживаются следующие параметры:
User
— пользователь, от имени которого происходит запуск VPN-клиента.Group
— группа, которая используется для запуска VPN-клиента.
Для каждого параметра доступны как числовые, так и текстовые значения.
Обработка конфигурации происходит в следующем порядке:
-
Если конфигурационный файл по умолчанию существует, а конфигурационный файл плагина отсутствует, то используется конфигурационный файл по умолчанию.
-
Если конфигурационный файл по умолчанию пуст или отсутствует, то изменения при выполнении VPN-клиента не вносятся, и запуск производится от имени того же пользователя и группы, что и запуск connman-vpnd. Аналогично, при отсутствии параметра в запуске бинарного файла не будет никаких изменений.
-
Если конфигурационный файл по умолчанию отсутствует, но существует конфигурационный файл плагина, то используется конфигурационный файл плагина. Если некоторые параметры конфигурационного файла плагина пусты, то при запуске VPN-клиента значения для этих параметров не изменяются.
Например, при незаданном значении параметра
User
запуск VPN-клиента будет производиться из-под того же пользователя, что и запуск conman-vpnd. -
Если конфигурационный файл по умолчанию и конфигурационный файл плагина с отсутствующими или пустыми параметрами существуют, то используются значения, установленные в конфигурационном файле по умолчанию.
Например, при установленном «User=» в файле конфигурации значение User будет взято из конфигурации по умолчанию.
Настройка свойств VPN-подключения
Свойства VPN-подключения должны настраиваться с помощью приложения «Настройки». Для поддержки собственного VPN-плагина необходимо разработать соответствующее расширение. Детали разработки данного расширения приведены в руководстве по разработке пользовательского интерфейса VPN-подключений.
Все параметры, которые определяет расширение для приложения «Настройки» в рамках VPN-профиля будут переданы VPN-плагину.
Разработка VPN-плагина
Заголовочные файлы
Для сборки VPN-плагина необходимо наличие следующих заголовочных файлов в системе сборки:
- dbus/dbus.h — использование D-Bus;
- linux/if_tun.h — заголовочный файл для TUN/TAP-драйвера ОС Linux;
- connman/plugin.h — загрузка ConnMan-плагина;
- connman/task.h — исполнение бинарных файлов, реализующих функциональность VPN;
- connman/vpn/plugins/vpn.h — заголовочный файл разработки плагина, включающий vpn-provider.h;
- connman/vpn/vpn-agent.h — заголовочный файл агента плагина.
Данные заголовочные файлы необходимо подключить в исходном файле плагина.
Например:
plugin/triflevpn_plugin.c
.
Настройка VPN-плагина
Все плагины ConnMan регистрируются с помощью макроса
CONNMAN_PLUGIN_DEFINE
,
который выполняется при загрузке плагина из директории плагинов VPN.
Функция загрузки плагина init()
, определённая в макросе,
выполняет инициализацию плагина.
Она должна содержать по крайней мере вызов функций
vpn_register()
для регистрации в качестве VPN-плагина и
connman_dbus_get_connection()
для получения средства для взаимодействия по протоколу D-Bus с агентами ConnMan.
Функция удаления плагина
Функция exit
, определённая в макросе
CONNMAN_PLUGIN_DEFINE
,
предназначена для удаления плагина.
Она должна содержать по крайней мере вызовы:
vpn_unregister(name)
, гдеname
— наименование плагина,dbus_connection_unref(connection)
— для удаления ссылки на установленное D-Bus-соединение с ConnMan.
Установление VPN-соединения
Функция connect()
подготавливает
VPN-соединение и осуществляет доступ к необходимым параметрам, которые содержатся в структуре
vpn_provider
,
в которой описаны параметры для подключения.
Если какой-либо аргумент отсутствует или не может быть записан в конфигурацию
(например, password
), необходимо использовать D-Bus для запроса данного аргумента от пользователя.
Например:
- OpenVPN использует интерфейс управления для получения аргументов
password
,username
и подключения других возможностей управления (подробнее вconnman/vpn/plugins/openvpn.c
). - Openconnect использует интерфейс VPN-агента ConnMan для получения данных файлов.
Подробнее в
connman/vpn/plugins/openvpn.c
:request_cookie_input()
.request_cookie_input()
— функция для получения cookie.
В общем случае, для получения вводимых пользователем данных следует использовать D-Bus.
Для этого можно использовать connman vpn agent
.
Подробное описание методов, полей и аргументов приведено в файле
connman/doc/vpn-agent-api.txt
.
Для работы с агентом можно воспользоваться методами VPN-агента и
функций поддержки работы с D-Bus.
Для исполнения бинарного файла используется функция
connman_task_run()
.
Запуск бинарного файла происходит, когда необходимо установить VPN-соединение.
Для обработки возникающих ошибок необходимо реализовать функцию обратного вызова
или использовать функцию vpn_died
.
Разработка скрипта
- Принять сообщения D-Bus от запущенного приложения через функцию обратного вызова
.notify
. - Проверить нет ли проблем с получением сообщения и вызовом функции.
- Передать сетевые параметры: адрес TUN-интерфейса, DNS сервера в виртуальной сети и т. д. Сетевые параметры упаковываются в DBusMessage в виде словаря и передаются в ConnMan Task, в присланные при запуске VPN-клиента D-Bus-параметры.
Скрипт запускается VPN-клиентом по завершении установления соединения. Можно либо воспользоваться существующим скриптом, либо разработать свой собственный.
Для разработки скрипта необходимо выполнить следующее:
-
Создать простой исполняемый файл (см.
connman/scripts/openvpn-script.c
). -
Получить необходимые переменные окружения ConnMan:
getenv("CONNMAN_BUSNAME")
,getenv("CONNMAN_INTERFACE")
,getenv("CONNMAN_PATH")
.
Для работы с плагином необходимые поля также передаются через переменные окружения (для их получения можно использовать
getenv()
). Также они могут быть заданы в качестве входных параметров скрипта. -
Создать D-Bus-сообщение, используя стандартные функции
dbus_message_*
с нужным содержимым плагина, которое будет обработано функцией.notify
. Функция.notify
определена в структуреvpn_driver
. -
Отправить сообщение в ConnMan через D-Bus.
Сборка скрипта
Название скрипта должно заканчиваться на «-script
», например, openvpn-script
.
При сборке должны использоваться следующие флаги:
- CFLAGS:
pkg-config --cflags dbus-1
; - LDFLAGS:
pkg-config --libs dbus-1
.
Рекомендуемый путь для установки: %{_libdir}/connman/scripts.
Установка скрипта
Все скрипты должны быть установлены в %{_libdir}/connman/scripts.
В spec-файл должно быть включено следующее:
%install
mkdir -p %{buildroot}/%{_libdir}/connman/script
%files
%{_libdir}/connman/scripts/*-script
Сборка плагина
VPN-плагин реализуется в виде динамической библиотеки и имеет расширение *.so
.
При сборке должны использоваться следующие флаги:
- CFLAGS:
pkg-config --cflags glib-2.0 dbus-1
; - LDFLAGS:
pkg-config --libs glib-2.0 dbus-1 -shared
.
Рекомендуемый путь для установки библиотеки: %{_libdir}/connman/plugins-vpn.
Пример файла сборки плагина представлен в репозиториях с примерами. Сборка может быть осуществлена как с помощью make, так и с помощью системы сборки qmake.
Упаковка плагина в RPM-пакет
Ниже приведены требования по упаковке плагина и его компонентов в RPM-пакет для распространения.
Все плагины должны быть установлены в директорию %{_libdir}/connman/plugins-vpn.
В spec-файл должно быть включено следующее:
%install
mkdir -p %{buildroot}/%{_libdir}/connman/plugins-vpn
%files
%{_libdir}/connman/plugins-vpn/*.so
Если с пакетом бинарного файла распространяется конфигурационный файл плагина, то следует добавить следующие строки в spec-файл:
%install
mkdir -p %{buildroot}%{_sysconfdir}/connman/vpn-plugin
cp -a path/to/plugin/config_file.conf %{buildroot}%{_sysconfdir}/connman/vpn-plugin
%files
%config %{_sysconfdir}/connman/vpn-plugin/*.conf
Пример общей структуры spec-файла плагина приведен в репозиториях с примерами.