Files
UpdateHaproxyConfig/readme.md
T
2026-10-13 12:30:44 +00:00

296 lines
12 KiB
Markdown
Raw 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.
# Документация проекта: Развертывание конфигурации HAProxy по событию через systemd path
## 1. Архитектурное описание
Комплекс предназначен для мгновенного и контролируемого отката/применения резервной конфигурации балансировщика **HAProxy** по клику оператора с рабочей станции Windows.
Вместо периодического опроса через cron система использует событийную модель ядра Linux (**inotify**) через связку **systemd path** + **systemd service**, что обеспечивает нулевую задержку реакции и отсутствие холостых запусков скрипта.
```
[ Рабочая станция Windows ]
|
(Ярлык на рабочем столе)
|
deployfile.exe (.NET 4.8)
|
| (1. SSH-сессия: ed25519)
| (2. Запись status/change.me + status/sha256.hash)
v
[ Linux-сервер (HAProxy) ]
/var/lib/depfile/status/change.me
|
(Событие inotify: IN_CLOSE_WRITE)
v
depfile-watcher.path (systemd)
| (Активирует однократный сервис)
v
depfile-watcher.service (systemd: oneshot)
| (Запуск /usr/local/bin/deploy_haproxy.sh)
|
|-- 1. Валидация SHA-256 суммы файла change.me
|-- 2. Проверка синтаксиса backup/haproxy.cfg (haproxy -c)
|-- 3. Подмена боевого /etc/haproxy/haproxy.cfg
|-- 4. Перезапуск службы haproxy (systemctl restart)
|-- 5. Удаление директории status/
`-- 6. Запись отчета в deployment/success.me
```
---
## 2. Настройка Linux-сервера
### 2.1. Создание сервисного пользователя и рабочих каталогов
Подключитесь к серверу с правами `root` или через `sudo`:
```bash
# 1. Создаем системного пользователя с домашним каталогом /var/lib/depfile
sudo useradd -m -d /var/lib/depfile -s /bin/bash -c "File deploment service" depfile
# 2. Назначаем права доступа на домашний каталог
sudo chown -R depfile:depfile /var/lib/depfile
sudo chmod 750 /var/lib/depfile
# 3. Создаем каталог резервных конфигураций HAProxy и размещаем эталонный конфиг
sudo mkdir -p /etc/haproxy/backup
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/backup/haproxy.cfg
sudo chown -R root:root /etc/haproxy/backup
sudo chmod 750 /etc/haproxy/backup
```
### 2.2. Подготовка каталога SSH-ключей
Домашняя директория пользователя — `/var/lib/depfile`, путь к файлу доверенных ключей: `/var/lib/depfile/.ssh/authorized_keys`.
```bash
sudo -u depfile mkdir -p /var/lib/depfile/.ssh
sudo -u depfile touch /var/lib/depfile/.ssh/authorized_keys
sudo chmod 700 /var/lib/depfile/.ssh
sudo chmod 600 /var/lib/depfile/.ssh/authorized_keys
```
### 2.3. Размещение скрипта развертывания
Скопируйте скрипт из репозитория в каталог `/usr/local/bin/`:
* Исходный файл: [`deploy_haproxy.sh`](deploy_haproxy.sh)
```bash
sudo cp deploy_haproxy.sh /usr/local/bin/deploy_haproxy.sh
sudo chmod +x /usr/local/bin/deploy_haproxy.sh
```
---
### 2.4. Настройка связки systemd (Path + Service)
#### Шаг 1: Юнит сервиса (`depfile-watcher.service`)
Создайте файл описания процесса:
```bash
sudo nano /etc/systemd/system/depfile-watcher.service
```
```ini
[Unit]
Description=HAProxy Config Rollback Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/deploy_haproxy.sh
StandardOutput=journal
StandardError=journal
```
#### Шаг 2: Юнит отслеживания файловой системы (`depfile-watcher.path`)
Создайте файл монитора событий:
```bash
sudo nano /etc/systemd/system/depfile-watcher.path
```
```ini
[Unit]
Description=Watch for deployment trigger file change.me
[Path]
# PathChanged срабатывает в момент завершения записи и закрытия дескриптора (IN_CLOSE_WRITE)
PathChanged=/var/lib/depfile/status/change.me
Unit=depfile-watcher.service
[Install]
WantedBy=multi-user.target
```
#### Шаг 3: Активация и запуск монитора
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now depfile-watcher.path
```
Проверьте статус наблюдателя:
```bash
systemctl status depfile-watcher.path
```
*(Должен находиться в состоянии `active (waiting)`).*
---
## 3. Настройка рабочей станции Windows
### 3.1. Генерация SSH-ключа
В командной строке (`cmd`) или PowerShell выполните:
```cmd
ssh-keygen -t ed25519 -f "D:\sys\C-Sharp\deployfile\key\test_key.key" -N ""
```
Будут созданы:
* `test_key.key` — приватный ключ (хранится строго на рабочей станции).
* `test_key.key.pub` — открытый ключ.
### 3.2. Экспорт открытого ключа на сервер
Выполните команду передачи публичного ключа (потребуется однократный ввод пароля `depfile`):
```powershell
type "D:\sys\C-Sharp\deployfile\key\test_key.key.pub" | ssh depfile@10.228.48.110 "cat >> /var/lib/depfile/.ssh/authorized_keys"
```
Проверьте вход по ключу:
```cmd
ssh -i "D:\sys\C-Sharp\deployfile\key\test_key.key" depfile@10.228.48.110 "whoami && pwd"
```
Ожидаемый ответ:
```text
depfile
/var/lib/depfile
```
---
## 4. Настройка безопасности и разграничения прав
### 4.1. Безопасность приватного ключа на рабочей станции (Windows NTFS)
Встроенный клиент Windows OpenSSH (`ssh.exe`) проверяет списки управления доступом (ACL) NTFS. Если к файлу ключа или каталогу имеют доступ сторонние группы (`Users`, `Everyone`), SSH прерывает выполнение с ошибкой `Permissions for '...' are too open`.
Выполните команду ограничения прав доступа в командной строке:
```cmd
:: 1. Отключаем наследование разрешений родительской папки для файла ключа
icacls "D:\sys\C-Sharp\deployfile\key\test_key.key" /inheritance:r
:: 2. Выдаем полный доступ только текущему пользователю и учетной записи SYSTEM
icacls "D:\sys\C-Sharp\deployfile\key\test_key.key" /grant:r "%USERNAME%:F"
icacls "D:\sys\C-Sharp\deployfile\key\test_key.key" /grant:r "SYSTEM:F"
```
*Для защиты всей папки `key`:*
```cmd
icacls "D:\sys\C-Sharp\deployfile\key" /inheritance:r
icacls "D:\sys\C-Sharp\deployfile\key" /grant:r "%USERNAME%:(OI)(CI)F"
icacls "D:\sys\C-Sharp\deployfile\key" /grant:r "SYSTEM:(OI)(CI)F"
```
### 4.2. Безопасность на стороне Linux-сервера
1. **Разграничение прав на конфигурации:**
* Права `700` на `/var/lib/depfile/.ssh` и `600` на `authorized_keys` исключают несанкционированное чтение или подмену ключей.
* Директория `/etc/haproxy/backup` принадлежит `root:root` с правами `750`. Пользователь `depfile` **не имеет прав на запись и редактирование** в каталоге `/etc/haproxy/`, что делает невозможной прямую подмену боевого конфига или бэкапа из-под учетной записи развертывания.
2. **Ограничение SSH-сессии ключа:**
* В `/var/lib/depfile/.ssh/authorized_keys` перед публичным ключом рекомендуется добавить флаги запрета интерактивного окружения:
```text
no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC...
```
3. **Изоляция привилегий исполнения:**
* Пользователь `depfile` является бесправной учетной записью без доступа к `sudo`.
* Замену файлов конфигурации и перезапуск службы осуществляет служба `systemd` от имени `root` исключительно после успешной валидации контрольной суммы SHA-256 и проверки синтаксиса `haproxy -c`.
---
## 5. Клиентское приложение C# (.NET Framework 4.8)
### 5.1. Исходный код
* Исходный файл приложения: [`Program.cs`](Program.cs)
Утилита автономна, не требует сторонних NuGet-библиотек, работает со штатным `ssh.exe` Windows 10/11 и производит автоматическую установку OpenSSH Client через PowerShell при первом обнаружении его отсутствия.
### 5.2. Сборка и создание ярлыка на рабочем столе
1. В Visual Studio в свойствах проекта (**Build** / **Сборка**) установите платформу **x64** (или снимите флаг *Prefer 32-bit*).
2. Скомпилируйте проект в конфигурации **Release** (`D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe`).
3. Создайте ярлык на рабочем столе:
* **Объект:** `"D:\sys\C-Sharp\deployfile\bin\Release\deployfile.exe"`
* **Название:** `Откатить конфигурацию HAProxy`.
---
## 6. Проверка работы комплекса
1. Нажмите на ярлык на рабочем столе Windows.
2. В консоли отобразится успешный статус:
```text
Используется ключ: D:\sys\C-Sharp\deployfile\key\test_key.key
Подключение к depfile@10.228.48.110:22...
Файл status/change.me и хеш status/sha256.hash успешно созданы на сервере.
```
3. Проверьте журнал выполнения сервиса на сервере (запуск происходит моментально по факту закрытия файла):
```bash
sudo journalctl -u depfile-watcher.service -n 25 --no-pager
```
4. Убедитесь в результатах развертывания:
* Каталог `/var/lib/depfile/status` удален.
* Конфигурация `/etc/haproxy/haproxy.cfg` обновлена из бэкапа.
* Служба активна: `systemctl status haproxy`.
* Метка времени зафиксирована в `/var/lib/depfile/deployment/success.me`:
```bash
cat /var/lib/depfile/deployment/success.me
```