~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to doc/src/sgml/sepgsql.sgml

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!-- doc/src/sgml/sepgsql.sgml -->
 
2
 
 
3
<sect1 id="sepgsql">
 
4
 <title>sepgsql</title>
 
5
 
 
6
 <indexterm zone="sepgsql">
 
7
  <primary>sepgsql</primary>
 
8
 </indexterm>
 
9
 
 
10
 <para>
 
11
  <filename>sepgsql</> is a loadable module which supports label-based
 
12
  mandatory access control (MAC) based on <productname>SELinux</> security
 
13
  policy.
 
14
 </para>
 
15
 
 
16
 <warning>
 
17
   <para>
 
18
     This implementation has signification limitations, and does not enforce
 
19
     mandatory access control for all actions.  See
 
20
     <xref linkend="sepgsql-limitations">.
 
21
   </para>
 
22
 </warning>
 
23
 
 
24
 <sect2 id="sepgsql-overview">
 
25
  <title>Overview</title>
 
26
 
 
27
  <para>
 
28
   This module integrates with <productname>SELinux</> to provide an
 
29
   additional layer of security checking above and beyond what is normaly
 
30
   provided by <productname>PostgreSQL</productname>.  From the perspective of
 
31
   <productname>SELinux</>, this module allows
 
32
   <productname>PostgreSQL</productname> to function as a user-space object
 
33
   manager.  Each table or function access initiated by a DML query will be
 
34
   checked against the system security policy.  This check is an additional to
 
35
   the usual permissions checking performed by
 
36
   <productname>PostgreSQL</productname>.
 
37
  </para>
 
38
 
 
39
  <para>
 
40
   <productname>SELinux</productname> access control decisions are made using
 
41
   security labels, which are represented by strings such as
 
42
   <literal>system_u:object_r:sepgsql_table_t:s0</>.  Each access control
 
43
   decision involves two labels: the label of the subject attempting to
 
44
   perform the action, and the label of the object on which the operation is
 
45
   to be performed.  Since these labels can be applied to any sort of object,
 
46
   access control decisions for objects stored within the database can be
 
47
   (and, with this module, are) subjected to the same general criteria used
 
48
   for objects of any other type (e.g. files).  This design is intended to
 
49
   allow a centralized security policy to protect information assets
 
50
   independent of the particulars of how those assets are stored.
 
51
  </para>
 
52
 
 
53
  <para>
 
54
   The <xref linkend="sql-security-label"> statement allows assignment of
 
55
   a security label to a database object.
 
56
  </para>
 
57
 
 
58
 </sect2>
 
59
 <sect2 id="sepgsql-installation">
 
60
  <title>Installation</title>
 
61
 
 
62
  <para>
 
63
    This module can only be used on <productname>Linux</productname> 2.6.28
 
64
    or higher with <productname>SELinux</productname> enabled.  It is not
 
65
    available on any other platform, and must be explicitly enabled using
 
66
    <literal>--with-selinux</>.  You will also need <productname>libselinux</>
 
67
    2.0.93 or higher and <productname>selinux-policy</> 3.9.13 or higher
 
68
    (some distributions may backport the necessary rules into older policy
 
69
    versions).
 
70
  </para>
 
71
 
 
72
  <para>
 
73
   The <command>sestatus</> command allows you to check the status of
 
74
   <productname>SELinux</productname>.
 
75
<screen>
 
76
$ sestatus
 
77
SELinux status:                 enabled
 
78
SELinuxfs mount:                /selinux
 
79
Current mode:                   enforcing
 
80
Mode from config file:          enforcing
 
81
Policy version:                 24
 
82
Policy from config file:        targeted
 
83
</screen>
 
84
   If <productname>SELinux</> is disabled or not installed, you must set
 
85
   that product up first before installing this module.
 
86
  </para>
 
87
 
 
88
  <para>
 
89
   To use this module, you must add include <literal>sepgsql</>
 
90
   in <xref linkend="guc-shared-preload-libraries">.  The module will not
 
91
   function if loaded in any other manner.  Once the module is loaded, you
 
92
   should execute <filename>sepgsql.sql</filename> in each database.
 
93
   This will install functions needed for security label management, and
 
94
   assign initial security labels.
 
95
  </para>
 
96
 
 
97
  <para>
 
98
   The following instructions that assume your installation is under the
 
99
   <filename>/usr/local/pgsql</> directory. Adjust the paths shown below as
 
100
   appropriate for your installaton.
 
101
  </para>
 
102
 
 
103
<screen>
 
104
$ initdb
 
105
$ vi $PGDATA/postgresql.conf
 
106
$ for DBNAME in template0 template1 postgres; do
 
107
  postgres --single -F -O -c exit_on_error=true $DBNAME \
 
108
      &lt; /usr/local/pgsql/share/contrib/sepgsql.sql &gt; /dev/null
 
109
  done
 
110
</screen>
 
111
 
 
112
  <para>
 
113
   If the installation process completes without error, you can now start the
 
114
   server normally.
 
115
  </para>
 
116
 </sect2>
 
117
 
 
118
 <sect2 id="sepgsql-regression">
 
119
  <title>Regression Tests</title>
 
120
  <para>
 
121
   Due to the nature of <productname>SELinux</productname>, running the
 
122
   regression tests for this module requires several additional configuration
 
123
   steps.
 
124
  </para>
 
125
 
 
126
  <para>
 
127
   First, build and install the policy package for the regression test.
 
128
   The <filename>sepgsql-regtest.pp</> is a special purpose policy package
 
129
   which provides a set of rules to be allowed during the regression tests.
 
130
   It should be built from the policy source file 
 
131
   (<filename>sepgsql-regtest.te</>), which is normally done using
 
132
   <command>make</command>.  You will need to locate the appropriate
 
133
   Makefile on your system; the path shown below is only an example.
 
134
   Once built, you can install this policy package using the
 
135
   <command>semodule</> command, which links supplied policy packages and
 
136
   loads them into the kernel space.  If this package is correctly installed,
 
137
   <literal><command>semodule</> -l</> should list sepgsql-regtest as an
 
138
   available policy package.
 
139
  </para>
 
140
 
 
141
<screen>
 
142
$ make -C ./contrib/sepgsql -f /usr/share/selinux/devel/Makefile
 
143
$ su
 
144
# semodule -u ./contrib/sepgsql/sepgsql-regtest.pp
 
145
# semodule -l
 
146
    :
 
147
sepgsql-regtest 1.03
 
148
    :
 
149
</screen>
 
150
 
 
151
  <para>
 
152
   Second, turn on <literal>sepgsql_regression_test_mode</>.
 
153
   We don't enable all the rules in the <filename>sepgsql-regtest.pp</>
 
154
   by default, for your system's safety.
 
155
   The <literal>sepgsql_regression_test_mode</literal> parameter is associated
 
156
   with rules to launch regression test.
 
157
   It can be turned on using <command>setsebool</> command.
 
158
  </para>
 
159
 
 
160
<screen>
 
161
$ su
 
162
# setsebool sepgsql_regression_test_mode on
 
163
# getsebool sepgsql_regression_test_mode
 
164
sepgsql_regression_test_mode --> on
 
165
</screen>
 
166
 
 
167
  <para>
 
168
   Last, kick the regression test from the <literal>unconfined_t</> domain.
 
169
  </para>
 
170
 
 
171
  <para>
 
172
   The <command>id</> command tells us the current working domain.
 
173
   Confirm your shell is now performing with the <literal>unconfined_t</>
 
174
   domain as follows.
 
175
  </para>
 
176
<screen>
 
177
$ id -Z
 
178
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
 
179
</screen>
 
180
 
 
181
  <para>
 
182
   See <xref linkend="sepgsql-resources"> for details on adjusting your
 
183
   working domain, if necessary.
 
184
  </para>
 
185
 
 
186
  <para>
 
187
   If <command>pg_regress</> fails to launch the <command>psql</> command,
 
188
   you may need to ensure that the <command>psql</> command is labeled
 
189
   as <literal>bin_t</>.  If it is not, the <command>restorecon</> command can
 
190
   often be used to fix up security labels within the
 
191
   <productname>PostgreSQL</productname> installation directory.
 
192
  </para>
 
193
 
 
194
<screen>
 
195
$ restorecon -R /usr/local/pgsql/
 
196
</screen>
 
197
 </sect2>
 
198
 
 
199
 <sect2 id="sepgsql-parameters">
 
200
  <title>GUC Parameters</title>
 
201
 
 
202
  <variablelist>
 
203
   <varlistentry id="guc-sepgsql-permissive" xreflabel="sepgsql.permissive">
 
204
    <term><varname>sepgsql.permissive</> (<type>boolean</type>)</term>
 
205
    <indexterm>
 
206
     <primary><varname>sepgsql.permissive</> configuration parameter</primary>
 
207
    </indexterm>
 
208
    <listitem>
 
209
     <para>
 
210
      This parameter enables <productname>SE-PostgreSQL</> to function
 
211
      in permissive mode, regardless of the system setting.
 
212
      The default is off.
 
213
      This parameter can only be set in the <filename>postgresql.conf</>
 
214
      file or on the server command line.
 
215
     </para>
 
216
 
 
217
     <para>
 
218
      When this parameter is on, <productname>SE-PostgreSQL</> functions
 
219
      in permissive mode, even if the platform system is working in enforcing
 
220
      mode.  This parameter is primarily useful for testing purposes.
 
221
     </para>
 
222
    </listitem>
 
223
 
 
224
   </varlistentry>
 
225
   <varlistentry id="guc-sepgsql-debug-audit" xreflabel="sepgsql.debug_audit">
 
226
    <term><varname>sepgsql.debug_audit</> (<type>boolean</>)</>
 
227
    <indexterm>
 
228
     <primary><varname>sepgsql.debug_audit</> configuration parameter</>
 
229
    </indexterm>
 
230
    <listitem>
 
231
     <para>
 
232
      This parameter enables the printing of audit messages independent from
 
233
      the policy setting.
 
234
      The default is off (according to the security policy setting).
 
235
     </para>
 
236
 
 
237
     <para>
 
238
      The security policy of <productname>SELinux</> also has rules to
 
239
      control whether or not particular accesses are logged.
 
240
      By default, access violations are logged, but allowed
 
241
      accesses are not.
 
242
     </para>
 
243
 
 
244
     <para>
 
245
      This parameter forces all possible logging to be turned on, regardless
 
246
      of the system policy.
 
247
     </para>
 
248
    </listitem>
 
249
   </varlistentry>
 
250
  </variablelist>
 
251
 </sect2>
 
252
 
 
253
 <sect2 id="sepgsql-features">
 
254
  <title>Features</title>
 
255
  <sect3>
 
256
   <title>Controlled Object Classes</title>
 
257
   <para>
 
258
    The security model of <productname>SELinux</> describes all the access
 
259
    control rules as a relationship between a subject entity (typically,
 
260
    it is a client of database) and an object entity, each of which is
 
261
    identified by a security label.  If access to an unlabelled object is
 
262
    attempted, the object is treated as if it were assigned the label
 
263
    <literal>unlabeled_t</>.
 
264
   </para>
 
265
 
 
266
   <para>
 
267
    Currently, <productname>sepgsql</productname> allows security labels to be
 
268
    assigned to schemas, tables, columns, sequences, views, and functions.
 
269
    When <productname>sepgsql</productname> is in use, security labels are
 
270
    automatically assigned to supported database objects at creation time.
 
271
    This label is called as a default security label, being decided according
 
272
    to the system security policy, which takes as input the creator's label
 
273
    and the label assigned to the new object's parent object.
 
274
   </para>
 
275
 
 
276
   <para>
 
277
    A new database object basically inherits the security label of the parent
 
278
    object, except when the security policy has special rules known as
 
279
    type-transition rules, in which case a different label may be applied.
 
280
    For schemas, the parent object is the current database; for columns, it
 
281
    is the corresponding table; for tables, sequences, views, and functions,
 
282
    it is the containing schema.
 
283
   </para>
 
284
  </sect3>
 
285
 
 
286
  <sect3>
 
287
   <title>DML Permissions</title>
 
288
 
 
289
   <para>
 
290
    For tables, <literal>db_table:select</>, <literal>db_table:insert</>,
 
291
    <literal>db_table:update</> or <literal>db_table:delete</> is
 
292
    checked for all the referenced target tables depending on the sort of
 
293
    statement;
 
294
    in addition, <literal>db_table:select</> is also checked for
 
295
    all the tables that contain the columns referenced in the
 
296
    <literal>WHERE</> or <literal>RETURNING</> clause, as a data source
 
297
    of <literal>UPDATE</>, and so on.
 
298
   </para>
 
299
 
 
300
   <para>
 
301
<synopsis>
 
302
UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
 
303
</synopsis>
 
304
 
 
305
    In this case, we must have <literal>db_table:select</> in addition to
 
306
    <literal>db_table:update</>, because <literal>t1.a</> is referenced
 
307
    within the <literal>WHERE</> clause.  Column-level permissions will also be
 
308
    checked for each referenced column.
 
309
   </para>
 
310
 
 
311
   <para>
 
312
    The client must be allowed to access all referenced tables and
 
313
    columns, even if they originated from views which were then expanded,
 
314
    so that we apply consistent access control rules independent of the manner
 
315
    in which the table contents are referenced.
 
316
   </para>
 
317
 
 
318
   <para>
 
319
    For columns, <literal>db_column:select</> is checked on
 
320
    not only the columns being read using <literal>SELECT</>, but being
 
321
    referenced in other DML statements.
 
322
   </para>
 
323
 
 
324
   <para>
 
325
    Of course, it also checks <literal>db_column:update</> or
 
326
    <literal>db_column:insert</> on the column being modified by
 
327
    <literal>UPDATE</> or <literal>INSERT</>.
 
328
   </para>
 
329
 
 
330
   <para>
 
331
<synopsis>
 
332
UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
 
333
</synopsis>
 
334
    In this case, it checks <literal>db_column:update</> on
 
335
    the <literal>t1.x</> being updated, <literal>db_column:{select update}</>
 
336
    on the <literal>t1.y</> being updated and referenced,
 
337
    and <literal>db_column:select</> on the <literal>t1.z</> being only
 
338
    referenced in the <literal>WHERE</> clause.
 
339
    <literal>db_table:{select update}</> will also be checked
 
340
    at the table level.
 
341
   </para>
 
342
 
 
343
   <para>
 
344
    For sequences, <literal>db_sequence:get_value</> is checked when we
 
345
    reference a sequence object using <literal>SELECT</>; however, note that we
 
346
    do not currently check permissions on execution of corresponding functions
 
347
    such as <literal>lastval()</>.
 
348
   </para>
 
349
 
 
350
   <para>
 
351
    For views, <literal>db_view:expand</> shall be checked, then any other
 
352
    corresponding permissions shall be also checked on the objects being
 
353
    expanded from the view, individually.
 
354
   </para>
 
355
 
 
356
   <para>
 
357
    For functions, <literal>db_procedure:{execute}</> is defined, but not
 
358
    checked in this version.
 
359
   </para>
 
360
 
 
361
   <para>
 
362
    The default database privilege system allows database superusers to
 
363
    modify system catalogs using DML commands, and reference or modify
 
364
    toast tables.  These operations are prohibited when
 
365
    <productname>sepgsql</> is enabled.
 
366
   </para>
 
367
  </sect3>
 
368
 
 
369
  <sect3>
 
370
   <title>DDL Permissions</title>
 
371
   <para>
 
372
    On <xref linkend="sql-security-label"> command, <literal>setattr</> and
 
373
    <literal>relabelfrom</> shall be checked on the object being relabeled
 
374
    with an old security label, then <literal>relabelto</> on the supplied
 
375
    new security label.
 
376
   </para>
 
377
 
 
378
   <para>
 
379
    In the case where multiple label providers are installed and the user tries
 
380
    to set a security label, but is not managed by <productname>SELinux</>,
 
381
    only <literal>setattr</> should be checked here.
 
382
    This is currently not checked due to implementation restrictions.
 
383
   </para>
 
384
  </sect3>
 
385
 
 
386
  <sect3>
 
387
   <title>Trusted Procedure</title>
 
388
   <para>
 
389
    Trusted procedures are similar to security definer functions or set-uid
 
390
    commands. <productname>SELinux</> provides a feature to allow trusted
 
391
    code to run using a security label different from that of the client,
 
392
    generally for the purpose of providing highly controlled access to
 
393
    sensitive data (e.g. rows might be omitted, or the precision of stored
 
394
    values might be reduced).  Whether or not a function acts as a trusted
 
395
    procedure is controlled by its security label and the operating system
 
396
    security policy.  For example:
 
397
   </para>
 
398
 
 
399
<screen>
 
400
postgres=# CREATE TABLE customer (
 
401
               cid     int primary key,
 
402
               cname   text,
 
403
               credit  text
 
404
           );
 
405
CREATE TABLE
 
406
postgres=# SECURITY LABEL ON COLUMN customer.credit
 
407
               IS 'system_u:object_r:sepgsql_secret_table_t:s0';
 
408
SECURITY LABEL
 
409
postgres=# CREATE FUNCTION show_credit(int) RETURNS text
 
410
             AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'')
 
411
                        FROM customer WHERE cid = $1'
 
412
           LANGUAGE sql;
 
413
CREATE FUNCTION
 
414
postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
 
415
               IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
 
416
SECURITY LABEL
 
417
</screen>
 
418
 
 
419
   <para>
 
420
    The above operations should be performed by an administrative user.
 
421
   </para>
 
422
 
 
423
<screen>
 
424
postgres=# SELECT * FROM customer;
 
425
ERROR:  SELinux: security policy violation
 
426
postgres=# SELECT cid, cname, show_credit(cid) FROM customer;
 
427
 cid | cname  |     show_credit
 
428
-----+--------+---------------------
 
429
   1 | taro   | 1111-2222-3333-xxxx
 
430
   2 | hanako | 5555-6666-7777-xxxx
 
431
(2 rows)
 
432
</screen>
 
433
 
 
434
   <para>
 
435
    In this case, a regular user cannot reference <literal>customer.credit</>
 
436
    directly, but a trusted procedure <literal>show_credit</> enables us
 
437
    to print the credit card number of customers with some of the digits masked
 
438
    out.
 
439
   </para>
 
440
  </sect3>
 
441
 
 
442
  <sect3>
 
443
   <title>Miscellaneous</title>
 
444
   <para>
 
445
    We reject the <xref linkend="sql-load"> command across the board, because
 
446
    any module loaded could easily circumvent security policy enforcement.
 
447
   </para>
 
448
 
 
449
  </sect3>
 
450
 </sect2>
 
451
 
 
452
 <sect2 id="sepgsql-limitations">
 
453
  <title>Limitations</title>
 
454
 
 
455
  <variablelist>
 
456
   <varlistentry>
 
457
    <term>Userspace access vector cache</term>
 
458
    <listitem>
 
459
     <para>
 
460
      <productname>sepgsql</> does not yet support an access vector cache.
 
461
      This would likely improve performance.
 
462
     </para>
 
463
    </listitem>
 
464
   </varlistentry>
 
465
 
 
466
   <varlistentry>
 
467
    <term>Data Definition Language (DDL) Permissions</term>
 
468
    <listitem>
 
469
     <para>
 
470
      Due to implementation restrictions, DDL permissions are not checked.
 
471
     </para>
 
472
    </listitem>
 
473
   </varlistentry>
 
474
 
 
475
   <varlistentry>
 
476
    <term>Data Control Language (DCL) Permissions</term>
 
477
    <listitem>
 
478
     <para>
 
479
      Due to implementation restrictions, DCL permissions are not checked.
 
480
     </para>
 
481
    </listitem>
 
482
   </varlistentry>
 
483
 
 
484
   <varlistentry>
 
485
    <term>Row-level access control</term>
 
486
    <listitem>
 
487
     <para>
 
488
      <productname>PostgreSQL</> does not support row-level access; therefore,
 
489
      <productname>sepgsql</productname> does not support it either.
 
490
     </para>
 
491
    </listitem>
 
492
   </varlistentry>
 
493
 
 
494
   <varlistentry>
 
495
    <term>Covert channels</term>
 
496
    <listitem>
 
497
     <para>
 
498
      <productname>sepgsql</> never tries to hide existence of
 
499
      a certain object, even if the user is not allowed to the reference.
 
500
      For example, we can infer the existence of an invisible object as
 
501
      a result of primary key conflicts, foreign key violations, and so on,
 
502
      even if we cannot reference contents of these objects.  The existence
 
503
      of a top secret table cannot be hidden; we only hope to conceal its
 
504
      contents.
 
505
     </para>
 
506
    </listitem>
 
507
   </varlistentry>
 
508
  </variablelist>
 
509
 </sect2>
 
510
 
 
511
 <sect2 id="sepgsql-resources">
 
512
  <title>External Resources</title>
 
513
  <variablelist>
 
514
   <varlistentry>
 
515
    <term><ulink url="http://wiki.postgresql.org/wiki/SEPostgreSQL">SE-PostgreSQL Introduction</ulink></term>
 
516
    <listitem>
 
517
     <para>
 
518
      This wiki page provides a brief-overview, security design, architecture,
 
519
      administration and upcoming features.
 
520
     </para>
 
521
    </listitem>
 
522
   </varlistentry>
 
523
   <varlistentry>
 
524
    <term><ulink url="http://docs.fedoraproject.org/selinux-user-guide/">Fedora SELinux User Guide</ulink></term>
 
525
    <listitem>
 
526
     <para>
 
527
      This document provides a wide spectrum of knowledge to administer
 
528
      <productname>SELinux</> on your systems.
 
529
      It focuses primarily on Fedora, but is not limited to Fedora.
 
530
     </para>
 
531
    </listitem>
 
532
   </varlistentry>
 
533
   <varlistentry>
 
534
    <term><ulink url="http://docs.fedoraproject.org/selinux-faq">Fedora SELinux FAQ</ulink></term>
 
535
    <listitem>
 
536
     <para>
 
537
      This document answers frequently asked questions about
 
538
      <productname>SELinux</productname>.
 
539
      It focuses primarily on Fedora, but is not limited to Fedora.
 
540
     </para>
 
541
    </listitem>
 
542
   </varlistentry>
 
543
  </variablelist>
 
544
 </sect2>
 
545
 
 
546
 <sect2 id="sepgsql-author">
 
547
  <title>Author</title>
 
548
  <para>
 
549
   KaiGai Kohei <email>kaigai@ak.jp.nec.com</email>
 
550
  </para>
 
551
 </sect2>
 
552
</sect1>