SQL Server用户-计算机一对一权限关联及特定登录错误屏蔽咨询
问题解决思路与实操方案
问题根源先理清楚
你遇到的Error: 18456, Severity: 14, State: 5,就是SQL Server找不到对应登录账户的错误——这里是客户端PC的域计算机账户(domain\computer name)在发起连接,但你没给这个账户建SQL登录。应用本身用用户账户连接正常,说明PC的计算机账户在发起额外的连接请求,大概率是应用的某些后台组件、系统服务或者驱动触发的。
针对你诉求的落地方案
1. 首选:实现用户与PC的一对一绑定访问
要限制主域的特定用户只能从指定子域PC连接SQL Server,有两种靠谱的实现方式:
- 登录触发器:建一个服务器级的登录触发器,在用户登录时同时验证登录账户和客户端的主机名/IP。示例代码:
注意:触发器需要CREATE TRIGGER RestrictUserToAssignedPC ON ALL SERVER WITH EXECUTE AS 'sa' FOR LOGON AS BEGIN -- 这里维护允许的用户-PC映射关系,可换成表查询实现批量管理 IF EXISTS ( SELECT 1 FROM sys.dm_exec_sessions WHERE session_id = @@SPID AND ( -- 匹配主域用户+子域PC主机名 (login_name = 'maindomain\user01' AND host_name = 'sub-pc-01.sub-domain.maindomain') -- 或者用IP(如果主机名解析不稳定) OR (login_name = 'maindomain\user01' AND client_net_address = '10.0.0.50') ) ) RETURN; -- 符合条件,允许登录 ELSE ROLLBACK; -- 不符合,拒绝登录 END;CONTROL SERVER权限,一定要先在测试环境测,别把管理员给锁外面;如果是多个用户和PC,建个映射表存对应关系,触发器查这个表就行,维护起来更方便。 - 域组+SQL登录(半绑定):建一个域安全组,把指定用户和PC的计算机账户加进去,然后给这个组建SQL登录并授权。但这是组内用户和PC都能访问,不是严格一对一,适合批量场景。
2. 移除PC权限,忽略特定错误日志
不想给PC加权限,又要屏蔽这类错误日志,可以这么搞:
- 用扩展事件定向收集日志:默认错误日志没法直接过滤,但可以建一个扩展事件会话,只收集非子域PC的18456错误,同时把默认错误日志里的这类错误定期清理——写个PowerShell脚本筛选并删除包含
sub-domain.maindomain和Error: 18456, Severity: 14, State: 5的日志条目,然后用SQL Server代理定时跑这个脚本。 - 日志系统层面过滤:如果你们用了ELK、Splunk这类日志工具,在采集阶段直接过滤掉子域PC的这类错误就行,不影响SQL Server本身的日志生成,也保留了其他登录失败的审计记录。
3. 只保留用户权限,彻底消除PC登录尝试
要从根上解决日志问题,得找到PC发起连接的源头:
- 查
sys.dm_exec_sessions和sys.dm_exec_connections视图,看program_name字段,定位是应用的哪个组件、系统服务还是第三方工具在发起PC账户连接。 - 直接找应用供应商,问能不能配置应用,禁止用计算机账户发起连接,只用用户账户连接——要是能改配置,这才是最省心的办法。
关于子域PC加权限的风险
你提到应用侧有访问控制,只允许指定用户访问:
- 如果应用的控制真的严格(比如必须先过用户身份验证才会连数据库,而且来宾账户、本地账户绕不过),那给PC加数据库权限的风险其实很低——就算PC有数据库权限,没有应用的用户授权也没法碰数据。
- 周一跟供应商确认的时候,重点问两个点:
- 有没有绕过用户验证的路径(比如来宾账户直接连数据库)
- PC账户的连接请求是不是应用正常运行必须的,能不能关掉
额外提醒
- 登录触发器一定要先在测试环境验证,留好应急方案(比如用DAC连接删触发器);
- 扩展事件是SQL Server 2012及以后的功能,比传统跟踪轻量,性能影响小;
- 清理错误日志的时候,要保留足够的审计记录,别违反合规要求。
内容的提问来源于stack exchange,提问作者JeffTheDBA
相关产品推荐
相关产品推荐

