EnterpriseDB的SQL流入攻击保护功能二

EnterpriseDB的SQL注入攻击保护功能二


3
通常维护操作

下面描述这样执行其他通用操作。
必须以超级用户连接到数据库并在查询路径中包含模式sqlprotect以执行这些操作。

3.1
给受保护角色列表增加角色,运行protect_role('rolename')函数。

edb=# SELECT protect_role('newuser');
protect_role
--------------
(1 row)

3.2
从受保护角色列表删除角色,运行unprotect_role('rolename')或unprotect_role(roleoid)函数。
注意:
如果在从受保护角色列表删除角色以前,用drop role或者drop user删除了这个角色,
用unprotect_role(roleoid)删除是有用的。如果在受保护的关系上查询,给这个用户
返回像unknown(OID=16458)这样的值,使用unprotect_role(roleoid)会ok。

用unprotect_role(roleoid)这个函数删除角色,也删除了这个角色的保护关系列表。
已删除角色的统计信息用drop_stats函数删除。

从受保护角色列表删除角色
edb=# SELECT unprotect_role('newuser');
unprotect_role
----------------
(1 row)

这个角色也可以根据其OID删除
edb=# SELECT unprotect_role(16693);
unprotect_role
----------------
(1 row)

3.3
为角色设置保护类型

可以改变要保护的角色的 免受SQL注入攻击的类型。
改变edb_sql_protect里相应SQL注入攻击类型列的boolean值。
保证在更新edb_sql_protect表的sql语句的where子句里有dbid, roleid。

例子
允许角色执行utility命令,如下更新列allow_utiltiy_cmds:
UPDATE edb_sql_protect SET allow_utility_cmds = TRUE WHERE dbid = 13917 AND roleid = 16671;

提供查询edb_sql_protect或list_protected_users验证
edb=# SELECT dbid, roleid, allow_utility_cmds FROM edb_sql_protect;
dbid | roleid | allow_utility_cmds
-------+--------+--------------------
13917 | 16671 | t
(1 row)
这个更新的规则在该用户新的会话上起作用。

edb=>  create table appuser_tab_3(f1 INTEGER);
CREATE TABLE

3.4
从受保护关系列表中删除关系
可以删除SQL/Protect在学习模式加入到受保护关系列表中的关系。
用下面的函数可以从edb_sql_protect_rel删除受保护关系列表中的关系。
unprotect_rel('rolename', 'relname')
unprotect_rel('rolename', 'schema', 'relname')
unprotect_rel(roleoid, reloid)
如果给定的关系步骤当前搜索路径下,用第二个函数指明该关系所在模式。

edb=# select * from list_protected_rels;

下面的例子演示了从appuser的受保护关系列表中删除public.emp关系
edb=# SELECT unprotect_rel('appuser', 'public', 'emp');
unprotect_rel
---------------
(1 row)

验证:
edb=# SELECT * FROM list_protected_rels;
Database | Protected User | Schema | Name | Type | Owner
----------+----------------+--------+-------------+-------+--------------
edb | appuser | public | dept | Table | enterprisedb
edb | appuser | public | appuser_tab | Table | appuser
(2 rows)
SQL/Protect现在会给一个warning或阻止这个用户对这个关系的访问
SQL/Protect现在会给一个warning或阻止appuser对public.emp的访问

3.5
删除统计信息

可以用下面的函数从视图edb_sql_protect_stats中删除统计信息:
drop_stats('rolename')
drop_stats(roleoid)
注意:
如果在用drop_stats('rolename')删除角色统计信息以前,用droprole或者drop user删除了这个角色,
用drop_stats(roleoid) 删除是有用的。如果在edb_sql_protect_stats上查询,
返回像unknown(OID=16458)这样的值,使用drop_stats(roleoid)会ok。

下面是删除统计信息的例子:
edb=# SELECT drop_stats('appuser');
drop_stats
------------
(1 row)
edb=# SELECT * FROM edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
(0 rows)

下面是在用drop_stats('rolename')删除角色统计信息以前,用droprole或者drop user删除了这个角色
的例子:
edb=# SELECT * FROM edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
---------------------+------------+-----------+----------+-----------+-----
unknown (OID=16693) | 0 | 5 | 3 | 1 | 0
appuser | 0 | 5 | 2 | 1 | 0
(2 rows)
edb=# SELECT drop_stats(16693);
drop_stats
------------
(1 row)
edb=# SELECT * FROM edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 5 | 2 | 1 | 0
(1 row)

3.6
使能或使不能监控

如果希望停止SQL/Protect监控,如下步骤操作:

步骤1:
在postgresql.conf文件中设置edb_sql_protect.enabled为off。
edb_sql_protect.enabled = off

步骤2:
加载postgresql.conf文件
以超级用户连接到数据库,执行下面的函数pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

如果希望重启SQL/Protect监控,如下步骤操作:
步骤1:
在postgresql.conf文件中设置edb_sql_protect.enabled为on。
edb_sql_protect.enabled = on

步骤2:
加载postgresql.conf文件
以超级用户连接到数据库,执行下面的函数pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

4
备份/恢复有sql注入保护的数据库

备份/恢复有sql注入保护的数据库,需要考虑额外的问题,主要是因为其相关表里涉及到OID。
注意:
当用Pg_dump备份,恢复时数据库对象会产生新的OID,本节论坛这个问题。
如果是通过操作系统的copy命令备份的ppas的数据集二进制文件这节就不用看了。

4.1
SQL/Protect相关表里的OID

SQL/Protect用两个表edb_sql_protect和edb_sql_protect_rel保存诸如database、role、relation
等数据库对象。使用这些对象的OID引用这些对象,而不是这些对象的名字。OID是唯一
标识数据库对象的数字数据类型。

当用Pg_dump备份,恢复数据库对象后会产生新的OID,如此的话,表edb_sql_protect和edb_sql_protect_rel
里OID会失效。

有两个函数: export_sqlprotect和import_sqlprotect,用来保证启用SQL/Protect的
数据库中备份恢复后SQL/Protect相关表里的OID引用到恢复后对应的数据库对象上。

4.2
备份启用SQL/Protect的数据库

步骤1:
使用pg_dump备份一个文件

例子:文本备份文件:
$ cd /opt/PostgresPlus/9.1AS/bin
$ ./pg_dump -U enterprisedb -Fp -f /tmp/edb.dmp edb
Password:
$
步骤2:
以超级用户连接到数据库,并用export_sqlprotect('sqlprotect_file')函数转储。
其中sqlprotect_file是可以存放SQL/Protect数据的地方。
enterprisedb OS用户能读写sqlprotect_file指定的文件。

edb=# SELECT sqlprotect.export_sqlprotect('/tmp/sqlprotect.dmp');
export_sqlprotect
-------------------
(1 row)

文件/tmp/edb.dmp和/tmp/sqlprotect.dmp组成了完整的数据库备份文件。

4.3
从备份文件恢复:

步骤1:
给新数据库恢复。
$ /opt/PostgresPlus/9.1AS/bin/psql -d newdb -U enterprisedb -f /tmp/edb.dmp
Password for user enterprisedb:
SET
SET
SET
SET
SET
COMMENT
CREATE SCHEMA
.
.

步骤2:
以超级用户连到新数据库并删除edb_sql_protect_rel表里的行,这些行包含了不正确的OID。

$ /opt/PostgresPlus/9.1AS/bin/psql -d newdb -U enterprisedb
Password for user enterprisedb:
psql (9.1.1.0)
Type "help" for help.
newdb=# DELETE FROM sqlprotect.edb_sql_protect_rel;
DELETE 2

步骤3:
以超级用户连到新数据库并删除edb_sql_protect表里的行,这些行包含了不正确的OID。

newdb=# DELETE FROM sqlprotect.edb_sql_protect;
DELETE 1

步骤4:
删除任何新数据库里SQL/Protect相关的统计信息

查询相关统计信息:
newdb=# SELECT * FROM sqlprotect.edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
(0 rows)

对于查询中的每一行信息,用drop_stats函数,参数是这行记录的角色的名字
例如有一行的username列是appuser,用下面的方法删除这条记录:
newdb=# SELECT sqlprotect.drop_stats('appuser');
drop_stats
------------
(1 row)

步骤5:
确保在新数据库中有原数据库中受保护角色的同名角色。
如果原db和新db在同一个dbms,什么都不用做。

步骤5:
运行函数import_sqlprotect('sqlprootect_file'),其中sqlprotect_file是什么备份文件的全路径名。
newdb=# SELECT sqlprotect.import_sqlprotect('/tmp/sqlprotect.dmp');
import_sqlprotect
-------------------
(1 row)
表edb_sql_protect和edb_sql_protect_rel里面的记录都有了新DB中对应的OID了。统计
视图edb_sql_protect_stats里也显示了从原DB导入的信息。

可以在PPAS的系统表上验证如下:
newdb=# SELECT datname, oid FROM pg_database;
datname | oid
-----------+-------
template1 | 1
template0 | 13909
edb | 13917
newdb | 16679
(4 rows)
newdb=# SELECT rolname, oid FROM pg_roles;
rolname | oid
--------------+-------
enterprisedb | 10
appuser | 16671
newuser | 16678
(3 rows)
newdb=# SELECT relname, oid FROM pg_class WHERE relname IN ('dept','emp','appuser_tab');
relname | oid
-------------+-------
appuser_tab | 16803
dept | 16809
emp | 16812
(3 rows)
newdb=# SELECT * FROM sqlprotect.edb_sql_protect;
dbid | roleid | protect_relations | allow_utility_cmds | allow_tautology | allow_empty_dml
-------+--------+-------------------+--------------------+-----------------+-----------------
16679 | 16671 | t | t | f | f
(1 row)
newdb=# SELECT * FROM sqlprotect.edb_sql_protect_rel;
dbid | roleid | relid
-------+--------+-------
16679 | 16671 | 16809
16679 | 16671 | 16803
(2 rows)
newdb=# SELECT * FROM sqlprotect.edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 5 | 2 | 1 | 0
(1 row)
注意edb_sql_protect和edb_sql_protect_rel里的列dbid和roleid与newdb里系统表
pg_database里的oid一致,roleid列与pg_roles里的appuser的oid列一致。
还有,表edb_sql_protect_rel里,relid列的值和pg_class里关系dept和appuser_tab的relid值一致。

步骤7:
验证在新DBMS上postgresql.conf文件里SQL/Protect的配置参数与前面2,2.1,2.2节里描述的一致,
任何重启数据库服务器或重新加载配置文件。