<\/figure>\n\n\n\nThe output tells you how many profiles are loaded, the mode (enforce or complain) of those profiles, how many processes have associated profiles, and whether any processes are running without profiles.<\/p>\n\n\n\n
In AppArmor, profiles can be in one of two modes: enforce or complain. Profiles in “enforce” mode actively enforce the security rules, meaning that the profile restrictions are in effect for the associated applications.<\/p>\n\n\n\n
Profiles in “complain” mode do not actively enforce the rules but generate audit messages when violations occur. You can think of this as a \u201clearning mode.\u201d This line indicates that there are currently no profiles in complain mode.<\/p>\n\n\n\n
AppArmor uses profiles to define the security rules for applications. These profiles are stored in the \/etc\/apparmor.d\/<\/strong>.<\/p>\n\n\n\n <\/figure>\n\n\n\nIt\u2019s necessary to install additional packages in order to use various AppArmor utilities:<\/p>\n\n\n\n
\n
sudo apt install apparmor-utils<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nStep 3: Creating Custom Profiles<\/h2>\n\n\n\n For this example, we will first install the Nginx web server.<\/p>\n\n\n\n
\n
sudo apt install nginx<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nThis will install Nginx alongside various dependencies and also start the service automatically.<\/p>\n\n\n\n
We can confirm that our Nginx is working by visiting the IP address of our server where you will get the default Nginx page.<\/p>\n\n\n\n <\/figure>\n\n\n\nWe can check the current profiles for AppArmor in \/etc\/apparmor.d<\/strong> directory and verify if one exists for the Nginx web server:<\/p>\n\n\n\n <\/figure>\n\n\n\nBy listing the directory we can see that there is no profile for Nginx, so we can create a new one.<\/p>\n\n\n\n
We can do so by running the following command:<\/p>\n\n\n\n
\n
sudo aa-autodep nginx<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nWe can check the default Nginx profile if we run the following command:<\/p>\n\n\n\n
\n
sudo cat \/etc\/apparmor.d\/usr.sbin.nginx<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nThe line that consists of \/usr\/sbin\/nginx mr<\/strong>, where m<\/strong> allows a file to be mapped into memory and r<\/strong> means read mode.<\/p>\n\n\n\nNow, we will activate the complain mode so that it doesn’t enforce the policy but produces a log each time it detects a violation of the security policy.<\/p>\n\n\n\n
\n
sudo aa-complain \/usr\/sbin\/nginx<\/p>\n<\/div><\/div>\n\n\n\n
Next, we need to restart our Nginx service.<\/p>\n\n\n\n
\n
sudo systemctl restart nginx<\/p>\n<\/div><\/div>\n\n\n\n
Step 4: Enforcing the Profile<\/h2>\n\n\n\n For this step, we will create a custom AppArmor profile, where we will need to write a profile definition for Nginx. <\/p>\n\n\n\n
Use your preferred text editor to edit the file:<\/p>\n\n\n\n
\n
sudo nano \/etc\/apparmor.d\/usr.sbin.nginx<\/p>\n<\/div><\/div>\n\n\n\n
Edit the file so that the new profile looks like this:<\/p>\n\n\n\n
\n
#include <tunables\/global> \/usr\/sbin\/nginx { #include <abstractions\/apache2-common> #include <abstractions\/base> #include <abstractions\/nis> #include <abstractions\/web-data> capability dac_override, capability dac_read_search, capability net_bind_service, capability setgid, capability setuid, deny \/var\/www\/html\/forbidden\/* r, \/etc\/group r, \/etc\/nginx\/conf.d\/ r, \/etc\/nginx\/mime.types r, \/etc\/nginx\/nginx.conf r, \/etc\/nsswitch.conf r, \/etc\/passwd r, \/etc\/ssl\/openssl.cnf r, \/run\/nginx.pid rw, \/usr\/sbin\/nginx mr, \/var\/log\/nginx\/access.log w, \/var\/log\/nginx\/error.log w, owner \/etc\/nginx\/modules-enabled\/ r, owner \/etc\/nginx\/sites-available\/default r, owner \/etc\/nginx\/sites-enabled\/ r, owner \/usr\/share\/nginx\/modules-available\/mod-http-geoip.conf r, owner \/usr\/share\/nginx\/modules-available\/mod-http-image-filter.conf r, owner \/usr\/share\/nginx\/modules-available\/mod-http-xslt-filter.conf r, owner \/usr\/share\/nginx\/modules-available\/mod-mail.conf r, owner \/usr\/share\/nginx\/modules-available\/mod-stream-geoip.conf r, owner \/usr\/share\/nginx\/modules-available\/mod-stream.conf r, }<\/p>\n<\/div><\/div>\n\n\n\n
We are creating an AppArmor profile where Nginx will restrict access to the \/var\/www\/html\/forbidden<\/strong> directory.<\/p>\n\n\n\nNext, we can create the specific directory by running the command:<\/p>\n\n\n\n
\n
sudo mkdir -p \/var\/www\/html\/forbidden<\/p>\n<\/div><\/div>\n\n\n\n
Inside that directory we can create a simple html file:<\/p>\n\n\n\n
\n
sudo nano \/var\/www\/html\/forbidden\/index.html<\/p>\n<\/div><\/div>\n\n\n\n
Now, just add a simple line of text:<\/p>\n\n\n\n
\n
<h1<\/strong>>This is forbidden.<\/h1<\/strong>><\/p>\n<\/div><\/div>\n\n\n\nAfter saving the file, we can load the new AppArmor profile by running the following command:<\/p>\n\n\n\n
\n
sudo apparmor_parser -r \/etc\/apparmor.d\/usr.sbin.nginx<\/p>\n<\/div><\/div>\n\n\n\n
When you run this command, it loads the specified AppArmor profile into the AppArmor kernel module. Loading the profile means that the security rules and restrictions defined in the profile will become active, and they will be enforced when the associated application (in this case, Nginx) runs.<\/p>\n\n\n\n
If you\u2019ve made changes to the profile definition file (e.g., to customize the security rules for Nginx), using the -r<\/strong> option is necessary to apply those changes. This ensures that the updated profile is, in effect, enhancing the security of the associated application.<\/p>\n\n\n\nAfter loading the profile, you need to enforce it for the Nginx service. Use the aa-enforce<\/strong> command:<\/p>\n\n\n\n\n
sudo aa-enforce \/usr\/sbin\/nginx<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nIn order to test if the profile is functioning correctly, restart the Nginx service.<\/p>\n\n\n\n
\n
sudo systemctl restart nginx<\/p>\n<\/div><\/div>\n\n\n\n
Now, if we run a simple curl command toward our localhost, we will see that the index page is still working properly.<\/p>\n\n\n\n
\n
curl http:\/\/localhost<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nHowever, if we run the curl command again, this time toward our forbidden directory, we will see that AppArmor blocked it.<\/p>\n\n\n\n
\n
curl http:\/\/localhost\/forbidden\/index.html<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nIn the screenshot above we can see that the file exists and has real content in it, but due to security rules, it doesn’t allow us to access it.<\/p>\n\n\n\n
Step 5: Debugging the Profile<\/h2>\n\n\n\n If, after applying enforce mode to your AppArmor profile, some service doesn’t restart or work in an unexpected way, we can use the built-in log utility from AppArmor.<\/p>\n\n\n\n
We can try to edit our Nginx profile again by running:<\/p>\n\n\n\n
\n
sudo nano \/etc\/apparmor.d\/usr.sbin.nginx<\/p>\n<\/div><\/div>\n\n\n\n
So we remove the following line:<\/p>\n\n\n\n
\n
\/etc\/nginx\/nginx.conf r,<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nAfter saving the file, we can apply new changes to the AppArmor parser:<\/p>\n\n\n\n
\n
sudo apparmor_parser -r \/etc\/apparmor.d\/usr.sbin.nginx<\/p>\n<\/div><\/div>\n\n\n\n
We can try to restart our Nginx service:<\/p>\n\n\n\n
\n
sudo systemctl restart nginx<\/p>\n<\/div><\/div>\n\n\n\n
But that will fail, and we will not able to start it again.<\/p>\n\n\n\n <\/figure>\n\n\n\nFor that reason, we will use a logging utility for AppArmor:<\/p>\n\n\n\n
\n
sudo aa-logprof<\/p>\n<\/div><\/div>\n\n\n\n
Based on the output, we can see that AppArmor doesn’t have a defined line related to the nginx.conf file that we previously deleted.<\/p>\n\n\n\n
For that reason, we can press A <\/strong>to allow that policy, which will again add it to our AppArmor custom profile.<\/p>\n\n\n\nNext, press S <\/strong>to save changes.<\/p>\n\n\n\n <\/figure>\n\n\n\nThis action will save the profile and we can try to restart our Nginx service again.<\/p>\n\n\n\n
\n
sudo systemctl restart nginx<\/p>\n<\/div><\/div>\n\n\n\n
If we run the status command, we can see that the Nginx is running again:<\/p>\n\n\n\n
\n
sudo systemctl status nginx<\/p>\n<\/div><\/div>\n\n\n\n <\/figure>\n\n\n\nThis way, each time you are in complain or enforce mode for AppArmor and receive any errors with the service, you can use the logging utility that will give you more insights about issues and the ability to add neecessary lines in your custom profile automatically.<\/p>\n\n\n\n
<\/p><\/div>
Note:<\/strong> Consider deploying a logging utility to detect whether attackers are attempting to disable AppArmor to evade your defenses.<\/p><\/div><\/div><\/div>\n\n\n\nConclusion<\/h2>\n\n\n\n AppArmor is a useful tool for enhancing the security of your Debian-based systems. By creating and enforcing custom profiles, you can control the access and behavior of these services, making your system more secure against potential threats. It’s important to carefully design and test your profiles to find the right balance between security and functionality.<\/p>\n\n\n\n