Gentoo Logo

Generating OVAL documents with genoval.sh

1.  OVAL and genoval.sh

Introduction

While developing a security guide for Gentoo (Hardened), I chose to use the OVAL and XCCDF formats as defined by NIST. These formats, although not GuideXML, allow for integration with other security-related tools.

One huge advantage of XCCDF and OVAL, compared to regular documents, is that they allow for the definitions to be executed by tools that are compatible with the SCAP language. In other words, you can have your system checked (as far as possible) against the content of the document. The disadvantage however is that this requires a lot of XML code which makes it quite difficult to read and maintain.

The genoval.sh script, documented here, helps a bit in the maintenance of such documents. It translates more readable lines into OVAL XML code.

Code Listing 1.1: Example translation result

(The line that genoval.sh captures)
sysctl net.ipv4.ip_forward must be 0 [rule-sysctl-ipv4-forward]

(The result of the translation, in XCCDF document)

<Rule id="rule-sysctl-ipv4-forward">
  <title>sysctl net.ipv4.ip_forward must be 0</title>
  <description>sysctl net.ipv4.ip_forward must be 0</description>
  <fix>echo 0 &gt; /proc/sys/net/ipv4/ip_forward</fix>
  <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
    <check-content-ref name="oval:org.gentoo.dev.swift:def:21" href="scap-gentoo-oval.xml" />
  </check>
</Rule>


(The result of the translation, in OVAL document)

<definition class="compliance" id="oval:org.gentoo.dev.swift:def:21" version="1">
  <metadata>
    <title>sysctl net.ipv4.ip_forward must be 0</title>
    <description>sysctl net.ipv4.ip_forward must be 0</description>
  </metadata>
  <criteria>
    <criterion test_ref="oval:org.gentoo.dev.swift:tst:21" comment="sysctl net.ipv4.ip_forward must be 0" />
  </criteria>
</definition>
...
<ind-def:textfilecontent54_test id="oval:org.gentoo.dev.swift:tst:21" version="1" check="at least one" comment="sysctl net.ipv4.ip_forward must be 0" check_existence="at_least_one_exists">
  <ind-def:object object_ref="oval:org.gentoo.dev.swift:obj:6" />
  <ind-def:state state_ref="oval:org.gentoo.dev.swift:ste:18" />
</ind-def:textfilecontent54_test>
...
<ind-def:textfilecontent54_object id="oval:org.gentoo.dev.swift:obj:6" version="1" comment="Non-comment lines in /proc/sys/net/ipv4/ip_forward">
  <ind-def:filepath>/proc/sys/net/ipv4/ip_forward</ind-def:filepath>
  <ind-def:pattern operation="pattern match">^[[:space:]]*([^#[:space:]].*[^[:space:]]?)[[:space:]]*$</ind-def:pattern>
  <ind-def:instance datatype="int" operation="greater than or equal">1</ind-def:instance>
</ind-def:textfilecontent54_object>
...
<ind-def:textfilecontent54_state id="oval:org.gentoo.dev.swift:ste:18" version="1" comment="The match of 0">
  <ind-def:subexpression operation="pattern match">0</ind-def:subexpression>
</ind-def:textfilecontent54_state>

As you can see, the single line expands into more than 30 lines across two documents. Now, the OVAL language is very powerful so for more complex activities, it is imo no problem to manually sift through it. But for generic tests (like regular expression matches of files or variables) this can better be automated. And that's the purpose of genoval.sh.

Setting up genoval.sh

To setup genoval, you can git clone from my "small.coding" repository. The genoval code is in the subdirectory called genoval (har har).

Code Listing 1.2: Getting genoval.sh

$ git clone http://github.com/sjvermeu/small.coding.git

Edit the Makefile since it points to my personal directories and as such will probably not work for you ;-)

You will notice that it contains the sources for the Gentoo security benchmark as well. Consider that a nice example to work from ;-)

Defining the rules

Start by defining the rules that you want to check for. The file is called definitions.conf and currently supports the following definition lines (the highlighted parts can be changed to your liking):

Code Listing 1.3: Example definitions.conf

/home is a separate file system [rule-partition-home]
/tmp is a separate file system of type tmpfs [rule-partition-tmp]
mount point /home is mounted with nosuid option [rule-home-mount-nosuid]
file /etc/ssh/sshd_config must have a line that matches ^PermitRootLogin.*no [rule-sshd-norootlogin]
file /etc/ssh/sshd_config may not have a line that matches ^UsePAM.*yes [rule-sshd-nousepam]
sysctl net.ipv4.ip_forward must be 0 [rule-sysctl-ipv4-forward]
gentoo variable USE must contain pam [rule-gentoo-use-pam]
gentoo variable GCC_SPECS must be [rule-gentoo-gccspecs-empty]
gentoo profile must contain hardened [rule-gentoo-profile-hardened]
kernel config CONFIG_GRKERNSEC_TPE must be y [rule-kernel-grsec-tpe]
kernel config CONFIG_GRKERNSEC_USER must be enabled [rule-kernel-grsec-user]
kernel config CONFIG_GRKERNSEC_IGNOREMRE must not be set [rule-kernel-grsec-ignoremre]

The lines contain information how the system should be. It always ends with the rule name between [ and ].

Editing the XCCDF file

The XCCDF file contains the benchmark document itself (the guide that describes to the user how to harden his system). To use XCCDF with genoval.sh, edit the scap-gentoo-xccdf.xml.template file (if you use your own XML files, make sure it ends with -xccdf.xml.template). The purpose of genoval.sh here is to automatically generate Rule definitions, which you can do as follows:

Code Listing 1.4: Snippet from XCCDF for genoval


        <Group id="gt-system-kernel-sysctl-ipv4forward">
          <title>Disable IPv4 Forwarding</title>
          <description>
            The <h:code>net.ipv4.ip_forward</h:code> sysctl setting controls if
            IP forwarding is allowed or not on the system.
            <h:br />
            <h:br />
            Unless the system is used as a router or gateway, IPv4 forwarding
            should be disabled.
          </description>
          <!-- @@GEN START rule-sysctl-ipv4-forward -->
          <!-- @@GEN END rule-sysctl-ipv4-forward -->
        </Group>

The @@GEN START rule-sysctl-ipv4-forward and the END one are important here: between these lines, genoval.sh will insert the necessary Rule code. The name (rule-sysctl-ipv4-forward) is taken from the definitions.conf file.

Make sure that you add a select line in the beginning of the document on the Profile:

Code Listing 1.5: Adding a select line for rule-sysctl-ipv4-forward


  <Profile id="Gentoo-Default">
    ...
    <select idref="rule-sysctl-ipv4-forward" selected="true" />
  </Profile>

Editing the OVAL file

The OVAL content is automatically generated from the scap-gentoo-oval.xml.template file, which contains the necessary placeholders between which genoval.sh will generate the necessary lines.

If you need to add your own OVAL statements, just edit this template file but never between the START and END statements for genoval.sh!

Also, make sure that the name of the file is similar to the XCCDF one, just with oval instead of xccdf in the name.

Calling genoval.sh

To execute the magic, call genoval.sh with three arguments:

  • Name of the XCCDF template file (currect directory)
  • Namespace to use for the OVAL ids (like "org.gentoo.dev.swift")
  • Directory in which to save the results

For instance:

Code Listing 1.6: Calling genoval.sh

$ ./genoval.sh scap-gentoo-xccdf.xml.template org.gentoo.dev.swift .
File scap-gentoo-oval.xml already exists. Renaming to scap-gentoo-oval.xml.20111223134826.607527446
Loading in ./lib/00-lib-gentoo.sh...
Loading in ./lib/00-lib-sysctl.sh...
Loading in ./lib/99-lib-fix.sh...
Loading in ./lib/99-lib-general.sh...

The genoval.sh script does not just overwrite an existing OVAL file. Instead, it makes a backup first. I do this because I might want to check the differences during development.

Once generated, you can execute the following to generate a report as well as guide:

Code Listing 1.7: Running XCCDF/OVAL content

### Generate the Gentoo specific output that OVAL cannot capture otherwise
# emerge --info --verbose > emerge-info-verbose
# zcat /proc/config.gz > kernel-config || cp /usr/src/linux/.config # kernel-config
# export GENOVAL_SCRIPTOUTPUTDIR=$(pwd)

### Generate the guide in HTML format
# oscap xccdf generate guide scap-gentoo-xccdf.xml > guide.html

### Verify the local system and generate report
# oscap xccdf eval --oval-results --profile Gentoo-Default --results xccdf-results.xml --report report.html

### Generate fix script where possible
# oscap xccdf generate fix --result-id OSCAP-Test-Gentoo-Profile xccdf-results.xml > fixscript.sh


Print

Page updated December 23, 2011

Summary: To help maintain XCCDF documents as well as allow fast additions of generic topics in the documents, the genoval.sh script uses a templating-mechanism and more readable definitions (instead of XML). This document describes genoval.sh and how to use it.

Sven Vermeulen
Author

Donate to support our development efforts.

Copyright 2001-2012 Gentoo Foundation, Inc. Questions, Comments? Contact us.