“Session 0 隔离” 是什么?
在Windows XP、Windows Server 2003 或早期Windows 系统时代,当第一个用户登录系统后 服务(Service) 和 应用程序(Application) 是在同一个Session 中运行的(即session 0)。
这种方式显而易见的有很高的风险,“非法”的应用程序能够轻而易举的干扰甚至破坏系统服务的正常运行。
因此从Vista 开始 Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。
“Session 0 隔离”导致的问题
在真实业务中,我们的 A服务 部署是依赖公司提供的集成发布平台。在该平台 windows类型的应用发布是借助 Saltstack工具完成的。由于配置的关系 Saltstack 会以 session 0 去启动A服务;同时作为A服务创建的 子进程 K 也会以 session 0 启动的。
而运行 K 所需的各种环境依赖(比如 GPU相关驱动),都是通过远程桌面登录手动安装的(session 1)。因此在 A 服务去启动 K 进程时,会出现启动失败。
若是通过远程桌面手动启动 A 服务,那么 A 服务和 K 进程就会变成session 1启动。能够正常运行。
突破 Session 隔离
在不考虑安全性的前提下,解决上面遇到的问题就变成了怎么将 A 服务以session 1去启动?
- 最简单的方法就是去调整Saltstack与节点连接的配置,调整为session 1。
- 另外在谷歌上搜索相关的文章,确实有大神给出了解决方案:穿透Session 0隔离
由于改变平台侧的配置会有很多的隐形成本,所以决定从修改服务的启动方式上做调整。即在session 0 中新建用户会话 session 1 再启动服务。
因此 A 服务的启动脚本如下:
function StartService {
# 使用新用户登陆并调用执行计划
$pw = convertto-securestring -AsPlainText -Force -String $env:USER_PSD
$username = -Join($env:COMPUTERNAME,"\",$env:USER_ID)
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$pw
$session = new-pssession -credential
$cred Invoke-Command -Session $session -ScriptBlock {Get-ScheduledTask -TaskName 'A' | Start-ScheduledTask} -AsJob
}
不关键的扩展信息
由于使用的 Saltstack工具 还有一个特殊的配置:如果在部署脚本中直接运行 java -jar会阻塞进程,导致salt无法获取返回值,而超时报错。
因此在启动脚本中并没有执行java -jar 直接启动 java 服务,而是通过触发计划任务,曲线救国。