Dovecot IMAP Proxy
Dovecot deployment acting as a pure IMAP proxy: it listens on your hostname (e.g. imap.example.com) with its own SSL certificate, accepts and terminates the client connections (implicit TLS on 993, STARTTLS on 143), then connects to the destination server (e.g. imap.example.net) as if it were the client, over the destination's own SSL, and forwards the traffic bit-by-bit in both directions.
How it works
Dovecot's login proxy is used with a static passdb: any username is accepted, no password is verified locally (nopassword), and the login is forwarded (credentials included) to the destination host, which performs the real authentication. Once the remote login succeeds, dovecot becomes a dumb pipe between client and destination. No mail is ever stored locally.
Because the password must be forwarded, clients have to use cleartext mechanisms (PLAIN / LOGIN); dovecot only allows them after TLS is negotiated, so nothing travels unencrypted.
Configuration
Copy example.env to .env and adjust:
SSL_CERT/SSL_KEY: certificate and key for the hostname the proxy serves (e.g. Let's Encrypt live paths).IMAP_EXPOSE/IMAPS_EXPOSE: host bindings for ports 143/993.
Copy example.dovecot.conf to ${DOVECOT_CONF} (default ./data/dovecot.conf) and set host in the passdb static block to your destination server. The destination certificate is verified against the system CA bundle (ssl_client_ca_file); use ssl = any-cert instead of ssl = yes if the destination has a self-signed certificate.
Usage
cp example.env .env
mkdir -p data && cp example.dovecot.conf data/dovecot.conf
$EDITOR .env data/dovecot.conf
docker compose up -d
Testing
openssl s_client -connect imap.example.com:993 -quiet
# then login as an existing user on the destination server:
a LOGIN user@example.com password
b LIST "" "*"
Notes
The -root image flavor is used so dovecot can read certificates that are only readable by root (as the Let's Encrypt live folder is); dovecot itself still drops privileges per-service. If your certificates are world-readable you can drop the -root suffix from DOVECOT_VERSION.