SEPostgreSQL 文档
本页面作为修订 SE-PostgreSQL 模块文档的基础。
So, don't use any markups which are not supported in *.sgml, such as inline images.
sepgsql
sepgsql 是一个模块,它充当外部安全提供者,以支持基于 SELinux 策略的基于标签的强制访问控制 (MAC)。
除非安装配置了--with-selinux.
,否则此扩展将无法构建。
概述
PostgreSQL 提供了各种类型的钩子。其中一些钩子可用于根据所提供用户对数据库对象的访问权限来做出访问控制决策。我们将基于其自身安全模型做出访问控制决策的插件模块称为外部安全提供者。
此模块会在这些关键点获取控制权,然后它会要求 SELinux 检查是否允许所提供的访问权限。然后,它会返回其访问控制决策。如果违反,此模块会阻止此访问,例如通过引发错误。
一系列决策过程与默认的数据库权限机制独立进行。无论用户何时尝试访问某些内容,他们都必须同时获得两种访问控制模型的授权。
我们可以将 SELinux 看作一个函数,它接受两个参数,然后返回一个布尔值:允许或拒绝。在这个类比中,第一个参数是尝试引用特定对象的主题的标签。另一个是此操作中被引用的对象的标签。标签是一个格式化的字符串,例如system_u:object_r:sepgsql_table_t:s0
。它不是依赖于特定类型的对象特征的属性,因此我们可以将通用凭据应用于数据库对象或其他对象。
PostgreSQL 9.1 或更高版本支持 SECURITY LABEL 语句,该语句允许在指定的数据库对象上分配安全标签,如果用户希望更改创建默认标签。SELinux 还提供了一个接口来获取连接到该接口的对等进程的安全标签。
这些功能能够将 SELinux 模型集成到对数据库对象的访问控制中。因为它根据一个通用的集中式安全策略(一组规则)做出访问控制决策,因此其决策将始终一致,与存储信息资产的方式无关。
安装
- sepgsql 模块需要以下软件包才能安装。请先检查它。
- Linux 内核
- v2.6.28 或更高版本,使用 SELinux 启用构建
- libselinux
- v2.0.93 或更高版本
- 此库提供了一组与内核中的 SELinux 通信的 API。
- selinux-policy
- 时间戳晚于 20110117。
默认安全策略提供了一组访问控制规则。SE-PostgreSQL 需要平台上提供 SELinux。您可以使用以下命令检查当前设置.
$ sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 24 Policy from config file: targeted
sestatus
如果已禁用或未安装,您需要在安装 SE-PostgreSQL 之前设置 SELinux。--with-selinux在编译时,添加选项到configure
$ ./configure --enable-debug --enable-cassert --with-selinux $ make $ make install
脚本以检查 libselinux 的存在,并设置一个标志,指示我们是否构建此 contrib 模块。接下来到initdb,添加'$libdir/sepgsql'到 shared_preload_libraries 中的.
postgresql.confsepgsql,它允许在 postmaster 进程启动时加载
插件。然后,运行sepgsql.sql
脚本以针对每个数据库。它将安装与安全标签管理相对应的函数,并尝试在目标对象上分配初始标签。以下说明假设您的安装在/usr/local/pgsql目录下,并且数据库集群位于/usr/local/pgsql/data
$ initdb -D /usr/local/pgsql/data $ vi /usr/local/pgsql/data/postgresql.conf $ for DBNAME in template0 template1 postgres; do postgres --single -F -O -c exit_on_error=true \ -D /usr/local/pgsql/data $DBNAME \ < /usr/local/pgsql/share/contrib/sepgsql.sql > /dev/null done
。请根据需要替换您的路径。
如果所有安装过程都没有错误,请启动 postmaster 进程。SE-PostgreSQL 将根据 SELinux 的安全策略阻止违规访问。
回归测试
此模块的回归测试除了上述安装过程外,还需要在平台系统上进行一些额外的配置。请参见以下步骤。首先,安装回归测试的策略包。这sepgsql-regtest.pp是一个特殊用途的策略包,它提供了一组在回归测试用例期间允许的规则。它应该安装在/usr/local/pgsql/share/contrib
目录下,在默认设置中。您需要使用以下命令安装此策略包semodule命令,它允许您链接提供的策略包并将它们加载到内核空间。如果您能够正确安装它,semodule -l将打印sepgsql-regtest
$ su # semodule -u /usr/local/pgsql/share/contrib/sepgsql-regtest.pp # semodule -l : sepgsql-regtest 1.03 :
作为当前可用的策略包的一部分。其次,开启sepgsql_regression_test_mode首先,安装回归测试的策略包。这。为了系统安全,我们不会在默认情况下启用所有规则。SELinux 的参数与用于启动回归测试的规则相关联。可以使用以下命令开启它其次,开启setsebool命令。最后,从
$ su # setsebool sepgsql_regression_test_mode on # getsebool sepgsql_regression_test_mode sepgsql_regression_test_mode --> on
unconfined_t域启动回归测试。此测试策略旨在从大多数已知 SELinux 安装基础中的默认选择
域启动每个测试用例。因此,只要您之前没有更改 SELinux 的默认配置,您就不需要设置任何特殊内容。域启动回归测试。这
id命令告诉我们当前的工作域。请确认您的 shell 现在正在使用以下域执行。域启动回归测试。如果不是预期域,您应该还原此配置。这 #External_Resources 部分将为您提供一些有用的提示。
$ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
然后,您可以启动回归测试。如果我们在此处没有问题,所有测试都将通过。
如果
$ 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 ===================== All 2 tests passed. =====================
pg_regress无法启动psql命令,这里有一个额外的提示。当它尝试使用限制性权限启动命令时,命令,这里有一个额外的提示。当它尝试使用限制性权限启动必须被标记为命令,这里有一个额外的提示。当它尝试使用限制性权限启动bin_t。如果不是,请尝试以下神奇的咒语。GUC 参数
$ restorecon -R /usr/local/pgsql
sepgsql.permissive (布尔值)
此参数允许 SE-PostgreSQL 以允许模式运行,与系统设置无关。默认值为
off(根据系统设置)。此参数只能在文件中或服务器命令行上设置。到 shared_preload_libraries 中的除了
disabled之外,我们还有两种运行模式;一种是强制模式,它会在引用时检查安全策略,并真正阻止违规访问。另一种是允许模式,它只检查安全策略,但不会阻止任何操作,除非生成日志。此日志应用于调试安全策略本身。当此参数为
on时,SE-PostgreSQL 以允许模式运行,即使平台系统处于强制模式。我们建议用户保留默认设置,除非您自己开发安全策略。sepgsql.debug_audit (布尔值)
此参数允许打印审核消息,与策略设置无关。默认值为
off(根据系统设置)。此参数只能在(根据安全策略设置)。
SELinux 的安全策略还包含控制哪些访问应记录的规则。默认情况下,任何访问违规都会被记录,但任何允许的访问都不会被记录。
on时,SE-PostgreSQL 以允许模式运行,即使平台系统处于强制模式。我们建议用户保留默认设置,除非您自己开发安全策略。on
,所有可能的日志都将根据策略设置独立打印。我们建议在正常情况下将变量关闭,以避免出现噪声消息。
功能
受控对象类
此版本的 SE-PostgreSQL 支持在以下数据库对象类上分配安全标签:模式、表、列、序列、视图和过程。目前,不支持在其他数据库对象类上分配安全标签。
- 安全标签将在其创建时自动分配给支持的数据库对象。此标签称为默认安全标签。它根据安全策略或客户端和上级对象的安全性标签对(更准确地说)来决定。新的数据库对象基本上继承了上级对象的安全性标签。例如,新列继承了其父表的安全性标签。如果和当安全策略在客户端和上级对象对上拥有特殊规则(称为类型转换)时,我们可以分配一个单独的标签作为默认标签。上级对象取决于对象类的类型,如下所示。
- 模式
- 其上级对象是当前数据库。
- 表
- 其上级对象是拥有新表的模式对象。
- 列
- 其上级对象是拥有新列的表对象。
- 序列
- 其上级对象是拥有新序列的模式对象。
- 视图
- 其上级对象是拥有新视图的模式对象。
- 过程
其上级对象是拥有新过程的模式对象。
所有访问控制决策都应基于 SELinux 模型中被引用的对象的安全性标签,因此我们无法控制对没有
DML 权限本节介绍将在 DML 语句上检查哪些权限;, SELECT, INSERTUPDATE和.
DELETE对于表,它会检查, db_table:select, db_table:insertdb_table:update或db_table:delete对于表,它会检查,具体取决于语句类型;对于所有出现的目标表。此外,它还会检查db_column:select, 对于所有包含要在WHERE
UPDATE t1 SET t1.b = 'bbb' WHERE t1.a = 10;
RETURNING对于表,它会检查或其他语句中引用的列的表。db_table:insert在这种情况下,我们必须拥有db_table:select,而不仅仅是db_column:selectdb_table:update
,因为它引用了
t1.adb_sequence:get_value将在本节介绍将在 DML 语句上检查哪些权限;上进行检查。目前,其他 DML 不支持访问序列对象,因此我们在这里也不再检查。请注意,我们不会检查处理序列对象的函数执行时的任何内容,例如lastval(),因为缺少对象访问钩子。
对于视图,db_view:expand将在本节介绍将在 DML 语句上检查哪些权限;。请注意,它还会检查从视图扩展的表的个别权限。在这种情况下,必须允许两种权限。
对于列,它检查db_column:select不仅在被本节介绍将在 DML 语句上检查哪些权限;读取的列上,而且在被db_column:select子句或INSERT的数据源引用的列上。它还检查db_column:updateUPDATEdb_column:insert在被INSERTdb_table:updateSELECT.
UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
修改的列上。在这种情况下,它检查db_column:update在t1.x被更新,db_column:{select update}在t1.y被更新和引用,以及db_column:select在t1.z仅在db_column:selectdb_table:update
中被引用。与默认数据库权限不同,列级权限永远不会覆盖表级权限,因此我们必须在两个级别都被允许,即。
对于过程,我们对过程的执行没有任何访问控制。它的安全标签只有在我们尝试启动受信任过程时才有意义。
COPY TO/FROM从访问控制的角度来看,提供了与本节介绍将在 DML 语句上检查哪些权限;db_table:updateSELECT类似的功能。它根据相同的标准检查出现的表和列上的权限。
DDL 权限
在SECURITY LABEL命令上,我们检查setattrUPDATErelabelfrom在被重新标记的对象上(注意它仍然具有旧的安全标签),然后检查relabelto在提供的新的标签上。
在安装了多个标签提供程序并且用户尝试设置 SELinux 未管理的安全标签的情况下,我们应该只检查setattr,但由于钩子的限制,它不可用。
目前,SE-PostgreSQL 不控制任何其他 DDL 操作。
受信任的过程
它类似于操作系统上的安全定义器函数或 set-uid 命令。它可以在执行某些函数时切换客户端的特权;被调用为受信任过程。
在 SELinux 模型中,它是一个具有特殊安全标签的函数,被配置为受信任过程。
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 COLUMN customer.credit IS 'system_u:object_r:sepgsql_secret_table_t:s0'; SECURITY LABEL
postgres=# SELECT * FROM customer; ERROR: SELinux: security policy violation postgres=# SELECT cid, cname, show_credit(cid) FROM customer; cid | cname | show_credit -----+-------+--------------------- 10 | alice | 1111-2222-3333-4444 20 | bob | 5555-6666-7777-8888 (2 rows)
在这种情况下,我们不能触碰customer.credit列,但show_credit的受信任过程允许我们通过一些修改打印信用卡号。
限制
本节介绍了 SE-PostgreSQL 在本版本中的限制。
- 用户空间访问向量缓存
- SE-PostgreSQL 会告诉 SELinux 它的访问控制决策。系统调用调用很重,但是,我们可以使用缓存机制(在 SELinux 中称为访问向量缓存)来减少调用次数。
- 由于代码大小,SE-PostgreSQL 还不支持这种机制。
- DDL 权限
- 现在 PostgreSQL 在 DDL 例程上不提供一组钩子。
- 这意味着插件模块不能在这里获取控制权,因此 SE-PostgreSQL 目前不检查 DDL 权限。
- 行级访问控制
- 现在 SE-PostgreSQL 不支持行级访问控制,因为一些必需的功能尚未提供。其中一个是用户表上的安全标签。另一个是优化器的行为。有关更多详细信息,另请参阅 规则和权限。我们知道 VIEW 上存在类似问题。
- 隐蔽信道
- 即使用户没有被允许引用,SE-PostgreSQL 也不会尝试隐藏特定对象的生存。例如,即使我们不能引用这些对象的内容,我们也可以使用主键冲突、外键冲突等推断不可见对象的生存。
外部资源
- SE-PostgreSQL 简介
- 此 wiki 页面提供了有关更多详细信息的简要概述、安全设计、体系结构、
- 管理和未来计划。
- Fedora SELinux 用户指南
- 本文档提供广泛的知识,用于在您的系统上管理 SELinux。
- 它主要关注 Fedora,但这些技术并不局限于 Fedora。
- Fedora SELinux 常见问题解答
- 本文档提供有关 SELinux 的常见问题解答。它主要关注 Fedora,但并不局限于 Fedora。