基于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实现内网http穿透的更多相关文章
- 基于frp的内网穿透实例4-为本地的web服务实现HTTPS访问
原文地址:https://wuter.cn/1932.html/ 一.想要实现的功能 目前已经实现将本地的web服务暴露到公网,现想要实现https访问.(前提:已经有相应的证书文件,如果没有就去申请 ...
- 后渗透阶段之基于MSF的内网主机探测
当我们通过代理可以进入某内网,需要对内网主机的服务进行探测.我们就可以使用MSF里面的内网主机探测模块了. 在这之前,先修改 /etc/proxychains.conf ,加入我们的代理. 然后 pr ...
- 基于C#的内网穿透学习笔记(附源码)
如何让两台处在不同内网的主机直接互连?你需要内网穿透! 上图是一个非完整版内外网通讯图由内网端先发起,内网设备192.168.1.2:6677发送数据到外网时候必须经过nat会转换成 ...
- 基于frp的内网穿透实例1-通过SSH访问内网机器
原文地址:https://wuter.cn/1804.html/ 老母鸡终于到了,作为一个能运行linux系统的四核1G硬件,它还是比较小巧的. FRP 全名:Fast Reverse Proxy.F ...
- 内网ssh穿透
公司服务器没有公网IP,只有内网IP,利用自己的阿里云服务器(有公网ip)做ssh内网穿透,使得外网可访问.方法如下: 环境: 公司服务器和阿里云服务器均为 Ubuntu 操作系统, 需要修改阿里云服 ...
- 搭建基于HTTP协议内网yum仓库
目录 1. 前言 2. 把rpm包下载到本地 3. 配置nginx对外提供服务 4. 配置本地repo文件 5. 生成repodata信息 6. 检查及使用 7. 对管理机器上的仓库进行更新 参考资料 ...
- 使用frp工具实现内网的穿透以及配置多个ssh和web服务
frp简介 FRP 项目地址 https://github.com/fatedier/frp/blob/master/README_zh.md frp 是一个可用于内网穿透的高性能的反向代理应用,支持 ...
- LanProxy 内网映射穿透
前言:用过 ngrok 的人都知道,这是一个免费并且简便的内网映射工具,可是现在ngrok不知道弄啥?不能用了,那我们只能去找一些新的工具,下面是我跟我朋友一起弄的(主要是他教我(✪ω✪)),免费的, ...
- 基于frp的内网穿透实例2-通过自定义域名访问部署于内网的 web 服务
原文地址:https://wuter.cn/1837.html/ 一.想要实现的功能 1.将部署在自己电脑上的网站用于公网访问. 2.将未备案域名解析至国内服务器(即我宿舍的老母鸡上). 二.服务端配 ...
随机推荐
- 【山外笔记-SVN命令】svn命令详解
本文打印版文件下载地址 [山外笔记-SVN命令]svn命令详解-打印版.pdf 一.命令简介 svn命令用于Subversion命令行客户端,执行svn相关的操作. 二.命令语法 1.svn语法: ( ...
- Sed常用功能个人整理
Sed常用功能个人整理 AsdilFibrizo关注 2019.06.24 10:23:41字数 240阅读 15 Sed对1G以下的数据效率很高这里介绍一些个人在工作中遇到的sed问题 1.查找字段 ...
- jackjson学习2+CVE-2019-14379漏洞分析
最近想着分析jackson,jackson和fastjson有点相似,浅蓝大神的文章很好,个人受益匪浅 昨天简单说了下jackson的用法,现在继续拓扑,补充前置知识,前置知识补充的足够多,那么漏洞分 ...
- Ubuntu16.04下使用ufw保护docker容器
ufw屏蔽服务器非docker容器应用端口没有任何问题.问题出在屏蔽不了容器应用对应端口.排除了"ufw使用不当"."docker-compose.yml端口映射不正 ...
- Celery 架构组成
Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async task)和定时任务(cron ...
- zk客户端及锁的使用
1.生成zk客户端对象 private CuratorFramework buildClient() { logger.info("zookeeper registry center ini ...
- C ++基本输入/输出
C ++基本输入/输出 本文将学习如何使用cin对象从用户那里获取输入,并使用cout对象在示例的帮助下向用户显示输出. C ++输出 在C ++中,cout将格式化的输出发送到标准输出设备,例如屏幕 ...
- 10分钟内基于gpu的目标检测
10分钟内基于gpu的目标检测 Object Detection on GPUs in 10 Minutes 目标检测仍然是自动驾驶和智能视频分析等应用的主要驱动力.目标检测应用程序需要使用大量数据集 ...
- TVM 架构设计
TVM 架构设计 本文面向希望了解TVM体系结构和/或积极参与项目开发的开发人员. 主要内容如下: 示例编译流程概述了TVM将模型的高级概念转换为可部署模块的步骤. 逻辑架构组件部分描述逻辑组件.针对 ...
- 初具雏形的UL标准侧重于自主车辆的安全性
初具雏形的UL标准侧重于自主车辆的安全性 Nascent UL standard focuses on autonomous vehicle safety 就任何自主汽车(AV)的安全性进行可信的争论 ...