Solaris 11.2 – Compliance beyond the basics

In my first post on Compliance in Solaris 11.2 (Solaris 11.2 – Compliance Basics) I covered the very basics that need to be known to get started. With this post I want to show where to find the data and how to customize it for your own needs.
I will use many code examples and try to keep the prose to a minimum in order to get a little how-to feeling.

Compliance’s files are located under /usr/lib/compliance

ROOT@zone1 > ls -l /usr/lib/compliance/
total 68
drwxr-xr-x   5 root     sys            5 Jan 29 15:45 benchmarks
drwxr-xr-x   2 root     sys          224 Jan 29 15:45 tests

As you can see the structure is quiet simple. In /usr/lib/compliance/benchmarks everything needed to run a benchmark with the compliance command will be found. /usr/lib/compliance/tests is the directory where all the test files are. Let’s take a quick look at it.

ROOT@zone1 > ls -l /usr/lib/compliance/tests/
total 1799
-r-xr-xr-x   1 root     bin         3429 Jan 29 15:37 OSC-01010-apache-cpe-oval.xml
-r-xr-xr-x   1 root     bin          328 Jan 29 15:37 OSC-01511-aslr-sce.sh
-r-xr-xr-x   1 root     bin         1821 Jan 29 15:37 OSC-02000-audit-baseline-sce.sh
-r-xr-xr-x   1 root     bin         1836 Jan 29 15:37 OSC-02001-audit-recommended-sce.sh
-r-xr-xr-x   1 root     bin         4755 Jan 29 15:37 OSC-02511-audit-daemons-cpe-oval.xml
-r-xr-xr-x   1 root     bin          473 Jan 29 15:37 OSC-03000-audit-roles-use-cusa-class-sce.sh
-r-xr-xr-x   1 root     bin         3640 Jan 29 15:37 OSC-03511-autofs-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4862 Jan 29 15:37 OSC-04010-avahi-bridge-dsd-cpe-oval.xml
...

We will get back to what those tests look like later on and will now move on with the other directory /usr/lib/compliance/benchmarks.
Keep in mind the components compliance uses are tests, benchmarks, and profiles.

ROOT@zone1 > compliance list -p    
Benchmarks:
pci-dss:        Solaris_PCI-DSS
solaris:        Baseline, Recommended
ROOT@zone1 > ls -l /usr/lib/compliance/benchmarks/
total 9
drwxr-xr-x   2 root     sys            5 Jan 29 15:39 pci-dss
drwxr-xr-x   2 root     sys            5 Jan 29 15:39 solaris

The benchmarks the compliance command lists seem to be named the same as these directories. Actually that is no coincidence. These directories define your benchmarks. Before I will show you the magic and all the steps needed to create your own benchmark we will check out the inside of the solaris directory.

ROOT@zone1 > ls -l /usr/lib/compliance/benchmarks/solaris/
total 519
-r-xr-xr-x   1 root     bin       252349 Jan 29 15:38 solaris-xccdf.xml
lrwxrwxrwx   1 root     root          11 Jan 29 15:39 tests -> ../../tests
lrwxrwxrwx   1 root     root          17 Jan 29 15:39 xccdf.xml -> solaris-xccdf.xml

One xml file and two links. There is really nothing to say about the links. The xccdf.xml (solaris-xccdf.xml) is the configuration file of this particular benchmark.
Easy and simple so far, right?!
Let’s add some customization. You could either go ahead and change the existing benchmarks (eg. tests, profiles, definitions, etc.) or create one on your own (that’s what we really want!). In order to do so copy one of the benchmark folders with all the files and links and name it what ever you feel like. Keep in mind the name of the directory will be the name the compliance command will use and show. After that adjust the xccdf.xml names (file and link) if you like.

ROOT@zone1 > cp -rpP /usr/lib/compliance/benchmarks/solaris /usr/lib/compliance/benchmark/ivv
ROOT@zone1 > ls -l /usr/lib/compliance/benchmarks/ivv/
total 775
-r-xr-xr-x   1 root     bin       338683 Jan 27 14:39 ivv-xccdf.xml
lrwxrwxrwx   1 root     root          11 Jan 29 15:45 tests -> ../../tests
lrwxrwxrwx   1 root     root          13 Jan 29 15:45 xccdf.xml -> ivv-xccdf.xml

Well congratulations! You just created your first benchmark.

ROOT@zone1 > compliance list
Benchmarks:
        ivv
        pci-dss
        solaris
...

Still simple and straight forward. The next thing is the most annoying part. Editing the ivv-xccdf.xml (in this case). But the good thing is this only needs to be done once if you create a benchmark and profile with every tests there is. After that you will just have to turn the tests on and off.
I will not show all the thousands of lines of code. But rather walk you through the interesting parts of it.
The first 14 lines will mostly never be touched. Line 16 though is the internal title of your benchmark followed by a few other information that you might want to customize.

  <status>accepted</status>
  <title>ivv Oracle Solaris Security Policy</title>
  <description>
    ivv-xccdf.xml
  </description>
  <version>ivv Solaris 11</version>

But the real deal actually starts now. Line 21 indicates that the profile section will start from here.

  <!-- profile-ivvBaseline.xml -->
  <Profile id="ivvBaseline">
    <title>ivv Solaris Baseline Security Policy</title>
    <select idref="ivv-000" selected="true" />
    <select idref="ivv-001" selected="false" /> <!--gz no ldap-->
    <select idref="OSC-54005" selected="true" />
    <select idref="OSC-53005" selected="true" />
    <select idref="OSC-53505" selected="true" />
    <select idref="OSC-16005" selected="true" />
    <select idref="OSC-15000" selected="true" />
    <select idref="OSC-14000" selected="true" />
    <select idref="OSC-90000" selected="true" />
    <select idref="OSC-90500" selected="true" />
    <select idref="OSC-91005" selected="true" />
    <select idref="OSC-13000" selected="true" />
    <select idref="OSC-13500" selected="true" />
    <select idref="OSC-91505" selected="true" />
    <select idref="OSC-78000" selected="false" />
    <select idref="OSC-17000" selected="true" />
    <select idref="OSC-16500" selected="false" />

The Profile id in line 22 is the name that the compliance command will show.

ROOT@zone1 > compliance list -p
Benchmarks:
ivv:    ivvBaseline
pci-dss:        Solaris_PCI-DSS
solaris:        Baseline, Recommended

So what else do we see? Another title but more interesting we see lines with idref and selected values. The idref will be simply referenced further down in this xml-file by the appropriate rule. This value is also part of the name of the test. That way the engineers asure that a test will only be there once and no matter which benchmark or profile you use it will always be named the same. No more confusion. Thanks a lot for this, dear engineering team! ;) This differs in the initial release of Solaris 11.2!
Back to the xccdf.xml. If you want to add any tests to your profile simply add it like it’s done in line 24 and 25.
The values true and false are used to turn tests “on/off” within a profile.
In my case, since I added every single test that came with the installation and added some of my own tests to the profile, line 249 is where the first Group starts.
By default all tests’ rules are grouped based on the topic. If you want you could also go ahead and use on big group for all.

  <!-- Begin Section 0 "ivv" -->
  <Group id="Section_0" weight="1.0">
    <title xml:lang="en-US">Verify Compliance Integrity</title>
    <description>The compliance tests and benchmarks have not been touched.
      <xhtml:br/>For more information, see:
      <xhtml:ul><xhtml:li>Bart Guide (http://www.oracle.com/pls/topic/lookup?ctx=solaris11&amp;id=IOSUI)</xhtml:li><xhtml:li>Security Guidelines (http://www.oracle.com/pls/topic/lookup?ctx=solaris11&amp;id=SYSADV7)</xhtml:li></xhtml:ul>
      <xhtml:br />
      In this section, you verify Compliance(1M) integrity, ensure that tests and benchmarks
      have not been edited.
    </description>
    <Rule id="ivv-000" weight="1.0" role="full" severity="high">
      <title xml:lang="en-US">Compliance integrity is given</title>
      <description>Compliance tests and benchmarks should not have been edited to ensure
      integrity.
      </description>
      <fixtext fixref="ivv-000-ref">
        Files have been edited. Please check files and create new manifest.
      </fixtext>
      <fix id="ivv-000-fix">
  # ls -lR /usr/lib/compliance
      </fix>
      <check system="http://open-scap.org/page/SCE">
        <check-import import-name="stdout" />
        <check-content-ref href="tests/ivv-000-check-compliance-integrity-sce.sh" />
      </check>
    </Rule>
...
</Group>

In this example I added my own group with the id=Section_0 to the profile. This section will be first to run. The order of when tests are run is not given be the profile section but rather by the order of the groups and their rules. Since I put my own group and rule infront of the others my test will be the first to run.
If you remember my first post on Compliance the details of the html report did show a handfull of information. Even more when a test failed. This is now the point where all this is defined. Lines 250-258 are only group related. In line 259 the actual rule for the first test starts. The id of the rule is very important. This id is what you will have to use as value for the idref in your profile section. The next few lines are what will be shown in the report. In this case you can see that the integrity of compliance is checked in some way and you will be told that the files have been edited when this test fails. Just edit title, description, fixtext and fix as needed. This obviously depends on what your test is doing.
Next up is check in line 270. This is the place where we decide what kind of check/test system will be used for this rule. In this case it is SCE (Script Check Engine). If you want to use oval for your tests instead change it to system=”http://oval.mitre.org/XMLSchema/oval-definitions-5″. Obviously the test has to match the given check system. href is the path to the test file itself.
The important thing is, if you don’t have a rule defined the test will not run. If you have a rule but no select entry in your profile it will still run the test. Yes, this is how it works. In order for a defined rule not to run you need to change the selected value to false!!!
That’s it! Seems a lot on the first view but actually all you need to know is:

  1. add/edit your rule in the group section
  2. add/edit the select entry in the profile section

All that is left is the test. Let’s look at the one I used in my rule above.

ROOT@zone1 > ls -l /usr/lib/compliance/tests
...
-r-xr-xr-x   1 root     bin          592 Jan 29 15:37 OSC-94501-users-local-have-home-dirs-sce.sh
-r-xr-xr-x   1 root     bin         3544 Jan 29 15:37 OSC-95011-utmp-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4559 Jan 29 15:37 OSC-95510-uucp-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4710 Jan 29 15:37 OSC-96011-vnc-config-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4595 Jan 29 15:37 OSC-96510-wall-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4609 Jan 29 15:37 OSC-97010-xfs-cpe-oval.xml
-r-xr-xr-x   1 root     bin         5298 Jan 29 15:37 OSC-97511-zones-cpe-oval.xml
-r-xr-xr-x   1 root     bin         4780 Jan 29 15:37 OSC-98011-zones-install-cpe-oval.xml
-r-xr-xr-x   1 root     root         558 Jan 27 13:51 ivv-000-check-compliance-integrity-sce.sh
-r-xr-xr-x   1 root     root         284 Jan 27 13:51 ivv-001-check-ldapclient-configuration-sce.sh

The above is the end of the listing. As you can see Oracle ships sce and oval files. I decided to go for SCE since this is pretty much regular shell scripting with the right (special) return code.

ROOT@zone1 > cat /usr/lib/compliance/tests/ivv-000-check-compliance-integrity-sce.sh
#!/bin/sh
#
# ivv-000-check-compliance-integrity-sce.sh
BART_MANIFEST="/var/tmp/test_0.1"
COMPARE_MANIFEST="/opt/compliance-bart/compare-manifest"
bart create -a sha512 -R /usr/lib/compliance/ > $BART_MANIFEST
SHOULD_BE_EMPTY=$(bart compare $COMPARE_MANIFEST $BART_MANIFEST 2>/dev/null)

if [[ $SHOULD_BE_EMPTY != "" ]]; then
        bart compare $COMPARE_MANIFEST $BART_MANIFEST 2> /dev/null
        rm $BART_MANIFEST
        exit $XCCDF_RESULT_FAIL
fi

rm $BART_MANIFEST 
exit $XCCDF_RESULT_PASS

As you can see bart is used to create a manifest (BART_MANIFEST) of /usr/lib/compliance and every file/folder inside of it. This manifest will be compared with a manifest that was manually created earlier and in this case stored under /opt/… which is read-only. Read-only because this is inside an immutable zone (flexible-configuration) and that way the file and the containing checksums cannot be changed from within the zone. If the compare doesn’t run into any errors it will remove the just created manifest and exit with the return code $XCCDF_RESULT_PASS. Should the compare lead to any differences of the checksums the return code $XCCDF_RESULT_FAIL is used. This will fail the test and depending of what your rule definition includes show the information on what went wrong and how to fix it.

And again, this is all there is to it. It might seem to be a lot but I wanted to show every single step that is needed to create your ow benchmark that fits your needs the best. In the end all that has to be done is copy & paste and a bit of editing. For the tests just copy an existing one and edit it.
It is simple!!! And by the way, it is free and an open standard called OpenSCAP.

If you want an even deeper view into Compliance(1M) and see how it uses oscap truss it or check out the python code of compliance itself. ;)

3 Replies to “Solaris 11.2 – Compliance beyond the basics”

  1. Pingback: Deploying automated CVE reporting for Solaris 11.3 | onlinedevice

  2. Pingback: Benefits of Solaris Immutable Zones – onlinedevice

  3. Pingback: Tailoring meets Solaris Compliance – onlinedevice

Leave a Reply

Your email address will not be published. Required fields are marked *