You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在IIS 10上的Flask SSL扫描应用执行异常求助

Flask+IIS部署后testssl.sh扫描未执行问题排查

概述

我开发了一款名为SSL Scanner的Python Flask Web应用,后端基于Github上Dirk Wetter开发的testssl.sh脚本。应用计划部署在IIS上,网页提供输入框让用户输入主机名(可带端口)或IP地址,点击「Begin Scan」按钮后,app.py会从HTML表单提取主机名,作为参数传入testssl.sh命令,扫描目标主机的服务器配置。

我已经提取ubuntu.exe并添加到环境变量和系统变量路径中,只需在命令前加bash就能运行shell命令(比如testssl.sh脚本)。Flask应用运行时,会先切换到testssl.sh所在目录,执行脚本后生成HTML报告文件,存储到指定目录;扫描过程中界面显示「正在扫描<输入的主机名>的服务器配置...」,完成后替换为扫描完成消息和下载链接。

问题

在Flask开发服务器(localhost:5000)上运行时,应用完全符合预期;但部署到IIS后,虽然Internal_scanner.html模板能正常渲染,但输入主机名点击「Begin Scan」按钮后,「正在扫描...」消息仅显示约1秒,随即显示扫描完成消息及下载链接,但实际扫描并未执行。

备注

之前app.log中出现过类似StackOverflow帖子里提到的错误(原帖为Django+IIS场景,我的是Flask+IIS),我已经应用了该帖子的解决方案,当前该错误不再出现在日志中,但问题仍存在。

我附上了相关代码文件,恳请协助解决该问题,使应用能在IIS上正常运行并可通过URL供其他设备访问。


Flask应用代码(app.py)

from flask import Flask, render_template, request, jsonify, url_for, send_file
import os
import datetime
import subprocess

app = Flask(__name__)  # app: Test SSL Interface

dateandtime = datetime.datetime.now().strftime("%H%M")

def create_app():
    @app.route("/")
    def index():
        return render_template("Internal_Scanner.html")
    
    
    @app.route("/scan", methods=["POST"])
    def scan():
        # Get the hostname from the form data
        hostname = request.form["hostname"]
    
        if len(hostname) > 50:
            return jsonify({"return_output": "The hostname is too long."})
        elif hostname.find(" ") != -1:
            return jsonify(
                {
                    "return_output": "The entered hostname is not valid as it has a whitespace."
                }
            )
        else:
            if hostname.find(":") == -1:
                htmlfilename = f"{hostname}_{dateandtime}.html"
            else:
                htmlfilename = f"{(hostname.split(':'))[0]}_{dateandtime}.html"
    
            # Call the backend code to scan the given hostname
            os.chdir(r"C:\inetpub\wwwroot\scanner\testssl.sh-3.1dev")
    
            # Execute the testssl.sh script with the URL and redirect the output to a folder        
            subprocess.run(f"bash ./testssl.sh --htmlfile ../reports/scans/{htmlfilename} -p -s -f -P -S -h -H -I -T -BB -R -C -B -O -W -F -D -4 --openssl-timeout 5 {hostname}")    
            download_link = f"/api/download/{htmlfilename}"
            return jsonify({"return_output": f"Scan completed for hostname: {hostname}.", "download_link": download_link})
    
    
    @app.route("/api/download/<string:filename>", methods=["GET"])
    def download_report(filename):
        # Serve the file from the reports directory
        # r"C:\WSL\reports\scans"
        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": "File not found"})
    
    return app

模板代码(Internal_Scanner.html)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
  <title>SSL Scanner</title>
  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" />
  <link rel="shortcut icon" type="image/x-icon" href="{{ url_for('static', filename='images/icons.ico') }}" />
</head>

<body>
  <div id="header">
    <div id="logo">
      <img src="{{ url_for('static', filename='images/image.jpeg') }}" width="150" height="50" alt="Logo"
        title="Scanner Logo" />
    </div>
    <div>
      <a href="" id="documentation">Documentation</a>
      <a href="mailto:prateek406@gmail.com" id="contactUs">Contact Us</a>
    </div>
  </div>

  <div id="submitBox">
    <form method="POST" action="/scan" style="color: rgb(255, 119, 1)">
      <label for="hostname"><b>Hostname</b></label>
      <input type="text" name="hostname" id="hostname" required />
      <button id="submit-btn" type="submit" style="
            color: rgb(227, 216, 203);
            font-weight: bold;
            background-color: rgb(255, 119, 1);
            border-radius: 5px;
            padding: 8px 12px;
            border: none;
            cursor: pointer;
          ">
        Begin Scan
      </button>
      <label style="margin-left: 5px">Do not refresh or go back during an ongoing scan.</label>
    </form>
  </div>

  <div id="loading" style="
        display: none;
        padding: 30px;
        text-align: center;
        color: rgb(255, 119, 1);
      ">
    Scanning the server configuration of <span id="hostname-text"></span>...
  </div>
  <div id="return_output" style="padding: 10px; text-align: center; color: rgb(255, 119, 1)">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
      $("form").submit(function (event) {
        event.preventDefault();
        var hostname = $("#hostname").val();
        $("#hostname-text").text(hostname);
        $("#submit-btn").attr("disabled", true);
        $("#loading").show();
        $("#return_output").empty(); // Remove previous output message and download link when a hostname is submitted
        $.ajax({
          type: "POST",
          url: "/scan",
          data: $("form").serialize(),
          success: function (response) {
            // Display the output message
            $("#return_output").text(response.return_output);
            // Check if download link is available in response
            if (response.download_link) {
              // Create a download link element
              var downloadLink = $("<a>")
                .attr("href", response.download_link)
                .attr("download", "report.html")
                .text("   Download Scan Report");
              // Append download link element to the return_output div
              $("#return_output").append(downloadLink);
            }
          },
          error: function (error) {
            console.log(error);
          },
          complete: function () {
            $("#submit-btn").attr("disabled", false);
            $("#loading").hide();
          },
        });
      });
    </script>
  </div>
</body>

</html>

IIS配置文件(web.config)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <add name="TesterHttpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
        </handlers>
        <httpPlatform stdoutLogEnabled="true" stdoutLogFile="C:\inetpub\wwwroot\scanner\logs" processPath="C:\inetpub\wwwroot\scanner\env\Scripts\python.exe" arguments="-m flask run --port %HTTP_PLATFORM_PORT%">
            <environmentVariables>
                <environmentVariable name="Ubuntu_Executable" value="C:\inetpub\wwwroot\Ubuntu\Ubuntu_2004.2021.825.0_x64" />
            </environmentVariables>
        </httpPlatform>
    </system.webServer>
</configuration>

内容的提问来源于stack exchange,提问作者PeaBee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:52:57