def test_settings_cache(self, mock_get_user_provided_overrides): mock_get_user_provided_overrides.return_value = {} self.assertEqual(utils.__SETTINGS__, {}) self.assertTrue('sysctl' in utils.get_settings('os')) self.assertEqual(sorted(list(six.iterkeys(utils.__SETTINGS__))), ['os']) self.assertTrue('server' in utils.get_settings('ssh')) self.assertEqual(sorted(list(six.iterkeys(utils.__SETTINGS__))), ['os', 'ssh'])
def test_settings_cache(self, mock_get_user_provided_overrides): mock_get_user_provided_overrides.return_value = {} self.assertEqual(utils.__SETTINGS__, {}) self.assertTrue('sysctl' in utils.get_settings('os')) self.assertEqual(sorted(list(six.iterkeys(utils.__SETTINGS__))), ['os']) self.assertTrue('server' in utils.get_settings('ssh')) self.assertEqual(sorted(list(six.iterkeys(utils.__SETTINGS__))), ['os', 'ssh'])
def get_audits(): """Get OS hardening security limits audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') # Ensure that the /etc/security/limits.d directory is only writable # by the root user, but others can execute and read. audits.append( DirectoryPermissionAudit('/etc/security/limits.d', user='******', group='root', mode=0o755)) # If core dumps are not enabled, then don't allow core dumps to be # created as they may contain sensitive information. if not settings['security']['kernel_enable_core_dump']: audits.append( TemplatedFile('/etc/security/limits.d/10.hardcore.conf', SecurityLimitsContext(), template_dir=TEMPLATES_DIR, user='******', group='root', mode=0o0440)) return audits
def __call__(self): settings = utils.get_settings('os') ctxt = { 'disable_core_dump': not settings['security']['kernel_enable_core_dump'] } return ctxt
def __call__(self): settings = utils.get_settings('os') # Octal numbers in yaml end up being turned into decimal, # so check if the umask is entered as a string (e.g. '027') # or as an octal umask as we know it (e.g. 002). If its not # a string assume it to be octal and turn it into an octal # string. umask = settings['environment']['umask'] if not isinstance(umask, string_types): umask = '%s' % oct(umask) ctxt = { 'additional_user_paths': settings['environment']['extra_user_paths'], 'umask': umask, 'pwd_max_age': settings['auth']['pw_max_age'], 'pwd_min_age': settings['auth']['pw_min_age'], 'uid_min': settings['auth']['uid_min'], 'sys_uid_min': settings['auth']['sys_uid_min'], 'sys_uid_max': settings['auth']['sys_uid_max'], 'gid_min': settings['auth']['gid_min'], 'sys_gid_min': settings['auth']['sys_gid_min'], 'sys_gid_max': settings['auth']['sys_gid_max'], 'login_retries': settings['auth']['retries'], 'login_timeout': settings['auth']['timeout'], 'chfn_restrict': settings['auth']['chfn_restrict'], 'allow_login_without_home': settings['auth']['allow_homeless'] } return ctxt
def __call__(self): settings = utils.get_settings('mysql') # Translate for python3 return { 'mysql_settings': [(k, v) for k, v in six.iteritems(settings['security'])] }
def __call__(self): settings = utils.get_settings('os') # Octal numbers in yaml end up being turned into decimal, # so check if the umask is entered as a string (e.g. '027') # or as an octal umask as we know it (e.g. 002). If its not # a string assume it to be octal and turn it into an octal # string. umask = settings['environment']['umask'] if not isinstance(umask, string_types): umask = '%s' % oct(umask) ctxt = { 'additional_user_paths': settings['environment']['extra_user_paths'], 'umask': umask, 'pwd_max_age': settings['auth']['pw_max_age'], 'pwd_min_age': settings['auth']['pw_min_age'], 'uid_min': settings['auth']['uid_min'], 'sys_uid_min': settings['auth']['sys_uid_min'], 'sys_uid_max': settings['auth']['sys_uid_max'], 'gid_min': settings['auth']['gid_min'], 'sys_gid_min': settings['auth']['sys_gid_min'], 'sys_gid_max': settings['auth']['sys_gid_max'], 'login_retries': settings['auth']['retries'], 'login_timeout': settings['auth']['timeout'], 'chfn_restrict': settings['auth']['chfn_restrict'], 'allow_login_without_home': settings['auth']['allow_homeless'] } return ctxt
def get_audits(): """Get OS hardening access audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') # Remove write permissions from $PATH folders for all regular users. # This prevents changing system-wide commands from normal users. path_folders = {'/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/bin'} extra_user_paths = settings['environment']['extra_user_paths'] path_folders.update(extra_user_paths) audits.append(ReadOnly(path_folders)) # Only allow the root user to have access to the shadow file. audits.append(FilePermissionAudit('/etc/shadow', 'root', 'root', 0o0600)) if 'change_user' not in settings['security']['users_allow']: # su should only be accessible to user and group root, unless it is # expressly defined to allow users to change to root via the # security_users_allow config option. audits.append(FilePermissionAudit('/bin/su', 'root', 'root', 0o750)) return audits
def __call__(self): ctxt = {} settings = utils.get_settings('os') ctxt['auth_lockout_time'] = settings['auth']['lockout_time'] ctxt['auth_retries'] = settings['auth']['retries'] return ctxt
def __call__(self): ctxt = {} settings = utils.get_settings('os') ctxt['auth_pam_passwdqc_options'] = \ settings['auth']['pam_passwdqc_options'] return ctxt
def __call__(self): ctxt = {} settings = utils.get_settings('os') ctxt['auth_lockout_time'] = settings['auth']['lockout_time'] ctxt['auth_retries'] = settings['auth']['retries'] return ctxt
def __call__(self): ctxt = {} settings = utils.get_settings('os') ctxt['auth_pam_passwdqc_options'] = \ settings['auth']['pam_passwdqc_options'] return ctxt
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 __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
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
def __call__(self): settings = utils.get_settings('os') ctxt = {'sysctl': {}} log("Applying sysctl settings", level=INFO) extras = {'net_ipv4_ip_forward': 0, 'net_ipv6_conf_all_forwarding': 0, 'net_ipv6_conf_all_disable_ipv6': 1, 'net_ipv4_tcp_timestamps': 0, 'net_ipv4_conf_all_arp_ignore': 0, 'net_ipv4_conf_all_arp_announce': 0, 'kernel_sysrq': 0, 'fs_suid_dumpable': 0, 'kernel_modules_disabled': 1} if settings['sysctl']['ipv6_enable']: extras['net_ipv6_conf_all_disable_ipv6'] = 0 if settings['sysctl']['forwarding']: extras['net_ipv4_ip_forward'] = 1 extras['net_ipv6_conf_all_forwarding'] = 1 if settings['sysctl']['arp_restricted']: extras['net_ipv4_conf_all_arp_ignore'] = 1 extras['net_ipv4_conf_all_arp_announce'] = 2 if settings['security']['kernel_enable_module_loading']: extras['kernel_modules_disabled'] = 0 if settings['sysctl']['kernel_enable_sysrq']: sysrq_val = settings['sysctl']['kernel_secure_sysrq'] extras['kernel_sysrq'] = sysrq_val if settings['security']['kernel_enable_core_dump']: extras['fs_suid_dumpable'] = 1 settings.update(extras) for d in (SYSCTL_DEFAULTS % settings).split(): d = d.strip().partition('=') key = d[0].strip() path = os.path.join('/proc/sys', key.replace('.', '/')) if not os.path.exists(path): log("Skipping '%s' since '%s' does not exist" % (key, path), level=WARNING) continue ctxt['sysctl'][key] = d[2] or None # Translate for python3 return {'sysctl_settings': [(k, v) for k, v in six.iteritems(ctxt['sysctl'])]}
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='******', group='root', mode=0o0640), TemplatedFile(os.path.join(settings['common']['apache_dir'], 'mods-available/alias.conf'), context, TEMPLATES_DIR, mode=0o0755, user='******', service_actions=[{ 'service': 'apache2', 'actions': ['restart'] }]), TemplatedFile(os.path.join(settings['common']['apache_dir'], 'conf-enabled/hardening.conf'), context, TEMPLATES_DIR, mode=0o0640, user='******', service_actions=[{ 'service': 'apache2', 'actions': ['restart'] }]), DirectoryPermissionAudit(settings['common']['apache_dir'], user='******', group='root', mode=0o640), DisabledModuleAudit(settings['hardening']['modules_to_disable']), NoReadWriteForOther(settings['common']['apache_dir']), ] return audits
def get_audits(): """Get OS hardening apt audits. :returns: dictionary of audits """ audits = [AptConfig([{'key': 'APT::Get::AllowUnauthenticated', 'expected': 'false'}])] settings = get_settings('os') clean_packages = settings['security']['packages_clean'] if clean_packages: security_packages = settings['security']['packages_list'] if security_packages: audits.append(RestrictedPackages(security_packages)) return audits
def get_audits(): """Get MySQL hardening config audits. :returns: dictionary of audits """ if subprocess.call(['which', 'mysql'], stdout=subprocess.PIPE) != 0: log( "MySQL does not appear to be installed on this node - " "skipping mysql hardening", level=WARNING) return [] settings = utils.get_settings('mysql') hardening_settings = settings['hardening'] my_cnf = hardening_settings['mysql-conf'] audits = [ FilePermissionAudit(paths=[my_cnf], user='******', group='root', mode=0o0600), TemplatedFile(hardening_settings['hardening-conf'], MySQLConfContext(), TEMPLATES_DIR, mode=0o0750, user='******', group='root', service_actions=[{ 'service': 'mysql', 'actions': ['restart'] }]), # MySQL and Percona charms do not allow configuration of the # data directory, so use the default. DirectoryPermissionAudit('/var/lib/mysql', user='******', group='mysql', recursive=False, mode=0o755), DirectoryPermissionAudit('/etc/mysql', user='******', group='root', recursive=False, mode=0o700), ] return audits
def get_audits(): """Get OS hardening profile audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') # If core dumps are not enabled, then don't allow core dumps to be # created as they may contain sensitive information. if not settings['security']['kernel_enable_core_dump']: audits.append(TemplatedFile('/etc/profile.d/pinerolo_profile.sh', ProfileContext(), template_dir=TEMPLATES_DIR, mode=0o0755, user='******', group='root')) return audits
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='******', group='root', mode=0o0640), TemplatedFile(os.path.join(settings['common']['apache_dir'], 'mods-available/alias.conf'), context, TEMPLATES_DIR, mode=0o0755, user='******', service_actions=[{'service': 'apache2', 'actions': ['restart']}]), TemplatedFile(os.path.join(settings['common']['apache_dir'], 'conf-enabled/hardening.conf'), context, TEMPLATES_DIR, mode=0o0640, user='******', service_actions=[{'service': 'apache2', 'actions': ['restart']}]), DirectoryPermissionAudit(settings['common']['apache_dir'], user='******', group='root', mode=0o640), DisabledModuleAudit(settings['hardening']['modules_to_disable']), NoReadWriteForOther(settings['common']['apache_dir']), ] return audits
def get_audits(): """Get OS hardening PAM authentication audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') if settings['auth']['pam_passwdqc_enable']: audits.append(PasswdqcPAM('/etc/passwdqc.conf')) if settings['auth']['retries']: audits.append(Tally2PAM('/usr/share/pam-configs/tally2')) else: audits.append(DeletedFile('/usr/share/pam-configs/tally2')) return audits
def get_audits(): """Get OS hardening PAM authentication audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') if settings['auth']['pam_passwdqc_enable']: audits.append(PasswdqcPAM('/etc/passwdqc.conf')) if settings['auth']['retries']: audits.append(Tally2PAM('/usr/share/pam-configs/tally2')) else: audits.append(DeletedFile('/usr/share/pam-configs/tally2')) return audits
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
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
def get_audits(): """Get MySQL hardening config audits. :returns: dictionary of audits """ if subprocess.call(['which', 'mysql'], stdout=subprocess.PIPE) != 0: log("MySQL does not appear to be installed on this node - " "skipping mysql hardening", level=WARNING) return [] settings = utils.get_settings('mysql') hardening_settings = settings['hardening'] my_cnf = hardening_settings['mysql-conf'] audits = [ FilePermissionAudit(paths=[my_cnf], user='******', group='root', mode=0o0600), TemplatedFile(hardening_settings['hardening-conf'], MySQLConfContext(), TEMPLATES_DIR, mode=0o0750, user='******', group='root', service_actions=[{'service': 'mysql', 'actions': ['restart']}]), # MySQL and Percona charms do not allow configuration of the # data directory, so use the default. DirectoryPermissionAudit('/var/lib/mysql', user='******', group='mysql', recursive=False, mode=0o755), DirectoryPermissionAudit('/etc/mysql', user='******', group='root', recursive=False, mode=0o700), ] return audits
def __call__(self): settings = utils.get_settings('os') with open('/proc/cpuinfo', 'r') as fd: cpuinfo = fd.readlines() for line in cpuinfo: match = re.search(r"^vendor_id\s+:\s+(.+)", line) if match: vendor = match.group(1) if vendor == "GenuineIntel": vendor = "intel" elif vendor == "AuthenticAMD": vendor = "amd" ctxt = {'arch': platform.processor(), 'cpuVendor': vendor, 'desktop_enable': settings['general']['desktop_enable']} return ctxt
def get_audits(): """Get OS hardening apt audits. :returns: dictionary of audits """ audits = [ AptConfig([{ 'key': 'APT::Get::AllowUnauthenticated', 'expected': 'false' }]) ] settings = get_settings('os') clean_packages = settings['security']['packages_clean'] if clean_packages: security_packages = settings['security']['packages_list'] if security_packages: audits.append(RestrictedPackages(security_packages)) return audits
def get_audits(): """Get OS hardening suid/sgid audits. :returns: dictionary of audits """ checks = [] settings = utils.get_settings('os') if not settings['security']['suid_sgid_enforce']: log("Skipping suid/sgid hardening", level=INFO) return checks # Build the blacklist and whitelist of files for suid/sgid checks. # There are a total of 4 lists: # 1. the system blacklist # 2. the system whitelist # 3. the user blacklist # 4. the user whitelist # # The blacklist is the set of paths which should NOT have the suid/sgid bit # set and the whitelist is the set of paths which MAY have the suid/sgid # bit setl. The user whitelist/blacklist effectively override the system # whitelist/blacklist. u_b = settings['security']['suid_sgid_blacklist'] u_w = settings['security']['suid_sgid_whitelist'] blacklist = set(BLACKLIST) - set(u_w + u_b) whitelist = set(WHITELIST) - set(u_b + u_w) checks.append(NoSUIDSGIDAudit(blacklist)) dry_run = settings['security']['suid_sgid_dry_run_on_unknown'] if settings['security']['suid_sgid_remove_from_unknown'] or dry_run: # If the policy is a dry_run (e.g. complain only) or remove unknown # suid/sgid bits then find all of the paths which have the suid/sgid # bit set and then remove the whitelisted paths. root_path = settings['environment']['root_path'] unknown_paths = find_paths_with_suid_sgid(root_path) - set(whitelist) checks.append(NoSUIDSGIDAudit(unknown_paths, unless=dry_run)) return checks
def get_audits(): """Get OS hardening sysctl audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') # Apply the sysctl settings which are configured to be applied. audits.append(SysctlConf()) # Make sure that only root has access to the sysctl.conf file, and # that it is read-only. audits.append(FilePermissionAudit('/etc/sysctl.conf', user='******', group='root', mode=0o0440)) # If module loading is not enabled, then ensure that the modules # file has the appropriate permissions and rebuild the initramfs if not settings['security']['kernel_enable_module_loading']: audits.append(ModulesTemplate()) return audits
def get_audits(): """Get OS hardening security limits audits. :returns: dictionary of audits """ audits = [] settings = utils.get_settings('os') # Ensure that the /etc/security/limits.d directory is only writable # by the root user, but others can execute and read. audits.append(DirectoryPermissionAudit('/etc/security/limits.d', user='******', group='root', mode=0o755)) # If core dumps are not enabled, then don't allow core dumps to be # created as they may contain sensitive information. if not settings['security']['kernel_enable_core_dump']: audits.append(TemplatedFile('/etc/security/limits.d/10.hardcore.conf', SecurityLimitsContext(), template_dir=TEMPLATES_DIR, user='******', group='root', mode=0o0440)) return audits
def __call__(self): settings = utils.get_settings('os') ctxt = {'ttys': settings['auth']['root_ttys']} return ctxt
def __call__(self): settings = utils.get_settings('os') ctxt = {'ttys': settings['auth']['root_ttys']} return ctxt
def __call__(self): settings = utils.get_settings('mysql') # Translate for python3 return {'mysql_settings': [(k, v) for k, v in six.iteritems(settings['security'])]}
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\[email protected],.+') # 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)
def __call__(self): settings = utils.get_settings('os') ctxt = {'disable_core_dump': not settings['security']['kernel_enable_core_dump']} return ctxt