Reference corresponding ticket on blueprint.
[tails.git] / wiki / src / contribute / design / application_isolation.mdwn
blobad49f35ee08e14472eb370b4b56a7cf71831e770
1 [[!meta title="Application isolation"]]
3 [[!toc levels=3]]
5 <a id="goals"></a>
7 Goals
8 =====
10 For now, we are only aiming at filesystem resources isolation: that
11 is, making sure that e.g. Pidgin cannot read the GnuPG keyring.
13 Other types of resources, such as signals, X, ptrace, sockets, D-Bus
14 etc. are [[not part of the isolation goals
15 yet|application_isolation#more-resources]].
17 Tools and basic configuration
18 =============================
20 For now, we have decided to use AppArmor to isolate applications,
21 mostly because:
23 * it is simple: AppArmor policy is relatively easy to understand,
24   improve, and audit;
25 * it is the best supported [[!wikipedia mandatory access control]]
26   framework in Debian; it wasn't too hard to reach this point, and
27   there is quite some room for improvement via collaboration with
28   other distributions, most notably Ubuntu.
30 The [[!debpts apparmor]] package is installed, and AppArmor is
31 enabled by default in Debian's Linux kernel since 4.13.10-1.
33 Confinement profiles
34 ====================
36 The AppArmor confinement profiles included in Tails come from:
38 * individual Debian packages that ship confinement profiles, e.g.
39   Tor;
40 * the [[!debpts apparmor-profiles]] package;
41 * the [[!debpts apparmor-profiles-extra]] package;
42 * the [[!debpts torbrowser-launcher]] package:
43   - [[!tails_gitweb config/chroot_local-includes/usr/share/tails/torbrowser-AppArmor-profile.patch]]
44   - [[!tails_gitweb config/chroot_local-hooks/19-install-tor-browser-AppArmor-profile]]
46 To get the full and current list, run `aa-status` as `root`
47 inside Tails.
49 Hacks to support the Live system usecase
50 ========================================
52 Most Live systems use a union filesystem to provide the operating
53 system with a read-write filesystem, based on a read-only branch
54 (typically, SquashFS) and a read-write one (most often, tmpfs).
56 Unfortunately, AppArmor currently does not support union filesystems
57 very well, because the LSM hooks do not allow it to distinguish
58 between an access to the upper layer, and an access to the loop-backed
59 underlying layer.
61 So, we have to adjust profiles a bit to make them support the paths
62 that are actually seen by AppArmor in the context of Tails.
64 First, we are using a couple of
65 [aliases](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Alias_and_rewrite_rules)
66 so that rules applying to "normal" paths (e.g.
67 `/home/amnesia/.gnupg/`) also apply to Debian Live -specific paths,
68 such as `/lib/live/mount/overlay/home/amnesia/.gnupg/`. And, to avoid
69 subsequent problems with overlapping rules, and to mitigate the
70 increased policy compilation time (see details below), we also patch
71 some some very broad rules to make them _not_ apply to `/lib/live/*`.
72 All these changes live in
73 [[!tails_gitweb config/chroot_local-patches/apparmor-aliases.diff]],
74 [[!tails_gitweb config/chroot_local-patches/apparmor-alias-dot-d.diff]]
75 and
76 [[!tails_gitweb config/chroot_local-includes/etc/apparmor.d/tunables/alias.d/tails]].
78 Second, few more targeted adjustments are also applied:
80 * [[!tails_gitweb config/chroot_local-includes/etc/apparmor.d/tunables/home.d/tails]]
81 * [[!tails_gitweb config/chroot_local-patches/apparmor-adjust-pidgin-profile.diff]]
82 * [[!tails_gitweb config/chroot_local-patches/apparmor-adjust-tor-abstraction.diff]]
83 * [[!tails_gitweb config/chroot_local-patches/apparmor-adjust-tor-profile.diff]]
84 * [[!tails_gitweb config/chroot_local-patches/apparmor-adjust-totem-profile.diff]]
86 Below, we discuss various leads that might avoid the need for coming
87 up with such adjustments, and maintaining it.
89 <a id="ux"></a>
91 User experience matters
92 =======================
94 Currently, no good way exists to let the user choose an arbitrary file
95 each time they want to open or save one, without leaving the AppArmor
96 profiles wide-open and then much less useful.
98 Solutions to this problem are work-in-progress in various upstream
99 places, e.g.:
101 * [for
102   AppArmor](https://lists.ubuntu.com/archives/apparmor/2015-March/007415.html)
103 * for GNOME sandboxed applications:
104   - [Initial ideas on portals for file
105     access](https://mail.gnome.org/archives/gnome-os-list/2015-March/msg00010.html)
106     thread on gnome-os-list
107   - <https://wiki.gnome.org/Design/OS/Sharing>
109 The idea is generally to introduce a privileged mediation layer
110 between applications, the GTK file chooser and the filesystem. So,
111 some day we can solve this problem in better ways, but we're not
112 there yet.
114 Tor Browser
115 -----------
117 As of Tails 1.3, the Tor Browser is somewhat confined with AppArmor.
119 Given we cannot seriously allow the Tor Browser to read and write
120 everywhere in the home and persistent directory, we had to allow it to
121 read/write files from/to one specific directory, and make it so the
122 user experience is not hurt too much.
124 Now, let's say we have a downloads/uploads directory that's shared
125 between the Tor Browser, the file browser, and all non-confined
126 applications. That directory is called `~/Tor Browser/`, and a GTK
127 bookmark pointing to it is created at login time:
129 * [[!tails_gitweb config/chroot_local-includes/usr/lib/systemd/user/tails-create-tor-browser-directories.service]]
130 * [[!tails_gitweb config/chroot_local-includes/usr/local/lib/create-tor-browser-directories]]
131 * [[!tails_gitweb config/chroot_local-includes/usr/lib/systemd/user/tails-add-GNOME-bookmarks.service]]
132 * [[!tails_gitweb config/chroot_local-includes/usr/local/lib/add-GNOME-bookmarks]]
134 Then, we have a usability issue: the space available in that directory
135 is limited by the free system memory (RAM). So large file downloads
136 may fail. Note that Firefox doesn't mind letting users start
137 downloading a file to a directory that hasn't enough room available to
138 store it entirely, so this problem is not specific to downloading to
139 an amnesiac directory.
141 Still, we thought it would be good to allow users to download large
142 files from Tor Browser to their persistent volume, so we have
143 introduced a second downloads/uploads directory: `~/Persistent/Tor
144 Browser/`, that is created whenever the "Personal data" (aka.
145 `~/Persistent/`) persistence feature is activated. In that case, if
146 persistence was activated read-write, another GTK bookmark pointing to
147 that directory is created at login time.
149 This seemed to be better than introducing yet another persistence
150 feature (e.g. for `~/Tor Browser/`): having downloads be either always
151 amnesiac or always persistent (unless you restart or do stuff outside
152 of the browser) would seem like a regression, since it breaks one of
153 the core Tails properties. And forcing it to be a persistent folder by
154 default actually has security issues since secure deletion does not
155 work as expected on Flash memory. So, we decided that users need to
156 have the option to download either to an amnesiac (`~/Tor Browser/`)
157 or persistent (`~/Persistent/Tor Browser/`) place, like it was the
158 case previously.
160 So, in a nutshell we give Tor Browser access to:
162 * `~/Tor Browser/`, which is amnesiac, as everything else in Tails by
163   default; this is set to be the default download directory
164   ([[!tails_gitweb config/chroot_local-includes/usr/share/tails/tor-browser-prefs.js]]);
165 * `~/Persistent/Tor Browser/`, that is persistent, and only created
166   when `~/Persistent/` is itself persistent and read-write.
168 Note that we don't call these folders "Downloads", because e.g.
169 if someone creates an ODT file and wants to upload it, having to move
170 it to a folder called "Downloads" sounds really weird.
172 Future work
173 ===========
175 More confinement profiles
176 -------------------------
178 As part of the [[!debwiki AppArmor desc="Debian AppArmor Team"]], we
179 are working to get more well-tested and maintained profiles integrated
180 into the distribution, and to improve cross-distribution collaboration
181 in this area.
183 <a id="more-resources"></a>
185 Isolating more types of resources
186 ---------------------------------
188 With AppArmor 2.9, once the corresponding kernel patches are
189 merged into Linux mainline, we will get support for mediating many
190 more types of resources: D-Bus calls, sockets, signals and so on.
192 [[Linux containers|application_isolation#linux-containers]] may also
193 be a good way to isolate more types of resources.
195 Using alias rules to avoid modifying profiles
196 ---------------------------------------------
198 The most obvious trick to workaround AppArmor's lack of support for
199 union filesystems is to use [alias
200 rules](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Alias_and_rewrite_rules),
201 such as:
203       echo 'alias / -> /lib/live/mount/rootfs/filesystem.squashfs/,' \
204       >> /etc/apparmor.d/tunables/alias
206 However, a number of problems prevent this seemingly simple solution
207 from just working in the context of Tails. The following discusses
208 these complications, and a few possible solutions.
210 ### Bugs in alias rules implementation
212 The implementation of alias rules is affected by severe bugs, such as
213 <https://bugs.launchpad.net/apparmor/+bug/888077>.
215 There's preliminary work to fix this at
216 <https://code.launchpad.net/~jjohansen/+junk/parser-alias-fix>.
217 Note that this code can still revert to the previous behaviour by
218 passing the `-O old-alias` option to `apparmor_parser`.
220 ### Overlapping rules
222 Alias rules can generate rules that overlap (and conflict) with
223 existing ones, which can cause the policy to fail to compile.
225 E.g. the `sanitized_helper` profile (sourced by the Evince
226 profile and many others) contains this rule:
228     /lib{,32,64}/**/ld{,32,64}-*.so     mrix,
230 which, once combined with this alias:
232     alias / -> /lib/live/mount/rootfs/filesystem.squashfs/,
234 will end up overlapping a lot of the rules generated for the alias.
235 E.g.
237     /bin/* Pixr,
239 results in a rule of:
241     /lib/live/mount/rootfs/filesystem.squashfs/bin/* Pixr,
243 being generated, however since the alias command does not remove other
244 rule sets, it only adds new rules. We end up with both:
246     /lib{,32,64}/**/ld{,32,64}-*.so     mrix,
247     /lib/live/mount/rootfs/filesystem.squashfs/bin/* Pixr,
249 which causes a conflict between `ix` and `Pix`.
251 To workaround this problem, we would need to change the
252 `/lib{,32,64}/**/ld{,32,64}-*.so mrix,` rule into:
254     /lib{32,64}/**/ld{,32,64}-*.so     mrix,
255     /lib/{[^l],l[^i],li[^v],liv[^e],live[^/]}**/ld{,32,64}-*.so mrix,
257 which allows the profile to compile, as the `x` conflict has
258 been removed.
260 Needless to say, this kind of regexp is painful to write, audit and
261 maintain. Things could be nicer if AppArmor supported set operations;
262 instead, we could do something like (syntax not finalized):
264     /lib/{^live**}/ld{,32,64}-*.so     mrix,
266 Other problematic overlaps include e.g. this rule from the
267 `sanitized_helper` profile:
269     audit deny owner /**/* m,
271 ... that will take away the executable mmap permission from _all_
272 applications under `/lib/live/` path, if the root user (who owns the
273 file) tries to launch an application.
275 This can possibly be fixed using [[rewrite
276 rules|application_isolation#rewrite-rules]] instead of aliases, or by
277 an update to the AppArmor permission merging logic that would give us
278 a way to define that the alias rules should have priority in
279 the union.
281 Fixing such problems one after the other may be doable, but
282 regardless: the way alias rules affect the policy as a whole,
283 especially once combined with globing, would make our policy harder to
284 understand, reason about, and audit.
286 ### Persistence
288 It may be that more aliases are needed to support the bind-mounts set
289 up by `live-boot` when using the [[contribute/design/persistence]]
290 feature. It may even be that these aliases need to be dynamically
291 added, in function of the persistence configuration... that is, at
292 login time. If that was the case, then the entire policy would need to
293 be recompiled at login time, which could make the user experience very
294 painful, especially considering that alias rules vastly increase
295 policy compilation time.
297 ### Increased policy compilation time
299 Alias rules dramatically increase the policy compile time (e.g.
300 100 seconds for the Evince profile, that can be brought down to
301 8 seconds with the aforementioned rule change in the
302 `sanitized_helper` profile).
304 <a id="pre-compiled-AppArmor-policy"></a>
306 To mitigate that problem, we could ship a cached pre-compiled policy,
307 that the parser will use as long as it considered it valid, and then
308 no policy compilation happens at boot time; if the parser detects that
309 the policy is out of date, then it will ignore the cache and compile
310 the policy. For instance, this is what was done for the Ubuntu phone.
311 To generate a valid binary policy cache at ISO build time:
313  - we need to call the parser with a `--features-file` value that
314    matches the pinned feature set used at Tails runtime; this comes
315    for free if we run the parser from the build chroot, where this
316    variable is set in the same `/etc/apparmor/parser.conf` file that
317    will be used at runtime;
319  - we need to use a similar enough version of the parser to the one
320    installed in Tails; here again, this comes for free if we run the
321    parser inside the build chroot;
323  - the version of the kernel used during the ISO build process, that
324    is the one the Vagrant box is running, should not matter: for
325    example, since 2.13-1, the [[!debpts apparmor]] package maintains
326    separate caches per feature set and a binary cache built on Linux
327    4.18 is still valid and used when booting on Linux 4.19 with the
328    same `features-file` setting.
330 This work is tracked on [[!tails_ticket 16138]].
332 Resources: `apparmor_parser(8)`, `apparmor_parser --help`,
333 examples in `parser/tst/features_files/*`, and `parser.conf`.
335 <a id="rewrite-rules"></a>
337 Using rewrite rules to avoid modifying profiles
338 -----------------------------------------------
340 Other than alias rules, another option to avoid modifying profiles
341 would be to use [rewrite
342 rules](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Alias_and_rewrite_rules).
343 They're basically the same as alias rules, except that it doesn't
344 duplicate rules, so no conflicting rules are generated.
346 It remains to be researched if rewrite rules would work in our use
347 case: e.g. it might be that some files are seen as read from the
348 SquashFS initially, and written to the overlay. If that would be the
349 case, then we would need to duplicate some rules in profiles to add
350 back some paths that were rewritten.
352 <a id="overlayfs"></a>
354 overlayfs
355 ---------
357 [overlayfs](https://git.kernel.org/cgit/linux/kernel/git/mszeredi/vfs.git/tree/Documentation/filesystems/overlayfs.txt?h=overlayfs.current)
358 is another kind of union filesystem. It has been merged in
359 Linux mainline, and is supported by live-boot 5.
360 overlayfs works differently from aufs, in ways that give hope that it
361 might be easier for AppArmor to support it natively.
363 Some ongoing work on AppArmor (labeling, extended conditionals) will
364 help support overlayfs. Time will tell whether the result meets
365 our needs.
367 See [[!tails_ticket 9045]] for more up-to-date information.
369 <a id="linux-containers"></a>
371 Linux containers
372 ----------------
374 Using Linux containers for application isolation is being [[researched
375 separately|blueprint/Linux_containers]].
377 Credits
378 =======
380 We owe a lot of thanks to John Johansen (<john.johansen@canonical.com>)
381 for his patience and support. Substantial parts of this document were
382 adapted from explanations he provided to us.