SEPostgreSQL 管理
本章介绍了管理 SELinux 和 SE-PostgreSQL 的一些提示。
- 章节列表
安装和设置
本部分介绍在你的系统上安装和设置 SE-PostgreSQL 的两种方法。一种是 rpm 安装,另一种是从源码包构建。
- 启用了 SELinux 的 Linux 内核(2.6.24 或更高版本)
- selinux-policy 3.4.2 或更高版本
- policycoreutils 2.0.16 或更高版本
- libselinux 2.0.80 或更高版本
- checkpolicy(仅从包安装)
- libselinux-devel 2.0.80 或更高版本(仅从包安装)
从 RPM 包安装
现在通过 Fedora 项目分发 SE-PostgreSQL 包。sepostgresql包在 Fedora 8 或更高版本发布中提供。
如果你已在系统上设置了较新的 Fedora 版本,则 SE-PostgreSQL 的安装非常简单,如下所示
[root@saba ~]# yum install sepostgresql Loaded plugins: refresh-packagekit Setting up Install Process Parsing package install arguments Resolving Dependencies --> Running transaction check ---> Package sepostgresql.i386 0:8.3.4-2.1077.fc10 set to be updated --> Processing Dependency: postgresql-server = 8.3.4 for package: sepostgresql --> Running transaction check ---> Package postgresql-server.i386 0:8.3.4-1.fc10 set to be updated --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: sepostgresql i386 8.3.4-2.1077.fc10 rawhide 2.0 M Installing for dependencies: postgresql-server i386 8.3.4-1.fc10 rawhide 4.6 M Transaction Summary ================================================================================ Install 2 Package(s) Update 0 Package(s) Remove 0 Package(s) Total download size: 6.6 M Is this ok [y/N]: y Downloading Packages: (1/2): sepostgresql-8.3.4-2.1077.fc10.i386.rpm | 2.0 MB 00:00 (2/2): postgresql-server-8.3.4-1.fc10.i386.rpm | 4.6 MB 00:01 ------------------------------------------------------------------------------------------ Total 1.3 MB/s | 6.6 MB 00:04 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing : postgresql-server [1/2] Installing : sepostgresql [2/2] Installed: sepostgresql.i386 0:8.3.4-2.1077.fc10 Dependency Installed: postgresql-server.i386 0:8.3.4-1.fc10 Complete!
如果不使用yum,你可以从 Fedora 镜像获取包
rpm 安装脚本标记已安装的文件以及链接的安全上下文的适当安全策略模块,因此我们不需要做更多的事情。
接下来,您必须初始化数据库集群。默认情况下,SE-PostgreSQL 在部署其数据库集群/var/lib/sepgsql,但它可通过位于以下位置的配置加以替换/etc/sysconfig/sepostgresql.
.../etc/init.d/sepostgresql带以下内容的脚本initdb初始化数据库集群,因此在启动服务器进程之前必须完成此任务。
[root@saba ~]# service sepostgresql initdb Initializing database: [ OK ]
然后,它将准备好启动服务器进程。
[root@localhost ~]# service sepostgresql start Starting sepostgresql service: [ OK ]
初始数据库使用sepgsql数据库角色进行设置,在需要时添加一些额外的角色。
[root@localhost ~]# su - sepgsql -bash-3.2$ createuser foo Shall the new role be a superuser? (y/n) :
从源代码 tarball 中进行安装
当我们从源代码 tarball 中构建和安装 SE-PostgreSQL 时,它比 RPM 安装需要多一些步骤以便与 SELinux 正常配合使用,不过其中大多数步骤对于使用 SELinux 运行 PostgreSQL 来说也是必需的。
获取源代码
首先,从以下位置下载 PostgreSQL 源代码 tarball 和 SE-PostgreSQL 补丁:
- PostgreSQL 公共镜像
- SE-PostgreSQL 补丁
然后,将其解压缩并应用补丁。
$ wget ftp://ftp.postgresql.org/pub/source/v8.4beta2/postgresql-8.4beta2.tar.bz2 $ wget http://sepgsql.googlecode.com/files/sepgsql-00-full-8.4beta2-r1911.patch.gz $ tar jxf postgresql-8.4beta2.tar.bz2 $ cd postgresql-8.4beta2 $ gunzip -c ../sepgsql-00-full-8.4beta2-r1911.patch.gz | patch -p1
常规步骤
在配置脚本中,您必须向配置脚本提供--enable-selinux选项以使用 SE-PostgreSQL 功能对其进行构建。
$ ./configure --enable-selinux $ make $ make -C src/backend/security/sepgsql/policy
...sepostgresql-devel.pp策略模块的源代码存储在src/backend/security/sepgsql/policy中,因此我们需要在独立于目录的情况下运行make该策略模块提供布尔值以启用/禁用 审核消息并正确地运行回归测试。如果您无法正确地构建它们,请向作者报告此问题。
...make install应作为root进行运行。...sepostgresql-devel.pp策略模块可以使用semodule命令进行安装。
$ su # make install # /usr/sbin/semodule -i src/backend/security/sepgsql/policy/sepostgresql-devel.pp
在此备忘录中,我们假设数据库集群部署在/opt/sepgsql并且属于sepgsql.
# mkdir -p /opt/sepgsql # chown sepgsql:users -R /opt/sepgsql
postgres
重新标记默认情况下,配置脚本使用/usr/local/pgsql作为安装的顶级目录。它基本上有system_u:object_r:usr_t:s0
安全上下文,因此所有已安装的文件都继承它,但是不正确。接下来,我们需要为每个已安装的文件指定适当的安全上下文。/sbin/restoreconsepostgresql-devel.pp是一个用于将安全上下文重置为安全策略中的默认配置的命令。包含一组特定路径与其正确的安全上下文的对。准许设置在正则表达式中显示的某些路径的默认安全上下文。我们必须为数据库集群提供默认路径,因为策略模块无法在构建时了解哪一条路径更合适。
# /sbin/restorecon -R /usr/local/pgsql # semanage fcontext -a -t postgresql_db_t '/opt/sepgsql(.*/)?' # /sbin/restorecon -R /opt/sepgsql
如果不带设置,sepostgresql-devel.pp请确认以下几对某些路径和一个安全上下文。(假设默认情况下,配置脚本使用作为前缀,并/opt/sepgsql作为数据库集群。)
- /usr/local/pgsql/bin/postgres应标记为postgresql_exec_t
- /usr/local/pgsql/bin/initdb应标记为postgresql_exec_t
- /usr/local/pgsql/bin/pg_ctl应标记为initrc_exec_t
- 其余的/usr/local/pgsql/bin/*应标记为bin_t
- /usr/local/pgsql/lib/*应标记为lib_t
- 其余的/ust/local/pgsql/*应标记为usr_t
- 数据库集群中的文件应标记为postgresql_db_t
# semanage fcontext -a -t usr_t '/usr/local/pgsql(.*/)?' # semanage fcontext -a -t bin_t '/usr/local/pgsql/bin(.*/)?' # semanage fcontext -a -t lib_t '/usr/local/pgsql/lib(.*/)?' # semanage fcontext -a -t postgresql_exec_t '/usr/local/pgsql/bin/postgres' # semanage fcontext -a -t postgresql_exec_t '/usr/local/pgsql/bin/initdb' # semanage fcontext -a -t initrc_exec_t '/usr/local/pgsql/bin/pg_ctl' # /sbin/restorecon -R /usr/local/pgsql # semanage fcontext -a -t postgresql_db_t '/opt/sepgsql(.*/)?' # /sbin/restorecon -R /opt/sepgsql
运行 initdb
最后,运行initdb使用--enable-selinux使用 SE-PostgreSQL 初始化数据库集群。
$ export PGDATA=/opt/sepgsql $ /usr/local/pgsql/bin/initdb --enable-selinux The files belonging to this database system will be owned by user "sepgsql". This user must also own the server process. The database cluster will be initialized with locale en_US.UTF-8. The default database encoding has accordingly been set to UTF8. The default text search configuration will be set to "english". fixing permissions on existing directory /opt/sepgsql ... ok creating subdirectories ... ok selecting default max_connections ... 100 selecting default shared_buffers ... 32MB creating configuration files ... ok creating template1 database in /opt/sepgsql/base/1 ... ok initializing pg_authid ... ok initializing dependencies ... ok creating system views ... ok loading system objects' descriptions ... ok creating conversions ... ok creating dictionaries ... ok setting privileges on built-in objects ... ok creating information schema ... ok vacuuming database template1 ... ok copying template1 to template0 ... ok copying template1 to postgres ... ok WARNING: enabling "trust" authentication for local connections You can change this by editing pg_hba.conf or using the -A option the next time you run initdb. Success. You can now start the database server using: /usr/local/pgsql/bin/postgres -D /opt/sepgsql or /usr/local/pgsql/bin/pg_ctl -D /opt/sepgsql -l logfile start
然后,调用/usr/local/pgsql/bin/pg_ctl,而不是直接调用/usr/local/pgsql/bin/postgres,因为默认安全策略不允许用户域翻译到服务器域。
$ touch /opt/sepgsql/sepostgresql.log $ chcon -t postgresql_log_t /opt/sepgsql/sepostgresql.log $ pg_ctl -l /opt/sepgsql/sepostgresql.log start
如果您收集服务器日志,则日志文件必须标记为postgresql_log_t.
GUC选项
现在,SE-PostgreSQL有两个选项来打开/关闭其功能。
- sepostgresql = [on | off]
- 此选项只能在服务器启动时设置。
- 这意味着当选项为on并且操作系统启用了 SELinux 时,SE-PostgreSQL 可用。
- 否则,SE-PostgreSQL 即使使用--enable-selinux.
- 构建二进制文件,将仍然处于禁用状态。--enable-selinux默认值取决于initdb.
- 中的
- sepostgresql_row_level = [on | off](默认 = on)
- 此选项只能在服务器启动时设置。它允许打开/关闭db_tuple
- 对象类的访问控制。它允许打开/关闭的数量
- 类对象往往会变大,所以如果您想稍微减少存储消耗,则可以选择关闭此选项,而不是权衡安全性。
- sepostgresql_mcstrans = [on | off](默认 = on)
- 此选项可随时设置。
它允许打开/关闭在打印安全上下文时对 mcstrans 的支持。
标记网络正如我们之前提到的,SE-PostgreSQL 在对访问控制做出决策时,将对等进程的安全上下文应用为客户端权限。libselinux提供getpeercon()
标记网络是对 IPsec 的增强型。当我们打开 IPsec 通信通道上的连接时,增强型密钥交换守护程序 (racoon) 会向对等发送一个加密密钥和流程的安全上下文。对等方上的内核存储该信息,并通过以下方式将其返回给应用程序:提供此外,SELinux 还提供一种方式在标记 IPsec 不可用的情况下分配一个备用安全上下文。该方式称为静态回退上下文。
标记 IPsec
此部分介绍了在两个主机之间设置标记 IPsec 的方式,这是最简单的情况。
要求
标记网络需要以下软件包。
- 启用了标记网络的 Linux Kernel
- ipsec-tools-0.6.5-6 或更高版本
内核配置选项CONFIG_SECURITY_NETWORK必须启用。在 Red Hat Enterprise Linux 5、Fedora 7 或更高版本中,最新的内核软件包上启用了此选项。
Red Hat 提供了一份很好的文档,请参阅以下文档了解更多信息。
- 假设
在以下示例中,SE-PostgreSQL 服务器进程正在192.168.11.6上运行,数据库客户端进程正在192.168.11.8上运行。它们可以在没有任何代理、路由器等情况下互相通信。
添加到 SPD(安全策略数据库)的条目
首先,我们必须告知之间的通信192.168.11.6和192.168.11.8应该通过 IPsec 隧道传输。以下示例需要从192.168.11.8到192.168.11.6的出站数据包以及其反向数据包通过 ESP 模式进行 IPsec 加密,并且两个 SPD 条目具有system_u:object_r:ipsec_spd_t:s0作为其安全上下文。
在服务器和客户端创建文件来描述以下配置。请注意,在客户端,列举的 IP 地址已反向排列。
服务器端(192.168.11.6):
spdadd 192.168.11.6 192.168.11.8 any -ctx 1 1 "system_u:object_r:ipsec_spd_t:s0" -P out ipsec esp/transport//require; spdadd 192.168.11.8 192.168.11.6 any -ctx 1 1 "system_u:object_r:ipsec_spd_t:s0" -P in ipsec esp/transport//require;
...setkey命令允许加载以下配置
# setkey -f <SPD configuration file>
编辑 /etc/racoon/racoon.conf
接着,编辑/etc/racoon/racoon.conf以添加用于在之间进行通信的配置块192.168.11.6和192.168.11.6。在此示例中,我们使用预共享密钥方法对远程主机进行身份验证,以便简化说明。请注意,在客户端,列举的 IP 地址已反向排列。
服务器端(192.168.11.6):
# Racoon IKE daemon configuration file. # See 'man racoon.conf' for a description of the format and entries. path include "/etc/racoon"; path pre_shared_key "/etc/racoon/psk.txt"; path certificate "/etc/racoon/certs"; path script "/etc/racoon/scripts"; sainfo anonymous { #pfs_group 2; lifetime time 1 hour ; encryption_algorithm 3des, blowfish 448, rijndael ; authentication_algorithm hmac_sha1, hmac_md5 ; compression_algorithm deflate ; } remote 192.168.11.8 { exchange_mode aggressive, main; my_identifier address; proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method pre_shared_key; dh_group 2 ; } }
编辑 /etc/racoon/psk.txt
接着,我们添加一个预共享密钥的条目。服务器和客户端端必须使用相同的密钥短语。
服务器端(192.168.11.6):
# file for pre-shared keys used for IKE authentication # format is: 'identifier' 'key' # For example: # # 10.1.1.1 flibbertigibbet # www.example.com 12345 # [email protected] micropachycephalosaurus 192.168.11.8 somethingsecrettext
启动 racoon
在两端启动 racoon 守护程序。
# service racoon start Starting racoon: [ OK ]
如果配置正确,那么对等进程的安全环境将传递给服务器进程,并且 SE-PostgreSQL 会将其用作客户端权限。我们可以使用 sepgsql_getcon()函数对其进行确认。
静态回退标签
标记网络可以通过传递对等进程的安全环境,我们建议尽可能使用此功能。但是,它还有限制,即必须在客户端启用 SELinux,因此不能在任何其他操作系统上运行客户端进程。从根本上讲,它们不为进程指定安全属性。
SELinux 提供了一种为客户端指定安全环境的替代方法,称为静态回退标签。它将连接与基于源 IP 地址和入站网络设备的备用安全环境关联,而标记网络不可用时也是如此。
这需要下列数据包
- Linux 内核 v2.6.25 或更高版本
- netlabel_tools v0.18 或更高版本
在这个示例中,我们打算指定备用安全环境staff_u:staff_r:staff_t:s0:c1用于来自下列情况的连接192.168.12.0/24经由eth0, staff_u:staff_r:staff_t:s0:c2用于来自下列情况的连接192.168.20.0/24经由eth1,而user_u:user_r:user_t:s0用于其他情况。
...netlabelctl使用unlbl子命令可以设置我们打算执行的配置。我们可以用 net-mask 和网络接口为网络地址提供备用安全环境。如果不关心入站网络设备,default应该放在此处。
# netlabelctl unlbl add interface:eth0 address:192.168.12.0/24 ¥ label:staff_u:staff_r:staff_t:s0:c1 # netlabelctl unlbl add interface:eth1 address:192.168.20.0/24 ¥ label:staff_u:staff_r:staff_t:s0:c2 # netlabelctl unlbl add default address:0.0.0.0/0 ¥ label:user_u:user_r:user_t:s0
备份和恢复
PostgreSQL 提供官方备份实用工具,pg_dump和pg_dumpall。它们最新版本具有--security-label选项,用于备份具有安全环境的数据库。我们可以通过pg_restore命令恢复它们,而无需任何特定选项。
不必说,备份和恢复过程对访问控制来说并不是例外。数据库管理员应具有足够的权限来引用和恢复这些权限。如果不是这样,则会中止备份或过滤掉违规元组。
示例输出
$ pg_dump --security-label postgres : : -- -- Name: customer; Type: TABLE; Schema: public; Owner: kaigai; Tablespace: -- CREATE TABLE customer ( cid integer NOT NULL, cname character varying(32), credit character varying(32) SECURITY_LABEL = 'system_u:object_r:sepgsql_secret_table_t:s0' ) SECURITY_LABEL = 'unconfined_u:object_r:sepgsql_table_t:s0'; ALTER TABLE public.customer OWNER TO kaigai; : : -- -- Data for Name: customer; Type: TABLE DATA; Schema: public; Owner: kaigai -- COPY customer (security_label, cid, cname, credit) FROM stdin; unconfined_u:object_r:sepgsql_table_t:s0 10 jack 1111-2222-3333-4444 unconfined_u:object_r:sepgsql_table_t:s0 13 adam 5555-6666-7777-8888 unconfined_u:object_r:sepgsql_table_t:s0 14 liza 9876-5432-1098-7654 \. :
回收孤立标签
安全环境的文本表示由pg_security系统目录(或pg_shsecurity用于共享数据库对象)。
安全环境有一个特点,即在大多数情况下许多对象共用有限数量的安全环境。由于性能原因,我们不在pg_security上使用引用计数器,因此如果有必要忽略孤立项增加,则稍后回收孤立安全环境。
SE-PostgreSQL 提供了一个称为security_reclaim_label的函数,用于回收孤立安全环境。当我们没有任何参数调用此函数时,它会尝试回收当前数据库中的所有孤立项。否则,它可能接受一个参数以缩小由某个表引用的项的范围。
只有数据库超级用户可以执行此函数。
postgres=# select security_reclaim_label('t1'); NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0", secid=16402 on public.t1 was reclaimed NOTICE: secattr="system_u:object_r:sepgsql_ro_table_t:s0", secid=16403 on public.t1 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c1", secid=16404 on public.t1 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c2", secid=16405 on public.t1 was reclaimed NOTICE: secattr="system_u:object_r:sepgsql_ro_table_t:s0:c3", secid=16406 on public.t1 was reclaimed NOTICE: secattr="system_u:object_r:sepgsql_ro_table_t:s0:c4", secid=16407 on public.t1 was reclaimed security_reclaim_label ------------------------ 6 (1 row)
此示例显示了public.t1.
postgres=# select security_reclaim_label(); NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0", secid=16412 on public.t2 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c1", secid=16414 on public.t2 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c2", secid=16415 on public.t2 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0", secid=16413 on public.t3 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c1", secid=16416 on public.t3 was reclaimed NOTICE: secattr="unconfined_u:object_r:sepgsql_table_t:s0:c2", secid=16417 on public.t3 was reclaimed security_reclaim_label ------------------------ 6 (1 row)
如果我们未在函数上指定任何特定表,则将回收所有孤立条目。但此选项的锁定粒度较低,并且可能会在回收过程中阻塞其他事务。
回收操作的理想频率取决于环境,但我们希望每两月回收一次足以维护安全标签。