Аутентификация и авторизация: разница, протоколы (OAuth 2.0, LDAP, JWT) и модели (RBAC, ABAC) | Практическое руководство для DevOps | AdminWiki

Аутентификация и авторизация: разница, протоколы (OAuth 2.0, LDAP, JWT) и модели (RBAC, ABAC) | Практическое руководство для DevOps

19 апреля 2026 13 мин. чтения
Содержание статьи

Основа безопасности: четкое разделение аутентификации и авторизации

Проектирование надежной IT-инфраструктуры начинается с понимания фундаментальных концепций контроля доступа. Аутентификация (Authentication, AuthN) отвечает на вопрос «кто вы?» - это процесс проверки личности пользователя или системы. Авторизация (Authorization, AuthZ) определяет «что вам можно?» - проверка прав на выполнение конкретного действия или доступ к ресурсу после успешной аутентификации. Смешение этих понятий приводит к архитектурным ошибкам, которые снижают безопасность всей среды.

Аутентификация подтверждает субъекта. Авторизация ограничивает его действия. Эта последовательность критична: система сначала должна узнать пользователя, затем решить, какие операции ему разрешены.

Примеры из жизни системного администратора: где что применяется

В повседневной работе администратора эти концепции встречаются постоянно:

  • Linux: модули PAM (Pluggable Authentication Modules) отвечают за проверку учетных данных при входе в систему или через SSH - это аутентификация. Права на файлы, заданные командой chmod, или правила в файле /etc/sudoers определяют, может пользователь читать, изменять или выполнять файл - это авторизация.
  • Базы данных: команда CREATE USER в PostgreSQL или MySQL создает учетную запись с паролем - это аутентификация. Команда GRANT SELECT ON table_name TO user_name предоставляет право чтения конкретной таблицы - это авторизация.
  • Веб-сервер Nginx: модуль auth_basic требует логин и пароль для доступа к директории - это аутентификация. Блок location /admin { allow 192.168.1.10; deny all; } разрешает доступ только с определенного IP - это авторизация на основе атрибута (адреса).
  • Kubernetes: файл kubeconfig содержит сертификаты или токены для подключения к API кластера - это аутентификация. Объекты Role и RoleBinding определяют, может пользователь создавать Pods или читать Secrets в namespace - это авторизация.

Для быстрого сравнения используйте эту таблицу:

Компонент инфраструктуры Аутентификация (Кто вы?) Авторизация (Что вам можно?)
Операционная система (Linux) Вход по паролю/SSH-ключу через PAM Права на файлы (chmod), правила sudo
База данных (PostgreSQL) Соединение с логином и паролем SQL-права: SELECT, INSERT, UPDATE
Веб-приложение Ввод логина/пароля на форме Возможность удалить запись или просмотреть отчет
Kubernetes кластер Подача токена или сертификата в API RBAC: Role и RoleBinding

Почему смешение понятий - критическая ошибка в архитектуре

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

Реализация разделения - первый шаг к отказоустойчивой системе безопасности. Она позволяет независимо масштабировать и усиливать каждый компонент: внедрить двухфакторную аутентификацию без изменения бизнес-правил или пересмотреть модель контроля доступа, не затрагивая механизмы проверки личности.

Как система узнает, кто вы: механизмы и протоколы аутентификации

После определения фундамента переходим к практической реализации проверки личности. Механизмы аутентификации классифицируются по количеству факторов: однофакторная (пароль или ключ), двухфакторная (2FA) и многофакторная (MFA). Для административного доступа к критичным системам двухфакторная аутентификация стала обязательным минимумом.

В корпоративной инфраструктуре управление тысячами учетных записей требует централизации. Основные решения для этого - LDAP и его расширение Active Directory от Microsoft.

LDAP/Active Directory: основа корпоративной инфраструктуры

LDAP (Lightweight Directory Access Protocol) служит протоколом для работы с директориями - централизованными хранилищами информации о пользователях, группах и устройствах. Active Directory (AD) - реализация LDAP от Microsoft с дополнительными службами, включая Kerberos для аутентификации.

Интеграция Linux-сервера с Active Directory стандартизирует управление доступом. Для Ubuntu или CentOS используйте SSSD (System Security Services Daemon).

Основные шаги:

  1. Установить пакеты: sudo apt install sssd-ad sssd-tools realmd (для Ubuntu/Debian).
  2. Настроить корректное время через NTP - это критично для работы Kerberos.
  3. Присоединить сервер к домену командой: sudo realm join --user=admin_user domain.example.com.
  4. Проверить и настроить файл /etc/sssd/sssd.conf, указав домен и параметры поиска.
  5. Обновить /etc/nsswitch.conf для использования SSSD как источника информации о пользователях: passwd: files sss.
  6. Настроить PAM для использования SSSD через файлы в /etc/pam.d/.

После конфигурации проверьте интеграцию командой getent passwd domain_user или id domain_user. Эти команды должны показать информацию о пользователе из AD.

Практический кейс: автоматизация присоединения к домену через Ansible
Для массового развертывания используйте Ansible-плейбук. Пример ниже выполняет базовую проверку и присоединение:

---
- name: Join Linux servers to Active Directory
  hosts: linux_servers
  become: yes
  vars:
    domain_name: "example.com"
    ad_admin_user: "join_user"
    ad_admin_password: "{{ vault_join_password }}"

  tasks:
    - name: Install required packages
      apt:
        name:
          - sssd
          - sssd-tools
          - realmd
          - adcli
          - samba-common-bin
        state: present
        update_cache: yes

    - name: Ensure time is synchronized (critical for Kerberos)
      systemd:
        name: systemd-timesyncd
        state: started
        enabled: yes

    - name: Discover the AD domain
      command: realm discover {{ domain_name }}
      register: realm_discover
      changed_when: false
      ignore_errors: yes

    - name: Join the domain
      command: "echo '{{ ad_admin_password }}' | realm join --user={{ ad_admin_user }} {{ domain_name }}"
      args:
        stdin: yes
      register: join_result
      changed_when: join_result.rc == 0
      failed_when:
        - join_result.rc != 0
        - "'Already joined to this domain' not in join_result.stderr"

    - name: Configure SSSD for home directory creation
      lineinfile:
        path: /etc/sssd/sssd.conf
        regexp: '^override_homedir'
        line: 'override_homedir = /home/%u'
        insertafter: '[domain/{{ domain_name|upper }}]'
      notify: restart sssd

  handlers:
    - name: restart sssd
      systemd:
        name: sssd
        state: restarted

Подробнее о работе с Linux и интеграции различных служб можно узнать в практическом руководстве по администрированию Linux для DevOps и сисадминов.

PAM (Pluggable Authentication Modules): гибкая аутентификация в Linux

PAM предоставляет модульную архитектуру для аутентификации в Linux. Он позволяет подключать разные источники проверки через набор динамических библиотек. Конфигурация PAM состоит из стеков модулей, управляемых файлами в директории /etc/pam.d/.

Основные типы модулей:

  • auth - проверка учетных данных (пароль, ключ).
  • account - проверка состояния учетной записи (доступ по времени, ограничения).
  • password - управление паролями (смена).
  • session - действия перед и после предоставления доступа (логирование, установка среды).

Пример конфигурации для службы SSH (/etc/pam.d/sshd), требующей сначала пароль, затем одноразовый код из Google Authenticator:

auth required pam_unix.so try_first_pass
auth required pam_google_authenticator.so

Модуль pam_ldap.so позволяет подключить аутентификацию через LDAP. Порядок модулей в стеке критически важен - система выполняет их последовательно.

Двухфакторная аутентификация (2FA): обязательный минимум для админ-доступа

Двухфакторная аутентификация добавляет второй, независимый фактор проверки после первого (обычно пароля). Основные методы: TOTP (Time-based One-Time Password) через приложения типа Google Authenticator или Authy, аппаратные токены (YubiKey), SMS (не рекомендуется из-за уязвимости протокола).

Пошаговая настройка 2FA для SSH на Linux-сервере с использованием PAM и Google Authenticator:

  1. Установить модуль: sudo apt install libpam-google-authenticator.
  2. Для каждого пользователя запустить google-authenticator и следовать инструкциям, сохранив QR-код.
  3. Настроить PAM для SSH как показано выше.
  4. В файле /etc/ssh/sshd_config убедиться, что PasswordAuthentication установлено в yes (или required).
  5. Перезапустить службу SSH: sudo systemctl restart sshd.

Для веб-интерфейсов (TrueNAS, Proxmox) 2FA часто настраивается внутри их админ-панели. Альтернативный подход - использование reverse proxy (например, Nginx) с модулем аутентификации перед основным приложением.

Как система решает, что вам можно: модели контроля доступа (авторизация)

После успешного входа система применяет модель контроля доступа для определения прав. Эволюция моделей идет от простых списков ACL к ролевым и атрибутным системам.

RBAC (Role-Based Access Control): стандарт для Kubernetes и внутренних систем

RBAC управляет доступом через роли. Пользователь или сервисный аккаунт получает роль, которая содержит набор разрешений. Роль затем связывается с субъектом через привязку (Binding).

Три основных компонента:

  • Пользователь/Сервисный аккаунт (Subject) - субъект, которому нужны права.
  • Роль (Role/ClusterRole) - набор правил (например, «читать Pods в namespace default»).
  • Привязка (RoleBinding/ClusterRoleBinding) - связывает роль с субъектом.

Пример YAML-манифеста для создания Role в Kubernetes, разрешающего только чтение Pods в конкретном namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: monitoring
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

Пример RoleBinding, присваивающего эту роль пользователю:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: monitoring
  name: read-pods-to-john
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- kind: User
  name: "john"
  apiGroup: rbac.authorization.k8s.io

Практический кейс: сервисный аккаунт для ArgoCD или мониторинга
Для CI/CD или мониторинга часто требуется сервисный аккаунт с правами на чтение ресурсов в нескольких namespace. Пример ClusterRole для такого аккаунта:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-monitoring-viewer
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints", "configmaps"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets", "daemonsets"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch"]

Шпаргалка: отладка прав в Kubernetes
Используйте команду kubectl auth can-i для быстрой проверки прав из консоли:

  • kubectl auth can-i list pods --as=system:serviceaccount:monitoring:prometheus – может ли сервисный аккаунт prometheus листать поды?
  • kubectl auth can-i create deployments --namespace=production – есть ли у текущего контекста право создавать deployments в namespace production?
  • kubectl auth reconcile -f rbac-manifest.yaml – полезная команда для применения RBAC-манифестов, которая показывает, какие изменения будут внесены.

В базах данных модель аналогична. В PostgreSQL создается роль readonly, затем выдаются права: GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;.

Преимущество RBAC - простота управления для больших групп. Недостаток - «взрыв ролей» (role explosion), когда для уникальных комбинаций прав приходится создавать множество мелких ролей.

ABAC (Attribute-Based Access Control) и политики на основе правил

ABAC оценивает доступ на основе атрибутов субъекта, ресурса, действия и условий среды. Политика описывается правилами типа: «Пользователь из отдела разработки может запускать контейнеры в кластере staging только в рабочее время».

Пример политики AWS IAM в JSON, разрешающей доступ к корзине S3 только с корпоративного IP-адреса:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::project-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "192.168.1.0/24"
        }
      }
    }
  ]
}

В Nginx Plus можно использовать модуль auth_jwt для проверки JWT токена и переменные для динамического контроля доступа на основе claims токена.

Универсальным движком для политик ABAC служит Open Policy Agent (OPA). Он позволяет декларативно описывать политики в отдельном языке (Rego) и применять их к различным системам (Kubernetes, Docker, API).

SELinux и AppArmor: авторизация на уровне ядра (MAC)

SELinux и AppArmor реализуют модель обязательного контроля доступа (Mandatory Access Control, MAC) на уровне ядра Linux. В отличие от дискреционного контроля (DAC), где владелец файла сам назначает права (например, chmod 777), MAC управляется централизованной политикой, которая ограничивает возможности даже владельца.

SELinux присваивает каждому процессу и файлу контекст безопасности (security context). Команда ls -Z показывает контекст файлов, ps -Z - контекст процессов.

Основные режимы работы SELinux:

  • Enforcing - политика активно применяется и блокирует нарушения.
  • Permissive - политика проверяется, но нарушения только логируются, не блокируются.
  • Disabled - SELinux отключен.

Для отладки проблем используйте audit2why или sealert для анализа логов аудита и получения рекомендаций. Базовые рекомендации по настройке: начинайте с режима permissive для составления политики, затем переключайте на enforcing после тестирования.

AppArmor работает по схожему принципу, но использует профили, привязанные к пути файлов, и часто считается более простым в конфигурации.

Протоколы для веба и распределенных систем: OAuth 2.0, OpenID Connect, JWT

В современных веб-приложениях и микросервисных архитектурах аутентификация и авторизация реализуются через стандартные протоколы. OAuth 2.0 стал основным протоколом делегирования авторизации для API. OpenID Connect (OIDC) расширяет его для задач аутентификации. JWT служит форматом токенов для передачи утверждений.

OAuth 2.0: делегирование доступа без передачи паролей

OAuth 2.0 позволяет приложению получить ограниченный доступ к ресурсам пользователя на другом сервисе без передачи логина и пароля. Типичный сценарий: веб-приложение хочет получить доступ к календарю пользователя в Google.

Роли в OAuth 2.0:

  • Resource Owner - пользователь, владеющий данными.
  • Client - приложение, которое запрашивает доступ.
  • Authorization Server - сервер, который проверяет пользователя и выдаёт токены (например, сервер Google).
  • Resource Server - сервер, хранящий данные пользователя (API Google Calendar).

Стандартный и наиболее безопасный поток - Authorization Code Flow:

  1. Приложение направляет пользователя на Authorization Server с параметрами client_id, redirect_uri и запрашиваемыми scope.
  2. Пользователь аутентифицируется на Authorization Server и соглашается предоставить доступ.
  3. Authorization Server перенаправляет пользователя обратно на приложение через redirect_uri, добавляя в URL временный код авторизации (code).
  4. Приложение отправляет этот код вместе со своим client_secret напрямую на Authorization Server (back-channel) и получает access_token.
  5. Приложение использует access_token для запросов к Resource Server.

Implicit Flow, где токен возвращается непосредственно в redirect URI, считается устаревшим и опасным из-за риска утечки токена через браузер.

JWT (JSON Web Tokens): что внутри и как безопасно использовать

JWT - компактный формат для безопасной передачи утверждений между двумя сторонами. Токен состоит из трех частей, разделенных точками: Header, Payload и Signature.

Header определяет тип токена и алгоритм подписи (например, {"alg": "RS256", "typ": "JWT"}). Payload содержит утверждения (claims) о субъекте и дополнительных данных. Стандартные claims включают iss (издатель), exp (время expiration), sub (subject). Signature создается путем подписи объединенного header и payload с использованием секретного ключа или приватного ключа RSA.

3 ключевых момента безопасности JWT:

  1. Всегда проверяйте подписи. Алгоритм RS256 (подпись приватным ключом, проверка публичным) предпочтительнее HS256 (симметричная подпись секретным ключом), так как секрет не должен храниться на клиенте.
  2. Обязательно проверяйте claim exp (время жизни токена) и iss (издатель).
  3. Избегайте использования алгоритма «none» в заголовке, который указывает на отсутствие подписи.

Пример создания и проверки JWT с RS256 в Python:

import jwt
import datetime

# Создание токена (на стороне Authorization Server)
private_key = open('private.pem').read()
token = jwt.encode({
    "sub": "user123",
    "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}, private_key, algorithm="RS256")

# Проверка токена (на стороне Resource Server)
public_key = open('public.pem').read()
decoded = jwt.decode(token, public_key, algorithms=["RS256"])

Шпаргалка: отладка JWT в CLI
Для быстрой проверки токенов в командной строке используйте утилиты:

  • jq + base64: echo "$JWT_TOKEN" | cut -d'.' -f2 | base64 --decode | jq . – декодирует payload (без проверки подписи).
  • openssl: Для проверки подписи RS256: openssl dgst -sha256 -verify public.pem -signature <(echo -n "$(echo $JWT_TOKEN | cut -d'.' -f1,2)" | openssl enc -base64 -d) <(echo -n "$(echo $JWT_TOKEN | cut -d'.' -f3)" | sed 's/-/+/g; s/_/\//g' | base64 --decode 2>/dev/null)
  • Генерация тестовых ключей: openssl genrsa -out private.pem 2048 и openssl rsa -in private.pem -pubout -out public.pem.

JWT часто используется в связке с OAuth 2.0 в качестве формата access_token. Подробнее о настройке OAuth 2.0 сервера читайте в соответствующем разделе.

Практика: настройка единого входа (SSO) с Keycloak

Keycloak - open-source решение для Identity and Access Management, которое выступает как Identity Provider (IdP) для единого входа (Single Sign-On, SSO). Он поддерживает протоколы OAuth 2.0 и OpenID Connect.

Базовая схема настройки SSO для двух приложений (например, Grafana и Jenkins):

  1. Развернуть Keycloak и создать Realm (домен безопасности).
  2. В Realm создать Clients для Grafana и Jenkins. Для каждого Client указать корректный Redirect URI.
  3. Настроить маппинг атрибутов: какие данные из токена (например, группа, email) передавать приложению.
  4. В Grafana и Jenkins настроить аутентификацию через OIDC, указав URL Keycloak, Client ID и Client Secret.
  5. Пользователь логинится в Keycloak один раз и получает доступ к обоим приложениям без повторного ввода учетных данных.

Важно правильно настроить механизм единого выхода (single logout), чтобы при выходе из одного приложения токены в других также аннулировались.

Практический кейс: интеграция GitLab CI/CD с HashiCorp Vault для управления секретами на основе ролей
HashiCorp Vault позволяет динамически генерировать секреты (например, доступ к БД) для CI/CD пайплайнов. Настройка включает:

  1. Включение JWT аутентификации в Vault и настройка trust с GitLab как OIDC провайдером.
  2. Создание политики в Vault, которая разрешает чтение секретов по определенному пути, например: path "secret/data/{{identity.entity.aliases.auth_jwt_.metadata.project_id}}/*" { capabilities = ["read"] }.
  3. В GitLab CI/CD пайплайне добавить шаг для аутентификации в Vault и получения секрета перед деплоем.

Детальнее о настройке SSL/TLS для защиты каналов связи читайте в руководстве по ручной установке SSL-сертификата на Nginx и Apache. Для углубленного изучения автоматизации инфраструктуры рекомендуем практический гайд по автоматизации инфраструктуры для DevOps и сисадминов.

Поделиться:
Сохранить гайд? В закладки браузера