# Docs: https://docker-mailserver.github.io/docker-mailserver/v14.0/config/advanced/mail-forwarding/relay-hosts/ # Additional context, with CLI commands for verification: # https://github.com/docker-mailserver/docker-mailserver/issues/4136#issuecomment-2253693490 services: # This would represent your actual DMS container: dms-sender: image: mailserver/docker-mailserver:latest # :14.0 hostname: mail.example.test environment: # All outbound mail will be relayed through this host # (change the port to 587 if you do not want the postfix-main.cf override) - DEFAULT_RELAY_HOST=[smtp.relay-service.test]:465 # Your relay host credentials. # (since the relay in the example is DMS, the relay account username is a full email address) - RELAY_USER=relay-user@relay-service.test - RELAY_PASSWORD=secret # The mail client (swaks) needs to connect with TLS: - SSL_TYPE=manual - SSL_KEY_PATH=/tmp/tls/key.pem - SSL_CERT_PATH=/tmp/tls/cert.pem # You would usually have `volumes` instead of this `configs`: configs: - source: dms-main target: /tmp/docker-mailserver/postfix-main.cf - source: dms-accounts target: /tmp/docker-mailserver/postfix-accounts.cf # Authenticating on port 587 or 465 enforces TLS requirement: - source: tls-cert target: /tmp/tls/cert.pem - source: tls-key target: /tmp/tls/key.pem # This is only needed if you want to verify the TLS cert chain with swaks # (normally with public CA providers like LetsEncrypt this file is already available to a mail client) - source: tls-ca-cert target: /tmp/tls/ca-cert.pem # Pretend this is your third-party relay service: dms-relay: image: mailserver/docker-mailserver:latest # :14.0 hostname: smtp.relay-service.test environment: # WORKAROUND: Bypass security checks from the mail-client (dms-sender container) # (avoids needing expected DNS records to run this example) - PERMIT_DOCKER=connected-networks # TLS is required when relaying to dms-relay via ports 587 / 465 # (dms-relay will then relay the mail to dms-destination over port 25) - SSL_TYPE=manual - SSL_KEY_PATH=/tmp/tls/key.pem - SSL_CERT_PATH=/tmp/tls/cert.pem configs: - source: dms-accounts-relay target: /tmp/docker-mailserver/postfix-accounts.cf - source: tls-cert target: /tmp/tls/cert.pem - source: tls-key target: /tmp/tls/key.pem # Pretend this is another mail server that your target recipient belongs to (like Gmail): dms-destination: image: mailserver/docker-mailserver:latest # :14.0 hostname: mail.destination.test # WORKAROUND: dms-relay must be able to resolve DNS for `@destination.test` to the IP of this container: # Normally a MX record would direct mail to the MTA (eg: `mail.destination.test`) networks: default: aliases: - destination.test environment: # WORKAROUND: Same workaround as needed for dms-relay - PERMIT_DOCKER=connected-networks configs: - source: dms-accounts-destination target: /tmp/docker-mailserver/postfix-accounts.cf # Using the Docker Compose `configs.content` feature instead of volume mounting separate files. # NOTE: This feature requires Docker Compose v2.23.1 (Nov 2023) or newer: # https://github.com/compose-spec/compose-spec/pull/446 configs: # `postfix-main.cf`, a single line change to make all outbound SMTP connections over implicit TLS instead of the default explicit TLS (StartTLS). # NOTE: If you need to only selectively relay mail, you would need to instead adjust this on the relay service in `/etc/postfix/master.cf`, # However DMS presently modifies this when using the DMS Relay Host feature support, which may override `postfix-master.cf` or `user-patches.sh` due to `check-for-changes.sh`. dms-main: content: | smtp_tls_wrappermode=yes # DMS expects an account to be configured to run, this example provides accounts already created. # Login credentials: # user: "john.doe@example.test" password: "secret" # user: "relay-user@relay-service.test" password: "secret" # user: "jane.doe@destination.test" password: "secret" dms-accounts: # NOTE: `$` needed to be repeated to escape it, # which opts out of the `compose.yaml` variable interpolation feature. content: | john.doe@example.test|{SHA512-CRYPT}$$6$$sbgFRCmQ.KWS5ryb$$EsWrlYosiadgdUOxCBHY0DQ3qFbeudDhNMqHs6jZt.8gmxUwiLVy738knqkHD4zj4amkb296HFqQ3yDq4UXt8. dms-accounts-relay: content: | relay-user@relay-service.test|{SHA512-CRYPT}$$6$$o65y1ZXC4ooOPLwZ$$7TF1nYowEtNJpH6BwJBgdj2pPAxaCvhIKQA6ww5zdHm/AA7aemY9eoHC91DOgYNaKj1HLxSeWNDdvrp6mbtUY. dms-accounts-destination: content: | jane.doe@destination.test|{SHA512-CRYPT}$$6$$o65y1ZXC4ooOPLwZ$$7TF1nYowEtNJpH6BwJBgdj2pPAxaCvhIKQA6ww5zdHm/AA7aemY9eoHC91DOgYNaKj1HLxSeWNDdvrp6mbtUY. # TLS files: # - Use an ECDSA cert that's been signed by a self-signed CA for TLS cert verification. # - This cert is only valid for mail.example.test, mail.destination.test, smtp.relay-service.test # `swaks` run in the container will need to reference this CA cert file for successful verficiation (optional). tls-ca-cert: content: | -----BEGIN CERTIFICATE----- MIIBfTCCASKgAwIBAgIRAMAZttlRlkcuSun0yV0z4RwwCgYIKoZIzj0EAwIwHDEa MBgGA1UEAxMRU21hbGxzdGVwIFJvb3QgQ0EwHhcNMjEwMTAxMDAwMDAwWhcNMzEw MTAxMDAwMDAwWjAcMRowGAYDVQQDExFTbWFsbHN0ZXAgUm9vdCBDQTBZMBMGByqG SM49AgEGCCqGSM49AwEHA0IABJX2hCtoK3+bM5I3rmyApXLJ1gOcVhtoSSwM8XXR SEl25Kkc0n6mINuMK8UrBkiBUgexf6CYayx3xVr9TmMkg4KjRTBDMA4GA1UdDwEB /wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBQD8sBrApbyYyqU y+/TlwGynx2V5jAKBggqhkjOPQQDAgNJADBGAiEAi8N2eOETI+6hY3+G+kzNMd3K Sd3Ke8b++/nlwr5Fb/sCIQDYAjpKp/MpTDWICeHC2tcB5ptxoTdWkTBuG4rKcktA 0w== -----END CERTIFICATE----- tls-key: content: | -----BEGIN EC PRIVATE KEY----- MHcCAQEEIOc6wqZmSDmT336K4O26dMk1RCVc0+cmnsO2eK4P5K5yoAoGCCqGSM49 AwEHoUQDQgAEFOWNgekKKvUZE89vJ7henUYxODYIvCiHitRc2ylwttjqt1KUY1cp q3jof2fhURHfBUH3dHPXLHig5V9Jw5gqeg== -----END EC PRIVATE KEY----- tls-cert: content: | -----BEGIN CERTIFICATE----- MIIB9DCCAZqgAwIBAgIQE53a/y2c//YXRsz2kLm6gDAKBggqhkjOPQQDAjAcMRow GAYDVQQDExFTbWFsbHN0ZXAgUm9vdCBDQTAeFw0yMTAxMDEwMDAwMDBaFw0zMTAx MDEwMDAwMDBaMBkxFzAVBgNVBAMTDlNtYWxsc3RlcCBMZWFmMFkwEwYHKoZIzj0C AQYIKoZIzj0DAQcDQgAEFOWNgekKKvUZE89vJ7henUYxODYIvCiHitRc2ylwttjq t1KUY1cpq3jof2fhURHfBUH3dHPXLHig5V9Jw5gqeqOBwDCBvTAOBgNVHQ8BAf8E BAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSz w74g+O6dcBbwienD70D8A9ESmDAfBgNVHSMEGDAWgBQD8sBrApbyYyqUy+/TlwGy nx2V5jBMBgNVHREERTBDghFtYWlsLmV4YW1wbGUudGVzdIIVbWFpbC5kZXN0aW5h dGlvbi50ZXN0ghdzbXRwLnJlbGF5LXNlcnZpY2UudGVzdDAKBggqhkjOPQQDAgNI ADBFAiEAoety5oClZtuBMkvlUIWRmWlyg1VIOZ544LSEbplsIhcCIHb6awMwNdXP m/xHjFkuwH1+UjDDRW53Ih7KZoLrQ6Cp -----END CERTIFICATE-----