aboutsummaryrefslogtreecommitdiffstats
path: root/charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py')
-rw-r--r--charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py394
1 files changed, 0 insertions, 394 deletions
diff --git a/charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py b/charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py
deleted file mode 100644
index 3fb6ae8..0000000
--- a/charms/trusty/ceilometer/charmhelpers/contrib/hardening/ssh/checks/config.py
+++ /dev/null
@@ -1,394 +0,0 @@
-# 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
-
-from charmhelpers.core.hookenv import (
- log,
- DEBUG,
-)
-from charmhelpers.fetch import (
- apt_install,
- apt_update,
-)
-from charmhelpers.core.host import lsb_release
-from charmhelpers.contrib.hardening.audits.file import (
- TemplatedFile,
- FileContentAudit,
-)
-from charmhelpers.contrib.hardening.ssh import TEMPLATES_DIR
-from charmhelpers.contrib.hardening import utils
-
-
-def get_audits():
- """Get SSH hardening config audits.
-
- :returns: dictionary of audits
- """
- audits = [SSHConfig(), SSHDConfig(), SSHConfigFileContentAudit(),
- SSHDConfigFileContentAudit()]
- return audits
-
-
-class SSHConfigContext(object):
-
- type = 'client'
-
- def get_macs(self, allow_weak_mac):
- if allow_weak_mac:
- weak_macs = 'weak'
- else:
- weak_macs = 'default'
-
- default = 'hmac-sha2-512,hmac-sha2-256,hmac-ripemd160'
- macs = {'default': default,
- 'weak': default + ',hmac-sha1'}
-
- default = ('hmac-sha2-512-etm@openssh.com,'
- 'hmac-sha2-256-etm@openssh.com,'
- 'hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,'
- 'hmac-sha2-512,hmac-sha2-256,hmac-ripemd160')
- macs_66 = {'default': default,
- 'weak': default + ',hmac-sha1'}
-
- # Use newer ciphers on Ubuntu Trusty and above
- if lsb_release()['DISTRIB_CODENAME'].lower() >= 'trusty':
- log("Detected Ubuntu 14.04 or newer, using new macs", level=DEBUG)
- macs = macs_66
-
- return macs[weak_macs]
-
- def get_kexs(self, allow_weak_kex):
- if allow_weak_kex:
- weak_kex = 'weak'
- else:
- weak_kex = 'default'
-
- default = 'diffie-hellman-group-exchange-sha256'
- weak = (default + ',diffie-hellman-group14-sha1,'
- 'diffie-hellman-group-exchange-sha1,'
- 'diffie-hellman-group1-sha1')
- kex = {'default': default,
- 'weak': weak}
-
- default = ('curve25519-sha256@libssh.org,'
- 'diffie-hellman-group-exchange-sha256')
- weak = (default + ',diffie-hellman-group14-sha1,'
- 'diffie-hellman-group-exchange-sha1,'
- 'diffie-hellman-group1-sha1')
- kex_66 = {'default': default,
- 'weak': weak}
-
- # Use newer kex on Ubuntu Trusty and above
- if lsb_release()['DISTRIB_CODENAME'].lower() >= 'trusty':
- log('Detected Ubuntu 14.04 or newer, using new key exchange '
- 'algorithms', level=DEBUG)
- kex = kex_66
-
- return kex[weak_kex]
-
- def get_ciphers(self, cbc_required):
- if cbc_required:
- weak_ciphers = 'weak'
- else:
- weak_ciphers = 'default'
-
- default = 'aes256-ctr,aes192-ctr,aes128-ctr'
- cipher = {'default': default,
- 'weak': default + 'aes256-cbc,aes192-cbc,aes128-cbc'}
-
- default = ('chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,'
- 'aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr')
- ciphers_66 = {'default': default,
- 'weak': default + ',aes256-cbc,aes192-cbc,aes128-cbc'}
-
- # Use newer ciphers on ubuntu Trusty and above
- if lsb_release()['DISTRIB_CODENAME'].lower() >= 'trusty':
- log('Detected Ubuntu 14.04 or newer, using new ciphers',
- level=DEBUG)
- cipher = ciphers_66
-
- return cipher[weak_ciphers]
-
- def __call__(self):
- settings = utils.get_settings('ssh')
- if settings['common']['network_ipv6_enable']:
- addr_family = 'any'
- else:
- addr_family = 'inet'
-
- ctxt = {
- 'addr_family': addr_family,
- 'remote_hosts': settings['common']['remote_hosts'],
- 'password_auth_allowed':
- settings['client']['password_authentication'],
- 'ports': settings['common']['ports'],
- 'ciphers': self.get_ciphers(settings['client']['cbc_required']),
- 'macs': self.get_macs(settings['client']['weak_hmac']),
- 'kexs': self.get_kexs(settings['client']['weak_kex']),
- 'roaming': settings['client']['roaming'],
- }
- return ctxt
-
-
-class SSHConfig(TemplatedFile):
- def __init__(self):
- path = '/etc/ssh/ssh_config'
- super(SSHConfig, self).__init__(path=path,
- template_dir=TEMPLATES_DIR,
- context=SSHConfigContext(),
- user='root',
- group='root',
- mode=0o0644)
-
- def pre_write(self):
- settings = utils.get_settings('ssh')
- apt_update(fatal=True)
- apt_install(settings['client']['package'])
- if not os.path.exists('/etc/ssh'):
- os.makedir('/etc/ssh')
- # NOTE: don't recurse
- utils.ensure_permissions('/etc/ssh', 'root', 'root', 0o0755,
- maxdepth=0)
-
- def post_write(self):
- # NOTE: don't recurse
- utils.ensure_permissions('/etc/ssh', 'root', 'root', 0o0755,
- maxdepth=0)
-
-
-class SSHDConfigContext(SSHConfigContext):
-
- type = 'server'
-
- def __call__(self):
- settings = utils.get_settings('ssh')
- if settings['common']['network_ipv6_enable']:
- addr_family = 'any'
- else:
- addr_family = 'inet'
-
- ctxt = {
- 'ssh_ip': settings['server']['listen_to'],
- 'password_auth_allowed':
- settings['server']['password_authentication'],
- 'ports': settings['common']['ports'],
- 'addr_family': addr_family,
- 'ciphers': self.get_ciphers(settings['server']['cbc_required']),
- 'macs': self.get_macs(settings['server']['weak_hmac']),
- 'kexs': self.get_kexs(settings['server']['weak_kex']),
- 'host_key_files': settings['server']['host_key_files'],
- 'allow_root_with_key': settings['server']['allow_root_with_key'],
- 'password_authentication':
- settings['server']['password_authentication'],
- 'use_priv_sep': settings['server']['use_privilege_separation'],
- 'use_pam': settings['server']['use_pam'],
- 'allow_x11_forwarding': settings['server']['allow_x11_forwarding'],
- 'print_motd': settings['server']['print_motd'],
- 'print_last_log': settings['server']['print_last_log'],
- 'client_alive_interval':
- settings['server']['alive_interval'],
- 'client_alive_count': settings['server']['alive_count'],
- 'allow_tcp_forwarding': settings['server']['allow_tcp_forwarding'],
- 'allow_agent_forwarding':
- settings['server']['allow_agent_forwarding'],
- 'deny_users': settings['server']['deny_users'],
- 'allow_users': settings['server']['allow_users'],
- 'deny_groups': settings['server']['deny_groups'],
- 'allow_groups': settings['server']['allow_groups'],
- 'use_dns': settings['server']['use_dns'],
- 'sftp_enable': settings['server']['sftp_enable'],
- 'sftp_group': settings['server']['sftp_group'],
- 'sftp_chroot': settings['server']['sftp_chroot'],
- 'max_auth_tries': settings['server']['max_auth_tries'],
- 'max_sessions': settings['server']['max_sessions'],
- }
- return ctxt
-
-
-class SSHDConfig(TemplatedFile):
- def __init__(self):
- path = '/etc/ssh/sshd_config'
- super(SSHDConfig, self).__init__(path=path,
- template_dir=TEMPLATES_DIR,
- context=SSHDConfigContext(),
- user='root',
- group='root',
- mode=0o0600,
- service_actions=[{'service': 'ssh',
- 'actions':
- ['restart']}])
-
- def pre_write(self):
- settings = utils.get_settings('ssh')
- apt_update(fatal=True)
- apt_install(settings['server']['package'])
- if not os.path.exists('/etc/ssh'):
- os.makedir('/etc/ssh')
- # NOTE: don't recurse
- utils.ensure_permissions('/etc/ssh', 'root', 'root', 0o0755,
- maxdepth=0)
-
- def post_write(self):
- # NOTE: don't recurse
- utils.ensure_permissions('/etc/ssh', 'root', 'root', 0o0755,
- maxdepth=0)
-
-
-class SSHConfigFileContentAudit(FileContentAudit):
- def __init__(self):
- self.path = '/etc/ssh/ssh_config'
- super(SSHConfigFileContentAudit, self).__init__(self.path, {})
-
- def is_compliant(self, *args, **kwargs):
- self.pass_cases = []
- self.fail_cases = []
- settings = utils.get_settings('ssh')
-
- if lsb_release()['DISTRIB_CODENAME'].lower() >= 'trusty':
- if not settings['server']['weak_hmac']:
- self.pass_cases.append(r'^MACs.+,hmac-ripemd160$')
- else:
- self.pass_cases.append(r'^MACs.+,hmac-sha1$')
-
- if settings['server']['weak_kex']:
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
- else:
- self.pass_cases.append(r'^KexAlgorithms.+,diffie-hellman-group-exchange-sha256$') # noqa
- self.fail_cases.append(r'^KexAlgorithms.*diffie-hellman-group14-sha1[,\s]?') # noqa
-
- if settings['server']['cbc_required']:
- self.pass_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- self.fail_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.pass_cases.append(r'^Ciphers\schacha20-poly1305@openssh.com,.+') # noqa
- self.pass_cases.append(r'^Ciphers\s.*aes128-ctr$')
- self.pass_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- if not settings['client']['weak_hmac']:
- self.fail_cases.append(r'^MACs.+,hmac-sha1$')
- else:
- self.pass_cases.append(r'^MACs.+,hmac-sha1$')
-
- if settings['client']['weak_kex']:
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
- else:
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256$') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
-
- if settings['client']['cbc_required']:
- self.pass_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- self.fail_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
-
- if settings['client']['roaming']:
- self.pass_cases.append(r'^UseRoaming yes$')
- else:
- self.fail_cases.append(r'^UseRoaming yes$')
-
- return super(SSHConfigFileContentAudit, self).is_compliant(*args,
- **kwargs)
-
-
-class SSHDConfigFileContentAudit(FileContentAudit):
- def __init__(self):
- self.path = '/etc/ssh/sshd_config'
- super(SSHDConfigFileContentAudit, self).__init__(self.path, {})
-
- def is_compliant(self, *args, **kwargs):
- self.pass_cases = []
- self.fail_cases = []
- settings = utils.get_settings('ssh')
-
- if lsb_release()['DISTRIB_CODENAME'].lower() >= 'trusty':
- if not settings['server']['weak_hmac']:
- self.pass_cases.append(r'^MACs.+,hmac-ripemd160$')
- else:
- self.pass_cases.append(r'^MACs.+,hmac-sha1$')
-
- if settings['server']['weak_kex']:
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
- else:
- self.pass_cases.append(r'^KexAlgorithms.+,diffie-hellman-group-exchange-sha256$') # noqa
- self.fail_cases.append(r'^KexAlgorithms.*diffie-hellman-group14-sha1[,\s]?') # noqa
-
- if settings['server']['cbc_required']:
- self.pass_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- self.fail_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.pass_cases.append(r'^Ciphers\schacha20-poly1305@openssh.com,.+') # noqa
- self.pass_cases.append(r'^Ciphers\s.*aes128-ctr$')
- self.pass_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- if not settings['server']['weak_hmac']:
- self.pass_cases.append(r'^MACs.+,hmac-ripemd160$')
- else:
- self.pass_cases.append(r'^MACs.+,hmac-sha1$')
-
- if settings['server']['weak_kex']:
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
- else:
- self.pass_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha256$') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group14-sha1[,\s]?') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group-exchange-sha1[,\s]?') # noqa
- self.fail_cases.append(r'^KexAlgorithms\sdiffie-hellman-group1-sha1[,\s]?') # noqa
-
- if settings['server']['cbc_required']:
- self.pass_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.fail_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
- else:
- self.fail_cases.append(r'^Ciphers\s.*-cbc[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes128-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes192-ctr[,\s]?')
- self.pass_cases.append(r'^Ciphers\s.*aes256-ctr[,\s]?')
-
- if settings['server']['sftp_enable']:
- self.pass_cases.append(r'^Subsystem\ssftp')
- else:
- self.fail_cases.append(r'^Subsystem\ssftp')
-
- return super(SSHDConfigFileContentAudit, self).is_compliant(*args,
- **kwargs)