From 968bc6fac91d6aaca594488ab85c179b686cbbdd Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Sun, 23 Jan 2011 20:44:48 -0500 Subject: sepgsql, an SE-Linux integration for PostgreSQL This is still pretty rough - among other things, the documentation needs work, and the messages need a visit from the style police - but this gets the basic framework in place. KaiGai Kohei --- doc/src/sgml/contrib.sgml | 1 + doc/src/sgml/filelist.sgml | 1 + doc/src/sgml/sepgsql.sgml | 704 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 706 insertions(+) create mode 100644 doc/src/sgml/sepgsql.sgml (limited to 'doc/src') diff --git a/doc/src/sgml/contrib.sgml b/doc/src/sgml/contrib.sgml index f5bd493543f..75d08d5f695 100644 --- a/doc/src/sgml/contrib.sgml +++ b/doc/src/sgml/contrib.sgml @@ -116,6 +116,7 @@ psql -d dbname -f SHAREDIR/contrib/module.sql &pgtrgm; &pgupgrade; &seg; + &sepgsql; &contrib-spi; &sslinfo; &tablefunc; diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index 9d4cfc927ba..99437ac3789 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -129,6 +129,7 @@ + diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml new file mode 100644 index 00000000000..91b8614b81a --- /dev/null +++ b/doc/src/sgml/sepgsql.sgml @@ -0,0 +1,704 @@ + + + + sepgsql + + + sepgsql + + + + The sepgsql is a module which performs as an external + security provider; to support label based mandatory access control + (MAC) base on SELinux policy. + + + This extension won't build at all unless the installation was configured + with --with-selinux. + + + + Overview + + + PostgreSQL provides various kind of hooks. Some of these + hooks can be utilized to make access control decision on the supplied + users' accesses on database objects. + We call plug-in modules making access control decision based on its own + security model as an external security provider. + + + This module acquires control on these strategic points, then it asks + SELinux to check whether the supplied access shall be + allowed, or not. Then, it returns its access control decision. + If violated, this module prevents this access with rising an error for + example. + + + A series of making decision is done independently from the default + database privilege mechanism. Users must be allowed with both of access + control models, whenever they try to access something. + + + We can see SELinux as a function which takes two arguments + then returns a bool value; allowed or denied. The first argument in this + analogy is label of subject which tries to reference a certain obejct. + The other one is label of the object being referenced in this operation. + + + Label is a formatted string, + like system_u:object_r:sepgsql_table_t:s0. + It is not a property depending on characteristics of a certain kind of + object, so we can apply common credentials on either database objects + or others. + + + PostgreSQL 9.1 or later supports + statement that allows to assign + a security label on specified database objects, if user wants to change + label from the creation default. + Also SELinux provides an interface to obtain security + label of the peer process that connected to. + + + These facilities enable to integrate SELinux model within + access controls to database objects. Because it makes access control + decision according to a common centralized security policy (a set of rules), + its decision will be always consistent independent from the way to store + information assets. + + + + Installation + + The sepgsql module requires the following packages to install. + Please check it at first. + + + + Linux kernel + + + v2.6.28 or later with built with SELinux enabled + + + + + libselinux + + + v2.0.80 or later + + + This library provides a set of APIs to communicate with + SELinux in kernel. + + + + + selinux-policy + + + v3.9.13 or later + + + The default security policy provides a set of access control rules. + Some of distribution may backports necessary rules, even if base + policy was older than above version. + + + + + + SE-PostgreSQL needs SELinux being + available on the platform. You can check the current setting using + sestatus. + +$ sestatus +SELinux status: enabled +SELinuxfs mount: /selinux +Current mode: enforcing +Mode from config file: enforcing +Policy version: 24 +Policy from config file: targeted + + If disabled or not-installed, you need to set up SELinux + prior to all the installation step of SE-PostgreSQL. + + + On the compile time, add --with-selinux option to + the configure script to check existence of + the libselinux, and to set a flag whether + we build this contrib module, or not. + +$ ./configure --enable-debug --enable-cassert --with-selinux +$ make +$ make install + + + + Next to the initdb, add '$libdir/sepgsql' + to in + the postgresql.conf. + + It enables to load sepgsql on the starting up of + postmaster process. + + + Then, load the sepgsql.sql script for each databases. + It installs functions corresponding to security label management, and + tries to assign initial labels on the target objects. + + + The following instruction assumes your installation is under the + /usr/local/pgsql directory, and the database cluster is in + /usr/local/pgsql/data. Substitute your paths appropriately. + + +$ initdb -D $PGDATA +$ vi $PGDATA/postgresql.conf +$ for DBNAME in template0 template1 postgres; do + postgres --single -F -O -c exit_on_error=true -D $PGDATA $DBNAME \ + < /usr/local/pgsql/share/contrib/sepgsql.sql > /dev/null + done + + + If all the installation process was done with no errors, start postmaster + process. SE-PostgreSQL shall prevent violated accesses + according to the security policy of SELinux. + + + + + Regression Tests + + The regression test of this module requires a few more configurations + on the platform system, in addition to the above installation process. + See the following steps. + + + First, install the policy package for regression test. + The sepgsql-regtest.pp is a special purpose policy package + that provides a set of rules to be allowed during the regression test + cases. It shall be installed at /usr/local/pgsql/share/contrib + directory in the default setup. + + + You need to install this policy package using semodule + command which enables to link supplied policy packages and load them + into the kernel space. If you could install the pakage correctly, + semodule -l prints sepgsql-regtest as a part + of policy packages currently available. + + +$ su +# semodule -u /usr/local/pgsql/share/contrib/sepgsql-regtest.pp +# semodule -l + : +sepgsql-regtest 1.03 + : + + + Second, turn on the sepgsql_regression_test_mode. + We don't enable all the rules in the sepgsql-regtest.pp + in the default, for your system's safety. + The sepgsql_regression_test_mode parameter is associated + with rules to launch regression test. + It can be turned on using setsebool command. + + +$ su +# setsebool sepgsql_regression_test_mode on +# getsebool sepgsql_regression_test_mode +sepgsql_regression_test_mode --> on + + + Last, kick the regression test from the unconfined_t domain. + + + This test policy is designed to kick each test cases from the + unconfined_t domain that is a default choice in most of + the known SELinux installation base. + So, you don't need to set up anything special, as long as you didn't + change default configuration of SELinux before. + + + The id command tells us the current working domain. + Confirm your shell is now performing with unconfined_t + domain as follows. + + +$ id -Z +unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 + + + If not an expected one, you should revert this configuration. + The section will give you + some useful hints. + + + Then, you will see the all-green result of regression test, + if we have no problem here. + + +$ make -C contrib/sepgsql/ installcheck + : +../../src/test/regress/pg_regress --inputdir=. --psqldir=/usr/local/pgsql/bin \ + --dbname=contrib_regression --launcher ../../contrib/sepgsql/launcher \ + label dml +(using postmaster on Unix socket, default port) +============== dropping database "contrib_regression" ============== +DROP DATABASE +============== creating database "contrib_regression" ============== +CREATE DATABASE +ALTER DATABASE +============== running regression test queries ============== +test label ... ok +test dml ... ok +test misc ... ok + +===================== + All 3 tests passed. +===================== + + + If pg_regress failed to launch psql command, + here is a hint to fix up the matter. + + When we try to launch psql command with restrictive + privileges, the psql must eb labeled as bin_t. + If not, try to run restorecon to fix up security label of + the commands as expected. + + +$ restorecon -R /usr/local/pgsql/ + + + + + GUC Parameters + + + + sepgsql.permissive (boolean) + + sepgsql.permissive configuration parameter + + + + This parameter enables to perform SE-PostgreSQL + in permissive mode independent from the system setting. + The default is off (according to the system setting). + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + We have two performing mode except for disabled; The one is enforcing + mode that checks the security policy on references and actually prevents + violated accesses. The other is permissive mode that only checks + the security policy, but does not prevents anything except for log + generation. + This log shall be utilized for debugging of the security policy itself. + + + When this parameter is on, SE-PostgreSQL performs + in permissive mode, even if the platform system is working on enforcing + mode. + We recommend users to keep the default setting, except for the case + when we develop security policy by ourself. + + + + + sepgsql.debug_audit (boolean) + + sepgsql.debug_audit configuration parameter + + + + This parameter enables to print audit messages independent from + the policy setting. + The default is off (according to the security policy setting). + + + The security policy of SELinux also has rules to + control what accesses shall be logged, or not. + In the default, any access violations are logged, but any allowed + accesses are not logged. + + + When this parameter is on, all the possible logs shall be printed + independently from the policy settings. + We recommend to keep the variable turned off in normal cases to + avoid noisy messages. + + + + + + + + Features + + controlled object classes + + The security model of SELinux describes all the access + control rules as a relationship between a subject entity (typically, + it is a client of database) and an object entity. + And, these entities are identified by a security label. + + + We call a set of these rules as security policy. + All the access control decision shall be made according to the security + policy, when we ask SELinux whether the required action shall be allowed + or not. + Thus, we have no way to control accesses on any sort of objects without + security labels. + (SELinux assumes unlabeled_t is assigned, + if no valid security label is assigned on the target object.) + + + This version of SE-PostgreSQL supports to assign + a security label on these database object classes: schema, table, column, + sequence, view and procedure. + Other database object classes are not supported to assign security label + on, right now. + + + A security label shall be automatically assigned to the supported + database objects on their creation time. + This label is called as a default security label; being decided according + to the security policy, or a pair of security label of the client and + upper object for more correctly. + + + A new database object basically inherits security label of the upper + object. A new column inherits security label of its parent table for + instance. + If and when the security policy has special rules called as + type-transition on a pair of the client and upper object, we can assign + an individual label as a default. The upper object depends on sort of + object classes as follows. + + + + schema + + + Its upper object is the current database. + + + + + table + + + Its upper object is the schema object which owns the new table. + + + + + column + + + Its upper object is the table object which owns the new column. + + + + + sequence + + + Its upper object is the schema object which owns the new sequence. + + + + + view + + + Its upper object is the schema object which owns the new view. + + + + + procedure + + + Its upper object is the schema object which owns the new procedure. + + + + + + + DML Permissions + + This section introduces what permissions shall be checked on DML; + SELECT, INSERT, UPDATE and + DELETE. + + + DML statements are used to reference or modify contents within + the specified database objects; such as tables or columns. + We basically checks access rights of the client on all the appeared + objects in the given statement, and kind of privileges depend on + class of object and sort of accesses. + + + For tables, db_table:select, db_table:insert, + db_table:update or db_table:delete shall be + checked for all the appeared target tables depending on the sort of + statement; + In addition, db_table:select shall be also checked for + all the tables that containin the columns to be referenced in + WHERE or RETURNING clause, as a data source + of UPDATE, and so on. + + + +UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; + + In this case, we must have db_table:select, not only + db_table:update, because t1.a is referenced + within WHERE clause. + Also note that column-level permission shall be checked individually. + + + The client must be allowed to reference all the appeared tables and + columns, even if they are originated from views then expanded, unlike + the default database privileges, because we intend to apply consistent + access control rules independent from the route to reference contents + of the tables. + + + For columns, db_column:select shall be also checked on + not only the columns being read using SELECT, but being + referenced in other DML statement. + + + Of course, it also checks db_column:update or + db_column:insert on the column being modified by + UPDATE or INSERT. + Note that we have no definition of column-level delete permission, + like as the default database privilege doing. + + + +UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; + + In this case, it checks db_column:update on + the t1.x being updated, db_column:{select update} + on the t1.y being updated and referenced, + and db_column:select on the t1.z being only + referenced in the WHERE clause. + Also note that db_table:{select update} shall be checked + in the table-level granularity. + + + For sequences, db_sequence:get_value when we reference + a sequence object using SELECT, however, note that we + cannot check permissions on execution of corresponding functions + such as lastval() right now, although they performs same + job, because here is no object access hook to acquire controls. + + + For views, db_view:expand shall be checked, then any other + corresponding permissions shall be also checked on the objects being + expanded from the view, individually. + Note that both of permissions have to be allowed. + + + For procedures, db_procedure:{execute} is defined, but not + checked in this version. + + + Here is a few more corner cases. + The default database privilege system allows database superusers to + modify system catalogs using DML commands, and reference or modify + toast tables, however, both of the cases shall be denied when + SE-PostgreSQL is enabled. + + + + DDL Permissions + + On command, setattr and + relabelfrom shall be checked on the object being relabeled + with an old security label, then relabelto on the supplied + new security label. + + + In a case when multiple label providers are installed and user tries + to set a security label, but is not managed by SELinux, + only setattr should be checked here. + However, it is not unavailable because of limitation of the hook. + + + As we will describe in section, + SE-PostgreSQL does not control any other DDL operations. + + + + Trusted Procedure + + It is a similar idea to security definer functions or set-uid commands + on operating systems. SELinux provides a feature to + switch privilege of the client (that is a security label of the client + for more correctness) during execution of certain functions; being + called as trusted procedures. + + + A trusted function is a function with a special security label being + set up as a trusted procedure. + So, we need to assign the special security label on the function that + we hope it to perform as a trusted procedure, by administrative users. + The default security policy also provides this special security label. + See the following example. + + +postgres=# CREATE TABLE customer ( + cid int primary key, + cname text, + credit text + ); +CREATE TABLE +postgres=# SECURITY LABEL ON COLUMN customer.credit + IS 'system_u:object_r:sepgsql_secret_table_t:s0'; +SECURITY LABEL +postgres=# CREATE FUNCTION show_credit(int) RETURNS text + AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'') + FROM customer WHERE cid = $1' + LANGUAGE sql; +CREATE FUNCTION +postgres=# SECURITY LABEL ON FUNCTION show_credit(int) + IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0'; +SECURITY LABEL + + + Above operations shall be done by administrative users. + + +postgres=# SELECT * FROM customer; +ERROR: SELinux: security policy violation +postgres=# SELECT cid, cname, show_credit(cid) FROM customer; + cid | cname | show_credit +-----+--------+--------------------- + 1 | taro | 1111-2222-3333-xxxx + 2 | hanako | 5555-6666-7777-xxxx +(2 rows) + + + In this case, a regular user cannot reference customer.credit + directly, but a trusted procedure show_credit enables us + to print credit number of customers with a bit modification. + + + + Miscellaneous + + In this version, we reject command across + the board, because the binary module can override security hooks to + make access control decision. It means a risk to invalidate all the + control by security providers. + + + + + Limitations + + This section introduces limitations of SE-PostgreSQL + in this version. + + + + Userspace access vector cache + + + SE-PostgreSQL tells SELinux its access + control decision. It takes system call invocation being heavy, however, + we can reduce number of the invocations using caching mechanism; called + as access vector cache in SELinux. + Because of code size, SE-PostgreSQL does not support + this mechanism yet. + + + + + DDL Permissions + + + Now PostgreSQL does not provide a set of hooks on + the DDL routines. + It means plugin modules cannot acquire control here, + so SE-PostgreSQL does not check DDL Permissions + right now. + + + + + Row-level access control + + + Now SE-PostgreSQL does not support row-level access + control, because a few needed facilities are not supported yet. + The one is security labels on users' tables. The other is behavior of + optimizer. Also see for more details. + We know similar issue on VIEW. + + + + + Covert channels + + + SE-PostgreSQL never tries to hide existence of + a certain object, even if user is not allowed to reference. + For example, we can infer an existence of invisible object using + primary-key confliction, foreign-key violation, and so on, even if + we cannot reference contents of these objects. + + + + + + + External Resources + + + SE-PostgreSQL Introduction + + + This wikipage provides a brief-overview, security design, architecture, + administration and upcoming feature for more details. + + + + + Fedora SELinux User Guide + + + This document provides wide spectrum of knowledge to administrate + SELinux on your systems. + It primary focuses on Fedora, but not limited to Fedora. + + + + + Fedora SELinux FAQ + + + This document provides FAQs about SELinux. + It primary focuses on Fedora, but not limited to Fedora. + + + + + + + Author + + KaiGai Kohei (kaigai@ak.jp.nec.com) + + + -- cgit v1.2.3