Monday, April 8, 2019

Using Signal on a server

For a long while, I'd been using an email to SMS gateway to push important notifications from my server, such as SMART error messages, to my phone.  After all the NSA warrantless surveillance, I made a commitment to encrypt as much of my communications as possible.  When Signal came out, I adopted it because of it's strong encryption and privacy.  Ever since I've been wanting to use it for notifications from my server.  I finally got around to trying out the CLI version, and got it to work.

The installation of the command line utility for Signal was more straight forward than I was expecting.  I decided to use signal-cli and I was a bit worried, as it uses Java.  Java has historically been difficult to run on FreeBSD due to lack of support and draconian licensing terms.  I was surprised that the packages for OpenJDK 8 were both present and just worked on my server.  A simple pkg install openjdk8 got Java up and running.

One thing to note is that the package said that fdesc and proc needed to be mounted for Java to work, but I did not, and things still worked.  There are likely other parts of Java that may not work w/o those mounted, but not for Signal.

As I have been using OSS for a long time, I like to build things from source, so I followed the instructions at Building signal-cli and got the command built with out any trouble.

Once the command was built, the Usage guide provided the basics, but didn't include instructions on how to verify the safety numbers to ensure that the initial exchange was not MitM'd.  There is a man page, but it requires a2x and separate steps to build, but a little bit of digging got me the necessary steps (also, it turns out that the adoc format is a simple text format).

With a bit of searching, I found the listIdentities and verify commands.  There may have been another way, but because I had sent a test message, my phone was listed:
$ signal-cli -u +XXXXXXXXXXX listIdentities+YYYYYYYYYYY: TRUSTED_UNVERIFIED Added: Sat Apr 06 18:43:15 PDT 2019 Fingerprint: ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ ZZ  Safety Number: WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW

And then I needed to use the trust subcommand:
$ signal-cli -u +XXXXXXXXXXX trust -v 'WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW WWWWW' +YYYYYYYYYYY

The hardest part of this was figuring out how to invoke the command upon reception of an email.  I used an alias listed in /etc/aliases to forward the email to both the SMS gateway and myself.  The issue with trying to invoke the command from here was that the command was run as the mailnull user, which of course didn't have access to my user's home directory to read the private key.  After a bit of debating, I remembered I use procmail, and realized this was the best way to send the message.

I created a symlink for the command into my user's bin directory, created a short script called sendcell:
$ cat ~/bin/sendcell
#!/bin/sh -

~user/bin/signal-cli -u +XXXXXXXXXXX send +YYYYYYYYYYY


and then added a filter to my .procmailrc file.  The filter at first looked like this:
:0Wf
* ^TO_celluser@([^@\.]*\.)*example.com
| sendcell


But after the first test, it included all the headers, including all the Received headers, so I updated it to use formail to remove all but the From, Subject and Date (in case the message gets significantly delayed, I can see by how much) headers:
:0c
* ^TO_celluser@([^@\.]*\.)*example.com
{
:0Wf
| formail -k -X From: -X Subject: -X Date:

:0
| sendcell
}


and now I get the messages delivered to my phone securely!

It is tempting to use this to be able to invoke commands on my server remotely, but there isn't much I need to do when I don't have my laptop with me.