Secure Ubuntu 24.04 with AppArmor – Complete Setup Tutorial
In this guide, you will learn a complete setup tutorial to Secure Ubuntu 24.04 with AppArmor. AppArmor, which stands for Application Armor, is a Linux Kernel security module. It enhances operating system security by limiting the access that applications have to system resources. It uses profiles to define the restrictions for each application, ensuring that even if an application is compromised, the damage it can inflict is minimized.
AppArmor operates in two primary modes:
- Enforce Mode: In this mode, AppArmor actively blocks actions that violate the defined profile rules. Any attempt by an application to exceed its permitted boundaries is denied and logged.
- Complain Mode: Also known as audit mode, this mode doesn’t block actions. Instead, it logs any actions that would have been blocked if AppArmor were in enforce mode. This mode is useful for testing and refining profiles before deploying them in a production environment. It allows administrators to identify potential issues and adjust profiles without disrupting application functionality.
Now, let’s delve into the steps to Secure Ubuntu 24.04 with AppArmor, following this comprehensive tutorial.
Easily Learn to Secure Ubuntu 24.04 with AppArmor
AppArmor comes pre-installed on Ubuntu 24.04 by default and is ready for activation and configuration. To proceed, log in to your Ubuntu 24.04 system as root or as a non-root user with sudo privileges. If you need to create a sudo user, refer to a guide such as "Create a Sudo User on Ubuntu 24.04 From Terminal."
Step 1 – Enabling and Checking AppArmor Status on Ubuntu 24.04
As mentioned, AppArmor is installed by default on Ubuntu 24.04 and should be enabled. To verify that AppArmor is enabled, run the following command:
cat /sys/module/apparmor/parameters/enabled
The output should be "Y," indicating that AppArmor is enabled. If the output is different, you can enable AppArmor using the Linux kernel command line in the bootloader. Execute the following commands:
# sudo mkdir -p /etc/default/grub.d
# echo 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT apparmor=1 security=apparmor"'
| sudo tee /etc/default/grub.d/apparmor.cfg
# sudo update-grub
# sudo reboot
After rebooting, verify that AppArmor is enabled using the cat
command above.
Next, check the current AppArmor profile status for each application on Ubuntu 24.04. Use the following command:
sudo aa-status
The output will resemble this:
apparmor module is loaded.
apparmor profiles are loaded.
134 profiles are loaded.
45 profiles are in enforce mode.
5 profiles are in complain mode.
94 profiles are in kill mode.

The output shows that 134 profiles are loaded, and 45 are in enforce mode. This means 45 applications are actively being restricted by AppArmor.
Step 2 – Change AppArmor Profile Modes on Ubuntu 24.04
This step explains how to change AppArmor profile modes.
To set a profile to complain mode, use the following command:
sudo aa-complain <mark>your-profile</mark>
For instance, to set the /usr/bin/man
profile to complain mode, execute:
sudo aa-complain /usr/bin/man
To set a profile to enforce mode, use the following command:
sudo aa-enforce <mark>your-profile</mark>
For instance, to set the /usr/bin/man
profile to enforce mode, execute:
sudo aa-enforce /usr/bin/man
You can also modify all profiles simultaneously. To set all profiles to either enforce or complain mode, use these commands:
sudo aa-complain /etc/apparmor.d/* #complain-mode
sudo aa-enforce /etc/apparmor.d/* #enforce-mode
Note: If you encounter "command not found" errors with AppArmor commands, install the AppArmor Utils. Use the following command:
sudo apt install apparmor-utils
Step 3 – How To Create a New Profile with AppArmor on Ubuntu 24.04?
This step demonstrates how to create a new profile to Secure Ubuntu 24.04 with AppArmor. First, identify applications that lack AppArmor profiles. Use the following command:
sudo aa-unconfined
The output will list applications without AppArmor profiles, similar to this:
/usr/bin/unconfined_app

Once you’ve identified an unconfined application, create a profile for it using the following command:
sudo aa-genprof <mark>unconfined-app</mark>
This command starts the profile creation process. During the process, you will be prompted to interact with the application to generate rules. After running the application, press F to finalize the profile creation. By default, the profile is created in enforce mode. You can change the profile mode as described in the previous step.
After creating or modifying profiles, reload the AppArmor service to apply the changes:
sudo systemctl reload apparmor.service
Now you’ve learned how to Secure Ubuntu 24.04 with AppArmor. Let’s explore how to delete a profile and disable AppArmor.
Step 4 – Delete a Profile and Disable AppArmor on Ubuntu 24.04
To delete an AppArmor profile, navigate to the AppArmor directory:
cd /etc/apparmor.d/
List all profiles:
ls
Then, delete the desired profile using the rm
command:
rm <mark>your-desired profile</mark>
To disable the AppArmor service, stop and disable it using the following commands:
# sudo systemctl stop apparmor
# sudo systemctl disable apparmor
To completely remove AppArmor from your server, use the following command:
sudo apt remove --assume-yes --purge apparmor
That concludes the tutorial. For further information, visit the official Ubuntu website.
Conclusion
You’ve now learned how to Secure Ubuntu 24.04 with AppArmor. You can enable AppArmor, change profile modes, and create new profiles for unconfined applications. This will enhance your system’s security and mitigate potential attacks.
Also, consider exploring these related articles:
- UFW Firewall Setup on Ubuntu 24.04
- Install and Use Metasploit on Ubuntu 22.04
- Set up AIDE on Ubuntu 22.04
- Install Ntopng Network Monitoring Tool on Ubuntu 24.04
Alternative Security Solutions
While AppArmor is a powerful tool for application confinement, other approaches can complement or, in some cases, serve as alternatives to enhance security on Ubuntu 24.04. Here are two such alternatives:
1. Docker Containerization
Docker containerization provides a layer of isolation between applications and the host operating system. Each application runs within its own container, with its own filesystem, network stack, and process space. This isolation limits the impact of a compromised application, preventing it from accessing or modifying resources outside the container.
Explanation:
Docker containers use kernel features like namespaces and cgroups to create isolated environments. Namespaces isolate the view of the system, such as process IDs, network interfaces, and mount points. Cgroups limit the resources that a container can consume, such as CPU, memory, and disk I/O.
Code Example:
First, install Docker:
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker
Next, create a Dockerfile for your application:
# Dockerfile
FROM ubuntu:24.04
# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends
python3
python3-pip
# Copy application files
COPY . /app
# Install Python packages
WORKDIR /app
RUN pip3 install -r requirements.txt
# Expose port (if needed)
EXPOSE 8000
# Run the application
CMD ["python3", "app.py"]
Build the Docker image:
docker build -t my-app .
Run the Docker container:
docker run -d -p 8000:8000 my-app
In this example, the application runs inside a Docker container. Even if the application is compromised, the attacker’s access is limited to the container’s environment, protecting the host system and other applications.
2. Using systemd Sandboxing Features
Systemd, the system and service manager in Ubuntu, offers built-in sandboxing features that can restrict the capabilities of services. These features allow you to control various aspects of a service’s environment, such as its access to the filesystem, network, and system calls. These features are configured within the systemd service unit file.
Explanation:
Systemd sandboxing features include:
ReadWritePaths=
: Specifies directories that the service can read from and write to.ReadOnlyPaths=
: Specifies directories that the service can only read from.NoNewPrivileges=yes
: Prevents the service from gaining new privileges (e.g., via setuid binaries).CapabilityBoundingSet=
: Restricts the capabilities that the service can use.PrivateTmp=yes
: Gives the service a private /tmp directory.ProtectSystem=full
: Mounts /usr and /boot as read-only for the service.
Code Example:
Create or modify the systemd service unit file for your application (e.g., /etc/systemd/system/my-app.service
):
[Unit]
Description=My Application
After=network.target
[Service]
User=myuser
Group=mygroup
WorkingDirectory=/opt/my-app
ExecStart=/opt/my-app/app.sh
# Sandboxing options
ReadWritePaths=/opt/my-app /var/log/my-app
ReadOnlyPaths=/usr /boot /etc
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_ADMIN
PrivateTmp=yes
ProtectSystem=full
Restart=on-failure
[Install]
WantedBy=multi-user.target
Reload systemd to apply the changes:
sudo systemctl daemon-reload
sudo systemctl restart my-app
In this example, the my-app.service
file configures several sandboxing options. It restricts the application’s access to the filesystem, prevents it from gaining new privileges, limits its capabilities, and provides a private temporary directory. This reduces the potential impact of a security vulnerability in the application.