This guide explains how to create custom AppArmor profiles for applications, including generating profiles from scripts and verifying their enforcement.
In this guide, we will walk through the process of creating custom AppArmor profiles. After reviewing several example profiles in previous lessons, it’s time to build an application-specific profile from scratch.
Instead of creating a profile manually, you can use AppArmor’s built-in tools. First, install the AppArmor-utils package. On Ubuntu, run:
Copy
Ask AI
apt-get install -y apparmor-utils
The installation output will resemble:
Copy
Ask AI
Reading package lists... DoneBuilding dependency tree Reading state information... DoneThe following packages were automatically installed and are no longer required: libc-ares2 libhttp-parser2.7.1 libnetplan0 libuv1 nodejs-doc python3-netifacesUse 'apt autoremove' to remove them.The following additional packages will be installed: python3-apparmor python3-libapparmorSuggested packages: vim-addon-managerThe following NEW packages will be installed: apparmor-utils python3-apparmor python3-libapparmor...Unpacking apparmor-utils (2.12-4ubuntu5.1) ...Setting up python3-libapparmor (2.12-4ubuntu5.1) ...Setting up python3-apparmor (2.12-4ubuntu5.1) ...Setting up apparmor-utils (2.12-4ubuntu5.1) ...Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Once installed, generate a profile for the Bash script using the following command:
Copy
Ask AI
aa-genprof /root/add_data.sh
The output will be similar to:
Copy
Ask AI
Writing updated profile for /root/add_data.sh.Setting /root/add_data.sh to complain mode!Before you begin, you may wish to check if a profile already exists for the application you wish to confine. See the following wiki page for more information:https://gitlab.com/apparmor/apparmor/wikis/ProfilesProfiling: /root/add_data.shPlease start the application to be profiled in another window and exercise its functionality now.Once completed, select the "Scan" option below in order to scan the system logs for AppArmor events.For each AppArmor event, you will be given the opportunity to choose whether the access should be allowed or denied.[(S)can system log for AppArmor events] / (F)inish
Since the script does not need access to this file, choose d to deny access.
Ensure that you only allow permissions essential for your application to operate. Deny any unnecessary access to maintain a secure profile.
After processing all events, press S to save and F to finish. You should see output similar to:
Copy
Ask AI
= Changed Local Profiles =The following local profiles were changed. Would you like to save them?[1 - /root/add_data.sh](s)ave Changes / Save Sele(c)t(ed Profile / [(V)iew Changes] / View Changesb/w -(C)lean profiles ./ Abo(r)tWriting updated profile for /root/add_data.sh.Profiling: /root/add_data.sh.For each AppArmor event, you will be given the opportunity to choose whether the access should be allowed or denied.[(S)can system log for AppArmor events] / (F)inish Setting /root/add_data.sh to enforce mode.Finished generating profile for /root/add_data.sh
Your new AppArmor profile is now running in enforce mode.
To confirm that the profile is in enforce mode, use the following command:
Copy
Ask AI
aa-status
Expected output:
Copy
Ask AI
apparmor module is loaded.13 profiles are loaded.13 profiles are in enforce mode./root/add_data.sh/sbin/dhclient/usr/bin/man/usr/lib/NetworkManager/nm-dhcp-client.action/usr/lib/NetworkManager/nm-dhcp-helper...usr/sbin/tcpdumpdocker-defaultman_filterman_groff0 profiles are in complain mode.11 processes have profiles defined.11 processes are in enforce mode./root/add_data.sh/sbin/dhclient (621)docker-default (3970)docker-default (4025)docker-default (9853)docker-default (9964)0 processes are in complain mode.0 processes are unconfined but have a profile defined.
The new profile, along with other existing profiles, is stored in the /etc/apparmor.d directory. An example profile for “add_data.sh” might look like this:
To verify that the enforced profile restricts unauthorized access, modify the script to change the log file path from /opt/app/data to /opt. Update the script as follows:
Copy
Ask AI
#!/bin/bashdata_directory=/optmkdir -p "${data_directory}"echo "=> File created at $(date)" | tee "${data_directory}/create.log"
When you run the modified script:
Copy
Ask AI
./add_data.sh
You should see an output similar to:
Copy
Ask AI
tee: /opt/create.log: Permission denied=> File created at Mon 22 Mar 2021 04:04:47 PM EDT
This confirms that while the script can output to the terminal, the AppArmor profile restricts write access only to the /opt/app directory, yielding a permission denied error when attempting to write directly to /opt.
To load an existing profile, use the AppArmor parser command. If no output is returned, the profile has been successfully loaded.
To disable a profile, use the same command with the -r flag and create a symlink to the profile in the /etc/apparmor.d/disable directory.
Now that you’ve learned how to create and enforce AppArmor profiles for a custom application, you can explore securing applications running within Kubernetes pods using AppArmor for enhanced security.
This concludes the lesson on creating AppArmor profiles. Next, we will explore securing an application running inside a Kubernetes pod with AppArmor profiles.Happy securing!