Home » RDBMS Server » Security » Service-Level ACLs for TCP Protocol (12.2)
Service-Level ACLs for TCP Protocol [message #666042] Tue, 10 October 2017 04:27 Go to next message
Michel Cadot
Messages: 65210
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Version 12.2 introduces a new feature which seems interesting: Service-Level ACLs for TCP Protocol.
Unfortunately I found nowhere any explanation or example on how to use it.
The only things I found are in Database New Features Guide and Database Net Services Administrator's Guide with the same paragraph:

Service-Level ACLs for TCP Protocol
With this feature, every database service can have its own access control list (ACL) and the ACL is based on IPs. Because each pluggable database is a different service, this feature enables different pluggable databases to have different ACLs. These ACLs are enforced by the listener. Access to a pluggable database service is enabled only for IPs that are permitted through an ACL.

This feature improves pluggable database security

Do you know more about this?

Re: Service-Level ACLs for TCP Protocol [message #666083 is a reply to message #666042] Thu, 12 October 2017 08:10 Go to previous messageGo to next message
John Watson
Messages: 7150
Registered: January 2010
Location: Global Village
Senior Member
I can see no more about this than you.

What I do know is that using a Connection Manager you can control access to services. For example, a rule like this in your cman.ora file:
(rule_list=
	(rule=
		(src=192.168.56.255/24)
		(dst=jwvaio.example.com)
		(srv=orclx)
		(act=accept))
)
Perhaps there is something coming that will let one put rules like this into listener.ora or sqlnet.ora files?


Re: Service-Level ACLs for TCP Protocol [message #666088 is a reply to message #666083] Thu, 12 October 2017 13:22 Go to previous messageGo to next message
Michel Cadot
Messages: 65210
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

It's a good idea.
In the meantime I found this in Net Services Administrator's Guide:

Managing Oracle Net Listener Security
Connections coming to listener on an IP (TCP, TCPS, and SDP) based endpoint with firewall functionality enabled, go through service ACL validation. The listener after receiving the service name validates the connection IP with ACL list.

A new attribute FIREWALL is added in the endpoint to enable firewall functionality.

(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521)(FIREWALL=ON))

The FIREWALL parameter can be configured as follows:
  • (FIREWALL=ON) is explicitly set in endpoint This enables strict ACL validation (whitelist-based approach) of all connections coming on this endpoint. If no ACLs are configured for a service, all connections are rejected for that service.
  • FIREWALL is not set in endpoint This implies relaxed validation. If ACL is configured for a service, validation is done for that service. In the absence of ACLs, no validation is done and all connections for that service are accepted.
  • (FIREWALL=OFF) is set in endpoint No validation is done and all connections are accepted from this endpoint.

And this in Database Net Services Reference:

7.4.8 LOCAL_REGISTRATION_ADDRESS_listener_name

Purpose

To secure registration requests through dedicated secure registration endpoints for local listeners. Service ACLs are accepted by listener only if LOCAL_REGISTRATION_ADDRESS_lsnr alias is configured. The parameter specifies the group that is allowed to send ACLs.

Usage Notes

The local registration endpoint accepts local registration connections from the specified group. All local registration requests coming on normal listening endpoints are redirected to the local registration endpoint. If the registrar is not a part of the group, then it cannot connect to the endpoint.

Default

OFF

Values

ON, OFF, or IPC endpoint address with group

When set to ON, listener defaults the group to oinstall on UNIX and ORA_INSTALL on Windows.

Example 7-3 Example

LOCAL_REGISTRATION_ADDRESS_lsnr_alias = (address=(protocol=ipc)(group=xyz))
LOCAL_REGISTRATION_ADDRESS_lsnr_alias =ON


And this package:

DBMS_SFW_ACL_ADMIN
The DBMS_SFW_ACL_ADMIN package provides interfaces for administering and managing access control policies for the "database service firewall" feature. Each policy is represented by an access control list (ACL) containing hosts that are allowed access to a specific database service. Local listeners and server processes validate all inbound client connections against the ACL.

But I didn't have time to investigate more and test them...
Re: Service-Level ACLs for TCP Protocol [message #666219 is a reply to message #666088] Fri, 20 October 2017 08:25 Go to previous message
Michel Cadot
Messages: 65210
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
I succeeded to make it work and this is indeed an interesting feature.
Here's an example.

First 2 remarks about the usage.

The documentation (see the links in my previous post) states about the DBMS_SFW_ACL_ADMIN package:

DBMS_SFW_ACL_ADMIN Security Model
This package is owned by the DBSFWUSER schema. The procedures in this package can be run only by the DBSFWUSER user.
This is not correct (or this is a bug of the current version) as I used my own account which privileges are:
SQL> @userprivsys michel

Utilisateur                    Role ou Privilege              Adm Dft
------------------------------ ------------------------------ --- ---
MICHEL                         CDB_DBA                        NO  YES
                               DBA                            NO  YES
                               CREATE SESSION                 NO
                               SELECT ANY DICTIONARY          NO
                               SET CONTAINER                  NO
                               UNLIMITED TABLESPACE           NO
The second remark is that, even if you want to set an ACL for a PDB you have to execute the procedures in CDB$ROOT otherwise you will get the following message:
SQL> show con_name
NAME_COL_PLUS_PDB_CONTAINER
------------------------------------------------------------------------------------------------------
MIKC2DB1

SQL> begin
  2    dbsfwuser.dbms_sfw_acl_admin.ip_add_pdb_ace('mikc2db1','FE81::540c:a77d:57d6:98a%11');
  3    dbsfwuser.dbms_sfw_acl_admin.ip_add_pdb_ace('mikc2db1','192.168.1.107');
  4    dbsfwuser.dbms_sfw_acl_admin.commit_acl;
  5  end;
  6  /
begin
*
ERROR at line 1:
ORA-20012: Must run in CDB$ROOT container
ORA-06512: at "DBSFWUSER.DBMS_SFW_ACL_ADMIN", line 324
ORA-06512: at "DBSFWUSER.DBMS_SFW_ACL_ADMIN", line 909
ORA-06512: at line 2

Step 1: Set the ACLs from CDB$ROOT

Here I allow only 2 hosts for PDB mikc2db1:
SQL> alter session set container=cdb$root;

Session altered.

SQL> begin
  2    dbsfwuser.dbms_sfw_acl_admin.ip_add_pdb_ace('mikc2db1','FE81::540c:a77d:57d6:98a%11');
  3    dbsfwuser.dbms_sfw_acl_admin.ip_add_pdb_ace('mikc2db1','192.168.1.107');
  4    dbsfwuser.dbms_sfw_acl_admin.commit_acl;
  5  end;
  6  /

PL/SQL procedure successfully completed.
The first 2 calls add the ACE, the last one commits the modification which means:
* it commits the changes in a table of the DBSFWUSER schema
* if the service is started, it sends the ACL to the listener
Note: you can use host names, range of IP with * wild character (IPv4 only) or CIDR notation.

Step 2: verify the ACE are recorded and sent

DBSFWUSER.IP_ACL contains the ACLs that have been committed and V$IP_ACL the ACL that have been sent to the listener.
SQL> col service_name format a40
SQL> col host         format a30
SQL> select * from dbsfwuser.ip_acl
  2  /
SERVICE_NAME                             HOST
---------------------------------------- ------------------------------
"MIKC2DB1.RADA"                          192.168.1.107
"MIKC2DB1.RADA"                          FE81::540C:A77D:57D6:98A%11

2 rows selected.

SQL> select rtrim(service_name,chr(0)) service_name,
  2         rtrim(host,chr(0)) host,
  3         con_id
  4  from v$ip_acl
  5  /

no rows selected

SQL> alter session set container=mikc2db1;

Session altered.

SQL> col service_name format a40
SQL> col host         format a30
SQL> select * from dbsfwuser.ip_acl
  2  /

no rows selected

SQL> select rtrim(service_name,chr(0)) service_name,
  2         rtrim(host,chr(0)) host,
  3         con_id
  4  from v$ip_acl
  5  /
SERVICE_NAME                             HOST                               CON_ID
---------------------------------------- ------------------------------ ----------
MIKC2DB1.RADA                            192.168.1.107                           3
MIKC2DB1.RADA                            FE81::540C:A77D:57D6:98A%11             3

2 rows selected.
As you can see, even if the ACE are recorded in CDB$ROOT and nothing in the target PDB, they are sent to the listener on behalf this later one.
So everything is in DBSFWUSER.IP_ACL of CDB$ROOT and nothing in DBSFWUSER.IP_ACL of MIKC2DB1 and the opposite for V$IP_ACL.

Step 3: Verify the listener knows the ACL

Version 12.2 introduces a new listener command: "servacls" which is documented nowhere (not even on MOS), you can just see it in listener "help" command:
LSNRCTL> servacls
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=RADA)(PORT=1533)))
Service ACLs Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc": 0 failure(s), status UNKNOWN...
Service "mikb2.rada" has 1 instance(s).
  Instance "mikb2": 0 failure(s), status UNKNOWN...
Service "mikc2.rada" has 1 instance(s).
  Instance "mikc2": 0 failure(s), status UNKNOWN...
Service "mikc2db1.rada" has 1 instance(s).
  Instance "mikc2db1": 0 failure(s), status UNKNOWN...
Service "mikc2db2.rada" has 1 instance(s).
  Instance "mikc2db2": 0 failure(s), status UNKNOWN...
The command completed successfully
Well, not very conclusive, you just have the list of the services.
This is because I forgot one point: the listener have to be configured to accept the ACL. This is done via the LOCAL_REGISTRATION_ADDRESS_xxx parameter (see my previous post).
So one conclusion is this not because the ACLs are sent to the listener (and visible in V$IP_ACL) that they are effective. I think this view is misleading.

Step 4: include LOCAL_REGISTRATION_ADDRESS_LISTENER in listener.ora and restart the listener

Step 5: Verify again the ACLs in the listener
(Note: not interesting lines have been removed to shorten the output)

LSNRCTL> servacls
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=RADA)(PORT=1533)))
Service ACLs Summary...
<...cut...>
Service "mikc2db1.rada" has 3 instance(s).
  Instance "MIKC2": 0 failure(s), status READY...
    ACL(s):
        IP_LIST has 2 item(s)
          FE81::540c:a77d:57d6:98a%11, 192.168.1.107
  Instance "MIKC2": 0 failure(s), status READY...
    ACL(s):
        IP_LIST has 2 item(s)
          FE81::540c:a77d:57d6:98a%11, 192.168.1.107
  Instance "mikc2db1": 0 failure(s), status UNKNOWN...
<...cut...>
The command completed successfully
Now we see our ACLs.

Step 6: Check the ACLs work

First connecting from an IP that is in the list:
SQL> @mikc2db1
Connected.
SQL> select sys_context('USERENV','IP_ADDRESS') from dual;
SYS_CONTEXT('USERENV','IP_ADDRESS')
---------------------------------------------------------------------
192.168.1.107
Hopefully this still works.
Now with an IP not in the list:
SQL> select sys_context('USERENV','IP_ADDRESS') from dual;
SYS_CONTEXT('USERENV','IP_ADDRESS')
----------------------------------------------------------------------
192.168.1.109

SQL> @mikc2db1
ERROR:
ORA-12518: TNS:listener could not hand off client connection
Tada!

Step 7: Verify what does give the listener

LSNRCTL> servacls
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=RADA)(PORT=1533)))
Service ACLs Summary...
<...cut...>
Service "mikc2db1.rada" has 3 instance(s).
  Instance "MIKC2": 1 failure(s), status READY...
    ACL(s):
        IP_LIST has 2 item(s)
          FE81::540c:a77d:57d6:98a%11, 192.168.1.107
  Instance "MIKC2": 1 failure(s), status READY...
    ACL(s):
        IP_LIST has 2 item(s)
          FE81::540c:a77d:57d6:98a%11, 192.168.1.107
  Instance "mikc2db1": 0 failure(s), status UNKNOWN...
<...cut...>
The command completed successfully
The listener indeed reports a failure.

To remove the ACLs just use (in CDB$ROOT):
begin
  dbsfwuser.dbms_sfw_acl_admin.ip_remove_pdb_acl('mikc2db1');
  dbsfwuser.dbms_sfw_acl_admin.commit_acl;
end;
/

Hope this will help.

[Updated on: Tue, 24 October 2017 12:25]

Report message to a moderator

Previous Topic: PDB SYSOPER/SYSDBA privileges
Next Topic: CREATE ANY CONTEXT privilege
Goto Forum:
  


Current Time: Sat Nov 25 03:29:31 CST 2017

Total time taken to generate the page: 0.01508 seconds