❗ This repository runs with the Postal version 2.1.1. It should be fine for version 2.1.x maybe 2.x
The Postal 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.
- Edit configuration file
/opt/postal/config/postal.ymladding FQDN of the Postal host (for examplepostal.example.com) instead of<HOST>
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
- Working directory will be
/opt/caddy-tls, so docd /opt, fetch the install repositorysudo git clone https://github.com/zdeneksvarc/postal-tls.gitand set working directorycd /opt/postal-tls - Set the FQDN of the Postal host in the files
.envandCaddyfileand also set your e-mail address in theCaddyfileinstead ofyour@email.comwhich is used to identify the owner of the certificate. - Still in the
/opt/postal-tlsnow rundocker compose up httpsand 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-dataand set the permissions of directorysudo find /opt/postal-tls/caddy-data -type d -exec chmod 755 {} +and filessudo find /opt/postal-tls/caddy-data -type f -exec chmod 644 {} + - Add the volume with certificates
/opt/postal/caddy-data:/caddy-datato 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/Caddyfileand link a working onesudo ln -s /opt/postal-tls/Caddyfile /opt/postal/config/Caddyfileand remove .git directorysudo rm -r /opt/postal-tls/.gitand .gitignore filesudo rm -r /opt/postal-tls/.gitignore - Stop Postal via
postal stopand start Postal viapostal start, which will now start with StartTLS support on port 25. - Still in the working directory
/opt/postal-tlsstart the postal-tls Docker Compose project viadocker compose up -dand 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/postalwrapper. - 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.