-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add charmhelpers.contrib.hardening and calls to install, config-changed, upgrade-charm and update-status hooks. Also add new config option to allow one or more hardening modules to be applied at runtime. Change-Id: If0d1e10b58ed506e0aca659f30120b8d5c96c04f
- Loading branch information
Showing
69 changed files
with
3,941 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ include: | |
- contrib.network.ip | ||
- contrib.python.packages | ||
- contrib.charmsupport | ||
- contrib.hardening|inc=* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Juju charm-helpers hardening library | ||
|
||
## Description | ||
|
||
This library provides multiple implementations of system and application | ||
hardening that conform to the standards of http://hardening.io/. | ||
|
||
Current implementations include: | ||
|
||
* OS | ||
* SSH | ||
* MySQL | ||
* Apache | ||
|
||
## Requirements | ||
|
||
* Juju Charms | ||
|
||
## Usage | ||
|
||
1. Synchronise this library into your charm and add the harden() decorator | ||
(from contrib.hardening.harden) to any functions or methods you want to use | ||
to trigger hardening of your application/system. | ||
|
||
2. Add a config option called 'harden' to your charm config.yaml and set it to | ||
a space-delimited list of hardening modules you want to run e.g. "os ssh" | ||
|
||
3. Override any config defaults (contrib.hardening.defaults) by adding a file | ||
called hardening.yaml to your charm root containing the name(s) of the | ||
modules whose settings you want override at root level and then any settings | ||
with overrides e.g. | ||
|
||
os: | ||
general: | ||
desktop_enable: True | ||
|
||
4. Now just run your charm as usual and hardening will be applied each time the | ||
hook runs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright 2016 Canonical Limited. | ||
# | ||
# This file is part of charm-helpers. | ||
# | ||
# charm-helpers is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License version 3 as | ||
# published by the Free Software Foundation. | ||
# | ||
# charm-helpers is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Copyright 2016 Canonical Limited. | ||
# | ||
# This file is part of charm-helpers. | ||
# | ||
# charm-helpers is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License version 3 as | ||
# published by the Free Software Foundation. | ||
# | ||
# charm-helpers is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
from os import path | ||
|
||
TEMPLATES_DIR = path.join(path.dirname(__file__), 'templates') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright 2016 Canonical Limited. | ||
# | ||
# This file is part of charm-helpers. | ||
# | ||
# charm-helpers is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License version 3 as | ||
# published by the Free Software Foundation. | ||
# | ||
# charm-helpers is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
from charmhelpers.core.hookenv import ( | ||
log, | ||
DEBUG, | ||
) | ||
from charmhelpers.contrib.hardening.apache.checks import config | ||
|
||
|
||
def run_apache_checks(): | ||
log("Starting Apache hardening checks.", level=DEBUG) | ||
checks = config.get_audits() | ||
for check in checks: | ||
log("Running '%s' check" % (check.__class__.__name__), level=DEBUG) | ||
check.ensure_compliance() | ||
|
||
log("Apache hardening checks complete.", level=DEBUG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Copyright 2016 Canonical Limited. | ||
# | ||
# This file is part of charm-helpers. | ||
# | ||
# charm-helpers is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License version 3 as | ||
# published by the Free Software Foundation. | ||
# | ||
# charm-helpers is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
import os | ||
import re | ||
import subprocess | ||
|
||
|
||
from charmhelpers.core.hookenv import ( | ||
log, | ||
INFO, | ||
) | ||
from charmhelpers.contrib.hardening.audits.file import ( | ||
FilePermissionAudit, | ||
DirectoryPermissionAudit, | ||
NoReadWriteForOther, | ||
TemplatedFile, | ||
) | ||
from charmhelpers.contrib.hardening.audits.apache import DisabledModuleAudit | ||
from charmhelpers.contrib.hardening.apache import TEMPLATES_DIR | ||
from charmhelpers.contrib.hardening import utils | ||
|
||
|
||
def get_audits(): | ||
"""Get Apache hardening config audits. | ||
:returns: dictionary of audits | ||
""" | ||
if subprocess.call(['which', 'apache2'], stdout=subprocess.PIPE) != 0: | ||
log("Apache server does not appear to be installed on this node - " | ||
"skipping apache hardening", level=INFO) | ||
return [] | ||
|
||
context = ApacheConfContext() | ||
settings = utils.get_settings('apache') | ||
audits = [ | ||
FilePermissionAudit(paths='/etc/apache2/apache2.conf', user='root', | ||
group='root', mode=0o0640), | ||
|
||
TemplatedFile(os.path.join(settings['common']['apache_dir'], | ||
'mods-available/alias.conf'), | ||
context, | ||
TEMPLATES_DIR, | ||
mode=0o0755, | ||
user='root', | ||
service_actions=[{'service': 'apache2', | ||
'actions': ['restart']}]), | ||
|
||
TemplatedFile(os.path.join(settings['common']['apache_dir'], | ||
'conf-enabled/hardening.conf'), | ||
context, | ||
TEMPLATES_DIR, | ||
mode=0o0640, | ||
user='root', | ||
service_actions=[{'service': 'apache2', | ||
'actions': ['restart']}]), | ||
|
||
DirectoryPermissionAudit(settings['common']['apache_dir'], | ||
user='root', | ||
group='root', | ||
mode=0o640), | ||
|
||
DisabledModuleAudit(settings['hardening']['modules_to_disable']), | ||
|
||
NoReadWriteForOther(settings['common']['apache_dir']), | ||
] | ||
|
||
return audits | ||
|
||
|
||
class ApacheConfContext(object): | ||
"""Defines the set of key/value pairs to set in a apache config file. | ||
This context, when called, will return a dictionary containing the | ||
key/value pairs of setting to specify in the | ||
/etc/apache/conf-enabled/hardening.conf file. | ||
""" | ||
def __call__(self): | ||
settings = utils.get_settings('apache') | ||
ctxt = settings['hardening'] | ||
|
||
out = subprocess.check_output(['apache2', '-v']) | ||
ctxt['apache_version'] = re.search(r'.+version: Apache/(.+?)\s.+', | ||
out).group(1) | ||
ctxt['apache_icondir'] = '/usr/share/apache2/icons/' | ||
ctxt['traceenable'] = settings['hardening']['traceenable'] | ||
return ctxt |
Empty file.
31 changes: 31 additions & 0 deletions
31
charmhelpers/contrib/hardening/apache/templates/alias.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
############################################################################### | ||
# WARNING: This configuration file is maintained by Juju. Local changes may | ||
# be overwritten. | ||
############################################################################### | ||
<IfModule alias_module> | ||
# | ||
# Aliases: Add here as many aliases as you need (with no limit). The format is | ||
# Alias fakename realname | ||
# | ||
# Note that if you include a trailing / on fakename then the server will | ||
# require it to be present in the URL. So "/icons" isn't aliased in this | ||
# example, only "/icons/". If the fakename is slash-terminated, then the | ||
# realname must also be slash terminated, and if the fakename omits the | ||
# trailing slash, the realname must also omit it. | ||
# | ||
# We include the /icons/ alias for FancyIndexed directory listings. If | ||
# you do not use FancyIndexing, you may comment this out. | ||
# | ||
Alias /icons/ "{{ apache_icondir }}/" | ||
|
||
<Directory "{{ apache_icondir }}"> | ||
Options -Indexes -MultiViews -FollowSymLinks | ||
AllowOverride None | ||
{% if apache_version == '2.4' -%} | ||
Require all granted | ||
{% else -%} | ||
Order allow,deny | ||
Allow from all | ||
{% endif %} | ||
</Directory> | ||
</IfModule> |
18 changes: 18 additions & 0 deletions
18
charmhelpers/contrib/hardening/apache/templates/hardening.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
############################################################################### | ||
# WARNING: This configuration file is maintained by Juju. Local changes may | ||
# be overwritten. | ||
############################################################################### | ||
|
||
<Location / > | ||
<LimitExcept {{ allowed_http_methods }} > | ||
# http://httpd.apache.org/docs/2.4/upgrading.html | ||
{% if apache_version > '2.2' -%} | ||
Require all granted | ||
{% else -%} | ||
Order Allow,Deny | ||
Deny from all | ||
{% endif %} | ||
</LimitExcept> | ||
</Location> | ||
|
||
TraceEnable {{ traceenable }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright 2016 Canonical Limited. | ||
# | ||
# This file is part of charm-helpers. | ||
# | ||
# charm-helpers is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License version 3 as | ||
# published by the Free Software Foundation. | ||
# | ||
# charm-helpers is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
class BaseAudit(object): # NO-QA | ||
"""Base class for hardening checks. | ||
The lifecycle of a hardening check is to first check to see if the system | ||
is in compliance for the specified check. If it is not in compliance, the | ||
check method will return a value which will be supplied to the. | ||
""" | ||
def __init__(self, *args, **kwargs): | ||
self.unless = kwargs.get('unless', None) | ||
super(BaseAudit, self).__init__() | ||
|
||
def ensure_compliance(self): | ||
"""Checks to see if the current hardening check is in compliance or | ||
not. | ||
If the check that is performed is not in compliance, then an exception | ||
should be raised. | ||
""" | ||
pass | ||
|
||
def _take_action(self): | ||
"""Determines whether to perform the action or not. | ||
Checks whether or not an action should be taken. This is determined by | ||
the truthy value for the unless parameter. If unless is a callback | ||
method, it will be invoked with no parameters in order to determine | ||
whether or not the action should be taken. Otherwise, the truthy value | ||
of the unless attribute will determine if the action should be | ||
performed. | ||
""" | ||
# Do the action if there isn't an unless override. | ||
if self.unless is None: | ||
return True | ||
|
||
# Invoke the callback if there is one. | ||
if hasattr(self.unless, '__call__'): | ||
results = self.unless() | ||
if results: | ||
return False | ||
else: | ||
return True | ||
|
||
if self.unless: | ||
return False | ||
else: | ||
return True |
Oops, something went wrong.