日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

基于Yarp实现内网http穿透

發(fā)布時間:2023/12/4 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Yarp实现内网http穿透 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Yarp介紹

YARP是微軟開源的用來代理服務(wù)器的反向代理組件,可實現(xiàn)的功能類似于nginx。
基于YARP,開發(fā)者可以非常快速的開發(fā)一個性能不錯的小nginx,用于代理http(s)請求到上游的http(s)服務(wù)。

http穿透原理

同網(wǎng)現(xiàn)象

在http反向代理里,代理服務(wù)器總是上游服務(wù)的http客戶端,為了網(wǎng)絡(luò)性能,實際上上游服務(wù)總是和代理服務(wù)處在同一個局域網(wǎng)。試問一個問題:在公網(wǎng)的小nginx,如何把請求代理到局域網(wǎng)的http服務(wù)器?你會發(fā)現(xiàn),小nginx做不到,因為小nginx所在公網(wǎng)服務(wù)器,無法直接與局域網(wǎng)的http服務(wù)器進行通信。

http穿透

在tcp里,進行連接時總是由客戶端發(fā)起,但當(dāng)連接之后客戶端與服務(wù)端是平等的,他們之間可以雙向收發(fā)數(shù)據(jù)。只要公網(wǎng)小nginx與局域網(wǎng)的http服務(wù)器存在tcp連接,我們可以使用這個連接做為httpClient的連接層,然后小nginx使用這個httpClient請求到局域網(wǎng)http服務(wù)器,而從達到http穿透效果。

完整流程

基于Yarp的http穿透

main連接

我們可以使用websocket協(xié)議,創(chuàng)建main連接,主要有以下好處:

  • 共享代理服務(wù)器監(jiān)聽的http(s)端口

  • 利用websocket的ping-pong實現(xiàn)連接檢測

  • 利用websocket連接請求頭進行身份認證

接收局域網(wǎng)創(chuàng)建的連接

我們可以為kestrel編寫中間件,用獲取獲取局域網(wǎng)主動創(chuàng)建的tcp連接,這些連接與代理服務(wù)器與瀏覽器之間的連接共享同一個服務(wù)器端口,以下的listen.Use(transportService.OnConnectedAsync);是一個kestrel中間件。

public static IWebHostBuilder UseKestrelTransportChannel(this IWebHostBuilder hostBuilder) {return hostBuilder.UseKestrel(kestrel =>{var transportService = kestrel.ApplicationServices.GetRequiredService<TransportChannelService>();var options = kestrel.ApplicationServices.GetRequiredService<IOptions<HttpMouseOptions>>().Value;var http = options.Listen.Http;if (http != null){kestrel.Listen(http.IPAddress, http.Port, listen =>{listen.Use(transportService.OnConnectedAsync);});}var https = options.Listen.Https;if (https != null && File.Exists(https.Certificate.Path)){kestrel.Listen(https.IPAddress, https.Port, listen =>{listen.Protocols = HttpProtocols.Http1AndHttp2;listen.UseHttps(https.Certificate.Path, https.Certificate.Password);listen.Use(transportService.OnConnectedAsync);});}}); }

綁定連接到HttpClient

Yarp進行代理時,需要指定HttpMessageInvoker,HttpMessageInvoker實際是SocketsHttpHandler的包裝。而SocketsHttpHandler可以設(shè)置ConnectCallback屬性,用于指定連接。

private static HttpMessageInvoker CreateHttpClient(TransportChannelService transportChannelService) {return new HttpMessageInvoker(new SocketsHttpHandler(){UseProxy = false,UseCookies = false,AllowAutoRedirect = false,AutomaticDecompression = DecompressionMethods.None,ConnectCallback = transportChannelService.CreateChannelAsync,SslOptions = new SslClientAuthenticationOptions{RemoteCertificateValidationCallback = delegate { return true; }}}); }

Yarp直接轉(zhuǎn)發(fā)

使用直接轉(zhuǎn)發(fā)中間件

/// <summary> /// 配置中間件 /// </summary> /// <param name="app"></param> /// <param name="connectionService"></param> /// <param name="httpForwarderService"></param> public void Configure(IApplicationBuilder app, IHostEnvironment hostEnvironment, ConnectionService connectionService, HttpForwarderService httpForwarderService) { app.UseWebSockets();app.Use(connectionService.OnConnectedAsync);app.Use(httpForwarderService.SendAsync); }

通過請求的域名,找到局域網(wǎng)要轉(zhuǎn)發(fā)的最終服務(wù)器地址,做為yarp的請求地址。

/// <summary> /// 發(fā)送http數(shù)據(jù) /// </summary> /// <param name="httpContext"></param> /// <returns></returns> public async Task SendAsync(HttpContext httpContext, Func<Task> next) {var clientDomain = httpContext.Request.Host.Host;if (this.connectionService.TryGetClientUpStream(clientDomain, out var clientUpstream)){var destPrefix = clientUpstream.ToString();if (this.options.CurrentValue.HttpRequest.TryGetValue(clientDomain, out var requestConfig) == false){requestConfig = this.defaultRequestConfig;}await this.httpForwarder.SendAsync(httpContext, destPrefix, httpClient, requestConfig, this.transformer);} }

總結(jié)

基于kestrel和SocketsHttpHandler高度可定制化的擴展能力,結(jié)合Yarp組件,我們可以很方便的開發(fā)一個支持內(nèi)網(wǎng)http穿透的公網(wǎng)http反向代理服務(wù)器。如果把泛域名指向公網(wǎng)反向代理服務(wù)器,最終實現(xiàn)一個二級域名綁定流量到一個局域網(wǎng)http服務(wù)器的一對多功能。

相關(guān)文章

  • YARP實現(xiàn)Dapr服務(wù)調(diào)用的反向代理

  • 用YARP當(dāng)網(wǎng)關(guān)

  • 小試YARP

總結(jié)

以上是生活随笔為你收集整理的基于Yarp实现内网http穿透的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。