Pages

  • Home
  • CV
  • Contact me
  • Links
spacer

December 3, 2011

Unit testing your configuration files

At work, we have a lot of different services running and we end up with hundreds of thousands of configuration files in our configuration repository (especially since we don't use templates - more on that in another upcoming post...).

In order to ensure the quality of these files (avoiding syntax errors and insecure configurations alike), we had the idea of writing a system to unit test the configuration files. Being involved in Augeas, I thought it would make a great parsing backend to write the tests.

This gave birth to what is currently a Perl module called Config::Augeas::Validator, which comes with a Perl script and an SVN wrapper (this is what we used, but wrappers for other VCS are welcome) to plug it to pre- and post-commit hooks.

The module relies on Augeas (and its lenses) to parse the configuration files. On top of that, you need to specify rules (which are essentially unit test scenarii), at least one for each type of file you wish to test. A minimal rule might look like this:

[DEFAULT]
lens=Fstab
pattern=.*/fstab


This rule will tell augeas-validator to test all files whose full path matches .*/fstab against the Fstab.lns Augeas lens. If the file contains syntax errors (that is, the lens fails to parse it), the program will report it and exit with a status of 1.

Here is another simple example adding two unit tests with warnings:

[DEFAULT]
lens=PHP
pattern=.*/(php\.ini|php[45]/conf\.d/.*\.ini)

[file_uploads]
name=file_uploads
explanation=file_uploads should be set to 'Off'
type=count
expr=$file//file_uploads[. != 'Off']
value=0
level=warning
tags=security

[expose_php]
name=expose_php
explanation=expose_php should be set to 'Off'
type=count
expr=$file//expose_php[. != 'Off']
value=0
level=warning
tags=security


This test checks for php.ini files. Not only does it fail with status 1 if there is a syntax error, it also applies two unit tests called file_uploads and expose_php, which will make the program output a warning and exit with status 2 if they are not met. The essential part of the rules is the expr parameter, which is an Augeas XPath expression. In this case, the expressions must not match any nodes in order to pass the tests (hence value=0).

These are just simple examples of what this module can do. You can find more examples shipped with the module itself. As a last example, here is one for Apache configuration files (in Debian/Ubuntu):

[DEFAULT]
lens=Httpd
pattern=.*/(sites-available/.*)|(apache2/.*\.conf)

[one_servername]
name=One ServerName per VirtualHost *
explanation=There should be only one ServerName per VirtualHost * entry
type=count
expr=$file[label() != "default"]/VirtualHost[arg =~ regexp("\*(:80)?")][count(directive[. = "ServerName"]) != 1]
value=0
level=warning

[bufferedlogs]
name=BufferedLogs
explanation=BufferedLogs must be set to Off
type=count
expr=$file//directive[. = "BufferedLogs"][arg = "On"]
value=0
level=warning
tags=security

[timeout]
name=Timeout
explanation=Timeout must be at least 45
type=count
expr=$file//directive[. = "Timeout"][int(arg) < 45]
value=0
level=warning
tags=security

0 commentaires:

Newer Post Older Post Home
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.