DEV Community

Cover image for AppArmor with Python
petercour
petercour

Posted on

AppArmor with Python

AppArmor is a Linux kernel security module that allows the system administrator to restrict programs' capabilities with per-program profiles.

It runs on Ubuntu Linux and Suse Linux by default. Other Linux distributions often have other solutions.

AppArmor lets you confine processes. Every program has a profile. A profile defines what a program can do.

It can set options like:

  • allow/deny capabilities like network access
  • allow/deny raw socket access
  • permission to read, write, or execute files

Python Interface

You can interact with AppArmor using Python. I've setup a very basic program that interacts with apparmor.

My idea was to just use subprocess to capture the data:

#!/usr/bin/python3
import subprocess
import json
import os

def profiles():
    result = subprocess.run(['apparmor_status', '--json'], stdout=subprocess.PIPE)    
    data = result.stdout.decode('utf-8')
    aa_status = json.loads(data)
    return aa_status

This will run the command apparmor_status and parse its json output. The rest of the program is made in a similar fashion.

#!/usr/bin/python3
# apparmor interface

import subprocess
import json
import os

def profiles():
    result = subprocess.run(['apparmor_status', '--json'], stdout=subprocess.PIPE)    
    data = result.stdout.decode('utf-8')
    aa_status = json.loads(data)
    return aa_status

def unconfined():
    result = subprocess.run(['aa-unconfined', '--paranoid'], stdout=subprocess.PIPE)
    data = result.stdout.decode('utf-8')
    lines = data.split("\n")
    apps = []

    for line in lines:
        app = line.split(" ")
        if len(app) > 1:
            apps.append( (app[0],app[1]) )

    return apps

def complain(profile):
    os.system("sudo aa-complain " + profile)

def enforce(profile):
    os.system("sudo aa-enforce  " + profile)

def disable(profile):
    os.system("sudo ln -s " + profile + " /etc/apparmor.d/disable/")


# List all profiles
aa_status = profiles()
print('version: ' + aa_status['version'])

for profile in aa_status['profiles']:
   status = aa_status["profiles"][profile]
   print(status + " " + profile)

# Get unconfined profiles
apps = unconfined()
for app in apps:
    print(app[1])

It simply interacts with the command line interface. Still very experimental, but seems to work.

Learn more:

Top comments (0)