ud_mac

1. 简介


ud_mac 是 unvdb 数据库与 Linux SELinux 安全安全模块深度集成的扩展,通过强制访问控制(MAC)机制为数据库对象(如表、行、列等)提供细粒度的安全策略管理。


2. 配置说明


运行以下命令确认 SELinux 已启用并处于强制模式:

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

确认 ud_mac 模块已加载:

unvdb=# SELECT name, setting FROM pg_settings WHERE name = 'shared_preload_libraries';
           name           | setting
--------------------------+---------
 shared_preload_libraries | ud_mac
(1 row)

3. 使用说明

3. 1 修改安全上下文

# 1.获取当前上下文
unvdb=# SELECT ud_mac_getcon();
                     ud_mac_getcon
-------------------------------------------------------
 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
(1 row)


# 2.尝试修改进程SELinux上下文--返回 t 成功
unvdb=# SELECT ud_mac_setcon('unconfined_u:unconfined_r:sepgsql_regtest_dba_t:s0');
 ud_mac_setcon
----------------
 t
(1 row)

# 3. 查看修改之后的上下文,类型已经变成了 sepgsql_regtest_dba_t
unvdb=# SELECT ud_mac_getcon();
                   ud_mac_getcon
----------------------------------------------------
 unconfined_u:unconfined_r:sepgsql_regtest_dba_t:s0
(1 row)

# 4. 退出输出库重新进入即可恢复原来的上下文
unvdb=# \q
[unvdb@localhost UDB-TX_prd]$ ud_sql
ud_sql (UDB-TX V2.4(build:24.2.13.1 a7fbe8782c))
Type "help" for help.

unvdb=# SELECT ud_mac_getcon();
                    ud_mac_getcon
-------------------------------------------------------
 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
(1 row)

3.2 设置初始安全标签

# 1. 新建测试表 rest ,并插入数据
unvdb=# CREATE TABLE rest (id serial PRIMARY KEY, content text);
CREATE TABLE
unvdb=# INSERT INTO rest (content) VALUES ('数据1'), ('数据2'), ('SELinux测试');
INSERT 0 3

# 2. 查看表 rest 的默认安全标签为 sepgsql_table_t
unvdb=# SELECT objname, label FROM pg_seclabels WHERE objname = 'rest';
 objname |                  label
---------+------------------------------------------
 rest    | unconfined_u:object_r:sepgsql_table_t:s0
(1 row)

# 3. 修改表 rest 的安全标签,将类型改为 sepgsql_regtest_foo_table_t
unvdb=# SECURITY LABEL ON TABLE rest IS 'unconfined_u:object_r:sepgsql_regtest_foo_table_t:s0';
SECURITY LABEL
unvdb=# SELECT objname, label FROM pg_seclabels WHERE objname = 'rest';
 objname |                        label
---------+------------------------------------------------------
 rest    | unconfined_u:object_r:sepgsql_regtest_foo_table_t:s0
(1 row)

# 4. 调用 ud_mac_restorecon(NULL) 来重置数据库所有对象的初始标签,返回 t 表示成功
unvdb=# SELECT ud_mac_restorecon(NULL);
 ud_mac_restorecon
--------------------
 t
(1 row)

# 5. 重新查看表 rest 的安全标签,已经变回 sepgsql_table_t
unvdb=# SELECT objname, label FROM pg_seclabels WHERE objname = 'rest';
 objname |                label
---------+--------------------------------------
 rest    | system_u:object_r:sepgsql_table_t:s0
(1 row)

3.3 使用SELinux的安全上下文标签来控制数据库访问权限

1)创建一个名为 test1 的测试表

unvdb=# CREATE TABLE test1 (id serial PRIMARY KEY, content text);
CREATE TABLE

2)为表 test1 设置SELinux 安全上下文标签

  • 用户: unconfined_u (不受限制的用户)

  • 角色: object_r (对象角色)

  • 类型: sepgsql_regtest_foo_table_t (特定测试表类型)

  • 敏感度: s0 (最低敏感级别)

unvdb=# SECURITY LABEL ON TABLE test1 IS 'unconfined_u:object_r:sepgsql_regtest_foo_table_t:s0';
SECURITY LABEL

# 查看已设置的安全标签
unvdb=# SELECT objname, label FROM pg_seclabels WHERE objname = 'test1';
 objname |                        label
---------+------------------------------------------------------
 test1   | unconfined_u:object_r:sepgsql_regtest_foo_table_t:s0
(1 row)

3)插入和查询数据

调用ud_mac_getcon()函数来查看当前的安全上下文,显示是unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023,表示这是一个不受限制的上下文。所以可以正常查看表格数据。

unvdb=# INSERT INTO test1 (content) VALUES ('正常数据'), ('测试数据'), ('SELinux测试');
INSERT 0 3
unvdb=# SELECT ud_mac_getcon();
                    ud_mac_getcon
-------------------------------------------------------
 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
(1 row)

unvdb=# SELECT * FROM test1;
 id |   content
----+-------------
  1 | 正常数据
  2 | 测试数据
  3 | SELinux测试
(3 rows)

4)更改安全上下文

使用ud_mac_setcon()函数将当前上下文的类型改为sepgsql_regtest_user_t,因为当前策略不允许sepgsql_regtest_user_t类型的进程访问sepgsql_regtest_foo_table_t类型的表,所以查询操作或被 SELinux 策略拒绝。

unvdb=# SELECT ud_mac_setcon('unconfined_u:unconfined_r:sepgsql_regtest_user_t:s0');
 ud_mac_setcon
----------------
 t
(1 row)

unvdb=# SELECT ud_mac_getcon();
                   ud_mac_getcon
-----------------------------------------------------
 unconfined_u:unconfined_r:sepgsql_regtest_user_t:s0
(1 row)

unvdb=# SELECT * FROM test1;
ERROR:  SELinux: security policy violation