Conectando ao SQL Server com autenticação Active Directory (Kerberos) no DBeaver pelo macOS
Conectar a um SQL Server que autentica via Active Directory parece trivial no Windows, onde tudo acontece de forma transparente. No macOS a história é diferente: o DBeaver não pega o login de domínio sozinho, e os erros que aparecem no caminho são pouco descritivos. Este guia documenta um procedimento que funciona de ponta a ponta, explicando o porquê de cada passo, não só o comando.
O cenário
Um SQL Server autenticando contra um Active Directory, acessado a partir de um Mac. O servidor pode estar em qualquer lugar (on-premises, Azure, AWS), porque isso não importa para o login.
Vale começar desfazendo uma confusão comum: o lugar onde o banco roda e o provedor de identidade que valida o login são camadas independentes. Um SQL Server numa instância de nuvem pode perfeitamente autenticar contra um Active Directory tradicional via Kerberos. O que determina o método de autenticação é como o SQL Server foi configurado para confiar num domínio, não a infraestrutura onde ele está hospedado. Então “está na nuvem” não quer dizer “não é Kerberos”.
Se o seu login é uma conta de domínio (usuario@DOMINIO) e funciona no Windows com Windows Authentication, você está no cenário deste guia: Kerberos contra Active Directory.
Por que o macOS complica
Dois detalhes específicos do macOS atrapalham, e entender os dois evita horas de tentativa e erro.
O cache de credenciais Kerberos. O macOS vem com a implementação Heimdal do Kerberos. Por padrão, ela armazena o ticket num cache de credenciais do tipo API: (um cache em memória gerenciado pelo sistema). O problema: o Java empacotado no DBeaver não consegue ler esse formato. Resultado, o DBeaver conecta ao banco mas envia uma credencial vazia. É preciso gerar o ticket em um arquivo (cache do tipo FILE:), e a implementação nativa da Apple ignora a variável que pediria isso. A saída é usar a implementação do MIT Kerberos, que respeita a variável e grava em arquivo.
A configuração JAAS. O driver JDBC da Microsoft, ao autenticar via Kerberos, usa o JAAS (Java Authentication and Authorization Service) para obter a credencial. Por padrão ele não sabe que deve ler o ticket de um arquivo de cache. É preciso fornecer um arquivo de configuração JAAS dizendo exatamente isso, e com o nome de bloco que o driver procura.
Resolvidos esses dois pontos, o resto é configuração de conexão comum.
sequenceDiagram
actor U as Usuário
participant K as kinit (MIT)
participant F as Ticket em arquivo
participant D as DBeaver
participant KDC as KDC (controlador AD)
participant S as SQL Server
U->>K: kinit usuario@REALM + senha
K->>KDC: solicita ticket (TGT)
KDC-->>K: TGT emitido
K->>F: grava ticket (formato FILE)
Note over F: macOS: precisa ser arquivo,<br/>o cache API não é lido pelo Java
U->>D: abre conexão (host = FQDN)
D->>F: lê o ticket via config JAAS
D->>S: conecta com JavaKerberos
S->>KDC: valida o ticket
KDC-->>S: ticket válido
S-->>D: conexão autenticada
Pré-requisitos
- Acesso de rede ao Active Directory e ao SQL Server. Se você acessa via VPN ou um cliente ZTNA, ele precisa estar ativo e tunelando o DNS interno do domínio, além de liberar as portas do AD (88 para Kerberos, 389 para LDAP, 53 para DNS) e do SQL Server (1433, ou a porta usada). Se um
nslookupde um host interno do domínio retornaNXDOMAIN, o túnel não está encaminhando o DNS interno e nada vai funcionar até resolver isso. - DBeaver instalado.
- Homebrew instalado.
- Os comandos abaixo assumem Mac Apple Silicon, onde o Homebrew instala em
/opt/homebrew. Em Mac Intel, troque/opt/homebrew/opt/krb5/binpor/usr/local/opt/krb5/bin.
Ao longo do guia, use estes valores de exemplo substituindo pelos seus:
- Realm Kerberos:
EXEMPLO.COM(sempre em maiúsculas) - Controladores de domínio:
dc01.exemplo.com,dc02.exemplo.com - Usuário:
seu.usuario - Host do SQL Server:
sqlserver.exemplo.com
Descobrindo realm e controladores
Se você não sabe o nome do realm nem os controladores de domínio, e está com o acesso de rede ativo, este comando lista os KDCs do domínio via registro SRV do DNS:
nslookup -type=SRV _kerberos._tcp.exemplo.com
Atenção: o domínio interno do Active Directory frequentemente é diferente do domínio público (do site, do e-mail). O AD pode estar em algo como corp.exemplo.com, ad.exemplo.local, etc. Na dúvida, confirme com a equipe de infraestrutura, ou inspecione qual domínio de busca seu sistema enxerga com o acesso ativo:
scutil --dns | grep -i domain
Passo 1 — Configurar o Kerberos (/etc/krb5.conf)
Crie ou edite /etc/krb5.conf:
[libdefaults]
default_realm = EXEMPLO.COM
udp_preference_limit = 1
dns_lookup_kdc = false
[realms]
EXEMPLO.COM = {
kdc = dc01.exemplo.com
kdc = dc02.exemplo.com
admin_server = dc01.exemplo.com
}
[domain_realm]
.exemplo.com = EXEMPLO.COM
exemplo.com = EXEMPLO.COM
O que cada parte faz:
default_realmdefine o domínio Kerberos padrão. Deve ficar em maiúsculas — Kerberos é case-sensitive no realm.- Múltiplos
kdcfuncionam como redundância. O cliente tenta na ordem listada e passa para o próximo se um controlador não responder. Liste mais de um se o domínio tiver vários controladores. kdcé o endereço do Key Distribution Center, que em Active Directory roda dentro do controlador de domínio. É o serviço que emite os tickets Kerberos.admin_serveré o serviço de administração do Kerberos (kadmind). Em ambiente AD você praticamente nunca o usa a partir do cliente, porque a administração é feita pelas ferramentas da Microsoft. Ele está aqui só porque o formato espera o campo, e costuma apontar para o mesmo host dokdc.udp_preference_limit = 1força o Kerberos a usar TCP em vez de UDP. Isso resolve um problema frequente quando o tráfego passa por túneis VPN ou ZTNA, que nem sempre lidam bem com o UDP do Kerberos na porta 88.dns_lookup_kdc = falsefaz o cliente usar exclusivamente os KDCs que você listou, em vez de tentar descobri-los via registros SRV do DNS. Torna o comportamento previsível. Se preferir que o Kerberos descubra os controladores automaticamente via DNS, omita esta linha.[domain_realm]mapeia nomes DNS para o realm Kerberos. A entrada com ponto (.exemplo.com) cobre todos os hosts dentro do domínio; a sem ponto cobre o domínio raiz exato. Isso garante que, ao montar o SPN do SQL Server, o cliente saiba a que realm aquele host pertence.
Passo 2 — Instalar o MIT Kerberos
A implementação nativa da Apple ignora a variável KRB5CCNAME e grava o ticket sempre no cache API:, que o Java do DBeaver não lê. O MIT Kerberos respeita a variável e grava em arquivo.
brew install krb5
No Apple Silicon, os binários ficam em /opt/homebrew/opt/krb5/bin/. O Homebrew não os coloca no PATH por padrão (para não sobrepor os comandos do sistema), por isso vamos chamá-los pelo caminho completo.
Passo 3 — Gerar o ticket em arquivo
Use o kinit do MIT, definindo KRB5CCNAME para apontar o cache a um arquivo:
KRB5CCNAME=/tmp/krb5cc_dbeaver /opt/homebrew/opt/krb5/bin/kinit seu.usuario@EXEMPLO.COM
Digite a senha quando solicitado. Confirme que o ticket foi para o arquivo, repetindo a variável no klist (sem ela, o klist olha para outro cache):
KRB5CCNAME=/tmp/krb5cc_dbeaver /opt/homebrew/opt/krb5/bin/klist
A saída deve mostrar o TGT (krbtgt/EXEMPLO.COM@EXEMPLO.COM), a validade do ticket, e o cache identificado como FILE:/tmp/krb5cc_dbeaver. Confirme também que o arquivo existe:
ls -la /tmp/krb5cc_dbeaver
Se o kinit do MIT reclamar que não encontra o realm ou os KDCs, ele pode estar lendo um krb5.conf em outro caminho. Aponte explicitamente:
KRB5_CONFIG=/etc/krb5.conf KRB5CCNAME=/tmp/krb5cc_dbeaver /opt/homebrew/opt/krb5/bin/kinit seu.usuario@EXEMPLO.COM
Repare nas duas variáveis distintas: KRB5_CONFIG aponta para o arquivo de configuração, KRB5CCNAME aponta para o cache de credenciais.
Passo 4 — Criar a configuração JAAS
O driver JDBC da Microsoft procura, por padrão, por um bloco de login JAAS chamado SQLJDBCDriver. Crie o arquivo:
cat > /tmp/jaas_dbeaver.conf << 'EOF'
SQLJDBCDriver {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true
ticketCache="/tmp/krb5cc_dbeaver"
doNotPrompt=true
debug=true;
};
EOF
O que cada opção faz:
useTicketCache=truediz para usar um cache de credenciais já existente, em vez de pedir senha de novo.ticketCacheaponta para o arquivo gerado no passo anterior.doNotPrompt=trueimpede o módulo de tentar pedir senha interativamente (o que quebraria numa aplicação gráfica).debug=trueimprime no console o que está acontecendo durante a autenticação Kerberos. Mantenha durante o diagnóstico e remova depois que estiver funcionando.
O nome do bloco (SQLJDBCDriver) precisa ser exatamente esse — é o nome que o driver da Microsoft procura. Se estiver diferente, o driver acusa que não há módulo de login configurado.
Passo 5 — Configurar o dbeaver.ini
O DBeaver usa um JRE próprio empacotado, então as opções de JVM precisam ser passadas pelo arquivo dbeaver.ini, e essas opções têm que vir depois da linha -vmargs. Qualquer coisa antes do -vmargs é argumento do launcher e ignora opções de JVM.
No macOS, o arquivo fica dentro do bundle do aplicativo:
/Applications/DBeaver.app/Contents/Eclipse/dbeaver.ini
(Pela interface: Finder → Aplicativos → clique direito no DBeaver → Show Package Contents → Contents/Eclipse/dbeaver.ini.)
Adicione estas quatro linhas ao final, cada uma na sua própria linha:
-Djava.security.krb5.conf=/etc/krb5.conf
-Djavax.security.auth.useSubjectCredsOnly=false
-DKRB5CCNAME=/tmp/krb5cc_dbeaver
-Djava.security.auth.login.config=/tmp/jaas_dbeaver.conf
O que cada uma faz:
java.security.krb5.confindica ao Java qual arquivo de configuração Kerberos usar.javax.security.auth.useSubjectCredsOnly=falsepermite ao Java buscar a credencial no cache de tickets, em vez de exigir que ela já esteja no Subject corrente. Sem isso, a autenticação falha mesmo com o ticket válido.KRB5CCNAMEaponta o cache de credenciais para o arquivo.java.security.auth.login.configaponta para o arquivo JAAS criado no passo 4.
Uma armadilha frequente: o dbeaver.ini pode não terminar com uma quebra de linha. Se você adicionar a última opção com um simples append, ela gruda na linha anterior e ambas viram lixo ignorado pela JVM. Para evitar, adicione via terminal forçando a quebra:
printf '\n-Djava.security.auth.login.config=/tmp/jaas_dbeaver.conf\n' >> /Applications/DBeaver.app/Contents/Eclipse/dbeaver.ini
Confira que cada opção ficou isolada em sua linha. O cat -A mostra os fins de linha como $, útil para detectar opções grudadas:
cat -A /Applications/DBeaver.app/Contents/Eclipse/dbeaver.ini | tail -6
Passo 6 — Reiniciar e conectar
Encerre o DBeaver por completo. Fechar a janela não basta; o processo precisa morrer para reler o .ini:
pkill -9 -f dbeaver
Durante o diagnóstico, abra o DBeaver pelo terminal em vez do Finder. Assim as mensagens de debug do Kerberos (por causa do debug=true no JAAS) aparecem no terminal:
/Applications/DBeaver.app/Contents/MacOS/dbeaver
Na configuração da conexão SQL Server:
- Host:
sqlserver.exemplo.com— sempre o FQDN, nunca o IP (explicação abaixo) - Porta:
1433(ou a porta usada) - Authentication: se houver opção “Kerberos” no dropdown, selecione-a. Algumas versões do DBeaver não têm essa opção; nesse caso deixe “SQL Server Authentication” e deixe usuário e senha em branco, pois a autenticação será forçada pelas propriedades do driver.
- Driver properties:
authenticationScheme = JavaKerberos
integratedSecurity = true
encrypt = true
trustServerCertificate = true
São integratedSecurity=true e authenticationScheme=JavaKerberos que fazem o driver ignorar usuário/senha e usar o ticket Kerberos. encrypt=true e trustServerCertificate=true lidam com a criptografia da conexão; ajuste trustServerCertificate conforme a política de certificados do seu ambiente (em produção, idealmente, valida-se o certificado em vez de confiar cegamente).
Por que FQDN e não IP
Esse ponto merece atenção porque é causa frequente de falha. No Kerberos, o cliente não envia usuário e senha ao SQL Server; ele pede ao KDC um ticket para um identificador do serviço, o SPN (Service Principal Name), com o formato:
MSSQLSvc/sqlserver.exemplo.com:1433
Esse SPN foi registrado no Active Directory, quando o SQL entrou no domínio, usando o nome do servidor — nunca o IP. Se você informar o IP no Host, o driver tenta montar MSSQLSvc/10.x.x.x:1433, um SPN que não existe no AD, e o KDC responde que não conhece o serviço (erro do tipo “Server not found in Kerberos database”). Por isso o Host precisa ser o FQDN. Se você só conhece o IP, descubra o nome com uma busca reversa: nslookup <ip>.
Uso no dia a dia
O ticket Kerberos expira (tipicamente em torno de 10 horas, conforme a política do domínio). Ao expirar, renove com o comando do passo 3. Para não digitar o comando longo toda vez, crie um alias no ~/.zshrc:
alias kinit-db='KRB5CCNAME=/tmp/krb5cc_dbeaver /opt/homebrew/opt/krb5/bin/kinit seu.usuario@EXEMPLO.COM'
Depois é só rodar kinit-db antes de conectar.
Se quiser remover o ruído do debug depois que tudo funcionar, edite /tmp/jaas_dbeaver.conf e troque debug=true por debug=false (ou remova a linha).
Diagnóstico de erros
Os erros do driver são pouco descritivos, mas cada um aponta para uma etapa específica.
Login failed for user '' (usuário vazio)
A conexão de rede chegou ao SQL, mas nenhuma credencial Kerberos foi enviada. Quase sempre o Java não está lendo o ticket. Verifique: o ticket foi gerado em arquivo com o kinit do MIT (e não no cache API: nativo)? As opções no dbeaver.ini estão depois do -vmargs e cada uma em sua linha? O DBeaver foi reiniciado de fato (pkill -9 -f dbeaver)?
No LoginModules configured for SQLJDBCDriver
Boa notícia parcial: o driver está de fato tentando Kerberos. Ele só não encontrou o bloco JAAS. Verifique: o arquivo /tmp/jaas_dbeaver.conf existe e o bloco se chama exatamente SQLJDBCDriver? A linha -Djava.security.auth.login.config=... foi aplicada no dbeaver.ini sem grudar na anterior?
Server not found in Kerberos database
O SPN do serviço não foi encontrado. Causas típicas: uso de IP em vez de FQDN no Host, ou o SPN do SQL Server não está registrado no AD (nesse caso, é tarefa da equipe que administra o domínio registrar o SPN MSSQLSvc/host:porta para a conta de serviço do SQL).
kinit dá timeout
Não há rota até o KDC. Confirme que a VPN ou o cliente ZTNA está ativo e tunelando. Teste a resolução e a porta:
nslookup dc01.exemplo.com
nc -vz dc01.exemplo.com 88
Se o nc conectar na porta 88, o caminho até o KDC está aberto.
nslookup retorna NXDOMAIN para hosts internos
O DNS interno do domínio não está sendo consultado. Seu sistema está caindo no DNS local em vez do DNS do domínio. Confirme que o túnel (VPN/ZTNA) está encaminhando as consultas internas e que o domínio que você está consultando é o domínio real do AD (que pode diferir do domínio público). Verifique o que o sistema enxerga com scutil --dns.
Resumo do fluxo
/etc/krb5.confcom realm, KDCs e mapeamento de domínio.- MIT Kerberos instalado via Homebrew.
- Ticket gerado em arquivo (
KRB5CCNAME+kinitdo MIT). - Arquivo JAAS com o bloco
SQLJDBCDriverapontando para o ticket. dbeaver.inicom as quatro opções de JVM, depois do-vmargs.- DBeaver reiniciado; conexão com FQDN no Host, usuário/senha em branco e as propriedades Kerberos no driver.
A causa raiz de tudo, que torna o macOS diferente do Windows aqui, são dois detalhes: o cache de ticket precisa estar em arquivo para o Java ler, e o driver precisa de um JAAS apontando para esse arquivo. Resolvidos esses dois, o login de domínio passa a funcionar como no Windows.
