IIS 作为反向代理:为 ASP.NET Core Kestrel 应用保驾护航

摘要

ASP.NET Core 应用的生产部署中,虽然 Kestrel 是一个高性能的 Web 服务器,但通常不建议直接暴露给公网。本文将详细介绍如何利用 IIS (Internet Information Services) 作为反向代理服务器,将来自客户端的请求安全、高效地转发给后端的 Kestrel 服务器,并处理相关的配置和注意事项。

目录
  1. 为何需要 IIS 作为反向代理?
  2. 准备工作:安装 Application Request Routing (ARR)
  3. 配置 IIS:启用代理功能
  4. 配置 URL 重写规则:实现请求转发
  5. 配置 ASP.NET Core:处理转发的头信息
  6. 部署与验证
  7. 常见问题与最佳实践
  8. 总结

1. 为何需要 IIS 作为反向代理?

虽然 Kestrel 性能卓越,但在生产环境中,直接将 Kestrel 暴露给互联网通常不是一个好主意,原因如下:

  • 安全性增强: IIS 作为前端代理,可以提供额外的安全层,例如防火墙规则、IP 地址筛选、请求过滤、DDoS 缓解(配合其他工具)等。它能处理一些恶意请求,保护后端的 Kestrel 应用免受直接攻击。
  • SSL 终止 (SSL Offloading): IIS 可以集中管理和终止 HTTPS 连接,卸载 SSL 握手和加密/解密的计算负担,然后将解密后的 HTTP 请求转发给 Kestrel。这可以提高 Kestrel 的处理效率。
  • 静态文件服务: IIS 在服务静态文件(如 CSS、JavaScript、图片)方面通常比 Kestrel 更高效。IIS 可以直接处理这些请求,而不必将其传递给 Kestrel,从而节省后端资源。
  • 负载均衡: 如果需要部署多个 Kestrel 实例,IIS (或 ARR) 可以作为负载均衡器,将请求分发到不同的后端实例。
  • 缓存: IIS 可以配置缓存规则,缓存响应内容,减少后端 Kestrel 的压力。
  • 成熟稳定的生态: IIS 是 Windows 平台下非常成熟和稳定的 Web 服务器,拥有丰富的管理工具和社区支持。

因此,在 Windows 服务器上,使用 IIS 作为反向代理,将请求转发给 Kestrel,是一种标准且推荐的部署模式。


2. 准备工作:安装 Application Request Routing (ARR)

IIS 本身并不具备反向代理功能,需要安装 Application Request Routing (ARR) 模块来实现。

步骤:

  1. 下载 ARR:

    • 打开浏览器,访问 Microsoft 官方下载中心。
    • 搜索 "Application Request Routing" 或直接访问下载页面(例如,搜索 "Microsoft Application Request Routing 3.0")。
    • 下载适用于你的 Windows 版本和系统架构(通常是 x64)的安装程序,例如 Application Request Routing x.x.x-x64.msi
  2. 安装 ARR:

    • 双击下载的 .msi 文件。
    • 遵循安装向导提示,一路点击 "Next" 或 "Accept" 直至完成安装。通常不需要修改任何设置。
    • 安装完成后,建议重启 IIS 管理器或执行 iisreset 命令以确保模块正确加载。

注意: 安装 ARR 通常还依赖于 URL Rewrite Module。如果安装过程中提示缺少 URL Rewrite,也需要先安装它。


3. 配置 IIS:启用代理功能

  1. 打开 IIS 管理器:

    • 在 Windows 服务器上,以管理员身份打开 "Internet Information Services (IIS) Manager"。
  2. 选择服务器节点:

    • 在左侧的连接树中,点击顶层的服务器名称(例如 WIN-SERVERNAME)。
  3. 打开 Application Request Routing Cache:

    • 在中央的"功能视图"中,找到并双击 "Application Request Routing Cache" 图标。
  4. 配置服务器代理设置:

    • 在右侧的"操作"面板中,点击 "Server Proxy Settings..."。
    • 在弹出的窗口中:
      • 勾选 "Enable proxy" 复选框。 这是启用反向代理功能的核心步骤
      • 取消勾选 "Reverse rewrite host in response headers" (推荐)。 这个选项会修改后端服务器返回的响应头中的 LocationSet-Cookie 等字段中的主机名。通常,我们希望这些响应头保持与客户端请求的主机名一致,所以取消勾选它。如果勾选,可能会导致重定向或 Cookie 问题。
      • 取消勾选 "Enable SSL offloading" (除非明确需要)。 如果 IIS 和 Kestrel 之间使用 HTTPS,或者你不希望 IIS 处理 SSL 终止,应取消勾选此项。通常,IIS 和 Kestrel 之间使用 HTTP。
    • 点击 "Apply" 按钮保存设置。

此时,IIS 已经具备了代理功能,但还没有具体的规则来指导它如何转发请求。


4. 配置 URL 重写规则:实现请求转发

现在需要为你的网站创建一个 URL 重写规则,告诉 IIS 将哪些请求转发给 Kestrel。

  1. 选择目标网站:

    • 在 IIS 管理器的左侧连接树中,展开服务器节点,找到并点击你想要配置反向代理的网站(例如 Default Web Site 或你创建的自定义站点)。
  2. 打开 URL Rewrite:

    • 在该网站的"功能视图"中,双击 "URL Rewrite" 图标。
  3. 添加规则:

    • 在右侧的"操作"面板中,点击 "Add Rule(s)..."。
  4. 选择规则类型:

    • 在弹出的对话框中,选择 "Inbound Rules" 下的 "Blank rule"(空白规则)。这允许我们手动配置规则。
  5. 配置规则详情:

    • Name: 为规则起个名字,例如 ProxyToKestrelKestrelBackendRule
    • Match URL:
      • Requested URL: 选择 Matches the Pattern
      • Using: 选择 Regular Expressions(正则表达式)或 Wildcards(通配符),正则表达式更灵活。
      • Pattern: 输入 .* (这是一个正则表达式,表示匹配任何字符组成的任意长度的字符串,即匹配所有传入的 URL 路径)。如果你想只为特定路径(如 /api)配置代理,可以将模式改为 ^api/(.*) (注意,如果使用通配符,可能是 api/*)。
      • Ignore case: 通常勾选。
    • Conditions: (可选) 如果需要根据请求头、查询字符串等添加更复杂的条件,可以在此处添加。对于简单的全站代理,通常留空。
    • Server Variables: (通常留空)。
    • Action:
      • Action Type: 选择 Rewrite。虽然名称是 "Rewrite",但由于 ARR 已启用代理,这里配置的 URL 实际上会被转发(Proxy)到后端服务器。注意:如果只是想重写 URL 而不是代理,会选择 Rewrite;如果想重定向,会选择 Redirect
      • Rewrite URL: 输入后端 Kestrel 服务器的地址。例如 http://127.0.0.1:5000/{R:0}
        • http://: 协议,通常是 http (因为 IIS 和 Kestrel 之间通常是 HTTP)。
        • 127.0.0.1: Kestrel 服务器监听的 IP 地址。如果你的 Kestrel 监听 localhost0.0.0.0,通常 127.0.0.0.1localhost 都可以。如果你的 Kestrel 在另一台机器上,填入那台机器的 IP。
        • :5000: Kestrel 服务器监听的端口。请根据你的 Kestrel 应用实际监听的端口进行修改。
        • /{R:0}: 这是占位符,{R:0} 表示匹配到的整个 URL 路径(即 Pattern .* 匹配的部分)。这确保了原始请求的路径被完整地转发给 Kestrel。如果你的 Pattern 是 ^api/(.*),那么 /{R:1} 会捕获括号内的部分(即 (.*)),你可以根据需要调整。
  6. 保存规则:

    • 点击 "OK" 保存规则。

现在,你为选定的网站创建了一个反向代理规则,它会将所有匹配 .* 的请求转发到 http://127.0.0.1:5000/


5. 配置 ASP.NET Core:处理转发的头信息

当 IIS 作为反向代理时,它会修改原始请求的一些信息,如 Host 头、协议 (HTTPS -> HTTP)、客户端真实 IP 地址 (X-Forwarded-For)。为了让 ASP.NET Core 应用能够感知到原始请求的真实信息(如客户端 IP、是否使用 HTTPS),需要在 ASP.NET Core 应用中配置 ForwardedHeaders 中间件。

在你的 ASP.NET Core 项目的 Program.cs 文件中:

复制代码
using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

// ... 其他服务配置 ...

var app = builder.Build();

// --- 配置 Forwarded Headers ---
// 注意:必须在 UseRouting 之前调用
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    // 指定要转发的头信息
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost,

    // **安全重要**:指定哪些代理服务器是可信的。
    // 在生产环境中,必须明确列出 IIS 服务器的 IP 地址。
    // 如果不设置 KnownProxies/KnownNetworks,所有请求都会被认为是代理请求,这可能导致安全问题。
    // 如果 IIS 和 Kestrel 在同一台机器上,IIS 的 IP 就是 127.0.0.1
    // 如果在不同机器上,需要设置 IIS 服务器的 IP 地址。
    KnownProxies = { IPAddress.Parse("127.0.0.1") }, // 根据实际情况修改 IP
    // 或者,如果 IIS 在一个特定网段,可以使用 KnownNetworks
    // KnownNetworks = { new IPNetwork(IPAddress.Parse("192.168.1.0"), 24) } // 示例网段
});
// --------------------------

app.UseRouting();

// ... 其他中间件配置 ...

app.Run();
  • ForwardedHeaders: 指定要处理的转发头。XForwardedFor 用于客户端 IP,XForwardedProto 用于原始协议 (HTTP/HTTPS),XForwardedHost 用于原始 Host。
  • KnownProxies / KnownNetworks: 极其重要! 必须明确指定哪些 IP 地址或网络是可信的代理服务器。否则,任何客户端都可以伪造 X-Forwarded-* 头来欺骗应用,造成安全风险。在 IIS 作为代理的场景下,这里应该填入 IIS 服务器的 IP 地址。

6. 部署与验证

  1. 部署 ASP.NET Core 应用:

    • 构建你的 ASP.NET Core 应用(例如 dotnet publish -c Release -o ./publish)。
    • 将发布的文件部署到 IIS 站点指向的物理路径(或创建虚拟目录指向发布路径)。
    • 确保你的 appsettings.Production.json (或 appsettings.json) 中的 urls 设置为 Kestrel 监听的地址和端口,例如 "http://127.0.0.1:5000""http://localhost:5000"。或者,依赖环境变量或命令行参数来指定端口。
  2. 启动 Kestrel 应用:

    • 通常,当 IIS 站点第一次被访问时,如果配置了 ASP.NET Core 模块 (AspNetCoreModule),它会自动启动你的 ASP.NET Core 应用。确保 web.config 文件(发布时自动生成)正确配置了启动命令。
  3. 访问 IIS 站点:

    • 打开浏览器,访问你的 IIS 站点地址(例如 https://yourdomain.comhttp://yoursite.local)。
    • 如果一切配置正确,IIS 会接收请求,通过 URL 重写规则将其转发给 Kestrel (http://127.0.0.1:5000),Kestrel 处理请求并返回响应,响应再通过 IIS 返回给客户端。
  4. 验证:

    • 检查 ASP.NET Core 应用的日志,看是否有请求到达。
    • 检查 IIS 日志,看是否有请求记录。
    • ASP.NET Core 应用中,检查 HttpContext.Connection.RemoteIpAddress 是否反映了真实的客户端 IP(而不是 127.0.0.1)。
    • 检查 HttpContext.Request.Scheme 是否反映了原始请求的协议(HTTPS 或 HTTP)。

7. 常见问题与最佳实践

  • 问题:访问 IIS 站点时出现 502 Bad Gateway 错误。

    • 原因: 通常是 IIS 无法连接到后端 Kestrel 服务器。
    • 排查: 检查 URL 重写规则中的目标地址 (http://127.0.0.1:5000) 是否正确,Kestrel 应用是否正在该地址和端口上运行,防火墙是否阻止了内部连接。
  • 问题:应用无法获取客户端的真实 IP 地址。

    • 原因: ForwardedHeaders 中间件未配置或 KnownProxies 设置不正确。
    • 解决: 确保 Program.cs 中正确配置了 ForwardedHeaders,并设置了可信的代理 IP。
  • 问题:HTTPS 重定向或 URL 生成不正确。

    • 原因: ForwardedHeaders 未配置 XForwardedProto,导致应用不知道原始请求是 HTTPS。
    • 解决: 确保 ForwardedHeadersOptions 中包含 ForwardedHeaders.XForwardedProto
  • 最佳实践:

    • 安全: 严格配置 KnownProxiesKnownNetworks
    • 性能: 启用 IIS 的静态文件缓存功能。
    • 日志: 同时关注 IIS 和 ASP.NET Core 应用的日志,便于调试。
    • 健康检查: 考虑为 Kestrel 应用添加健康检查端点,并在 IIS/ARR 中配置健康探测。

8. 总结

通过安装 ARR 模块、启用代理功能、配置 URL 重写规则,并在 ASP.NET Core 应用中正确处理转发的头信息,我们可以成功地将 IIS 配置为 ASP.NET Core Kestrel 应用的反向代理。这种配置模式不仅提升了应用的安全性和性能,还充分利用了 IIS 作为成熟 Web 服务器的优势,是 Windows 服务器环境下部署 ASP.NET Core 应用的推荐方式。


相关推荐
野犬寒鸦1 天前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德1 天前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_93591 天前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
程序员泠零澪回家种桔子1 天前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
源代码•宸1 天前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
晚霞的不甘1 天前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
喵叔哟1 天前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
Charlie_lll1 天前
力扣解题-移动零
后端·算法·leetcode
打工的小王1 天前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
80530单词突击赢1 天前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端