206 lines
10 KiB
Markdown
206 lines
10 KiB
Markdown
# План реализации изменений для reverse proxy
|
||
|
||
## Обзор проекта
|
||
|
||
Проект `acme-reverseproxy` — это reverse proxy с автоматическим получением TLS-сертификатов через ACME/LetsEncrypt (autocert). Текущая реализация:
|
||
- Проксирует HTTP-запросы на бэкенд-серверы
|
||
- Обрабатывает /.well-known/acme-challenge через локальную файловую систему
|
||
- Использует autocert для HTTPS на входящих запросах
|
||
|
||
## Требования
|
||
|
||
1. **Поддержка HTTPS для бэкенд-серверов** — прозрачная работа как с HTTP, так и с HTTPS бэкендами
|
||
2. **NFS для /.well-known** — подключение к NFS-серверу для хранения ACME-файлов
|
||
3. **Конфигурация NFS** — параметры NFS указываются в конфиге
|
||
4. **Авто-подключение NFS** — автоматическое монтирование и контроль с переподключением
|
||
|
||
## Архитектурные решения
|
||
|
||
### 1. HTTPS для бэкендов (выбран вариант A)
|
||
|
||
**Решение:** Автоматическое определение по схеме в конфиге (http:// vs https://)
|
||
|
||
**Реализация:**
|
||
- `httputil.NewSingleHostReverseProxy` уже поддерживает HTTPS через `url.Parse`
|
||
- Необходимо добавить настройку `Transport` с поддержкой TLS для HTTPS-бэкендов
|
||
- Для HTTP-бэкендов использовать стандартный транспорт
|
||
- Для HTTPS-бэкендов создать `http.Transport` с `TLSClientConfig`
|
||
|
||
**Изменения в коде:**
|
||
- `proxymap/proxymap.go`: модифицировать `ToReverseProxyMap` для настройки транспорта
|
||
- Добавить проверку схемы URL и соответствующую настройку транспорта
|
||
|
||
### 2. NFS конфигурация (выбран вариант B)
|
||
|
||
**Решение:** Отдельные поля в конфиге: server, export_path, mount_point
|
||
|
||
**Структура конфигурации:**
|
||
```toml
|
||
[nfs]
|
||
enabled = true
|
||
server = "192.168.1.100"
|
||
export_path = "/export/acme"
|
||
mount_point = "/mnt/acme-wellknown"
|
||
options = "rw,vers=4.1,timeo=50,retrans=2"
|
||
```
|
||
|
||
**Изменения в коде:**
|
||
- `config/config.go`: добавить структуру `NFSConfig`
|
||
- `my-config.yaml` (или .toml): добавить секцию `[nfs]`
|
||
|
||
### 3. Монтирование NFS (выбран вариант B)
|
||
|
||
**Решение:** Использовать FUSE без root-прав
|
||
|
||
**Библиотеки:**
|
||
- `github.com/willscott/go-nfs-client` или
|
||
- `github.com/anacrolix/fuse` с NFS-поддержкой
|
||
|
||
**Альтернатива:** Если FUSE не подходит, рассмотреть:
|
||
- Системное монтирование через `exec.Command("mount", ...)` с проверкой прав
|
||
- Или предположить, что NFS уже смонтирован, но делать контроль
|
||
|
||
**Рекомендация:** Использовать системное монтирование с проверкой прав, так как:
|
||
- FUSE для NFS сложен в реализации
|
||
- Reverse proxy обычно запускается с привилегиями
|
||
- Системное монтирование надежнее
|
||
|
||
**Изменения:**
|
||
- Создать новый пакет `nfs` или добавить в существующий
|
||
- Реализовать функции: `Mount()`, `Unmount()`, `IsMounted()`, `CheckHealth()`
|
||
|
||
### 4. Контроль доступности NFS (выбран вариант A)
|
||
|
||
**Решение:** Проверка при каждом запросе к /.well-known
|
||
|
||
**Реализация:**
|
||
- Перед обработкой запроса к /.well-known проверять доступность mount point
|
||
- При недоступности — попытка перемонтировать
|
||
- Логирование всех событий монтирования/размонтирования
|
||
|
||
**Изменения:**
|
||
- `proxymap/proxymap.go`: модифицировать `handleWellKnown` для проверки NFS
|
||
- Добавить механизм retry с экспоненциальной задержкой
|
||
|
||
## План работ
|
||
|
||
### Этап 1: Конфигурация
|
||
|
||
1. **Расширить структуру Config** (`config/config.go`)
|
||
- Добавить поле `NFS NFSConfig`
|
||
- Создать структуру `NFSConfig` с полями:
|
||
- `Enabled bool`
|
||
- `Server string`
|
||
- `ExportPath string`
|
||
- `MountPoint string`
|
||
- `Options string` (опционально)
|
||
|
||
2. **Обновить пример конфигурации** (`GenConfigAction` в `main.go`)
|
||
- Добавить секцию NFS в генерируемый конфиг
|
||
- По умолчанию `enabled = false`
|
||
|
||
### Этап 2: Поддержка HTTPS для бэкендов
|
||
|
||
3. **Модифицировать `ToReverseProxyMap`** (`proxymap/proxymap.go`)
|
||
- Проверить схему URL бэкенда
|
||
- Для HTTPS создать `http.Transport` с `TLSClientConfig`
|
||
- Для HTTP использовать стандартный транспорт
|
||
- Настроить `proxy.Transport`
|
||
|
||
4. **Добавить логирование**
|
||
- Логировать тип подключения к бэкенду (HTTP/HTTPS)
|
||
- Логировать ошибки TLS-рукопожатия
|
||
|
||
### Этап 3: NFS монтирование
|
||
|
||
5. **Создать пакет для работы с NFS** (`nfs/nfs.go`)
|
||
- Функция `Mount(server, export, mountpoint, options) error`
|
||
- Функция `Unmount(mountpoint) error`
|
||
- Функция `IsMounted(mountpoint) bool`
|
||
- Функция `CheckHealth(mountpoint) error`
|
||
- Использовать `exec.Command` для системных вызовов mount/umount
|
||
|
||
6. **Добавить контроль прав**
|
||
- Проверка, что процесс имеет права на монтирование
|
||
- Обработка ошибок без прав с понятным сообщением
|
||
|
||
### Этап 4: Интеграция NFS в обработку /.well-known
|
||
|
||
7. **Модифицировать `handleWellKnown`** (`proxymap/proxymap.go`)
|
||
- Перед обработкой запроса проверять `nfs.IsMounted()`
|
||
- При размонтировании — попытка `nfs.Mount()`
|
||
- Добавить retry-логику с задержкой
|
||
|
||
8. **Добавить глобальный менеджер NFS**
|
||
- Создать singleton для управления NFS
|
||
- Избегать множественных попыток монтирования
|
||
- Синхронизация через `sync.Mutex` или `sync.Once`
|
||
|
||
### Этап 5: Тестирование и документация
|
||
|
||
9. **Добавить тесты**
|
||
- Тесты для HTTPS-бэкендов
|
||
- Тесты для NFS монтирования (mock)
|
||
- Тесты для обработки ошибок
|
||
|
||
10. **Обновить документацию**
|
||
- README.md: добавить секцию по NFS
|
||
- Пример конфигурации с NFS
|
||
- Требования к правам доступа
|
||
|
||
## Файлы для изменения
|
||
|
||
### Существующие файлы:
|
||
- `config/config.go` — расширение структуры Config
|
||
- `proxymap/proxymap.go` — HTTPS бэкенды и NFS интеграция
|
||
- `main.go` — инициализация NFS при старте
|
||
|
||
### Новые файлы:
|
||
- `nfs/nfs.go` — работа с NFS монтированием
|
||
- `nfs/nfs_test.go` — тесты для NFS
|
||
|
||
## Риски и ограничения
|
||
|
||
### Риски:
|
||
1. **Права доступа** — монтирование NFS требует root-прав
|
||
- Решение: Запускать как сервис с systemd или с sudo
|
||
- Альтернатива: Предварительное монтирование вручную
|
||
|
||
2. **Сетевые проблемы** — разрыв NFS может привести к зависанию
|
||
- Решение: Настройка `timeo` и `retrans` в опциях mount
|
||
- Мониторинг доступности с автоматическим переподключением
|
||
|
||
3. **Безопасность** — NFS может быть уязвим
|
||
- Решение: Использовать NFSv4 с Kerberos аутентификацией
|
||
- Ограничить доступ по IP через firewall
|
||
|
||
### Ограничения:
|
||
1. **Платформа** — монтирование NFS работает только на Unix-системах
|
||
- На Windows потребуется альтернативное решение
|
||
|
||
2. **Производительность** — проверка при каждом запросе может замедлить работу
|
||
- Кэширование результата проверки
|
||
- Асинхронная проверка в фоне
|
||
|
||
## Рекомендуемый порядок реализации
|
||
|
||
1. **Сначала HTTPS для бэкендов** — проще, меньше рисков
|
||
2. **Затем NFS конфигурация** — подготовка структуры
|
||
3. **Потом NFS монтирование** — ядро функциональности
|
||
4. **Наконец интеграция** — объединение всего вместе
|
||
|
||
## Следующие шаги
|
||
|
||
После утверждения плана:
|
||
1. Делегировать реализацию HTTPS бэкендов агенту `golang`
|
||
2. Делегировать реализацию NFS агенту `golang`
|
||
3. Делегировать ревью изменений агенту `reviewer`
|
||
4. Провести тестирование и валидацию
|
||
|
||
## Примечания
|
||
|
||
- Все изменения должны быть обратно совместимы
|
||
- По умолчанию NFS отключен (`enabled = false`)
|
||
- По умолчанию бэкенды работают как раньше (HTTP)
|
||
- Логирование должно быть подробным в режиме debug
|