Proton Mail in the Native iOS Mail App

Table of Contents

Background

I've been trying to get my family to switch to Proton Mail, a privacy-focused, encrypted email service, as an effort to de-Google our lives. As often happens when switching away from any big tech company, there was a little bit of friction. Namely, because of Proton Mail's encryption, you have to download their mobile app to access your emails. Your account can't be added to your regular email client, because other email clients can't decrypt the emails. This is fine for me, but getting my wife to use a second app for emails has been a struggle, especially when she still receives most of her emails at her gmail address in the default mail client.

Fortunately, on Desktop environments, you can download their Proton Mail Bridge application. This sets up kind of a proxy server, which downloads the emails and decrypts them, and then delivers them over a localhost email server to your desktop email client. So I thought, why couldn't I set up Proton Mail Bridge on a linux server, and connect to it through a VPN to access emails on our mobile devices in their native email apps?

Tutorial Assumptions

βœ‰οΈ You have a paid Proton Mail plan (required for Proton Mail Bridge).
🐳 You know how to run docker containers.
🌐 You have a secure way to access your homelab from your mobile device. I'm using Tailscale.

Creating the Bridge

Setting up the container

I found the wonderful (unofficial) protonmail-bridge docker container that containerizes the linux version of the Proton Mail Bridge application! The readme has great information for getting things set up, but I'll walk you through it here as well in a little more detail.

First I set up a docker compose file for this container.

#compose.yaml

services:
  protonmail-bridge:
    image: shenxn/protonmail-bridge
    container_name: protonmail-bridge
    environment:
      - TZ=<your timezone>
    restart: unless-stopped
    volumes:
      - protonmail:/root

I'm going to be covering how to configure a reverse proxy (Traefik) to generate TLS certificates for clients. However, the protonmail-bridge container can generate TLS certs with the Proton Mail Bridge CLI. If you want to manually install those certs on your devices, or are just not going to use a reverse proxy to access your container, then you'll also need to expose the following tcp ports:

    ports:
      - 1025:25/tcp
      - 1143:143/tcp

Since I'm configuring Traefik to handle the public IMAP and SMTP connections, I'm not going to expose any ports, because Traefik will connect to it internally over a docker network (configured later).

Configuring our credentials

Before we actually start the protonmail-bridge container, we're going to need to configure it with our Proton Mail account. Execute the following command in your docker compose directory:

docker compose run protonmail-bridge init

Wait for everything to load, and then you'll see a prompt for the Proton Mail Bridge CLI. You can execute help for a list of commands, or just type login and follow the instructions to get your Proton Mail account set up. The nice thing is that you can configure multiple Proton Mail accounts, so if you have multiple family members all connected to your homelab, they can all use this service. You'll just need to execute the login command for each of them.

Once you've logged in, you'll need to execute info in the CLI to see the configuration information for your email client. It will look something like this:

>>> info
Configuration for michael@rossjr.dev
IMAP Settings
Address:   127.0.0.1
IMAP port: 1143
Username:  michael@rossjr.dev
Password:  <password>
Security:  STARTTLS

SMTP Settings
Address:   127.0.0.1
SMTP port: 1025
Username:  michael@rossjr.dev
Password:  <password>
Security:  STARTTLS

You'll notice the Username and Password are the same for both IMAP and SMTP. And the username should just be your Proton Mail email address, so you'll just need to copy the password.

Note

This is the password you'll use to connect in your email client, which is different from your Proton Mail account's password.

At this point, just execute

docker compose up -d

to start your container. If you're configuring a reverse proxy, keep reading, otherwise you can jump to Connecting to the iOS Mail App.

Configuring Traefik with Tailscale TLS Certificates

Now that our docker container is configured, we need to configure our reverse proxy to handle the TLS certificates so our email clients play nice with the server. I'm going to be using Traefik as a reverse proxy. The following is configured to connect with tailscale using the machine's MagicDNS name as the hostname, and tailscale as the tls certificate resolver. Tailscale only generates tls certificates for the MagicDNS hostname, so you must use that; you can't use the IP address.

#compose.yaml

services:
  protonmail-bridge:
    
    # Existing Config....
    
    networks:
      - traefik # This will be whatever network your reverse proxy is configured to use
    labels:
      traefik.enable: true
      # IMAP Config
      traefik.tcp.routers.proton-imap.entrypoints: imap
      traefik.tcp.routers.proton-imap.rule: HostSNI(`<tailscale-domain>.ts.net`)
      traefik.tcp.routers.proton-imap.tls.certresolver: tailscale
      traefik.tcp.routers.proton-imap.service: proton-imap-service
      traefik.tcp.services.proton-imap-service.loadbalancer.server.port: 143
      # SMTP Config
      traefik.tcp.routers.proton-smtp.entrypoints: smtp
      traefik.tcp.routers.proton-smtp.rule: HostSNI(`<tailscale-domain>.ts.net`)
      traefik.tcp.routers.proton-smtp.tls.certresolver: tailscale
      traefik.tcp.routers.proton-smtp.service: proton-smtp-service
      traefik.tcp.services.proton-smtp-service.loadbalancer.server.port: 25

Note

The domain names do not need to be different for IMAP and SMTP, as is often seen with email providers (imap.gmail.com vs smtp.gmail.com).

You'll notice I have two Traefik entrypoints listed, imap and smtp. You'll need to define these in your Traefik static configuration. In my case, in the traefik.yml config:

#traefik.yml

entryPoints:
  imap:
    address: :993
  smtp:
    address: :465

These will be the ports you use in your email client to connect to connect to the mail server. If you want to know why these specific ports were chosen, check out the Ports section of the docker-mailserver wiki's Mail Server behind a Proxy tutorial for more information.

Important

Please make sure you update your Traefik docker container to expose ports 993 and 465!

Additionally, I added the following tls config to my traefik.yml file. I don't know if I needed to, but I read this blog post that said it's necessary to get things working for Apple devices.

#traefik.yml

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

Connecting to the iOS Mail App

At this point, you should be all set and ready to connect to your email client! This part is fairly straightforward, and I imagine you could figure it out on your own. You'll need to manually set the hostname to the domain (or IP if preferred when not using TLS/SSL) that's pointing to your Bridge server. Next, enter your email address as the username, and be sure to use the password that you got from the Bridge CLI, not your normal Proton Mail password.

iOS IMAP Settings

Advanced iOS IMAP SettingsAfter entering my credentials, iOS did a good job of automatically detecting the correct IMAP settings, but you may need to go into the advanced settings and manually configure some of these options. If you're not using a reverse proxy, you'll likely need to manually specify ports 1143 (IMAP) and 1025 (SMTP) in the advanced configuration, and make sure to approve the Bridge's TLS certificate when prompted.

iOS SMTP Settings Unfortunately, the SMTP settings required a bit of tweaking. Initially, iOS assumed that the SMTP connection required no authentication. When configuring SMTP, be sure to specify your username and password (again, the one from the Bridge CLI). I also manually needed to enable "Use SSL", and set "Authentication" to "Password".

You should be able to follow relatively the same configuration to add your account to any additional email clients you may have. For the macOS Mail client, I had to uncheck "Automatically manage connection settings" for the SMTP server and make the same tweaks I did for iOS.

Conclusion

At this point you should be able to send and receive emails with your Proton Mail email address without having to use the 3rd party Proton Mail client. Congrats! Hopefully this will improve the wife-approval factor if you're de-googling and switching to Proton Mail. Please drop a comment below if you run into any issues or with any ideas on how the process could be improved.