❗ This repository runs with the Postal version 2.1.2. It should be fine for version 2.1.x maybe 2.x
The Postal mail delivery platform does not offer encrypted services in the basic installation. That is certificate management, HTTPS interface, mail submission via oportunistic TLS (StartTLS) and implicit TLS. Deploying this repository via Docker Compose will provide these services.
Components of the deployment:
- Caddy 2 web server used for automated certificate management and HTTPS reverse proxy.
- Stunnel for implicit TLS termination on port 465. This is the preferred method of mail submission, see RFC8314
- Socat for mirroring ports 587 and 25, which is running StartTLS directly from Postal.
Installed Postal according to the official instructions with working web interface on port 80 and SMTP on port 25. No HTTPS reverse proxy, no certificates management.
- Suppose the directory for installed Postal is
/opt/postal
. Edit configuration file/opt/postal/config/postal.yml
adding FQDN of the Postal host (for examplepostal.example.com
) instead of<HOST>
in the smtp_server section:
smtp_server:
port: 25
tls_enabled: true
tls_certificate_path: /caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/<HOST>/<HOST>.crt
tls_private_key_path: /caddy-data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/<HOST>/<HOST>.key
- Suppose the directory for postal-tls will be
/opt/caddy-tls
. Change the working directorycd /opt
. Fetch the install repositorysudo git clone https://github.com/zdeneksvarc/postal-tls.git
. Jump to the new working directorycd /opt/postal-tls
- Set the FQDN of the Postal host in the files
.env
andCaddyfile
. Also set your e-mail address in theCaddyfile
instead of[email protected]
which is used to identify the owner of the certificate. - Still in the
/opt/postal-tls
now rundocker compose up https
and wait a while until Caddy gets the certificates. Then exit via CTRL-C - Create a symlink
sudo ln -s /opt/postal-tls/caddy-data /opt/postal/caddy-data
and set permissions of directorysudo find /opt/postal-tls/caddy-data -type d -exec chmod 755 {} +
and set permissions of filessudo find /opt/postal-tls/caddy-data -type f -exec chmod 644 {} +
- Add the volume with certificates
/opt/postal/caddy-data:/caddy-data
to the Postal smtp service in/opt/postal/install/docker-compose.yml
. - This step is not necessary, but for the sake of clarity we can delete the Caddyfile offered by Postal
sudo rm /opt/postal/config/Caddyfile
and link a working onesudo ln -s /opt/postal-tls/Caddyfile /opt/postal/config/Caddyfile
and remove .git directorysudo rm -r /opt/postal-tls/.git
and .gitignore filesudo rm -r /opt/postal-tls/.gitignore
- Stop Postal via
postal stop
and start Postal viapostal start
, which will now start with StartTLS support on port 25. - Still in the working directory
/opt/postal-tls
start the postal-tls Docker Compose project viadocker compose up -d
and you're done 🎉
- For StartTLS on port 587 or 25 you can try
openssl s_client -starttls smtp -connect <host>:<port>
- For implicit TLS on port 465 you can try
openssl s_client -connect <host>:465
- The Postal SMTP container log can be accessed via
docker compose -p postal logs -f | grep smtp_1
- You can use Swaks to send test emails and testssl.sh for TLS checks.
- There is a small glitch because the implicit TLS on port 456 also advertises
250-STARTTLS
. This is an obvious behavior, since the decrypted communication from port 465 goes to port 25. There are no known issues that this should cause in production. - Follows the recommendations of RFC8314 use implicit TLS on port 465 instead of StartTLS on port 587 due to the possibility of strip SSL attack.
- As you can see, the service on ports 25 and 587 is identical because it is mirroring.
- Postal does not support ECC certificates, but these are default for Caddy v2. Therefore, an explicit
{ key_type rsa4096 }
directive is used in the Caddyfile to force Caddy to use RSA certificates. - Postal internal services also run as Docker Compose project, but are handled by the
/usr/bin/postal
wrapper. - It's okay to be cautious about the trustworthiness of public docker images. If you consider it better, you can build the image of each of the three services used yourself.