Поменял настройки актуальности clamav

This commit is contained in:
mi
2026-08-14 10:39:47 +03:00
parent 99605b1c77
commit 9eb8b2bc6e
11 changed files with 196 additions and 16 deletions
@@ -504,6 +504,36 @@ deployment/preflight.sh
новый монотонный номер и отдельные значения `--actor`/`--approved-by`; повторно
активировать старую версию нельзя. Alembic downgrade запрещён.
При обновлении ClamAV policy образ Message Safety должен содержать согласованные
seed и schema: seed `max_signature_age_hours=240`, schema maximum `720`
(30 дней). После обновления immutable image digest создайте новую config
version; существующую active version не редактируйте и не активируйте повторно:
```sh
NEXT_VERSION='<СЛЕДУЮЩИЙ_МОНОТОННЫЙ_НОМЕР>'
/usr/local/sbin/han-vm2-compose --profile ops pull \
message-safety-migrate
/usr/local/sbin/han-vm2-compose --profile ops run --rm \
--entrypoint message-safety-config message-safety-migrate \
validate /app/app/artifacts/seed-config.yaml
/usr/local/sbin/han-vm2-compose --profile ops run --rm \
--entrypoint message-safety-config message-safety-migrate \
create /app/app/artifacts/seed-config.yaml \
--version "$NEXT_VERSION" --actor '<OPERATOR>'
/usr/local/sbin/han-vm2-compose --profile ops run --rm \
--entrypoint message-safety-config message-safety-migrate \
activate --version "$NEXT_VERSION" --approved-by '<APPROVER>'
/usr/local/sbin/han-vm2-compose up -d --no-deps --force-recreate \
message-safety-api message-safety-worker
/usr/local/sbin/han-vm2-compose ps \
message-safety-api message-safety-worker clamd freshclam
unset NEXT_VERSION
```
Старый image, schema которого ограничивает поле значением `168`, нельзя
оставлять после активации значения `240`: сначала обновите
`MESSAGE_SAFETY_IMAGE` на новый digest и проверьте `config --quiet`.
### Gate 4 — конфигурация nginx до запуска
После выпуска public TLS в `/etc/letsencrypt` и материализации internal TLS
@@ -819,3 +849,69 @@ han-message-safety-mode mock --text-free false --file-free false
задокументируйте минимальные writable пути для сигнатур/runtime и
компенсируйте сетевыми и ресурсными лимитами. Egress к signature-CDN
получает только `freshclam`; `clamd` — нет.
# Gate 9 завершает техническую приёмку VM2, но не означает production cutover сервисов.
Дальнейший порядок:
1. Проверить автозапуск:
```sh
systemctl is-enabled \
docker.service \
han-chat-vm2-docker-firewall.service \
han-secrets-vm2.service \
han-processing.service \
certbot.timer
systemctl is-active \
docker.service \
han-chat-vm2-docker-firewall.service \
han-processing.service \
certbot.timer
/usr/local/sbin/han-vm2-compose ps
```
2. Провести reboot-gate. Только после проверки отдельного входа `admin` и доступа к консоли Selectel:
```sh
systemctl reboot
```
После переподключения повторить команды выше и кратко Gate 68: HTTPS, firewall, private Safety API.
3. Зафиксировать итог релиза:
```sh
/usr/local/sbin/han-vm2-compose config --images
/usr/local/sbin/han-vm2-compose ps
systemctl list-timers certbot.timer
journalctl --no-pager -u han-processing.service -u han-secrets-vm2.service
```
Сохранить версии образов, дату приёмки и результаты gates без значений секретов.
4. Настроить эксплуатационный мониторинг:
- container unhealthy/restart/OOM;
- срок TLS;
- возраст ClamAV signatures;
- OTEL queue/export errors;
- disk/RAM;
- активный MOCK mode;
- недоступность private Safety API.
5. Далее — отдельный controlled cutover Message Safety на VM1: private URL, internal CA, service token, API integration, rollback rehearsal и функциональные проверки.
6. `bitrix-sync` пока оставить:
```dotenv
BITRIX_SYNC_ENABLED=false
BITRIX_SYNC_MODE=disabled
```
Public allow-list — только `deny all;`. Включать Bitrix можно лишь после выполнения gates `module-07`: поля портала, webhooks, migrations, grants, backfill/watermark и rollback rehearsal.
Таким образом, ближайший шаг сейчас — reboot-gate и фиксация приёмки VM2. Затем переход к интеграции VM1, а не немедленное включение Bitrix.
@@ -50,7 +50,7 @@
},
"clamav": {
"type": "object", "additionalProperties": false, "required": ["scan_timeout_sec", "max_signature_age_hours"],
"properties": {"scan_timeout_sec": {"type": "integer", "minimum": 1, "maximum": 120}, "max_signature_age_hours": {"type": "integer", "minimum": 1, "maximum": 168}}
"properties": {"scan_timeout_sec": {"type": "integer", "minimum": 1, "maximum": 120}, "max_signature_age_hours": {"type": "integer", "minimum": 1, "maximum": 720}}
},
"file_policy": {
"type": "object", "additionalProperties": false, "required": ["enabled_mime_types", "max_size_bytes"],
@@ -23,7 +23,7 @@ link:
pipeline_timeout_sec: 2
clamav:
scan_timeout_sec: 45
max_signature_age_hours: 24
max_signature_age_hours: 240
file_policy:
enabled_mime_types:
[image/jpeg, image/png, image/webp, image/heic, image/heif, application/pdf]
@@ -7,6 +7,7 @@ from pathlib import Path
import pytest
import yaml
from jsonschema import ValidationError
from app.config import validate_config
from app.db import Base
@@ -34,6 +35,16 @@ def test_config_cross_field_and_manifest_subset(artifacts: Path) -> None:
validate_config(bad, artifacts)
def test_clamav_signature_age_policy_bounds(artifacts: Path) -> None:
document = seed(artifacts)
assert document["clamav"]["max_signature_age_hours"] == 240
document["clamav"]["max_signature_age_hours"] = 720
validate_config(document, artifacts)
document["clamav"]["max_signature_age_hours"] = 721
with pytest.raises(ValidationError):
validate_config(document, artifacts)
def test_normative_tables_are_in_service_schema() -> None:
expected = {
"safety_requests",