作者 :Saad Ladki
介绍
本文档概述了为 IIS 7.0 及更高服务器设置应用程序池和辅助进程隔离所需的步骤。 应用程序池隔离需要保护 WAS(IIS 本地系统进程)需要访问的数据。 此数据的示例是应用程序池密码。 另一方面,辅助进程隔离需要保护应用程序池标识需要访问的数据。 此数据的示例是匿名用户帐户密码。
先决条件
为了帮助简化此过程,提供了两段示例代码:
- 在 machine.config中创建新的 RSA 加密提供程序。
- 在 machine.config中设置默认提供程序的名称。
最后的先决条件部分将指导你设置四个将在后续主题中使用的用户帐户。
创建新的 RSA 加密提供程序应用程序
打开 Windows 记事本,在所选名为 createProvider.cs 的目录中创建一个文件,其中包含以下 C# 代码:
using System; using Microsoft.Web.Administration; using System.Configuration; namespace testingEncryption { public class createProvider { public static void Main(string[] args) { String keyContainerName = args[0]; String description = args[1]; String providerName = args[2]; System.Configuration.Configuration machineConfig = System.Configuration.ConfigurationManager.OpenMachineConfiguration(); System.Configuration.ProviderSettings settings = new System.Configuration.ProviderSettings(providerName, "System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); settings.Parameters["description"] = description; settings.Parameters["keyContainerName"] = keyContainerName; settings.Parameters["cspProviderName"] = String.Empty; settings.Parameters["useMachineContainer"] = "true"; settings.Parameters["useOAEP"] = "false"; settings.Parameters["name"] = providerName; ProtectedConfigurationSection pcSection = (System.Configuration.ProtectedConfigurationSection)machineConfig.GetSection ("configProtectedData"); pcSection.Providers.Add(settings); machineConfig.Save(); } } }
接下来,启动提升的命令提示符:
- 单击“ 开始 ”菜单。
- 右键单击 命令提示符。
- 选择“ 以管理员身份运行”。
在命令提示符窗口中,导航到保存 createProvider.cs 文件的位置,并运行以下命令来编译代码:
%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\csc.exe /reference:%SystemRoot%\System32\inetsrv\Microsoft.Web.Administration.dll createProvider.cs
此步骤现已完成。
创建应用程序以更改默认提供程序
打开 Windows 记事本,在所选名为 setProvider.cs 的目录中创建一个文件,其中包含以下 C# 代码:
using System; using Microsoft.Web.Administration; using System.Configuration; namespace testingEncryption { public class setProvider { public static void Main(string[] args) { String provider = args[0]; // example: DataProtectionConfigurationProvider System.Configuration.Configuration machineConfig = System.Configuration.ConfigurationManager.OpenMachineConfiguration(); ProtectedConfigurationSection pcSection = (System.Configuration.ProtectedConfigurationSection)machineConfig.GetSection("configProtectedData"); string oldEncryptionProviderName = pcSection.DefaultProvider; Console.WriteLine("The default provider is currently: " + oldEncryptionProviderName); Console.WriteLine("Changing the default provider to: " + provider); pcSection.DefaultProvider = provider; machineConfig.Save(); } } }
接下来,启动提升的命令提示符:
- 单击“ 开始 ”菜单。
- 右键单击 命令提示符。
- 选择“ 以管理员身份运行”。
在命令提示符窗口中,导航到保存 setProvider.cs 文件的位置,并运行以下命令来编译代码:
%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\csc.exe /reference:%SystemRoot%\System32\inetsrv\Microsoft.Web.Administration.dll setProvider.cs
此步骤现已完成。
创建用户帐户
在此步骤中,我们将创建四个新的用户帐户,该用户帐户将在整个文档中使用。
若要开始,请使用以下步骤打开在管理权限下运行的命令行界面窗口:
- 单击“ 开始 ”菜单。
- 右键单击 命令提示符。
- 选择“ 以管理员身份运行”。
- 在命令窗口中,执行以下命令:
net user /add AppPoolIdentity1 password1
net user /add AppPoolIdentity2 password2
net user /add AnonymousAccount1 password3
net user /add AnonymousAccount2 password
此步骤现已完成。
应用程序池隔离
IIS 有一个名为 WAS 的进程,该进程在 LOCALSYSTEM 的上下文下运行,并且是唯一需要访问应用程序池密码的进程。 在此任务中,我们将:
- 创建一个新的 RSA 密钥(iisWasKey),只有 LOCALSYSTEM 和管理员有权访问。 此密钥将用于加密每个应用程序池的密码。
- 创建两个应用程序池。
- 将每个应用程序池配置为在不同的标识下运行,并使用 iisWasKey 加密其密码。
- 限制密钥文件的 NTFS 文件系统权限,因此只有系统管理员才有权访问。
创建新的 RSA 密钥
- 单击“ 开始 ”菜单。
- 右键单击 命令提示符。
- 选择“ 以管理员身份运行”。
- 在命令窗口中,导航到保存 createProvider.exe 的位置并运行以下命令:
createProvider.exe iisWasKey RsaKeyForWAS Rsa_WAS
验证这些更改是否正确发生。 使用 Windows 记事本打开 %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\config\machine.config
并验证新提供程序分区中的行是否存在。
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
<providers>
<add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="NetFrameworkConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/>
<add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/>
<add name="Rsa_WAS" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="RsaKeyForWAS" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
</providers>
</configProtectedData>
加密应用程序池密码
默认情况下,每当加密属性时,IIS 都使用 defaultProvider 进行 machine.config中定义的加密。默认值为 RsaProtectedConfigurationProvider。
在此步骤中,我们使用前面创建的 setProvider.exe 应用程序将提供程序更改为 iisWasKey,然后使用 IIS 管理器更改密码:
- 单击“ 开始 ”菜单。
- 右键单击 命令提示符。
- 选择“ 以管理员身份运行”。
- 在命令窗口中,导航到保存 setProvider.exe 的位置并运行以下命令:
setProvider.exe Rsa_WAS
已成功更改默认提供程序Rsa_WAS。
创建新的应用程序池
在此步骤中,我们将创建两个新的应用程序池,这些池彼此隔离。 为此,请启动 IIS 管理器:
单击“ 开始”,然后键入“INetMgr.exe”,然后按 Enter (如果出现提示,请选择 “继续 ”提升权限)。
在+“连接”部分中单击计算机名称旁边的按钮。
单击“应用程序池”。
选择标题为 “添加应用程序池”的右侧任务。
输入名称“AppPool1”,然后按 OK ,如下所示:
重复前面的步骤,但这次使用名称 AppPool2。
请注意 AppPool1 和 AppPool2 的标识如何为 NetworkService。 我们将通过右键单击 AppPool1 并选择“高级设置”,将其更改为之前创建的帐户
在标题 “进程模型”下:
现在 标识 值应如下所示:
单击“确定”,以保存您的更改。
对 AppPool2 重复上一步,并将用户名“AppPoolIdentity2”和密码“password2”重复。
IIS 管理器中显示以下内容(主要是应用程序池的标识已更改):
使用 Windows 记事本并打开
%SystemRoot%\System32\Inetsrv\applicationHost.config
文件来验证更改。 导航到 applicationPools 部分,可以看到我们按预期使用Rsa_WAS密钥加密了应用程序池密码:password="[enc:Rsa_WAS:jAAAAAECAAADZgAAAKQAAAUkBfhWFbUHIt/qtlo+P7CiZC10r9H0DGBvAl U2mhiOxMoHXX6Dz0S8TQjKx2YTKvuE8y+SBUWrEs3JYzXKOkY45Q9z6E/3BFvru5oR9uzbjInASKF/83N N1tIEsoorQWmUOjnL4XM9RNzpqkY6TgyC3CyPUGN9fR7li5+AUupHHfgVPMzcLHfCsoq+ri+X6IbEnJdu cUEAYBn1P9F/Zxk=:enc]" /> password="[enc:Rsa_WAS:jAAAAAECAAADZgAAAKQAAEbQEa/sAmyLbryAR0hD3voip2+0RfzM44sXPekp I2H7HYLzta55NfLcG8vSPHhasahKVgO4wcIcT03CLSn+5koWvAaIRdeClhXWK/X8ZQPFooOpyhOqT0TEP5v jB+DXAKgq0RC6ufHFtrHMy0U69ew7/49YXEcrkF+o8OJZ1K+EkgA3J2ikHKxW0pFBU0tFvLCjt2/UXypfNI 0hYPe2syk=:enc]" />
锁定加密提供程序
默认情况下,在创建密钥时,IIS_IUSRS被授予读取密钥的权限。 但是,可以使用ASPNET_REGIIS工具来删除该访问权限。 为此,请从提升的命令提示符运行以下命令:
cd /d %systemroot%
cd Microsoft.NET\Framework\v2.0.50727
aspnet_regiis.exe -pr iisWasKey IIS_IUSRS
这项操作取消了 IIS_IUSRS(应用程序池标识组)访问 iisWasKey 的权限,该权限仅供管理员和 LOCALSYSTEM 访问。
工作进程隔离
本主题介绍如何通过创建属于不同应用程序池的两个新站点并具有不同的匿名身份验证标识来设置工作进程隔离。 然后,为每个应用程序池创建新的 RSA 提供程序,以加密匿名密码。
创建新网站
在本部分中,我们将创建两个新站点,并将每个站点添加到之前创建的应用程序池。 首先,使用以下步骤打开在管理权限下运行的命令行界面:
单击“ 开始 ”菜单。
右键单击 命令提示符。
选择“ 以管理员身份运行”。
在命令窗口中,使用以下命令导航到 wwwroot 目录:
cd /d %SystemDrive%\inetpub\wwwroot
使用以下命令创建名为“one”的新目录和目录“two”:
mkdir one
mkdir two
创建包含以下 HTML 代码的基本 Default.htm 文件,并将其放置在"one"和"two"目录中。
<html><body>Hello from site X</body></html>
注释
根据文件的目录位置,将“X”替换为“one”或“two”。
现在,使用 IIS 管理器创建两个站点:
单击“ 开始”,键入 INetMgr.exe 然后按 Enter (如果出现提示,请选择 “继续 ”提升权限)。
在+“连接”部分中单击计算机名称旁边的按钮。
右键单击“连接”下的树视图中的“站点”,然后选择“添加网站”。
使用以下信息创建网站:
网站名称:一个
应用程序池:AppPool1
物理路径:{___location of your inetpub directory}\wwwroot\one
端口:81完成后,应如下所示:
Click OK to save the changes.
重复前面的两个步骤,但这次对第二个站点使用以下信息:
网站名称:2
应用程序池:AppPool2
物理路径:{您的 inetpub 目录位置}\wwwroot\two
端口:82
现已创建两个名为 One 和 Two 的新站点,并将其添加到 AppPool1 和 AppPool2 应用程序池。
用于测试网站的 URL 为:
-
http://localhost:81
对于站点 One -
http://localhost:82
用于站点 二
为每个应用程序池创建新提供程序
在本部分中,我们将为每个应用程序池创建新的 RSA 提供程序:
单击“ 开始”菜单。
右键单击 命令提示符。
选择“ 以管理员身份运行”。
在命令窗口中,导航到保存 createProvider.exe 的位置并运行以下命令:
createProvider.exe App1Key RsaKeyForAppPool1 Rsa_app1 createProvider.exe App2Key RsaKeyForAppPool2 Rsa_app2
设置网站 One 的匿名帐户
在提升的命令提示符窗口中,运行以下命令:
setProvider.exe Rsa_app1
返回 IIS 管理器 ,然后双击站点 One。
双击功能名称标题下的“身份验证”项。
选择“匿名身份验证”,然后在右侧的“任务”标题下单击“编辑匿名身份验证凭据”对话框。
单击 “特定用户 ”选项,然后单击“ 设置 ”按钮。
输入用户名 AnonymousAccount1 和 密码密码 3 ,然后选择“ 确定”。
此时会显示以下对话框:
按 “确定” 保存更改。
为站点 2 设置匿名帐户
在提升的命令提示符窗口中,运行以下命令:
setProvider.exe Rsa_app2
- 返回 IIS 管理器 ,然后双击站点 二。
- 双击功能名称标题下的“身份验证”项。
- 选择“匿名身份验证”,然后单击右侧的“任务”标题下的“编辑匿名凭据”对话框。
- 单击 “特定用户 ”选项,然后单击“ 设置”。
- 输入用户名 AnonymousAccount2 和 密码密码 4 ,然后选择“ 确定”。
- 单击“确定”,以保存您的更改。
将加密提供程序重置为默认值
- 返回到具有管理员权限的命令提示符窗口并运行以下命令:
setProvider.exe RsaProtectedConfigurationProvider
注释
此更改可确保所有加密的未来属性都使用默认加密提供程序。
验证更改
验证我们想要的事情是否已发生。 使用 Windows 记事本打开 %SystemRoot%\System32\Inetsrv\applicationHost.config
该文件:
请注意, AppPool1 和 AppPool2 的密码仍使用 Rsa_Was 密钥进行保护。
请注意, AnonymousAccount1 的密码也受到 Rsa_app1 密钥的保护:
password="[enc:Rsa_app1:jAAAAAECAAADZgAAAKQAAKoz4LV7HyPQuyNzXh8gspB0rPG7j3Ijvn3d+jY3/f gma8ZxA7AHLUxjis9b0+Qu8XkLvsGn/A+F+m1O68gY1LkWzAcSW9ks81FuiBVhpZx73FzEo6aOz2QqBduJ7Xhu x923KMBqmwkIVJ0mVAdzwFIm6LWymwRXxNxDE4eosKsw6QP6Rd6duC8gckaLxrTndclErQYgGdMt3W6ofxzRMlc=:enc]" />
最后,请注意, AnonymousAccount2 密码也受到 Rsa_app2 密钥的保护:
password="[enc:Rsa_app2:jAAAAAECAAADZgAAAKQAAKmHMhCTICEUhGncSGCxQc6ll/QGXo0asEIzOf3rIjl sBDGRYhlDQWlf2QbFcIsBGYt8dHo9hzAQN/f03BPSlaFynevpSx4xJOg2/B8ATgPmCg4vgxpY5huZbGxongs55c Rr20WFXsxzlUuw1xoUZI8c1+7gQPOtF0Rwh1g8NBmb5ML/R3jAIFcMtVhaj0OOIfAP7JCjdInwztBqK0XO7FM=:enc]" />
锁定加密提供程序
保护密钥的文件权限,如前面所述。 从提升的命令提示符运行以下命令:
cd /d %systemroot%
cd Microsoft.NET\Framework\v2.0.50727
aspnet_regiis.exe -pr App1Key IIS_IUSRS
aspnet_regiis.exe -pa App1Key AppPoolIdentity1
aspnet_regiis.exe -pr App2Key IIS_IUSRS
aspnet_regiis.exe -pa App2Key AppPoolIdentity2
这些命令删除了IIS_IUSRS读取密钥的功能,并仅添加了需要密钥访问权限的应用程序池标识。
测试您的站点
现在测试网站:
http://localhost:81
http://localhost:82
一切应该像以前一样正常运作。
摘要
总之,我们执行了以下任务来保护应用程序池设置:
- 创建了两个应用程序池
- 创建了两个本地用户帐户,并将其配置为应用程序池标识
- 我们创建了管理加密密钥,并使用它来保护所有应用程序池标识密码
- 我们使用ASPNET_REGIIS来取消IIS_IUSRS(应用程序池标识组)对密钥的访问权限。
这些任务有效地确保只有管理员和 SYSTEM 帐户才能读取应用程序池的密码。 因此,如果应用程序池中的应用程序尝试检索其(或任何)应用程序池的密码,则尝试会失败。
为了隔离工作进程设置,我们:
- 创建新的匿名标识帐户
- 我们为应用程序池创建了一个新的提供程序
- 我们使用应用程序池密钥加密了匿名身份验证密码
- 我们删除了对IIS_IUSRS匿名身份验证提供程序的访问权限,并仅授予对应用程序池标识的访问权限
这可以有效地确保应用程序池的标识可以解密其所属的匿名密码,而其他人无法解密。