Create a simple profile manually
In this tutorial, you will create, test, and load a profile for the ping application. ping is a popular network tool used to test the reachability of a host on an IP network.
Check the current status of AppArmor and existing profiles
Verify that AppArmor is enabled on your system:
sudo aa-status
apparmor module is loaded.
215 profiles are loaded.
114 profiles are in enforce mode.
...
List all the existing profiles and make sure that you have no profile for ping:
sudo ls /etc/apparmor.d/
Prepare a test plan
When writing profiles for applications, it is important to understand what behavior of your application you want to limit. Make sure you write down all the functionality your application has, such as:
- Start, stop, and restart the application
- Use every command-line option available
- Open files, save files, and perform standard operations with files
In this tutorial, we will limit our test plan to one operation with ping for demonstration purposes. If you are looking for an in-depth
Disable kernel rate limiting
Temporarily disable kernel rate limiting:
# sysctl -w kernel.printk_ratelimit=0
# sysctl -w kernel.printk_ratelimit_burst=100000
auditd but it is recommended to disable it for the purpose of this tutorial.
Run ping
Verify that ping works as expected:
ping example.com
PING example.com (23.192.228.84) 56(84) bytes of data.
64 bytes from a23-192-228-84.deploy.static.akamaitechnologies.com (23.192.228.84): icmp_seq=1 ttl=49 time=218 ms
...
Create a basic profile file
Create and open a text file:
sudo vim /etc/apparmor.d/ping
Attach the profile to the ping executable:
profile ping /usr/bin/ping {
}
Restrict application's capabilities
To create meaningful restrictions, you need to understand how ping works.
ping is a utility that is used for troubleshooting the network, it sends data packets to a specified IP address.
ping sends ICMP packets using raw sockets. Raw sockets allow userspace programs to send and receive data by directly accessing low-level network protocols. Raw sockets are useful for applications such as ping since the data sent or received through them doesn't need to be wrapped in various headers of the network layer which makes the entire process fast and efficient. Because raw sockets bypass all of the usual protocols, raw socket operations require a privileged capability CAP_NET_RAW. See also, Capabilities.
Now let's check ping's capabilities:
getcap /usr/bin/ping
/usr/bin/ping cap_net_raw=ep
cap_net_raw is set to effective and permitted which means that ping can open raw sockets.
Now let's restrict both of these permissions by editing the profile:
/usr/bin/ping flags=(complain) {
deny capability net_raw,
}
Note that the profile is in the complain mode. Complain mode means that applications can perform the restricted operations but the attempts will be logged instead of blocked.
Test the application and check the logs
Load the profile into the kernel:
apparmor_parser -C /etc/apparmor.d/ping
Run ping again and check the logs:
ping example.com
There are various ways of monitoring the logs. Some popular tools and files to monitor are:
- dmesg
- /var/log/kern.log
- /var/log/messages
- aa-notify
You will see a similar message:
audit: type=1400 apparmor="DENIED" operation="capable" profile="/usr/bin/ping" capability=net_raw ...