# Руководство по Traefik Forward Auth – Простая защита через Google SSO

![](https://st1t.ru/wp-content/uploads/2022/11/traefik-forward-auth-google-flow-840x525.png)

----------

Хотите защитить свой стек Docker чем-то более надежным, чем обычная HTTP-аутентификация? Google OAuth2 SSO с Traefik Forward Auth — ваш выбор.

Я был очень удивлен, узнав, что образ Thomseddon  [Traefik Forward Auth](https://github.com/thomseddon/traefik-forward-auth)  может защитить мои службы в Docker. Этот образ обеспечивает вход и аутентификацию OAuth/SSO для обратного прокси-сервера Traefik с использованием Traefik.

> Почему Traefik Google OAuth2 для служб Docker?
> 
> Google OAuth2 позволяет вам использовать свою учетную запись Google для входа в свои службы. Использование  **Google OAuth с Traefik**  позволит вам добавлять учетные записи в белый список, внедрять двухфакторную аутентификацию Google, а также обеспечивать единый вход (SSO) для ваших служб. Это не только обеспечивает удобство, поскольку вам не нужно часто входить в систему, но и повышает безопасность.

Добавление Traefik OAuth2 для ваших служб Docker будет простым шагом и важным дополнением к вашему стеку Docker Traefik.


## НАСТРОЙКА TRAEFIK FORWARD AUTH ПРИ ПОМОЩИ GOOGLE OAUTH2

Добавление базовой аутентификации, предоставляемой Traefik, — это самый простой способ защитить ваш Docker и другие службы.

В нашем предыдущем руководстве мы рассмотрели, как использовать учетные данные для входа .htpasswd и промежуточное ПО  **Traefik auth middleware**  для добавления базовой аутентификации с использованием меток.

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

После внедрения  **Traefik forward authentication**  теперь нужно войти в систему только один раз. И внедрив  _Traefik OAuth2 с Google_, можно добавить двухфакторную аутентификацию (2FA), что делает этот метод намного более безопасным и удобным, чем использование обычной аутентификации.

Если вы предпочитаете частную self-hosted систему многофакторной аутентификации (а не полагаться на Google), обратите внимание на Authelia или Keycloak. Я использовал Authelia для ранее, а сейчас перешел на Keyсloak для управления несколькими пользователями. Traefik OAuth2 я использую для домашних проектов.

> ### Что такое OAuth?
> 
> **OAuth** — открытый протокол (схема) [авторизации](https://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F "Авторизация"), обеспечивающий предоставление третьей стороне ограниченный доступ к защищённым ресурсам пользователя без передачи ей (третьей стороне) логина и пароля  [– Wikipedia](https://ru.wikipedia.org/wiki/OAuth)

Прежде чем настраивать Traefik Forward Auth с Google OAuth2, давайте посмотрим, как все это сочетается друг с другом.

### Как работает Google OAuth2 с Traefik?

Вход и аутентификация Google OAuth для Traefik действует как посредник для ваших служб, разрешая или запрещая доступ после проверки авторизованного файла cookie в вашем браузере. Подводя итог, процесс выглядит примерно так:

1.  Для нашего хоста сделан  **запрос**  (например, https://traefik.example.com)
2.  Запрос направляется нашим провайдером DNS на наш IP-адрес WAN, где порты 80 и 443 перенаправляются в контейнер Traefik.
3.  Traefik видит входящий запрос и распознает, что  **Forward Auth**  определен в  **метках**  для этого хоста, поэтому запрос перенаправляется в контейнер  **Traefik Forward Auth**.
4.  Затем контейнер проверяет, есть ли в браузере авторизованный файл cookie. Если файл cookie отсутствует, запрос отправляется на  **сервер авторизации Google OAuth2**.
5.  После успешного входа в Google запрос отправляется на  **URI перенаправления**, указанный для  **веб-приложения**  (https://oauth.example.com/_oauth).
6.  Затем авторизованный файл cookie сохраняется в браузере, и пользователь отправляется во внутреннюю службу.

В следующий раз, когда этот браузер попытается получить доступ к службе, защищенной входом и аутентификацией на основе OAuth, файл cookie будет распознан, и пользователь будет перенаправлен на их службу без запроса на вход!

![](https://st1t.ru/wp-content/uploads/2022/11/traefik-forward-auth-google-flow-1024x654.png)

Этот процесс происходит очень быстро, и как только ваш браузер получит файл cookie, вы забудете, что даже включили Google OAuth с Traefik!

**Примечание.**  Образ Traefik Forward Auth использует  [**OpenID** **Connect**](https://en.wikipedia.org/wiki/OpenID_Connect) (**OIDC**),который представляет собой уровень аутентификации поверх протокола  [OAuth 2.0](https://en.wikipedia.org/wiki/OAuth#OAuth_2.0 "OAuth"). Образ Docker, представленный в этом руководстве, поддерживает Google, а также  [других поставщиков OIDC](https://github.com/thomseddon/traefik-forward-auth/wiki/Provider-Setup).

Позаботившись об основах, давайте перейдем к настройке прямой аутентификации Google OAuth Traefik для наших сервисов Docker.

> ### Как настроить OAuth?
> 
> Настройка Google OAuth для Docker с помощью Traefik включает в себя 3 этапа:
> 
> 1.  создание записей DNS,
> 2.  настройку службы Google OAuth2 и
> 3.  изменение файлов компоновки Docker и добавление меток Traefik для активации прямой аутентификации.

Итак, во-первых, нам нужно настроить службу Traefik OAuth2. Давайте настроим все предварительные условия сейчас:

### Шаг 1. Создайте записи DNS

Начните с создания новой DNS-записи CNAME для нашей службы OAuth (Google перенаправит на этот адрес после аутентификации). В этом руководстве мы будем использовать доменное имя  **example.com**.

Установите запись DNS как **oauth.example.com**. На рисунках ниже показан скриншот из Cloudflare. В зависимости от вашего провайдера DNS, для вас все может выглядеть по-разному, но по сути иметь одно и то же содержание.

![](https://st1t.ru/wp-content/uploads/2022/11/01-clouldflare-dns-for-google-oauth-1024x367.png)

Обратите внимание, что для распространения и активации записей DNS может потребоваться несколько часов.

В качестве альтернативы, если вы включили запись CNAME с подстановочными знаками, указывающую на ваш корневой домен, вы можете пропустить этот шаг.

### Шаг 2. Настройте службу Google OAuth2

Создав записи DNS, давайте перейдем к настройке Google OAuth.

#### Шаг 2.1. Создайте проект Google.

Нам нужно создать  **проект Google**, который будет содержать наше  **веб-приложение**,  **экран согласия**  и  **учетные данные**.

Перейдите в  [Google Cloud Developers Console](https://console.developers.google.com/)  и убедитесь, что вы вошли в правильный аккаунт Google, который хотите использовать (обычно это будет ваш адрес электронной почты).

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

При появлении запроса вам нужно будет согласиться с  **Условиями использования Google Cloud Platform**, чтобы использовать их API.

Сервис OAuth от Google можно использовать бесплатно, поэтому пока мы можем  **отказаться**  от бесплатной пробной версии. Нажмите «**Select a project**» и «**New project**».

![](https://st1t.ru/wp-content/uploads/2022/11/02-google-cloud-oauth-create-new-project-1024x498.png)

Введите уникальное имя для идентификации проекта, например  **“Traefik Authentication”**. Нажмите  **Create**.

![](https://st1t.ru/wp-content/uploads/2022/11/03-google-cloud-oauth-new-project-details.png)

#### Шаг 2.2. Создайте учетные данные OAuth

Теперь, когда наш проект создан, нам нужно создать идентификатор клиента и секрет клиента, чтобы пройти аутентификацию в Google. Выберите наш проект  **Traefik Authentication**  и в меню навигации выберите  **APIs & Services > Credentials**. Нажмите  **Create Credentials > OAuth client ID**.

![](https://st1t.ru/wp-content/uploads/2022/11/04-google-cloud-oauth-create-oauth-client-id.png)

#### Шаг 2.3: Настройте Consent Screen

После того, как вы нажмете Идентификатор клиента OAuth, вы увидите примечание о настройке consent screen, как показано ниже. Перед продолжением необходимо настроить consent screen.

После того, как вы нажмете  **OAuth Client ID**, вы увидите примечание о настройке consent screen, как показано ниже. Перед продолжением необходимо настроить consent screen.

![](https://st1t.ru/wp-content/uploads/2022/11/05-google-cloud-oauth-configure-consent-screen.png)

Если автоматический запрос не появится, выберите  **OAuth consent screen**  на левой панели.

Далее выберите тип пользователей приложения. Выбираем тип  **External** и нажимаем  **Create**.

![](https://st1t.ru/wp-content/uploads/2022/11/06-google-cloud-oauth-consent-screen-type.png)

Выберите имя для своего приложения, например  **Traefik Auth**, затем в разделе  **Authorized domains**  введите свой домен, например  **example.com**. Убедитесь, что вы нажимаете  **Enter**, чтобы добавить его, а затем нажмите  **Save**.

![](https://st1t.ru/wp-content/uploads/2022/11/07-google-cloud-oauth-consent-screen.png)

После нажатия кнопки  **Save**  вы перейдете на следующий шаг. Везде нажимаем снизу  **Save and Continue**.

#### **Шаг 2.4. Создайте идентификатор клиента OAuth.**

Выберите наш проект  **Traefik Authentication**  и в меню навигации выберите  **APIs & Services > Credentials**. Нажмите  **Create Credentials > OAuth client ID**.

Теперь выберите тип  **Web Application**  и введите имя для своего веб-приложения, например,  **Traefik**. Кроме того, вам потребуется ввести  **Authorized redirect URI**  в виде  _https://oauth.example.com/_oauth_. Убедитесь, что вы нажимаете  **Enter**, чтобы добавить его, а затем нажмите  **Save**.

**Примечание.**  Вам разрешено добавлять только  **URI перенаправления**, которые ведут на ваши  **авторизованные домены**. Вернитесь к экрану согласия OAuth, если вам нужно их отредактировать.

![](https://st1t.ru/wp-content/uploads/2022/11/08-oauth-authorized-redirect-uris.png)

Учетные данные для нашего единого входа для Docker созданы! Скопируйте и сохраните  **client ID**  и  **client secret**; нам нужно будет использовать их на следующем шаге.

![](https://st1t.ru/wp-content/uploads/2022/11/09-oauth-client-id-and-secret.png)

### Шаг 3. Настройте прямую аутентификацию Traefik с помощью OAuth2

Теперь, когда учетные данные OAuth настроены, осталось настроить контейнер OAuth. Войдите на свой локальный компьютер или используйте SSH-клиен для удаленного входа.

Обязательно остановите Traefik (при необходимости) и отредактируйте файл docker-compose, добавив метки Traefik и контейнер OAuth, как описано ниже.

Предполагается, что вы уже прочитали и выполнили большую часть моего руководства по Traefik 2 и читаете этот пост только для того, чтобы внедрить Google OAuth.

#### Шаг 3.1. Создайте промежуточное ПО Traefik Auth и цепочку

Давайте теперь укажем промежуточное ПО для аутентификации Traefik для OAuth2. Создайте новый файл middlewares-oauth.yml и добавьте следующие строки:
```yaml
http:
  middlewares:
    middlewares-oauth:
      forwardAuth:
        address:  "http://oauth:4181"  # Make sure you have the OAuth service in docker-compose.yml
        trustForwardHeader:  true
        authResponseHeaders:
          - "X-Forwarded-User"
```
Кроме того, давайте создадим новую цепочку промежуточного программного обеспечения для сервисов, которые будут использовать Google OAuth. Откройте файл  **middleware-chains.yml**, созданный в моем руководстве по Traefik, и добавьте следующие строки ниже того, что уже есть:
```yaml
http:
  middlewares:
    chain-oauth:
      chain:
        middlewares:
         - middlewares-rate-limit
         - middlewares-https-redirectscheme
         - middlewares-secure-headers
         - middlewares-oauth
         - middlewares-compress
```
**Примечание:** Промежуточное ПО для ограничения скорости, перенаправления HTTPS, заголовков безопасности и сжатия должно быть определено в соответствии с моим руководством Traefik. В противном случае Traefik не запустится.

Сохраните файлы и выйдите из редактирования.

#### Шаг 3.2: Добавьте секреты прямой аутентификации Traefik

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

Создайте файл с именем  **traefik_forward_auth**  в папке  **secrets**  ($DOCKERDIR\secrets, если ваша установка основана на моих руководствах) и добавьте в него следующее содержимое:
```
providers.google.client-id=yourGOOGLEclientID
providers.google.client-secret=yourCLIENTsecret
secret=yourOAUTHsecret
whitelist=yourEMAILaddress1
whitelist=yourEMAILaddress2
```
Настройте вышеуказанное, используя информацию ниже:

-   **yourGOOGLEclientID**  и  **yourCLIENTsecret**: полученные ранее в этом руководстве по Traefik Oauth2.
-   **yourOAUTHsecret**: используется для подписи файла cookie и должен быть случайным. Создайте случайный секрет с помощью:     
`openssl rand -hex 16`
    

Кроме того, вы можете использовать  [онлайн-сервис, подобный этому](https://www.browserling.com/tools/random-string), для создания случайного секрета.

![](https://st1t.ru/wp-content/uploads/2022/11/10-random-secret.png)

-   **yourEMAILAddress1**: идентификатор электронной почты Google, который будет использоваться для аутентификации. При желании вы можете добавить дополнительные адреса электронной почты, которым разрешено проходить аутентификацию (например,  **yourEMAILAddress2**; удалите эту строку, если вы хотите разрешить только один идентификатор электронной почты).

Сохранить и выйти.

Обратите внимание, что папка  **secrets**  и файл  **traefik_forward_auth**  должны иметь разрешение **600**  и принадлежать пользователю  **root**.

Далее давайте настроим контейнер OAuth Forwarder.

#### Шаг 3.3: Добавляем OAuth Forwarder контейнер

Откройте файл docker-compose, который был создан на основе нашего предыдущего руководства по Traefik 2, и добавьте в него следующее.

# Google OAuth - Single Sign On using OAuth 2.0
```yaml
version: '3.7'
services:
  oauth:
    container_name: oauth
    image: thomseddon/traefik-forward-auth:latest
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    environment:
      - CONFIG=/config
      - COOKIE_DOMAIN=$DOMAINNAME_CLOUD_SERVER
      - INSECURE_COOKIE=false
      - AUTH_HOST=oauth.$DOMAINNAME_CLOUD_SERVER
      - URL_PATH=/_oauth
      - LOG_LEVEL=info
      - LOG_FORMAT=text
      - LIFETIME=86400  # 1 day
      - DEFAULT_ACTION=auth
      - DEFAULT_PROVIDER=google
	secrets:
      - source: traefik_forward_auth
	target: /config
	labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.oauth-rtr.tls=true"
      - "traefik.http.routers.oauth-rtr.entrypoints=https"
      - "traefik.http.routers.oauth-rtr.rule=Host(`oauth.$DOMAINNAME_CLOUD_SERVER`)"
      ## Middlewares
      - "traefik.http.routers.oauth-rtr.middlewares=chain-oauth@file"
      ## HTTP Services
      - "traefik.http.routers.oauth-rtr.service=oauth-svc"
      - "traefik.http.services.oauth-svc.loadbalancer.server.port=4181"
```
**$DOMAINNAME_CLOUD_SERVER**  = имя вашего домена в файле .env

Обратите внимание, что мы используем цепочку промежуточного программного обеспечения аутентификации Traefik (**chain-oauth**) для аутентификации вместо базовой аутентификации. Используйте правильный образ для архитектуры вашей системы.

Вы также можете изменить продолжительность (**LIFETIME**), в течение которой аутентификация действительна, с 1 дня, указанного в секундах, на другую продолжительность. Сначала установите  **LOG_LEVEL**  для  **trace**  или  **debug**. Когда все заработает, вы можете изменить его на  **warn**.

При желании остальные переменные среды, определенные для oauth , можно настроить по своему вкусу (если вы знаете, что делаете).

После этого используйте команду docker-compose up. Теперь вы должны быть перенаправлены на страницу входа в систему Google OAuth перед доступом к службе.

#### Шаг 3.4. Добавление Google OAuth для служб Docker

Возьмем пример панели инструментов Traefik 2. Если вы следовали моему руководству по Traefik, теперь у вас должна быть базовая аутентификация с использованием промежуточного программного обеспечения:
```
## Middlewares
- "traefik.http.routers.traefik-rtr.middlewares=middlewares-basic-auth@file"
```
Или цепочка промежуточного программного обеспечения:
```
- "traefik.http.routers.traefik-rtr.middlewares=chain-basic-auth@file"
```
Мы уже определили цепочку промежуточного программного обеспечения для Traefik oauth (**chain-oauth**) выше.

Перейти с базовой аутентификации на oauth теперь так же просто, как изменить  **chain-basic-auth**  на  **chain-oauth**  в файле  **docker-compose**  (показано ниже).
```
- "traefik.http.routers.traefik-rtr.middlewares=chain-oauth@file"
```
Итак, вот и все, вход и аутентификация на основе OAuth для стека обратного прокси-сервера Traefik.

После этого используйте команду  **docker-compose up**.

#### Шаг 3.5. Добавление OAuth в другие (не Docker) службы

Приложениями, не относящимися к Docker, могут быть любые службы, находящиеся в хост-системе или в удаленной системе.

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

Давайте для примера возьмем сервис ex1, работающий на другом хосте (192.168.1.100).

Чтобы добавить к сервису возможность аутентификации Traefik OAuth2, вам нужно всего лишь создать промежуточное ПО маршрутизатора, как показано ниже.
```
http:
  routers:
    ex1-rtr:
      rule:  "Host(`ex1.{{env "DOMAINNAME_CLOUD_SERVER"}}`)"
      entryPoints:
        - https
      middlewares:
        - chain-oauth
      service: ex1-svc
      tls:
        certResolver: dns-cloudflare
  services:
    ex1-svc:
      loadBalancer:
        servers:
          - url:  "http://192.168.1.100:80"  # or whatever your external host's IP:port is
```
Интерфейс ex1 будет доступен по адресу  **ex1.example.com**, при условии, что для переменной среды  **DOMAINNAME_CLOUD_SERVER**  установлено значение  **example.com**  и она передается в контейнер Traefik.

Поскольку каталог rules является динамическим, просто добавив этот файл в этот каталог, мы создали маршрут. Вы должны иметь возможность подключиться к ex1 через Google OAuth2 без перезапуска Traefik!

## ОБХОД OAUTH / ВЫБОРОЧНАЯ АУТЕНТИФИКАЦИЯ

Некоторые приложения не могут аутентифицировать себя и пройти через авторизацию Oauth. Для этого есть обход Oauth на основе правил  [Auth Forwarder GitHub](https://github.com/thomseddon/traefik-forward-auth).

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

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

### Определение правила обхода

Как мы можем выяснить, какие конкретные правила использовать?

Это может быть довольно сложно. Как указано в приведенной ниже ссылке, общий способ обхода аутентификации — использование пути.

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

Проверьте журналы Docker для контейнера OAuth (основные команды Docker). Это выдаст почти все, что происходит в этом контейнере, что может быть ошеломляющим. Вы можете сократить это до интересующего вас приложения, введя команду grep ****.

### Указание правила обхода OAuth

Обратите внимание, что  **uri**  в логах может содержать ключ API (X-Api-Key:[apikey]). Таким образом, вы можете установить использование обхода на основе этого следующим образом. На примере файла middleware сервиса ex1:

В строчку
```
rule: "Host(`ex1.{{env "DOMAINNAME_CLOUD_SERVER"}}`)"
```
Дописываем
```
rule: "Host(`ex1.{{env "DOMAINNAME_CLOUD_SERVER"}}`) && Headers(`X-Api-Key`, `$API_KEY`)"
```

Перезапустите контейнер OAuth и попробуйте сейчас получить доступ к ex1 через приложение и браузер. Браузер должен представить логин OAuth, а приложение должно направить вас напрямую к сервису.

### Использование пользовательских заголовков

Некоторые приложения позволяют добавлять собственные заголовки. Поэтому, когда приложение пытается связаться с вашим Radarr, Sonarr и т. д., может быть отправлен собственный заголовок.

Затем этот настраиваемый заголовок можно отслеживать и, если он присутствует, можно использовать для запуска обхода. Это альтернатива поиску ключей API. Вы можете установить один стандартный заголовок для всех приложений и использовать для всех одно и то же правило обхода. Это также устраняет догадки и пробы и ошибки, описанные выше.

## OAUTH И ЗАГОЛОВКИ БЕЗОПАСНОСТИ

Одна вещь, которую следует отметить при использовании службы  **Traefik OAuth2**, — это ваши заголовки безопасности. Если служба использует  **OAuth**  и вы пытаетесь проверить, применяются ли ваши заголовки безопасности, вы, вероятно, получите более низкую оценку.

## FAQ

### **Что такое traefik-forward-auth-provider?**

Прямая аутентификация Traefik — это служба, которая интегрируется со сторонним поставщиком аутентификации (например, Google, Microsoft, Authelia и т. д.) для защиты ваших служб и веб-приложений.

### **В чем разница между OIDC и OAuth?**

OIDC или OpenID Connect (OIDC) — это протокол аутентификации. Это набор спецификаций, основанный на OAuth 2.0, который добавляет дополнительные функции. По сути, OIDC — это аутентичный протокол, а OAuth — набор спецификаций для доступа к ресурсам и их совместного использования.

### Существуют ли другие (более частные) альтернативы Google OAuth?

Да.  [Authelia](https://github.com/authelia/authelia)  и [Keycloak](https://github.com/keycloak/keycloak)  – два, о которых я могу вспомнить. ИМХО, Authelia была намного проще в настройке, чем Keycloak. Существует также  [Authentik](https://goauthentik.io/).