Browse Source

Merge pull request #21861 from jfrazelle/apparmor-examples-for-the-apparmor-gods

Add example to apparmor docs
Sebastiaan van Stijn 9 years ago
parent
commit
1a87a21053
1 changed files with 158 additions and 23 deletions
  1. 158 23
      docs/security/apparmor.md

+ 158 - 23
docs/security/apparmor.md

@@ -20,8 +20,8 @@ Docker automatically loads container profiles. The Docker binary installs
 a `docker-default` profile in the `/etc/apparmor.d/docker` file. This profile
 a `docker-default` profile in the `/etc/apparmor.d/docker` file. This profile
 is used on containers, _not_ on the Docker Daemon.
 is used on containers, _not_ on the Docker Daemon.
 
 
-A profile for the Docker Engine Daemon exists but it is not currently installed 
-with the deb packages. If you are interested in the source for the Daemon
+A profile for the Docker Engine daemon exists but it is not currently installed
+with the `deb` packages. If you are interested in the source for the daemon
 profile, it is located in
 profile, it is located in
 [contrib/apparmor](https://github.com/docker/docker/tree/master/contrib/apparmor)
 [contrib/apparmor](https://github.com/docker/docker/tree/master/contrib/apparmor)
 in the Docker Engine source repository.
 in the Docker Engine source repository.
@@ -72,15 +72,15 @@ explicitly specifies the default policy:
 $ docker run --rm -it --security-opt apparmor=docker-default hello-world
 $ docker run --rm -it --security-opt apparmor=docker-default hello-world
 ```
 ```
 
 
-## Loading and Unloading Profiles
+## Load and unload profiles
 
 
-To load a new profile into AppArmor, for use with containers:
+To load a new profile into AppArmor for use with containers:
 
 
-```
+```bash
 $ apparmor_parser -r -W /path/to/your_profile
 $ apparmor_parser -r -W /path/to/your_profile
 ```
 ```
 
 
-Then you can run the custom profile with `--security-opt` like so:
+Then, run the custom profile with `--security-opt` like so:
 
 
 ```bash
 ```bash
 $ docker run --rm -it --security-opt apparmor=your_profile hello-world
 $ docker run --rm -it --security-opt apparmor=your_profile hello-world
@@ -97,39 +97,174 @@ $ apparmor_parser -R /path/to/profile
 $ /etc/init.d/apparmor start
 $ /etc/init.d/apparmor start
 ```
 ```
 
 
-## Debugging AppArmor
+### Resources for writing profiles
+
+The syntax for file globbing in AppArmor is a bit different than some other
+globbing implementations. It is highly suggested you take a look at some of the
+below resources with regard to AppArmor profile syntax.
+
+- [Quick Profile Language](http://wiki.apparmor.net/index.php/QuickProfileLanguage)
+- [Globbing Syntax](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#AppArmor_globbing_syntax)
+
+## Nginx example profile
+
+In this example, you create a custom AppArmor profile for Nginx. Below is the
+custom profile.
+
+```
+#include <tunables/global>
+
+
+profile docker-nginx flags=(attach_disconnected,mediate_deleted) {
+  #include <abstractions/base>
+
+  network inet tcp,
+  network inet udp,
+  network inet icmp,
+
+  deny network raw,
+
+  deny network packet,
+
+  file,
+  umount,
+
+  deny /bin/** wl,
+  deny /boot/** wl,
+  deny /dev/** wl,
+  deny /etc/** wl,
+  deny /home/** wl,
+  deny /lib/** wl,
+  deny /lib64/** wl,
+  deny /media/** wl,
+  deny /mnt/** wl,
+  deny /opt/** wl,
+  deny /proc/** wl,
+  deny /root/** wl,
+  deny /sbin/** wl,
+  deny /srv/** wl,
+  deny /tmp/** wl,
+  deny /sys/** wl,
+  deny /usr/** wl,
+
+  audit /** w,
+
+  /var/run/nginx.pid w,
+
+  /usr/sbin/nginx ix,
+
+  deny /bin/dash mrwklx,
+  deny /bin/sh mrwklx,
+  deny /usr/bin/top mrwklx,
+
+
+  capability chown,
+  capability dac_override,
+  capability setuid,
+  capability setgid,
+  capability net_bind_service,
+
+  deny @{PROC}/{*,**^[0-9*],sys/kernel/shm*} wkx,
+  deny @{PROC}/sysrq-trigger rwklx,
+  deny @{PROC}/mem rwklx,
+  deny @{PROC}/kmem rwklx,
+  deny @{PROC}/kcore rwklx,
+  deny mount,
+  deny /sys/[^f]*/** wklx,
+  deny /sys/f[^s]*/** wklx,
+  deny /sys/fs/[^c]*/** wklx,
+  deny /sys/fs/c[^g]*/** wklx,
+  deny /sys/fs/cg[^r]*/** wklx,
+  deny /sys/firmware/efi/efivars/** rwklx,
+  deny /sys/kernel/security/** rwklx,
+}
+```
+
+1. Save the custom profile to disk in the
+`/etc/apparmor.d/containers/docker-nginx` file.
+
+    The file path in this example is not a requirement. In production, you could
+    use another.
+
+2. Load the profile.
+
+    ```bash
+    $ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-nginx
+    ```
+
+3. Run a container with the profile.
+
+    To run nginx in detached mode:
+
+    ```bash
+    $ docker run --security-opt "apparmor=docker-nginx" \
+        -p 80:80 -d --name apparmor-nginx nginx
+    ```
+
+4. Exec into the running container
+
+    ```bash
+    $ docker exec -it apparmor-nginx bash
+    ```
+
+5. Try some operations to test the profile.
+
+    ```bash
+    root@6da5a2a930b9:~# ping 8.8.8.8
+    ping: Lacking privilege for raw socket.
+
+    root@6da5a2a930b9:/# top
+    bash: /usr/bin/top: Permission denied
+
+    root@6da5a2a930b9:~# touch ~/thing
+    touch: cannot touch 'thing': Permission denied
+
+    root@6da5a2a930b9:/# sh
+    bash: /bin/sh: Permission denied
+
+    root@6da5a2a930b9:/# dash
+    bash: /bin/dash: Permission denied
+    ```
+
+
+Congrats! You just deployed a container secured with a custom apparmor profile!
+
+
+## Debug AppArmor
+
+You can use `demsg` to debug problems and `aa-status` check the loaded profiles.
 
 
-### Using `dmesg`
+### Use dmesg
 
 
 Here are some helpful tips for debugging any problems you might be facing with
 Here are some helpful tips for debugging any problems you might be facing with
 regard to AppArmor.
 regard to AppArmor.
 
 
 AppArmor sends quite verbose messaging to `dmesg`. Usually an AppArmor line
 AppArmor sends quite verbose messaging to `dmesg`. Usually an AppArmor line
-will look like the following:
+looks like the following:
 
 
 ```
 ```
 [ 5442.864673] audit: type=1400 audit(1453830992.845:37): apparmor="ALLOWED" operation="open" profile="/usr/bin/docker" name="/home/jessie/docker/man/man1/docker-attach.1" pid=10923 comm="docker" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
 [ 5442.864673] audit: type=1400 audit(1453830992.845:37): apparmor="ALLOWED" operation="open" profile="/usr/bin/docker" name="/home/jessie/docker/man/man1/docker-attach.1" pid=10923 comm="docker" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
 ```
 ```
 
 
-In the above example, the you can see `profile=/usr/bin/docker`. This means the
+In the above example, you can see `profile=/usr/bin/docker`. This means the
 user has the `docker-engine` (Docker Engine Daemon) profile loaded.
 user has the `docker-engine` (Docker Engine Daemon) profile loaded.
 
 
 > **Note:** On version of Ubuntu > 14.04 this is all fine and well, but Trusty
 > **Note:** On version of Ubuntu > 14.04 this is all fine and well, but Trusty
 > users might run into some issues when trying to `docker exec`.
 > users might run into some issues when trying to `docker exec`.
 
 
-Let's look at another log line:
+Look at another log line:
 
 
 ```
 ```
 [ 3256.689120] type=1400 audit(1405454041.341:73): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=17651 comm="docker" requested_mask="receive" denied_mask="receive"
 [ 3256.689120] type=1400 audit(1405454041.341:73): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=17651 comm="docker" requested_mask="receive" denied_mask="receive"
 ```
 ```
 
 
 This time the profile is `docker-default`, which is run on containers by
 This time the profile is `docker-default`, which is run on containers by
-default unless in `privileged` mode. It is telling us, that apparmor has denied
-`ptrace` in the container. This is great.
+default unless in `privileged` mode. This line shows that apparmor has denied
+`ptrace` in the container. This is exactly as expected.
 
 
-### Using `aa-status`
+### Use aa-status
 
 
-If you need to check which profiles are loaded you can use `aa-status`. The
+If you need to check which profiles are loaded,  you can use `aa-status`. The
 output looks like:
 output looks like:
 
 
 ```bash
 ```bash
@@ -162,17 +297,17 @@ apparmor module is loaded.
 0 processes are unconfined but have a profile defined.
 0 processes are unconfined but have a profile defined.
 ```
 ```
 
 
-In the above output you can tell that the `docker-default` profile running on
-various container PIDs is in `enforce` mode. This means AppArmor will actively
-block and audit in `dmesg` anything outside the bounds of the `docker-default`
+The above output shows that the `docker-default` profile running on various
+container PIDs is in `enforce` mode. This means AppArmor is actively blocking
+and auditing in `dmesg` anything outside the bounds of the `docker-default`
 profile.
 profile.
 
 
-The output above also shows the `/usr/bin/docker` (Docker Engine Daemon)
-profile is running in `complain` mode. This means AppArmor will _only_ log to
-`dmesg` activity outside the bounds of the profile. (Except in the case of
-Ubuntu Trusty, where we have seen some interesting behaviors being enforced.)
+The output above also shows the `/usr/bin/docker` (Docker Engine daemon) profile
+is running in `complain` mode. This means AppArmor _only_ logs to `dmesg`
+activity outside the bounds of the profile. (Except in the case of Ubuntu
+Trusty, where some interesting behaviors are enforced.)
 
 
-## Contributing to AppArmor code in Docker
+## Contribute Docker's AppArmor code
 
 
 Advanced users and package managers can find a profile for `/usr/bin/docker`
 Advanced users and package managers can find a profile for `/usr/bin/docker`
 (Docker Engine Daemon) underneath
 (Docker Engine Daemon) underneath