Files
reactive-mail-server/backend/src/main/resources/application.properties
T
Liosha84andClaude Opus 5.5 f9b929ac7a
continuous-integration/drone/pr Build is passing
Веб-почта по HTTPS на том же адресе: https://mail.jambocheck.com (порт 443)
HTTPS_PORT — второй Netty-сервер с тем же HttpHandler и тем же сертификатом, что SMTP/IMAP
(Let's Encrypt от acme, перечитывается при продлении). HSTS добавляет Spring Security.
docker-compose.public.yml: 443 → 8443. HTTP 8080 остаётся для прокси внутри сети.
Тесты: HttpsConfigTest, всего 74; живой запуск: /api/config по HTTPS, HSTS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 02:18:42 +01:00

102 lines
5.2 KiB
Properties

spring.application.name=mail-server
server.port=8080
# behind a proxy (Jambotron Caddy): take scheme/host from X-Forwarded-*, otherwise the browser's own
# domain looks like another origin to CORS and every API call with an Origin header gets 403
server.forward-headers-strategy=framework
# 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: mail to any address without its own mailbox here goes into this one mailbox (mail trap), nothing goes outside
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:}
# Who manages mailboxes (Settings → Mailboxes), comma separated; empty — the first mailbox (admin.email or admin@<first domain>)
mailserver.admins=${MAIL_ADMINS:}
# Generated passwords of created mailboxes (first admin, catch-all) are appended here (mode 600); empty — printed to the log once
mailserver.passwords-file=${MAIL_PASSWORDS_FILE:}
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
# TLS (75.1): STARTTLS on the SMTP port; implicit TLS on SMTPS_PORT (465) if set. Certificate: MAIL_TLS_CERT + MAIL_TLS_KEY
# (PEM, PKCS#8 key), otherwise a self-signed one created once in MAIL_TLS_DIR. MAIL_TLS=false — no TLS
mailserver.tls.enabled=${MAIL_TLS:true}
mailserver.tls.cert-file=${MAIL_TLS_CERT:}
mailserver.tls.key-file=${MAIL_TLS_KEY:}
mailserver.tls.dir=${MAIL_TLS_DIR:./tls}
# Web client + API over HTTPS with the same certificate (public compose: 8443 → 443); 0 — only plain HTTP (server.port)
mailserver.https.port=${HTTPS_PORT:0}
mailserver.smtps.port=${SMTPS_PORT:0}
# 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 (75.2): STARTTLS on IMAP_PORT, implicit TLS on IMAPS_PORT (993) if set; same certificate as SMTP.
# LOGIN only inside TLS unless IMAP_AUTH_WITHOUT_TLS=true (a closed network only)
mailserver.imap.enabled=${IMAP_ENABLED:true}
mailserver.imap.port=${IMAP_PORT:3143}
mailserver.imaps.port=${IMAPS_PORT:0}
mailserver.imap.auth-without-tls=${IMAP_AUTH_WITHOUT_TLS:false}
# 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
# Brute-force protection for SMTP AUTH, IMAP login, web login and password change (one counter for all of them):
# MAX_PER_IP wrong passwords from one IP within WINDOW → the IP is blocked for BLOCK (each next block twice as long,
# up to MAX_BLOCK); MAX_PER_ACCOUNT wrong passwords to one mailbox from any IPs → the mailbox is blocked for BLOCK,
# except for IPs that logged in to it before. TRUSTED_IPS (comma-separated) are never blocked by IP
mailserver.login-guard.enabled=${LOGIN_GUARD:true}
mailserver.login-guard.max-per-ip=${LOGIN_GUARD_MAX_PER_IP:10}
mailserver.login-guard.max-per-account=${LOGIN_GUARD_MAX_PER_ACCOUNT:20}
mailserver.login-guard.window=${LOGIN_GUARD_WINDOW:15m}
mailserver.login-guard.block=${LOGIN_GUARD_BLOCK:15m}
mailserver.login-guard.max-block=${LOGIN_GUARD_MAX_BLOCK:24h}
mailserver.login-guard.trusted-ips=${LOGIN_GUARD_TRUSTED_IPS:}