Source code for provy.more.debian.security.apparmor

from provy.core import Role
from provy.more.debian.package.aptitude import AptitudeRole

'''
Roles in this namespace are meant to provide `AppArmor <http://wiki.apparmor.net/>`_ management utilities for Debian distributions.
'''


[docs]class AppArmorRole(Role): ''' This role provides `AppArmor <http://wiki.apparmor.net/>`_ utilities for Debian distributions. .. warning:: If you're provisioning a Debian Wheezy server or older, it's highly recommended you use :class:`SELinuxRole <provy.more.debian.security.selinux.SELinuxRole>` instead of this one. Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.disable("/bin/ping", "/sbin/dhclient") with self.using(AppArmorRole) as apparmor: apparmor.create("/usr/sbin/nginx", policy_groups=['networking', 'user-application'], read=["/srv/my-site"], read_and_write=["/srv/my-site/uploads"]) '''
[docs] def provision(self): ''' Installs AppArmor profiles and utilities. Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): self.provision_role(AppArmorRole) # no need to call this if using with block. ''' with self.using(AptitudeRole) as aptitude: aptitude.ensure_package_installed('apparmor-profiles') aptitude.ensure_package_installed('apparmor-utils')
def __execute_batch(self, command, executables): arguments = ' '.join(executables) command += ' %s' % arguments self.execute(command, stdout=False, sudo=True)
[docs] def disable(self, *executables): ''' Disables executables in AppArmor, removing them from confinement - that is, they will not be under vigilance anymore -. :param executables: The executables to change. :type executables: positional arguments of :class:`str` Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.disable("/bin/ping", "/sbin/dhclient") ''' self.__execute_batch('aa-disable', executables)
[docs] def complain(self, *executables): ''' Puts the executables to complain mode - the policies are not enforced, but when they're broken, the action gets logged -. :param executables: The executables to change. :type executables: positional arguments of :class:`str` Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.complain("/bin/ping", "/sbin/dhclient") ''' self.__execute_batch('aa-complain', executables)
[docs] def enforce(self, *executables): ''' Puts the executables to enforce mode - the policies are enforced, but only break attempts will be logged -. :param executables: The executables to change. :type executables: positional arguments of :class:`str` Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.enforce("/bin/ping", "/sbin/dhclient") ''' self.__execute_batch('aa-enforce', executables)
[docs] def audit(self, *executables): ''' Puts the executables to audit mode - the policies are enforced, and all actions (legal and ilegal ones) will be logged -. :param executables: The executables to change. :type executables: positional arguments of :class:`str` Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.audit("/bin/ping", "/sbin/dhclient") ''' self.__execute_batch('aa-audit', executables)
[docs] def create(self, executable, template=None, policy_groups=None, abstractions=None, read=[], read_and_write=[]): ''' Creates a profile for an executable. Please refer to the `aa-easyprof manual pages <http://manpages.ubuntu.com/manpages/precise/man8/aa-easyprof.8.html>`_ for more documentation. :param executable: The executable to be referenced by the profile being created. :type executable: :class:`str` :param template: If provided, will be used instead of the "default" one. Defaults to :data:`None`. :type template: :class:`str` :param policy_groups: If provided, use its items as the policy groups. Defaults to :data:`None`. :type policy_groups: :data:`iterable` :param abstractions: If provided, use its items as the abstractions. Defaults to :data:`None`. :type abstractions: :data:`iterable` :param read: If provided, paths to be readable by the executable. Defaults to :data:`[]` (empty list). :type read: :data:`iterable` :param read_and_write: If provided, paths to be readable and writable by the executable (there's no need to provide the "read" argument in this case). Defaults to :data:`[]` (empty list). :type read_and_write: :data:`iterable` Example: :: from provy.core import Role from provy.more.debian import AppArmorRole class MySampleRole(Role): def provision(self): with self.using(AppArmorRole) as apparmor: apparmor.create("/usr/sbin/nginx", policy_groups=['networking', 'user-application'], read=["/srv/my-site"], read_and_write=["/srv/my-site/uploads"]) ''' command = 'aa-easyprof' if template is not None: command += ' -t %s' % template if policy_groups is not None: groups = ','.join(policy_groups) command += ' -p %s' % groups if abstractions is not None: abstr = ','.join(abstractions) command += ' -a %s' % abstr for path in read: command += ' -r %s' % path for path in read_and_write: command += ' -w %s' % path command += ' %s' % executable self.execute(command, stdout=False, sudo=True)