返回

Docker Linux Java Kerberos SQL Server 连接问题排查

java

Docker Linux 下 Java Kerberos 连接 SQL Server 问题排查

在 Docker Linux 环境下,通过 Java Kerberos 连接 SQL Server 常常会遇到“Cannot locate default realm”的错误。这种问题可能源于 Kerberos 配置在容器中的差异,或者是 Java 应用本身的环境设置。以下将对常见原因进行分析,并提供相应的解决方案。

问题原因分析

当 Java 应用尝试使用 Kerberos 协议进行身份验证时,它依赖于 krb5.conf 文件来查找 Kerberos 域(realm)信息。该文件定义了默认的域、KDC(密钥分发中心)位置和其他相关参数。如果在 Docker 容器中未能正确配置 krb5.conf 文件,或 Java 应用未正确读取配置信息,就可能出现无法定位默认域的错误。以下是一些常见的情况:

  1. krb5.conf 文件路径不正确 : Java 应用启动时,java.security.krb5.conf 系统属性应该指定了 krb5.conf 文件的确切位置,但路径可能不正确或在容器内部不可访问。
  2. krb5.conf 配置缺失或错误 : 即使文件路径正确,krb5.conf 文件本身的内容可能不完整,或者包含了不准确的 realm 信息,比如 default_realm 配置遗漏、错误,或者 [realms] 中 realm 定义不正确。
  3. Java 系统属性未设置或设置不正确: 运行 Java 应用时,-Djava.security.krb5.conf 系统属性未设置或设置值和 krb5.conf文件位置不一致, 或未设置其它和 kerberos 认证相关的 Java 系统属性,导致程序读取不到 kerberos 的配置信息。
  4. 域名解析问题: 容器内部可能存在网络解析问题,无法根据 krb5.conf 中指定的 KDC 主机名查找到对应的 IP 地址。

解决方案

方案一: 正确指定 krb5.conf 文件路径

确保 Java 应用能够正确找到 krb5.conf 文件,使用 -Djava.security.krb5.conf 指定该文件路径,检查该文件是否在 docker container内部存在。
使用docker exec -it <container_id> bash进入 docker container, 然后 ls -l /opt/krb5.conf 确保 /opt/krb5.conf 文件存在并且能读取。

java -jar app.jar  -Djava.security.krb5.conf=/opt/krb5.conf -Djava.security.auth.login.config=/opt/jaas.conf -Djavax.security.auth.useSubjectCredsOnly=false

操作步骤:

  1. 确认 krb5.conf 文件位于容器的 /opt/krb5.conf 目录。
  2. 在运行 Java 应用时,使用 -Djava.security.krb5.conf=/opt/krb5.conf 明确指定该文件的路径。

方案二:检查并修正 krb5.conf 配置

仔细检查 krb5.conf 文件中的 realm 和 KDC 配置,确保所有内容均正确无误。确保 [libdefaults] 段落中包含 default_realm = YOUR_REALM 的配置项,并且 [realms][domain_realm] 中包含正确的信息。YOUR_REALM 需要替换为你真实的 kerberos realm。
例如:

[libdefaults]
    default_realm = US.TEST.COM
    dns_lookup_kdc = true
    dns_lookup_realm = true
    ticket_lifetime = 86400
    renew_lifetime = 604800
    forwardable = true
    default_tgs_enctypes = rc4-hmac
    default_tkt_enctypes = rc4-hmac
    permitted_enctypes = rc4-hmac
    udp_preference_limit = 1
[realms]
    US.TEST.COM = {
      kdc = crldap1.us.test.com
      admin_server = crldap1.us.test.com
}

[domain_realm]
  .us.test.com = US.TEST.COM
  us.test.com = US.TEST.COM

操作步骤:

  1. 检查 default_realm 是否被正确设置。
  2. 检查 [realms] 部分, 确保 KDC 配置项正确。
  3. 确保 [domain_realm] 正确将域名映射到 realm 。

方案三:确认 Java 系统属性配置正确

除了 -Djava.security.krb5.conf 系统属性, 还有 java.security.auth.login.configjavax.security.auth.useSubjectCredsOnly 这些和 java kerberos 认证有关的属性。确保 java.security.auth.login.config 指向正确路径下的jaas.conf, 并按照实际需要设置 javax.security.auth.useSubjectCredsOnly 的值,一般可以设置为false.

示例:

java -jar app.jar -Djava.security.krb5.conf=/opt/krb5.conf -Djava.security.auth.login.config=/opt/jaas.conf  -Djavax.security.auth.useSubjectCredsOnly=false

操作步骤:

  1. 确认系统属性-Djava.security.auth.login.config 指定正确的文件路径。
  2. 根据情况,设定 javax.security.auth.useSubjectCredsOnly的值,多数情况设置为false 即可。

方案四:网络连通性和域名解析

容器的网络配置如果未配置正确,可能导致无法连接 KDC。请检查容器的网络设置和 KDC 地址解析情况,确保能够访问 Kerberos 服务器, 可以通过 ping crldap1.us.test.com 命令确认域名解析是否正常,也可以尝试直接使用IP地址测试网络连通性。

操作步骤:

  1. 使用 ping crldap1.us.test.com测试域名是否可解析。
  2. 如果域名不可解析,检查/etc/hosts文件或者网络配置。
  3. 检查网络是否允许访问kdc。

安全提示

  1. 不要将 Kerberos 密钥文件存储在容器镜像中。最好使用卷挂载或环境变量等方式,在运行时将密钥文件传递给容器。
  2. 仔细审查 Kerberos 配置文件的权限,确保只有需要访问该文件的人才能访问它。
  3. 使用 kinit 等工具验证 krb5.conf 是否配置正确。
  4. 使用 tcpdump 工具抓包分析网络层是否存在问题。

资源链接

请依据你的实际环境进行相应调整,以便解决该问题。这些方法涵盖了常见的配置问题,应当可以帮助你定位问题并最终成功连接到SQL Server数据库。