CheckMK Agent on Alpine Linux

How to use the Checkmk Agent on Alpine Linux

Alpine Linux is a lean Linux distribution based on OpenRC designed for security, simplicity, and resource efficiency. Because of the reduced size, it lacks daemons such as xinetd or system, and thus, the default way of working with the Checkmk Agent through a TCP port is not available.

In this how-to I show you my solution to run the Checkmk Agent on Alpine Linux. To do so, I will use the normal TCP port, but will customize a few things. In the end you will be able to monitor Alpine Linux.

In case you plan to use this how-to, you don’t have to do all the manual steps. I created an Ansible playbook and GitHub repositories. You find the link at the end of this post. You should still continue reading the steps to understand what I did.

Ideally, you give me feedback or for share this content with someone that could use it.

Instal socat

To make the output of the Checkmk Agent available on TCP port 6556, I will use “socat”. This command line tool allows transferring data bidirectionally between two data streams. The tool is flexible about kind of streams, and in this case, it will be a TCP connection and a local script output.

First thing I had to do: Instal socat on Alpine Linux. It needs to be installed manually; you find it here: https://alpine.pkgs.org/3.11/alpine-main-x86_64/socat-1.7.3.3-r1.apk.html or you can use

apk add socat

to install it from the repositories.

Open the port with socat

Once you installed socat, the basic command will be:


/usr/bin/socat -U TCP-LISTEN:6556,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent

This command has two sides, the left side with the listening TCP port 6556, and the right side with the executed script, in this case our Checkmk Agent. The “-U” ensures that only data from the script is send to the port and no data could be sent from the network to the script.

Customize options

The left side for the command shown before will make all interfaces listen to TCP port, but it is possible to bind on a specified interface. Then you need to replace “TCP-LISTEN:6556,fork” and use this command:


/usr/bin/socat -U TCP-LISTEN:6556,bind=$YOURIP$,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent

Also, it is possible to define, which systems are allowed to access the Checkmk Agent via TCP by using “hosts.allow” and “hosts.deny” files. The next command controls access for Checkmk Agent by defining rules for the daemon process “checkmk”.


/usr/bin/socat -U TCP-LISTEN:6556,tcpwrap=checkmk,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent

In case, you want to define a range from where the service is reachable, use the following command. The port can be reached from everywhere, but by using this command socat will ignore ranges that are not defined.


/usr/bin/socat -U TCP-LISTEN:6556,range=8.8.8.8/32$,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent

the init script

As mentioned before, Alpine Linux is using OpenRC as default init system. OpenRC has defined many defaults, which offers the possibility to build a very simple init script. We only need to specify the command in this case “/usr/bin/socat” and the needed arguments.

In this example this is a very basic setup:
"-U TCP-LISTEN:6556,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent".

We use “root” as user and set command-background to “yes” because socat has no real daemon mode. You can modify the command args as described above if you want to allow more connections or be stricter on their limitations.

/etc/init.d/checkmk_agent


#!/sbin/openrc-run

name=check_mk_agent

description="Check_MK Agent on Alpine Linux"

command="/usr/bin/socat"

command_args="-U TCP-LISTEN:6556,fork,reuseaddr EXEC:/usr/local/bin/check_mk_agent"

command_user="root"

pidfile="/run/$RC_SVCNAME.pid"

command_background="yes"

depend() {

need net

}

Getting the agent to work

I am using the Checkmk plug-in for openwrt to monitor Alpine Linux, because the openwrt agent is designed to use “/bin/ash”, which is default shell in Alpine Linux. The openwrt agent comes with your Checkmk installation.

For me, this worked out, to the most part, at least. After a short test, I noticed that the monitoring service for filesystem usage was not working. This is due the BusyBox version of df does not support all options that are needed by the agent.

Thus, in this section I’ll describe how to overcome this. It is a good idea to install ethtool via “app add ethtool” to get all stats from your NICs.

To get the df section working on Alpine I checked the FreeBSD agent to see how it is solved there. I only had to change two lines in the agent code.

original: df -PTlk $excludefs | sed 1d

modified: df -kTP | egrep -v ‘(Filesystem|none|udev|tmpfs)’

original: df -PTli $excludefs | sed 1d

modified: df -kTPi | egrep -v ‘(Filesystem|none|udev|tmpfs)’

And that was it. Now, I have a full working agent on Alpine Linux, thanks for taking to time to read this post.

I created a GitHub repositories https://github.com/mcasviper/alpine_checkmk_agent with a basic init script ( checkmk_agent) and an ansible playbook ( install_checkmk_agent_alpine.yml) to create all needed folders, install and activate the init script and the Checkmk Agent. The playbook will also install socat and ethool.

8 Likes

Great guide. Just wanted to point out that Alpine busybox-extras package has inetd. For example, on Home Assistant Operating System (hassos):

[core-ssh ~]$ apk add busybox-extras
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
(1/1) Installing busybox-extras (1.33.1-r7)
Executing busybox-extras-1.33.1-r7.post-install
Executing busybox-1.33.1-r6.trigger
OK: 90 MiB in 100 packages

[core-ssh ~]$ which inetd
/usr/sbin/inetd

Then it’s only a matter of creating /etc/inetd.conf and setting it up as per the official documentation: Monitoring Linux in legacy mode. Might be easier for some compared to socat.

More on inetd configuration on Alpine: Alpine inetd setup | Alpine Linux forums