数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

Oracle11gR1中细粒度访问网络服务


发布日期:2023年09月20日
 
Oracle11gR1中细粒度访问网络服务

Oracle允许使用几个PL/SQL API(UTL_TCP UTL_SMTP UTL_MAIL UTL_HTTP和 UTL_INADDR)访问外部网络服务这些API都使用TCP协议在上一个数据库版本中(g)是通过一个基于用户是否被授予执行某个包的许可的on/off开关来实现的Oracle g引入了细粒度访问网络服务

通过在XML DB 数据库中使用访问控制列表(ACL)来实现允许控制哪个用户能够访问哪个网络资源而不关心包的授权

使用FTP或WebDav可以直接在XML DB 数据库中创建修改和删除访问控制列表Oracle提供了DBMS_NETWORK_ACL_ADMIN和DBMS_NETWORK_ACL_UTILITY程序包允许从PL/SQL管理访问控制列表这些API就是本文的主角

创建一个访问控制列表(ACL)

访问控制列表是使用DBMS_NETWORK_ACL_ADMIN程序包来操作的CREATE_ACL存储过程使用下面的参数来创建一个新的访问控制列表

? acl 访问控制列表XML文件的名字产生在XML DB 数据库中的/sys/acls目录下? description 访问控制列表的描述信息? principal 第一个被授予或拒绝的用户账号大小写敏感? is_grant TRUE意味着授予了权限FALSE意味着权限被拒绝? privilege 给UTL_TCP UTL_SMTP UTL_MAIL和UTL_HTTP授予connect权限给UTL_INADDR名称/ip解析授予resolve权限大小写敏感? start_date 默认值是NULL当指定了一个值后访问控制列表只有在指定的日期到达时或到达后才被激活? en_date 访问控制列表结束日期(可选的)

下面的代码创建了两个测试用户充当委托人然后又创建了一个新的访问控制列表

CONN sys/password@dbg AS SYSDBACREATE USER test IDENTIFIED BY test;GRANT CONNECT TO test;CREATE USER test IDENTIFIED BY test;GRANT CONNECT TO test;BEGIN DBMS_NETWORK_ACL_ADMINcreate_acl ( acl => test_acl_filexml description => A test of the ACL functionality principal => TEST is_grant => TRUE privilege => connect start_date => SYSTIMESTAMP end_date => NULL); COMMIT;END;/

一旦创建完毕访问控制列表就能够//host:port/sys/acls目录下看到

使用ADD_PRIVILEGE存储过程将其他的用户或角色添加到访问控制列表中它的参数与CREATE_ACL存储过程的参数类似省略了DESCRIPTION参数同时增加了POSITION参数它用于设置优先顺序

BEGIN DBMS_NETWORK_ACL_ADMINadd_privilege ( acl => test_acl_filexml principal => TEST is_grant => FALSE privilege => connect position => NULL start_date => NULL end_date => NULL); COMMIT;END;/

每个委托人在访问控制列表中都被作为一个独立的访问控制单元(ACE)进行定义当定义了多条原则时他们按照从上到下的顺序被评估直到最后一条定义权限的原则这就意味着一个拒绝访问某个资源的角色可以被授予一个用户但是如果这个用户又作为一个委托人定义在文件中时这个定义将覆盖角色的定义使用POSITION参数保证权限是按顺序进行评估的

使用DELETE_PRIVILEGE存储过程移除权限如果IS_GRANT或PRIVILEGE参数的值是NULL将移除所有授予的权限

BEGIN DBMS_NETWORK_ACL_ADMINdelete_privilege ( acl => test_acl_filexml principal => TEST is_grant => FALSE privilege => connect); COMMIT;END;/

使用DROP_ACL删除访问控制列表

BEGIN DBMS_NETWORK_ACL_ADMINdrop_acl ( acl => test_acl_filexml); COMMIT;END;/

给网络分配一个访问控制列表

使用ASSIGN_ACL存储过程给网络分配访问控制列表它有下面一些参数

? acl 访问控制列表XML文件的名字? host 主机名域名ip地址或分配的子网主机名大小写敏感ip地址和域名允许使用通配符? lower_port 默认值是NULL为connect权限指定低端口范围? upper_port 默认值是NULL如果指定了lower_port同时upper_port的值为 NULL它就认为upper_port等同于lower_port

下面的代码展示了前面创建的访问控制列表被分配一个特定的ip地址和一个子网

BEGIN DBMS_NETWORK_ACL_ADMINassign_acl ( acl => test_acl_filexml host => lower_port => upper_port => NULL); DBMS_NETWORK_ACL_ADMINassign_acl ( acl => test_acl_filexml host => * lower_port => NULL upper_port => NULL); COMMIT;END;/

只有一个访问控制列表可以分配给一个特殊的主机+端口范围的组合给主机+端口范围分配一个新的访问控制列表将导致前面分配的访问控制列表被删除在你开始一个新的分配操作时要特别留意前一个访问控制列表关闭的端口现在又被你打开了因此分配给:的访问控制列表的优先级比分配给*的访问控制列表要高

UNASSIGN_ACL存储过程允许你手动删除访问控制列表它使用的参数与ASSIGN_ACL存储过程相同使用NULL参数作为通配符

BEGIN DBMS_NETWORK_ACL_ADMINunassign_acl ( acl => test_acl_filexml host => lower_port => upper_port => NULL); COMMIT;END;/

访问控制列表视图

DBA_NETWORK_ACLS DBA_NETWORK_ACL_PRIVILEGES和USER_NETWORK_ACL_PRIVILEGES视图显示当前的访问控制列表设置下面预期的输出认为没有执行过delete/drop/unassign操作

DBA_NETWORK_ACLS视图显示关于网络和访问控制列表分配的信息

COLUMN host FORMAT ACOLUMN acl FORMAT ASELECT host lower_port upper_port aclFROM dba_network_acls;HOST * LOWER_PORT UPPER_PORT ACL

/sys/acls/test_acl_filexml /sys/acls/test_acl_filexml

rows selectedSQL>DBA_NETWORK_ACL_PRIVILEGES视图显示关于与访问控制列表联合的权限信息COLUMN acl FORMAT ACOLUMN principal FORMAT ASELECT acl principal privilege is_grant TO_CHAR(start_date DDMONYYYY) AS start_date TO_CHAR(end_date DDMONYYYY) AS end_dateFROM dba_network_acl_privileges;ACL PRINCIPAL /sys/acls/test_acl_filexml TEST /sys/acls/test_acl_filexml TEST PRIVILE IS_GR START_DATE END_DATE

connect true APR

connect false

rows selectedSQL>USER_NETWORK_ACL_PRIVILEGES视图显示当前用户网络访问控制列表设置CONN test/test@dbgCOLUMN host FORMAT ASELECT host lower_port upper_port privilege statusFROM user_network_acl_privileges;HOST LOWER_PORT UPPER_PORT PRIVILE STATUS * connect GRANTED connect GRANTED rows selectedSQL> CONN test/test@dbgCOLUMN host FORMAT ASELECT host lower_port upper_port privilege statusFROM user_network_acl_privileges;HOST LOWER_PORT UPPER_PORT PRIVILE STATUS * connect DENIED connect DENIED rows selectedSQL>

权限检查

处理访问控制列表视图外还可以使用DBMS_NETWORK_ACL_ADMIN包中的CHECK_PRIVILEGE和CHECK_PRIVILEGE_ACLID函数来检查权限

CONN sys/password@dbg AS SYSDBASELECT DECODE( DBMS_NETWORK_ACL_ADMINcheck_privilege(test_acl_filexml TEST connect) GRANTED DENIED NULL) privilege FROM dual;PRIVILEGRANTED row selectedSQL> COLUMN acl FORMAT ACOLUMN host FORMAT ASELECT acl host DECODE( DBMS_NETWORK_ACL_ADMINcheck_privilege_aclid(aclid TEST connect) GRANTED DENIED NULL) privilege FROM dba_network_acls;PRIVILEDENIED row selectedSQL>

DBMS_NETWORK_ACL_UTILITY包包括了帮助判断可能匹配的域的函数DOMAINS表函数按顺序返回所有可能受影响的主机ip地址或子网的集合

SELECT *FROM TABLE(DBMS_NETWORK_ACL_UTILITYdomains(oelglocaldomain)); COLUMN_VALUEoelglocaldomain*localdomain* rows selectedSQL>SELECT *FROM TABLE(DBMS_NETWORK_ACL_UTILITYdomains());COLUMN_VALUE**** rows selectedSQL>

DOMAIN_LEVEL函数返回主机ip地址或子网的级数

SELECT DBMS_NETWORK_ACL_UTILITYdomain_level(oelglocaldomain)FROM dual;DBMS_NETWORK_ACL_UTILITYDOMAIN_LEVEL(OELGLOCALDOMAIN) row selectedSQL> SELECT DBMS_NETWORK_ACL_UTILITYdomain_level()FROM dual;DBMS_NETWORK_ACL_UTILITYDOMAIN_LEVEL() row selectedSQL>

在为可能匹配的主机ip地址或子网查询访问控制列表视图是这些函数可能非常有用

SELECT host lower_port upper_port acl DECODE( DBMS_NETWORK_ACL_ADMINcheck_privilege_aclid(aclid TEST connect) GRANTED DENIED null) PRIVILEGEFROM dba_network_aclsWHERE host IN (SELECT * FROM TABLE(DBMS_NETWORK_ACL_UTILITYdomains()))ORDER BY DBMS_NETWORK_ACL_UTILITYdomain_level(host) desc lower_port upper_port; HOST LOWER_PORT UPPER_PORT ACL PRIVILE * /sys/acls/test_acl_filexml GRANTED row selectedSQL>

测试访问控制列表

用户TEST和TEST分别拥有了允许的和拒绝的访问控制列表这就意味着我们可以开始通过对比对访问外部网络服务时它们的响应来测试访问控制列表的功能下面的代码授予了这两个用户都可以执行UTL_HTTP包的权限然后尝试从每个用户访问一个web页面

CONN sys/password@dbg AS SYSDBAGRANT EXECUTE ON UTL_HTTP TO test test;CONN test/test@dbgDECLARE l_url VARCHAR() := ; l_; l_;BEGIN Make a HTTP request and get the response l_(l_url); l_(l_http_request); UTL_HTTPend_response(l_http_response);END;/PL/SQL procedure successfully completedSQL>CONN test/test@dbgDECLARE l_url VARCHAR() := ; l_; l_;BEGIN Make a HTTP request and get the response l_(l_url); l_(l_http_request); UTL_HTTPend_response(l_http_response);END;/DECLARE*ERROR at line :ORA: HTTP request failedORA: at SYSUTL_HTTP line ORA: network access denied by access control list (ACL)ORA: at line SQL>

从返回的信息我们不难看出用户TEST能够访问web页面而用户TEST被访问控制列表拒绝了服务器的默认行为是拒绝访问外部网络服务下面显示了一个新用户的测试情况

CONN sys/password@dbg AS SYSDBACREATE USER test IDENTIFIED BY test;GRANT CONNECT TO test;GRANT EXECUTE ON UTL_HTTP TO test;CONN test/test@dbgDECLARE l_url VARCHAR() := ; l_; l_;BEGIN Make a HTTP request and get the response l_(l_url); l_(l_http_request); UTL_HTTPend_response(l_http_response);END;/DECLARE*ERROR at line :ORA: HTTP request failedORA: at SYSUTL_HTTP line ORA: network access denied by access control list (ACL)ORA: at line SQL>

在从g升级到g时访问外部网络服务时可能会产生一些混乱在那种情况下你需要实现合理的访问控制列表

其他安全因素

Pete Finnigan在它的博客上和关于访问控制列表的安全陈述只没有附上具体的程序包这就意味着通过UTL_TCP UTL_SMTP UTL_MAIL和UTL_HTTP加上connect权限就能在服务器上打开一个端口牢记这一点并考虑以下事项

◆细粒度访问网络服务的使用不能作为忽略基本的安全评估的借口如收回与网络服务有关程序包的不必要的权限

◆通过限制对特定端口的访问控制你的服务是可用的如果你仅仅需要访问http 端口指定这个端口比在服务器上开放所有端口的访问要好得多

◆授权时使用通配符比不使用通配符安全性更差也更危险

◆你必须保护你的访问控制列表如果有人能够修改它们因为保护机制问题它们变得毫无用处阻止直接访问存储在XML DB 数据库中的访问控制列表确保用户不能访问管理API

上一篇:Re: 请问youngcow的FTP上DB2

下一篇:oracleRAC--归档日志的开启方法