ASP.NET Core2.1在IIS中部署的拓扑图原理

匿名 (未验证) 提交于 2019-12-02 22:06:11

ASP.NET Core2.1与AspNet 拓扑图对比

  • ASP.NET Core2.1 IIS部署拓扑图

  • AspNet 拓扑图

我们看到相比Asp.Net, 出现了3个新的组件:ASP.NET Core Module、Kestrel、dotnet.exe, 后面我们会理清楚引入这3个组件的作用和组件之间的交互原理。

- ASP.NET Core 出现的一个初衷是为实现跨平台部署web,IIS、Nginx、Apache 有他们自己的启动进程和环境;为了实现与这些web服务器的解耦,网络通信是一个比较好的选择。 Kestrel 应运而生:进程内HTTP服务器,ASP.NET Core 不需要去适配IIS,Nginx,Apache等web服务器,相反只需要将这些web服务器的请求转发到 kestrel。
- Kestrel自诞生之日起还有一些网络安全方面的缺陷,这些缺陷包括但不限于 一个合适的timeouts,Size limits,和并发数量, 总之,功能比不上老牌的web服务器。
也就说从主观和客观上都要求我们在 外网部署应用的情况下 使用反向代理服务器。

在内网部署和开发环境中我们完全可以使用Kestrel来充当web服务器。
Kestrel的实现细节:Kestrel 要做到跨平台HTTP服务器,需要脱离底层系统细节实现跨平台IO,在Asp.NetCore2.1 版本之前使用libuv(高性能跨平台IO库), 2.1 版本之后采用的 managed sockets,这是一个巨大的变化。
(另外微软针对 windows系统又提供了一个叫HTTP.sys 的Http服务器,该Http服务器最早叫WebListener, 地位与Kestrel 一样, 该组件可以直接暴露给外网,不依赖IIS)

引入ASP.NET Core Module

上面的反向代理服务器是怎么工作的呢 ?
这其中就涉及到ASP.NET Core Module, 这个 IIS专用组件让ASP.NET Core 应用程序能够在配置了反向代理的IIS后面运行,该组件只对Kestrel有效。

基于以上拓扑图, Asp.Net Core Module需要完成
1. 进程管理
2. 请求转发
两大核心功能。
当第一个请求到来的时候,ASP.NET Core Module启动.NetCore App ; 程序崩溃的时候重启程序。
请求先到达内核模式的Http.sys driver,该驱动将请求路由到IIS 上网站上配置了80/443端口的网站,然后Asp.Net Core Module将请求转发到配置了随机端口的kestrel服务器(这个随机端口不一定是80/443)。
ASP.NET Core Module 会在启动的时候通过环境变量指定kestrel监听的端口;IIS Integration中间件则配置kestrel服务器在 http://localhost:{指定端口}上监听。
同时开始检查请求是否来自ASPNET Core Module(非ASPNET Core Module转发的请求会被拒绝)。
另外由于存在IIS代理服务器,需要保持原始的请求信息:源IP地址、scheme、可能被代理服务器修改的原始Host请求头,这个工作由ForwardedHeader middleware完成,
该中间件在(部署在IIS后面的ASPNETCORE 程序)使用IISIntegration方法默认开启。
ASP.NET Core Module 还有其他的能力:
  • 为worker process 设置环境变量
  • startup 出现故障的时候将标准输出记录到文件系统
  • 转发Windows authentication tokens
20181205 更新,.NetCore2.2+ ASP.NETCore Module支持进程内托管模型,本文章内容针对AspNetCore2.1

FAQ:

1. 什么叫反向代理服务器 Reverse Proxy Server?

通常的代理服务器,只用于代理内部网络对Internet的连接需求,客户机必须指定代理服务器将本来要直接发送到web服务器上的http请求发送到代理服务器中,普通的代理服务器不支持外部对内部网络的访问请求;当一个代理服务器能够代理外部网络的主机,访问内部网时,这种代理服务器的方式称为反向代理服务器 。
- 我在实际项目中研发的 EqidProxyServer在ETL和EqidManager之间就起代理服务器的作用。
- 在aspnetcore应用IIS、Ngnix的过程中,内部的Kestrel和Applicaiton Code是一个完整的内部网络,IIS在这里的角色就起到了反向代理reverse proxy的作用。

2. 按照我们通常的做法,一般使用IIS等作为反向代理服务器,请求转发给Kestrel http 服务器,Kestrel是不是没有提供外网访问的能力?

No. 我们始终要明白 Kestrel设计的初衷是为了实现跨平台,但是诞生后遇到的现实问题是防止攻击和进程管理的的能力比较弱,从其作用来看,Kestrel 定位成Http服务器是合适的,并不是一个完整的Web服务器,但是并不是说我们的Kestrel 并不能做到外网访问(默认和IIS express一样只提供本地主机访问)。
使用下面2种方式为Kestrel提供外部主机访问能力:
  • Use WebHost.UseUrls()
  • Set up hosting.json
具体coding的方式自己看官方文档。
另外由于我们没有使用IIS 等界面化web Server, 我们完成这个事情要按照以下3个步骤:
  • Change the default URL binding to a non-localhost address
  • Open the Firewall port
  • Map a host name to make it easier
还不清楚可以看: https://weblog.west-wind.com/posts/2016/Sep/28/External-Network-Access-to-Kestrel-and-IIS-Express-in-ASPNET-Core#Kestrel:What'stheProblem?UrlBindings

按照上文的说法,应用IIS Integration Middleware之后,会拒绝 非ASPNETCORE Module 转发的请求, 这个拒绝是通过一个PairToken 来完成的。
步骤如下:
  1. 从error log 中拷贝出该MS-ASPNETCORE-TOKEN, 附在request header中便可以直接访问背靠在IIS后面的Kestrel
相关资料:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!