Revert "Add apparmor template for nova compute services"
Reverting initial support for AppArmor as this change had some un-intended side-effects and the profiles still need further work. This reverts commit b08fe049066c0519bfab06d871780d45f1b48062. Change-Id: I8538b491bc0c6bd3ad02ac0b1d4fda190b137c41
This commit is contained in:
parent
240a80062b
commit
fda0a0da41
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,7 +5,3 @@ bin
|
|||||||
tags
|
tags
|
||||||
*.sw[nop]
|
*.sw[nop]
|
||||||
*.pyc
|
*.pyc
|
||||||
trusty/
|
|
||||||
xenial/
|
|
||||||
tests/cirros-*-disk.img
|
|
||||||
.unit-state.db
|
|
||||||
|
@ -276,9 +276,3 @@ options:
|
|||||||
description: |
|
description: |
|
||||||
Apply system hardening. Supports a space-delimited list of modules
|
Apply system hardening. Supports a space-delimited list of modules
|
||||||
to run. Supported modules currently include os, ssh, apache and mysql.
|
to run. Supported modules currently include os, ssh, apache and mysql.
|
||||||
aa-profile-mode:
|
|
||||||
type: string
|
|
||||||
default: 'disable'
|
|
||||||
description: |
|
|
||||||
Experimental enable apparmor profile. Valid settings: 'complain', 'enforce' or 'disable'.
|
|
||||||
AA disabled by default.
|
|
||||||
|
@ -20,7 +20,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
from subprocess import check_call, CalledProcessError
|
from subprocess import check_call
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import yaml
|
import yaml
|
||||||
@ -45,7 +45,6 @@ from charmhelpers.core.hookenv import (
|
|||||||
INFO,
|
INFO,
|
||||||
WARNING,
|
WARNING,
|
||||||
ERROR,
|
ERROR,
|
||||||
status_set,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.core.sysctl import create as sysctl_create
|
from charmhelpers.core.sysctl import create as sysctl_create
|
||||||
@ -1492,92 +1491,3 @@ class InternalEndpointContext(OSContextGenerator):
|
|||||||
"""
|
"""
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
return {'use_internal_endpoints': config('use-internal-endpoints')}
|
return {'use_internal_endpoints': config('use-internal-endpoints')}
|
||||||
|
|
||||||
|
|
||||||
class AppArmorContext(OSContextGenerator):
|
|
||||||
"""Base class for apparmor contexts."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._ctxt = None
|
|
||||||
self.aa_profile = None
|
|
||||||
self.aa_utils_packages = ['apparmor-utils']
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ctxt(self):
|
|
||||||
if self._ctxt is not None:
|
|
||||||
return self._ctxt
|
|
||||||
self._ctxt = self._determine_ctxt()
|
|
||||||
return self._ctxt
|
|
||||||
|
|
||||||
def _determine_ctxt(self):
|
|
||||||
"""
|
|
||||||
Validate aa-profile-mode settings is disable, enforce, or complain.
|
|
||||||
|
|
||||||
:return ctxt: Dictionary of the apparmor profile or None
|
|
||||||
"""
|
|
||||||
if config('aa-profile-mode') in ['disable', 'enforce', 'complain']:
|
|
||||||
ctxt = {'aa-profile-mode': config('aa-profile-mode')}
|
|
||||||
else:
|
|
||||||
ctxt = None
|
|
||||||
return ctxt
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
return self.ctxt
|
|
||||||
|
|
||||||
def install_aa_utils(self):
|
|
||||||
"""
|
|
||||||
Install packages required for apparmor configuration.
|
|
||||||
"""
|
|
||||||
log("Installing apparmor utils.")
|
|
||||||
ensure_packages(self.aa_utils_packages)
|
|
||||||
|
|
||||||
def manually_disable_aa_profile(self):
|
|
||||||
"""
|
|
||||||
Manually disable an apparmor profile.
|
|
||||||
|
|
||||||
If aa-profile-mode is set to disabled (default) this is required as the
|
|
||||||
template has been written but apparmor is yet unaware of the profile
|
|
||||||
and aa-disable aa-profile fails. Without this the profile would kick
|
|
||||||
into enforce mode on the next service restart.
|
|
||||||
|
|
||||||
"""
|
|
||||||
profile_path = '/etc/apparmor.d'
|
|
||||||
disable_path = '/etc/apparmor.d/disable'
|
|
||||||
if not os.path.lexists(os.path.join(disable_path, self.aa_profile)):
|
|
||||||
os.symlink(os.path.join(profile_path, self.aa_profile),
|
|
||||||
os.path.join(disable_path, self.aa_profile))
|
|
||||||
|
|
||||||
def setup_aa_profile(self):
|
|
||||||
"""
|
|
||||||
Setup an apparmor profile.
|
|
||||||
The ctxt dictionary will contain the apparmor profile mode and
|
|
||||||
the apparmor profile name.
|
|
||||||
Makes calls out to aa-disable, aa-complain, or aa-enforce to setup
|
|
||||||
the apparmor profile.
|
|
||||||
"""
|
|
||||||
self()
|
|
||||||
if not self.ctxt:
|
|
||||||
log("Not enabling apparmor Profile")
|
|
||||||
return
|
|
||||||
self.install_aa_utils()
|
|
||||||
cmd = ['aa-{}'.format(self.ctxt['aa-profile-mode'])]
|
|
||||||
cmd.append(self.ctxt['aa-profile'])
|
|
||||||
log("Setting up the apparmor profile for {} in {} mode."
|
|
||||||
"".format(self.ctxt['aa-profile'], self.ctxt['aa-profile-mode']))
|
|
||||||
try:
|
|
||||||
check_call(cmd)
|
|
||||||
except CalledProcessError as e:
|
|
||||||
# If aa-profile-mode is set to disabled (default) manual
|
|
||||||
# disabling is required as the template has been written but
|
|
||||||
# apparmor is yet unaware of the profile and aa-disable aa-profile
|
|
||||||
# fails. If aa-disable learns to read profile files first this can
|
|
||||||
# be removed.
|
|
||||||
if self.ctxt['aa-profile-mode'] == 'disable':
|
|
||||||
log("Manually disabling the apparmor profile for {}."
|
|
||||||
"".format(self.ctxt['aa-profile']))
|
|
||||||
self.manually_disable_aa_profile()
|
|
||||||
return
|
|
||||||
status_set('blocked', "Apparmor profile {} failed to be set to {}."
|
|
||||||
"".format(self.ctxt['aa-profile'],
|
|
||||||
self.ctxt['aa-profile-mode']))
|
|
||||||
raise e
|
|
||||||
|
@ -128,13 +128,6 @@ def service(action, service_name):
|
|||||||
return subprocess.call(cmd) == 0
|
return subprocess.call(cmd) == 0
|
||||||
|
|
||||||
|
|
||||||
def systemv_services_running():
|
|
||||||
output = subprocess.check_output(
|
|
||||||
['service', '--status-all'],
|
|
||||||
stderr=subprocess.STDOUT).decode('UTF-8')
|
|
||||||
return [row.split()[-1] for row in output.split('\n') if '[ + ]' in row]
|
|
||||||
|
|
||||||
|
|
||||||
def service_running(service_name):
|
def service_running(service_name):
|
||||||
"""Determine whether a system service is running"""
|
"""Determine whether a system service is running"""
|
||||||
if init_is_systemd():
|
if init_is_systemd():
|
||||||
@ -147,15 +140,11 @@ def service_running(service_name):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# This works for upstart scripts where the 'service' command
|
|
||||||
# returns a consistent string to represent running 'start/running'
|
|
||||||
if ("start/running" in output or "is running" in output or
|
if ("start/running" in output or "is running" in output or
|
||||||
"up and running" in output):
|
"up and running" in output):
|
||||||
return True
|
return True
|
||||||
# Check System V scripts init script return codes
|
else:
|
||||||
if service_name in systemv_services_running():
|
return False
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def service_available(service_name):
|
def service_available(service_name):
|
||||||
|
@ -37,10 +37,6 @@ OVS_BRIDGE = 'br-int'
|
|||||||
CEPH_CONF = '/etc/ceph/ceph.conf'
|
CEPH_CONF = '/etc/ceph/ceph.conf'
|
||||||
CHARM_CEPH_CONF = '/var/lib/charm/{}/ceph.conf'
|
CHARM_CEPH_CONF = '/var/lib/charm/{}/ceph.conf'
|
||||||
|
|
||||||
NOVA_API_AA_PROFILE = 'usr.bin.nova-api'
|
|
||||||
NOVA_COMPUTE_AA_PROFILE = 'usr.bin.nova-compute'
|
|
||||||
NOVA_NETWORK_AA_PROFILE = 'usr.bin.nova-network'
|
|
||||||
|
|
||||||
|
|
||||||
def ceph_config_file():
|
def ceph_config_file():
|
||||||
return CHARM_CEPH_CONF.format(service_name())
|
return CHARM_CEPH_CONF.format(service_name())
|
||||||
@ -519,45 +515,3 @@ class HostIPContext(context.OSContextGenerator):
|
|||||||
ctxt['host_ip'] = host_ip
|
ctxt['host_ip'] = host_ip
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
class NovaAPIAppArmorContext(context.AppArmorContext):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(NovaAPIAppArmorContext, self).__init__()
|
|
||||||
self.aa_profile = NOVA_API_AA_PROFILE
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
super(NovaAPIAppArmorContext, self).__call__()
|
|
||||||
if not self.ctxt:
|
|
||||||
return self.ctxt
|
|
||||||
self._ctxt.update({'aa-profile': self.aa_profile})
|
|
||||||
return self.ctxt
|
|
||||||
|
|
||||||
|
|
||||||
class NovaComputeAppArmorContext(context.AppArmorContext):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(NovaComputeAppArmorContext, self).__init__()
|
|
||||||
self.aa_profile = NOVA_COMPUTE_AA_PROFILE
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
super(NovaComputeAppArmorContext, self).__call__()
|
|
||||||
if not self.ctxt:
|
|
||||||
return self.ctxt
|
|
||||||
self._ctxt.update({'aa-profile': self.aa_profile})
|
|
||||||
return self.ctxt
|
|
||||||
|
|
||||||
|
|
||||||
class NovaNetworkAppArmorContext(context.AppArmorContext):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(NovaNetworkAppArmorContext, self).__init__()
|
|
||||||
self.aa_profile = NOVA_NETWORK_AA_PROFILE
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
super(NovaNetworkAppArmorContext, self).__call__()
|
|
||||||
if not self.ctxt:
|
|
||||||
return self.ctxt
|
|
||||||
self._ctxt.update({'aa-profile': self.aa_profile})
|
|
||||||
return self.ctxt
|
|
||||||
|
@ -82,10 +82,7 @@ from charmhelpers.core.unitdata import kv
|
|||||||
|
|
||||||
from nova_compute_context import (
|
from nova_compute_context import (
|
||||||
CEPH_SECRET_UUID,
|
CEPH_SECRET_UUID,
|
||||||
assert_libvirt_imagebackend_allowed,
|
assert_libvirt_imagebackend_allowed
|
||||||
NovaAPIAppArmorContext,
|
|
||||||
NovaComputeAppArmorContext,
|
|
||||||
NovaNetworkAppArmorContext,
|
|
||||||
)
|
)
|
||||||
from charmhelpers.contrib.charmsupport import nrpe
|
from charmhelpers.contrib.charmsupport import nrpe
|
||||||
from charmhelpers.core.sysctl import create as create_sysctl
|
from charmhelpers.core.sysctl import create as create_sysctl
|
||||||
@ -178,9 +175,6 @@ def config_changed():
|
|||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
ceph_changed(rid=rid, unit=unit)
|
ceph_changed(rid=rid, unit=unit)
|
||||||
|
|
||||||
NovaAPIAppArmorContext().setup_aa_profile()
|
|
||||||
NovaComputeAppArmorContext().setup_aa_profile()
|
|
||||||
NovaNetworkAppArmorContext().setup_aa_profile()
|
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,12 +81,6 @@ from nova_compute_context import (
|
|||||||
ceph_config_file,
|
ceph_config_file,
|
||||||
HostIPContext,
|
HostIPContext,
|
||||||
DesignateContext,
|
DesignateContext,
|
||||||
NOVA_API_AA_PROFILE,
|
|
||||||
NOVA_COMPUTE_AA_PROFILE,
|
|
||||||
NOVA_NETWORK_AA_PROFILE,
|
|
||||||
NovaAPIAppArmorContext,
|
|
||||||
NovaComputeAppArmorContext,
|
|
||||||
NovaNetworkAppArmorContext,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
|
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
|
||||||
@ -165,12 +159,6 @@ LIBVIRT_BIN = '/etc/default/libvirt-bin'
|
|||||||
LIBVIRT_BIN_OVERRIDES = '/etc/init/libvirt-bin.override'
|
LIBVIRT_BIN_OVERRIDES = '/etc/init/libvirt-bin.override'
|
||||||
NOVA_CONF = '%s/nova.conf' % NOVA_CONF_DIR
|
NOVA_CONF = '%s/nova.conf' % NOVA_CONF_DIR
|
||||||
QEMU_KVM = '/etc/default/qemu-kvm'
|
QEMU_KVM = '/etc/default/qemu-kvm'
|
||||||
NOVA_API_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'.format(NOVA_API_AA_PROFILE))
|
|
||||||
NOVA_COMPUTE_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
|
||||||
''.format(NOVA_COMPUTE_AA_PROFILE))
|
|
||||||
NOVA_NETWORK_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
|
||||||
''.format(NOVA_NETWORK_AA_PROFILE))
|
|
||||||
|
|
||||||
|
|
||||||
BASE_RESOURCE_MAP = {
|
BASE_RESOURCE_MAP = {
|
||||||
NOVA_CONF: {
|
NOVA_CONF: {
|
||||||
@ -198,18 +186,6 @@ BASE_RESOURCE_MAP = {
|
|||||||
context.LogLevelContext(),
|
context.LogLevelContext(),
|
||||||
context.InternalEndpointContext()],
|
context.InternalEndpointContext()],
|
||||||
},
|
},
|
||||||
NOVA_API_AA_PROFILE_PATH: {
|
|
||||||
'services': ['nova-api'],
|
|
||||||
'contexts': [NovaAPIAppArmorContext()],
|
|
||||||
},
|
|
||||||
NOVA_COMPUTE_AA_PROFILE_PATH: {
|
|
||||||
'services': ['nova-compute'],
|
|
||||||
'contexts': [NovaComputeAppArmorContext()],
|
|
||||||
},
|
|
||||||
NOVA_NETWORK_AA_PROFILE_PATH: {
|
|
||||||
'services': ['nova-network'],
|
|
||||||
'contexts': [NovaNetworkAppArmorContext()],
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBVIRT_RESOURCE_MAP = {
|
LIBVIRT_RESOURCE_MAP = {
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
# Last Modified: Thu Mar 31 18:53:33 2016
|
|
||||||
#include <tunables/global>
|
|
||||||
|
|
||||||
/usr/bin/nova-api {
|
|
||||||
#include <abstractions/authentication>
|
|
||||||
#include <abstractions/base>
|
|
||||||
#include <abstractions/bash>
|
|
||||||
#include <abstractions/libvirt-qemu>
|
|
||||||
#include <abstractions/python>
|
|
||||||
#include <abstractions/wutmp>
|
|
||||||
|
|
||||||
|
|
||||||
capability audit_write,
|
|
||||||
capability net_admin,
|
|
||||||
capability net_raw,
|
|
||||||
capability sys_resource,
|
|
||||||
|
|
||||||
network inet raw,
|
|
||||||
|
|
||||||
/bin/dash ix,
|
|
||||||
/etc/nova/api-paste.ini r,
|
|
||||||
/etc/nova/nova.conf r,
|
|
||||||
/etc/nova/rootwrap.conf r,
|
|
||||||
/etc/nova/rootwrap.d/ r,
|
|
||||||
/etc/nova/rootwrap.d/api-metadata.filters r,
|
|
||||||
/etc/nova/rootwrap.d/compute.filters r,
|
|
||||||
/etc/nova/rootwrap.d/network.filters r,
|
|
||||||
/etc/sudoers r,
|
|
||||||
/etc/sudoers.d/ r,
|
|
||||||
/etc/sudoers.d/90-cloud-init-users r,
|
|
||||||
/etc/sudoers.d/README r,
|
|
||||||
/etc/sudoers.d/nova_sudoers r,
|
|
||||||
/lib{,32,64}/** mr,
|
|
||||||
owner @{PROC}/@{pid}/fd/ r,
|
|
||||||
owner @{PROC}/@{pid}/mounts r,
|
|
||||||
owner @{PROC}/@{pid}/net/ip_tables_names r,
|
|
||||||
owner @{PROC}/@{pid}/stat r,
|
|
||||||
owner @{PROC}/@{pid}/status r,
|
|
||||||
/run/lock/nova/nova-iptables wk,
|
|
||||||
/sbin/ldconfig rix,
|
|
||||||
/sbin/ldconfig.real rix,
|
|
||||||
/sbin/xtables-multi rix,
|
|
||||||
/tmp/ r,
|
|
||||||
/tmp/** rwk,
|
|
||||||
/usr/bin/ r,
|
|
||||||
/usr/bin/nova-api r,
|
|
||||||
/usr/bin/nova-rootwrap rix,
|
|
||||||
/usr/bin/python2.7 ix,
|
|
||||||
/usr/bin/python3.4 ix,
|
|
||||||
/usr/bin/sudo ix,
|
|
||||||
/usr/lib{,32,64}/** mr,
|
|
||||||
/var/lib/nova/ r,
|
|
||||||
/var/lib/nova/** rw,
|
|
||||||
/var/log/nova/nova-api.log w,
|
|
||||||
/var/tmp/ r,
|
|
||||||
/var/tmp/** rwk,
|
|
||||||
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
# Last Modified: Tue Apr 5 22:19:53 2016
|
|
||||||
#include <tunables/global>
|
|
||||||
|
|
||||||
/usr/bin/nova-compute {
|
|
||||||
#include <abstractions/base>
|
|
||||||
#include <abstractions/bash>
|
|
||||||
#include <abstractions/python>
|
|
||||||
|
|
||||||
capability dac_override,
|
|
||||||
capability dac_read_search,
|
|
||||||
|
|
||||||
network inet dgram,
|
|
||||||
network inet stream,
|
|
||||||
|
|
||||||
deny /* w,
|
|
||||||
/bin/dash rix,
|
|
||||||
/bin/mv rix,
|
|
||||||
/bin/uname rix,
|
|
||||||
/etc/nova/nova-compute.conf r,
|
|
||||||
/etc/nova/nova.conf r,
|
|
||||||
/etc/nova/policy.json r,
|
|
||||||
/etc/nsswitch.conf r,
|
|
||||||
/etc/passwd r,
|
|
||||||
/proc/*/net/psched r,
|
|
||||||
/run/libvirt/libvirt-sock rw,
|
|
||||||
/run/lock/nova/nova-iptables wk,
|
|
||||||
/sbin/ldconfig rix,
|
|
||||||
/sbin/ldconfig.real rix,
|
|
||||||
/sys/devices/system/cpu/ r,
|
|
||||||
/sys/devices/system/node/ r,
|
|
||||||
/sys/devices/system/node/** r,
|
|
||||||
/tmp/* rw,
|
|
||||||
/tmp/*/ rw,
|
|
||||||
/usr/bin/ r,
|
|
||||||
/usr/bin/env rix,
|
|
||||||
/usr/bin/gcc-4.8 rix,
|
|
||||||
/usr/bin/nova-compute r,
|
|
||||||
/usr/bin/python2.7 ix,
|
|
||||||
/usr/bin/python3.4 ix,
|
|
||||||
/usr/bin/qemu-img rix,
|
|
||||||
/usr/bin/sudo rix,
|
|
||||||
/usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 rix,
|
|
||||||
/usr/lib{,32,64}/** rw,
|
|
||||||
/usr/lib{,32,64}/python{2,3}.[34567]/**.{pyc,so} mrw,
|
|
||||||
/var/lib/nova/* rwk,
|
|
||||||
/var/lib/nova/instances/ r,
|
|
||||||
/var/lib/nova/instances/** rwk,
|
|
||||||
/var/lib/nova/instances/locks/nova-storage-registry-lock k,
|
|
||||||
/var/log/nova/nova-compute.log w,
|
|
||||||
/var/run/libvirt/* rw,
|
|
||||||
/var/run/libvirt/libvirt-sock rw,
|
|
||||||
/var/tmp/* w,
|
|
||||||
owner @{PROC}/@{pid}/mounts r,
|
|
||||||
owner @{PROC}/@{pid}/net/psched r,
|
|
||||||
owner @{PROC}/@{pid}/status r,
|
|
||||||
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
# Last Modified: Thu Mar 31 18:21:05 2016
|
|
||||||
#include <tunables/global>
|
|
||||||
|
|
||||||
/usr/bin/nova-network {
|
|
||||||
#include <abstractions/base>
|
|
||||||
#include <abstractions/bash>
|
|
||||||
#include <abstractions/nameservice>
|
|
||||||
#include <abstractions/python>
|
|
||||||
|
|
||||||
deny /usr/bin/sudo x,
|
|
||||||
|
|
||||||
/bin/dash rix,
|
|
||||||
/bin/uname rix,
|
|
||||||
/etc/nova/nova.conf r,
|
|
||||||
owner @{PROC}/@{pid}/mounts r,
|
|
||||||
owner @{PROC}/@{pid}/status r,
|
|
||||||
/sbin/ldconfig rix,
|
|
||||||
/sbin/ldconfig.real rix,
|
|
||||||
/tmp/** rw,
|
|
||||||
/usr/bin/ r,
|
|
||||||
/usr/bin/nova-network r,
|
|
||||||
/usr/bin/python2.7 ix,
|
|
||||||
/usr/bin/python3.4 ix,
|
|
||||||
/usr/lib{,32,64}/python{2,3}.[34567]/**.{pyc,so} mra,
|
|
||||||
/var/lib/nova/* a,
|
|
||||||
/var/log/nova/nova-network.log w,
|
|
||||||
/var/tmp/* a,
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user