Protonmail Bridge on a headless ARM64 server running Debian 10

This website runs on a RockPro64 SBC from Pine64. I’ve been very happy with the board so far, quite an improvement from my previous forays with the Raspberry Pi. I’ll write up a short guide on how I got Debian Buster installed later.

I’m a happy customer with ProtonMail. With their ProtonMail Bridge for Linux now out of beta, it seemed like a good idea to use it on the RockPro64, since I like firing up Neomutt to catch up on emails if I ssh to the machine.

The Bridge application itself is written in Go, and is available for Download in RPM, DEB or PKGBUILD format here. Unfortunately, the DEB file isn’t working on ARM64, so we have to fetch the source from Github and compile from source. The instructions on Github are a little basic though. At least for a non-expert like me. So, here goes!

Step 1: Install the ProtonMail Bridge application on your headless server

I’ll assume you have ssh and sudo access.

Create a working directory (home folder is fine):

mkdir ~/pm-bridge
cd ~/pm-bridge

Get the basic stuff we need:

sudo apt install git build-essential

I opted to download Go directly and put it in “/usr/local”. Grab the latest version for ARM64:

wget https://golang.org/dl/go1.15.5.linux-arm64.tar.gz
tar zxvf https://golang.org/dl/go1.15.5.linux-arm64.tar.gz
sudo mv go/ /usr/local/

Set necessary paths to use Go from your working directory (append these to your ~/.profile file you’d like them to be permanent):

export GOROOT=/usr/local/go
export GOPATH=$HOME/pm-bridge/
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

Get the ProtonMail Bridge code from Github:

git clone https://github.com/ProtonMail/proton-bridge/

Enter the repository and install Go dependencies for the bridge application:

cd proton-bridge
make install-dev-dependencies

Finally, we can build the Bridge. Since we’re running on a headless server there’s no need for a GUI, and so we will use an undocumented option to build a smaller, simpler version:

make build-nogui

This should only take a few seconds, and will leave you with the Desktop-Bridge binary in the working directory. Put the binary in whatever location you’d like to use it from (I put it in a hidden folder under /home):

mkdir ~/.pm-bridge
mv Desktop-Bridge ~/.pm-bridge/

You now have the bridge application ready for use. But wait! How do you actually make it work, and how do you run this thing as a service?

Step 2: Make the ProtonMail Bridge work in a headless environment

In order for the Bridge to work, it needs somewhere to store keys. Since we’re running headless, there’s no gnome-keyring that will do the job. Luckily, we can use “gpg” and “pass” instead.

Install them first:

cd ~/.
sudo apt install gpg pass libsecret-common libsecret-tools

Create a GPG key for the email address you intend to use with the Bridge (this is just used for local communication with the Bridge, it has nothing to do with the encryption keys employed by ProtonMail itself). This should be your protonmail email address, or whatever email address you use with their service if you have a custom domain:

For ease of use, I suggest you do NOT create a password for the GPG-key. Follow the defaults but simply hit “ENTER” when asked for password.

gpg --full-generate-key

Have pass open the key for use:

pass init username@protonmail.com # <-- Or whatever email address you defined for the GPG key.

If you try to run the Bridge, it should now work!

~/.pm-bridge/Desktop-Bridge

Bridge running

Great, so the Bridge is working. Now we need some way to daemonize the bridge. For this we will use screen and a systemd script. This was originally detailed here. I’ve modified it slightly to account for ‘pass’ to unlock the keys.

Step 3: Make the ProtonMail Bridge start as a service

First, install screen and netstat for testing:

sudo apt install screen netstat

Install the script we need to launch the bridge client and to able to kill it:

sudo nano /opt/protonmail.sh

Enter the following and customize as needed (email address for pass and the path to the Bridge binary):

   
#!/bin/bash
case "$1" in
  start)
    # will create an screen in detached mode (background) with name "protonmail"
    screen -S protonmail -dm bash -c "pass init username@protonmail.com; /home/username/.pm-bridge/Desktop-Bridge -c"
    echo "Service started."
    ;;
  status)
    # ignore this block unless you understand how screen works and that only lists the current user's screens
    result=$(screen -list | grep protonmail)
    if [ $? == 0 ]; then
      echo "Protonmail bridge service is ON."
    else
      echo "Protonmail bridge service is OFF."
    fi
    ;;
  stop)
    # Will quit a screen called "protonmail" and therefore terminate the running protonmail-bridge process
    screen -S protonmail -X quit
    echo "Service stopped."
    ;;
  *)
    echo "Unknown command: $1"
    exit 1
  ;;
esac

Make the script executable:

sudo chmod +x /opt/protonmail.sh

Create a systemd service:

sudo nano /etc/systemd/system/protonmail.service

Enter the following (adjust the username for your shell user):

[Unit]
Description=Service to run the Protonmail bridge client
After=network.target

[Service]
Type=oneshot
User=username
ExecStart=/opt/protonmail.sh start
ExecStop=/opt/protonmail.sh stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Start the service and test that it’s working:

sudo systemctl start protonmail
netstat -tulpn | grep 1025

If you see it listening on port 1025, all is well. Finally, enable the service for automatic startup:

sudo systemctl enable protonmail

You can now switch to the screen where the Bridge is running to interact with it (log in to your protonmail account, retrieve username and password for your email application etc.):

screen -r

Detach from the screen session when you’re done (By default, the escape key to disconnect is “CTRL+A”, then “d”)

Using the Bridge application is well documented by ProtonMail. The Bridge remembers your login etc. when it has been configured for the first time.

Configure your email-client to your heart’s content!

Step 4 (Optional): Keeping the ProtonMail Bridge updated

This is a somewhat hacky update script I use to update the Bridge. It basically scrapes the atom RSS file for the Bridge and checks if the latest version number on GIT is higher than the one I’m running (so it should work as long as the nomenclature on Git doesn’t change). If there is a newer version available, it will download, build and install the new version.

First, generate a version file for the Bridge binary you’re currently running:

/home/username/.pm-bridge/Desktop-Bridge -v | grep -Po '(?<=version)[^-git]+' | cut -c2- > /home/username/.pm-bridge/current_version                       

Then install a script to /usr/local/bin:

sudo nano /usr/local/bin/update-protonmail-bridge

Enter the following:

#/bin/bash 

echo 'Checking latest version available in Git...'

{
cd /tmp
rm releases.atom*
rm /home/username/.pm-bridge/latest_version
wget https://github.com/ProtonMail/proton-bridge/releases.atom
cat /tmp/releases.atom | grep -Po '(?<=br-)[^<]+' | head -1 > /home/username/.pm-bridge/latest_version
rm /tmp/releases.atom*
} &> /dev/null

V1="$(cat /home/username/.pm-bridge/current_version)"
V2="$(cat /home/username/.pm-bridge/latest_version)"

if [ "$V1" = "$V2" ]; then
        echo "You already have the latest version"

else
        echo "A newer version is available"

echo 'Set paths for GO'
export GOROOT=/usr/local/go 
export GOPATH=$HOME/pm-bridge/
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
echo 'Stop running ProtonMail Bridge Service'
sudo systemctl stop protonmail
echo 'Enter build directory and prepare for build'
cd /home/username/pm-bridge
rm -rf proton-bridge-old
mv proton-bridge proton-bridge-old
echo 'Downloading new ProtonMail-Bridge from git...'
{
git clone https://github.com/ProtonMail/proton-bridge
} &> /dev/null
cd proton-bridge
echo 'Building new ProtonMail-Bridge release'
{
make build-nogui
} &> /dev/null
echo 'Moving new build in place and restarting ProtonMail Bridge service'
cp Desktop-Bridge /home/username/.pm-bridge/Desktop-Bridge
rm /home/username/.pm-bridge/current_version
/home/username/.pm-bridge/Desktop-Bridge -v | grep -Po '(?<=version)[^-git]+' | cut -c2- > /home/username/.pm-bridge/current_version
sudo systemctl start protonmail
echo 'Upgrade completed!'

fi

Finally, make it executable:

sudo chmod +x /usr/local/bin/update-protonmail-bridge

The script should be pretty self explanatory. If an update is available, it will reuse your original build-folder with the same Go-paths, and also move the old working git folder to “proton-bridge-old” so that you have the previous version available. Any suggestions to improve the script is welcome!

Hopefully this is useful to someone, feel free to comment!