Traefik as a TLS proxy for IMAPS

By | 31 Aug 2024

I’m a data hoarder. And as such I still have email conversations going back to 2003. To not clog up my provider’s disk space and, because I don’t want to donate all these old conversations to Google, I’ve setup my own email archive using dovecot.

Early versions ran natively on one of my Raspberry Pis, however, in November 2022, I’ve set it up as a Docker container. Together with Solr and the fts-solr extension, you even get full-text search, clients can leverage. (The official Docker image should work the same – it’s just based on Debian-slim instead of Alpine Linux.)

On the Pi I had dovecot handle TLS and just pointed it to the Let’s Encrypt certificate for that hostname. As I had caddyserver running on the same machine and taking care of acquiring these certificates, that worked fine.

Now, having it all packaged up in a Docker container, I wanted Traefik to handle the TLS part and only talk plaintext with the dovecot container. To do that, I’ve added a new entrypoint on port 993 (imaps) to Traefik and these labels to the compose file section of the dovecot container:

    labels:
      traefik.enable: "true"
      traefik.tcp.routers.dovecot.entrypoints: imaps
      traefik.tcp.routers.dovecot.rule: HostSNI(`*`)
      traefik.tcp.routers.dovecot.tls.passthrough: "false"
      traefik.tcp.routers.dovecot.tls.certresolver: le
      traefik.tcp.routers.dovecot.tls.domains[0].main: "mail.domain.com"
      traefik.tcp.services.dovecot.loadbalancer.server.port: "143"

This made Traefik accept all traffic on the imaps entrypoint, handle TLS (as mail.domain.com) and use plaintext when talking to dovecot.

It worked fine. Using Thunderbird and Apple Mail on macOS, that is. However, it didn’t work from my iPhone or iPad. Instead, I saw this error in the Traefik logs:

2024-08-31T12:59:36Z ERR Error while handling TCP connection error="readfrom tcp 192.168.0.2:38582->172.20.0.10:143: tls: client requested unsupported application protocols ([imap])"

After some digging I’ve found someone mentioning the TLS option alpnProtocols in Traefik. This normally only allows HTTP and ACME. So I needed to change that. It’s part of the dynamic configuration and thus, changing the config file applies the changes immediately without the need for a Traefik restart. And, since we’re overriding the option, I had to keep the defaults as well:

tls:
  options:
    default:
      alpnProtocols:
        - h2
        - http/1.1
        - acme-tls/1
        - imap

And suddenly, my iDevices were able to talk to the mail server again.

Leave a Reply