Files
reactive-mail-server/backend/src/main/resources/application.properties
T
jambotron α 165edf1a1e Безопасность, SMTP, очередь отправки, DKIM, деплой на Jambotron (Jambotron v0.2.3 75.1–75.3)
- SMTP-сервер переписан: разбор по строкам, AUTH PLAIN/LOGIN, нет открытого релея,
  MAIL FROM только свой после входа, 250 только после сохранения (иначе 451), лимит размера
- отправка наружу: очередь outbound_queue (V2) с повторами ~22 ч и уведомлением о недоставке;
  Jakarta Mail, режимы off / mx / smarthost, байты письма не меняются (DKIM)
- DKIM: подпись utils-mail-dkim, проверка Apache jDKIM; ключ PKCS#8, старый PKCS#1 читается
- права: письма, папки, вложения — только владельцу (было: любой по номеру); имена вложений без ../
- секреты без значений по умолчанию (DB_PASSWORD, JWT_SECRET), регистрация закрыта,
  admin123 и /api/simulate/receive — только профиль dev
- веб-клиент внутри jar (относительный /api), Dockerfile в 3 этапа, не root, health;
  docker-compose.jambotron.yml: секреты создаются при первом запуске, наружу только 8080
- gradle-wrapper.jar был в .gitignore — сборка не запускалась
- тесты: 26 (SMTP реальным клиентом и сокетом, GreenMail, DKIM подпись+проверка, очередь)

α
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 03:37:43 +01:00

72 lines
3.0 KiB
Properties

spring.application.name=mail-server
server.port=8080
# Secrets: environment variables, or files in a config tree (file name = variable name, e.g. /run/mail-secrets/DB_PASSWORD).
# No defaults — the server does not start without them (dev profile: application-dev.properties).
spring.config.import=optional:configtree:${MAILSERVER_SECRETS_DIR:/run/mail-secrets}/
# PostgreSQL: R2DBC for the app, JDBC for Flyway migrations
spring.r2dbc.url=r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:mailserver}
spring.r2dbc.username=${DB_USER:mail}
spring.r2dbc.password=${DB_PASSWORD}
spring.flyway.enabled=true
spring.flyway.url=jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:mailserver}
spring.flyway.user=${DB_USER:mail}
spring.flyway.password=${DB_PASSWORD}
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=true
jwt.secret=${JWT_SECRET}
# Mailboxes of these domains live here; catch-all: every message to any address goes into this one mailbox (mail trap)
mailserver.domains=${MAIL_DOMAINS:localhost}
mailserver.catch-all=${MAIL_CATCH_ALL:}
mailserver.registration.enabled=${MAIL_REGISTRATION:false}
mailserver.admin.email=${MAIL_ADMIN_EMAIL:}
mailserver.admin.password=${MAIL_ADMIN_PASSWORD:}
mailserver.cors.origins=${MAIL_CORS_ORIGINS:}
# Attachments
mailserver.attachments.dir=${MAIL_ATTACHMENTS_DIR:./attachments}
spring.webflux.multipart.max-file-size=10MB
spring.webflux.multipart.max-request-size=10MB
# SMTP server (incoming mail and submission). AUTH without TLS only in a closed network (docker network, VM)
mailserver.smtp.port=${SMTP_PORT:3025}
mailserver.smtp.hostname=${MAIL_HOSTNAME:localhost}
mailserver.smtp.auth-without-tls=${SMTP_AUTH_WITHOUT_TLS:false}
mailserver.smtp.max-message-bytes=26214400
# Outbound: off | mx (straight to recipients' MX, port 25) | smarthost (via a provider, e.g. Resend)
mailserver.outbound.mode=${OUTBOUND_MODE:off}
mailserver.outbound.host=${OUTBOUND_HOST:}
mailserver.outbound.port=${OUTBOUND_PORT:587}
mailserver.outbound.username=${OUTBOUND_USERNAME:}
mailserver.outbound.password=${OUTBOUND_PASSWORD:}
mailserver.outbound.tls=${OUTBOUND_TLS:starttls}
# IMAP — off: simplified, blocks the event loop (v0.2.3 75.2)
mailserver.imap.enabled=false
mailserver.imap.port=1143
mailserver.imap.hostname=localhost
# DKIM — signing of our mail; DNS record printed to the log at start
mailserver.dkim.enabled=${DKIM_ENABLED:true}
mailserver.dkim.domain=${DKIM_DOMAIN:localhost}
mailserver.dkim.selector=${DKIM_SELECTOR:mail}
mailserver.dkim.keys-dir=${DKIM_KEYS_DIR:./dkim-keys}
# SPF / DMARC for incoming mail
mailserver.spf.enabled=${SPF_ENABLED:true}
mailserver.spf.local-bypass=true
mailserver.dmarc.enabled=${DMARC_ENABLED:true}
mailserver.dmarc.local-bypass=true
# error responses carry the reason ("No such mailbox", "Sending outside is disabled") for the web client
server.error.include-message=always
management.endpoints.web.exposure.include=health
management.endpoint.health.show-details=never
logging.level.com.mailserver=INFO