Press "Enter" to skip to content

Update on using ProtonMail Bridge on headless WordPress/Linux servers

Last updated on September 7, 2021

Ever since I posted these two posts (here and here) of using ProtonMail Bridge on a headless WordPress/Linux server, ProtonMail Bridge has somehow changed a lot. It now has more support for non-graphical environments. For example, gnome-keyring can be replaced with a command-line-based password manager called pass. And ProtonMail Bridge now also has an option, --noninteractive, to run without interaction. All this to say, using ProtonMail Bridge is pretty easy currently on headless WordPress/Linux servers. So I write this post to update how I use ProtonMail Bridge on my server now.

pass is friendlier to headless environments than gnome-keyring is. However, pass requires a GPG key. Moreover, when using ProtonMail Bridge with pass on a headless server, it’s better to use a GPG key that doesn’t need a passphrase. So I had been reluctant to write this update because of too much to cover.

I’m now still reluctant to explain the details, so I only write commands to create a passphrase-free GPG key, set up pass, and use ProtonMail Bridge in a headless environment in the mentioned new way.

Disclaimer: the practice described in this post is not safe. If the server is hacked, the ProtonMail credential may be easily obtained by hackers. So make sure the server is secure.

Prerequisites

  1. pass — most Linux distributions should have this in their official repositories
  2. GnuPG — I guess most Linux distributions should already have this
  3. ProtonMail Bridge v1.2.7 — not sure if all distributions have this package. If not, an option is to download the .deb package from here (see update) for Debian-based distributions (update: as of Sep. 07, 2021, v1.2.7 is not available anymore. Please download the latest release from Bridge’s official webpage or its GitHub page.). For Arch-based systems, there are several packages in AUR. Another option is to compile from the source code on GitHub.

Step 1: create a passphrase-free GPG key non-interactively

$ gpg --batch --passphrase '' --quick-gen-key 'ProtonMail Bridge' default default never

The above command creates a basic GPG key, and its ID is ProtonMail Bridge. This key does not have a passphrase, so pass does not need to ask users for a passphrase whenever it tries to use the key. The key does not expire. Don’t use this key for other things (such as encryption, signing, identity, etc.). It is not safe.

NOTE: Make sure the server has a firewall and is secure. If a hacker gets into the server, he/she can use this key freely to open the ProtonMail credential saved in pass. So be careful!!

Step 2: set up pass

$ pass init "ProtonMail Bridge"

This creates a new password database in pass (pass calls the database password store). And the GPG key ProtonMail Bridge can be used to open the database. If the server is multi-purpose or even a machine for daily work, don’t save other passwords/credentials in this database. This database does not need any passphrase to open due to the passphrase-free GPG key.

After this step, we can continue on the old way of running ProtonMail Bridge in the background as described in this post. Alternatively, we can use the new way described in the following steps.

Step 3: start ProtonMail Bridge in command-line & interactive mode and set it up

The new way to run ProtonMail Bridge in the background does not allow users to interact with the protonmail-bridge daemon. We have to set up protonmail-bridge interactively in advance. First, start the protonmail-bridge in command-line mode:

$ protonmail-bridge --cli
Start ProtonMail Bridge in command-line mode

Login our ProtonMail account with login command and record the username and password of the local SMTP server. Please refer to the step 1 in the old post for details if not familiar with this.

After setting up protonmail-bridge and obtaining the required information (SMTP username & password), we can now use exit to exit the interactive interface.

Step 4: run ProtonMail Bridge in the background

This step is where it is different from the old way. Now we just execute the following two commands to start protonmail-bridge:

$ nohup protonmail-bridge --noninteractive > bridge_log.txt 2>&1 &
$ disown

The above command also redirects the output message from protonmail-bridge to a file called bridge_log.txt. We can use $ cat bridge_log.txt to see protonmail-bridge‘s output message.

One thing important is that now protonmail-bridge daemon is non-interactive, which means there’s no way to give commands to the background daemon. If we want to control or set anything in protonmail-bridge, we always have to kill the daemon and then do the work with the interactive interface. This is a major drawback compared to the old way.

For example, if protonmail-bridge logs us out for some reason and requires us to re-login to the ProtonMail account, in the old way, we can just do $ echo "login" > bridge_input && echo "ProtonMail account" > bridge_input && echo "ProtonMail password" > bridge_input to re-login. On the other hand, with the --noninteractive way, we’ll have to kill the protonmail-bridge daemon, start $ protonmail-bridge --cli, login, exit, and then start the background daemon again. Or another example is when we want to check the status of the daemon. In the old way, we can just do $ echo "info" > bridge_input && cat bridge_output to see if the daemon is still working fine. While with the --noninteractive way, we can’t issue the info command to the daemon.

Finally, we can continue on the step 3 and step 4 in the old post to set up the WP Mail SMTP plugin as usual.

Also… to reduce GUI-related dependencies

For those who don’t like to install a lot of GUI-related dependencies on a server, we can compile and build protonmail-bridge from the source code on GitHub. Just build the build-nogui target with make. See the PKGBUILD of this AUR package.

41 Comments

  1. Anonymous Anonymous

    Hello, thank you for this new publication. But something is missing for a beginner. I cannot launch ProtonMail. When should we put the username and password ?

    ubuntu@www-example-com ~ $ pass

    Password Store
    └── protonmail-credentials
    └── aW5pdENoZWNrL3Bhc3M=

    ubuntu@www-example-com ~ $ protonmail-bridge –cli

    INFO[0000] Run app appLong=”Protonmail Bridge” appShort=bridge args=”[protonmail-bridge –cli]” build=”2020-05-19T00:33:31+0200″ pkg=main revision=50ed40f205 runtime=linux version=1.2.7
    ProtonMail Bridge is not able to detect a supported password manager
    (pass, gnome-keyring). Please install and set up a supported password manager
    and restart the application.
    Frontend error

    • This is weird. When you executed “pass”, apparently protonmail-bridge had successfully stored some credentials into “pass”. That’s why we see “protonmail-credentials” under “Password Store.” So it’s weird protonmail-bridge afterward complained it couldn’t find “pass”

      Can you try to reset pass? By default, “pass” stores data in “~/.password-store”. If you remove “~/.password-store” and re-execute “pass”, and the message tells you the password store is empty, then that means the pass has been reset.

      After reset, try “pass init “ProtonMail Bridge”” and “protonmail-bridge –cli” again.

      • Anonymous Anonymous

        Great, thanks, it works now. But if I do “exit” the emails no longer work. Here are my command line :

        ubuntu@www-example-com ~ $ sudo mkfifo bridge_input
        mkfifo: cannot create fifo ‘bridge_input’: File exists
        ubuntu@www-example-com ~ $ nohup protonmail-bridge –cli < bridge_log &
        [1] 12957
        ubuntu@www-example-com ~ $ telnet 127.0.0.1 1025
        Trying 127.0.0.1…
        telnet: Unable to connect to remote host: Connection refused
        [1]+ Exit 2 nohup protonmail-bridge –cli < bridge_log

        • Just want to confirm: your comment says you do $ nohup protonmail-bridge –cli < bridge_log &, but I think what you did is $ nohup protonmail-bridge --cli < <(tail -f bridge_input) &> bridge_log &, right? (< and > pair is considered to be a HTML tag, so <(tail -f bridge_input) &> disappears from your comment. This comment system accepts HTML tags.)

          Back to the "exit" you mentioned. Do you mean exiting the terminal? Or exiting protonmain-bridge? You need to keep protonmail-bridge running in the background even after you logout the server. So we don't exit protonmail-bridge. We just keep it running. To see what happened to the protonmail-bridge process, do $ cat bridge_log to see the output message.

          Also, have you already signed in your ProtonMail account in protonmail-bridge?

        • By the way, I just noticed this: try not to use sudo when doing $ mkfifo bridge_input. If you use sudo, bridge_input is owned by root, and I’m not sure if your current user identity (i.e., ubuntu) has the permission to use bridge_input or not. Maybe with sudo it still works, but just in case.

          • Anonymous Anonymous

            I mean, if I do “exit” in protonmain-bridge it doesn’t work anymore. I redid the steps to operate in the background, but it does not work for me :

            ubuntu@www-example-com ~ $ rm bridge_input
            ubuntu@www-example-com ~ $ mkfifo bridge_input
            ubuntu@www-example-com ~ $ nohup protonmail-bridge –cli < bridge_log &
            [1] 15925
            ubuntu@www-example-com ~ $ telnet 127.0.0.1 1025
            Trying 127.0.0.1…
            telnet: Unable to connect to remote host: Connection refused
            [1]+ Exit 2 nohup protonmail-bridge –cli < bridge_log
            ubuntu@www-example-com ~ $ client_loop: send disconnect: Broken pipe

        • After you restart the protonmail-bridge and before doing the telnet thing, can you execute the following command and see what the return message says? $ echo "info" > bridge_input && cat bridge_log

          If protonmail-bridge has been set up correctly, it should output the information of the local SMTP server. Otherwise, it will say something telling you to add an account to continue.

          • Anonymous Anonymous

            In the end it works, but you should not do “exit”. You have to close the terminal directly.

          • Great! Congrats!

            I probably know what happened. That blog post may be kind of misleading. I mentioned exit in that blog post just to tell readers they can do exit if they want to stop protonmail-bridge. But they shouldn’t do exit if they want to keep protonmail-bridge running in the background.

  2. Anonymous Anonymous

    Thanks for your blog

  3. Tony Morelli Tony Morelli

    PY,
    First, thanks so much for taking the time to write this and the previous articles. They gave me the exact solution I needed. I would like to ask your recommendation for starting the bridge on system boot . I have tried altering the command above in various ways and using different methods such as crontab and a .sh script in /etc/init.d/. However, none of these worked for me so far. I’m using Debian Buster and inexperienced with creating custom startup commands.

    • Hi,

      I use Arch Linux most of the time, so I’m only familiar with using systemd to start a service/program on system boot. Though my WordPress server is Debian, it also uses systemd. For a general introduction to systemd, see Arch’s Wiki page: https://wiki.archlinux.org/index.php/Systemd. That requires you to write a custom service file and let systemd to auto-start the service on boot. Someone else has created such service file for Bridge, see https://aur.archlinux.org/cgit/aur.git/tree/bridge.service?h=protonmail-bridge-nogui. I don’t do auto-start of Bridge, so I never actually tried that service file.

      • Tony Morelli Tony Morelli

        PY,
        Thanks again. Indeed my Debian installation does use systemd. The example service you linked was a perfect start for me and I found the man pages for systemd pretty straightforward. The only thing I altered was setting the service to run under my local user and not as root because the server was denying SMTP credentials if it ran as root. I noticed if I tried to sudo start the nohup command above to manually launch the bridge, it would throw an error that pass wasn’t found on the system. So it seems pass and protonmail bridge expect to run as a local user so making the latter into a service requires running the same way. Cheers.

        • Great! Maybe I’ll also try to auto-start Bridge! I think running Bridge with sudo needs also setting up pass with sudo because pass creates a password store per user. It also means we have to create a GPG key for sudo. So if running all the commands with sudo, Bridge should work with sudo. At least it works on my machine. But I think it’s kind of dangerous to do so. Just a hunch.

          Another issue is that, depending on the settings in /etc/sudoer, password stores of sudo may be conflicting with the local user’s password store due to sharing the same folder path (i.e., /home/<local username>/.password-store and/or even /home/<local username>/.gnupg). So some configurations may be needed to let sudo use other paths.

  4. Ed Ed

    Sucks for me because pass is no longer available in the repositories on CentOS.

      • Anonymous Anonymous

        Hello, I’m sorry to reopen the problem but ProtonMail does not want to remain started on my server. It cuts itself, I don’t understand why. If I issue this command sudo protonmail-bridge –cli it starts up and works. But it ends up going off by itself.

    • Hi, from the figure, I noticed some issues:

      1. After you started Bridge with --noninteractive flag, the bridge_log.txt says Bridge is already running. That means you already have Bridge running in the background. So if you want to start another Bridge, you need to kill the old one first. Because the old one is probably running silently in the background, you have to find out the PID and kill the PID.

      2. echo "info" >> bridge_input && cat bridge_log only works if you start Bridge through the the step2 described in the old post (link here). If you start Bridge with the --noninteractive flag, echo "info" >> bridge_input && cat bridge_log is not going to work.

      3. In the last part of the figure, you started another Bridge with sudo. This makes the new Bridge process belongs to root. So it is different from the one you previously started with the user ubuntu. I believe Bridge launched by different users is independent to each other.

      • Anonymous Anonymous

        My problem is that I can’t run Bridge without using “sudo”. And when I go to my Bridge server is stopped when I haven’t stopped it.

        ubuntu@www-example-com ~ $ protonmail-bridge –cli
        INFO[0000] Run app appLong=”Protonmail Bridge” appShort=bridge args=”[protonmail-bridge –cli]” build=”2020-05-19T00:33:31+0200″ pkg=main revision=50ed40f205 runtime=linux version=1.2.7
        ProtonMail Bridge is not able to detect a supported password manager
        (pass, gnome-keyring). Please install and set up a supported password manager
        and restart the application.
        Frontend error
        ubuntu@www-example-com ~ $

        • Can you see if the regular user ubuntu has a usable password store? For example, do pass (without sudo) and see the output. If it returns password information with no issues, but Bridge still cannot use it, then try to remove /home/ubuntu/.password-store and redo pass init "ProtonMail Bridge" (without sudo and assuming the name of the GPG key is ProtonMail Bridge). Also, make sure no previous Bridge is running silently in the background.

          • Anonymous Anonymous

            Ok thank you, I will start again from the beginning. Can you give me the commands to kill the process and delete the store. I also have another question, can we monitor the Bridge with Monit?

          • Anonymous Anonymous

            ubuntu@www-example-com ~ $ pass
            Password Store
            ubuntu@www-example-com ~ $ gpg –batch –passphrase ” –quick-gen-key ‘ProtonMail Bridge’ default default never
            gpg: A key for “ProtonMail Bridge” already exists
            ubuntu@www-example-com ~ $ pass init “ProtonMail Bridge”
            /usr/bin/pass: line 326: /home/ubuntu/.password-store//.gpg-id: Permission denied
            Password store initialized for ProtonMail Bridge
            find: ‘/home/ubuntu/.password-store/’: Permission denied

          • Anonymous Anonymous

            I finally succeeded after 3 days. I’m going to try adding this to Monit to monitor if the Bridge is working properly

            ProtonMail (envoyer des courriels) :

            Télécharger ProtonMail
            $ wget https://protonmail.com/download/protonmail-bridge_1.2.7-1_amd64.deb
            Installer ProtonMail
            $ sudo apt install ./protonmail-bridge_1.2.7-1_amd64.deb
            Changer le propriétaire et le groupe
            $ sudo chown -R ubuntu:ubuntu /home/ubuntu
            Configurer ProtonMail
            $ sudo apt install pass
            $ gpg –batch –passphrase ” –quick-gen-key ‘ProtonMail Bridge’ default default never
            $ pass init “ProtonMail Bridge”
            $ protonmail-bridge –cli
            $ login
            entrer l’identifiant et le mots de passe ProtonMail
            $ change mode
            $ info
            information de connexion ProtonMail pour Drupal
            Lancer ProtonMail en arrière-plan
            $ exit
            $ nohup protonmail-bridge –noninteractive > bridge_log.txt 2>&1 &
            $ disown
            $ jobs -l
            le sortie ne doit rien afficher

          • I’m glad it eventually worked out. It looks like at one point you created a password store with sudo and also started Bridge with sudo. This might make some folders to be owned by root instead of ubuntu and so you got permission denied. From the messages, it’s very likely the folder /home/ubuntu/.cache/protonmail/bridge/c11/mailbox-3kKMAhWJi72i****************************************==.db and /home/ubuntu/.password-store are owned by root. Next time when you encounter the same situation, you can try to remove both /home/ubuntu/.password-store and /home/ubuntu/.cache/protonmail with sudo privilege.

            I never used Monit, so I’m not sure how to use it with Bridge.

          • Anonymous Anonymous

            Thank you. I tested this morning and no cuts. So it works. For Monit I need the path to the PID file of protonmail-bridge

            I have searched and I cannot find

          • I’m gald it worked. Sorry for the late reply. I didn’t check my blog frequently these days. Did you eventually achieve what you wanted to do?

  5. Anonymous Anonymous

    Hi, can you show how to configure Postfix on the server to use ProtonMail Bridge ? Thank you

  6. Noni Noni

    My WordPress installation is not on the same server as ProtonMail Bridge, would it be possible to route a smtp.mydomain.com to the localhost somehow? And how would I go about that? Many thanks.

    • Did you mean routing the email from the WordPress server to where the ProtonMail Bridge is? I’ve never tried it, but I believe it’s possible. I can think of two possible solutions, depending on whether ProtonMail Bridge can listen to an external IP. If ProtonMail Bridge can listen to an external IP, you can just use the IP of the ProtonMail Bridge server in the SMTP setting. Otherwise, if ProtonMail Bridge is hard-coded to listen to 127.0.0.1 (i.e., localhost), then you can try using SSH port forwarding.

  7. Anonymous Anonymous

    Anyone know how to get this working on a Raspberry Pi4 8GB running Ubuntu Server Arm64 20.04.2LTS?

  8. Thanks for this and your other two articles on the subject! Super helpful.

  9. Here’s an example systemd unit file (i.e. `/etc/systemd/system/proton-bridge.service`)

    “`
    [Unit]
    Description=ProtonMail Bridge
    After=network.target

    [Service]
    User=YOUR_LOCAL_USER_WHERE_PASS_WAS_INITIALIZED
    ExecStart=/usr/local/bin/proton-bridge –noninteractive

    [Install]
    WantedBy=multi-user.target
    “`

  10. Anonymous Anonymous

    Very Helpful. thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.