diff --git a/cfbs.json b/cfbs.json index 549f89d..58e4358 100644 --- a/cfbs.json +++ b/cfbs.json @@ -167,6 +167,15 @@ "subdirectory": "management/every-minute", "steps": ["json def.json def.json"] }, + "inventory-selinux-modules": { + "description": "Inventory installed SELinux modules and their enabled/disabled status.", + "subdirectory": "security/inventory-selinux-modules", + "steps": [ + "copy main.cf services/cfbs/modules/inventory-selinux-modules/main.cf", + "policy_files services/cfbs/modules/inventory-selinux-modules/main.cf", + "bundles inventory_selinux:semodule_list_modules" + ] + }, "inventory-unshadowed-users": { "description": "Adds reporting data (inventory) on local users in /etc/passwd not using /etc/shadow for their password.", "subdirectory": "security/inventory-unshadowed-users", diff --git a/security/inventory-selinux-modules/README.org b/security/inventory-selinux-modules/README.org new file mode 100644 index 0000000..aa72e9a --- /dev/null +++ b/security/inventory-selinux-modules/README.org @@ -0,0 +1,15 @@ +This module inventories the SELinux Modules that are installed. + +* Inventory +- SELinux Modules Enabled :: SELinux Modules that are installed and not disabled. +- SELinux Modules Disabled :: SELinux Modules that are installed and disabled. + +[[https://raw.githubusercontent.com/cfengine/modules/master/security/inventory-selinux-modules/inventory-selinux-modules.png]] + +* Configuration +** Variables +- =inventory_selinux:semodule_list_modules.hours_cached= :: Number of hours to cache the output from ~semodule --list-modules=full~. + +* Requirements + +The ~semodule~ command is required for inventory to be reported. diff --git a/security/inventory-selinux-modules/inventory-selinux-modules.png b/security/inventory-selinux-modules/inventory-selinux-modules.png new file mode 100644 index 0000000..fe3e424 Binary files /dev/null and b/security/inventory-selinux-modules/inventory-selinux-modules.png differ diff --git a/security/inventory-selinux-modules/main.cf b/security/inventory-selinux-modules/main.cf new file mode 100644 index 0000000..84bea63 --- /dev/null +++ b/security/inventory-selinux-modules/main.cf @@ -0,0 +1,74 @@ +body file control +{ + namespace => "inventory_selinux"; +} + +bundle agent semodule_list_modules +{ + classes: + "_$(this.namespace)_$(this.bundle)_supported_platform" + if => isexecutable( "$(path[semodule])"); + + vars: + "path[semodule]" + string => ifelse( isexecutable("/sbin/semodule"), "/sbin/semodule", + isexecutable("/usr/sbin/semodule"), "/usr/sbin/semodule", + "" ), + meta => { "paths.cf" }; + + _inventory_selinux_semodule_list_modules_supported_platform:: + "hours_cached" + string => "1", + if => not( isvariable( hours_cached )); + + "cache_file" + string => "$(sys.statedir)/$(this.namespace)_$(this.bundle).txt"; + + "cache_file_age" + string => filestat( $(cache_file), mtime ), + if => fileexists( "$(cache_file)" ); + + # Example $(cache_file) content + # 400 cfengine-enterprise pp + # 200 container pp + # 100 wine pp disabled + # 100 wireshark pp + + + "d" data => data_readstringarrayidx( "$(cache_file)", + "", + "\s+", + inf, + inf), + if => fileexists( $(cache_file) ); + + "i" slist => getindices( "d" ); + + # Inventory enabled and disabled selinux modules + "enabled[$(i)]" + string => "$(d[$(i)][1])", + if => strcmp( "$(d[$(i)][3])", "" ), + meta => { "inventory", "attribute_name=SELinux Modules Enabled" }; + + "disabled[$(i)]" + string => "$(d[$(i)][1])", + if => strcmp( "$(d[$(i)][3])", "disabled" ), + meta => { "inventory", "attribute_name=SELinux Modules Disabled" }; + + files: + _inventory_selinux_semodule_list_modules_supported_platform:: + # Delete the cache file if it's older than hours_cached + "$(cache_file)" + delete => default:tidy, + if => isgreaterthan( + format( "%d", eval( "$(sys.systime)-$(cache_file_age)" )), # now minus mtime of cache file + format( "%d", eval( "$(hours_cached)*60*60" ))); # cache minutes + commands: + _inventory_selinux_semodule_list_modules_supported_platform:: + "/sbin/semodule" + arglist => { "--list-modules=full", + ">", "$(cache_file)" }, + contain => default:in_shell, # Required for redirection + if => not( fileexists( $(cache_file) )); + +}