Proxy protocol | Stalwart Labs

**cat /root/stalwart/compose.yml**
version: '3.9'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    command:
      - '--api.dashboard=false'
      - '--accesslog=true'
      - '--accesslog.format=json'
      - '--providers.docker=true'
      - '--providers.docker.exposedbydefault=false'
      - '--providers.docker.network=traefik'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.websecure.address=:443'
      - '--entrypoints.web.http.redirections.entrypoint.to=websecure'
      - '--certificatesresolvers.letsencrypt.acme.tlschallenge=true'
      - '[email protected]'
      - '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'

      - '--entrypoints.smtpsecure.address=:465'
      - '--entrypoints.smtpsecure.proxyProtocol.trustedIPs=172.18.0.2,172.18.0.3'
      - '--entrypoints.imapsecure.address=:993'
      - '--entrypoints.imapsecure.proxyProtocol.trustedIPs=172.18.0.2,172.18.0.3'
    ports:
      - '80:80'
      - '443:443'
      - '465:465/tcp'
      - '993:993/tcp'
    volumes:
      - './letsencrypt:/letsencrypt'
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
    networks:
      - traefik
      - stalwart

  stalwart:
    image: stalwartlabs/mail-server:latest
    container_name: stalwart
    restart: always
    ports:
      - '25:25/tcp'
      - '8080:8080'
    volumes:
      - './data:/opt/stalwart-mail'
    labels:
      - traefik.enable=true
      # smtpsecure
      - traefik.tcp.routers.smtpsecure.rule=HostSNI(`mail.example.com`)
      - traefik.tcp.routers.smtpsecure.tls=true
      - traefik.tcp.routers.smtpsecure.tls.certresolver=letsencrypt
      - traefik.tcp.routers.smtpsecure.entrypoints=smtpsecure
      - traefik.tcp.routers.smtpsecure.service=smtp
      - traefik.tcp.services.smtp.loadbalancer.server.port=587
      - traefik.tcp.services.smtp.loadbalancer.proxyprotocol.version=2
      # imapsecure
      - traefik.tcp.routers.imapsecure.rule=HostSNI(`mail.example.com`)
      - traefik.tcp.routers.imapsecure.tls=true
      - traefik.tcp.routers.imapsecure.tls.certresolver=letsencrypt
      - traefik.tcp.routers.imapsecure.entrypoints=imapsecure
      - traefik.tcp.routers.imapsecure.service=imap
      - traefik.tcp.services.imap.loadbalancer.server.port=143
      - traefik.tcp.services.imap.loadbalancer.proxyprotocol.version=2
    depends_on:
      - traefik
    networks:
      - traefik
      - stalwart

networks:
  traefik:
    external: true
  stalwart:
    driver: bridge
    attachable: true
    internal: true
    driver_opts:
      com.docker.network.driver.mtu: 9000
docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
4c78d6603782   bridge              bridge    local
111847ce3e6f   host                host      local
523dacf20f3f   none                null      local
44e0c4b9fe7a   stalwart_stalwart   bridge    local
3f35f04aa071   traefik             bridge    local
**cat /root/stalwart/data/etc/config.toml**
authentication.fallback-admin.secret = "..."
authentication.fallback-admin.user = "admin"
directory.internal.store = "rocksdb"
directory.internal.type = "internal"
lookup.default.hostname = "mail.example.com"
server.http.hsts = false
server.http.permissive-cors = false
server.http.url = "protocol + '://' + key_get('default', 'hostname') + ':' + local_port"
server.http.use-x-forwarded = false
server.listener.http.bind = "[::]:8080"
server.listener.http.protocol = "http"
server.listener.https.bind = "[::]:443"
server.listener.https.protocol = "http"
server.listener.https.tls.implicit = true
server.listener.imap.bind = "[::]:143"
server.listener.imap.protocol = "imap"
server.listener.imap.proxy.override = false
server.listener.imap.socket.override = false
server.listener.imap.tls.implicit = false
server.listener.imap.tls.override = false
server.listener.imaptls.bind = "[::]:993"
server.listener.imaptls.protocol = "imap"
server.listener.imaptls.proxy.override = false
server.listener.imaptls.socket.override = false
server.listener.imaptls.tls.implicit = true
server.listener.imaptls.tls.override = false
server.listener.sieve.bind = "[::]:4190"
server.listener.sieve.protocol = "managesieve"
server.listener.sieve.proxy.override = false
server.listener.sieve.socket.override = false
server.listener.sieve.tls.implicit = true
server.listener.sieve.tls.override = false
server.listener.smtp.bind = "[::]:25"
server.listener.smtp.protocol = "smtp"
server.listener.smtp.proxy.override = false
server.listener.smtp.socket.override = false
server.listener.smtp.tls.implicit = false
server.listener.smtp.tls.override = false
server.listener.submission.bind = "[::]:587"
server.listener.submission.protocol = "smtp"
server.listener.submission.proxy.override = false
server.listener.submission.socket.override = false
server.listener.submission.tls.implicit = false
server.listener.submission.tls.override = false
server.listener.submissions.bind = "[::]:465"
server.listener.submissions.protocol = "smtp"
server.listener.submissions.proxy.override = false
server.listener.submissions.socket.override = false
server.listener.submissions.tls.implicit = true
server.listener.submissions.tls.override = false
server.max-connections = 8192
server.proxy.trusted-networks = "172.18.0.0/16"
server.socket.backlog = 1024
server.socket.nodelay = true
server.socket.reuse-addr = true
server.socket.reuse-port = true
storage.blob = "rocksdb"
storage.data = "rocksdb"
storage.directory = "internal"
storage.fts = "rocksdb"
storage.lookup = "rocksdb"
store.rocksdb.compression = "lz4"
store.rocksdb.path = "/opt/stalwart-mail/data"
store.rocksdb.type = "rocksdb"
tracer.log.ansi = false
tracer.log.enable = true
tracer.log.level = "info"
tracer.log.path = "/opt/stalwart-mail/logs"
tracer.log.prefix = "stalwart.log"
tracer.log.rotate = "daily"
tracer.log.type = "log"

Checking connectivity in Mail.app on macOS

Untitled

IMAP - Connection to the server and login was successful. SMTP - Connection to the server was successful, you do not need to log in.

Emails come in with no problem, sending emails doesn't work.

Test commands with openssl

openssl s_client -quiet -crlf -connect [mail.example.com:465](<http://mail.example.com:465/>)
Connecting to IP
depth=2 C=US, O=Internet Security Research Group, CN=ISRG Root X1
verify return:1
depth=1 C=US, O=Let's Encrypt, CN=R11
verify return:1
depth=0 [CN=mail.example.com](<http://cn=mail.example.com/>)
verify return:1
220 [mail.example.com](<http://mail.example.com/>) Stalwart ESMTP at your service
AUTH LOGIN
503 5.5.1 AUTH not allowed.

For some reason authorization for SMTP does not work.

Links

Stalwart Traefik configuration