在IIS上,ASP.Net服务器的进程未能正确运行

7

我正在尝试在ASP.Net Web应用程序上对上传的文件运行反病毒扫描。我们使用Sophos,因此可以访问其命令行API sav32cli。在代码中,我使用:

Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = @"-remove -nc " + SavedFile;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;

当在开发服务器上附加到w3wp进程并逐步执行代码时,代码似乎只是从一行跳到另一行而没有任何实际操作。但是当从开发服务器上的代码运行时,它会按预期的方式扫描文件并在视为病毒时进行删除。
该服务器正在运行IIS 8.0,并且应用程序构建在.NET Framework 4中。我已更改机器配置以允许该进程作为SYSTEM帐户运行,根据这些说明进行操作:https://support.microsoft.com/en-us/kb/317012#%2Fen-us%2Fkb%2F317012
<processModel  userName="SYSTEM" password="AutoGenerate" />

有什么我没有考虑到的吗?这种实现方式的最佳实践是什么?

编辑:调用时,Process返回一个2(错误停止执行)的ExitCode,而不是预期的0(扫描正常,未发现病毒)或3(扫描正常,发现病毒)。

编辑2:根据下面的评论,我更改了代码:

Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = @"-remove -nc " + SavedFile;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
StringBuilder output = new StringBuilder();

while (!proc.StandardOutput.EndOfStream)
{
    string line = proc.StandardOutput.ReadLine();
    output.AppendLine(line);
}
proc.WaitForExit();

int exitCode = proc.ExitCode;
ASPxMemo2.Text = exitCode.ToString() + Environment.NewLine + output.ToString();

当在IIS上运行时,output始终为空,但从代码中运行时正确地填充。

编辑3:我们查看了StandardError而不是StandardOutput,它显示了这个错误:

Error initialising detection engine [0xa0040200] (Possible insufficient user Admin rights.)

目前,我们将转向另一种病毒检测方法,但仍然希望知道可能的解决方案。


1
进程返回一个 ExitCode - 只需读取进程的输出... - CodeCaster
当通过IIS运行时,进程的输出为空,但在本地代码运行时正确填充。 - anothershrubery
2
您设置的IIS用户还需要对Sophos路径具有管理员权限。我建议不要使用任何内置的IIS用户,而是让系统管理员创建一个服务帐户,可用于此任务。 - Ian
第一个问题:Sophos在服务环境中是否得到支持?他们支持这种配置吗?无论如何,您可以编写一个小的自定义网关Windows服务,并以足够的权限运行,该服务将与此Sophos exe一起工作。然后,您可以使用更简单的方法(例如HTTP / REST / WCF / Remoting等)从IIS与此服务通信,因此无需在IIS和此服务之间需要特殊权限。 - Simon Mourier
1
通常这种错误可以通过使用Process Monitor来解决。它可以跟踪您启动的sav32cli.exe进程的所有文件/注册表/进程/网络活动。您将看到哪些请求失败了。您能创建这些跟踪吗? - Oleg
显示剩余2条评论
4个回答

1

您需要确保在IIS中运行.NET应用程序的应用程序池具有对文件的执行权限

"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe"

您可能还需要将此权限添加到要扫描的文件上传位置(例如c:\ temp)所在的文件夹位置

由于IIS8不以管理员身份运行,因此您可能还需要具有管理员权限来运行防病毒扫描。在调试Visual Studio时,它使用当前登录的Windows用户(除非您使用runas),因此这就解释了为什么在调试时可以正常工作。


不,如果无法执行该进程,他将不会收到特定于该进程的错误代码。 - nothingisnecessary
我的答案是关于实际扫描过程并确保应用程序在启动时具有足够的权限来完成扫描。如果防病毒软件没有权限,我会期望从防病毒应用程序返回“错误停止执行”。执行权限部分是为了澄清和帮助回答“这种实现方式的最佳实践是什么?” - Mallek

0

0

很可能扫描的内容(uploads文件夹)权限配置不正确,或者工作进程用户没有使用Sophos所需的完全权限。您知道可执行文件本身可以被工作进程访问,因为您正在收到特定于Sophos的退出代码和错误消息。

由于您的进程将删除被视为威胁的文件,因此您需要授予运行该进程的用户对存储上传文件的文件夹的修改完全控制权限。

默认情况下,您可以使用IIS_IUSRS组来进行ApplicationPoolIdentity进程,但是您可以在IIS Manager > App Pools > Advanced中验证(并修改)用户。

此答案有更多细节


0

这里有一些想法:

  1. 使用拥有提升权限的不同用户创建进程,参见start-a-net-process-as-a-different-user
  2. 如果上一个建议失败,请使用点1中使用的凭据在服务器上登录一次。它将配置与用户配置文件相关的注册表条目,某些程序需要它。
  3. 开发一个简单的.NET服务,在服务器上运行并监视上传文件夹。该服务更有可能成功运行Sophos扫描。这里是一个关于service creation using .net的参考。
  4. 该服务还可以通过数据库/文件系统等方式与您的网页交互,使操作看起来是同步的。

这是我的四分之一美分 :-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接