====== Nginx ======
Reverse proxy с терминацией HTTPS. Единственный компонент, слушающий публичные
интерфейсы: все остальные сервисы доступны только на ''127.0.0.1''.
Установлен **на хосте**, не в контейнере — отсюда ''proxy_pass'' на loopback-порты,
куда docker публикует контейнеры.
Версия: nginx/1.22.1 (пакет Debian).
===== Файлы =====
^ Путь ^ Назначение ^
| ''/etc/nginx/sites-enabled/default'' | единственный конфиг, три виртуальных хоста |
| ''/etc/nginx/conf.d/upload_size.conf'' | ''client_max_body_size 100M'' |
| ''/var/log/nginx/error.log'' | ошибки, в т.ч. отказы allow-листа |
| ''/var/log/nginx/access.log'' | запросы |
''client_max_body_size'' вынесен в drop-in, чтобы действовать глобально. Без него
загрузка медиа в вики крупнее 1 МБ отбивается с ''413''.
===== Виртуальные хосты =====
==== entrypoint.ve-playground.ai.zevgen.com ====
DokuWiki. Открыт всем.
* ''/'' → ''127.0.0.1:8080''
* Заголовки: ''X-Frame-Options: SAMEORIGIN'', ''X-Content-Type-Options'', HSTS
* ''proxy_hide_header X-Powered-By'' — скрывает версию PHP, которую отдаёт DokuWiki
* Пробрасывается ''Authorization'' — нужен для JSON-RPC под Basic Auth
==== api.ve-playground.ai.zevgen.com ====
Webhook Telegram-бота.
* ''/webhook'' → ''127.0.0.1:8443''
* Всё остальное → ''404''
Дополнительно порт 8443 планируется ограничить CIDR-диапазонами Telegram
(''91.108.4.0/22'', ''149.154.160.0/20'') на уровне цепочки ''DOCKER-USER'' в iptables —
на момент написания **не сделано**, см. [[tech:risks]].
==== mcp.ve-playground.ai.zevgen.com ====
ToolMesh. Два уровня доступа:
^ Location ^ Доступ ^ Зачем ^
| ''/authorize'', ''/token'' | все | OAuth 2.1 flow |
| ''/'' (включая ''/mcp'', ''/.well-known/'', ''/register'') | allow-лист | MCP-эндпоинт |
Allow-лист:
allow 160.79.104.0/21; # Anthropic IPv4
allow 2607:6bc0::/48; # Anthropic IPv6
allow 127.0.0.1;
allow ; # для mcp-remote, добавляются индивидуально
deny all;
Таймауты подняты до ''proxy_read_timeout 300s'' — агентные вызовы с цепочкой
инструментов идут долго.
Про необходимость добавлять IP сотрудников —
[[tech:connect#ограничение по ip]].
===== SSL =====
Один **SAN-сертификат** Let's Encrypt на все три домена. Лежит в каталоге первого
домена:
/etc/letsencrypt/live/entrypoint.ve-playground.ai.zevgen.com/
fullchain.pem
privkey.pem
Все три ''server''-блока ссылаются на **этот же** путь. Отдельных каталогов
''api...'' и ''mcp...'' не существует — при попытке указать их nginx не стартует
с ошибкой ''cannot load certificate ... No such file or directory''.
Автопродление — ''certbot.timer''. Управление сертификатом описано в
[[tech:server:host#ssl-сертификаты]].
===== Настройка с нуля =====
Порядок важен: финальный конфиг ссылается на сертификаты, которых до выпуска не
существует, и nginx с ним не запустится.
- Проверить, что A/AAAA-записи всех трёх поддоменов указывают на этот сервер
- Установить: ''apt install nginx certbot python3-certbot-nginx''
- Положить **временный** HTTP-only конфиг с ''server_name'' на все три домена и
''location /.well-known/acme-challenge/ { root /var/www/html; }''
- Выпустить сертификат: ''certbot --nginx -d entrypoint... -d api... -d mcp...''
- Заменить конфиг на финальный с тремя раздельными ''server''-блоками
- ''nginx -t && systemctl reload nginx''
Замечание по шагу 4: ''certbot --nginx'' правит тот конфиг, который видит. Если во
временном конфиге один ''server''-блок на три домена, certbot допишет в него SSL для
**одного** домена и добавит ''return 404'' в HTTP-блок. Поэтому финальный конфиг
пишется целиком заново, а не дописывается поверх.
[[tech:server|← Сервер]]