Ativando o VNCR no Oracle RAC

This post is also available in: English

Ativar o VNCR (Valid Node Checking for Registration) é uma tarefa mandatória que todo DBA deveria fazer assim que termina a configuração de um banco de dados novo, seja ele Single Instance ou RAC. Na minha opinião, a Oracle já deveria deixar essa opção ativada por default nas novas releases.

Em tempos de TNS Poison (Oracle Security Alert CVE-2012-1675), que atinge "qualquer" versão do Oracle até a mais atual (12c), não podemos arriscar que um computador comprometido da rede acabe por efetuar um ataque man-in-the-middle. Portanto, neste artigo irei ensinar a ativar essa proteção em um RAC.

Lembrando que o VNCR só está disponível nas versões 11g (a partir do PS 11.2.0.4) e 12c. Em outras versões, a proteção deverá ser feita através de uma funcionalidade do Oracle chamada COST (Class of Secure Transport). Se você executa uma versão de BD inferior a 10.2.0.4, não existe ferramenta da Oracle e a melhor forma de proteção é via firewall (iptables, etc).

Para mais informações sobre o COST, o MOS fornece passo a passo de como habilita-lo:

  • 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)

(Em ambos os casos, será necessário aplicar o patch para o Bug 12880299)

Vamos então começar. No nosso cenário, estamos em um Oracle RAC com 4 nós: oracbddrjs001,oracbddrjs002,oracbddrjs003,oracbddrjs004.

Iremos precisar editar o arquivo listener.ora que está na GRID_HOME dos 4 servidores. O caminho para o arquivo pode ser obtido executando "lsnrctl status":

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

Ao conferir o conteúdo atual, temos:

[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 ~]$

O que precisamos fazer é acrescentar para cada um dos 4 listeners que existem (1 local e 3 scans) o parâmetro VALID_NODE_CHECKING_REGISTRATION_listener_name=ON.
Sendo assim, acrescentamos:

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

O valor ON do parâmetro permite que apenas solicitações de registro vindas localmente sejam aceitas. Portanto, para permitir que os SCAN_LISTENERS aceitem solicitações dos outros nós do cluster, devemos incluir uma lista de exceção de nós permitidos:

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)

OBS: Note que aqui precisamos incluir o nome do hostname correspondente a interface pública.

Com essas alterações, ficamos com os listeners dos nossos servidores da seguinte forma:

[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 ~]$

Outra forma que também poderia ter sido utilizada seria alterando os 3 parâmetros do LISTENER SCAN de VALID_NODE_CHECKING_REGISTRATION_listener_name para SUBNET. Com isso, seria desnecessário a utilização do parâmetro REGISTRATION_INVITED_NODES_listener_name.

No entanto, eu não recomendo essa abordagem pois dependendo da quantidade de servidores que existirem na subrede do seu cluster, você poderia coloca-lo em risco caso algum destes servidores esteivesse comprometido. A desvantagem de não utilizar o valor SUBNET é que sempre que um nó novo for acrescentado no cluster, todos os listener.ora deverão ser alterados incluindo o host novo.

Segue abaixo os valores possíveis para as variáveis do VNCR, segundo o 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.

Por fim, faça o reload dos listeners (em cada nó) para ativar as mudanças efetuadas no listener.ora:

Verifique quais estão executando:

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

Para os que estiverem executando, faça o reload:

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

Pronto, agora estamos com o nosso Oracle RAC protegido de ataques SQL Poison.

Gostou? Não deixe de comentar ou deixar um 👍!

2 comentários

    • Vitor Ugo Roda da Rosa Junior em agosto 18, 2016 às 10:54
    • Responder

    Bom dia Rodrigo, tudo certo?

    Essa configuração impacta, de alguma forma, aplicações ou clients que conectem na base, visto que irão utilizar o listener? Ou isso é apenas interno, ou seja, para registro de nodes no cluster?
    E em ambiente single? É a mesma coisa? Impacta na aplicação também?

    Abraço!

    Vitor Jr.

    1. Fala Vitor, bom dia.
      Não impacta a aplicação nem para single quanto para RAC pois este filtro é para registros de serviços no listener, não para conexões.
      Para ambientes single basta colocar "ENABLE_GLOBAL_DYNAMIC_ENDPOINT_LISTENER=ON". Não há necessidade de criar uma lista de exceção como no RAC já que há apenas o próprio nó.

      Abcs,
      RJ

Deixe um comentário

Seu e-mail não será publicado.