基于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.将未备案域名解析至国内服务器(即我宿舍的老母鸡上). 二.服务端配 ...
随机推荐
- 014.Python函数
一 函数的概念 1.1 函数的含义 功能 (包裹一部分代码 实现某一个功能 达成某一个目的) 1.2 函数特点 可以反复调用,提高代码的复用性,提高开发效率,便于维护管理 1.3 函数的基本格式 # ...
- OS_FLAG_GRP_DEPLETED
178 * OS_FLAG_GRP_DEPLETED 系统没有剩余的空闲事件标志组,需要更改OS_CFG.H中 179 * 的事件标志组数目配置创建 标志组的时候返回这个错误 打印出错误代码后发现是1 ...
- Linux中级之ansible概念及hoc命令行调用模式
一.Ansible简介 ansible是新出现的开源的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统 ...
- Lua的string库函数列表
基本函数 函数 描述 示例 结果 len 计算字符串长度 string.len("abcd") 4 rep 返回字符串s的n个拷贝 string.rep("abcd&qu ...
- 【Python】神器:Streamlit,仅使用Python开发一个运维管理后台(不需要编写html,js,css)
背景 作为SRE,我们有很多很多自动化的工具,大部分都是自动运行的,还有一部分是CLI,我们一直苦于没有一个自己的管理后台网站,受限于前端能力薄弱,开发出来的网页只能说凑活能用,但是不好用. 现在我们 ...
- Auto ML自动调参
Auto ML自动调参 本文介绍Auto ML自动调参的算法介绍及操作流程. 操作步骤 登录PAI控制台. 单击左侧导航栏的实验并选择某个实验. 本文以雾霾天气预测实验为例. 在实验画布区,单击左上角 ...
- Darknet_Yolov3模型搭建
Darknet_Yolov3模型搭建 YOLO(You only look once)是目前流行的目标检测模型之一,目前最新已经发展到V3版本了,在业界的应用也很广泛.YOLO的特点就是"快 ...
- SpringAOP 原理解析
什么是AOP? 1: 传统的OOP编程他的代码逻辑是一种自上向下, 而在这些自上而下的过程中会产生一些横切性的问题,比如说:日志信息,权限校验认证,事务等, 2: 这些横切性问题,往往与我们的主业务逻 ...
- redis常用命令练习
redis-server redis-cli select 0-15 redis key: string\hash\list\set\sortedset 1.增删改查... keys * 所有key ...
- 【NX二次开发】拉伸的偏置方向猜想与验证
结论:偏置的方向为曲线方向与拉伸方向的向量叉乘. 在UF_MODL_create_extrusion帮助中有这么一句话:Note that the offset direction is determ ...