开发者社区> 嗯哼9925> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

SQL Kerberos的原理及实验

简介:
+关注继续查看

参考文献

Microsoft SQL Server企业级平台管理实践

Kerberos Explained

Kerberos (protocol)wiki

正文

这一周一直在研究kerberos的原理,并做了一些实验,现在做一下总结。

首先我们要知道,SQL Server中的验证机制。SQL Server有两种验证机制,一种是windows验证,还有一种是SQL Server验证,这也就对应了两种用户类型,即SQL Server自己的用户账号和Windows用户账号。

对于SQL Server账号,SQL Server会对用户发过来的用户名与密码进行核对(比如我们安装数据库是自动创建的sa账号就是sql server账号)。只要正确,认证就可以通过。这个过程比较简单,一般不会出问题。

对于Windows账号,SQL Server需要借助Windows来帮助完成认证过程。如果这个认证过程出现问题,则SQL Server会出错。Windows用户认证机制比SQL Server认证要复杂得多,不但牵涉SQL Server服务器和客户端,还要牵涉域服务器。我们在安装SQL Server的时候要求我们添加windows账户,我们一般添加的都是当前的本机账户。

SQL Server内部,对SQL Server账号和Windows账号的处理有所不同。对Windows账号,SQL Server依赖于Windows做身份认证,自己无须保存和维护用户密码信息。对SQL Server账号,SQL Server自己负责用户认证工作,所以需要自己来保存和维护用户密码。像Windows一样,SQL Server只保存密码经过加密算法以后的hash值,而不保存密码的原文。所以管理员可以直接修改密码,但是无法知道密码的原文是什么。

Windows认证是一个相对复杂的机制,它至少需要三方的参与:SQL Server、客户端和域控制器(Domain Controller),因此在后面的实验中会创建三台虚拟机,分别担任DC,Client和ServerWindows认证技术有两种,NTLMKerberos。这两种方法都能够完成用户认证。使用哪一种方法不是客户端应用指定的,也不是SQL Server自己决定的。在SQL Server客户端申请用户认证的时候,会去调用Windows认证API,根据当时Windows API返回值决定使用哪种方法。

接下我们直接进入主题,讲讲kerberos是如何验证的。我们可以参考Kerberos Explained 中的kerberos连接原理图,如下图所示:

从上面可以看出,kerberos连接一共有六步,我分别介绍这六步主要做了哪些工作。

  1. 当客户端登录的时候,会将自己的用户名发送给KDC中的Authentication Service(AS),并申请一个TGT,一般情况下KDC是在Domain Controller(DC)上面的。
  2. 如前面提到的,DC中不保存用户明文密码的,只保存了密码的hash值,所以AS将该用户的TGT用其密码hash值进行加密,并将这个加密后的TGT传送给客户端。客户端可以使用自己的密码hash解密得到TGT,如果密码hash错误将得不到TGT。所以AS的作用是保证客户端的用户不是假冒的。
  3. 当客户端申请链接网络中的服务时(可以有很多类型的服务,比如SQL Server,Sharepoint等),客户端将自己的TGT,要访问服务的Server Principal Name(SPN)发送给TGS,申请用于访问服务的Service Ticket。
  4. TGS验证是否只有一个服务账户注册过这个SPN,如果是的话,那么就将这个SPN用服务账户的信息进行加密,然后将这个Service Ticket返回给客户端。
  5. 客户端将要访问服务的Service Ticket发送给服务端,如果服务端能够用自己的账户名正确解密Serice Ticket,那么就建立连接,所以从这里我们看到,TGS是为了保证服务器端不是假冒的,避免用户登录钓鱼网站。
  6. 服务器端发送session 给客户端,表明建立连接

以上就我我对kerberos连接的理解。

PS:2012-8-17

上面对于kerberos连接的理解过于简单,可以参考:

How the Kerberos Version 5 Authentication Protocol Works: Logon and Authentication

还可以参考我的另外一篇博客:Kerberos连接过程

SQL Server中配置Kerberos

SQL Server在每次启动的时候,都会去尝试用自己的启动账号注册SPN。但是在Windows域里,默认普通机器账号有权注册SPN,但是普通域用户账号是没有权利注册SPN的。这就会导致这样一个现象,SQL Server如果使用“Local System account”来启动,Kerberos就能够成功,因为SQL Server这时可以在DC上注册SPN。如果用一个域用户来启动,Kerberos就不能成功,因为这时SPN注册不上去。

解决的方法之一,当然可以使用工具SetSPN -S来手动注册SPN。但是这不是一个最好的方法,毕竟手工注册不是长久之计。如果SPN下次丢了,又要再次手动注册。所以比较好的方法,是让SQL Server当前的启动账号有注册SPN的权力。要在DC上为域账号赋予“Read servicePrincipalName”和“Write serverPrincipalName”的权限即可。讲解如何配置kerberos。

步骤1

使用msft\sanzhang这个域账户启动Machine A,在Machine A中使用local system账户启动sql server服务,这样在服务启动的时候,就会自动注册spn。我们通过在SSMS中输入如下的存储过程:

sp_readerrorlog 0,1,'spn'

查看到

LogDate 

ProcessInfo 

Text

2012-08-10 00:09:22.980

Server 

The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/SANZ-W7.msft.com ] for the SQL Server service.

2012-08-10 00:09:22.980

Server

The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/SANZ-W7.msft.com:1433 ] for the SQL Server service.

步骤2

使用msft\wuwang域账户启动Machine B,并且同时使用这个域账户启动sql server服务。因为域账户没有权限注册SPN,所以在服务启动以后,查看errorlog,

sp_readerrorlog 0,1,'spn'

得到如下结果:

LogDate 

ProcessInfo 

Text

2012-08-10 00:08:57.890

Server 

The SQL Server Network Interface library could not register the Service Principal Name (SPN) for the SQL Server service. Error: 0x2098, state: 15. Failure to register an SPN may cause integrated authentication to fall back to NTLM instead of Kerberos. This is an informational message. Further action is only required if Kerberos authentication is required by authentication policies.

Troubleshooting可以参考The SQL Network Interface library was unable to register SPN

此时我们要为域账户添加注册spn的权限,具体方法如下:

在DC上运行工具“adsiedit.msc”,在“ADSI edit”里,展开“Domain”—“DC=XXXX,DC=XXX”(这里是域的名字)—“CN=Users”—“CN=wuwang”,打开这个用户的属性,按照如下图所示的操作添加“Read servicePrincipalName”和“Write serverPrincipalName”的权限。

假如machine B不使用域账户登录,就不用这么麻烦了。配置完上述权限以后,重启服务就可以看到自动注册SPN了。

步骤3

打开SSMS,在machine B中的sql server实例中添加login,记得是添加windows authentication的login,我们这里要添加的就是sanzhang这个账户。

之前我们一直思考kerberos如何控制账户访问呢,是不是域里面的所有账户都可以访问呢?这里就有答案了。只有被instance添加到windows authentication中的login用户才可以连接数据库,而具体访问数据库的权限还是在sql server里面配置的。

步骤4

在machine A上面使用sanzhang 这个域账户,连接 machine B上面的数据库实例,SSMS中的数据库连接字符串是Tcp:MACHINEB\,登录账户是msft\sanzhng。成功连接到machine B上面的数据库实例

步骤5

为了验证使用的是kerberos,可以使用如下查询:

SELECT auth_scheme FROM sys.dm_exec_connections WHERE session_id = @@spid ;

查询结果如下图所示:

 

 本文转自xwdreamer博客园博客,原文链接:http://www.cnblogs.com/xwdreamer/archive/2012/08/11/2633958.html,如需转载请自行联系原作者

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
VS2017调用SQL server 2019 和C++连接语句字符串
VS2017调用SQL server 2019 和C++连接语句字符串
0 0
函数计算 Python 连接 SQL Server
函数计算 Python 连接 SQL Server 自制脑图
0 0
SQL Server 2000 函数使用---CAST 和 CONVERT
日期格式样式,借以将 datetime 或 smalldatetime 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型);或者字符串格式样式,借以将 float、real、money 或 smallmoney 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型)。
0 0
【Sql Server】进阶之行数据转为列显示
在开发系统维护阶段,经常需要进行各种数据统计,各种报表之类的。 这个时候,行数据转数据显示就发挥作用了。 场景:行数据的某列值想作为字段列显示
0 0
【Sql Server】时间转换和查询时间范围查询不正确的原因
最近在做时间方法封装的时候发现了一个问题! 如果sql语句输出的时间字段转为了字符串输出,那么在使用此字段作为时间范围筛选时发现无效了,没法过滤对应的时间范围内记录
0 0
【Sql Server】基础之统计库龄语句,仅作为语句使用
知识点的综合使用 分组、数据转换、Case when then、max、min、count、sum、left join多表关联等知识点
0 0
【Sql Server】sql语句文件组分区函数分组方案对应分区表的简单步骤
本篇文章中,主要讲讲sql server数据库中通过sql语句方式对组分区函数的使用 在实际项目中,sql server数据库中有分区的概念,因为在一个表存在大量数据的情况下,需要通过分区方式保存数据来提供查询性能
0 0
【Sql Server】存储过程通过定时执行添加记录作业
通过上篇了解了什么是存储过程,创建存储过程的方法,以及调用存储过程的方法 本次将通过数据库中的作业功能,进行定时执行存储过程,这样就可以完成我们刚开始假设的场景
0 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
SQL Sever迁移PG经验
立即下载
Blink SQL关键技术及实现原理
立即下载
MaxCompute SQL计算成本调优以及优化方法
立即下载