进程每 7 天失去一次查看网络驱动器的能力 (UnauthorizedAccessException)。找到了有效的解决方案,但为什么有效?

Process loses ability to see network drives (UnauthorizedAccessException) once every seven days. Found solution that works, but WHY does it work?

场景

考虑一个由域控制器和五个 Windows 2016 成员服务器组成的小型 Windows 域。在其中一个成员服务器上有一个我编写的 .NET 程序,它负责启动和停止其他关键的 .NET 进程。

当启动与启动程序位于同一台计算机上的进程时,我使用 Proces.Start(),通过 ProcessStartInfo 对象传递用于该进程的凭据。

但是在 远程 成员服务器上启动进程时,我会这样做:

ConnectionOptions connOpts=new ConnectionOptions{
    Impersonation=ImpersonationLevel.Delegate,
    Authentication= AuthenticationLevel.Default,
    EnablePrivileges=false
};
if(usesCredentials){connOpts.Username=fqu.Username;connOpts.Password=password;}
new ManagementClass(
    new ManagementScope(String.Format("\\{0}\root\cimv2",machineName),connOpts),
    new ManagementPath("Win32_Process"),
    null
).InvokeMethod("Create",new String[]{Utils.DelimitItems(launchArgs,' ')});

当应用第二种方法在远程机器上启动进程时,该进程将正确启动并且 运行。 但恰好 7 天后,该进程失去对域上网络共享的访问权限,在尝试读取或写入 files/directories 时抛出 UnauthorizedAccessException

解决方案

我已经调试了很长时间,但我最终找到了解决方案:

在域控制器上,我导航到:

组策略管理 > 默认域策略 > [编辑] > 策略 > Windows 设置 > 安全设置 > 帐户策略 > Kerberos 策略

在该节点中有一个名为 "Maximum lifetime for ticket renewal" 的键,默认设置为 7 天。将此值增加到更多的天数会增加我的进程可以 运行 而不会失去对网络共享的访问权限的时间长度。

问题

幕后究竟发生了什么?大概远程服务器成功启动进程并告诉它,"Ok, here's the domain account to use and here are the credentials. They're good for seven days." 但是为什么存在这个 7 天的限制,为什么它仅在使用 ManagementClass 时适用?如果我告诉远程服务器做一些更传统的事情,例如启动服务,该服务可以 运行 远远超过 7 天。同样,如果使用 Process.Start() 启动本地进程,它将 运行 的时间远远超过 7 天。那么,这种启动触发对网络共享访问的 7 天限制的进程的特殊方法是什么?

7 天限制不是针对凭据本身,而是针对用于 Kerberos 身份验证的派生 TGT。

这种工作方式或多或少是将信用发送到远程机器,远程机器使用这些信用来请求 TGT。然后,该 TGT 用于向您的网络共享请求服务票证。

TGT 的使用寿命约为 10 小时,最多可以续订 7 天(或根据政策规定)。只要您在 window 之内,您就可以获得该帐户授予您的所有访问权限。一旦 7 天结束,您必须使用信用重新验证以验证该帐户是否仍被允许执行操作。

似乎正在发生的事情是那些信用丢失了,可能在使用后立即被明确删除,因此您永远无法获得新的 TGT。这很可能发生,因为它是作为网络登录而不是交互式登录进入的。启动的服务会在本地保存凭据,以便在必要时查询它们,而不进行网络登录。

如果你需要运行很长时间的东西最好直接在机器上运行一个服务。