201 lines
7.3 KiB
Markdown
201 lines
7.3 KiB
Markdown
Создание локального плагина для Traefik: Перенос куки jwt_a в заголовок Authorization: Bearer
|
||
Этот документ описывает, как создать и настроить локальный плагин для Traefik, который извлекает значение куки jwt_a и устанавливает его в заголовок Authorization: Bearer <token>, аналогично правилу HAProxy:
|
||
acl is_jwt_cookie hdr_sub(cookie) jwt_a=
|
||
http-request set-header Authorization "Bearer %[cook(jwt_a)]" if is_jwt_cookie
|
||
|
||
Плагин будет работать локально без публикации на GitHub.
|
||
📋 Требования
|
||
|
||
Go: Версия 1.21 или выше.
|
||
Traefik: Версия 3.3.4 (или совместимая).
|
||
Linux Mint/Ubuntu: ОС, на которой установлен Traefik.
|
||
Права доступа: Пользователь с правами на изменение конфигурации Traefik и запуск сервисов.
|
||
|
||
📥 Шаг 1: Подготовка окружения
|
||
|
||
Проверьте, установлен ли Go:
|
||
go version
|
||
|
||
Если Go не установлен, установите его:
|
||
sudo apt update
|
||
sudo apt install golang
|
||
|
||
|
||
Убедитесь, что Traefik установлен и работает. Проверьте версию:
|
||
traefik version
|
||
|
||
|
||
|
||
📂 Шаг 2: Создание плагина
|
||
|
||
Создайте директорию для плагина:
|
||
mkdir -p ~/traefik-jwt-cookie-plugin
|
||
cd ~/traefik-jwt-cookie-plugin
|
||
|
||
|
||
Инициализируйте Go-модуль:
|
||
go mod init traefik-jwt-cookie-plugin
|
||
|
||
|
||
Создайте файл plugin.go с кодом плагина:
|
||
package traefik_jwt_cookie_plugin
|
||
|
||
import (
|
||
"context"
|
||
"net/http"
|
||
)
|
||
|
||
// Config holds the plugin configuration.
|
||
type Config struct {
|
||
CookieName string `json:"cookieName"`
|
||
}
|
||
|
||
// CreateConfig creates and initializes the plugin configuration.
|
||
func CreateConfig() *Config {
|
||
return &Config{
|
||
CookieName: "jwt_a", // Имя куки по умолчанию
|
||
}
|
||
}
|
||
|
||
// JWTCookiePlugin is the plugin structure.
|
||
type JWTCookiePlugin struct {
|
||
next http.Handler
|
||
name string
|
||
cookieName string
|
||
}
|
||
|
||
// New creates a new instance of the plugin.
|
||
func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
|
||
return &JWTCookiePlugin{
|
||
next: next,
|
||
name: name,
|
||
cookieName: config.CookieName,
|
||
}, nil
|
||
}
|
||
|
||
func (p *JWTCookiePlugin) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||
// Извлекаем куки
|
||
cookie, err := req.Cookie(p.cookieName)
|
||
if err == nil && cookie != nil && cookie.Value != "" {
|
||
// Устанавливаем заголовок Authorization
|
||
req.Header.Set("Authorization", "Bearer "+cookie.Value)
|
||
}
|
||
// Передаем запрос дальше
|
||
p.next.ServeHTTP(rw, req)
|
||
}
|
||
|
||
|
||
Создайте файл go.mod (создается автоматически при инициализации модуля):
|
||
module traefik-jwt-cookie-plugin
|
||
|
||
go 1.21
|
||
|
||
|
||
Создайте файл plugin.yaml:
|
||
moduleName: traefik-jwt-cookie-plugin
|
||
displayName: JWT Cookie to Authorization Header
|
||
summary: Middleware to extract a cookie and set it as Authorization Bearer header
|
||
|
||
|
||
|
||
⚙️ Шаг 3: Настройка Traefik для локального плагина
|
||
|
||
Отредактируйте файл конфигурации Traefik (/etc/traefik/traefik.yml):
|
||
experimental:
|
||
localPlugins:
|
||
jwtCookiePlugin:
|
||
moduleName: traefik-jwt-cookie-plugin
|
||
sourcePath: /home/igor/traefik-jwt-cookie-plugin # Замените на ваш путь
|
||
|
||
http:
|
||
routers:
|
||
my-router:
|
||
rule: "Host(`example.com`)" # Замените на ваш домен
|
||
service: my-service
|
||
middlewares:
|
||
- jwt-cookie-middleware
|
||
entryPoints:
|
||
- web
|
||
|
||
middlewares:
|
||
jwt-cookie-middleware:
|
||
plugin:
|
||
jwtCookiePlugin:
|
||
cookieName: "jwt_a"
|
||
|
||
services:
|
||
my-service:
|
||
loadBalancer:
|
||
servers:
|
||
- url: "http://backend:8080" # Ваш бэкенд-сервис
|
||
|
||
|
||
Убедитесь, что путь /home/igor/traefik-jwt-cookie-plugin соответствует вашей директории. Проверьте путь:
|
||
echo $HOME
|
||
|
||
|
||
|
||
🔒 Шаг 4: Настройка прав доступа
|
||
Убедитесь, что Traefik имеет доступ к директории плагина:
|
||
sudo chown -R igor:igor ~/traefik-jwt-cookie-plugin
|
||
sudo chmod -R 755 ~/traefik-jwt-cookie-plugin
|
||
|
||
Если Traefik работает от другого пользователя (например, traefik), выполните:
|
||
sudo chown -R traefik:traefik ~/traefik-jwt-cookie-plugin
|
||
|
||
🚀 Шаг 5: Запуск Traefik
|
||
|
||
Перезапустите Traefik:sudo systemctl restart traefik
|
||
|
||
|
||
Если Traefik запущен вручную:traefik --configFile=/etc/traefik/traefik.yml
|
||
|
||
|
||
|
||
🧪 Шаг 6: Тестирование
|
||
|
||
Включите дебаг-логи в traefik.yml:log:
|
||
level: DEBUG
|
||
|
||
|
||
Отправьте тестовый запрос с куки jwt_a:curl -H "Host: example.com" -b "jwt_a=your_jwt_token_here" http://192.168.200.85
|
||
|
||
|
||
Проверьте логи Traefik:sudo journalctl -u traefik
|
||
|
||
Ищите записи, связанные с jwtCookiePlugin, чтобы подтвердить, что куки обрабатываются.
|
||
|
||
🌐 Шаг 7: Интеграция с HAProxy
|
||
Поскольку вы используете HAProxy перед Traefik, убедитесь, что HAProxy передает куки без изменений. Если вы хотите перенести логику обработки куки из HAProxy в Traefik, удалите следующее правило из HAProxy:
|
||
acl is_jwt_cookie hdr_sub(cookie) jwt_a=
|
||
http-request set-header Authorization "Bearer %[cook(jwt_a)]" if is_jwt_cookie
|
||
|
||
Обновленная конфигурация HAProxy:
|
||
frontend fe_main
|
||
bind *:80
|
||
mode http
|
||
default_backend be_traefik
|
||
|
||
backend be_traefik
|
||
mode http
|
||
server traefik 192.168.200.85:80
|
||
|
||
⚠️ Возможные проблемы
|
||
|
||
Ошибка загрузки плагина: Проверьте логи Traefik (journalctl -u traefik) и убедитесь, что sourcePath указан правильно.
|
||
Куки не извлекаются: Убедитесь, что куки jwt_a передаются в запросе (проверьте через curl или браузер).
|
||
Go-ошибки: Выполните go mod tidy для установки зависимостей.
|
||
|
||
✅ Преимущества
|
||
|
||
Работает локально без публикации на GitHub.
|
||
Заменяет функциональность HAProxy без внешнего сервиса.
|
||
Полная интеграция с Traefik.
|
||
|
||
❗ Недостатки
|
||
|
||
Требует базовых навыков Go.
|
||
Экспериментальная поддержка плагинов в Traefik может быть нестабильной.
|
||
|
||
🔄 Альтернатива
|
||
Если плагин не работает, оставьте обработку куки в HAProxy, а Traefik используйте только для маршрутизации. Это минимизирует изменения в вашей инфраструктуре. |