Auditing hosts using CFEngine, EFL, and Delta Reporting
Sometimes you want to audit a host without changing it. This can be hard with CFEngine, but with EFL and Delta Reporting it's possible.
Consider these arbitrary tests:
Is vm.swappiness 60?
Is vm.swappiness not 70?
Does the hash of /etc/ssh/ssh_config match a predetermined string?
Is ntp configured to start at boot time?
Is ftpd not configured to start at boot time?
Testing is all about classes in CFEngine. Whether or not a class is set determines the results of your test. EFL has many bundles for creating classes. Two of them, efl_class_cmd_regcmp and efl_class_returnszero, I'll use to make the above tests. I'm assuming that you have some knowledge of CFEngine and EFL.
The first three tests can be accomplished by testing the output of a command with a regular expression. I'll use the bundle efl_class_cmd_regcmp for that. Here is the parameter file:
[
{
"class": "any",
"class_to_set": "vm_swappiness_is_60",
"command" : "/sbin/sysctl vm.swappiness",
"regex" : "\Qvm.swappiness = 60\E",
"expression" : "expression",
"useshell" : "noshell",
"promisee" : "infosec audit"
},
{
"class": "any",
"class_to_set": "vm_swappiness_is_not_70",
"command" : "/sbin/sysctl vm.swappiness",
"regex" : "\Qvm.swappiness = 70\E",
"expression" : "not",
"useshell" : "noshell",
"promisee" : "infosec audit"
},
{
"class": "any",
"class_to_set": "ssh_config_hash_is_6005ad62cd337cecbe177097cc74f0052eb15de92713eccd57c2e22fb162eaef",
"command" : "/usr/bin/sha256sum /etc/ssh/ssh_config",
"regex" : "(?x) 6005ad62cd337cecbe177097cc74f0052eb15de92713eccd57c2e22fb162eaef \s+ /etc/ssh/ssh_config",
"expression" : "expression",
"useshell" : "noshell",
"promisee" : "infosec audit"
}
]
The last two tests can be performed by testing the return value of chkconfig. I'll use the bundle efl_class_returnszero for that. Here is the parameter file:
[
{
"class" : "any",
"class_to_set" : "ntpd_boot_startup_enabled",
"command" : "/sbin/chkconfig -c ntp",
"zero" : "yes",
"shell" : "noshell",
"promisee" : "infosec audit"
},
{
"class" : "any",
"class_to_set" : "ftpd_boot_startup_disabled",
"command" : "/sbin/chkconfig -c ftpd",
"zero" : "no",
"shell" : "noshell",
"promisee" : "infosec audit"
}
]
Both bundles will be run using EFL's efl_main bundle, which I won't show here. I also want some pretty and testable output. I can use EFL's efl_test_classes bundle for that. (see TAP and EFL). Here is the parameter file:
[
{
"class" : "any",
"class_to_test" : "vm_swappiness_is_60",
"test_type" : "is",
"name" : "Testing if vm.swappiness is 60"
},
{
"class" : "any",
"class_to_test" : "vm_swappiness_is_not_70",
"test_type" : "is",
"name" : "Testing if vm.swappiness is not 70"
},
{
"class" : "any",
"class_to_test" : "ssh_config_hash_is_6005ad62cd337cecbe177097cc74f0052eb15de92713eccd57c2e22fb162eaef",
"test_type" : "is",
"name" : "Testing if ssh_config is the correct file"
},
{
"class" : "any",
"class_to_test" : "ntpd_boot_startup_enabled",
"test_type" : "is",
"name" : "Testing if ntpd boot start is enabled"
},
{
"class" : "any",
"class_to_test" : "ftpd_boot_startup_disabled",
"test_type" : "is",
"name" : "Testing if ftpd boot start is disabled"
}
]
Now the output (note that cf-agent 3.7.0 spewed a bunch of warnings about JSON and escape characters. I think they are harmless. You can see the bug report here.):
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
1..5
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
ok 1 - Testing if vm.swappiness is 60
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
ok 2 - Testing if vm.swappiness is not 70
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
ok 3 - Testing if ssh_config is the correct file
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
ok 4 - Testing if ntpd boot start is enabled
R: _home_neil__cfagent_inputs_test_efl_test_classes_json_4b703cc338ec6c24abbc72019bea6929482d0a38
ok 5 - Testing if ftpd boot start is disabled
Success! For this host anyway, but suppose I have many hosts. Enter Delta Reporting. By integrating the first two bundles into my production policy I can use DR to search for class membership.
Auditing hosts using Delta Reporting[/caption]
Without writing any new CFEngine policy I was able to audit my hosts in a safe and passive manner. I hope you'll try this for yourself and feel free to contact us for help.