Erro de conexão ao tentar acessar o SQL Azure

Por Daniel Mauser e Roberto Cavalcanti

Introdução

Considere o cenário em que o usuário do SQL Azure recebe de forma intermitente recebe a seguinte mensagem ao tentar acessar o SQL Azure:

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. [provider: SSL Provider, error: 0 – The certificate’s CN name does not match the passed value.)

Coletando informações para entender o problema

Para entender o que ocorre realizamos uma coleta via ferramenta de captura de rede Network Monitor 3.4 que foi coletado durante a hora do problema:

1. Inicio da conversação através do TCP 3 way handshake - Syn (S), Ack Syn (A S), Ack (A) na porta de destino TCP 1433

Frame Origem Destino Proto Descrição
339 10.1.1.1 RemoteAzure.database.windows.net TCP TCP:Flags=......S., SrcPort=49179, DstPort=1433
342 RemoteAzure.database.windows.net 10.1.1.1 TCP TCP:Flags=...A..S., SrcPort=1433, DstPort=49179
343 10.1.1.1 RemoteAzure.database.windows.net TCP TCP:Flags=...A...., SrcPort=49179, DstPort=1433

Nota: RemoteAzure.database.windows.net é igual ao nome randômico gerado pelo SQL Azure. Este nome é utilizado aqui neste artigo apenas de forma ilustrativa.

2. Pre-login do TDS (Protocolo do SQL)

Frame Origem Destino Proto Descrição
344 10.1.1.1 RemoteAzure.database.windows.net TDS TDS:Prelogin, Version = 7.300000
348 RemoteAzure.database.windows.net 10.1.1.1 TDS TDS:Response, Version = 7.300000

3. Negociação do certificado do cliente para o servidor via protocolo TLS

Frame Origem Destino Proto Descrição
349 10.1.1.1 RemoteAzure.database.windows.net TLS TLS:TLS Rec Layer-1 HandShake: Client Hello.
352 RemoteAzure.database.windows.net 10.1.1.1 TLS TLS:TLS Rec Layer-1 HandShake: Server Hello. Certificate.
358 10.1.1.1 RemoteAzure.database.windows.net TLS TLS:TLS Rec Layer-1 HandShake: Client Key Exchange.;
361 RemoteAzure.database.windows.net 10.1.1.1 TLS TLS:TLS Rec Layer-1 Cipher Change Spec; TLS Rec Layer-2

4. O cliente repentinamente fecha a conexão enviando um ACK FIN (A F) com confirmação do servidor – ACK (A) - e o servidor envia um ACK FIN (A F) com confirmação ACK (A) do cliente.

Frame Origem Destino Proto Descrição
362 10.1.1.1 RemoteAzure.database.windows.net TCP TCP:Flags=...A...F, SrcPort=49179, DstPort=1433
366 RemoteAzure.database.windows.net 10.1.1.1 TCP TCP:Flags=...A...., SrcPort=1433, DstPort=49179
367 RemoteAzure.database.windows.net 10.1.1.1 TCP TCP:Flags=...A...F, SrcPort=1433, DstPort=49179
368 10.1.1.1 RemoteAzure.database.windows.net TCP TCP:Flags=...A...., SrcPort=49179, DstPort=1433

Verificando os detalhes do certificado no frame 352 vemos as seguintes informações:
Signature: Sha1WithRSAEncryption (1.2.840.113549.1.1.5)
Issuer: Microsoft Secure Server Authority,redmond,corp,microsoft,com
Subject: data.sn1-1.database.windows.net,STBOS-Clouddb,Microsoft,Redmond,WA,US
Validity: From: 09/15/10 17:15:33 UTC To: 09/14/12 17:15:33 UTC

Vemos que o cliente tenta a fazer a conexão para o nome gerado randomicamente pelo SQL Azure e teoricamente deveria fazer a resolução para o nome data.sn1-1.database.windows.net* que está no certificado em vez de tentar o próprio nome: RemoteAzure.database.windows.net.

Certificados são estritamente sensíveis ao nome especificado no atributo Subject e a suspeita que temos até agora é que podemos estar tendo um problema na resolução de nomes o que iremos validar na próxima seção

Resolução de Nomes

O processo de resolução de nomes do SQL Azure é bastante interessante. Para cada cliente é gerado um nome randômico, conforme representado na analise de rede acima por RemoteAzure.database.windows.net. Se executarmos através da linha de comando do Windows (cmd.exe) podemos verificar como este procedimento funciona:

C:\>nslookup
> RemoteAzure.database.windows.net
Server: [10.1.1.100]
Address: 10.1.1.100

Non-authoritative answer:
Name: data.sn1-1.database.windows.net
Address: 65.55.74.144
Aliases: RemoteAzure.database.windows.net

Na terminologia de DNS temos aqui uma entrada CNAME (Alias ou apelido) para o RemoteAzure.database.windows.net que é mapeado para uma outra entrada HOST representada pelo data.sn1-1.database.windows.net. Por este tipo de consulta através da ferramenta nslookup podemos observar que o nome gerado pelo SQL Azure é na realidade um DNS alias para o nome: data.sn1-1.database.windows.net que é o mesmo do certificado.

Voltando ao nosso problema original, solicitamos ao cliente afetado pelo problema para validar se resolução de nomes estava funcionando dentro dos padrões. Verificamos que nos caso do cliente afetado tínhamos o seguinte resultado:

C:\>nslookup
> RemoteAzure.database.windows.net
Server: [192.168.1.1]
Address: 192.168.1.1

Non-authoritative answer:
Name: RemoteAzure.database.windows.net
Address: 65.55.74.144

No caso acima podemos perceber que o nome randômico consultado é retornado o IP diretamente como se RemoteAzure.database.windows.net fosse uma entrada HOST no DNS. Ao utilizar este nome para o certificado a negociação SSL vai falhar, pois o mesmo não está configurado no certificado digital. Por isso obtermos o erro na console do SQL durante a conexão.

Conclusão

Para resolver este tipo de problema deve ser verificado se servidor DNS utilizado possui uma entrada estática para a entrada HOST com o nome do servidor randômico ou algum problema específico no roteador ou na rede que esteja fazendo com que a consulta não trabalhe de forma correta, ou seja, retornar o nome randômico do SQL Azure (RemoteAzure.database.windows.net) como o nome real data.sn1-1.database.windows.net.

Nota:

* data.sn1-1.database.windows.net indica que o SQL Azure está localizado no nosso datacenter em South Central US. Se o SQL Azure estivesse no datacenter North Central US ele se chamaria data.ch1-1.database.windows.net e assim por diante, de acordo com o datacenter escolhido na opção:

clip_image002