aboutsummaryrefslogtreecommitdiff
blob: 51626aa184e63d5e84fee6435b672ee9058e219f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link title="new" rel="stylesheet" href="http://www.gentoo.org/css/main.css" type="text/css">
<link REL="shortcut icon" HREF="http://www.gentoo.org/favicon.ico" TYPE="image/x-icon">
<link rel="search" type="application/opensearchdescription+xml" href="http://www.gentoo.org/search/www-gentoo-org.xml" title="Gentoo Website">
<link rel="search" type="application/opensearchdescription+xml" href="http://www.gentoo.org/search/forums-gentoo-org.xml" title="Gentoo Forums">
<link rel="search" type="application/opensearchdescription+xml" href="http://www.gentoo.org/search/bugs-gentoo-org.xml" title="Gentoo Bugzilla">
<link rel="search" type="application/opensearchdescription+xml" href="http://www.gentoo.org/search/packages-gentoo-org.xml" title="Gentoo Packages">
<link rel="search" type="application/opensearchdescription+xml" href="http://www.gentoo.org/search/archives-gentoo-org.xml" title="Gentoo List Archives">
<title>Gentoo Linux Handbook Page
--
  </title>
</head>
<body style="margin:0px;" bgcolor="#ffffff"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td valign="top" height="125" bgcolor="#45347b"><a href="http://www.gentoo.org/"><img border="0" src="http://www.gentoo.org/images/gtop-www.jpg" alt="Gentoo Logo"></a></td></tr>
<tr><td valign="top" align="right" colspan="1" bgcolor="#ffffff"><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr>
<td width="99%" class="content" valign="top" align="left">
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Introduction</p>
<p class="secthead"><a name="doc_chap1_sect1">SELinux Concepts</a></p>
<p>
Since SELinux is a MAC system, you should already figure out that managing
SELinux-based permissions and rights might be a bit more challenging than 
managing the discretionary access control rights generally used on a Linux
system. What is more is that SELinux works <b>on top of</b> the DAC system
everybody is used from Linux. As a system administrator, you will need to be
acquainted with some of the concepts and structures that SELinux has put in
place in order to manage the access on the SELinux system.
</p>
<p>
Describing those concepts is the purpose of this particular chapter. We will
give examples on the various concepts from a SELinux enabled Gentoo Hardened
system. However, do not fear if the use of particular commands is not explained
sufficiently. They are currently meant as examples (their output is more
important) and will be discussed further in this document.
</p>
<p class="secthead"><a name="doc_chap1_sect1">SELinux Policies</a></p>
<p>
Within Gentoo (and other distributions as well), SELinux is supported through
several policy levels. These are, in climbing order of complexity (meaning they
can offer more security, but are harder to manage):
</p>
<ol>
  <li>
    <b>targeted</b> is a policy where network-facing services (daemons) are
    confined (the processes can only execute those actions that are defined
    in the policy), but other applications are running what is called
    <span class="emphasis">unconfined</span>, meaning that there are little to no restrictions for
    those processes.
  </li>
  <li>
    <b>strict</b> is a policy where all processes are confined. There are no
    unconfined domains. In other distributions, this is still considered the
    <span class="emphasis">targeted</span> policy but without the unconfined domain definition.
  </li>
  <li>
    <b>multi-category security</b> is a policy where the (confined) domains can
    be categorized (split up), allowing for multiple processes running in
    different instances of a confined domain
  </li>
  <li>
    <b>multi-level security</b> is a policy where rules exist regarding the
    sensitivity of domains and resources. This allows for a "proper"
    information flow policy (make sure that sensitive data isn't leaked
    to less privileged domains). Conceptually, one can understand this best
    if one considers sensitivity levels of Public, Internal, Confidential, 
    Strictly Confidential, etc.
  </li>
</ol>
<p>
When using Gentoo Hardened, all these policies are available. However,
development focuses mainly on <span class="emphasis">strict</span> and <span class="emphasis">mcs</span>. The 
<span class="emphasis">targeted</span> policy is assumed to work if strict works whereas we know
that the <span class="emphasis">mls</span> policy is currently not fit yet for production use.
</p>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Security Contexts</p>
<p class="secthead"><a name="doc_chap1_sect1">Users, Roles, Domains, Sensitivities and Categories</a></p>
<p>
One of the first concepts you will need to be acquainted with is the concept of
a <span class="emphasis">security context</span>. This is a state given to a resource that uniquely
identifies which grants (permissions) are applicable to the resource. This
context is extremely important for SELinux as it is the definition on which it
bases its permissions (grants or denials). When a resource has no security
context assigned, SELinux will try to give it a default security context which -
in the spirit of lowest privilege - has little permissions to perform any actions.
</p>
<p>
Within SELinux, such a security context is displayed using three to five 
definitions, depending on the type of policy you are running:
</p>
<dl>
  <dt>user</dt>
  <dd>
    This is the <span class="emphasis">SELinux user</span> (which is not the same as the Linux/Unix
    technical user) assigned to the resource
  </dd>
  <dt>role</dt>
  <dd>
    This is the SELinux role in which the resource currently works
  </dd>
  <dt>type</dt>
  <dd>
    This is the type assigned to the resource and is the key to SELinux'
    enforcement rules
  </dd>
  <dt>sensitivity</dt>
  <dd>
    This is a level given to a resource informing the system about the
    sensitivity of this resource. A sensitivity is something akin to 
    Public, Internal, Restricted, Confidential, Strictly Confidential, ...
    Sensitivity levels are only supported in MLS policies.
  </dd>
  <dt>category</dt>
  <dd>
    This is a specific instantiation of a resource. It allows segregation of
    resources even if they are of the same type. More about categories later - 
    categories are supported in MLS and MCS policies.
  </dd>
</dl>
<p>
More information on these particular definitions is given throughout the
remainder of this chapter. 
</p>
<p>
As an example let's take a look at the security context of a logged on user:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Getting the security context of a logged on user</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~$ <span class="code-input">id -Z</span>
staff_u:staff_r:staff_t
</pre></td></tr>
</table>
<p>
In this case, the user is identified as the SELinux user <span class="emphasis">staff_u</span>,
currently in the <span class="emphasis">staff_r</span> role and assigned to the <span class="emphasis">staff_t</span>
type. The actions the user is allowed to do are based upon this security
context. Also, you notice that only three identifiers are shown. This is
because the example is taken on a <span class="emphasis">strict</span> (or <span class="emphasis">targeted</span>) policy
system. The next example gives the same result, but on an <span class="emphasis">MCS</span> policy
system.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Getting the security context of a logged on user on an MCS policy system</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~$ <span class="code-input">id -Z</span>
staff_u:staff_r:staff_t:s0-s0:c0.c1023
</pre></td></tr>
</table>
<p>
Here, the user is running with sensitivity level of s0 (which, in an MCS policy
system, is the only available sensitivity) and with a category set of c0 up to
and including c1023. However, note that in an MCS policy system categories are
optional, so you might just see an output of <span class="emphasis">staff_u:staff_r:staff_t:s0</span>.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Access Control Policy</a></p>
<p>
As mentioned before, these security contexts are used as the base for the
permission rules. What SELinux does is check the security context of the source
(for instance a process) and the destination (for instance a file that that
process wants to read). It then checks if the requested operation (read) is
allowed between those two contexts. Keep in mind though that SELinux works on
top of the standard permission system used by Linux. If a process is not able to
read a file to begin with, SELinux is not even consulted.
</p>
<p>
Now, where the security context defines the state of a resource, we have not
spoken about the resources themselves. Within SELinux, the resource types are
defined as <span class="emphasis">object classes</span>. Common examples are <span class="emphasis">file</span> or <span class="emphasis">dir</span>,
but SELinux also manages classes such as <span class="emphasis">filesystem</span>, <span class="emphasis">tcp_socket</span>,
<span class="emphasis">process</span>, <span class="emphasis">sem</span> (semaphores) and more.
</p>
<p>
On each object class, a set of <span class="emphasis">permissions</span> is declared which are possible
against a resource within this object class. For instance, the <span class="emphasis">process</span>
object class supports at least the following permissions:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Supported permissions against a 'process' resource</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~# <span class="code-input">ls /selinux/class/process/perms</span>
dyntransition  getcap      rlimitinh     setpgid        siginh
execheap       getpgid     setcap        setrlimit      sigkill
execmem        getsched    setcurrent    setsched       signal
execstack      getsession  setexec       setsockcreate  signull
fork           noatsecure  setfscreate   share          sigstop
getattr        ptrace      setkeycreate  sigchld        transition
</pre></td></tr>
</table>
<p>
The most common SELinux access control rule (<span class="emphasis">allow</span>) is described as
follows:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: SELinux allow statement</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
allow ACTOR  TARGET:CLASS PRIVILEGE;
      +-+-+  +-+--+ +-+-+ +---+---+
        |      |      |       `- Permission to be granted (like "write")
	|      |      `- Class on which permission is given (like "file")
	|      `- Resource (label) on which permission is valid (like "portage_conf_t")
	`- Actor (domain) which gets the privilege (like "sysadm_t")
</pre></td></tr>
</table>
<p>
Let's take a look at a small example to explain the permission rules and how 
SELinux uses them. The example user is in the <span class="emphasis">staff_u:staff_r:staff_t</span>
context and wants to write to its own home directory. As we can expect, this
should be allowed. Don't worry about the commands here, we'll discuss them more
properly further in this document.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Seeing if a user can write to its own home directory</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
<span class="code-comment">(Show the security context for the users' home directory)</span>
~$ <span class="code-input">ls -dZ ${HOME}</span>
staff_u:object_r:user_home_dir_t  /home/swift

<span class="code-comment">(Find the allow-rule which allows the staff_t type to write into a 
 directory with the user_home_dir_t type)</span>
~$ <span class="code-input">sesearch -s staff_t -t user_home_dir_t -c dir -p write -A</span>
Found 1 semantic av rules:
  allow staff_t user_home_dir_t : dir { ioctl read write create ... };
</pre></td></tr>
</table>
<p>
As expected, the security context of the user (to be more specific, the domain
in which it resides) has write access to the domain of the target's directories.
The notion of <span class="emphasis">domain</span> is frequently used in SELinux documentation and
refers to the type assigned to a process. BTW, as files do not have roles, 
they are given the default <span class="emphasis">object_r</span> role by SELinux.
</p>
<p>
Now take a look at the following example. Our user, who is inside the portage
group, wants to write to the <span class="path" dir="ltr">/var/tmp/portage</span> directory:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Seeing if a user can write to the /var/tmp/portage directory</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~$ <span class="code-input">id -a</span>
uid=1001(swift) gid=100(users) groups=100(users),...,250(portage),...
~$ <span class="code-input">ls -ldZ /var/tmp/portage</span>
drwxrwxr-x. 3 portage portage  system_u:object_r:portage_tmp_t 4096 Dec  6 21:08 /var/tmp/portage
</pre></td></tr>
</table>
<p>
From the standard Linux permissions, the user has write access. But does SELinux
also grant it?
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Trying to write into /var/tmp/portage</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~$ <span class="code-input">sesearch -s staff_t -t portage_tmp_t -c dir -p write -A</span>
~$ 
<span class="code-comment">(Notice that there is no output given here)</span>
~$ <span class="code-input">touch /var/tmp/portage/foo</span>
touch: cannot touch '/var/tmp/portage/foo': Permission denied
</pre></td></tr>
</table>
<p>
As SELinux could not find a rule that allows the staff_t domain to write to any 
directory labeled with the portage_tmp_t type, the permission was denied.
</p>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Type Enforcements / Domain Types</p>
<p class="secthead"><a name="doc_chap1_sect1">Types and Domains</a></p>
<p>
To explain how the permission rules work and how this is enforced through the
security contexts, let's start from the last definition in the context (the
<span class="emphasis">type</span>) and work our way forward through the roles and users.
</p>
<ul>
  <li>
    A <span class="emphasis">SELinux type</span> is a particular label assigned to a resource. The
    <span class="code" dir="ltr">passwd</span> command for instance is labeled with the passwd_exec_t type.
  </li>
  <li>
    A <span class="emphasis">SELinux domain</span> is the security state of a process and identifies the rights 
    and permissions it has. It is most often referred to by its type declaration.
    For instance, for a running <span class="code" dir="ltr">passwd</span> command, its domain is passwd_t.
  </li>
</ul>
<p>
The rules that identify the allowed actions for a domain have been described earlier. Again:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Standard SELinux policy rules</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
allow &lt;src_domain&gt; &lt;dst_type&gt; : &lt;class&gt; { permission [ permission [ ... ] ] } ;
</pre></td></tr>
</table>
<p>
An example for the <span class="emphasis">passwd_t</span> domain would be the permissions granted
between the <span class="emphasis">passwd_t</span> domain and the <span class="emphasis">shadow_t</span> type (used by the
<span class="path" dir="ltr">/etc/shadow</span> file).
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Grants between passwd_t and shadow_t</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
allow passwd_t shadow_t : file { ioctl read write create ... } ;
</pre></td></tr>
</table>
<p>
This permission syntax is very powerful, but also difficult. To have a secure
system where normal behavior is allowed, you need to seriously fine-tune these
rules for each and every application (and thus domain) that your system wants to
host. Giving too broad permissions to a domain on a particular type might result
in unauthorized activity being granted. Giving too few permissions might result 
in loss of efficiency or even effectiveness.
</p>
<p>
To support easier grant rules, SELinux allows grouping of types using type
attributes. For instance, the attribute <span class="emphasis">exec_type</span> bundles all types 
that are assigned to executable files (such as <span class="emphasis">bin_t</span>, <span class="emphasis">ssh_exec_t</span>,
...), whereas the <span class="emphasis">file_type</span> attribute bundles all types that are
assigned to regular files. Although this can simplify rule management, it makes
it easier to grant too many permissions.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Domain Transitions</a></p>
<p>
So far for types, domain definitions and their permissions. We have stated before
that permissions are based on the domain in which a process resides. But how
does a process become part of the domain? You might think that this happens by
default (starting the <span class="code" dir="ltr">passwd</span> command would automatically bring the
process in the <span class="emphasis">passwd_t</span> domain), but this is in fact a combination of
three specific privileges that need to be granted:
</p>
<ol>
  <li>
    The current domain must be allowed to transition to a domain
  </li>
  <li>
    The target domain should have an <span class="emphasis">entry point</span>, which is an executable
    that is allowed to start in the domain
  </li>
  <li>
    The source domain should have <span class="emphasis">execute</span> rights on (the domain of) that 
    executable
  </li>
</ol>
<table class="ncontent" width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td bgcolor="#ffffbb"><p class="note"><b>Important: </b>
Not being allowed to transition does not mean that you cannot
execute the binary. The binary can still be executed, but will not run inside
the target domain. Instead, it will inherit the domain of the executor and hence
the rights and permissions of this domain.
</p></td></tr></table>
<p>
Through these rules, the security administrator of a system can more
specifically control who and under which conditions particular actions can be
taken.
</p>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Roles and Rights</p>
<p class="secthead"><a name="doc_chap1_sect1">The Role of a Role</a></p>
<p>
The previously discussed domains and domain rules is quite powerful. However,
this is not where SELinux stops. After all, you want to be able to deny access
towards particular domains from unauthorized users. One requirement is of course
not to allow transitions from the user domain to that restricted domain, but how
can you enforce one set of users to be allowed and another to be denied?
</p>
<p>
Enter the roles. By using roles, you can tell SELinux which domains are allowed
for a role and which aren't. An example would be the <span class="emphasis">ifconfig_t</span> domain.
This domain has the rights to change the networking interface definitions - not
something you want to allow your users. And in fact, if you would verify,
SELinux does not allow the user role <span class="emphasis">user_r</span> to be assigned with the
<span class="emphasis">ifconfig_t</span> domain.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: ifconfig_t domain and user_r versus sysadm_r</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~$ <span class="code-input">seinfo -ruser_r -x</span>
  user_r
    Dominated Roles:
      user_r
    Types:
      ...
~$ <span class="code-input">seinfo -rsysadm_r -x</span>
  sysadm_r
    Dominated Roles:
      sysadm_r
    Types:
      ...
      ifconfig_t
      ...
</pre></td></tr>
</table>
<table class="ncontent" width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td bgcolor="#ffffbb"><p class="note"><b>Important: </b>
Again, not being able to be associated with a domain does not mean that the
<span class="emphasis">user_r</span> role cannot <span class="emphasis">execute</span> the <span class="code" dir="ltr">ifconfig</span> binary. It can, but
it will execute the binary within its own domain (<span class="emphasis">user_t</span>) and as such
will not have the rights to manipulate the networking interface (but will still
be able to read the interface information albeit with limited output).
</p></td></tr></table>
<p>
Roles are often used in access control systems to group permissions to a single
functional set (the role) which can then be assigned to individuals (accounts). 
For instance, such access control systems create roles for accountants, 
operators, managers, ... and grant the appropriate privileges to these roles.
Then, their users are assigned one (or sometimes multiple) roles and the users
inherit the permissions assigned to these roles.
</p>
<p>
With SELinux, the idea remains the same (use roles to functionally differentiate
privileges) but is implemented differently: roles are assigned target domains
in which a role is allowed to "be in". The permissions remain assigned to the
domains.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Role Transitions</a></p>
<p>
Users (and processes) have the ability to switch roles. This is allowed by
SELinux, but of course only when the switch itself is granted. By default,
the SELinux policy used by Gentoo Hardened offers five roles on a SELinux 
system:
</p>
<dl>
  <dt>object_r</dt>
  <dd>
    The <span class="emphasis">object_r</span> role is the only role by default available through
    SELinux. It is usually only assigned to resources where roles have no
    benefit or value (such as files and directories).
  </dd>
  <dt>system_r</dt>
  <dd>
    The <span class="emphasis">system_r</span> role is used for highly privileged system services. 
    The <span class="emphasis">system_r</span> role is allowed to switch to any other "default" role. 
    No role exception <span class="emphasis">sysadm_r</span> can switch to the <span class="emphasis">system_r</span> role.
  </dd>
  <dt>sysadm_r</dt>
  <dd>
    The <span class="emphasis">sysadm_r</span> role is used for system administration activities. The
    <span class="emphasis">sysadm_r</span> role is allowed to switch to any other "default" role. Only
    the <span class="emphasis">system_r</span> and <span class="emphasis">staff_r</span> roles are allowed to switch to the
    <span class="emphasis">sysadm_r</span> role.
  </dd>
  <dt>staff_r</dt>
  <dd>
    The <span class="emphasis">staff_r</span> role is used for system operators who might have the
    rights to perform system administration tasks. The <span class="emphasis">staff_r</span> role is
    only allowed to switch to the <span class="emphasis">sysadm_r</span> role. Only <span class="emphasis">sysadm_r</span> and
    <span class="emphasis">system_r</span> can switch to the <span class="emphasis">staff_r</span> role.
  </dd>
  <dt>user_r</dt>
  <dd>
    The <span class="emphasis">user_r</span> role is used for standard, unprivileged users. It is not
    allowed to transition towards any other role; only <span class="emphasis">sysadm_r</span> and
    <span class="emphasis">system_r</span> roles are allowed to switch to the <span class="emphasis">user_r</span> role.
  </dd>
</dl>
<table class="ncontent" width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td bgcolor="#bbffbb"><p class="note"><b>Note: </b>
A "default" role is any of <span class="emphasis">user_r</span>, <span class="emphasis">staff_r</span>, <span class="emphasis">sysadm_r</span> or
<span class="emphasis">system_r</span>. If you create additional roles yourself, they are not part of
the "default" roles.
</p></td></tr></table>
<p>
Using these definitions, a user inside the <span class="emphasis">user_r</span> role will never be able
to execute <span class="code" dir="ltr">ifconfig</span> within the <span class="emphasis">ifconfig_t</span> domain. The use of the
word <span class="emphasis">never</span> here is important: not even if the user is able to become
root using <span class="code" dir="ltr">sudo</span> or any other command will he be able to run the
<span class="code" dir="ltr">ifconfig</span> command in the <span class="emphasis">ifconfig_t</span> domain because, even after
running <span class="code" dir="ltr">sudo</span>, he is still inside the <span class="emphasis">user_r</span> role.
</p>
<p class="secthead"><a name="doc_chap1_sect1">SELinux Users</a></p>
<p>
A SELinux user is not the same as the Linux user. Whereas standard Linux user
accounts can be switched using commands such as <span class="code" dir="ltr">su</span> or <span class="code" dir="ltr">sudo</span>, a
SELinux user can not be changed. Even when you successfully execute <span class="code" dir="ltr">sudo</span>,
your SELinux user will remain the same.
</p>
<p>
When you look at a SELinux powered system, you might notice that that system
doesn't use many SELinux users. For instance, Gentoo Hardened's default setup
defines the users <span class="emphasis">root</span>, <span class="emphasis">user_u</span>, <span class="emphasis">staff_u</span>, <span class="emphasis">sysadm_u</span> and
<span class="emphasis">system_u</span> and some systems never introduce any other SELinux user. But if
that is the case, is the above advantage of SELinux users (once a user is logged
on, he cannot change his SELinux user) the only one?
</p>
<p>
Well, no. SELinux users are also used to categorize accounts which have the 
permission to use a particular role.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: SELinux users and their associated roles</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~# <span class="code-input">semanage user -l</span>
SELinux User    SELinux Roles

root            staff_r sysadm_r
staff_u         staff_r sysadm_r
sysadm_u        sysadm_r
system_u        system_r
user_u          user_r
</pre></td></tr>
</table>
<p>
Standard Linux users are mapped to these SELinux users:
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Linux users and their SELinux user mappings</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
~# <span class="code-input">semanage login -l</span>
Login Name          SELinux User

__default__         user_u
root                root
swift               staff_u
</pre></td></tr>
</table>
<p>
In this example, only logins of the Linux user <span class="emphasis">swift</span> (through 
<span class="emphasis">staff_u</span>) and <span class="emphasis">root</span> (through the <span class="emphasis">root</span> SELinux user) 
will be able to eventually run inside the <span class="emphasis">sysadm_r</span> role. All other
Linux accounts will be by default mapped to the <span class="emphasis">user_u</span> user (and 
this <span class="emphasis">user_r</span> role).
</p>
<p>
This is <span class="emphasis">only</span> applicable for interactive logins. Processes that are
launched through an init script or otherwise do not automatically become part of
the SELinux user <span class="emphasis">user_u</span>: depending on the security context of whatever
process is starting them, they can become anything. Of course, if the security
context of the process that is starting them is <span class="emphasis">user_u:user_r:user_t</span> then
they will not be able to transform into anything other than
<span class="emphasis">user_u:user_r:*</span> with <span class="emphasis">*</span> a domain supported by the <span class="emphasis">user_r</span>
role.
</p>
<p>
SELinux users are also used to implement <span class="emphasis">User Based Access Control</span> or
<span class="emphasis">UBAC</span>. This SELinux functionality allows for domains to be SELinux user
aware: a process running in the context of a particular SELinux user can then -
for instance - only work with files of the same SELinux user. This offers a
finer grained access method, because that process might run within a domain
which has write access to the domain of the file, but can still not write to the
file because the SELinux users' differ.
</p>
<p>
At this moment, Gentoo Hardened SELinux' supports both policies with and
without UBAC, although we strongly recommend to use UBAC. This is controlled
through the <span class="code" dir="ltr">ubac</span> USE flag.
</p>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Multi Level Security / Multi Category Security</p>
<p class="secthead"><a name="doc_chap1_sect1">Introduction</a></p>
<p>
Next to the type enforcement feature, SELinux also offers MLS and MCS support.
This allows administrators to define a hierarchical confidentiality policy.
For instance, you can ensure that a user or process within a certain
security domain and level can write to files with the same level (or higher), or
read files with the same level (or lower), but not write files to a lower level.
This allows administrators to implement some sort of 
public/internal/confidential/strictly confidential hierarchical security level
for files.
</p>
<p>
Although implementation of MLS is possible with the type enforcement rules we
have previously explained, it would lead to an unmanageable collection of types
and permissions. The MLS implementation simplifies this.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Multi-Level Security</a></p>
<p>
The most flexible - but also most challenging to manage - method offered by
SELinux is MLS, or <span class="emphasis">Multi-Level Security</span>. When using this policy type, 
security administrators can assign sensitivity labels to resources and define
which domains (and which sensitivity levels) are able to read/write to which
level. A level is always given as a range, showing the lowest and highest level
that a particular domain is running in.
</p>
<p>
Next to the sensitivity level, MLS supports categories on a per-level basis.
These categories allow the security administrator to make different, possibly
independent "containers" for sensitive resources. To give an example, the
administrator can support the levels Public up to Strictly Confidential, and
categories of "Finance", "Risk Analysis", "Acquisitions", "IT Systems", ...
</p>
<p>
With such categories, one can then allow one role to have access to all
sensitivity levels for a particular category (say "IT Systems") but still only
have access to the Public and Internal documents of all other categories.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Multi-Category Security</a></p>
<p>
The MCS or <span class="emphasis">Multi-Category Security</span> policy is a subset of the MLS policy.
It supports the various categories, but without using the multiple security
levels for the resources. 
</p>
<p>
The use of MCS has become popular because it is far less difficult to manage
while still retaining some of the flexibilities offered by the MLS policy.
Where MLS is more chosen for business purposes (and as such has some influence
on the organization of the business), MCS is often used for <span class="emphasis">multitenancy</span>
architectures. In a multi-tenant architecture, systems are running processes for
various clients simultaneously. Categorisation allows for separation of
privileges across these processes without introducing multiple domains (which
would require the development of new policies for each new client that a system
wants to serve).
</p>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Reference Policy</p>
<p class="secthead"><a name="doc_chap1_sect1">About refpolicy</a></p>
<p>
As described previously, SELinux uses type enforcement to describe the state of
your system. This is done by giving each resource on your system (be it a
process, a network port, a file or directory) a specific type and describe the
rules how types can work with each other. 
</p>
<p>
Managing such a policy is not easy. Unlike some other MAC systems, which rely
on a learning mode and do not use domain definitions (they rather keep track of
which commands a process is allowed to execute), a proper SELinux definition
requires lots (thousands and thousands) of permission lines.
</p>
<p>
To ensure that no duplicate effort is made, and to help distributions like
Gentoo, Fedora, RedHat, Debian, ... with their SELinux integration efforts, a
project is launched called <span class="emphasis">The Reference Policy</span>.
</p>
<p>
This project, managed by <a href="http://oss.tresys.com/projects/refpolicy">Tresys</a>, is used by almost
all SELinux supporting distributions, including Gentoo Hardened, Fedora, RedHat
Enterprise Linux, Debian, Ubuntu and more. This implementation not only offers
the modular policies that users are looking for, but also enhances the SELinux
experience with additional development tools that make it easier to work with
the SELinux policies on your system. Updates in the reference policy eventually
make it in all supported distributions. The same goes for Gentoo Hardened, which
aims to use a policy as close as possible to the reference policy, and submits
its own patches to the reference policy as well, which benefits the entire
community.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Reference Policy API</a></p>
<p>
One major advantage of the reference policy is its API. To help policy writers,
the reference policy uses a macro language which generates the necessary allow
(and other) rules. This macro language makes it a lot easier to add rights to
particular domains. You can find the API documented <a href="http://oss.tresys.com/docs/refpolicy/api/">online</a>, but if you have
USE="doc" set, it will be stored on your system as well the moment you install
and configure SELinux.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Modular Approach</a></p>
<p>
Another feature of the reference policy is its use of <span class="emphasis">modules</span>. If you
would build all rules in a single policy (a binary file readable by the Linux
kernel, allowing it to interpret and enforce SELinux rules), the file would
quickly become too huge and inefficient.
</p>
<p>
Instead, the reference policy defines the rules in what it calls modules, which
define one domain (like <span class="code" dir="ltr">portage_t</span>) or more (if they are all tightly
related) and the rights and privileges that that domain would need in order to
function properly. Any right that the domain needs with respect to another
domain needs to be defined through that domains' interfaces (see earlier),
forcing the modules to be specific and manageable.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Example overview of installed SELinux modules</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
# <span class="code-input">semodule -l</span>
alsa    1.11.0
apache  2.3.0
audioentropy    1.6.0
dbus    1.15.0
dmidecode       1.4.0
<span class="code-comment">(...)</span>
</pre></td></tr>
</table>
<p>
By using a modular approach, one only needs to load the base policy (kernel
layer as well as other, core definitions) and the modules related to his system.
You can then safely ignore the other modules. This improves performance (smaller
policy, which also causes rebuilds to be a lot less painful) and manageability
(properly defined boundaries for policy rules).
</p>
<p class="secthead"><a name="doc_chap1_sect1">Tunables and Conditionals</a></p>
<p>
But wait, there's more. The reference policy also supports <span class="emphasis">booleans</span>.
Those are flags that a security administrator can enable or disable to change
the active policy. Properly defined booleans allow security administrators to
fine-tune the policy for their system.
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Overview of available booleans</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
# <span class="code-input">getsebool -a</span>
allow_execheap --&gt; off
allow_execmem --&gt; off
allow_execmod --&gt; off
allow_execstack --&gt; off
allow_gssd_read_tmp --&gt; on
allow_httpd_anon_write --&gt; off
</pre></td></tr>
</table>
<p>
Booleans are an important part to make a generic reference policy which is still
usable for the majority of SELinux users. Although they have specific
requirements (such as allowing ptrace, or disallowing execmem) they can still
use the same reference policy and only need to toggle the booleans they need.
</p>
<p class="secthead"><a name="doc_chap1_sect1">Policy Files and Versions</a></p>
<p>
The SELinux policy infrastructure that is used (i.e. the capabilities and
functionalities that it offers) isn't in its first version. Currently, SELinux
deployments use a binary version of 24 or 26 (depending on the kernel version
used).
</p>
<a name="doc_chap1_pre1"></a><table class="ntable" width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td bgcolor="#7a5ada"><p class="codetitle">Code Listing1.1: Getting the binary policy version</p></td></tr>
<tr><td bgcolor="#eeeeff" align="left" dir="ltr"><pre>
# <span class="code-input">sestatus</span>
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        strict
</pre></td></tr>
</table>
<p>
Every time functionalities or capabilities are added which require
changes to the internal structure of the compiled policy, this version is
incremented. The following is an overview of the policy versions' history. 
</p>
<dl>
  <dt>Version 12</dt>
  <dd>"Old API" for SELinux, which is now deprecated</dd>
  <dt>Version 15</dt>
  <dd>"New API" for SELinux, merged in Linux kernel 2.6.0 (until 2.6.5)</dd>
  <dt>Version 16</dt>
  <dd>Conditional policy extensions added (2.6.5)</dd>
  <dt>Version 17</dt>
  <dd>IPV6 support added (2.6.6 - 2.6.7)</dd>
  <dt>Version 18</dt>
  <dd>Fine-grained netlink socket support added (2.6.8 - 2.6.11)</dd>
  <dt>Version 19</dt>
  <dd>Enhanced multi-level security (2.6.12 - 2.6.13)</dd>
  <dt>Version 20</dt>
  <dd>Access vector table size optimizations (2.6.14 - 2.6.18)</dd>
  <dt>Version 21</dt>
  <dd>Object classes in range transitions (2.6.19 - 2.6.24)</dd>
  <dt>Version 22</dt>
  <dd>Policy capabilities (features) (2.6.25)</dd>
  <dt>Version 23</dt>
  <dd>Per-domain permissive mode (2.6.26 - 2.6.27)</dd>
  <dt>Version 24</dt>
  <dd>Explicit hierarchy (type bounds) (2.6.28 - 2.6.38)</dd>
  <dt>Version 25</dt>
  <dd>Filename based transition support (2.6.39)</dd>
  <dt>Version 26</dt>
  <dd>Role transition support for non-process classes (3.0)</dd>
</dl>
<p class="chaphead"><a name="doc_chap1"></a><span class="chapnum">1.
            </span>Next Steps</p>
<p class="secthead"><a name="doc_chap1_sect1">What Next</a></p>
<p>
It might be difficult to understand now, but the concepts are important because,
if something fails on your system when SELinux is enabled, but it doesn't fail
when SELinux is disabled, then you will need to dive into the security contexts,
rules, types and domain transitions to find out why.
</p>
<p>
The next chapter in line will give you some background resource information
(online resources, books, FAQs, etc.) After that, we'll dive into the
installation and configuration of SELinux on your Gentoo Hardened system. Then,
we'll configure and tune the SELinux policy to our needs.
</p>
</td>
<td width="1%" bgcolor="#dddaec" valign="top"><table border="0" cellspacing="4px" cellpadding="4px">
<tr><td class="topsep" align="center"><p class="alttext">Page updated July 21, 2011</p></td></tr>
<tr lang="en"><td align="center" class="topsep">
<p class="alttext"><b>Donate</b> to support our development efforts.
        </p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="paypal@gentoo.org"><input type="hidden" name="item_name" value="Gentoo Linux Support"><input type="hidden" name="item_number" value="1000"><input type="hidden" name="image_url" value="http://www.gentoo.org/images/paypal.png"><input type="hidden" name="no_shipping" value="1"><input type="hidden" name="return" value="http://www.gentoo.org"><input type="hidden" name="cancel_return" value="http://www.gentoo.org"><input type="image" src="http://images.paypal.com/images/x-click-but21.gif" name="submit" alt="Donate to Gentoo">
</form>
</td></tr>
<tr lang="en"><td align="center"><iframe src="http://sidebar.gentoo.org" scrolling="no" width="125" height="850" frameborder="0" style="border:0px padding:0x" marginwidth="0" marginheight="0"><p>Your browser does not support iframes.</p></iframe></td></tr>
</table></td>
</tr></table></td></tr>
<tr><td colspan="2" align="right" class="infohead">
Copyright 2001-2012 Gentoo Foundation, Inc. Questions, Comments? <a class="highlight" href="http://www.gentoo.org/main/en/contact.xml">Contact us</a>.
</td></tr>
</table></body>
</html>