Lynis Plugins

Development guide for Lynis plugins.




Introduction



Scripting Language

Lynis is written in shell script, a versatile scripting language available on all systems running Linux or a UNIX-based operating system. For this reason, most system administrators can easily create their own tests for Lynis.

Creating your own tests and plugins is useful to customize the functionality of Lynis to your needs. In this document we have a look on how to achieve this.


Lynis Execution Steps

Lynis runs each time a full cycle of steps. For plugins there are two moments when they can run, which we call phase 1 and phase 2. The complete cycle looks like this:

[Initialization] → [OS detection] → [Detection of binaries] → [Plugins phase 1] → [Built-in tests] → [Custom tests] → [Plugins phase 2] → [Report]



Lynis Software Development Kit

To help maintaining a high level of quality, we use a software development kit (SDK). This includes unit-tests and linting tools, to perform tests on proper functioning and code hygiene.

The Lynis SDK can be found on GitHub, and contains the last set of tests, and documentation. The SDK is especially useful when you consider building your own tests, contribute, or want to convert your custom scripts into Lynis tests.


Development Steps


Step 1. Find your plugin directory

The first step is to know where Lynis is installed, and in particular in which directory your plugins are stored. This path is displayed on screen when running Lynis, and stored in your log file (usually /var/log/lynis.log).

Command:

grep -i plugin /var/log/lynis.log


Step 2. Select plugin phase


Phase 1

Plugins running in phase 1 will be executed before the normal built-in tests. This phase is ideal for tests that just collect data. This could be something like getting a list of installed packages, or the processes running on a system.

Phase 2

The second phase for plugins occurs when normal tests have ended. This is the time when you want to analyze earlier discovered information, process it, and optionally display it on screen.

Tip: If you create a plugin for the first time, use the second phase. This way you use screen output and have all test data available, as it is executed at the end of the audit cycle.


Step 3. Create the plugin file


With the plugins directory, copy the file custom_plugin.template to plugin_[name]_phase[number].

Plugin Name and Phase

The [name] should be replace with an unique name for your plugin. Only use lowercase characters, numbers, and, optionally a dash (-) to link two words. The [number] defines the plugin phase, which is 1 or 2, as described in step 2.

Example of names: companyname, custom-tests, iso27001, personal

For this purpose of documentation we use “custom-tests” as the name of our plugin. As we do want to use screen output in this example, we will use phase 2. These are the tests being executed near the end of the audit cycle.

Command:

cp custom_plugin.template plugin_custom-tests_phase2

Step 4. Plugin Configuration


Change the header

The first adjustments to be made to this file is changing the header. These details are used to document the plugin, and are used to validate the right format of the plugin.

#########################################################################
#
#    * DO NOT REMOVE *
#-----------------------------------------------------
# PLUGIN_AUTHOR=Mr Auditor <auditor@company.example.org>
# PLUGIN_CATEGORY=Custom
# PLUGIN_DESC=This are my custom tests
# PLUGIN_NAME=custom-tests
# PLUGIN_REQUIRED_TESTS=
#-----------------------------------------------------
#########################################################################
  • PLUGIN_AUTHOR: The author field defines who is responsible for the creation and updates to this file.
  • PLUGIN_CATEGORY: The category describes what kind of tests this plugin belongs to (e.g. Networking). It is fine to use "Custom".
  • PLUGIN_DESC: The description field, with an optional explanation on why this plugin was created and its goals.
  • PLUGIN_NAME: Should be equal to the name you used as file name. So in this case quot;“custom-tests".
  • PLUGIN_REQUIRED_TESTS: Field describes any tests that should already have been executed. Can usually be skipped.

Tips:

Check if the PLUGIN_NAME field is correctly defined. Leave the # signs in place and only change the values on each line.


Step 5. Creating Tests

Each plugin consists of one or more individual tests. They are marked with an unique ID, to allow for logging and proper storing of the outcomes of the test. For this same reason all tests you create should begin with “CUST-”, followed by four numbers (e.g. CUST-0010).

Tests are created with the common shell scripting language. To make things easier, we have predefined several functions (include/functions). Examples include adding text to the screen, log file, or report file. It also includes test for checking permissions and more.

Basic functions:
  • Display: show something on screen
  • LogText: store details of the test in the log file
  • Register: queue the test for execution
  • Report: store the outcome of a test in the report
Test flow:
  1. Set an optional prerequisite
  2. Register the test (Register function). Lynis will then check if it needs to be executed, or skipped.
  3. Check the status of Register function (if [ ${SKIPTEST} -eq 0 ]; then)
  4. Perform individual actions
  5. Close test (fi)

Some example of tests and functions can be seen in the include/tests_custom.template file. Another great resource is the normal tests within Lynis, which can be also found in the include directory.


Step 6. Running Lynis

Last action is running Lynis, and test if your newly created plugin is being used.


Troubleshooting

If your plugin is not being activated, check these items:

  • Is the plugin enabled in the profile?
  • Is the plugin properly named in the plugin file itself?
  • Are the file permissions of the plugin file correct?

The log file (/var/log/lynis.log) will also explain why it skipped a particular plugin.