Browse code

Add example to apparmor docs

Signed-off-by: Jess Frazelle <jess@mesosphere.com>

Jess Frazelle authored on 2016/04/08 04:05:16
Showing 1 changed files
... ...
@@ -20,8 +20,8 @@ Docker automatically loads container profiles. The Docker binary installs
20 20
 a `docker-default` profile in the `/etc/apparmor.d/docker` file. This profile
21 21
 is used on containers, _not_ on the Docker Daemon.
22 22
 
23
-A profile for the Docker Engine Daemon exists but it is not currently installed 
24
-with the deb packages. If you are interested in the source for the Daemon
23
+A profile for the Docker Engine daemon exists but it is not currently installed
24
+with the `deb` packages. If you are interested in the source for the daemon
25 25
 profile, it is located in
26 26
 [contrib/apparmor](https://github.com/docker/docker/tree/master/contrib/apparmor)
27 27
 in the Docker Engine source repository.
... ...
@@ -72,15 +72,15 @@ explicitly specifies the default policy:
72 72
 $ docker run --rm -it --security-opt apparmor=docker-default hello-world
73 73
 ```
74 74
 
75
-## Loading and Unloading Profiles
75
+## Load and unload profiles
76 76
 
77
-To load a new profile into AppArmor, for use with containers:
77
+To load a new profile into AppArmor for use with containers:
78 78
 
79
-```
79
+```bash
80 80
 $ apparmor_parser -r -W /path/to/your_profile
81 81
 ```
82 82
 
83
-Then you can run the custom profile with `--security-opt` like so:
83
+Then, run the custom profile with `--security-opt` like so:
84 84
 
85 85
 ```bash
86 86
 $ docker run --rm -it --security-opt apparmor=your_profile hello-world
... ...
@@ -97,39 +97,174 @@ $ apparmor_parser -R /path/to/profile
97 97
 $ /etc/init.d/apparmor start
98 98
 ```
99 99
 
100
-## Debugging AppArmor
100
+### Resources for writing profiles
101
+
102
+The syntax for file globbing in AppArmor is a bit different than some other
103
+globbing implementations. It is highly suggested you take a look at some of the
104
+below resources with regard to AppArmor profile syntax.
105
+
106
+- [Quick Profile Language](http://wiki.apparmor.net/index.php/QuickProfileLanguage)
107
+- [Globbing Syntax](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#AppArmor_globbing_syntax)
108
+
109
+## Nginx example profile
110
+
111
+In this example, you create a custom AppArmor profile for Nginx. Below is the
112
+custom profile.
113
+
114
+```
115
+#include <tunables/global>
116
+
117
+
118
+profile docker-nginx flags=(attach_disconnected,mediate_deleted) {
119
+  #include <abstractions/base>
120
+
121
+  network inet tcp,
122
+  network inet udp,
123
+  network inet icmp,
124
+
125
+  deny network raw,
126
+
127
+  deny network packet,
128
+
129
+  file,
130
+  umount,
131
+
132
+  deny /bin/** wl,
133
+  deny /boot/** wl,
134
+  deny /dev/** wl,
135
+  deny /etc/** wl,
136
+  deny /home/** wl,
137
+  deny /lib/** wl,
138
+  deny /lib64/** wl,
139
+  deny /media/** wl,
140
+  deny /mnt/** wl,
141
+  deny /opt/** wl,
142
+  deny /proc/** wl,
143
+  deny /root/** wl,
144
+  deny /sbin/** wl,
145
+  deny /srv/** wl,
146
+  deny /tmp/** wl,
147
+  deny /sys/** wl,
148
+  deny /usr/** wl,
149
+
150
+  audit /** w,
151
+
152
+  /var/run/nginx.pid w,
153
+
154
+  /usr/sbin/nginx ix,
155
+
156
+  deny /bin/dash mrwklx,
157
+  deny /bin/sh mrwklx,
158
+  deny /usr/bin/top mrwklx,
159
+
160
+
161
+  capability chown,
162
+  capability dac_override,
163
+  capability setuid,
164
+  capability setgid,
165
+  capability net_bind_service,
166
+
167
+  deny @{PROC}/{*,**^[0-9*],sys/kernel/shm*} wkx,
168
+  deny @{PROC}/sysrq-trigger rwklx,
169
+  deny @{PROC}/mem rwklx,
170
+  deny @{PROC}/kmem rwklx,
171
+  deny @{PROC}/kcore rwklx,
172
+  deny mount,
173
+  deny /sys/[^f]*/** wklx,
174
+  deny /sys/f[^s]*/** wklx,
175
+  deny /sys/fs/[^c]*/** wklx,
176
+  deny /sys/fs/c[^g]*/** wklx,
177
+  deny /sys/fs/cg[^r]*/** wklx,
178
+  deny /sys/firmware/efi/efivars/** rwklx,
179
+  deny /sys/kernel/security/** rwklx,
180
+}
181
+```
182
+
183
+1. Save the custom profile to disk in the
184
+`/etc/apparmor.d/containers/docker-nginx` file.
185
+
186
+    The file path in this example is not a requirement. In production, you could
187
+    use another.
188
+
189
+2. Load the profile.
190
+
191
+    ```bash
192
+    $ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-nginx
193
+    ```
194
+
195
+3. Run a container with the profile.
196
+
197
+    To run nginx in detached mode:
198
+
199
+    ```bash
200
+    $ docker run --security-opt "apparmor=docker-nginx" \
201
+        -p 80:80 -d --name apparmor-nginx nginx
202
+    ```
203
+
204
+4. Exec into the running container
205
+
206
+    ```bash
207
+    $ docker exec -it apparmor-nginx bash
208
+    ```
209
+
210
+5. Try some operations to test the profile.
211
+
212
+    ```bash
213
+    root@6da5a2a930b9:~# ping 8.8.8.8
214
+    ping: Lacking privilege for raw socket.
215
+
216
+    root@6da5a2a930b9:/# top
217
+    bash: /usr/bin/top: Permission denied
218
+
219
+    root@6da5a2a930b9:~# touch ~/thing
220
+    touch: cannot touch 'thing': Permission denied
221
+
222
+    root@6da5a2a930b9:/# sh
223
+    bash: /bin/sh: Permission denied
224
+
225
+    root@6da5a2a930b9:/# dash
226
+    bash: /bin/dash: Permission denied
227
+    ```
228
+
229
+
230
+Congrats! You just deployed a container secured with a custom apparmor profile!
231
+
232
+
233
+## Debug AppArmor
234
+
235
+You can use `demsg` to debug problems and `aa-status` check the loaded profiles.
101 236
 
102
-### Using `dmesg`
237
+### Use dmesg
103 238
 
104 239
 Here are some helpful tips for debugging any problems you might be facing with
105 240
 regard to AppArmor.
106 241
 
107 242
 AppArmor sends quite verbose messaging to `dmesg`. Usually an AppArmor line
108
-will look like the following:
243
+looks like the following:
109 244
 
110 245
 ```
111 246
 [ 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
112 247
 ```
113 248
 
114
-In the above example, the you can see `profile=/usr/bin/docker`. This means the
249
+In the above example, you can see `profile=/usr/bin/docker`. This means the
115 250
 user has the `docker-engine` (Docker Engine Daemon) profile loaded.
116 251
 
117 252
 > **Note:** On version of Ubuntu > 14.04 this is all fine and well, but Trusty
118 253
 > users might run into some issues when trying to `docker exec`.
119 254
 
120
-Let's look at another log line:
255
+Look at another log line:
121 256
 
122 257
 ```
123 258
 [ 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"
124 259
 ```
125 260
 
126 261
 This time the profile is `docker-default`, which is run on containers by
127
-default unless in `privileged` mode. It is telling us, that apparmor has denied
128
-`ptrace` in the container. This is great.
262
+default unless in `privileged` mode. This line shows that apparmor has denied
263
+`ptrace` in the container. This is exactly as expected.
129 264
 
130
-### Using `aa-status`
265
+### Use aa-status
131 266
 
132
-If you need to check which profiles are loaded you can use `aa-status`. The
267
+If you need to check which profiles are loaded,  you can use `aa-status`. The
133 268
 output looks like:
134 269
 
135 270
 ```bash
... ...
@@ -162,17 +297,17 @@ apparmor module is loaded.
162 162
 0 processes are unconfined but have a profile defined.
163 163
 ```
164 164
 
165
-In the above output you can tell that the `docker-default` profile running on
166
-various container PIDs is in `enforce` mode. This means AppArmor will actively
167
-block and audit in `dmesg` anything outside the bounds of the `docker-default`
165
+The above output shows that the `docker-default` profile running on various
166
+container PIDs is in `enforce` mode. This means AppArmor is actively blocking
167
+and auditing in `dmesg` anything outside the bounds of the `docker-default`
168 168
 profile.
169 169
 
170
-The output above also shows the `/usr/bin/docker` (Docker Engine Daemon)
171
-profile is running in `complain` mode. This means AppArmor will _only_ log to
172
-`dmesg` activity outside the bounds of the profile. (Except in the case of
173
-Ubuntu Trusty, where we have seen some interesting behaviors being enforced.)
170
+The output above also shows the `/usr/bin/docker` (Docker Engine daemon) profile
171
+is running in `complain` mode. This means AppArmor _only_ logs to `dmesg`
172
+activity outside the bounds of the profile. (Except in the case of Ubuntu
173
+Trusty, where some interesting behaviors are enforced.)
174 174
 
175
-## Contributing to AppArmor code in Docker
175
+## Contribute Docker's AppArmor code
176 176
 
177 177
 Advanced users and package managers can find a profile for `/usr/bin/docker`
178 178
 (Docker Engine Daemon) underneath