diff options
Diffstat (limited to 'devdocs/docker/engine%2Fsecurity%2Fapparmor%2Findex.html')
| -rw-r--r-- | devdocs/docker/engine%2Fsecurity%2Fapparmor%2Findex.html | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/devdocs/docker/engine%2Fsecurity%2Fapparmor%2Findex.html b/devdocs/docker/engine%2Fsecurity%2Fapparmor%2Findex.html new file mode 100644 index 00000000..a146da07 --- /dev/null +++ b/devdocs/docker/engine%2Fsecurity%2Fapparmor%2Findex.html @@ -0,0 +1,134 @@ +<h1>AppArmor security profiles for Docker</h1> + +<p>AppArmor (Application Armor) is a Linux security module that protects an operating system and its applications from security threats. To use it, a system administrator associates an AppArmor security profile with each program. Docker expects to find an AppArmor policy loaded and enforced.</p> <p>Docker automatically generates and loads a default profile for containers named <code class="language-plaintext highlighter-rouge">docker-default</code>. The Docker binary generates this profile in <code class="language-plaintext highlighter-rouge">tmpfs</code> and then loads it into the kernel.</p> <blockquote> <p><strong>Note</strong>: This profile is used on containers, <em>not</em> on the Docker Daemon.</p> </blockquote> <p>A profile for the Docker Engine daemon exists but it is not currently installed with the <code class="language-plaintext highlighter-rouge">deb</code> packages. If you are interested in the source for the daemon profile, it is located in <a href="https://github.com/moby/moby/tree/master/contrib/apparmor">contrib/apparmor</a> in the Docker Engine source repository.</p> <h2 id="understand-the-policies">Understand the policies</h2> <p>The <code class="language-plaintext highlighter-rouge">docker-default</code> profile is the default for running containers. It is moderately protective while providing wide application compatibility. The profile is generated from the following <a href="https://github.com/moby/moby/blob/master/profiles/apparmor/template.go">template</a>.</p> <p>When you run a container, it uses the <code class="language-plaintext highlighter-rouge">docker-default</code> policy unless you override it with the <code class="language-plaintext highlighter-rouge">security-opt</code> option. For example, the following explicitly specifies the default policy:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker run --rm -it --security-opt apparmor=docker-default hello-world +</pre></div> <h2 id="load-and-unload-profiles">Load and unload profiles</h2> <p>To load a new profile into AppArmor for use with containers:</p> <div class="highlight"><pre class="highlight" data-language="">$ apparmor_parser -r -W /path/to/your_profile +</pre></div> <p>Then, run the custom profile with <code class="language-plaintext highlighter-rouge">--security-opt</code> like so:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker run --rm -it --security-opt apparmor=your_profile hello-world +</pre></div> <p>To unload a profile from AppArmor:</p> <div class="highlight"><pre class="highlight" data-language=""># unload the profile +$ apparmor_parser -R /path/to/profile +</pre></div> <h3 id="resources-for-writing-profiles">Resources for writing profiles</h3> <p>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.</p> <ul> <li><a href="https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage">Quick Profile Language</a></li> <li><a href="https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#AppArmor_globbing_syntax">Globbing Syntax</a></li> </ul> <h2 id="nginx-example-profile">Nginx example profile</h2> <p>In this example, you create a custom AppArmor profile for Nginx. Below is the custom profile.</p> <div class="highlight"><pre class="highlight" data-language="">#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}/* w, # deny write for all files directly in /proc (not in a subdir) + # deny write to files not in /proc/<number>/** or /proc/sys/** + deny @{PROC}/{[^1-9],[^1-9][^0-9],[^1-9s][^0-9y][^0-9s],[^1-9][^0-9][^0-9][^0-9]*}/** w, + deny @{PROC}/sys/[^k]** w, # deny /proc/sys except /proc/sys/k* (effectively /proc/sys/kernel) + deny @{PROC}/sys/kernel/{?,??,[^s][^h][^m]**} w, # deny everything except shm* in /proc/sys/kernel/ + 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/** rwklx, + deny /sys/kernel/security/** rwklx, +} +</pre></div> <ol> <li> <p>Save the custom profile to disk in the <code class="language-plaintext highlighter-rouge">/etc/apparmor.d/containers/docker-nginx</code> file.</p> <p>The file path in this example is not a requirement. In production, you could use another.</p> </li> <li> <p>Load the profile.</p> <div class="highlight"><pre class="highlight" data-language="">$ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-nginx +</pre></div> </li> <li> <p>Run a container with the profile.</p> <p>To run nginx in detached mode:</p> <div class="highlight"><pre class="highlight" data-language="">$ docker run --security-opt "apparmor=docker-nginx" \ + -p 80:80 -d --name apparmor-nginx nginx +</pre></div> </li> <li> <p>Exec into the running container.</p> <div class="highlight"><pre class="highlight" data-language="">$ docker container exec -it apparmor-nginx bash +</pre></div> </li> <li> <p>Try some operations to test the profile.</p> <div class="highlight"><pre class="highlight" data-language="">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 +</pre></div> </li> </ol> <p>Congrats! You just deployed a container secured with a custom apparmor profile!</p> <h2 id="debug-apparmor">Debug AppArmor</h2> <p>You can use <code class="language-plaintext highlighter-rouge">dmesg</code> to debug problems and <code class="language-plaintext highlighter-rouge">aa-status</code> check the loaded profiles.</p> <h3 id="use-dmesg">Use dmesg</h3> <p>Here are some helpful tips for debugging any problems you might be facing with regard to AppArmor.</p> <p>AppArmor sends quite verbose messaging to <code class="language-plaintext highlighter-rouge">dmesg</code>. Usually an AppArmor line looks like the following:</p> <div class="highlight"><pre class="highlight" data-language="">[ 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 +</pre></div> <p>In the above example, you can see <code class="language-plaintext highlighter-rouge">profile=/usr/bin/docker</code>. This means the user has the <code class="language-plaintext highlighter-rouge">docker-engine</code> (Docker Engine Daemon) profile loaded.</p> <p>Look at another log line:</p> <div class="highlight"><pre class="highlight" data-language="">[ 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" +</pre></div> <p>This time the profile is <code class="language-plaintext highlighter-rouge">docker-default</code>, which is run on containers by default unless in <code class="language-plaintext highlighter-rouge">privileged</code> mode. This line shows that apparmor has denied <code class="language-plaintext highlighter-rouge">ptrace</code> in the container. This is exactly as expected.</p> <h3 id="use-aa-status">Use aa-status</h3> <p>If you need to check which profiles are loaded, you can use <code class="language-plaintext highlighter-rouge">aa-status</code>. The output looks like:</p> <div class="highlight"><pre class="highlight" data-language="">$ sudo aa-status +apparmor module is loaded. +14 profiles are loaded. +1 profiles are in enforce mode. + docker-default +13 profiles are in complain mode. + /usr/bin/docker + /usr/bin/docker///bin/cat + /usr/bin/docker///bin/ps + /usr/bin/docker///sbin/apparmor_parser + /usr/bin/docker///sbin/auplink + /usr/bin/docker///sbin/blkid + /usr/bin/docker///sbin/iptables + /usr/bin/docker///sbin/mke2fs + /usr/bin/docker///sbin/modprobe + /usr/bin/docker///sbin/tune2fs + /usr/bin/docker///sbin/xtables-multi + /usr/bin/docker///sbin/zfs + /usr/bin/docker///usr/bin/xz +38 processes have profiles defined. +37 processes are in enforce mode. + docker-default (6044) + ... + docker-default (31899) +1 processes are in complain mode. + /usr/bin/docker (29756) +0 processes are unconfined but have a profile defined. +</pre></div> <p>The above output shows that the <code class="language-plaintext highlighter-rouge">docker-default</code> profile running on various container PIDs is in <code class="language-plaintext highlighter-rouge">enforce</code> mode. This means AppArmor is actively blocking and auditing in <code class="language-plaintext highlighter-rouge">dmesg</code> anything outside the bounds of the <code class="language-plaintext highlighter-rouge">docker-default</code> profile.</p> <p>The output above also shows the <code class="language-plaintext highlighter-rouge">/usr/bin/docker</code> (Docker Engine daemon) profile is running in <code class="language-plaintext highlighter-rouge">complain</code> mode. This means AppArmor <em>only</em> logs to <code class="language-plaintext highlighter-rouge">dmesg</code> activity outside the bounds of the profile. (Except in the case of Ubuntu Trusty, where some interesting behaviors are enforced.)</p> <h2 id="contribute-dockers-apparmor-code">Contribute Docker’s AppArmor code</h2> <p>Advanced users and package managers can find a profile for <code class="language-plaintext highlighter-rouge">/usr/bin/docker</code> (Docker Engine Daemon) underneath <a href="https://github.com/moby/moby/tree/master/contrib/apparmor">contrib/apparmor</a> in the Docker Engine source repository.</p> <p>The <code class="language-plaintext highlighter-rouge">docker-default</code> profile for containers lives in <a href="https://github.com/moby/moby/tree/master/profiles/apparmor">profiles/apparmor</a>.</p> +<p><a href="https://docs.docker.com/search/?q=AppArmor">AppArmor</a>, <a href="https://docs.docker.com/search/?q=security">security</a>, <a href="https://docs.docker.com/search/?q=docker">docker</a>, <a href="https://docs.docker.com/search/?q=documentation">documentation</a></p> +<div class="_attribution"> + <p class="_attribution-p"> + © 2019 Docker, Inc.<br>Licensed under the Apache License, Version 2.0.<br>Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.<br>Docker, Inc. and other parties may also have trademark rights in other terms used herein.<br> + <a href="https://docs.docker.com/engine/security/apparmor/" class="_attribution-link">https://docs.docker.com/engine/security/apparmor/</a> + </p> +</div> |
