http内网穿透CYarp[开源]
0 前言
在物联网领域中,mqtt消息一直是海量设备连接到平台的标配协议,而平台向移动端开放的操作接口往往是http协议,这就要求平台为两种协议作消息一一适配。在某些情况下,这些设备是有操作系统的linux或安卓设备,如果我们换个思路,让这些设备直接提供http协议的操作接口(httpd服务器),平台端使用隧道打通设备与移动端的传输层,做为平台开发人员,就可以省去时间做这些繁琐的消息级别的一一适配工作了。
1 面临的问题
1.1 海量连接
mqtt默认基于tcp传输,一台设备与平台维持一个tcp连接即可高效的上下并行传输消息。而http/1.1在协议层限制了单个连接串行请求响应,但我们可以使用http/2.0或http/3.0做为http/1.1的传输层,也能达到一个物理链接多路传输http/1.1的目的。这样下来内网http/1.1穿透也和mqtt一样,只需要一个物理长连接。
2.2 身份认证
我尝试使用frp来承载物联网设备的http内网穿透,但至今还没成功完成海量设备的一机一密的身份认证,它里面的token认证方式只适合一平台对一个设备的安全要求,而OIDC验证我至今仍然看不明白怎么使用。对于一款内网穿透组件或应用,能像asp.netcore的身份验证强大,对平台端而言是非常需要的。
2.3 安全传输
设备内置的http服务器,一般都是没有https,因为它本身就不考虑公网传输的能力。但在内网穿透之后,我们必须要考虑设备到公网平台这段的传输安全。
2.4 开放协议
内网穿透组件涉及到平台的服务端和集成在设备里的客户端库,平台端一般只有二次开发的需求。而设备端由于芯片、系统和指令集、内存限制等等因素,只提供客户端库或二进制可执行文件是不够的,还可能需要客户端开发者根据交互协议来自行开发客户端组件。这就要求内网穿透组件提供客户端与服务端的交互协议,且最好是设计为非常简单的协议。
2 CYarp出场
CYarp基于Yarp的http内网穿透中间件,支持tcp、http/2.0或http/3.0作为http/1.1的传输层,其具有以下特征
- 是一个标准的asp.netcore中间件
- 能完整使用asp.netcore框架和其它中间件
- 使用服务端的tls(https)做为安全传输层
- 单连接多路复用,无需客户端提供http2服务器
- 协议透明简单,参考了WebSocket升级和Bootstrapping WebSockets with HTTP/2
2.1 服务端开发
CYarp中间件其依赖于Authentication身份认证中间件,使用如下方法进行注册和中间件的配置。
builder.Services.AddCYarp(cyarp=>
{
...
});
中间件配置顺序如下:
...
app.UseAuthentication();
...
app.UseCYarp();
...
最后在Controller、minapi的处理者或中间件中处理http转发
// 请求者的授权验证
[Authorize(Roles = "Mobile")]
public class CYarpController : ControllerBase
{
private static readonly string clientIdClaimType = "ClientId";
/// <summary>
/// 处理cyarp
/// 核心操作是从请求上下文获取clientId
/// 然后使用clientId从clientManager获取client来转发http
/// </summary>
/// <param name="clientManager"></param>
/// <returns></returns>
[Route("/{**cyarp}")]
public async Task InvokeAsync([FromServices] IClientManager clientManager)
{
var clientId = this.User.FindFirstValue(clientIdClaimType);
if (clientId != null && clientManager.TryGetValue(clientId, out var client))
{
this.Request.Headers.Remove(HeaderNames.Authorization);
await client.ForwardHttpAsync(this.HttpContext);
}
else
{
this.Response.StatusCode = StatusCodes.Status502BadGateway;
}
}
}
2.2 客户端开发
使用CYary.Client.CYarpClient很方便完成客户端开发
using var client = new CYarpClient();
while (true))
{
await client.TransportAsync(this.clientOptions.CurrentValue, stoppingToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
}
2.3 客户端协议
由于篇幅有限,不在这里展开,可以查阅CYarp握手协议
3 同源产品
Yarp是dotnet平台下堪比nginx的一个组件,其它融入asp.netcore框架作为里面的中间件共享asp.netcore生态。
davidfowl大神也曾经小手一挥造就了YarpTunnelDemo项目,也是实现了http内网穿透的能力。但是他的实现方案要求客户端方能要运行asp.netcore监听做为客户端组件,由于asp.netcore的runtime只适配了桌面系统,且编译出的二进制文件很大,此方法自然无法在物联网设备中运行了。
http内网穿透CYarp[开源]的更多相关文章
- 聊聊第一个开源项目(内网穿透) - CProxy
文章首发:聊聊第一个开源项目 - CProxy 作者:会玩code 初衷 最近在学C++,想写个项目练练手.对网络比较感兴趣,之前使用过ngrok(GO版本的内网穿透项目),看了部分源码,想把自己的一 ...
- 【新晋开源项目】内网穿透神器[中微子代理] 加入 Dromara 开源社区
1.关于作者 dromara开源组织成员,dromara/neutrino-proxy项目作者 名称:傲世孤尘.雨韵诗泽 名言: 扎根土壤,心向太阳.积蓄能量,绽放微光. 拘浊酒邀明月,借赤日暖苍穹. ...
- 内网穿透神器(ngrok)服务端部署【分享一台自己的ngrok服务器】【多平台】
Ngrok为何物 “ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道.ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放.”这是百度百科上给Ng ...
- 内网穿透+VS2015自带IIS express实现本地调试(微信等需要将开发环境暴漏到外网的情况使用)
今天一个兼职结束了,又要开始寻找新的兼职公司了 ,为了贴补家用啊,为了给儿子更好的生活加油! 抒情完毕进入正题,本篇文章要解决的问题是其实在开发微信支付,微信公众号等回调地址必须是外网可访问的80端口 ...
- Mac配置内网穿透
闲语: Java开发过程中,往往会对接第三方,而在对接过程中,双方间使用的最多的"通讯"方式就是异步通知.可是异步通知过程中,只能通知到外网地址,可是在调试过程我们都是在本地进行- ...
- 如何使用 frp 实现内网穿透
这有一个专注Gopher技术成长的开源项目「go home」 背景 作为一名程序员,家里多多少少会有一些落了灰的电脑,如果把闲置的电脑变成服务器,不仅有良好的配置,还能用来做各种测试,那就再好不过了. ...
- 分享一个内网穿透工具frp
首先简单介绍一下内网穿透: 内网穿透:通过公网,访问局域网里的IP地址与端口,这需要将局域网里的电脑端口映射到公网的端口上:这就需要用到反向代理,即在公网服务器上必须运行一个服务程序,然后在局域网中需 ...
- frp实现内网穿透
frp实现内网穿透 目标 通过外网访问内网设备,本文中实现通过手机的移动流量,可以访问到树莓派设备 设备准备 需要被访问的设备(本文中使用Raspberry Pi`).公网IP设备(本文中使用阿里云 ...
- 基于Yarp的http内网穿透库HttpMouse
简介 前几天发表了<基于Yarp实现内网http穿透>,当时刚刚从原理图变成了粗糙的代码实现,项目连名字都还没有,也没有开放源代码.在之后几天的时间,我不断地重构,朝着"可集成. ...
- FastTunnel-开源内网穿透框架
FastTunnel - 打造人人都能搭建的内网穿透工具 FastTunnel是用.net core开发的一款跨平台内网穿透工具,它可以实现将内网服务暴露到公网供自己或任何人访问. 与其他穿透工具不同 ...
随机推荐
- TStringList,的IndexOf,find,IndexOfName 例子
a=wokao b=in c=wori d=ri e=我靠 f=我插 procedure TForm1.Button1Click(Sender: TObject); var MyList: TStri ...
- 下载Apache软件基金的软件和项目(Hadoop相关组件)
一.下载Hadoop相关组件,可以到Apache软件基金的资源目录: Apache 分发目录地址:https://dlcdn.apache.org/ 二.下载软件 方法一:在页面中找到需要下载的软件目 ...
- JS leetcode 合并两个有序数组 解题分析
壹 ❀ 引 今天做的一题是前两周博客园一粉丝在面试360时遇到的算法题,题目来自leetcode88. 合并两个有序数组,理解起来可能有些费劲,不过我尽量用图的形式给大家解释它,题目描述如下: 给你两 ...
- python 创建动态类
一般情况下多数是预先定义类 而少数特殊情况就需要去动态创建类了,直接贴代码. class BaseModel(Model): class Meta: database = _tb class_new ...
- html基础和js基础
HTML基础 html文件结构 <!DOCTYPE html> 文档类型声明 <html lang="en"></html> 是html标签,称 ...
- Java新建一个子线程异步运行方法
如何在运行主方法的同时异步运行另一个方法,我是用来更新缓存: 1. 工具类 public class ThreadPoolUtils { private static final Logger LOG ...
- 我的第一个项目(九) :飞机大战Vue版本塞到主页
好家伙, 这是未进行分包的vue版本的飞机大战 效果如下: 这里说明一下,大概使用逻辑是提供一个<div> 然后在这<div>中渲染游戏 游戏主界面代码如下: 1 < ...
- Nebula Graph 源码解读系列|客户端的通信秘密——fbthrift
概述 Nebula Clients 给用户提供了多种编程语言的 API 用于和 Nebula Graph 交互,并且对服务端返回的数据结构进行了重新封装,便于用户使用. 目前 Nebula Clien ...
- springboot+kaptcha生成数学运算验证码和字符验证码
使用以下代码只需要复制粘贴,修改一处文本生成器路径即可,文中有交代. 1.添加kaptcha依赖 <dependency> <groupId>com.github.penggl ...
- Springboot中-全局异常处理类用法示例
使用springboot搭建web项目的时候,一般都会添加一个全局异常类,用来统一处理各种自定义异常信息, 和其他非自定义的异常信息,以便于统一返回错误信息.下面就是简单的示例代码, 自定义异常信息. ...