基于Yarp实现内网http穿透

Yarp介绍

YARP是微软开源的用来代理服务器的反向代理组件,可实现的功能类似于nginx。
基于YARP,开发者可以非常快速的开发一个性能不错的小nginx,用于代理http(s)请求到上游的http(s)服务。

http穿透原理

同网现象

在http反向代理里,代理服务器总是上游服务的http客户端,为了网络性能,实际上上游服务总是和代理服务处在同一个局域网。试问一个问题:在公网的小nginx,如何把请求代理到局域网的http服务器?你会发现,小nginx做不到,因为小nginx所在公网服务器,无法直接与局域网的http服务器进行通信。

http穿透

在tcp里,进行连接时总是由客户端发起,但当连接之后客户端与服务端是平等的,他们之间可以双向收发数据。只要公网小nginx与局域网的http服务器存在tcp连接,我们可以使用这个连接做为httpClient的连接层,然后小nginx使用这个httpClient请求到局域网http服务器,而从达到http穿透效果。

完整流程

基于Yarp的http穿透

main连接

我们可以使用websocket协议,创建main连接,主要有以下好处:

  • 共享代理服务器监听的http(s)端口

  • 利用websocket的ping-pong实现连接检测

  • 利用websocket连接请求头进行身份认证

接收局域网创建的连接

我们可以为kestrel编写中间件,用获取获取局域网主动创建的tcp连接,这些连接与代理服务器与浏览器之间的连接共享同一个服务器端口,以下的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可以设置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直接转发

使用直接转发中间件

/// <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);
}

通过请求的域名,找到局域网要转发的最终服务器地址,做为yarp的请求地址。

/// <summary>
/// 发送http数据
/// </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);} 
}

总结

基于kestrel和SocketsHttpHandler高度可定制化的扩展能力,结合Yarp组件,我们可以很方便的开发一个支持内网http穿透的公网http反向代理服务器。如果把泛域名指向公网反向代理服务器,最终实现一个二级域名绑定流量到一个局域网http服务器的一对多功能。

相关文章

  • YARP实现Dapr服务调用的反向代理

  • 用YARP当网关

  • 小试YARP

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么把c语言转换汇编程序,如何把汇编语言转换成C语言

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼程序:ORG 0000HLJMP MAINORG 000BHLJMP TIMEORG 1000HHOUR1 EQU 10hHOUR2 EQU 12hMIN1 EQU 14hMIN2 EQU 16hSEC1 EQU 18HCOUNT EQU 20HNUM1 EQU 22HNUM2 EQU 24HLL4 EQU 26Hs1 bit P1.0s2 bit P1.1s3 bit P1.2s4 bit P1.3A1 EQU 36…

Linux命令——chmod

chmod----改变一个或多个文件的存取模式(mode)chmod [options] mode files只能文件属主或特权用户才能使用该功能来改变文件存取模式。mode可以是数字形式或以who opcode permission形式表示。who是可选的&#xff0c;默认是a(所有用户)。只能选择一个opcode(操作码)。可指定多…

学习STL map, STL set之数据结构基础

STL map和set的使用虽不复杂&#xff0c;但也有一些不易理解的地方&#xff0c;如&#xff1a; 或许有得人能回答出来大概原因&#xff0c;但要彻底明白&#xff0c;还需要了解STL的底层数据结构。 C STL 之所以得到广泛的赞誉&#xff0c;也被很多人使用&#xff0c;不只是提供…

男科医生到底有多不正经… | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源真是个鬼才&#xff09;赶紧转给了身边有这种经历的朋友↓ ↓ ↓

5张图带你了解Pulsar的存储引擎BookKeeper

Apache BookKeeper是一款企业级存储系统&#xff0c;最初由雅虎研究院研发&#xff0c;在2011年作为Apache ZooKeeper的子项目进行孵化&#xff0c;在2015年1月成为 Apache顶级项目。起初&#xff0c;BookKeeper是一个预写日志(WAL)系统&#xff0c;经过几年的发展&#xff0c;…

筛选装置用c语言编程,一种空壳瓜子筛选装置的制作方法

本实用新型涉及食品机械领域&#xff0c;特别是一种空壳瓜子筛选装置。背景技术&#xff1a;食品机械是指把食品原料加工成食品(或半成品)过程中所应用的机械设备和装置。食品工业是我国国民经济的支柱产业&#xff0c;食品机械是为食品工业提供装备的行业。随着人民生活水平的…

SO_REUSEADDR

转载&#xff1a; http://www.cppblog.com/aa19870406/archive/2012/07/12/183018.html http://www.cnblogs.com/mydomain/archive/2011/08/23/2150567.html 编写 TCP/SOCK_STREAM 服务程序时&#xff0c;SO_REUSEADDR到底什么意思&#xff1f;这个套接字选项通知内核&#xff…

唱响春天

春天&#xff0c;对就是在这个春天我在博客园里注册了这个ID。一直以来都没有在这里写点什么东西&#xff0c;我想在有空的时候是应该写点东西了。昨天看了江苏卫视的一个叫“绝对唱响”的节目&#xff0c;觉得很有意思&#xff0c;有些许感人的场面&#xff0c;有些触动&#…

不止 Windows 10!Windows 7/8 也能免费升级到 Windows 11

起初&#xff0c;微软宣布为 Windows 7、Windows 8 和 Windows 8.1 用户提供的 Windows 10 免费升级于 2016 年结束。Windows 11 免费升级近日&#xff0c;微软表示将继续支持从 Windows 7、Windows 8 和 Windows 8.1 用户免费升级到 Windows 10 或 Windows 11 &#xff0c;只要…

c语言求平衡因子,平衡二叉树(AVL树)的基本操作

0x00、平衡二叉树的定义平衡二叉树(AVL树)是一种特殊的二叉搜索树&#xff0c;只是在二叉搜索树上增加了对"平衡"的需求。假如一棵二叉搜索树&#xff0c;按照“1,2,3,4,5”的顺序插入数据&#xff0c;会发现二叉树甚至变成了一个线性的链表状结构&#xff0c;这样查…

学校老师绝对不会教的方法,让你的孩子拥有一个开挂般的人生!

比勤奋更重要的&#xff0c;是孩子的思维能力。从上幼儿园开始&#xff0c;很多父母很喜欢给孩子报各种兴趣班&#xff0c;比如钢琴班、英语班、乐高班、报各种各样的课程&#xff0c;就是希望孩子具有18般武艺&#xff0c;赢在起跑线上。其实除了外在的能力&#xff0c;不显山…

通过openpctv简单学习opkg安装与生成包的一些过程

http://linuxtoy.org/archives/openpctv-adding-full-tv-functionality-to-htpc.htmlOpenPCTV - 让你的HTPC拥有更全面的电视功能通过linuxtoy了解到openPCTV是使用opkg打包的获得源代码&#xff1a;git clone git://git.code.sf.net/p/openpctv/code openpctv-code下载完后发现…

保证一个用户已选取的记录不被其他用户选取

问题描述&#xff1a;  用ADO访问数据库&#xff0c;从一个表中取一定的记录&#xff08;比如20行&#xff09;&#xff0c;取出后在程序中使用&#xff0c;使用完后删除掉记录&#xff08;不用更新或删除记录&#xff09;。在多用户操作下(每个用户采用相同的操作)&#xff…

解答网友提问:如何构建动态表达式实现高级查询服务

上次我们介绍了"一秒创建高级查询服务"。前天&#xff0c;有网友在公众号后台问我&#xff0c;怎么使用动态表达式&#xff1a;我想应该是客户提出了更高的要求&#xff0c;查询的条件不仅限于大于、小于&#xff0c;更加多样化&#xff0c;需要动态组合成条件&#…

π!到底蕴藏了多少不为人知的秘密?|今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源网络&#xff0c;侵权删&#xff09;赶紧检查一下π里面有没有你的秘密↓ ↓ ↓

23V3有这种C语言表达式吗,数据结构(C语言版第2版_李云清)习题答案2012-12.doc

数据结构(C语言版第2版_李云清)习题答案2012-12.doc第 1 章 绪论1.1 什么是数据结构&#xff1f;【答】&#xff1a;数据结构是指按一定的逻辑结构组成的一批数据&#xff0c;使用某种存储结构将这批数据存储 于计算机中&#xff0c;并在这些数据上定义了一个运算集合。1.2 数据…

动态内表

很多时候我们的alv报表列是动态的不确定&#xff0c;这样的话如果用平时那种办法肯定是不可行的。 最近有个需求刚好是alv动态的报表&#xff0c;所以现学现卖&#xff0c;总结经验一下&#xff1a; 有一般的列是固定的&#xff0c;还有一些列是动态的 必须要定义的语法如下 *存…

.net core 下的分布式事务锁

系统分布式锁的用法公司框架新增功能分布式锁&#xff1a;锁的性能之王&#xff1a;缓存 > Zookeeper > 数据库锁的实现实现原理&#xff1a;核心采用StackExchange.Redis的LockTake方法实现。支持同步获取锁&#xff0c;或者等待直到超时获取锁。/// <summary>///…

困死我了

又是周一,真想回到周六重新睡個大懶覺..提起來就有氣,可惡的施工負責人....困到現在,還沒精神做事情 转载于:https://www.cnblogs.com/LisaLiu/archive/2006/09/25/514132.html

n以内的素数c语言,关于求N以内素数的一点小问题(N小于一亿)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼我个人觉得第二个可能是因为内存不够的缘故&#xff0c;于是照着网上的办法弄了一个辅助布尔型数组来改进一下&#xff0c;然后就变成这样了……结果是2The total of the primes are: 1代码如下#include#include#define N 10000usi…