Ubuntu 16.04上SQL Server 2017 AD认证失败问题求助
我之前帮同事排查过几乎一模一样的问题,这个Login failed. The login is from an untrusted domain and cannot be used with Integrated authentication. (Error: 18452)错误,本质是Linux上的SQL Server依赖Kerberos和AD做集成认证,而你的Kerberos链路或者域信任配置出了问题。结合你已经做了Samba基础配置的前提,给你一步步梳理排查和解决的关键点:
别以为装了Samba就万事大吉,得验证域连接的核心状态:
- 跑
kinit <AD管理员用户名>@<你的AD域全称,比如CONTOSO.COM>,输入密码后如果没有报错,说明Kerberos客户端能正常和AD通信 - 执行
net ads testjoin,必须返回Join is OK,这才证明Ubuntu真的成功加入域了 - 用
getent passwd <某个AD普通用户名>,如果能输出该用户的完整信息(比如UID、GID、家目录),说明Winbind/SSSD已经在同步AD用户数据了
如果以上命令有问题,先解决域加入的基础问题:
- 检查
/etc/resolv.conf,必须把AD域控制器的IP设为首选DNS(绝对不能用公共DNS,不然AD域名解析会失败) - 核对
/etc/krb5.conf,确保default_realm是你的AD域全称,而且realms块里配置了AD服务器的地址
这是最容易踩坑的环节——Linux SQL Server没法自动向AD注册服务主体名称(SPN),必须手动操作:
在AD服务器上注册SPN:用域管理员账号打开PowerShell,执行以下命令(替换成你的实际信息):
# 注册FQDN的SPN setspn -A MSSQLSvc/<Ubuntu服务器FQDN>:1433 <AD服务账号> # 注册短主机名的SPN(兼容老客户端) setspn -A MSSQLSvc/<Ubuntu短主机名>:1433 <AD服务账号>👉 这里的
<AD服务账号>建议专门创建一个AD用户(不要用域管理员),用来作为SQL Server的域身份;<Ubuntu服务器FQDN>必须是AD能识别的完整域名(比如sql01.contoso.com)在Ubuntu上生成Keytab文件:Keytab是SQL Server用来向AD获取Kerberos票据的凭证文件,执行以下步骤:
# 进入ktutil工具 ktutil # 添加AES256加密的凭证(优先用强加密) addent -password -p <AD服务账号>@<AD域全称> -k 1 -e aes256-cts-hmac-sha1-96 # 输入AD服务账号的密码 # 添加RC4加密的凭证(兼容老AD环境) addent -password -p <AD服务账号>@<AD域全称> -k 1 -e rc4-hmac # 再输入一次密码 # 保存Keytab到SQL Server的秘密目录 wkt /var/opt/mssql/secrets/mssql.keytab # 退出ktutil quit然后修改Keytab的权限,确保只有SQL Server服务能读取:
chown mssql:mssql /var/opt/mssql/secrets/mssql.keytab chmod 600 /var/opt/mssql/secrets/mssql.keytab配置SQL Server使用Keytab和SPN:
# 指定Keytab文件路径 /opt/mssql/bin/mssql-conf set network.kerberoskeytabfile /var/opt/mssql/secrets/mssql.keytab # 指定SPN(用之前注册的FQDN版本) /opt/mssql/bin/mssql-conf set network.kerberosservicename MSSQLSvc/<Ubuntu服务器FQDN>:1433 # 重启SQL Server生效 systemctl restart mssql-server
重启后,检查SQL Server服务账号是否拿到了有效的Kerberos票据:
sudo -u mssql klist
如果输出里能看到一个针对MSSQLSvc/<Ubuntu服务器FQDN>:1433的票据,说明Kerberos配置已经成功了。
就算服务器端配置好了,客户端连接也容易出问题:
- 必须用Ubuntu服务器的FQDN连接(比如
sql01.contoso.com),不能用IP或者短主机名,不然SPN匹配不上 - 客户端机器必须加入同一个AD域,或者是信任该域的域;如果是非域机器,要用
runas /user:<AD域>\<用户名> "ssms.exe"启动SSMS,模拟域用户身份连接 - 客户端的DNS也要指向AD服务器,不然没法解析FQDN和找到域控制器
- 时间同步:Kerberos对时间差要求极高,Ubuntu和AD域控制器的时间差不能超过5分钟!用
ntpdate <AD服务器IP>手动同步,或者配置chrony服务自动同步AD时间 - SPN重复:如果其他机器注册了相同的SPN,会导致认证失败,在AD上用
setspn -X检查重复的SPN,删掉多余的 - 加密类型兼容:有些老AD默认禁用了AES256,所以我们之前加了RC4-HMAC作为 fallback,如果还是有问题,可以在
/etc/krb5.conf里把default_tkt_enctypes和default_tgs_enctypes加上rc4-hmac - Winbind/SSSD配置:如果用SSSD,确保
/etc/sssd/sssd.conf里ad_enable_gc = True,而且enumerate = True(这样getent才能拿到AD用户)
如果还是不行,可以开启SQL Server的Kerberos调试日志,看具体错误:
/opt/mssql/bin/mssql-conf set traceflag 7300 on systemctl restart mssql-server
然后查看/var/opt/mssql/log/errorlog里的Kerberos相关日志,里面会有更详细的失败原因(比如SPN找不到、票据过期、加密类型不匹配等)。
内容的提问来源于stack exchange,提问作者JC Frigon

