3

我在 .Net 中有一个应用程序,它为其他应用程序执行各种管理/配置。我需要能够停止和启动应用程序池。我已经实现了这一点,但前提是我将应用程序池作为本地系统运行(这通常被认为是一个坏主意)。

最初我使用 Process.Start 启动 appcmd.exe(使用适当的 ProcessStartInfo 对象),但这最终导致我的退出代码为 -1073741502,进一步的研究表明我需要使用 windows SDK 进行调试,因为它与程序集未加载,所以我在命名空间中发现了一个更简单的解决方案Microsoft.Web.Administration

我使用下面的代码,但它似乎要求运行它的 AppPool 具有本地系统的身份(否则我会得到System.UnauthorizedAccessException) - 有没有办法使用特权较低的帐户启动/停止(我更喜欢使用应用程序身份) - 虽然暂时提升权限也是可以接受的。

    Dim serverManager As New ServerManager()
    Dim applicationPoolCollection As ApplicationPoolCollection = serverManager.ApplicationPools

    For Each applicationPool As ApplicationPool In applicationPoolCollection

        If applicationPool.Name = appPoolName Then
            applicationPool.Stop()
            applicationPool.Start()
        End If

    Next

我已将自定义帐户设置为身份,但我无法确定该用户需要的最小 ACL。作为测试,我将用户添加到本地管理员组,但仍然得到System.UnauthorizedAccessException- 这表明我需要为用户配置特定权限,但我不确定这是什么或如何做。任何人都可以帮忙吗?

问题也在这里解释

4

2 回答 2

4

您可以这样做的唯一方法是,如果用于运行代码的帐户(使用 Microsoft.Web.Administration)具有在 IIS 中执行“运行时操作”的正确权限,并且默认情况下仅包括管理员和 SYSTEM,并且正如您正确指出的那样,通常从 Web 公开该级别的权限是一个坏主意。

相反,您可能应该做的是创建一个应用程序池或其他方式以高权限运行,但确保只能在本地访问(例如使用 IP 和域限制)并使用额外级别的授权检查(例如例如只允许从应用程序调用),并且被限制为运行尽可能少的代码和所需的最小表面,例如仅回收属于用户的池等。这样,如果您的 Web 应用程序受到损害损害将受到更多限制。

现在,出于好奇……以下内容是“不受支持的”,因此请不要使用它,而只是为了提供信息而提供它。
我们在ServerManager中用于读取配置的 API 称为AHADMIN,您可以“破解足以读取配置”,例如,如果您的 ACL 如下:

Cd C:\Windows\System32\inetsrv\config  
icacls . /grant yourUser:(R)  
icacls redirection.config /grant yourUser:(R)  
icacls applicationHost.config /grant yourUser:(R)  

从那时起,您将能够与该用户一起读取配置。知道此时加密属性仍然无法读取,因为加密密钥也受到单独保护,您可能永远不应该更改那里的 ACL,但其他所有内容都将是可读的(除了运行时属性,如状态等)。您永远不应该允许对非特权帐户进行写访问,因为这很容易允许提升特权(例如,他们可以创建一个以 SYSTEM 身份运行的应用程序池并将其链接到现在可以以 SYSTEM 身份运行代码的随机目录)。

现在,回到运行时状态,为此我们使用我们称为RSCA(运行时状态和控制 API)的 API,并且它本身也受到保护,只能以 SYSTEM 或管理员身份运行,尽管您可能会找到一种方法破解它,改变它也是一个坏主意。但长话短说,这不受支持,您可能很容易导致系统出现问题。

于 2012-11-14T16:18:57.380 回答
1

使用@CarlosAg 答案,以下解决方案有效:

  1. 创建一个新用户并将其放入管理员组

  2. 创建一个 Web 服务来运行重新启动代码,将其放入以您创建的用户身份运行的自己的应用程序池中(配置适当的应用程序池属性,例如队列长度等)

    一个。将以下代码放入您的 Web 方法(或 begin_reqest)中以防止它被外部调用(我认为在 IIS 中也有其他方法可以做到这一点,但这是我发现的最快的方法)

    湾。在您认为合适的情况下向 Web 服务代码添加额外的身份验证(我们有一个我可以使用的单点登录服务)。

  3. 从在 ApplicationIdentity 下的应用程序池中运行的网站引用此服务

这行得通。

代码:

     If Not HttpContext.Current.Request.IsLocal Then
         Const msg As String = "Only local requests are allowed"
         log4net.LogManager.GetLogger(GetType(Global_asax)).Fatal(msg)
         Throw New Exception(msg)
     End If
于 2012-11-15T14:04:27.617 回答