Overview
Oracle allows access to external network services using several PL/SQL APIs (UTL_TCP, UTL_SMTP, UTL_MAIL, UTL_HTTP and UTL_INADDR), all of which are implemented using the TCP protocol. In previous versions of the database, access to external services was effectively an on/off switch based on whether a user was granted execute permissions on a specific package or not. Oracle 11g introduces fine grained access to network services using access control lists (ACL) in the XML DB repository, allowing control over which users access which network resources, regardless of package grants. Access control lists can be created, amended and deleted in the XML DB repository directly using FTP or WebDav. In addition, Oracle provide the DBMS_NETWORK_ACL_ADMIN and DBMS_NETWORK_ACL_UTILITY packages to allow ACL management from PL/SQL.
Creating an Access Control List
An access control list is simply a list of users and their privileges. The database stores the XML document containing the usernames and privileges in the /sys/acl folder in Oracle XML DB. The following example demonstrates how to use the DBMS_ NETWORK_ACL_ADMIN.CREATE_ACL procedure to create an ACL:
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl(
acl => 'test_acl_file.xml',
description => 'A test of the ACL functionality',
principal => 'TEST1',
is_grant => TRUE,
privilege => 'connect',
start_date => SYSTIMESTAMP,
end_date => NULL);
END;
/
Here are the key things to note in the CREATE_ACL procedure:
- The acl parameter specifies the name of the XML file holding the usernames and privileges in the ACL. principal indicates the username and must match the username of the session.The text is case sensitive.
- is_grant shows whether a privilege is granted or denied.
- privilege specifies the network privilege to be granted or denied - 'connect | resolve' (case sensitive). A database user needs the connect privilege to an external network host computer if he or she is connecting using the UTL_TCP, UTL_HTTP, UTL_SMTP, and UTL_MAIL utility packages. To resolve a host name that was given a host IP address, or the IP address that was given a host name, with the UTL_INADDR package, grant the database user the resolve privilege.
- start_date - Default value NULL. When specified, the ACL will only be active on or after the specified date.
- end_date - An optional end date for the ACL.
Additional users or roles are added to the ACL using the ADD_PRIVILEGE procedure. Its parameter list is similar to the CREATE_ACL procedure, with the omission of the DESCRIPTION parameter and the addition of a POSITION parameter, which sets the order of precedence.
BEGIN
DBMS_NETWORK_ACL_ADMIN.add_privilege (
acl => 'test_acl_file.xml',
principal => 'TEST2',
is_grant => FALSE,
privilege => 'connect',
position => NULL,
start_date => NULL,
end_date => NULL);
COMMIT;
END;
/
Each principal is defined as a separate access control element (ACE), within the ACL. When multiple principles are defined, they are eval(or TCP port range, if you specify it).
Precedence Order for a Host Computer
Here’s the order of precedence for the eval('www.baidu.com') from dual;
DBMS_NETWORK_ACL_UTILITY.DOMAIN_LEVEL('WWW.BAIDU.COM')
------------------------------------------------------
3
SQL> select dbms_network_acl_utility.domain_level('192.168.1.1') from dual;
DBMS_NETWORK_ACL_UTILITY.DOMAIN_LEVEL('192.168.1.1')
----------------------------------------------------
4
The DBMS_NETWORK_ACL_UTILITY package contains functions to help determine possible matching domains. The DOMAINS table function returns a collection of all possible references that may affect the specified host, domain, IP address or subnet, in order of precedence.
SQL> select * from table(DBMS_NETWORK_ACL_UTILITY.domains('www.baidu.com'));
COLUMN_VALUE
--------------------------------------------------------------------------------
www.baidu.com
*.baidu.com
*.com
*
SQL> select * from table(DBMS_NETWORK_ACL_UTILITY.domains('192.168.1.1'));
COLUMN_VALUE
--------------------------------------------------------------------------------
192.168.1.1
192.168.1.*
192.168.*
192.*
*
Manager the ACL
The UNASSIGN_ACL procedure allows you to manually drop ACL assignments. It uses the same parameter list as the ASSIGN_ACL procedure, with any NULL parameters acting as wildcards.
BEGIN
DBMS_NETWORK_ACL_ADMIN.unassign_acl (
acl => 'test_acl_file.xml',
host => '192.168.2.3',
lower_port => 80,
upper_port => NULL);
COMMIT;
END;
/
ACLs are deleted using the DROP_ACL procedure.
BEGIN
DBMS_NETWORK_ACL_ADMIN.drop_acl (
acl => 'test_acl_file.xml');
COMMIT;
END;
/
The DBA_NETWORK_ACLS view displays information about network and ACL assignments.
SQL> select host,lower_port,upper_port,acl from dba_network_acls
HOST LOWER_PORT UPPER_PORT ACL
---------------------------------------- ---------- ---------- ----------------------------------------
119.147.151.50 80 80 /sys/acls/test_acl_file.xml
10.1.10.* /sys/acls/test_acl_file.xml
The DBA_NETWORK_ACLS, DBA_NETWORK_ACL_PRIVILEGES and USER_NETWORK_ACL_PRIVILEGES views display the current ACL settings. The expected output below assumes none of the delete/drop/unassign operations have been performed.
SQL> select acl,principal,privilege,is_grant
from dba_network_acl_privileges;
ACL PRINCIPAL PRIVILEGE IS_GRANT
---------------------------------------- -------------------- --------------------- ---------------
/sys/acls/test_acl_file.xml TEST1 connect true
/sys/acls/test_acl_file.xml TEST2 connect false
In addition to the ACL views, privileges can be checked using the CHECK_PRIVILEGE and CHECK_PRIVILEGE_ACLID functions of the DBMS_NETWORK_ACL_ADMIN package.
SELECT DECODE(
DBMS_NETWORK_ACL_ADMIN.check_privilege('test_acl_file.xml', 'TEST1', 'connect'),
1, 'GRANTED', 0, 'DENIED', NULL) privilege
FROM dual;
PRIVILE
-------
GRANTED
1 row selected.
SELECT acl,
host,
DECODE(
DBMS_NETWORK_ACL_ADMIN.check_privilege_aclid(aclid, 'TEST2', 'connect'),
1, 'GRANTED', 0, 'DENIED', NULL) privilege
FROM dba_network_acls;
PRIVILE
-------
DENIED
1 row selected.
Other Security Considerations
Pete Finnigan commented on his blog and in his security presentations about the fact that the ACLs are not tied to a specific package. This means opening a port on a server with the 'connect' privilege makes it accessible by UTL_TCP, UTL_SMTP, UTL_MAIL and UTL_HTTP. With this in mind there are some things to consider:
- The use of fine-grained access to network services is not an excuse to ignore basic security measures, like revoking unnecessary privileges on network service related packages.
- Control over the services you make available is possible by limiting access to the specific ports. If you only need HTTP access to port 80, specify the port rather than opening access to all ports on the server.
- Wildcards can be dangerous as you may be granting access to more servers that you should.
- You must protect your ACLs. If people can alter them, they become useless as a protection mechanism. Prevent direct access to the ACLs in the XML DB repository and make sure users don't have access to the management APIs.
参考至:《McGraw.Hill.OCP.Oracle.Database.11g.New.Features.for.Administrators.Exam.Guide.Apr.2008》
http://www.oracle-base.com/articles/11g/fine-grained-access-to-network-services-11gr1.php http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_networkacl_adm.htm#ARPLS67220