From Openscap


Script Check Engine


Currently, many administrators use several "dirty" scripts to make sure their systems follow certain guidelines. They would like to move to the new set of standards that allow them to interoperate and use tools supporting these standards. However they can't afford to make that transition abruptly, it would require them to rework all of their testing scripts at once.

To solve this issue, we have created a small and simple check engine called Script Check Engine (=SCE). The aims were to allow administrators to use their old check script content with XCCDF. This way they can even mix tests up with OVAL and slowly move to OVAL completely, without having to go through immediate migration of all their content.

Keeping it simple while offering choices

One of the goals was to make it as simple as possible and to avoid making decisions for the user. Therefore we chose to support everything that is executable from the command line (with shebangs, or even Linux binaries). This should allow complete freedom. While we realize that this doesn't enforce any standards and will make collaboration on checking scripts harder, we believe that it's up to the content creation projects to enforce these standards.

Examples of supported languages:

  • Bash
  • Python
  • Perl
  • Ruby

The new Script Check Engine is simply registered with a namespace of our choice "", the namespace URI matches URL of this page. When you reference content in your XCCDF you simply use that namespace as the "system" attribute and use path to the script as the "href" attribute (the path should be relative to the XCCDF file or absolute).

Reporting the XCCDF result

Before we run the scripts, we set the environment variables to feed them XCCDF variables and possible exit codes (XCCDF_RESULT_* variables). Scripts run, optionally print something to their stdout/stderr (we collect both of these, see section Script output) and they finish with an exit code (exit(exit_code) in C, sys.exit(exit_code) in Python, ...). This exit code is mapped to the xccdf_result enum (we actually don't use the exit codes from 1 onwards but from 100 onwards to avoid having syntax errors and other nasty business reported as simply XCCDF_FAIL).

Detailed results are stored in SCE result files.

Reporting reasons when check fails

Usually, when a script fails, you want to know why that happened so that you can correct the cause. If the scripts only returned the final result, this would have been difficult. This is why we redirect stdout and stderr and capture the output. There are 2 possible ways to get the output.

The prefered way is to have a check-import element in the source XCCDF with import-name "stdout". This will effectivelly fetch stdout from the Script Check Engine and put it in rule-result later on. XSLT transformations of openscap will see that the check-import is there and use their data.

In case there is no stdout check-import in the XCCDF (or the XSLT can't find it for whatever reason), it will try to look for SCE result files and get their stdout element content.

Practical example

Section of an XCCDF

<Rule id="rule-20" selected="true">
        <xhtml:pre xmlns:xhtml="">Checks if you have SELinux enabled</xhtml:pre>
    <check system="">
        <check-import import-name="stdout" />
        <check-content-ref href="" />

#!/usr/bin/env bash


if [[ $SELINUX_MODE != "Enforcing" ]]
	echo "Selinux is in "$SELINUX_MODE" mode."
	echo "Using Enforing mode is highly recommended. See selinux manual page for switching to Enforcing mode."



Passing variables using <check-export>

XCCDF variables and operators are communicated to the check executable using environment variables. Please refer to the XCCDF specification for more info about how variables can be passed to checks - specifically the <check-export> element.

XCCDF_TYPE_${variable name} holds the type - "BOOLEAN", "NUMBER" or "STRING".
XCCDF_VALUE_${variable name} holds the value payload.
XCCDF_OPERATOR_${variable name} holds the operator - "EQUALS", "NOT_EQUALS", "GREATER", "GREATER_EQUAL", "LESS", "LESS_EQUAL" or "PATTERN_MATCH".

It is recommended to create some sort of a reusable parser in your check scripts.


We are using this check engine to port sectool tests. It mostly involves changing report calls to echo calls and changing the way the final result is reported. Content that has already been ported is kept in the openscap git repository as sample content - [1]

Enable SCE in openscap

openscap won't have SCE support by default, you have to pass --enable-sce to ./configure to get SCE support. Up until 0.9.12 SCE was inbuilt into, since then it is built separately into and loaded as a plugin at runtime (if it's available).

Package repository (only for openscap > 0.9.12)

If you are using openscap from your package repository, check whether you need to install a supplemental package. For example in Fedora openscap SCE engine is packaged as "openscap-engine-sce". To enable it, execute:

# yum install openscap-engine-sce
Views Article Discussion Edit History
Personal tools:  Log in / create account
Toolbox What links here Related changes Upload file Special pages Printable version