Аутентификация и авторизация пользователей в Apache AirFlow

администрирование Apache AirFlow, безопасность Apache AirFlow, аутентификация и авторизация пользователей Apache AirFlow, управление пользователями Apache AirFlow, обучение Apache AirFlow, курсы по AirFlow, обучение дата-инженеров, инженерия данных примеры курсы обучение, Школа Больших Данных Учебный Центр Коммерсант

Зачем ограничивать доступ к папке с DAG и как это сделать: категории и роли пользователей в Apache AirFlow, способы входа в систему и конфигурации для настройки прав.

Категории и роли пользователей Apache AirFlow

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

  • менеджер развертывания – администратор, который отвечает за установку, безопасность и настройку фреймворка, включая смену бэкенда, о чем мы рассказываем в новой статье;
  • аутентифицированный пользователь — пользователь интерфейсов, который имеет доступ к веб-GUI и API, а также может взаимодействовать с ними, отправляя соответствующие запросы;
  • автор DAG — дата-инженер, который разрабатывает DAG и отправляет его в AirFlow, помещая Python-файлы в DAGS_FOLDER. Код этих py-файлов не проверяется и выполняется в AirFlow без помещения в песочницу. Поэтому авторы DAG могут выполнять произвольный код на рабочих процессах, которые запускаются планировщиком (Celery Workers для Celery Executor, локальные процессы в случае Local Executor, Task Kubernetes POD при Kubernetes Executor), в файловом процессоре DAG, который может выполняться как автономный процесс или быть частью планировщика, и в Triggerer.

Менеджер развертывания может решить ввести дополнительные механизмы контроля, чтобы не допустить выполнения произвольного кода авторами DAG. Это важно, поскольку выполнение кода DAG происходит в среде, в зависимости от выбранного исполнителя:

  • если локальный исполнитель и файловый процессор DAG работают как часть планировщика, автор DAG может выполнять произвольный код на компьютере, на котором работает планировщик. Так можно повлиять на сам процесс планировщика и потенциально повлиять на всю установку AirFlow, включая изменение политик всего кластера и изменение конфигурации фреймворка.
  • в случае Celery Executor автор DAG может выполнять произвольный код на рабочем процессе Celery, что может потенциально повлиять на все задачи, выполняемые там же;
  • при Kubernetes Executor автор DAG может выполнять произвольный код на запускаемом поде Kubernetes. Каждая задача выполняется в отдельном поде, обеспечивая изоляцию задач.
  • В случае выполнения отложенных задач, т.е. Triggerer автор DAG может выполнять произвольный код без изоляции задач, использующих отложенные функции друг друга. При этом произвольный код различных задач может выполняться в одном и том же процессе/узле кластера AirFlow.

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

Поэтому менеджер развертывания должен использовать дополнительные механизмы для предотвращения выполнения авторами DAG произвольного кода. В частности, можно ввести средства для проверки DAG перед его отправкой в AirFlow, чтобы просматривать код перед его развертыванием, статически проверять и добавлять другие способы предотвращения вредоносного кода. Способ отправки и защиты кода в папку DAG полностью зависит от менеджера развертывания. Сам фреймворк не предоставляет подобных инструментов и механизмов для защиты доступа к папке DAG.

Аутентификация пользователей

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

  • публичный (Public) – неаутентифицированный пользователь;
  • зритель (Viewer) – пользователь с ограниченными правами на чтение журналов аудита, определений и кода DAG, информации о заданиях, задачах, XCom-объектах и пр.;
  • администратор (Admin) – управляет правами других пользователям, имея полный доступ ко всем возможностям пользовательского интерфейса, может выполнять код на рабочих процессах путем настройки соединений, имеет доступ к конфиденциальным учетным данным и может изменять их. Хотя у администратора нет доступа к конфигурации на уровне системы, потенциально он может создать ситуацию отказа в обслуживании веб-сервера.
  • Оператор (Operator) – в отличие от администратора, НЕ может управлять другими пользователями и предоставлять им разрешения. Однако, остальные возможности у этих ролей одинаковы.
  • Пользователь (User) – имеет доступ к веб-GUI и API, может взаимодействовать с ними, просматривать и редактировать DAG, экземпляры задач и запуски, а также просматривать журналы задач.

Администратор может создать набор ролей, которым разрешен просмотр только определенного набора DAG. Это называется доступом на уровне DAG. Каждый DAG, определенный в таблице DAG, рассматривается как объект View, имеющий два связанных с ней разрешения: can_read и can_edit. Также есть представление DAGs, которое позволяет роли получать доступ ко всем DAG, к которому имеют доступ все роли по умолчанию: Admin, Viewer, User, Operator.

Только для разрешений уровня DAG доступ можно контролировать на уровне всех DAG или отдельных его объектов. Если у пользователя есть разрешение DAGs.can_read, DAGs.can_edit и DAGs.can_delete, он может выполнять соответствующие действия с набором направленных ациклических графов. Аналогично для отдельного DAG в списке разрешений должен быть явно перечислен его идентификатор. Например, если пользователь пытается просмотреть информацию DAG для example_dag_id, он сможет сделать это, имея доступ DAGs.can_read или DAG:example_dag_id.can_read.

Поскольку контроль доступа на уровне DAG можно настроить в нескольких местах, это может привести к конфликту разрешений. Поэтому AirFlow считает аргумент access_control в самом DAG более приоритетным, например:

DAG(
    dag_id="example_dag",
    start_date=pendulum.datetime(2024, 2, 17, tz="UTC"),
    access_control={
        "Viewer": {"can_edit", "can_create", "can_delete"},
    },
)

При его наличии в любом значении, кроме None, все ранее существовавшие разрешения уровня DAG будут перезаписаны. Полное удаление аргумента access_control из DAG или установка для него значения None не приведет к изменениям, но может стать причиной того, что разрешения останутся неактивными.

Если значение access_control не определено в самом DAG, AirFlow будет использовать существующие разрешения, определенные в базе данных метаданных. Их можно установить через пользовательский интерфейс, CLI или предыдущие аргументы access_control в рассматриваемом DAG. Общесистемные роли имеют приоритет над контролем доступа на уровне DAG.

Поскольку AirFlow по умолчанию требует аутентификации пользователей, для входа в систему нужно создать учетную запись. Для этого используются команды CLI-интерфейса users create. Например, когда я запускала AirFlow в Google Colab, так создала пользователя Anna с ролью администратора:

!airflow users create --username anna --firstname Anna --lastname Anna --email anna@example.com --role Admin --password password
веб-интерфейс Apache AirFlow
Вход в веб-интерфейс Apache AirFlow

Можно использовать другие варианты аутентификации, например, OAuth, OpenID, LDAP, REMOTE_USER. Начиная с версии 2.0, пользовательским интерфейсом AirFlow по умолчанию является RBAC Flask App Builder — простая и быстрая среда разработки REST-приложений на основе фреймворка Flask. Способ аутентификации задается в файле $AIRFLOW_HOME/webserver_config.py. Из-за ограничений Flask AppBuilder и Authlib поддерживается только ограниченный перечень провайдеров OAuth2: github, githublocal, twitter, linkedin, google, azure, openshift, okta, keycloak и keycloak_before_17.

Также можно создавать пользователей, регистрируя их на странице входа в пользовательский интерфейс AirFlow. Для этого надо внести изменения в файл $AIRFLOW_HOME/webserver_config.py:

AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Desired Role For The Self Registered User"
RECAPTCHA_PRIVATE_KEY = 'private_key'
RECAPTCHA_PUBLIC_KEY = 'public_key'

MAIL_SERVER = 'smtp.gmail.com'
MAIL_USE_TLS = True
MAIL_USERNAME = 'yourappemail@gmail.com'
MAIL_PASSWORD = 'passwordformail'
MAIL_DEFAULT_SENDER = 'sender@gmail.com'

При этом необходимо установить пакет Flask-Mail, чтобы разрешить самостоятельную регистрацию пользователя, поскольку это функция инфраструктуры Flask-AppBuilder. Для поддержки аутентификации через стороннего поставщика AUTH_TYPE запись необходимо обновить, указав желаемую опцию, например OAuth, OpenID, LDAP, а в строках со ссылками на выбранную опцию необходимо удалить комментарии и настроить их в файле $AIRFLOW_HOME/webserver_config.py.

Поскольку AirFlow использует анализатор конфигурации Python, который интерполирует знаки %, их обязательно надо экранировать в файле конфигурации как %%, чтобы фреймворк не передавал эти данные из исключения парсера в лог.

В заключение отметим, что для ограничения количества запросов аутентификации в заданном временном диапазоне можно задать соответствующие настройки Flask-Limiter . По умолчанию AirFlow допускает для каждого веб-сервера не более 5 запросов за 40 секунд. Поскольку между запускаемыми Gunicorn-процессами не используется общее хранилище, ограничение скорости применяется отдельно для каждого процесса. Однако, можно настроить ограничение скорости для совместного использования между процессами, используя внешнее хранилище и задав параметры конфигурации RATELIMIT_* в файле webserver_config.py. Например, можно использовать NoSQL-СУБД Redis в качестве хранилища с ограничением скорости:

RATELIMIT_STORAGE_URI = "redis://my_redis_host:6379/0"

Освоить на практике лучшие приемы использования этого оркестратора пакетных процессов в задачах реальной дата-инженерии вам помогут специализированные курсы в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://airflow.apache.org/docs/apache-airflow/stable/security/index.html
  2. https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html
  3. https://airflow.apache.org/docs/apache-airflow/stable/security/webserver.html#sensitive-variable-fields

Добавить комментарий

Поиск по сайту