1
- Nova
2
- ====
1
+ Introduction
2
+ ============
3
+
4
+ Nova is designed to audit the compliance and security level of a system. It is
5
+ composed of multiple modules, which ingest YAML configuration profiles to run a
6
+ single or series of audits against a system.
7
+
8
+ Two different installation methods are outlined below. The first method is more
9
+ stable (and therefore recommended). This method uses Salt's package manager to
10
+ track versioned, packaged updates to Hubble's components.
3
11
4
- Nova plugins are designed specifically for auditing the compliance and security level
5
- of an existing system. These plugins are designed to alow an administrator to
6
- run security checks or even groups of security checks within their SaltStack
7
- installation. This allows for real-time insight into the compliance level of
8
- running systems.
12
+ The second method installs directly from git. It should be considered bleeding
13
+ edge and possibly unstable.
9
14
10
15
Installation
11
16
============
12
17
13
- Place `hubble.py <_modules/hubble.py >`_ in your ``_modules/ `` directory in your Salt
14
- fileserver (whether roots or gitfs) and sync it to the minion.
18
+ Each of the four HubbleStack components have been packaged for use with Salt's
19
+ Package Manager (SPM). Note that all SPM installation commands should be done
20
+ on the *Salt Master *.
15
21
16
- Create a ``hubblestack_nova `` directory in the root of your Salt fileserver's
17
- ``base `` environment. Inside of this directory, create a directory tree to
18
- organize your audit modules. Place any desired audit modules into this
19
- directory tree, along with any supporting files (yaml files, etc). Nova audits
20
- are targeted via this directory structure, with an optional filter on tags
22
+ **Required Configuration **
21
23
22
- The directory/environment in which nova searches for audit modules are
23
- configurable via pillar. The defaults are shown below :
24
+ Salt's Package Manager (SPM) installs files into `` /srv/spm/{salt,pillar} ``.
25
+ Ensure that this path is defined in your Salt Master's `` file_roots `` :
24
26
25
27
.. code-block :: yaml
26
28
27
- hubblestack.nova.dir : salt://hubblestack_nova
28
- hubblestack.nova.saltenv : base
29
+ file_roots :
30
+ - /srv/salt
31
+ - /srv/spm/salt
29
32
30
- Usage
31
- =====
33
+ .. note :: This should be the default value. To verify run: ``salt-call config.get file_roots``
32
34
33
- There are three functions in the hubble.py module. ``hubble.sync `` will sync the
34
- configured ``hubblestack_nova/ `` directory to the minion. ``hubble.load `` will
35
- load the synced audit modules and their yaml configuration files. Finally,
36
- ``hubble.audit `` will run the audits.
35
+ .. tip :: Remember to restart the Salt Master after making this change to the configuration.
37
36
38
- By default, ``hubble.audit `` will call ``hubble.load `` (which in turn calls
39
- ``hubble.sync ``) (in order to ensure that it is auditing with the most up-to-date
40
- information. These operations are fairly fast, but if you want to avoid the
41
- additional overhead, you can disable these behaviors via pillar (defaults are
42
- shown, change to False to disable behaviors):
37
+ Installation (Packages)
38
+ -----------------------
43
39
44
- .. code-block :: yaml
40
+ Installation is as easy as downloading and installing a package. (Note: in
41
+ future releases you'll be able to subscribe directly to our HubbleStack SPM
42
+ repo for updates and bugfixes!)
43
+
44
+ .. code-block :: shell
45
+
46
+ wget https://spm.hubblestack.io/2016.7.0/hubblestack_nova-2016.7.0-1.spm
47
+ spm local install hubblestack_nova-2016.7.0-1.spm
48
+
49
+ You should now be able to sync the new modules to your minion(s) using the
50
+ ``sync_modules `` Salt utility:
51
+
52
+ .. code-block :: shell
53
+
54
+ salt \* saltutil.sync_modules
55
+
56
+ Once these modules are synced you are ready to run a HubbleStack Nova audit.
57
+
58
+ Skip to [Usage].
45
59
46
- hubblestack.nova.autosync : True
47
- hubblestack.nova.autoload : True
60
+ Installation (Manual)
61
+ ---------------------
62
+
63
+ Place ``_modules/hubble.py `` into your ``salt/_modules/ `` directory, and sync
64
+ it to the minions.
65
+
66
+ .. code-block :: shell
67
+
68
+ git clone https://github.com/hubblestack/nova.git hubblestack-nova.git
69
+ cd hubblestack-nova.git
70
+ mkdir -p /srv/salt/_modules/
71
+ cp _modules/hubble.py /srv/salt/_modules/
72
+ cp -a hubblestack_nova /srv/salt/
73
+
74
+ salt \* saltutil.sync_modules
75
+ salt \* hubble.sync
76
+
77
+ Usage
78
+ =====
79
+
80
+ There are four primary functions in the hubble.py module:
81
+
82
+ 1. ``hubble.sync `` will sync the ``hubblestack_nova/ `` directory to the minion(s).
83
+ 2. ``hubble.load `` will load the synced audit modules and their yaml configuration files.
84
+ 3. ``hubble.audit `` will audit the minion(s) using the YAML profile(s) you provide as comma-separated arguments
85
+ 4. ``hubble.top `` will audit the minion(s) using the ``top.nova `` configuration.
48
86
49
87
``hubble.audit `` takes two optional arguments. The first is a comma-separated
50
- list of paths. These paths can be files or directories. If a path is a
51
- directory, all modules below that directory will be run. If it is a file, that
52
- file will be run .
88
+ list of paths. These paths can be files or directories within the
89
+ `` hubblestack_nova `` directory. The second argument allows for toggling Nova
90
+ configuration, such as verbosity, level of detail, etc .
53
91
54
- The second argument is a glob pattern, against which audit tags will be
55
- matched. All audits have an accompanying tag. Nova modules are designed to take
56
- this argument, compare it to each tag that module handles, and only run those
57
- which match the argument (using ``fnmatch ``).
92
+ If ``hubble.audit `` is run without targeting any audit configs or directories,
93
+ it will instead run ``hubble.top `` with no arguments.
58
94
59
95
``hubble.audit `` will return a list of audits which were successful, and a list
60
96
of audits which failed.
@@ -63,17 +99,136 @@ Here are some example calls:
63
99
64
100
.. code-block :: bash
65
101
66
- # Run all yaml configs and tags under salt://hubblestack_nova/
67
- salt ' * ' hubble.audit
102
+ # Run the cve scanner and the CIS profile:
103
+ salt \* hubble.audit cve.scan-v2,cis.centos-7-level-1-scored-v1
68
104
69
- # Run all yaml configs and tags under salt://hubblestack_nova/foo/
70
- # Will also run salt://hubblestack_nova/foo.yaml if it exists
71
- salt ' *' hubble.audit modules=foo
105
+ # Run hubble.top with the default topfile (top.nova)
106
+ salt \* hubble.top
72
107
73
108
# Run all yaml configs and tags under salt://hubblestack_nova/foo/ and
74
109
# salt://hubblestack_nova/bar, but only run audits with tags starting
75
110
# with "CIS"
76
- salt ' *' hubble.audit modules=foo,bar tags=' CIS*'
111
+ salt \* hubble.audit foo,bar tags=' CIS*'
112
+
113
+
114
+ Nova Topfiles
115
+ -------------
116
+
117
+ Nova topfiles look very similar to saltstack topfiles, except the top-level
118
+ key is always ``nova ``, as nova doesn't have environments.
119
+
120
+ .. code-block :: yaml
121
+
122
+ nova :
123
+ ' * ' :
124
+ - cve.scan-v2
125
+ - network.ssh
126
+ - network.smtp
127
+ ' web* ' :
128
+ - cis.centos-7-level-1-scored-v1
129
+ - cis.centos-7-level-2-scored-v1
130
+ ' G@os_family:debian ' :
131
+ - network.ssh
132
+ - cis.debian-7-level-1-scored : ' CIS*'
133
+
134
+ Additionally, all nova topfile matches are compound matches, so you never
135
+ need to define a match type like you do in saltstack topfiles.
136
+
137
+ Each list item is a string representing the dot-separated location of a
138
+ yaml file which will be run with hubble.audit. You can also specify a
139
+ tag glob to use as a filter for just that yaml file, using a colon
140
+ after the yaml file (turning it into a dictionary). See the last two lines
141
+ in the yaml above for examples.
142
+
143
+ Examples:
144
+
145
+ .. code-block :: bash
146
+
147
+ salt ' *' hubble.top
148
+ salt ' *' hubble.top foo/bar/top.nova
149
+ salt ' *' hubble.top foo/bar.nova verbose=True
150
+
151
+
152
+ Compensating Control Configuration
153
+ ----------------------------------
154
+
155
+ In some cases, your organization may want to skip certain audit checks for
156
+ certain hosts. This is supported via compensating control configuration.
157
+
158
+ You can skip a check globally by adding a ``control: <reason> `` key to the check
159
+ itself. This key should be added at the same level as ``description `` and
160
+ ``trigger `` pieces of a check. In this case, the check will never run, and will
161
+ output under the ``Controlled `` results key.
162
+
163
+ Nova also supports separate control profiles, for more fine-grained control
164
+ using topfiles. You can use a separate YAML top-level key called ``control ``.
165
+ Generally, you'll put this top-level key inside of a separate YAML file and
166
+ only include it in the top-data for the hosts for which it is relevant.
167
+
168
+ For these separate control configs, the audits will always run, whether they
169
+ are controlled or not. However, controlled audits which fail will be converted
170
+ from ``Failure `` to ``Controlled `` in a post-processing operation.
171
+
172
+ The control config syntax is as follows:
173
+
174
+ .. code-block :: yaml
175
+
176
+ control :
177
+ - CIS-2.1.4 : This is the reason we control the check
178
+ - some_other_tag :
179
+ reason : This is the reason we control the check
180
+ - a_third_tag_with_no_reason
181
+
182
+ Note that providing a reason for the control is optional. Any of the three
183
+ formats shown in the yaml list above will work.
184
+
185
+ Once you have your compensating control config, just target the yaml to the
186
+ hosts you want to control using your topfile. In this case, all the audits will
187
+ still run, but if any of the controlled checks fail, they will be removed from
188
+ ``Failure `` and added to ``Controlled ``, and will be treated as a Success for
189
+ the purposes of compliance percentage.
190
+
191
+
192
+ Schedule
193
+ --------
194
+
195
+ In order to run the audits once daily, you can use the following schedule:
196
+
197
+ .. code-block :: yaml
198
+
199
+ schedule :
200
+ nova_day :
201
+ function : hubble.top
202
+ seconds : 86400
203
+
204
+ Configuration
205
+ =============
206
+
207
+ Under the Hood
208
+ ==============
209
+
210
+ 1. The directory/environment in which nova searches for audit modules are
211
+ configurable via pillar. The defaults are shown below:
212
+
213
+ .. code-block :: yaml
214
+
215
+ hubblestack :
216
+ nova :
217
+ saltenv : base
218
+ dir : salt://hubblestack_nova
219
+
220
+ 2. By default, ``hubble.audit `` will call ``hubble.load `` (which in turn calls
221
+ ``hubble.sync ``) in order to ensure that it is auditing with the most up-to-date
222
+ information. These operations are fairly fast, but if you want to avoid the
223
+ additional overhead, you can disable these behaviors via pillar (defaults are
224
+ shown, change to False to disable behaviors):
225
+
226
+ .. code-block :: yaml
227
+
228
+ hubblestack :
229
+ nova :
230
+ autosync : True
231
+ autoload : True
77
232
78
233
Development
79
234
===========
@@ -114,14 +269,17 @@ include full documentation
114
269
return True
115
270
116
271
117
- def audit (data_list , tag , verbose = False ):
272
+ def audit (data_list , tag , verbose = False , show_profile = False , debug = False ):
118
273
__tags__ = []
119
- for data in data_list:
274
+ for profile, data in data_list:
120
275
# This is where you process the dictionaries passed in by hubble.py,
121
276
# searching for data pertaining to this audit module. Modules which
122
277
# require no data should use yaml which is empty except for a
123
278
# top-level key, and should only do work if the top-level key is
124
279
# found in the data
280
+
281
+ # if show_profile is True, then we need to also inject the profile
282
+ # in the data for each check so that it appears in verbose output
125
283
pass
126
284
127
285
ret = {' Success' : [], ' Failure' : []}
@@ -137,17 +295,29 @@ All Nova plugins require a ``__virtual__()`` function to determine module
137
295
compatibility, and an ``audit() `` function to perform the actual audit
138
296
functionality
139
297
140
- The ``audit() `` function must take three arguments, ``data_list ``, ``tag `` and
141
- ``verbose ``. The ``data_list `` argument is a list of dictionaries passed in by
142
- ``hubble.py ``. ``hubble.py `` gets this data from loading the specified yaml for
143
- the audit run. Your audit module should only run if it finds its own data in
144
- this list. The ``tag `` argument is a glob expression for which tags the audit
145
- function should run. It is the job of the audit module to compare the ``tag ``
146
- glob with all tags supported by this module and only run the audits which
147
- match. The ``verbose `` argument defines whether additional information should
148
- be returned for audits, such as description and remediation instructions.
149
-
150
- The return value should be a dictionary, with two keys, "Success" and
151
- "Failure". The values for these keys should be a list of tags as strings, or a
152
- list of dictionaries containing tags and other information for the audit (in
153
- the case of ``verbose ``).
298
+ The ``audit() `` function must take four arguments, ``data_list ``, ``tag ``,
299
+ ``verbose ``, ``show_profile ``, and ``debug ``. The ``data_list `` argument is a
300
+ list of dictionaries passed in by ``hubble.py ``. ``hubble.py `` gets this data
301
+ from loading the specified yaml for the audit run. Your audit module should
302
+ only run if it finds its own data in this list. The ``tag `` argument is a glob
303
+ expression for which tags the audit function should run. It is the job of the
304
+ audit module to compare the ``tag `` glob with all tags supported by this module
305
+ and only run the audits which match. The ``verbose `` argument defines whether
306
+ additional information should be returned for audits, such as description and
307
+ remediation instructions. The ``show_profile `` argument tells whether the
308
+ profile should be injected into the verbose data for each check. The ``debug ``
309
+ argument tells whether the module should log additional debugging information
310
+ at debug log level.
311
+
312
+ The return value should be a dictionary, with optional keys "Success",
313
+ "Failure", and "Controlled". The values for these keys should be a list of
314
+ one-key dictionaries in the form of ``{<tag>: <string_description>} ``, or a
315
+ list of one-key dictionaries in the form of ``{<tag>: <data_dict>} `` (in the
316
+ case of ``verbose ``).
317
+
318
+ Contribute
319
+ ==========
320
+
321
+ If you are interested in contributing or offering feedback to this project feel
322
+ free to submit an issue or a pull request. We're very open to community
323
+ contribution.
0 commit comments