Merge lp:~joeborg/charm-helpers/charm-helpers into lp:charm-helpers

Proposed by Joseph Borg
Status: Needs review
Proposed branch: lp:~joeborg/charm-helpers/charm-helpers
Merge into: lp:charm-helpers
Diff against target: 228 lines (+84/-15)
10 files modified
charmhelpers/contrib/hardening/apache/checks/config.py (+4/-1)
charmhelpers/contrib/hardening/apache/templates/hardening.conf (+3/-0)
charmhelpers/contrib/hardening/defaults/apache.yaml (+4/-2)
charmhelpers/contrib/hardening/defaults/apache.yaml.schema (+2/-0)
charmhelpers/contrib/hardening/host/checks/__init__.py (+2/-0)
charmhelpers/contrib/hardening/host/checks/openstack.py (+30/-0)
tests/contrib/hardening/apache/checks/test_config.py (+7/-3)
tests/contrib/hardening/host/checks/test_limits.py (+5/-8)
tests/contrib/hardening/host/checks/test_openstack.py (+24/-0)
tests/contrib/hardening/test_templating.py (+3/-1)
To merge this branch: bzr merge lp:~joeborg/charm-helpers/charm-helpers
Reviewer Review Type Date Requested Status
Edward Hope-Morley Needs Fixing
Ante Karamatić (community) Approve
Review via email: mp+319830@code.launchpad.net
To post a comment you must log in.
719. By Joseph Borg

Adding checks on Openstack specific files when in hardening mode

Revision history for this message
Edward Hope-Morley (hopem) wrote :

Hi Joseph, thank you for submitting a patch to charm-helpers. In general your patch looks good and unit tests are passing. I do however have one comment that i'd like you to consider;

The os module is not intended to be used for the hardening of non-system applications. I think it would be wiser, particularly given the potential scope, to have an openstack module that performs hardening of Openstack-specific resources. Alternatively, we could add support to the os module to perform perm ops on arbitrary files but that seems less clean. I'll leave it to you to decide.

review: Needs Information
Revision history for this message
Joseph Borg (joeborg) wrote :

I think that's a wise idea. I'll move it and push again.
Thanks

720. By Joseph Borg

Moving Openstack hardening audits into own module

721. By Joseph Borg

Hardening Apache ciphers

Revision history for this message
Ante Karamatić (ivoks) :
review: Needs Fixing
Revision history for this message
Ante Karamatić (ivoks) :
review: Approve
Revision history for this message
Edward Hope-Morley (hopem) wrote :

Hi Joseph, can you please add a slightly more descriptive commit message. Also you seem to have unintentionally removed traceenable from the context. With regards to my previous comment on adding a new module for openstack hardening, i meant actually adding support for an altogether new layer to the stack i.e. right now we have os/apache/ssh/mysql and I'm suggesting that we add an openstack layer. This is a somewhat non-trivial change to make but if in the long run we are planning to add more openstack-specific hardening then we should evaluate doing this. If that is not the route you want to go down then I suggest you look into finding a way to make these changes purely through config such that we can avoid having subsystem-specific code in the host module.

review: Needs Fixing
Revision history for this message
Joseph Borg (joeborg) wrote :

Hi Edward,

It was removed intentionally as it appears to be a completely redundant (and misleading) statement, please correct me if I'm wrong.

Forgive me for being a bit dense, but I don't understand the point about a new layer. I've created a new module (openstack.py) and moved the code into there. Are you talking about breaking all of the modules inside hardening up? I've not got much experience with this library (only about a month), so please forgive any ignorance my end.

Revision history for this message
Edward Hope-Morley (hopem) wrote :

Hi Joseph, yep sure I see why you removed it now that's fine. Admittedly I am overloading the term module so apologies if it is confusing. What i mean is that in the harding library we have four hardening modules i.e. "os", "mysql", "apache" and "ssh" each of which has an accompanying set of code e.g. "os" is implemented in contrib.hardening.host, "ssh" in contrib.hardning.ssh etc. What I am suggesting is that we either bite the bullet now (if we think there will be enough requirements to warrant the extra work) and implement a new hardening module called "openstack" and add the bits you need to that (i.e. setting openstack config file permissions). Another possible alternative is that we add support to the "os" module for setting permissions on arbitrary files which could be provided through configuration. My reason for saying this is principally that contrib.hardening.host is not supposed to have project specific code in it. If this patch is time-sensitive then it probably makes more sense to add support for setting permissions on arbitrary files. I also wonder whether it woud be simpler to just fix this in the charms themselves. If you fix this in charmhelpers you are going to have to sync it into the charms anyway in order for it to be used so you could just fix it straight in the charms for which a problem has been identified.

Revision history for this message
Ante Karamatić (ivoks) wrote :

Hi Ed

Joe and I had a chat about this and what we will do is amend this MP. Since we will extend OpenStack hardening even further in future, I think you are right and that should be a separate module. Please don't close this MR, as we will confine it only to apache hardening fixes.

Thanks

Revision history for this message
Joseph Borg (joeborg) wrote :

Unmerged revisions

721. By Joseph Borg

Hardening Apache ciphers

720. By Joseph Borg

Moving Openstack hardening audits into own module

719. By Joseph Borg

Adding checks on Openstack specific files when in hardening mode

718. By Joseph Borg

Enforcing Apache welcome page is deleted when hardening is enabled

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charmhelpers/contrib/hardening/apache/checks/config.py'
--- charmhelpers/contrib/hardening/apache/checks/config.py 2016-07-06 14:41:05 +0000
+++ charmhelpers/contrib/hardening/apache/checks/config.py 2017-03-17 10:36:56 +0000
@@ -26,6 +26,7 @@
26 DirectoryPermissionAudit,26 DirectoryPermissionAudit,
27 NoReadWriteForOther,27 NoReadWriteForOther,
28 TemplatedFile,28 TemplatedFile,
29 DeletedFile
29)30)
30from charmhelpers.contrib.hardening.audits.apache import DisabledModuleAudit31from charmhelpers.contrib.hardening.audits.apache import DisabledModuleAudit
31from charmhelpers.contrib.hardening.apache import TEMPLATES_DIR32from charmhelpers.contrib.hardening.apache import TEMPLATES_DIR
@@ -74,6 +75,8 @@
74 DisabledModuleAudit(settings['hardening']['modules_to_disable']),75 DisabledModuleAudit(settings['hardening']['modules_to_disable']),
7576
76 NoReadWriteForOther(settings['common']['apache_dir']),77 NoReadWriteForOther(settings['common']['apache_dir']),
78
79 DeletedFile(['/var/www/html/index.html'])
77 ]80 ]
7881
79 return audits82 return audits
@@ -94,5 +97,5 @@
94 ctxt['apache_version'] = re.search(r'.+version: Apache/(.+?)\s.+',97 ctxt['apache_version'] = re.search(r'.+version: Apache/(.+?)\s.+',
95 out).group(1)98 out).group(1)
96 ctxt['apache_icondir'] = '/usr/share/apache2/icons/'99 ctxt['apache_icondir'] = '/usr/share/apache2/icons/'
97 ctxt['traceenable'] = settings['hardening']['traceenable']100
98 return ctxt101 return ctxt
99102
=== modified file 'charmhelpers/contrib/hardening/apache/templates/hardening.conf'
--- charmhelpers/contrib/hardening/apache/templates/hardening.conf 2016-03-14 12:39:21 +0000
+++ charmhelpers/contrib/hardening/apache/templates/hardening.conf 2017-03-17 10:36:56 +0000
@@ -16,3 +16,6 @@
16</Location>16</Location>
1717
18TraceEnable {{ traceenable }}18TraceEnable {{ traceenable }}
19
20SSLHonorCipherOrder {{ honor_cipher_order }}
21SSLCipherSuite {{ cipher_suite }}
1922
=== modified file 'charmhelpers/contrib/hardening/defaults/apache.yaml'
--- charmhelpers/contrib/hardening/defaults/apache.yaml 2016-03-14 13:57:17 +0000
+++ charmhelpers/contrib/hardening/defaults/apache.yaml 2017-03-17 10:36:56 +0000
@@ -9,5 +9,7 @@
99
10hardening:10hardening:
11 traceenable: 'off'11 traceenable: 'off'
12 allowed_http_methods: "GET POST"
13 modules_to_disable: [ cgi, cgid ]
14\ No newline at end of file12\ No newline at end of file
13 allowed_http_methods: 'GET POST'
14 modules_to_disable: [ cgi, cgid ]
15 honor_cipher_order: 'on'
16 cipher_suite: 'ALL:+MEDIUM:+HIGH:!LOW:!MD5:!RC4:!eNULL:!aNULL:!3DES'
1517
=== modified file 'charmhelpers/contrib/hardening/defaults/apache.yaml.schema'
--- charmhelpers/contrib/hardening/defaults/apache.yaml.schema 2016-03-14 13:57:17 +0000
+++ charmhelpers/contrib/hardening/defaults/apache.yaml.schema 2017-03-17 10:36:56 +0000
@@ -7,3 +7,5 @@
7hardening:7hardening:
8 allowed_http_methods:8 allowed_http_methods:
9 modules_to_disable:9 modules_to_disable:
10 honor_cipher_order:
11 cipher_suite:
1012
=== modified file 'charmhelpers/contrib/hardening/host/checks/__init__.py'
--- charmhelpers/contrib/hardening/host/checks/__init__.py 2016-07-06 14:41:05 +0000
+++ charmhelpers/contrib/hardening/host/checks/__init__.py 2017-03-17 10:36:56 +0000
@@ -21,6 +21,7 @@
21 limits,21 limits,
22 login,22 login,
23 minimize_access,23 minimize_access,
24 openstack,
24 pam,25 pam,
25 profile,26 profile,
26 securetty,27 securetty,
@@ -35,6 +36,7 @@
35 checks.extend(limits.get_audits())36 checks.extend(limits.get_audits())
36 checks.extend(login.get_audits())37 checks.extend(login.get_audits())
37 checks.extend(minimize_access.get_audits())38 checks.extend(minimize_access.get_audits())
39 checks.extend(openstack.get_audits())
38 checks.extend(pam.get_audits())40 checks.extend(pam.get_audits())
39 checks.extend(profile.get_audits())41 checks.extend(profile.get_audits())
40 checks.extend(securetty.get_audits())42 checks.extend(securetty.get_audits())
4143
=== added file 'charmhelpers/contrib/hardening/host/checks/openstack.py'
--- charmhelpers/contrib/hardening/host/checks/openstack.py 1970-01-01 00:00:00 +0000
+++ charmhelpers/contrib/hardening/host/checks/openstack.py 2017-03-17 10:36:56 +0000
@@ -0,0 +1,30 @@
1# Copyright 2016 Canonical Limited.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14from charmhelpers.contrib.hardening.audits.file import DirectoryPermissionAudit
15
16
17def get_audits():
18 """
19 Get OS hardening security limits audits.
20
21 :returns: List of audits
22 """
23 audits = [
24 DirectoryPermissionAudit('/etc/openstack-dashboard', user='horizon', group='horizon', mode=0o700),
25 DirectoryPermissionAudit('/etc/cinder', user='cinder', group='cinder', mode=0o700),
26 DirectoryPermissionAudit('/etc/glance', user='glance', group='glance', mode=0o700),
27 DirectoryPermissionAudit('/etc/heat', user='heat', group='heat', mode=0o700),
28 DirectoryPermissionAudit('/etc/ceilometer', user='ceilometer', group='ceilometer', mode=0o700)
29 ]
30 return audits
031
=== modified file 'tests/contrib/hardening/apache/checks/test_config.py'
--- tests/contrib/hardening/apache/checks/test_config.py 2016-07-06 14:41:05 +0000
+++ tests/contrib/hardening/apache/checks/test_config.py 2017-03-17 10:36:56 +0000
@@ -51,14 +51,16 @@
51 @patch.object(config.subprocess, 'call', lambda *args, **kwargs: 0)51 @patch.object(config.subprocess, 'call', lambda *args, **kwargs: 0)
52 def test_get_audits_apache_is_installed(self):52 def test_get_audits_apache_is_installed(self):
53 audits = config.get_audits()53 audits = config.get_audits()
54 self.assertEqual(6, len(audits))54 self.assertEqual(7, len(audits))
5555
56 @patch.object(config.utils, 'get_settings', lambda x: {56 @patch.object(config.utils, 'get_settings', lambda x: {
57 'common': {'apache_dir': TEST_TMPDIR},57 'common': {'apache_dir': TEST_TMPDIR},
58 'hardening': {58 'hardening': {
59 'allowed_http_methods': {'GOGETEM'},59 'allowed_http_methods': {'GOGETEM'},
60 'modules_to_disable': {'modfoo'},60 'modules_to_disable': {'modfoo'},
61 'traceenable': 'off'61 'traceenable': 'off',
62 'honor_cipher_order': 'on',
63 'cipher_suite': 'ALL:+MEDIUM:+HIGH:!LOW:!MD5:!RC4:!eNULL:!aNULL:!3DES'
62 }64 }
63 })65 })
64 @patch.object(config, 'subprocess')66 @patch.object(config, 'subprocess')
@@ -77,4 +79,6 @@
77 '/usr/share/apache2/icons/',79 '/usr/share/apache2/icons/',
78 'apache_version': '2.4.7',80 'apache_version': '2.4.7',
79 'modules_to_disable': set(['modfoo']),81 'modules_to_disable': set(['modfoo']),
80 'traceenable': 'off'})82 'traceenable': 'off',
83 'honor_cipher_order': 'on',
84 'cipher_suite': 'ALL:+MEDIUM:+HIGH:!LOW:!MD5:!RC4:!eNULL:!aNULL:!3DES'})
8185
=== modified file 'tests/contrib/hardening/host/checks/test_limits.py'
--- tests/contrib/hardening/host/checks/test_limits.py 2016-07-06 14:41:05 +0000
+++ tests/contrib/hardening/host/checks/test_limits.py 2017-03-17 10:36:56 +0000
@@ -16,6 +16,7 @@
1616
17from mock import patch17from mock import patch
1818
19from charmhelpers.contrib.hardening.audits import BaseAudit
19from charmhelpers.contrib.hardening.host.checks import limits20from charmhelpers.contrib.hardening.host.checks import limits
2021
2122
@@ -26,13 +27,8 @@
26 def test_core_dump_disabled(self):27 def test_core_dump_disabled(self):
27 audits = limits.get_audits()28 audits = limits.get_audits()
28 self.assertEqual(2, len(audits))29 self.assertEqual(2, len(audits))
29 audit = audits[0]30 for audit in audits:
30 self.assertTrue(isinstance(audit, limits.DirectoryPermissionAudit))31 self.assertTrue(isinstance(audit, BaseAudit))
31 self.assertEqual('/etc/security/limits.d', audit.paths[0])
32 audit = audits[1]
33 self.assertTrue(isinstance(audit, limits.TemplatedFile))
34 self.assertEqual('/etc/security/limits.d/10.hardcore.conf',
35 audit.paths[0])
3632
37 @patch.object(limits.utils, 'get_settings', lambda x: {33 @patch.object(limits.utils, 'get_settings', lambda x: {
38 'security': {'kernel_enable_core_dump': True}34 'security': {'kernel_enable_core_dump': True}
@@ -40,4 +36,5 @@
40 def test_core_dump_enabled(self):36 def test_core_dump_enabled(self):
41 audits = limits.get_audits()37 audits = limits.get_audits()
42 self.assertEqual(1, len(audits))38 self.assertEqual(1, len(audits))
43 self.assertTrue(isinstance(audits[0], limits.DirectoryPermissionAudit))39 for audit in audits:
40 self.assertTrue(isinstance(audit, BaseAudit))
4441
=== added file 'tests/contrib/hardening/host/checks/test_openstack.py'
--- tests/contrib/hardening/host/checks/test_openstack.py 1970-01-01 00:00:00 +0000
+++ tests/contrib/hardening/host/checks/test_openstack.py 2017-03-17 10:36:56 +0000
@@ -0,0 +1,24 @@
1# Copyright 2016 Canonical Limited.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from unittest import TestCase
16from charmhelpers.contrib.hardening.host.checks import openstack
17from charmhelpers.contrib.hardening.audits.file import DirectoryPermissionAudit
18
19
20class LimitsTestCase(TestCase):
21 def test_core_dump_disabled(self):
22 audits = openstack.get_audits()
23 for audit in audits:
24 self.assertTrue(isinstance(audit, DirectoryPermissionAudit))
025
=== modified file 'tests/contrib/hardening/test_templating.py'
--- tests/contrib/hardening/test_templating.py 2016-07-06 14:41:05 +0000
+++ tests/contrib/hardening/test_templating.py 2017-03-17 10:36:56 +0000
@@ -221,7 +221,9 @@
221 'hardening': {221 'hardening': {
222 'allowed_http_methods': {'GOGETEM'},222 'allowed_http_methods': {'GOGETEM'},
223 'modules_to_disable': {'modfoo'},223 'modules_to_disable': {'modfoo'},
224 'traceenable': 'off'224 'traceenable': 'off',
225 'honor_cipher_order': 'on',
226 'cipher_suite': 'ALL:+MEDIUM:+HIGH:!LOW:!MD5:!RC4:!eNULL:!aNULL:!3DES'
225 }227 }
226 })228 })
227 @patch('charmhelpers.contrib.hardening.audits.file.os.path.exists',229 @patch('charmhelpers.contrib.hardening.audits.file.os.path.exists',

Subscribers

People subscribed via source and target branches