Hope Mail Server — Развёртывание
Руководство по установке и промышленной эксплуатации HopeDB на сервере Linux (рекомендуется отечественная ОС: Astra Linux, РЕД ОС, ALT). Сборка описана в .
1. Требования
Аппаратно (старт): 2 vCPU, 4 ГБ ОЗУ, SSD; далее — по числу ящиков и объёму почты. Диск закладывайте с запасом: тела писем хранятся на ФС, компакция WAL пока ручная (через бэкап/пересоздание).
Программно: - Linux x86-64 (Astra Linux / РЕД ОС / ALT / Ubuntu); - для сборки — Rust (stable) + Cargo, Node.js 18+ и npm; - веб-сервер для статики и TLS-терминации (nginx/Angie); - доступ к DNS-зоне домена (MX, A/AAAA, PTR).
2. Сетевые порты
| Порт | Сервис | Переменная | Назначение |
|---|---|---|---|
| 25 | SMTP (входящий) | HOPE_SMTP_PORT |
приём внешней почты |
| 587 | Submission (STARTTLS+AUTH) | HOPE_SUBMISSION_PORT |
отправка почты клиентами |
| 143 | IMAP (STARTTLS) | HOPE_IMAP_PORT |
доступ клиентов к ящикам |
| 110 | POP3 (STLS) | HOPE_POP3_PORT |
простой доступ к «Входящим» |
| 8090 | CalDAV/CardDAV (HTTPS по умолчанию) | HOPE_DAV_PORT / HOPE_DAV_TLS |
синхронизация календаря/контактов |
| 8092 | ActiveSync/EAS (HTTPS по умолчанию) | HOPE_EAS_PORT / HOPE_EAS_TLS |
«родная» мобильная почта |
| 8443* | Админка + API (axum, HTTPS по умолчанию) | HOPE_API_PORT / HOPE_API_TLS |
GUI админки и REST API (встроены в бинарь) |
| 443 | Веб-почта + API (HTTPS) | HOPE_MAIL_HTTP_PORT |
GUI веб-почты и REST API того же origin (встроены в бинарь) |
* Порт API соответствует адресу, на который настроен веб-клиент (VITE_API_URL, по умолчанию https://localhost:8443). Начиная с этой версии, REST API, CalDAV/CardDAV и ActiveSync по умолчанию поднимаются по HTTPS (тем же сертификатом, что и почтовые протоколы). Если API стоит за обратным прокси с TLS-терминацией на loopback, встроенный TLS API можно отключить переменной HOPE_API_TLS=0 (см. §3 и §6).
Откройте в межсетевом экране только нужное: 25 (если сервер принимает внешнюю почту напрямую; иначе приём идёт через Hope MSG Gateway), 587/143/110 для клиентов, 443 для веб/API, 8090 (или проксируйте DAV через 443).
3. Переменные окружения
| Переменная | По умолчанию | Описание |
|---|---|---|
DB_DATA_DIR |
./hopedb_data |
каталог WAL и JSON-состояния |
BLOB_DATA_DIR |
./hopedb_blobs |
каталог тел писем |
HOPE_SMTP_PORT |
25 |
входящий SMTP |
HOPE_SUBMISSION_PORT |
587 |
submission |
HOPE_IMAP_PORT |
143 |
IMAP |
HOPE_IMAP_IDLE_SECS |
60 |
фолбэк-опрос при IMAP IDLE, сек (новая почта приходит событийно; опрос — страховка) |
HOPE_POP3_PORT |
110 |
POP3 |
HOPE_DAV_PORT |
8090 |
CalDAV/CardDAV |
HOPE_DAV_TLS |
1 (вкл) |
HTTPS для DAV; отключить: 0/false/off/no (например, за TLS-прокси на loopback) |
HOPE_EAS_PORT |
8092 |
ActiveSync (EAS), путь /Microsoft-Server-ActiveSync |
HOPE_EAS_TLS |
1 (вкл) |
HTTPS для EAS; отключить: 0/false/off/no |
HOPE_EAS_HEARTBEAT_SECS |
600 |
таймаут Ping (heartbeat) для EAS, сек |
HOPE_PUBLIC_HOST |
(нет) | публичное имя почтового сервера для автонастройки (Autodiscover/Autoconfig). Если не задано — используется mail.<домен> |
Безопасность (все значения — безопасны по умолчанию)
| Переменная | По умолчанию | Описание |
|---|---|---|
HOPE_API_TLS |
1 (вкл) |
HTTPS для REST API и GUI. Отключить (0/false/off/no) только за TLS-терминирующим прокси на loopback |
HOPE_API_PORT |
8443 |
Порт админки + API (единый бинарник отдаёт здесь GUI админки и REST API) |
HOPE_MAIL_HTTP_PORT |
443 |
Порт веб-почты + API (тот же бинарник отдаёт здесь GUI почты; API того же origin). Порт <1024 требует root/CAP_NET_BIND_SERVICE |
HOPE_JWT_SECRET |
(нет) | Секрет подписи JWT. Если не задан — генерируется криптостойкий случайный секрет и сохраняется в DB_DATA_DIR/jwt_secret.key. Обязательно задайте один общий секрет на всех узлах кластера |
HOPE_CORS_ORIGINS |
(нет) | Список разрешённых Origin через запятую (напр. https://mail.example.com,https://admin.example.com). Если не задан — CORS разрешён только для localhost/127.0.0.1. Раньше по умолчанию был * (любой источник) |
HOPE_LDAP_INSECURE_TLS |
0 (проверка вкл) |
1 — отключить проверку TLS-сертификата AD/LDAP (и LDAPS HopeDC). Небезопасно; только для внутреннего AD с самоподписанным сертификатом на изолированном стенде |
HOPE_DC_INSECURE_HTTP |
0 (запрет) |
1 — разрешить отправку учётных данных на удалённый контроллер домена HopeDC по HTTP. Небезопасно; по умолчанию удалённый http:// запрещён (loopback и https:// разрешены всегда) |
HOPE_DC_INSECURE_LDAP |
0 (запрет) |
1 — разрешить проверку паролей через удалённый HopeDC по LDAP без TLS (ldap://). Небезопасно: пароль идёт открытым текстом. По умолчанию разрешены только ldaps:// и loopback. |
HOPE_EWS_INSECURE_HTTP |
0 (запрет) |
1 — разрешить подключение к EWS Exchange по http:// (переход с Exchange). Небезопасно: учётные данные сервисной учётки идут без шифрования. По умолчанию разрешены https:// и loopback. |
HOPE_INTERNAL_TOKEN |
(нет) | Общий секрет для приёма почты от Hope MSG Gateway (/internal/messages/receive). Без него приём от шлюза отключён (fail-closed): раньше эндпоинт принимал любой запрос и позволял впрыснуть письмо в любой ящик. Задайте одинаковое значение здесь и в шлюзе |
HOPE_ADMIN_RESET |
(нет) | Аварийный сброс/создание учётной записи admin с указанным паролем при старте. Задавать временно; снимите переменную после входа, иначе пароль будет сбрасываться при каждом запуске |
HOPE_MAIL_TRUSTED_PROXIES |
127.0.0.1,::1 |
Доверенные обратные прокси (адреса или подсети через запятую). Только от них учитываются заголовки X-Real-IP / X-Forwarded-For — для белых списков IP панели и журналов. Прокси должен передавать адрес клиента (см. п. 6) |
HOPE_MAIL_EULA_ACCEPTED |
(нет) | 1 — считать лицензионное соглашение принятым (для автоматизированных стендов). На рабочих серверах соглашение принимает полный администратор в панели |
Задайте абсолютные пути к
DB_DATA_DIR/BLOB_DATA_DIRвне каталога сборки. Каталоги должны быть на диске с достаточным местом и включаться в резервное копирование.
Командная строка
Служба запускается без аргументов (так её запускает systemd). Допустимые аргументы:
| Команда | Что делает |
|---|---|
hope-mail-server --version |
номер выпуска: hope-mail-server 22 (semver=22.0.0) |
hope-mail-server --eula |
текст лицензионного соглашения без разметки, с редакцией и SHA‑256 |
hope-mail-server --help |
подсказка |
Любой другой аргумент печатает подсказку и завершает работу с кодом 2 — служба при этом не запускается (опечатка не поднимет второй экземпляр).
Скрипт install_mail.sh сохраняет текст соглашения в /usr/local/share/doc/hope-mail-server/EULA.txt (командой --eula); при обновлении из панели файл обновляется. Тот же файл EULA.txt лежит в комплекте поставки рядом с hope-mail-server.gz.
4. Установка (единый бинарник)
Фронтенд вшивается в бинарь (rust-embed): собранная статика админки и веб-почты
становится частью исполняемого файла. Поэтому один бинарь hopedb-server отдаёт и GUI,
и API — отдельный веб-сервер для статики не нужен. Важно: фронт собирается ДО бэкенда,
иначе встраивать будет нечего.
cd /opt/hope-mail/HOPE_MAIL_SERVER
# 1. Сначала фронт (npm workspaces: пакеты admin и client, общий @hopedb/shared-ui)
cd hopedb-web
npm ci # или npm install
npm run build -w client # → apps/client/dist (веб-почта)
npm run build -w admin # → apps/admin/dist (админка)
cd ..
# 2. Затем бэкенд — он вшивает apps/admin/dist и apps/client/dist в бинарь
cargo build -p hopedb-server --release
sudo install -m755 target/release/hopedb-server /usr/local/bin/hopedb-server
# 3. Каталоги данных
sudo mkdir -p /var/lib/hope/{data,blobs}
sudo chown -R hope:hope /var/lib/hope
Бинарь сам поднимает админку+API на HOPE_API_PORT (8443) и веб-почту+API на
HOPE_MAIL_HTTP_PORT (443), оба по HTTPS (встроенным сертификатом). Фронт обращается к
API того же origin (относительные пути /api/...) — адрес API прописывать не нужно.
Node/npm нужны только для сборки; в рантайме прода их не требуется — всё в одном бинаре. Раскладывать
distпод nginx больше не нужно (вариант с внешним веб-сервером — опционален, см. §6).
5. systemd-юнит
/etc/systemd/system/hopedb.service:
[Unit]
Description=Hope Mail Server
After=network.target
[Service]
User=hope
Group=hope
Environment=DB_DATA_DIR=/var/lib/hope/data
Environment=BLOB_DATA_DIR=/var/lib/hope/blobs
Environment=HOPE_DAV_TLS=1
# при необходимости переопределите порты
ExecStart=/usr/local/bin/hopedb-server
Restart=always
RestartSec=3
# порты <1024 (25/110/143/587) требуют привилегии:
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
sudo useradd -r -s /usr/sbin/nologin hope
sudo systemctl daemon-reload
sudo systemctl enable --now hopedb
journalctl -u hopedb -f
Порты ниже 1024 (25/110/143/587) требуют CAP_NET_BIND_SERVICE (как выше) либо запуск за прокси/перенаправление портов.
6. nginx: статика + прокси API/DAV + TLS
server {
listen 443 ssl http2;
server_name mail.company.ru;
ssl_certificate /etc/hope/tls/fullchain.pem;
ssl_certificate_key /etc/hope/tls/privkey.pem;
# Имя хоста и адрес клиента — для всех location ниже (см. п. 6.1).
# Внутри location не пишите свои proxy_set_header: тогда эти строки перестанут наследоваться.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
# Веб-почта
root /var/www/hope/client;
location / { try_files $uri /index.html; }
# Админка
location /admin/ {
alias /var/www/hope/admin/;
try_files $uri /admin/index.html;
}
# REST API
location /api/ { proxy_pass http://127.0.0.1:8443; }
# CalDAV/CardDAV (если не включён HOPE_DAV_TLS)
location /dav/ { proxy_pass http://127.0.0.1:8090; }
location /.well-known/caldav { proxy_pass http://127.0.0.1:8090; }
location /.well-known/carddav { proxy_pass http://127.0.0.1:8090; }
# Автонастройка клиентов (Autodiscover/Autoconfig) — на REST API
location /autodiscover/ { proxy_pass http://127.0.0.1:8443; }
location /Autodiscover/ { proxy_pass http://127.0.0.1:8443; }
location /AutoDiscover/ { proxy_pass http://127.0.0.1:8443; }
location = /mail/config-v1.1.xml { proxy_pass http://127.0.0.1:8443; }
location = /.well-known/autoconfig/mail/config-v1.1.xml { proxy_pass http://127.0.0.1:8443; }
location = /mobileconfig { proxy_pass http://127.0.0.1:8443; }
# ActiveSync (EAS) — на отдельный порт; долгий Ping требует большого таймаута
location /Microsoft-Server-ActiveSync {
proxy_pass http://127.0.0.1:8092;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
SPA-приложения используют BrowserRouter, поэтому обязателен try_files … /index.html.
Важно (HTTPS по умолчанию). REST API (8443), DAV (8090) и EAS (8092) теперь по умолчанию слушают HTTPS. Приведённый выше конфиг проксирует на них по
http://— выберите один из вариантов: - Рекомендуется: отключить встроенный TLS этих подсистем на loopback за nginx —HOPE_API_TLS=0,HOPE_DAV_TLS=0,HOPE_EAS_TLS=0(трафик остаётся внутри хоста, наружу TLS терминирует nginx). Тогдаproxy_pass http://127.0.0.1:…работает как есть. - Либо оставить их по HTTPS и проксировать поhttps://сproxy_ssl_verify off;(сертификат самоподписанный): напримерproxy_pass https://127.0.0.1:8443;+proxy_ssl_verify off;.Autodiscover/Autoconfig клиенты обращаются к специальным именам (
autodiscover.<домен>,autoconfig.<домен>) — заведите на нихserver_name(или отдельныеserver{}-блоки), проксирующие те же пути на127.0.0.1:8443. Публичное имя серверов в ответах задаётсяHOPE_PUBLIC_HOST(иначеmail.<домен>). Автонастройка отдаёт STARTTLS на 143/110/587 — нужен валидный TLS-сертификат почтовых протоколов.
6.1. Адрес клиента за прокси
Hope Mail должен знать настоящий адрес клиента: по нему работают белые списки IP («Настройки сервера → Сетевой доступ») и записи журналов. За обратным прокси сервер видит соединение от самого прокси, поэтому прокси обязан передавать адрес клиента в заголовке.
Что нужно в nginx. Строки на уровне server, как в примере выше:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
- Они должны действовать во всех
location, которые ведут на порт панели и API (8443) и на порт веб‑почты:/api/, автонастройка,/mobileconfigи другие. - Если в каком‑то
locationесть свойproxy_set_header(например,Host), nginx перестаёт наследовать строки изserver. Тогда повторите обе строки внутри этогоlocation. X-Forwarded-Forзадавайте именно$remote_addr, а не$proxy_add_x_forwarded_for: так заголовок перезаписывается, а не дополняет то, что прислал клиент.
Что будет без этих строк. Все запросы через nginx будут выглядеть как пришедшие с самого сервера (127.0.0.1). Такие запросы белые списки IP пропускают всегда, иначе нельзя было бы войти через SSH‑туннель. В итоге список не ограничит никого, кто заходит через nginx.
Прокси на другом сервере. Hope Mail учитывает эти заголовки только от доверенных прокси — по умолчанию от самого сервера (127.0.0.1 и ::1). От остальных адресов заголовки игнорируются, чтобы клиент не мог подставить чужой адрес. Если nginx, HAProxy или балансировщик стоит на отдельной машине, укажите его адрес или подсеть: HOPE_MAIL_TRUSTED_PROXIES=10.0.0.5 (несколько — через запятую). Для HAProxy включите option forwardfor.
Как проверить. Откройте панель через прокси с рабочего места: «Настройки сервера → Сетевой доступ». Под списком строка «Ваш адрес: …» должна показывать адрес рабочего места или его внешний адрес. Если там 127.0.0.1 или адрес прокси, заголовок не доходит до Hope Mail: проверьте proxy_set_header и HOPE_MAIL_TRUSTED_PROXIES.
7. TLS-сертификаты
Два уровня TLS:
1. Веб/API/DAV — сертификат на nginx (публичный УЦ или отечественный УЦ).
2. Почтовые протоколы (STARTTLS на 25/587/143/110) — сертификат внутри hopedb-server.
Загрузите сертификат почтовых протоколов через админку (раздел TLS): либо готовые PEM (сертификат + ключ), либо сгенерируйте CSR в админке, получите сертификат в УЦ и загрузите обратно. Применение — без перезапуска. Этот же сертификат используется для REST API (8443), DAV (8090) и EAS (8092) при включённом HTTPS (по умолчанию включён) — для мобильных клиентов нужен валидный сертификат УЦ.
Постоянный самоподписанный сертификат. Если свой сертификат не загружен, сервер генерирует самоподписанный один раз и сохраняет его в
DB_DATA_DIR(selfsigned_cert.pem/selfsigned_key.pem). Он переживает перезапуски — браузеру/клиентам не нужно заново доверять серту после каждого рестарта. Для продакшена загрузите сертификат от УЦ.
8. DNS
Для домена company.ru:
- A/AAAA — адрес почтового хоста (mail.company.ru).
- MX — mail.company.ru (или на Hope MSG Gateway, если он принимает внешнюю почту).
- PTR (обратная зона) — на имя хоста; важно для доставки наружу.
- SPF/DKIM/DMARC — настраиваются на почтовой границе (Hope MSG Gateway), не в HopeDB.
- Autodiscover/Autoconfig — для автонастройки клиентов добавьте A/CNAME на autodiscover.company.ru и autoconfig.company.ru → почтовый хост; по желанию SRV _autodiscover._tcp → mail.company.ru:443. Прокси должен отдавать пути автонастройки на REST API (см. §6).
Автообнаружение клиентов (Autodiscover/Autoconfig) реализовано: Outlook (POX autodiscover.xml), Thunderbird (Mozilla config-v1.1.xml), Apple Mail (профиль .mobileconfig). Клиенту достаточно ввести адрес и пароль; ручная настройка также описана в Веб‑почта и почтовые программы.
9. Первичная настройка
- Войдите в админку полным администратором и примите лицензионное соглашение (до этого разделы панели недоступны; почтовые службы работают).
- Создайте домен(ы) в админке (при мультитенантности — с изоляцией blob'ов).
- Загрузите TLS-сертификат почтовых протоколов.
- Настройте коннектор исходящей почты (smart host на Gateway или DNS/MX).
- Заведите ящики и выдайте пользователям адреса/пароли.
- Проверьте живым клиентом: отправку (587), приём (25), IMAP (143), CalDAV (8090).
10. Резервное копирование и восстановление
Состояние целиком — это DB_DATA_DIR + BLOB_DATA_DIR.
sudo systemctl stop hopedb # или используйте атомарный снапшот ФС/LVM
sudo tar czf /backup/hope-$(date +%F).tgz -C /var/lib/hope data blobs
sudo systemctl start hopedb
Восстановление — распаковать оба каталога на место и запустить сервис. Держите TLS-сертификаты и systemd-юнит в отдельной резервной копии.
11. Обновление
git pull
# фронт СНАЧАЛА (его dist вшивается в бинарь), затем бэкенд
cd hopedb-web && npm ci && npm run build -w client && npm run build -w admin && cd ..
cargo build -p hopedb-server --release
sudo install -m755 target/release/hopedb-server /usr/local/bin/hopedb-server
sudo systemctl restart hopedb
Формат WAL обратно совместим (есть legacy-варианты чтения). Перед крупным обновлением делайте бэкап.
12. Эксплуатационные заметки
- Мониторинг: следите за
journalctl -u hopedb, размеромDB_DATA_DIR/BLOB_DATA_DIR, состоянием очереди в админке. - Место на диске: удаление писем не освобождает WAL сразу (тумбстоны). Планируйте запас и периодическую переинициализацию из бэкапа до появления компакции.
- Гейтвей: внешний приём/отправку, антиспам и SPF/DKIM/DMARC ведёт Hope MSG Gateway; HopeDB связывается с ним через коннектор (smart host).
- Безопасность: закройте прямой доступ к порту API (8443) снаружи — только через nginx; ограничьте 25 источниками Gateway, если приём идёт через него. За nginx обязательно передавайте адрес клиента (
X-Real-IP, п. 6.1), иначе белые списки IP не работают для запросов через прокси. - Безопасные значения по умолчанию (см. §3 «Безопасность»): HTTPS для API/DAV/EAS включён; JWT-секрет генерируется и хранится на диске (для кластера задайте общий
HOPE_JWT_SECRET); CORS по умолчанию только дляlocalhost(для прода задайтеHOPE_CORS_ORIGINS); проверка TLS-сертификата AD/LDAP включена; учётные данные к удалённому HopeDC по HTTP запрещены; доставка в Gateway не откатывается на незашифрованное соединение при неудавшемся STARTTLS. Файлы-секреты вDB_DATA_DIR(jwt_secret.key,selfsigned_*.pem) включайте в резервную копию, но не в систему контроля версий.