1
<!-- doc/src/sgml/sepgsql.sgml -->
6
<indexterm zone="sepgsql">
7
<primary>sepgsql</primary>
11
<filename>sepgsql</> is a loadable module which supports label-based
12
mandatory access control (MAC) based on <productname>SELinux</> security
18
This implementation has signification limitations, and does not enforce
19
mandatory access control for all actions. See
20
<xref linkend="sepgsql-limitations">.
24
<sect2 id="sepgsql-overview">
25
<title>Overview</title>
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>.
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.
54
The <xref linkend="sql-security-label"> statement allows assignment of
55
a security label to a database object.
59
<sect2 id="sepgsql-installation">
60
<title>Installation</title>
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
73
The <command>sestatus</> command allows you to check the status of
74
<productname>SELinux</productname>.
77
SELinux status: enabled
78
SELinuxfs mount: /selinux
79
Current mode: enforcing
80
Mode from config file: enforcing
82
Policy from config file: targeted
84
If <productname>SELinux</> is disabled or not installed, you must set
85
that product up first before installing this module.
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.
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.
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
< /usr/local/pgsql/share/contrib/sepgsql.sql > /dev/null
113
If the installation process completes without error, you can now start the
118
<sect2 id="sepgsql-regression">
119
<title>Regression Tests</title>
121
Due to the nature of <productname>SELinux</productname>, running the
122
regression tests for this module requires several additional configuration
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.
142
$ make -C ./contrib/sepgsql -f /usr/share/selinux/devel/Makefile
144
# semodule -u ./contrib/sepgsql/sepgsql-regtest.pp
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.
162
# setsebool sepgsql_regression_test_mode on
163
# getsebool sepgsql_regression_test_mode
164
sepgsql_regression_test_mode --> on
168
Last, kick the regression test from the <literal>unconfined_t</> domain.
172
The <command>id</> command tells us the current working domain.
173
Confirm your shell is now performing with the <literal>unconfined_t</>
178
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
182
See <xref linkend="sepgsql-resources"> for details on adjusting your
183
working domain, if necessary.
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.
195
$ restorecon -R /usr/local/pgsql/
199
<sect2 id="sepgsql-parameters">
200
<title>GUC Parameters</title>
203
<varlistentry id="guc-sepgsql-permissive" xreflabel="sepgsql.permissive">
204
<term><varname>sepgsql.permissive</> (<type>boolean</type>)</term>
206
<primary><varname>sepgsql.permissive</> configuration parameter</primary>
210
This parameter enables <productname>SE-PostgreSQL</> to function
211
in permissive mode, regardless of the system setting.
213
This parameter can only be set in the <filename>postgresql.conf</>
214
file or on the server command line.
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.
225
<varlistentry id="guc-sepgsql-debug-audit" xreflabel="sepgsql.debug_audit">
226
<term><varname>sepgsql.debug_audit</> (<type>boolean</>)</>
228
<primary><varname>sepgsql.debug_audit</> configuration parameter</>
232
This parameter enables the printing of audit messages independent from
234
The default is off (according to the security policy setting).
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
245
This parameter forces all possible logging to be turned on, regardless
246
of the system policy.
253
<sect2 id="sepgsql-features">
254
<title>Features</title>
256
<title>Controlled Object Classes</title>
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</>.
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.
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.
287
<title>DML Permissions</title>
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
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.
302
UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
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.
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.
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.
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</>.
332
UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
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
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()</>.
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.
357
For functions, <literal>db_procedure:{execute}</> is defined, but not
358
checked in this version.
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.
370
<title>DDL Permissions</title>
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
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.
387
<title>Trusted Procedure</title>
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:
400
postgres=# CREATE TABLE customer (
406
postgres=# SECURITY LABEL ON COLUMN customer.credit
407
IS 'system_u:object_r:sepgsql_secret_table_t:s0';
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'
414
postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
415
IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
420
The above operations should be performed by an administrative user.
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
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
443
<title>Miscellaneous</title>
445
We reject the <xref linkend="sql-load"> command across the board, because
446
any module loaded could easily circumvent security policy enforcement.
452
<sect2 id="sepgsql-limitations">
453
<title>Limitations</title>
457
<term>Userspace access vector cache</term>
460
<productname>sepgsql</> does not yet support an access vector cache.
461
This would likely improve performance.
467
<term>Data Definition Language (DDL) Permissions</term>
470
Due to implementation restrictions, DDL permissions are not checked.
476
<term>Data Control Language (DCL) Permissions</term>
479
Due to implementation restrictions, DCL permissions are not checked.
485
<term>Row-level access control</term>
488
<productname>PostgreSQL</> does not support row-level access; therefore,
489
<productname>sepgsql</productname> does not support it either.
495
<term>Covert channels</term>
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
511
<sect2 id="sepgsql-resources">
512
<title>External Resources</title>
515
<term><ulink url="http://wiki.postgresql.org/wiki/SEPostgreSQL">SE-PostgreSQL Introduction</ulink></term>
518
This wiki page provides a brief-overview, security design, architecture,
519
administration and upcoming features.
524
<term><ulink url="http://docs.fedoraproject.org/selinux-user-guide/">Fedora SELinux User Guide</ulink></term>
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.
534
<term><ulink url="http://docs.fedoraproject.org/selinux-faq">Fedora SELinux FAQ</ulink></term>
537
This document answers frequently asked questions about
538
<productname>SELinux</productname>.
539
It focuses primarily on Fedora, but is not limited to Fedora.
546
<sect2 id="sepgsql-author">
547
<title>Author</title>
549
KaiGai Kohei <email>kaigai@ak.jp.nec.com</email>