Proton Mail is a great web email service. If you've landed here, you probably already agree with that. However, one major missing feature is SMTP/IMAP access to your mailboxes. They offer a "local" bridge application which is designed to run in a desktop environment and enable you to use Outlook or Thunderbird, etc. on that same local desktkop computer. However, if you'd like to run the bridge on a server and enable SMTP/IMAP access for your Android/iOS devices, that's a whole different story.
Challenges
There are a few challenges here that we've got to overcome to enable using the proton-bridge
project in this way:
- Application by default requires a GUI Desktop environment to run
- Application listens only on localhost (
127.0.0.1
) - And only on non-standard ports
Prerequisites
I'll be doing this on a Debian 12 server, so we'll need to install some dependencies.
sudo apt install pass libsecret-1-dev pkg-config gnupg dbus-x11 build-essential
- Install golang (the Debian repo one is usually too old)
- Clone the
proton-bridge
repository
User Account
We're going to create a system user account for the proton-bridge
service to run as. To do this, simply use this useradd
command.
sudo useradd -s /bin/false proton
sudo mkdir /home/proton
sudo chown -R proton: /home/proton
You'll probably want to add your local user to the proton
group as well, in order to make reading it's logs, etc. easier in the future.
sudo usermod -aG proton $USER
And finally, create a directory for its logs
sudo mkdir /var/log/proton-bridge
sudo chown -R proton: /var/log/proton-bridge
Keystore
Next, lets figure out how to start the thing on a server without a desktop environment.
First, you'll want to setup a passphrase-free GPG key.
Notice all of these following commands are run in the context of the
proton
user viasudo -u proton ..
.
$ sudo -u proton gpg --batch --passphrase '' --quick-gen-key 'ProtonMail Bridge' default default never
This will generate a new key with the name ProtonMail Bridge
in your local keyring.
Then we'll need to setup a new password database in pass
.
$ sudo -u proton pass init "ProtonMail Bridge"
Now we've got all of the prerequisite steps out of the way!
Compiling from source
Finally, we can begin installing the actual ProtonMail proton-bridge
package. They offer a deb
build artifact, but the *.deb
package that they provide on their download page requires a ton of graphical dependencies that we don't want to install on our server. Fortunately they have a make
target called build-nogui
setup in their Makefile in the repository. Before we begin compiling it with this special target, there is one change we must make in the source-code.
0.0.0.0
Host
By default, the bridge is designed as a local application to run on your desktop machine to enable you to use Thunderbird/Outlook with ProtonMail. However, when running on a server, we often want to connect to it from the outside. So we've got to make a small change in the internal/constants/constants.go
file.
Change the line defining Host
from Host = '127.0.0.1'
to Host = '0.0.0.0'
.
build-nogui
Compilation
Next, ensure you're in the root of the proton-bridge
repository again and run make build-nogui
. This should compile the simple go binary proton-bridge
without all of the GUI dependencnies like qt-*
and the like.
After running make build-nogui
, we should now have a compiled bridge
binary in the root of the repository which does not require a GUI to setup!
Run ./bridge --version
to ensure it can run and prints the expected output.
If that all seems well, symlink this binary to a more appropriate locaiton.
sudo ln -s $(pwd)/bridge /usr/local/bin/bridge
Authentication
Finally, we can begin authenticating and getting this thing up and running. Execute the binary with the --cli
flag to enter into an interactive CLI mode.
$ sudo -u proton bridge --cli
In this interactive environment, use the login
command to begin the login procedure. This will ask you for your normal web-based ProtonMail username/password and potentially 2FA code. After successfully authenticating, it will begin syncing mails for offline storage. Depending on the age of your account and the size of your mailbox, this may take a while.
After that's completed, type info
in the interactive shell and it will print out a table of critical information including:
- SMTP / IMAP port and host connection details
- SMTP / IMAP credentials
Daemonizing
Finally, we can set this bridge
binary to run as a service with a small systemd unit file.
$ sudo vim /etc/systemd/system/proton-bridge.service
And enter something like the following:
[Unit]
Description=ProtonMail Bridge
After=network.target
[Service]
User=proton
ExecStart=/usr/local/bin/bridge --noninteractive
StandardOutput=append:/var/log/proton-bridge/activity.log
StandardError=append:/var/log/proton-bridge/error.log
[Install]
WantedBy=multi-user.target
Remember to potentially adjust a few things here.
- The
ExecStart
path to the binary. In my case, I've symlinked the binary from its compilation source folder to/usr/local/bin/proton
. Also notice the--noninteractive
flag we're passing here. - The user with which this binary will be executed.
- The paths for the log files. Ensure these directories exist and the user has access to write to them.
After saving and closing that file, enable and start the systemd service.
$ sudo systemctl daemon-reload
$ sudo systemctl enable proton-bridge
$ sudo systemctl start proton-bridge
This should start the proton-bridge
service now and enable it to auto-start on reboot.
You can check the current status by executing sudo systemctl status proton-bridge
and as the service file indicated, the logs are located at /var/log/proton-bridge/*
.
Ports (Optional)
Finally, after starting that service we have the IMAP and SMTP bridge running as a daemon on our server! However, it's still using the odd arbitrary ports. This may be fine if your client application allows you to manually input any number in the port field. However, many Email clients will only allow you to select from a dropdown of a preselected few IMAP/SMTP ports when adding a new Email account.
For cases like these, we can use iptables
to our advantage!
These commands will forward traffic coming from A to destination B.
tcp/143
->tcp/1143
tcp/25
->tcp/1025
Make sure to replace 10.0.1.52
with the IP address of the interface where you'd like proton-bridge
to listen on.
$ iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 143 -j DNAT --to-destination 10.0.1.52:1143 # IMAP
$ iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 25 -j DNAT --to-destination 10.0.1.52:1025 # SMTP
Summary
So with a bit of tweaking we were able to use the pre-existing local bridge GUI application to run a headless server daemon to allow us to connect via SMTP / IMAP from any client to our ProtonMail inboxes!