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
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.
Autor
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