ASP.NET Core2.1在IIS中部署的拓扑图原理
程序员文章站
2022-03-12 17:44:25
ASP.NET Core2.1与AspNet 拓扑图对比 ASP.NET Core2.1 IIS部署拓扑图 AspNet 拓扑图 AspNet 拓扑图 我们看到相比Asp.Net, 出现了3个新的组件:ASP.NET Core Module、Kestrel、dotnet.exe, 后面我们会理清楚引 ......
asp.net core2.1与aspnet 拓扑图对比
- asp.net core2.1 iis部署拓扑图
- aspnet 拓扑图
我们看到相比asp.net, 出现了3个新的组件:asp.net core module、kestrel、dotnet.exe, 后面我们会理清楚引入这3个组件的作用和组件之间的交互原理。
引入kestrel的原因
- 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
3. 依照上图的拓扑图,我们可以知道aspnet core 2.1 iis和 kestrel 实际是两个web服务器,iis将请求转发给kestrel, 我们理所当然可以认为 托管在iis后面的kestrel应该是可以访问的,因为它也是一个 web服务器, 怎么直接访问背靠在iis后面的kestrel ?
按照上文的说法,应用iis integration middleware之后,会拒绝 非aspnetcore module 转发的请求, 这个拒绝是通过一个pairtoken 来完成的。
根据上文理论,将该pairtoken拷贝到 请求头,我们也是可以在kestrel behind iis的情况下,直接访问kestrel。
步骤如下:
- 找到 dotnet 进程: tasklist | findstr "dotnet" ( tasklist 显示本地或者远程机器上运行的进程列表 )
- 找到该进程占用的port : netstat -ano | findstr "pid" (netstat 显示协议统计信息和当前tcp/ip 网络连接), 利用输出的port请求kestrel 服务器: curl localhost:port, 会提示400 badrequest
- 从error log 中拷贝出该ms-aspnetcore-token, 附在request header中便可以直接访问背靠在iis后面的kestrel
相关资料:
下一篇: 加强企业Linux系统安全的若干方法
推荐阅读
-
ASP.NET Core 3.0 : 二十八. 在Docker中的部署以及docker-compose的使用
-
ASP.NET Core2.1在IIS中部署的拓扑图原理
-
php-PHP在IIS7中部署后,外网IE打开的时候会出现404,其浏览器一切正常
-
在IIS上部署ASP.NET Core Web API的方法步骤
-
ASP.NET Core 3.0 : 二十八. 在Docker中的部署以及docker-compose的使用
-
PHP在IIS7中部署后,外网IE打开的时候会出现404,其浏览器一切正常
-
php-PHP在IIS7中部署后,外网IE打开的时候会出现404,其浏览器一切正常
-
ASP.NET Core应用程序运行Vue并且部署在IIS上的详解
-
ASP.NET Core应用程序运行Vue并且部署在IIS上的详解
-
ASP.NET Core2.1在IIS中部署的拓扑图原理