Setup VNCR in Oracle RAC

This post is also available in: Português

Enabling VNCR (Valid Node Checking for Registration) is a mandatory task that every DBA should do when terminates the configuration of a new database, being it a Single Instance or a Oracle RAC. In my opinion, Oracle should have already defined this option enabled by default on new releases.

In times of TNS Poison (Oracle Security Alert CVE-2012-1675), which reaches "any" version of Oracle to the most current (12c), we can not risk that a compromised computer inside the network of eventually making a man-in-the-middle attack. So, in this article, I'll show you how to activate this protection in a RAC.

Remembering that VNCR is only available in versions 11g (after PS 11.2.0.4) and 12c. In other versions, this protection may be done using an Oracle feature called COST (Class of Secure Transport). If you run a version of DB lower than 10.2.0.4, there is no Oracle tool and the best form of protection is via firewall (iptables, etc).

For more information about COST, MOS provides step by step guides of how to enable it:

  • Using Class of Secure Transport (COST) to Restrict Instance Registration (Doc ID 1453883.1)
  • Using Class of Secure Transport (COST) to Restrict Instance Registration in Oracle RAC (Doc ID 1340831.1)

(In both cases, you must apply the patch for Bug 12880299)

Let's start. In our scenario, we are in a 4 nodes Oracle RAC: oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004.

We will need to edit the listener.ora file inside GRID_HOME of all 4 servers. The path to the file can be obtained by running "lsnrctl status":

[oracle@oracbddrjs001 ~]$ lsnrctl status
...
Listener Parameter File /u01/app/11.2.4/grid/network/admin/listener.ora
...
[oracle@oracbddrjs001 ~]$

Checking the current content, we have:

[oracle@oracbddrjs001 ~]$ cat /u01/app/11.2.4/grid/network/admin/listener.ora
LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))) # line added by Agent
LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1)))) # line added by Agent
LISTENER_SCAN2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN2)))) # line added by Agent
LISTENER_SCAN3=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN3)))) # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN2=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN3=ON # line added by Agent
[oracle@oracbddrjs001 ~]$

What we need to do is to add in each of the 4 listeners (1 local and 3 scans) the parameter VALID_NODE_CHECKING_REGISTRATION_listener_name=ON.
Thus, we add:

VALID_NODE_CHECKING_REGISTRATION_LISTENER=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN1=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN2=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN3=ON

The ON value permits that only locally originated registration requests are accepted. Therefore, to allow SCAN_LISTENERS accept requests from other nodes in the cluster, we must include an exception list of nodes allowed:

REGISTRATION_INVITED_NODES_LISTENER_SCAN1=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)
REGISTRATION_INVITED_NODES_LISTENER_SCAN2=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)
REGISTRATION_INVITED_NODES_LISTENER_SCAN3=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)

PS: Note that we need to include here the name of the corresponding hostname for the public interface.

With those changes, we will have the listeners of our servers as follows:

[oracle@oracbddrjs001 ~]$ cat /u01/app/11.2.4/grid/network/admin/listener.ora
LISTENER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))) # line added by Agent
LISTENER_SCAN1=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN1)))) # line added by Agent
LISTENER_SCAN2=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN2)))) # line added by Agent
LISTENER_SCAN3=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER_SCAN3)))) # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN1=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN2=ON # line added by Agent
ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER_SCAN3=ON # line added by Agent
# Enable VNCR
VALID_NODE_CHECKING_REGISTRATION_LISTENER=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN1=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN2=ON
VALID_NODE_CHECKING_REGISTRATION_LISTENER_SCAN3=ON
REGISTRATION_INVITED_NODES_LISTENER_SCAN1=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)
REGISTRATION_INVITED_NODES_LISTENER_SCAN2=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)
REGISTRATION_INVITED_NODES_LISTENER_SCAN3=(oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004)
[oracle@oracbddrjs001 ~]$

Another way that could also have been utilized would be changing the 3 parameters VALID_NODE_CHECKING_REGISTRATION_listener_name of SCAN LISTENER to SUBNET. This would make unnecessary the use of REGISTRATION_INVITED_NODES_listener_name parameter.

However, I do not recommend this approach because depending on the amount of servers that exist in the subnet of your cluster, you could put it at risk if any of these servers were compromised. The disadvantage of not using the value SUBNET is that whenever a new node is added to the cluster, all listener.ora may be changed including the new host.

Following are the possible values ​​for the variables of the VNC, according to the MOS Oracle Net 12c: Valid Node Checking For Registration (VNCR) (Doc ID 1600630.1)

VALID_NODE_CHECKING_REGISTRATION_listener_name
Values:
OFF/0 - Disable VNCR
ON/1/LOCAL - The default. Enable VNCR. All local machine IPs can register.
SUBNET/2 - All machines in the subnet are allowed registration.

REGISTRATION_INVITED_NODES_listener_name
Values are valid IPs, valid hosts, a subnet using CIDR notation (for ip4/6), or wildcard (*) for ipv4. For example: REGISTRATION_INVITED_NODES_Listener=(net-vm1, 127.98.45.209, 127.42.5.*)

Note that when an INVITED list is set, it will automatically include the machine's local IP in the list. There is no need to include it.

REGISTRATION_EXCLUDED_NODES_listener_name - the inverse of INVITED_NODES.

Finally, reload all listeners (on each node) to activate the changes made in listener.ora:

Check which are running:

[grid@oracbddrjs001 ~]$ lsnrctl status LISTENER
[grid@oracbddrjs001 ~]$ lsnrctl status LISTENER_SCAN1
[grid@oracbddrjs001 ~]$ lsnrctl status LISTENER_SCAN2
[grid@oracbddrjs001 ~]$ lsnrctl status LISTENER_SCAN3

For those who are running, do the reload:

[grid@oracbddrjs001 ~]$ lsnrctl reload LISTENER
[grid@oracbddrjs001 ~]$ lsnrctl reload LISTENER_SCAN3

Okay, now we are with our Oracle RAC protected from SQL Poison attacks.

Have you enjoyed? Please leave a comment or give a 👍!

24 comments

Skip to comment form

    • preethi on November 12, 2014 at 02:29
    • Reply

    Hi,

    Could you recommend us with the steps to implement these VNCR on Non-RAC Oracle Database of version 11.2.0.4

    Regards,
    Preethi

    1. Hi Preethi,

      If your running the default listener "LISTENER", just add "VALID_NODE_CHECKING_REGISTRATION_LISTENER=ON" line to your listener.ora file.

    • krishna on May 13, 2015 at 14:45
    • Reply

    Excellent! Very well explained. Thank you RJ 🙂

    • raj on December 9, 2015 at 19:41
    • Reply

    i have two questions.

    1. Can we specify IP Address instead of host-name?
    2. If we have Data guard running on another server for DR then what will be configuration for that?

    1. Hi Raj,
      1 - Yes, you can. If you check the docs link, you can even specify wildcard format (*).
      2 - DG does not remotely register a service. So if your DG nodes are single instances, you should set VALID_NODE_CHECKING_REGISTRATION_LISTENER parameter to ON (only allowing local service to be registered).

      Rodrigo Jorge

    • raj on December 10, 2015 at 11:55
    • Reply

    Thanks RJ!!

    • raj on December 10, 2015 at 12:06
    • Reply

    Another Question.. I noticed that Primary Single instance register to DG.. It means, we need to specify Single instance IP address at DG server to allow registration..

    Can you confirm?

    1. No, when you use VALID_NODE_CHECKING_REGISTRATION_LISTENER='ON', the localhost is already allowed by default. You don't need to specify the local server IP or hostname.

      Regards,

      RJ

        • raj on December 11, 2015 at 12:28
        • Reply

        I think, i did not ask clearly.. Main and DR instances running on two different server.. can we specify both server as VALID_NODE_CHECKING_REGISTRATION_LISTENER=’ON’ .. No IP LIST.. will DR server able to work without remote ( Primary Instance) registration..

        1. Yes you can. You don't need any IP list or anything else as each listener will need to register only its own instance in a DG setup.

    • Yogesha on February 26, 2016 at 00:29
    • Reply

    Hi RJ,

    during this activity we need any down time db..? or directly we can go edit listener.ora file..?

    1. Hi Yogesha,
      You can simply edit listener.ora and reload your listener. No down time is required.

      Regards,
      RJ

    • Sujith on April 25, 2016 at 22:35
    • Reply

    Hi RJ,
    You had mentioned it as sql poisoning. Is sql poisoning and TNS listener poisoning same. As I have to do the same for a 4 node rac affected with tns poisoning.

    Regards,
    Sujith

    1. Hi Sujith,
      Yes, they are the same in this context.

      Regards,
      Rodrigo Jorge

        • Sujith on April 26, 2016 at 05:52
        • Reply

        Hi RJ,

        Thanks a lot for clarifying.

        Regards,
        Sujith

    • syed on May 16, 2016 at 04:37
    • Reply

    Hi

    Very nice and very clear document. Could we have steps to simulate VNCR ?.

    Regards

    Syed.

    1. To simulate if this is working, just point any other database on your network to one of your RAC listeners using "remote_listener" parameter. Then check the logs to see if the registration was rejected.

    • syed on May 24, 2016 at 07:25
    • Reply

    Hi

    I tried to setup VNCR however i find one error. I have two node rac , when i reload listener after putting values same as mentioned , it is successful on one node and give below error on 2nd node.

    TNS-01196: Listener failed to initialize valid node list.

    I have implemented exactly same way as described in the post.

    Any idea of above error?

    Regards & Thanks

    Syed.

    1. Hi Syed,
      I would need to check your hosts and OCR.
      Probably the nodes you specified in the parameter could not be translated or you have a syntax error.
      Regards

    • Yogesha on May 25, 2016 at 23:20
    • Reply

    Hello DBA RJ,

    In our environment Two node and Four node RAC 11.2.0.4 and 11.2.0.3 version with SAP application, please provide us the implementation plan for " Oracle Database Server TNS Listener Poison Attack Remote Code Execution"

    thanks
    Yogesha.
    yogesha.dk@gmail.com

    1. Read this post and create one your own, adapting it.

    • Amarnath on May 26, 2016 at 09:29
    • Reply

    Could you please explain how to simulate the VNCR in detail.
    Actually ours is standalone 11.2.0.4 database and i have added only parameter "VALID_NODE_CHECKING_REGISTRATION_EBSDEV=ON" and how to test the VNCR rejection from other database.

    1. Hi Amarnath,
      As already said in the comments, to simulate if this is working, just point any other database on your network to this one using “remote_listener” parameter. Then check the listener logs to see if the registration was rejected.
      Regards,
      DBA RJ

    • Sten on November 9, 2018 at 21:33
    • Reply

    On RAC you are actually supposed to use srvctl modify scan_listener -update -invitednodes node1,node1,.... instead of editing listener.ora directly. Then the agent updates the files --current one immediately and others when scan relocated.
    But i haven't seen anyone mention the other listeners on a RAC -- the local DB one, ASM one and _MGMNTDB ones. I guess they should be added manually as srvcntl modify listener doesn't have such an option?

Leave a Reply

Your email address will not be published.