Linux  ·  medium  ·  Access, hardening & packages

AppArmor is blocking an application

A confinement profile is refusing an operation. The denial in the log names the profile, the operation and the path.

What you see

An application fails with permission denied on a file whose Unix permissions are clearly correct. Common with MySQL, nginx and Docker after moving a data directory.

What is actually wrong

The profile permits the default paths only. Moving a data directory, adding a socket, or writing to a new location is denied even when the filesystem permissions allow it.

Codes and articles

apparmor="DENIED"audit: type=1400operation="open" profile=Permission denied apparmor

Fixes (2)

Confirm AppArmor is the cause
Root shell15 minuteslow riskreversible

Permission denied that the filesystem does not explain.

  1. Look for denials.

    Shell
    sudo dmesg -T | grep -i apparmor | tail -20sudo journalctl -k --since '30 min ago' | grep -i 'apparmor.*DENIED'
  2. Check which profiles are loaded and in what mode.

    Shell
    sudo aa-status | head -20
  3. Put the profile into complain mode temporarily to confirm the diagnosis. It logs what it would have blocked instead of blocking it.

    Shell
    sudo aa-complain /usr/sbin/mysqld

    Complain mode is the right diagnostic: the application works, and the log fills with exactly the permissions the profile is missing. Disabling AppArmor entirely proves the same thing and leaves the machine unconfined.

  4. Reproduce the failure and read the new log lines.

    Shell
    sudo journalctl -k --since '5 min ago' | grep -i apparmor
Confirm it workedYou have the profile name and the specific denied operation.
If you need to undo itsudo aa-enforce <profile> puts it back into enforcing mode — do this as soon as the profile is fixed.
Add the specific permission to the profile
Root shell30 minutesmedium riskreversible

You know what is being denied.

  1. Use the local override file so the change survives a package upgrade.

    Shell
    sudo ls /etc/apparmor.d/local/

    Editing the shipped profile works until the package updates and replaces it. The local directory is included by the main profile precisely so site changes are kept separate.

  2. Add the rule for the new path.

    Shell
    echo '/srv/mysql/** rwk,' | sudo tee -a /etc/apparmor.d/local/usr.sbin.mysqld
  3. Reload the profile.

    Shell
    sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld
  4. Alternatively, use the interactive tool, which reads the denials and proposes rules.

    Shell
    sudo aa-logprof
  5. Put the profile back into enforcing mode and re-test.

    Shell
    sudo aa-enforce /usr/sbin/mysqldsudo aa-status | grep mysqld
Confirm it workedThe application works with the profile enforcing and no new denials appear.
Shell
sudo aa-status | head -10sudo dmesg -T | grep -ci 'apparmor.*DENIED'
If you need to undo itRemove the added lines from the local file and reload the profile.

Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.