Guide: split-Protonmail (offline send/receive qubes + pm bridge vm)

Thanks again for writing up this guide! I think we can update some things so that it’s locked down even more, in particular we can eliminate the need to allow arbitrary TCP connections between the qubes.

The new policy file (using the new fromat described at Qubes Architecture Next Steps: The New Qrexec Policy System | Qubes OS) looks like this, in /etc/qubes/policy.d/30-protonmail.policy:

# Always allow connection to imap. Thunderbird will give you 2 pop-ups every
# time it checks for new messages, which can be annoying, but this could be
# modified to look like the smtp rule if you want to be prompted every time.
# Enabling notify=yes means that you will have visibility into when the requests
# are happening.
# Note that even though the destination vm is listed as *, we are overriding the
# target in the options. This means that the client can send "default" as the target
# qube and connect correctly.
user.protonmail-imap * protonmail-receive * allow target=protonmail-bridge notify=yes
# Ask for sending mail. This will only happen once for each mail you send which is
# much more manageable.
user.protonmail-smtp * protonmail-send    * ask   default_target=protonmail-bridge
# Finally, make sure that all other uses of these services are denied.
user.protonmail-imap * *                  * deny
user.protonmail-smtp * *                  * deny

Next, we need to update the callbacks in the bridge qube. The only change here is that they need the hashbang added to the top, and they also need to be marked as executable:

echo "#!/bin/sh" > /rw/usrlocal/etc/qubes-rpc/user.protonmail-smtp
echo "socat STDIO TCP:localhost:1025" >> /rw/usrlocal/etc/qubes-rpc/user.protonmail-smtp
echo "#!/bin/sh" > /rw/usrlocal/etc/qubes-rpc/user.protonmail-imap
echo "socat STDIO TCP:localhost:1143" >> /rw/usrlocal/etc/qubes-rpc/user.protonmail-imap
chmod a+x /rw/usrlocal/etc/qubes-rpc/user.protonmail-{smtp,imap}

Finally, we need to update the config files in the receive and send VMs. For receiving:

echo 'socat TCP-LISTEN:1143,fork EXEC:"qrexec-client-vm default user.protonmail-imap"' >> /rw/config/rc.local

And for sending:

echo 'socat TCP-LISTEN:1025,fork EXEC:"qrexec-client-vm default user.protonmail-smtp"' >> /rw/config/rc.local

The fork option to TCP-LISTEN makes it so that socat will run the EXEC every time a new connection is made on that port. The EXEC gets data from the bridge qubes through the qrexec framework instead of using TCP directly (though of course, thunderbird and the bridge are still using tcp, but this communication stays internal to their respective qubes).

This also has the benefit that you don’t have to start the bridge qube manually, because it will be autostarted when the qrexec request is made.