← Документация Hope·Hope Mailhopedc.ru

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. Первичная настройка

  1. Войдите в админку полным администратором и примите лицензионное соглашение (до этого разделы панели недоступны; почтовые службы работают).
  2. Создайте домен(ы) в админке (при мультитенантности — с изоляцией blob'ов).
  3. Загрузите TLS-сертификат почтовых протоколов.
  4. Настройте коннектор исходящей почты (smart host на Gateway или DNS/MX).
  5. Заведите ящики и выдайте пользователям адреса/пароли.
  6. Проверьте живым клиентом: отправку (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) включайте в резервную копию, но не в систему контроля версий.