In a previous post I wrote about the documentation structure I have in mind for a PostgreSQL security best practice. Considering what XCCDF can give us, the idea is to have the following structure:

Hardening PostgreSQL
+- Basic setup
+- Instance level configuration
|  +- Pre-startup configuration
|  `- PostgreSQL internal configuration
+- Database recommendations
`- User definitions

For the profiles, I had:

+- administrator
+- end user
`- functional account

Let's bring this into an XCCDF document.

The XCCDF (Extensible Configuration Checklist Description Format) format is an XML structure in which we can document whatever we want - but it is primarily used for configuration checklists and best practices. The documenting aspect of a security best practice in XCCDF is done through XHTML basic tags (do not use fancy things - limit yourself to p, pre, em, strong, ... tags), so some knowledge on XHTML (next to XML in general) is quite important while developing XCCDF guides. At least, if you don't use special editors for that.

We start with the basics:

``` {lang="xml"}

PostgreSQL Best Practices

This document describes how to securely set up PostgreSQL on a Gentoo Linux platform,
making it more resilient against attacks and vulnerabilities.
Two things I want to focus on here: the `xmlns:h` and `id` attributes.

-   The `xmlns:h` attribute is an XML requirement, telling whatever XML
    parser is used later that tags that use the `h:` namespace is for
    XHTML tags. So later in the document, we'll use `<h:p>...</h:p>` for
    XHTML paragraphs.
-   The `id` attribute is XCCDF specific, and since XCCDF 1.2 also
    requires to be in this particular syntax:


    The `<namespace>` is recommended to be an inverted domain
    name structure. I also added my nickname so there are no collisions
    with namespaces provided by other developers in Gentoo. So *SwifT's* becomes **.

This id structure will be used in other tags as well. Instead of
`*_benchmark` it would be `*_rule` (for `Rule` ids), `*_group` (for
`Group` ids), etc. You get the idea.

Now we add in some metadata in the document (with `Benchmark` as

``` {lang="xml"}


So what is all this?

  • The <status> tag helps in tracking the state of the document.
  • The <platform> tag is to tell the XCCDF interpreter when the document is applicable. It references a CPE (Common Platform Enumeration) entity, in this case for PostgreSQL. Later, we will see that an automated test is assigned to the detection of this CPE. If the test succeeds, then PostgreSQL is installed and the XCCDF interpreter can continue testing and evaluating the system for PostgreSQL best practices. If not, then PostgreSQL is not installed and the XCCDF does not apply to the system.

    There is a huge advantage to this: you can check all your systems for compliance with the PostgreSQL best practices (this XCCDF document) and on the systems that PostgreSQL is not installed, it will simply state that the document is not applicable (without actually trying to validate all the rules in the document). So there is no direct need to only check systems you know have PostgreSQL on (and thus potentially ignore systems that have PostgreSQL but that you don't know of - usually those systems are much less secure as well ;-).

  • The <version> tag versions the document.
  • The <model> tags tell the XCCDF interpreter which scoring system should be used.

    Scoring will give points to rules, and the XCCDF interpreter will sum the scores of all rules to give a final score to the "compliance" state of the system. But scoring can be done on several levels. The default one uses the hierarchy of the document (nested Groups and Rules) to give a final number whereas the flat one does not care about the structure. Finally, the flat-unweighted one does not take into account the scores given by the author - all rules get the value of 1.

Now we define the Profiles to use. I will give the example for two: user and administrator, you can fill in the other ones ;-)

``` {lang="xml"}

User profile

This profile defines the basic security measures to be applied against a database
user (role in PostgreSQL parlance).

Administrator profile

This profile extends the user profile with those rules specific to administrators,
such as stronger password requirements.
Finally, the `Group`s (still with `Benchmark` as their parent, but below
the `Profile`s) which define the documentation structure of the guide:

``` {lang="xml"}



  Basic setup

  Instance level configuration

    Pre-startup configuration

    PostgreSQL internal configuration

With all this defined, our basic skeleton for the PostgreSQL best practice document is ready. To create proper content, we can use the XHTML code inside the <description> tags, like so:

``` {lang="xml"}

Considering these pros and cons, it is recommended to have at least the following file system locations to be on a different file system:

/tmp as this is a world-writable location and requires specific mount options. When possible, this location can be made a tmpfs file system. This is to protect the root file system from being flooded.

/var as this contains variable data (and thus is prone to grow extensively depending on the installed services). This is to protect the root file system from being flooded.

As said in the previous post though, just documenting various aspects is
not enough. It is recommended to add references. In XCCDF, this is done
through the `<reference>` tag, which is within a `Group` and usually
below the `<description>` information:

``` {lang="xml"}

  Resource Guide,...

With this alone, it is already possible to write up an XCCDF guide describing how to securely setup (in our case) PostgreSQL while keeping track of the resources that helped define the secure setup. Tools like openscap can generate HTML or even Docbook (which in turn can be converted to manual pages, PDF, Word, RTF, ...) from this information:

# oscap xccdf generate guide --format docbook --output guide.docbook postgresql-xccdf.xml

In the next post, I'll talk about the other documenting entities within XCCDF (besides <description> and their meaning) and start with enhancing the document with automated checks.


To comment as a guest, use "Or sign up with disqus" and then select the "I'd rather post as guest" option.

comments powered by Disqus