Chkrootkit has a simple way to “set and forget” the system, only notifying you of when it sees something new.

Note

For how to install it, see Checking for Rootkits with chkrootkit.

However, what about if there’s a changing PID or other detail in the output that changes with every boot? Or if there are network interfaces that change on each boot?

We don’t want these alerts, and here we’ll show how to exclude them.

What False Positives look like

Here’s an example of how these false positives look like and how to read them. You may skip to the next section if you already know this.

You’ve likely already done this, but if not, run the cronjob:

/etc/cron.daily/chkrootkit

It may show something changed, but you’ll see it’s only the PIDs. It shows as a normal diff format, was was added (+), and what was removed (-).

chkrootkit output was not as expected.

The difference is:
--- [ BEGIN: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---
--- /var/log/chkrootkit/log.expected
+++ /var/log/chkrootkit/log.today
@@ -195,8 +195,8 @@
-eth0: PACKET SNIFFER(/usr/lib/systemd/systemd-networkd[717])
-eth0: PACKET SNIFFER(/usr/lib/systemd/systemd-networkd[717])
+eth0: PACKET SNIFFER(/usr/lib/systemd/systemd-networkd[726])
+eth0: PACKET SNIFFER(/usr/lib/systemd/systemd-networkd[726])
--- [ END: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---

As you can see, only the PID of the process changed from 717 ti 726, due to the machine rebooting.

If you’re using Docker, you may see the br interfaces changing:

+br-a7b7812cce5f: not promisc and no packet sniffer sockets
-br-b12cd3fa2c4e: not promisc and no packet sniffer sockets

How to Exclude

There are two ways to exclude this, via the Filter or the Ignore file.

Tip

Only use filter or ignore for each item you want to exclude. You may be able to use one for excluding one item, and use another for some other item. But don’t use both for the same.

Filter

FILTER allows you to use sed, grep, or whatever other filters you would like to filter/replace chkrootkit’s output.

Opening up /etc/chkrootkit/chkrootkit.conf, you’ll see the FILTER= line. It’s a regular expression of what to ignore.

FILTER="sed -re 's![[:alnum:]]+: PACKET SNIFFER\(((/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*|wpa_supplicant|NetworkManager))\[[0-9]+\](, )?)+\)!<interface>: PACKET SNIFFER\([systemd-networkd|dhclient|dhcpd|dhcpcd|wpa_supplicant|NetworkManager]{PID}\)!' -e 's/(! [[:alnum:]+-]+)\s+[0-9]+/\1 {PID}/'"

The above issue was caused because /usr/lib/systemd/systemd-networkd was specified as /lib/systemd/systemd-networkd in the filter.

...PACKET SNIFFER\(((/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*...
                     ^ no /usr was used, unlike how ^ here it is

Thus the answer is simple, add (/usr)?

...PACKET SNIFFER\((((/usr)?/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*...

Thus giving you

FILTER="sed -re 's![[:alnum:]]+: PACKET SNIFFER\((((/usr)?/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*|wpa_supplicant|NetworkManager))\[[0-9]+\](, )?)+\)!<interface>: PACKET SNIFFER\([systemd-networkd|dhclient|dhcpd|dhcpcd|wpa_supplicant|NetworkManager]{PID}\)!' -e 's/(! [[:alnum:]+-]+)\s+[0-9]+/\1 {PID}/'"

Then try it again.

/etc/cron.daily/chkrootkit

If the exclude was successful, it won’t show any output.

Ignore file

IGNORE_FILE is not as powerful as the Filter option, but may be easier. It uses the file /etc/chkrootkit/chkrootkit.ignore and can use egrep regular expressions.

For the above issue, we’d use this line. Note how I had to replace ( with \(, and [ with \[. As well as their counterparts.

eth0: PACKET SNIFFER\(/usr/lib/systemd/systemd-networkd\[.*\]\)

Warning

Do not leave an empty line in the file, or it will exclude all lines from the output.

Save the file, and try it again.

/etc/cron.daily/chkrootkit

If the exclude was successful, it won’t show any output.

Docker

In docker there are interfaces that will change their name with each boot and even each time applications are added or removed. Thus they will show up in chkrootkit’s report.

From the output:

chkrootkit output was not as expected.

The difference is:
--- [ BEGIN: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---
--- /var/log/chkrootkit/log.expected
+++ /var/log/chkrootkit/log.today
@@ -255,8 +255,8 @@
+br-238bc6070667: not promisc and no packet sniffer sockets
+br-a7b7812cce5f: not promisc and no packet sniffer sockets
-br-ab1b2e3f5ceb: not promisc and no packet sniffer sockets
-br-a7ed973cd3a0: not promisc and no packet sniffer sockets

We’ll use the Ignore file to exclude these.

Open /etc/chkrootkit/chkrootkit.ignore and add the following line.

^br-[0-9a-f]+: not promisc and no packet sniffer sockets$

Warning

Do not leave an empty line in the file, or it will exclude all lines from the output.

This looks for any like that starts with br, has an interface name like a7b7812cce5f and ends in the text not promisc and no packet sniffer sockets.

Run the cronjob again

/etc/cron.daily/chkrootkit

And now it should only show that it’s removing the interfaces.

chkrootkit output was not as expected.

The difference is:
--- [ BEGIN: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---
--- /var/log/chkrootkit/log.expected
+++ /var/log/chkrootkit/log.today
@@ -255,8 +255,8 @@
-br-238bc6070667: not promisc and no packet sniffer sockets
-br-a7b7812cce5f: not promisc and no packet sniffer sockets

To update the expected output, run (as root)
#  cp -a -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected

If it looks good, then accept it and you’re good to go.

cp -a -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected

Using Filter to exclude br instead

We could have modified the FILTER= by using a | grep ..., but this adds more complexity to the filter option. Still, if you have a complex situation, this may be helpful.

Info

No need to do this if you’ve already used the above ignore file to exclude it. Consider this extra credit.

Open /etc/chkrootkit/chkrootkit.conf and on the FILTER= line add this to the end, before the last quote mark. This will remove any line that starts with “br-” and contains “not promisc and no packet sniffer sockets”.

| grep -Ev '^br-[0-9a-f]+: not promisc and no packet sniffer sockets$'

So it looks something like this (scroll all the way to the right,and make sure ‘copy’ isn’t blocking your view).

FILTER="sed -re 's![[:alnum:]]+: PACKET SNIFFER\((((/usr)?/lib/systemd/systemd-networkd|(/usr)?/sbin/(dhclient|dhcpc?d[0-9]*|wpa_supplicant|NetworkManager))\[[0-9]+\](, )?)+\)!<interface>: PACKET SNIFFER\([systemd-networkd|dhclient|dhcpd|dhcpcd|wpa_supplicant|NetworkManager]{PID}\)!' -e 's/(! [[:alnum:]+-]+)\s+[0-9]+/\1 {PID}/' | grep -Ev '^br-[0-9a-f]+: not promisc and no packet sniffer sockets$'"

Note

I could have added -e 's/^br-*//g' to the filter line, however this would have just left an empty line for each br network. So when an app was added or removed (and thus a docker br sub-network was created/deleted), it would have added or removed an empty line. And thus sent out an unnecessary email.

Run the cronjob again

/etc/cron.daily/chkrootkit

And it will show

chkrootkit output was not as expected.

The difference is:
--- [ BEGIN: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---
--- /var/log/chkrootkit/log.expected
+++ /var/log/chkrootkit/log.today
@@ -258,17 +258,17 @@
-br-238bc6070667: not promisc and no packet sniffer sockets
-br-a7b7812cce5f: not promisc and no packet sniffer sockets
--- [ END: diff -u /var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today ] ---

To update the expected output, run (as root)
#  cp -a -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected

And that’s what we want. We can save it.

cp -a -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected

Conclusion

And with that, we are a bit more secure, knowing we’ll be alerted to the presence of a rootkit on our system.

For more on rootkits, see how to setup rkhunter.

Jellyfish