Installing Graylog on OpenBSD from Scratch

⊕ 2020-04-12

Syslog integration in a network is relatively simple, but in my own network I was lacking a good way to analyze my logs and create triggers for certain events. This lead me to attempting to install Graylog CE on OpenBSD. Installing Graylog on OpenBSD is pretty simple, but I wanted to write down notes and show the process for creating a robust near-ports ready service from scratch. I also wanted to show a bit about how strange design choices by developers can actually interfere with ease of packaging.

Installing

In order to get things rolling the first step is to install the dependencies, luckily OpenBSD ports has everything that you will need in order to get things set up, so a simple pkg_add(1) is will do the trick (pwgen is not actually a requirement, it just simplifies the actual initial account creation steps):

pkg_add mongodb elasticsearch pwgen jdk

The next step is to grab a copy of the latest Graylog CE release, 3.2.4 at the time of writing. As an additional step I want to add a daemon user to my host and run Graylog to prevent it from being run as root and to take advantage of some inherent privilege separation protections on OpenBSD. For those unfamiliar with OpenBSD ports generally when a new user is needed for a package it is created from the commands in usr.sbin/pkg_add/OpenBSD/Add.pm (Mirror) which gives us all the normal arguments for invoking useradd and groupadd, then we need to select a UID/GID that is not in the ports/infrastructure/db/user.list (Mirror). For my example I selected 999 for no other reason that it was an upper bounds, if anyone is more familiar with how decisions about UID/GID selection should be done for local/non-public ports it would be greatly appreciated:

cd $(mktemp -d)
ftp "https://downloads.graylog.org/releases/graylog/graylog-3.2.4.tgz"
tar xzf "graylog-3.2.4.tgz"
cd graylog-3.2.4
#https://github.com/openbsd/ports/blob/master/infrastructure/db/user.list
#https://github.com/openbsd/src/blob/653997b58d05e9a77b764da4da38160e1649dbe6/usr.sbin/pkg_add/OpenBSD/Add.pm
groupadd -g 999 _graylog
useradd -u 999 -g 999 -L daemon -c "Graylog logging" -d /nonexistent -s /sbin/nologin _graylog
mkdir -p -m 744 /etc/graylog/server /usr/local/graylog
chown _graylog:_graylog /etc/graylog /usr/local/graylog

Once we have our user created and directories set up for Graylog we run into our first real hurdle. Graylog really doesn’t want default credentials to be created, which normally I appreciate, but for the sake of packaging creates a painful situation where you either create a patch and default credential or create some sort of automatic password generation part of the install process, inject it template style, and then print out a package notification about what the generated password is. At the current time this is the hurdle that I’m trying to deal with and it’s the main reason I stopped attempting to package Graylog itself. In the meantime for manual installation, I just decided to use pwgen(1) to create the key:

export GLSECRET="$(pwgen -N 1 -s 96)"
# generate a password for the admin interface, usual password warnings and hints as usual
# remember that this will be stored in shell logs and could also be a retrievable environment variable, so be careful. Clean up you history or even better just do this manually
export GLPASS="$(echo 'secretpassword' | sha256 | cut -d" " -f1)"
sed -e "s/^password_secret =.*\$/password_secret = $GLSECRET/g" -e "s/^root_password_sha2 =.*\$/root_password_sha2 = $GLPASS/g" ./graylog.conf.example > /etc/graylog/server/server.conf
chmod 740 /etc/graylog/server/server.conf
cp -r -p * /usr/local/graylog/
chown -R _graylog:_graylog /etc/graylog /usr/local/graylog/data /usr/local/graylog/plugin

NOTE: The configuration file does contain hashes and you should ensure that no one but the Graylog daemon has access to these.

Configuring Dependencies

Graylog itself should now be ready to run, but we need to configure mongod and elasticsearch in order to start at boot and ensure that their configurations will work with Graylog. Luckily, the default OpenBSD configuration options are sane for these packages and the only thing that needs to be done is changing the elasticsearch cluster name to be graylog. Once that is changed, enable the services, start them, and test Graylog:

sed -i -e 's/^cluster.name:.*$/cluster.name: graylog/g' /etc/elasticsearch/elasticsearch.yml
rcctl enable mongod
rcctl enable elasticsearch
rcctl start mongod
rcctl start elasticsearch

Final Steps

Now we need to create an init service to manage Graylog at startup and handle the management of the daemon, frankly I found that creating a service for Java on the platform to be a bit nebulous and hard to find much documentation on but I’m not sure if that’s a OpenBSD or Java problem. Create the following file in /etc/rc.d/graylog:

#!/bin/ksh
# $OpenBSD: graylog.rc,v 1.0 2020/04/12 TODO 10:22:58 pvk Exp $

daemon="/usr/local/graylog/bin/graylogctl"
daemon_flags="start"
daemon_user="_graylog"

. /etc/rc.d/rc.subr

#if this were really packaged well this would help
#pexp="$(/usr/local/bin/javaPathHelper -c graylog)"
pexp="/usr/local/jdk-1.8.0/bin/java .*graylog.*"

rc_reload=NO

rc_start() {
        JAVA_CMD="/usr/local/jdk-1.8.0/bin/java" "$daemon" start
}

rc_stop() {
        JAVA_CMD="/usr/local/jdk-1.8.0/bin/java" "$daemon" stop
}

rc_cmd $1

Once the init script is created it needs to be marked executable and enabled. Since this additionally needs to have the mongod and elasticsearch components running before Graylog starts an additional rcctl order needs to be issued to ensure that they start first:

chmod +x "/etc/rc.d/graylog" 
rcctl enable graylog
rcctl order elasticsearch mongod graylog
rcctl start graylog

Validate that everything is working the log for Graylog can be followed with a simple tail -f /usr/local/graylog/log/graylog-server.log and a netstat -lnta | grep LISTEN | grep 9000. You should also ensure that the daemon is running as the _graylog user.

The default Graylog configuration can now be reached from the http://localhost:9000 or the http_bind_address configuration option in /etc/graylog/server/server.conf can be changed to be expose it to anyone on the local network. Simply follow the configuration prompts in a web browser and ensure that everything is set up sufficiently, then set up your rules and normal Graylog configuration.