如何在IIS部署调用subprocess执行PowerShell命令的Flask应用
Flask应用IIS部署问题排查与解决
问题概述
该Flask应用通过Web界面接收用户输入的主机名,调用testssl.sh脚本执行安全扫描,通过subprocess模块调用PowerShell执行命令序列。开发环境(localhost:5000)运行正常,但部署到Microsoft IIS后出现两类问题:
- 使用HttpPlatformHandler部署时,应用无法正常启动,日志提示「系统找不到指定路径」(开发环境无此问题)。
- 使用FastCGIHandler部署时,出现Stack Overflow相关帖子提及的错误,即使按帖子方案修改后仍无法工作,日志仅记录wfastcgi.py的启动与关闭信息。
Flask应用代码
from flask import Flask, render_template, request, jsonify, url_for, send_file import subprocess import os import datetime onlytime = datetime.datetime.now().strftime("%H%M") app = Flask(__name__) # Flask应用实例名称 @app.route("/") # 默认路由 def index(): return render_template("Internal_Scanner.html") @app.route( "/scan", methods=["POST"] ) # 网页点击「开始扫描」按钮触发的路由 def scan(): # 从表单获取主机名参数 hostname = request.form.get("hostname") if len(hostname) > 50: return jsonify({"return_output": "主机名过长,请输入50字符以内的内容。"}) elif hostname.find(" ") != -1: return jsonify( { "return_output": "输入的主机名包含空格,格式无效。" } ) else: # 根据主机名格式生成报告文件名 if hostname.find(":") == -1: htmlfilename = "{}_{}.html".format(hostname, onlytime) else: htmlfilename = "{}_{}.html".format((hostname.split(":"))[0], onlytime) # 构造PowerShell执行命令序列 comm = "cd ..; cd .\Ubuntu\Ubuntu_2004.2021.825.0_x64\; .\ubuntu.exe run 'cd ..; cd ..; cd testssl.sh-3.1dev/; ./testssl.sh --htmlfile ../scanner/reports/scans/{} {}'" .format(htmlfilename, hostname) subprocess.run(['powershell.exe','-Command',comm], shell=True) return_output = f"主机名 {hostname} 扫描完成。" download_link = f"/api/download/{htmlfilename}" return jsonify(return_output=return_output, download_link=download_link) @app.route( "/api/download/<string:filename>", methods=["GET"] ) # 扫描报告下载路由 def download_report(filename): # 从指定目录读取报告文件 file_path = os.path.join(r"C:\inetpub\wwwroot\scanner\reports\scans", filename) if os.path.isfile(file_path): return send_file(file_path, as_attachment=True) else: return jsonify({"error": "文件未找到,请确认扫描已完成。"}) if __name__ == "__main__": app.run()
HttpPlatformHandler 配置文件(web.config)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <httpPlatform processPath="C:\Users\PRATEEK\AppData\Local\Programs\Python\Python311\python.exe" arguments="-m flask run --port %HTTP_PLATFORM_PORT%" stdoutLogEnabled="true" stdoutLogFile="C:\inetpub\wwwroot\scanner\logs\app.log" /> <handlers> <add name="HphHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" /> </handlers> </system.webServer> </configuration>
FastCGIHandler 配置文件(web.config)
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <add name="ScannerFCGIPowershellHandler" path="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" verb="*" modules="CgiModule" scriptProcessor="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" resourceType="Unspecified" requireAccess="Execute" /> <add name="ScannerFCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\inetpub\wwwroot\scanner\env\Scripts\python.exe|C:\inetpub\wwwroot\scanner\env\Lib\site-packages\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" /> </handlers> </system.webServer> <appSettings> <add key="WSGI_HANDLER" value="app.app" /> <!-- {文件名}.{Flask应用实例名}--> <add key="PYTHONPATH" value="C:\inetpub\wwwroot\scanner" /> <add key="WSGI_LOG" value="C:\inetpub\wwwroot\scanner\logs\app.log" /> </appSettings> </configuration>
问题解决方案
1. HttpPlatformHandler「系统找不到指定路径」问题
核心原因
- IIS应用池默认用户(
IIS AppPool\<应用池名称>)无权限访问用户目录下的Python程序,或相对路径解析与开发环境不一致。 - 命令中使用
cd ..等相对路径,IIS部署时的工作目录与本地开发环境不同,导致路径跳转失败。
修复步骤
- 迁移Python到公共路径:将Python安装到公共目录(如
C:\Python311),并给IIS AppPool\<应用池名称>账户分配该目录的读取、执行权限。 - 指定工作目录:在
httpPlatform节点添加workingDirectory属性,固定应用根目录:<httpPlatform processPath="C:\Python311\python.exe" arguments="-m flask run --port %HTTP_PLATFORM_PORT%" stdoutLogEnabled="true" stdoutLogFile="C:\inetpub\wwwroot\scanner\logs\app.log" workingDirectory="C:\inetpub\wwwroot\scanner" /> - 替换相对路径为绝对路径:修改
comm变量中的路径为绝对路径,避免工作目录差异导致的错误:comm = "cd C:\path\to\Ubuntu\Ubuntu_2004.2021.825.0_x64; .\ubuntu.exe run 'cd /absolute/path/to/testssl.sh-3.1dev/; ./testssl.sh --htmlfile /absolute/path/to/scanner/reports/scans/{} {}'" .format(htmlfilename, hostname) - 配置目录权限:给
C:\inetpub\wwwroot\scanner、Ubuntu安装目录及testssl.sh目录添加IIS AppPool\<应用池名称>的读取、执行权限。
2. FastCGIHandler部署后无有效日志且无法工作问题
核心原因
- 额外添加的PowerShell CGI Handler导致请求路由冲突,干扰Flask应用的请求处理。
- wfastcgi日志未记录详细错误,且subprocess调用未捕获异常,无法定位问题。
- IIS应用池用户权限不足,无法调用PowerShell或访问扫描相关路径。
修复步骤
- 移除多余的CGI Handler:删除web.config中的
ScannerFCGIPowershellHandler节点,避免路由干扰。 - 添加异常捕获与日志:修改subprocess调用代码,捕获执行错误并返回详细信息:
try: result = subprocess.run(['powershell.exe','-Command',comm], shell=True, check=True, capture_output=True, text=True) except subprocess.CalledProcessError as e: return jsonify({"return_output": f"扫描失败:{e.stderr}"}) - 提升应用池权限:将应用池身份改为本地系统账户,或具有足够权限的专用服务账户,确保该账户能访问PowerShell、Python、Ubuntu及testssl.sh的所有相关路径。
- 验证FastCGI配置:确认
scriptProcessor中的Python和wfastcgi.py路径完全正确,且应用池用户对这些文件有读取权限。
内容的提问来源于stack exchange,提问作者PeaBee
相关产品推荐
相关产品推荐

