请求者的安全注意事项

VSS 基础结构要求 VSS 请求程序(例如备份应用程序)能够充当 COM 客户端和服务器。

充当服务器时,请求者会公开一组可从外部进程调用的 COM 回调接口, (例如编写器或 VSS 服务) 。 因此,请求者需要安全地管理哪些 COM 客户端能够对其进程进行传入 COM 调用。

同样,请求者也可以充当由 VSS 编写器或 VSS 服务提供的 COM API 的 COM 客户端。 特定于请求者的安全设置必须允许从请求方传出 COM 调用到这些其他进程。

管理请求者的安全问题的最简单机制涉及正确选择运行它的用户帐户。

请求者通常需要在管理员组或备份操作员组的成员的用户下运行,或作为本地系统帐户运行。

默认情况下,当请求者充当 COM 客户端时,如果未在这些帐户下运行,则任何 COM 调用都会使用 E_ACCESSDENIED 自动拒绝,甚至无法访问 COM 方法实现。

禁用 COM 异常处理

开发请求者时,将 COM COMGLB_EXCEPTION_DONOT_HANDLE全局选项标志设置为禁用 COM 异常处理。 请务必执行此操作,因为 COM 异常处理可能会掩盖 VSS 应用程序中的致命错误。 屏蔽的错误会使进程处于不稳定且不可预知的状态,这可能导致损坏和挂起。 有关此标志的详细信息,请参阅 IGlobalOptions

设置请求者默认 COM 访问检查权限

请求者需要注意,当其进程充当服务器 ((例如,允许编写器修改备份组件文档) ),他们必须允许来自其他 VSS 参与者(如编写器或 VSS 服务)的传入调用。

但是,默认情况下,Windows进程将仅允许在同一登录会话下运行的 COM 客户端 (SELF SID) 或在本地系统帐户下运行。 这是一个潜在的问题,因为这些默认值不足以用于 VSS 基础结构。 例如,编写器可能作为“备份操作员”用户帐户运行,该用户帐户既不在请求方进程所在的同一登录会话中,也不是本地系统帐户。

为了处理此类问题,每个 COM 服务器进程都可以进一步控制是否允许 RPC 或 COM 客户端执行由服务器实现的 COM 方法,在本例中, (请求者,在本) 例中,使用 CoInitializeSecurity 设置进程范围的“默认 COM 访问检查权限”。

请求者可以显式执行以下操作:

  • 允许所有进程访问请求方进程。

    此选项可能足以满足绝大多数请求者的需求,并且由其他 COM 服务器使用,例如,所有基于 SVCHOST 的Windows服务都已使用此选项,而默认情况下所有 COM+ 服务也是如此。

    允许所有进程执行传入 COM 调用不一定是安全漏洞。 充当 COM 服务器的请求者(与其他所有 COM 服务器一样)始终保留在其进程中实现的每个 COM 方法上对其客户端授权的选项。

    请注意,默认情况下,VSS 实现的内部 COM 回调受到保护。

    若要允许所有进程 COM 访问请求者,可以将 NULL 安全描述符作为 CoInitializeSecurity 的第一个参数传递。 (请注意,必须在整个过程中最多调用一次 CoInitializeSecurity 。有关 CoInitializeSecurity calls.) 的详细信息,请参阅 COM 文档或 MSDN

    以下代码示例演示请求者如何在 Windows 8 和 Windows Server 2012 及更高版本中调用 CoInitializeSecurity,以便与 VSS 兼容,以便与远程文件共享 (RVSS) 兼容:

    // Initialize COM security.
       hr = CoInitializeSecurity(
            NULL,                          //  PSECURITY_DESCRIPTOR         pSecDesc,
            -1,                            //  LONG                         cAuthSvc,
            NULL,                          //  SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
            NULL,                          //  void                        *pReserved1,
            RPC_C_AUTHN_LEVEL_PKT_PRIVACY, //  DWORD                        dwAuthnLevel,
            RPC_C_IMP_LEVEL_IMPERSONATE,   //  DWORD                        dwImpLevel,
            NULL,                          //  void                        *pAuthList,
            EOAC_STATIC,                   //  DWORD                        dwCapabilities,
            NULL                           //  void                        *pReserved3
            );
    

    使用 CoInitializeSecurity 显式设置请求者的 COM 级别安全性时,应执行以下操作:

    • 将身份验证级别设置为至少 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY。 为了提高安全性,请考虑使用 RPC_C_AUTHN_LEVEL_PKT_PRIVACY
    • 将模拟级别设置为 RPC_C_IMP_LEVEL_IMPERSONATE
    • 将遮盖安全功能设置为 EOAC_STATIC。 有关遮盖安全性的详细信息,请参阅 “隐藏”。

    以下代码示例演示请求者如何在 Windows 7 和 Windows Server 2008 R2 及更低版本 (或 Windows 8 和 Windows Server 2012 及更高版本中调用 CoInitializeSecurity(如果不需要 RVSS 兼容性)) :

    // Initialize COM security.
       hr = CoInitializeSecurity(
            NULL,                          //  PSECURITY_DESCRIPTOR         pSecDesc,
            -1,                            //  LONG                         cAuthSvc,
            NULL,                          //  SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
            NULL,                          //  void                        *pReserved1,
            RPC_C_AUTHN_LEVEL_PKT_PRIVACY, //  DWORD                        dwAuthnLevel,
            RPC_C_IMP_LEVEL_IDENTIFY,      //  DWORD                        dwImpLevel,
            NULL,                          //  void                        *pAuthList,
            EOAC_NONE,                     //  DWORD                        dwCapabilities,
            NULL                           //  void                        *pReserved3
            );
    

    使用 CoInitializeSecurity 显式设置请求者的 COM 级别安全性时,应执行以下操作:

    • 将身份验证级别设置为至少 RPC_C_AUTHN_LEVEL_CONNECT。 为了提高安全性,请考虑使用 RPC_C_AUTHN_LEVEL_PKT_PRIVACY
    • 将模拟级别设置为 RPC_C_IMP_LEVEL_IDENTIFY ,除非请求方进程需要允许模拟与 VSS 无关的特定 RPC 或 COM 调用。
  • 仅允许指定进程访问以调用请求方进程。

    COM 服务器 ((如调用 CoInitializeSecurity 且具有非 NULL 安全描述符)的请求者) ,因为第一个参数可以使用描述符来配置自身,以便仅接受属于特定帐户集的用户的传入调用。

    请求者必须确保在有效用户下运行的 COM 客户端有权调用其进程。 在第一个参数中指定安全描述符的请求者必须允许以下用户对请求程序进程执行传入调用:

    • Local System

    • Local Service

      Windows XP:Windows Server 2003 之前不支持此值。

    • Network Service

      Windows XP:Windows Server 2003 之前不支持此值。

    • 本地管理员组的成员

    • 本地备份运算符组的成员

    • 在下面的注册表位置指定的特殊用户,其“1”作为其REG_DWORD值

显式控制对请求者的用户帐户访问权限

在某些情况下,限制对作为本地系统运行的进程或本地管理员或本地备份运算符组下运行的进程的访问权限可能过于严格。

例如,指定的请求程序进程通常不需要在管理员或备份操作员帐户下运行。 出于安全原因,最好不要人为地提升进程特权以支持 VSS。

在这些情况下,必须修改 HKEY_LOCAL_MACHINE\SYSTEMCurrentControlSetServicesVSSVssAccessControl\\\\ 注册表项,以指示 VSS 指定用户安全运行 VSS 请求程序。

在此密钥下,必须创建与要授予或拒绝访问的帐户同名的子项。 此子项必须设置为下表中的值之一。

含义
0 拒绝用户对编写者和请求者的访问权限。
1 向用户授予对编写器的访问权限。
2 向用户授予对请求者的访问权限。
3 向用户授予对编写者和请求者的访问权限。

 

以下示例授予对“MyDomain\MyUser”帐户的访问权限:

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         Services
            VSS
               VssAccessControl
                  MyDomain\MyUser = 2<dl>
<dt>

                  Data type
</dt>
<dd>                  REG_DWORD</dd>
</dl>

此机制还可用于显式限制允许的用户运行 VSS 请求程序。 以下示例将限制来自“ThatDomain\Administrator”帐户的访问:

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         Services
            VSS
               VssAccessControl
                  ThatDomain\Administrator = 0<dl>
<dt>

                  Data type
</dt>
<dd>                  REG_DWORD</dd>
</dl>

用户 ThatDomain\Administrator 将无法运行 VSS 请求程序。

执行系统状态的文件备份

如果请求者通过备份单个文件而不是对备份使用卷映像来执行系统状态备份,则必须调用 FindFirstFileNameWFindNextFileNameW 函数来枚举位于以下目录中的文件的硬链接:

  • Windows\system32\WDI\perftrack\
  • Windows\WINSXS\

这些目录只能由管理员组的成员访问。 因此,此类请求者必须在系统帐户或作为管理员组成员的用户帐户下运行。

Windows XP 和 Windows Server 2003:在 Windows Vista 和 Windows Server 2008 之前,不支持 FindFirstFileNameWFindNextFileNameW 函数。