Sending alerts to Signal Messenger from syslog-ng

Signal Messenger is becoming the instant messaging platform of choice for privacy-minded individuals, including many sysadmins. No wonder that some of them would like to see alerts from syslog-ng in this IM platform. Below, you can learn about an initial implementation, and why it is not part of syslog-ng.

Developing a new destination for syslog-ng from scratch in the C programming language is a considerable effort. As a result, this first implementation is utilizing an already existing command line application.

A word of caution

The syslog-ng application is known for its performance and resource-friendliness. The implementation below is slow, inefficient and requires lots of computing resources. It starts a Java application for each new alert (log message) sent through it, which works if you do not have much alerts. However, this method can overwhelm your system if you have an alert every few seconds.

We share here this initial implementation, as it is still better than nothing. You can also learn how you can create a reusable configuration block for syslog-ng, and how you can wrap a command line application into a shell script in order to be useful as a program() destination from syslog-ng.

Before you begin

The configuration was tested on the latest syslog-ng version (that is, version 3.28), but most likely works with any not too ancient versions. Check https://www.syslog-ng.com/3rd-party-binaries for up-to-date binaries if you do not have at least version 3.21 installed.

You also need signal-cli, a command line application to access the Signal IM platform. It is developed in Java, so you also need OpenJDK installed. You can compile it yourself or install it from an archive containing binaries.

You also need at least two mobile phone numbers for testing. One for sending alerts through signal-cli and another number (target) to receive them. Throughout this blog I use two false numbers as an example:

  • sender: +3611111111

  • target: +3622222222

You need two valid numbers even for testing. The approval numbers are also just examples, you will receive those by SMS and they are different each time.

Note that if you utilize a mobile number where Signal was already in use on the mobile, then the mobile app will stop functioning, and you will need to re-register the mobile app once you finish testing.

Signal-cli quick start

The easiest method is to use a binary distribution of signal-cli. It is available on the signal-cli release page at https://github.com/AsamK/signal-cli/releases and the latest available version is 0.6.8 at the time of writing. Download it, unpack it under the /opt directory and create a link to it from the /usr/local/bin directory:

wget https://github.com/AsamK/signal-cli/releases/download/v0.6.8/signal-cli-0.6.8.tar.gz
tar xf signal-cli-0.6.8.tar.gz -C /opt
ln -sf /opt/signal-cli-0.6.8/bin/signal-cli /usr/local/bin/

Use different version numbers if necessary. You are now ready to configure signal-cli. The first step is to register signal-cli with the Signal platform. For registering, you need a valid mobile number and the ability to receive text messages:

signal-cli -u +3611111111 register

Soon after you hit Enter, you will receive an SMS from Signal with a verification number. You should run a similar command that includes your mobile number and the verification number:

signal-cli -u +3611111111 verify 123-456

You are now ready to use Signal from the command line. Before utilizing it from syslog-ng, you should test it manually:

signal-cli -u +3611111111 send -m "this is a test" +3622222222

The test message should show up in Signal on the other side.

Preparing a wrapper script

As you can see, signal-cli operates from the command line. One message, one command. This is not what syslog-ng expects from a program() destination, so we need a wrapper script around signal-cli, which runs continuously and executes signal-cli as necessary. You can find the content of the script below. It expects three arguments:

  • the path to the signal-cli executable

  • sender number

  • target number

You can paste it into a text editor and save it to /usr/local/bin/signal-cli-wrapper.sh.

#!/bin/bash
#############################################################################
# Copyright (c) 2020 Balabit
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# As an additional exemption you are allowed to compile & link against the
# OpenSSL libraries as published by the OpenSSL project. See the file
# COPYING for details.
#
#############################################################################


for ARGUMENT in "$@"
do

  KEY=$(echo $ARGUMENT | cut -f1 -d=)
  VALUE=$(echo $ARGUMENT | cut -f2 -d=)

  case "$KEY" in
    SIGNAL_CLI_EXECUTABLE)    SIGNAL_CLI_EXECUTABLE=${VALUE} ;;
    OWN_NUMBER)               OWN_NUMBER=${VALUE} ;;
    PARTNER_NUMBER)           PARTNER_NUMBER=${VALUE} ;;
    *)
  esac

done

if [[ ! -x $SIGNAL_CLI_EXECUTABLE ]]
then
  echo "Not found, or not executable: $SIGNAL_CLI_EXECUTABLE"
  exit 1
fi

while read line ; do
  $SIGNAL_CLI_EXECUTABLE -u $OWN_NUMBER send $PARTNER_NUMBER -m "$line"
done

Once you saved it, make sure that the script is executable (chmod 755 /usr/local/bin/signal-cli-wrapper.sh). If you use a different file or path name, make sure that you reflect that in the syslog-ng configuration as well.

Configuring syslog-ng

Append the next configuration snippet to your syslog-ng.conf or create a new .conf file in /etc/syslog-ng/conf.d/ if the Linux distribution of your choice supports it:

block destination signal-cli-dest(
  signal-wrapper('usr/local/bin/signal-cli-wrapper.sh')
  signal-cli-executable('/usr/local/bin/signal-cli')
  own-number()
  partner-number()
  message-template('${MSG}')
  ...)

{
  program("`signal-wrapper` \
    SIGNAL_CLI_EXECUTABLE=\"`signal-cli-executable`\" \
    OWN_NUMBER=\"`own-number`\" \
    PARTNER_NUMBER=\"`partner-number`\""
    `__VARARGS__`
  );
};

No, this configuration is not yet sending messages anywhere. It is a reusable configuration block defining a Signal destination, making your life easier on the long run. This way, you can have multiple Signal destinations without the need to copy & paste large chunks of the syslog-ng configuration around.

The first part of the block lists a number of parameters. Those with an initial value have a sensible default and you do not have to configure them each time you use them. Sender and target mobile numbers, on the other hand, are left blank, so the configuration gives a syntax error if they are not defined by the user.

To actually use this, you need a destination utilizing this configuration block and have to use that in a log path. Normally, you would create some complex filters to find some important events in your log messages. For testing, I show a different approach: a network source directly connected to a Signal destination. This way, it is easier to test the destination. Once it works as expected, you can put it into production use with real logs and filters. But that is another story. For now, append the configuration below to the previous configuration block:

source s_net {
    tcp(ip("0.0.0.0") port(514));
};

destination d_signal_cli{
  signal-cli-dest(
    own-number("+36111111111")
    partner-number("+3622222222")
  );
};

log {
    source(s_net);
    destination(d_signal_cli);
};

Testing

You are now ready to test the Signal destination, which is called d_signal_cli in the example above. You can use the logger utility to send a log message to port 514:

logger -T --rfc3164 -n 127.0.0.1 -P 514 this is an alert from syslog-ng to Signal

If you have questions or comments related to syslog-ng, do not hesitate to contact us. You can reach us by email or even chat with us. For a list of possibilities, check our GitHub page under the “Community” section at https://github.com/syslog-ng/syslog-ng. On Twitter, I am available as @PCzanik.

Related Content