SSH@0执行SQL脚本失败:仅从SQL节点报匿名登录失败错误
问题描述
通过DevOps的SSH任务执行PowerShell脚本调用SQL脚本时失败,报错:
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'
该任务在主SQL节点执行成功,但在从SQL节点上失败。手动通过DevOps代理SSH到从SQL服务器执行,同样报此错误。
使用的SSH任务YAML配置:
- task: SSH@0 displayName: 'Create Scheduled Job' inputs: sshEndpoint: 'ssh_Server2' # 替换为你的SSH服务连接名称 runOptions: 'commands' commands: | pwsh -File "$(PackagePath)\RunSQLScripts.ps1" -dbName msdb -dbServer Server2 -sqlScript "$(PackagePath)\Scripts\Create_Scheduled_Job.sql"
补充信息:
- SSH服务以Local System账户运行,仅启用
publicKeyAuthentication,禁用了密码认证 CopyFilesOverSSH@0任务连接同一服务器完全正常- 直接在SQL服务器上以任意用户运行脚本均成功,仅通过代理SSH执行时出问题
对应的PowerShell脚本RunSQLScripts.ps1代码:
param ( [Parameter(Position=0,Mandatory=$true, HelpMessage="数据库名称")] [string]$dbName, [Parameter(Position=1,Mandatory=$true, HelpMessage="数据库服务器名称和实例")] [string]$dbServer, [Parameter(Position=2,Mandatory=$true, HelpMessage="SQL脚本路径")] [string]$sqlScript ) $ErrorActionPreference = "Stop" Write-Output "################## 执行SQL脚本任务 ##############" Write-Output "数据库服务器: $dbServer" Write-Output "数据库名称: $dbName" Write-Output "脚本路径: $sqlScript" try { Write-Output "########## 在SQL服务器 $dbServer\\$dbName 上执行脚本" invoke-sqlcmd -inputfile "$sqlScript" -serverinstance "$dbServer" -database "$dbName" -TrustServerCertificate | Out-String Write-Output "########## 已在SQL服务器 $dbServer\\$dbName 上执行脚本 $sqlScript" } catch { Write-Warning -Message "########## 执行SQL脚本时出错" Write-Error -Message "$($_.Exception.Message)" } Write-Output "################## 任务结束 ##############"
解决方案
1. 解决Kerberos双跳认证问题
当通过SSH以Local System账户登录从SQL服务器后,再连接SQL实例会触发Kerberos双跳限制:Local System账户无法将身份凭据传递到SQL实例,导致默认使用匿名登录。
处理步骤:
- 在AD中找到从SQL服务器的计算机账户,右键进入「属性」→「委派」
- 选择「信任此计算机来委派指定的服务」,添加SQL实例的服务主体(格式通常为
MSSQLSvc/<SQL服务器FQDN>:<端口/实例名>) - 用
setspn -L <SQL服务器名>检查已注册的SPN,确保SQL实例的SPN已正确配置
2. 改用SQL身份认证
若无法配置Kerberos委派,可修改PowerShell脚本,直接使用SQL账户连接实例:
invoke-sqlcmd -inputfile "$sqlScript" -serverinstance "$dbServer" -database "$dbName" -Username "SQL账户名" -Password "SQL账户密码" -TrustServerCertificate | Out-String
建议在DevOps变量组中存储密码,避免硬编码。
3. 更换SSH服务运行账户
将SSH服务的运行账户从Local System改为具备SQL访问权限的域账户或本地管理员:
- 在从SQL服务器的服务管理器中找到OpenSSH服务,右键进入「属性」→「登录」
- 选择「此账户」,输入有权访问SQL实例的账户凭据,重启SSH服务后重新测试
4. 检查从SQL节点的SQL权限
确认从SQL实例允许对应账户访问:
- 打开SSMS连接从SQL实例,进入「安全性」→「登录名」
- 检查
NT AUTHORITY\SYSTEM(Local System对应的登录名)是否存在,且拥有msdb数据库的作业创建权限 - 若使用域账户登录SSH,需确保该域账户在SQL实例中有对应的登录名和权限
内容的提问来源于stack exchange,提问作者DanielTamil
相关产品推荐
相关产品推荐

