2026-04-17 11:56:39 +07:00

206 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# План реализации изменений для 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