# mproxy-original **Repository Path**: xmh3000/mproxy-original ## Basic Information - **Project Name**: mproxy-original - **Description**: go 语言写的代理 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-18 - **Last Updated**: 2025-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mProxy ![Go Report Card][grc] [![License][LIC-BADGE]][LIC] mProxy是一个轻量级、可扩展、可定制的物联网API网关,旨在支持跨多种协议的无缝通信。它支持实时数据包操作,具有可插拔的身份验证机制,并提供可观测性以进行监控和故障排除。为了灵活性,mProxy可以作为sidecar或独立服务部署,也可以作为库集成到应用程序中。 mProxy的可扩展性允许开发人员将其定制以适应各种物联网生态系统,确保最佳的性能和安全性。 ## 主要特性 mProxy的一些关键特性包括多协议支持、实时数据包操作、可插拔身份验证、可观测性和可扩展性,同时保持轻量级、可定制并且可以轻松地作为sidecar或独立服务部署。

#### 多协议支持 mProxy构建为与广泛的物联网协议接口,包括: - MQTT - CoAP - HTTP - WebSocket - 易于扩展以支持其他协议。 ### 即时数据包操作 允许实时数据包转换和处理。 可以注入自定义逻辑或数据包拦截器来修改传入和传出消息。 ### 身份验证和授权 支持不同提供商(如OAuth、JWT、API密钥等)的可插拔身份验证系统。 访问控制用于细粒度资源授权。 易于替换的身份验证模块,便于与自定义或企业身份系统集成。 ### 可观测性 提供实时指标以监控系统健康状况和性能。 提供日志记录和跟踪功能,便于故障排除和优化,并且可以轻松与Prometheus、Grafana和OpenTelemetry集成,实现详细的跟踪和可视化。 ### 可扩展架构 mProxy设计为水平扩展,确保能够处理高吞吐量环境。 ### 可插拔和可扩展 核心组件是模块化的,使得插入自定义模块或替换现有模块变得容易。 可扩展以添加新的物联网协议、中间件和功能。 ### 可定制 高度可配置,允许调整特定于协议的行为、可观测性和性能优化。 默认部署只需要最少的配置,但支持深度定制。 ### 轻量级 使用Go编程语言构建,针对低资源使用进行了优化,使其既适用于高性能数据中心,也适用于资源受限的物联网边缘设备。 ### 部署灵活性 可以作为sidecar部署以增强现有微服务,或作为独立服务直接与物联网设备交互。 可作为库集成到现有应用程序中。 ## 使用方法 ```bash git clone https://github.com/absmach/mgate.git cd mgate make ./build/mgate ``` ## 架构 mProxy启动协议服务器,为设备提供连接。在连接时,它与远程协议服务器建立会话。然后它将数据包从设备传输到协议服务器,在通过代理流动时检查或修改它们。 以下是更详细的流程: - 设备连接到mProxy服务器 - mProxy接受入站(IN)连接并与远程服务器建立新会话(例如,只有在接受到来自设备的新连接后,它才会拨号到MQTT代理。这样,一个设备-mProxy连接对应一个mProxy-MQTT代理连接) - mProxy随后产生2个goroutine:一个将从设备-mProxy套接字读取传入数据包(INBOUND或UPLINK),检查它们(调用事件处理程序)并将它们写入mProxy-server套接字(向服务器转发),另一个将从mProxy-server套接字读取服务器响应并将其写入设备,在设备-mProxy套接字中(DOWNLINK或OUTBOUND)。

mProxy可以解析和理解协议包,检测到它们时,会调用外部事件处理程序。事件处理程序应实现[pkg/mqtt/events.go](pkg/mqtt/events.go)中定义的以下接口: ```go // Handler是mProxy钩子的接口 type Handler interface { // 客户端`CONNECT`时的授权 // 每个参数都通过引用传递,以便可以更改 AuthConnect(ctx context.Context) error // 客户端`PUBLISH`时的授权 // 主题通过引用传递,以便可以修改 AuthPublish(ctx context.Context, topic *string, payload *[]byte) error // 客户端`SUBSCRIBE`时的授权 // 主题通过引用传递,以便可以修改 AuthSubscribe(ctx context.Context, topics *[]string) error // 客户端成功连接后 Connect(ctx context.Context) // 客户端成功发布后 Publish(ctx context.Context, topic *string, payload *[]byte) // 客户端成功订阅后 Subscribe(ctx context.Context, topics *[]string) // 客户端取消订阅后 Unsubscribe(ctx context.Context, topics *[]string) // 连接丢失时断开连接 Disconnect(ctx context.Context) } ``` Handler接口受到MQTT协议控制包的启发;如果底层协议不支持其中某些操作,实现可以简单地省略它们。[这里](examples/simple/simple.go)给出了实现示例,以及它的[`main()`函数](cmd/main.go)。 ## 部署 为了解释部署过程,将以MQTT代理为例,因为MQTT是最广泛使用和功能丰富的协议之一。mProxy不进行负载均衡——只是纯粹简单的代理和TLS终止。这就是为什么应该将其部署在其对应的MQTT代理实例之前:MQTT集群中的每个MQTT代理实例对应一个mProxy。 通常,这是通过在同一Kubernetes pod中将mProxy作为side-car与MQTT代理实例(MQTT集群节点)一起部署完成的。

LB任务可以卸载到标准入口代理——例如NginX。 ## mProxy的示例设置和测试 ### 要求 - Golang - Mosquitto MQTT服务器 - Mosquitto发布者和订阅者客户端 - coap-client或Magistrala coap-cli ### mProxy的示例设置 mProxy用于将请求代理到后端服务器。对于示例设置,我们将使用Mosquitto服务器作为MQTT的后端,以及MQTT over Websocket和HTTP echo服务器用于HTTP。 1. 使用以下命令启动Mosquitto MQTT服务器。这个bash脚本将启动支持WebSocket的Mosquitto MQTT服务器。Mosquitto服务器将在端口1883上监听MQTT连接,在端口8000上监听MQTT over WebSocket连接。 ```bash examples/server/mosquitto/server.sh ``` 2. 启动HTTP Echo服务器: ```bash go run examples/server/http-echo/main.go ``` 3. 启动OCSP/CRL模拟响应器: ```bash go run examples/ocsp-crl-responder/main.go ``` 4. 启动各种协议的示例mProxy服务器: ```bash go run cmd/main.go ``` `cmd/main.go` Go程序初始化以下协议的mProxy服务器: - 端口`1884`上的`无TLS的MQTT`协议mProxy服务器 - 端口`8883`上的`带TLS的MQTT`协议mProxy服务器 - 端口`8884`上的`带mTLS的MQTT`协议mProxy服务器 - 端口`8083`上的`无TLS的MQTT over WebSocket`协议mProxy服务器 - 端口`8084`上的`带TLS的MQTT over WebSocket`协议mProxy服务器 - 端口`8085`上带前缀路径`/mqtt`的`带mTLS的MQTT over WebSocket`协议mProxy服务器 - 端口`8086`上带前缀路径`/messages`的`无TLS的HTTP协议`mProxy服务器 - 端口`8087`上带前缀路径`/messages`的`带TLS的HTTP协议`mProxy服务器 - 端口`8088`上带前缀路径`/messages`的`带mTLS的HTTP协议`mProxy服务器 - 端口`5682`上的`无DTLS的CoAP协议`mProxy服务器 - 端口`5684`上的`带DTLS的CoAP协议`mProxy服务器 ### mProxy的示例测试 #### 测试MQTT协议的mProxy服务器 `examples/client/mqtt`目录中的bash脚本有助于测试运行MQTT协议的mProxy服务器 - 测试端口1884上无TLS的MQTT mProxy服务器的脚本 ```bash examples/client/mqtt/without_tls.sh ``` - 测试端口8883上带TLS的MQTT mProxy服务器的脚本 ```bash examples/client/mqtt/with_tls.sh ``` - 测试端口8884上带mTLS的MQTT mProxy服务器的脚本 ```bash examples/client/mqtt/with_mtls.sh ``` #### 测试MQTT over WebSocket协议的mProxy服务器 `examples/client/websocket/*/main.go`目录中的Go程序有助于测试运行MQTT over WebSocket协议的mProxy服务器 - 测试端口8083上无TLS的MQTT over WebSocket mProxy服务器的Go程序 ```bash go run examples/client/websocket/without_tls/main.go ``` - 测试端口8084上带TLS的MQTT over WebSocket mProxy服务器的Go程序 ```bash go run examples/client/websocket/with_tls/main.go ``` - 测试端口8085上带mTLS的MQTT over Websocket mProxy服务器的Go程序 ```bash go run examples/client/websocket/with_mtls/main.go ``` #### 测试HTTP协议的mProxy服务器 `examples/client/http`目录中的bash脚本有助于测试运行HTTP协议的mProxy服务器 - 测试端口8086上无TLS的HTTP mProxy服务器的脚本 ```bash examples/client/http/without_tls.sh ``` - 测试端口8087上带TLS的HTTP mProxy服务器的脚本 ```bash examples/client/http/with_tls.sh ``` - 测试端口8088上带mTLS的HTTP mProxy服务器的脚本 ```bash examples/client/http/with_mtls.sh ``` ### 测试CoAP协议的mProxy服务器 `example/client/coap`目录中的bash脚本有助于测试运行CoAP协议的mProxy服务器。您需要安装[coap-client](https://libcoap.net/doc/reference/4.3.1/man_coap-client.html)或[Magistrala coap-cli](https://github.com/absmach/coap-cli)。 该脚本可以与`example/server/coap`中提供的简单go-coap服务器一起使用。 - 测试端口5682上无DTLS的CoAP mProxy服务器的脚本 ```bash examples/client/coap/without_dtls.sh ``` - 测试端口5684上带DTLS的CoAP mProxy服务器的脚本 ```bash examples/client/coap/with_dtls.sh ``` ## 配置 服务使用下表中的环境变量进行配置。请注意,任何未设置的变量将被替换为其默认值。 | 变量 | 描述 | 默认值 | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | | MPROXY_MQTT_WITHOUT_TLS_ADDRESS | 无TLS的MQTT入站(IN)连接监听地址 | :1884 | | MPROXY_MQTT_WITHOUT_TLS_TARGET | 无TLS的MQTT出站(OUT)连接地址 | localhost:1883 | | MPROXY_MQTT_WITH_TLS_ADDRESS | 带TLS的MQTT入站(IN)连接监听地址 | :8883 | | MPROXY_MQTT_WITH_TLS_TARGET | 带TLS的MQTT出站(OUT)连接地址 | localhost:1883 | | MPROXY_MQTT_WITH_TLS_CERT_FILE | 带TLS的MQTT证书文件路径 | ssl/certs/server.crt | | MPROXY_MQTT_WITH_TLS_KEY_FILE | 带TLS的MQTT密钥文件路径 | ssl/certs/server.key | | MPROXY_MQTT_WITH_TLS_SERVER_CA_FILE | 带TLS的MQTT服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WITH_MTLS_ADDRESS | 带mTLS的MQTT入站(IN)连接监听地址 | :8884 | | MPROXY_MQTT_WITH_MTLS_TARGET | 带mTLS的MQTT出站(OUT)连接地址 | localhost:1883 | | MPROXY_MQTT_WITH_MTLS_CERT_FILE | 带mTLS的MQTT证书文件路径 | ssl/certs/server.crt | | MPROXY_MQTT_WITH_MTLS_KEY_FILE | 带mTLS的MQTT密钥文件路径 | ssl/certs/server.key | | MPROXY_MQTT_WITH_MTLS_SERVER_CA_FILE | 带mTLS的MQTT服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WITH_MTLS_CLIENT_CA_FILE | 带mTLS的MQTT客户端CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WITH_MTLS_CERT_VERIFICATION_METHODS | 带mTLS的MQTT证书验证方法,如果没有值或未设置,则mProxy服务器不会对客户端进行验证 | ocsp | | MPROXY_MQTT_WITH_MTLS_OCSP_RESPONDER_URL | 带mTLS的MQTT OCSP响应器URL,当客户端证书AIA中没有可用的OCSP响应器URL时使用 | | | MPROXY_MQTT_WS_WITHOUT_TLS_ADDRESS | 无TLS的MQTT over Websocket入站(IN)连接监听地址 | :8083 | | MPROXY_MQTT_WS_WITHOUT_TLS_TARGET | 无TLS的MQTT over Websocket出站(OUT)连接地址 | ws://localhost:8000/ | | MPROXY_MQTT_WS_WITH_TLS_ADDRESS | 带TLS的MQTT over Websocket入站(IN)连接监听地址 | :8084 | | MPROXY_MQTT_WS_WITH_TLS_TARGET | 带TLS的MQTT over Websocket出站(OUT)连接地址 | ws://localhost:8000/ | | MPROXY_MQTT_WS_WITH_TLS_CERT_FILE | 带TLS的MQTT over Websocket证书文件路径 | ssl/certs/server.crt | | MPROXY_MQTT_WS_WITH_TLS_KEY_FILE | 带TLS的MQTT over Websocket密钥文件路径 | ssl/certs/server.key | | MPROXY_MQTT_WS_WITH_TLS_SERVER_CA_FILE | 带TLS的MQTT over Websocket服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WS_WITH_MTLS_ADDRESS | 带mTLS的MQTT over Websocket入站(IN)连接监听地址 | :8085 | | MPROXY_MQTT_WS_WITH_MTLS_PATH_PREFIX | 带mTLS的MQTT over Websocket入站(IN)连接路径 | /mqtt | | MPROXY_MQTT_WS_WITH_MTLS_TARGET | 带mTLS的MQTT over Websocket出站(OUT)连接地址 | ws://localhost:8000/ | | MPROXY_MQTT_WS_WITH_MTLS_CERT_FILE | 带mTLS的MQTT over Websocket证书文件路径 | ssl/certs/server.crt | | MPROXY_MQTT_WS_WITH_MTLS_KEY_FILE | 带mTLS的MQTT over Websocket密钥文件路径 | ssl/certs/server.key | | MPROXY_MQTT_WS_WITH_MTLS_SERVER_CA_FILE | 带mTLS的MQTT over Websocket服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WS_WITH_MTLS_CLIENT_CA_FILE | 带mTLS的MQTT over Websocket客户端CA文件路径 | ssl/certs/ca.crt | | MPROXY_MQTT_WS_WITH_MTLS_CERT_VERIFICATION_METHODS | 带mTLS的MQTT over Websocket证书验证方法,如果没有值或未设置,则mProxy服务器不会对客户端进行验证 | ocsp | | MPROXY_MQTT_WS_WITH_MTLS_OCSP_RESPONDER_URL | 带mTLS的MQTT over Websocket OCSP响应器URL,当客户端证书AIA中没有可用的OCSP响应器URL时使用 | | | MPROXY_HTTP_WITHOUT_TLS_ADDRESS | 无TLS的HTTP入站(IN)连接监听地址 | :8086 | | MPROXY_HTTP_WITHOUT_TLS_PATH_PREFIX | 无TLS的HTTP入站(IN)连接路径 | /messages | | MPROXY_HTTP_WITHOUT_TLS_TARGET | 无TLS的HTTP出站(OUT)连接地址 | | | MPROXY_HTTP_WITH_TLS_ADDRESS | 带TLS的HTTP入站(IN)连接监听地址 | :8087 | | MPROXY_HTTP_WITH_TLS_PATH_PREFIX | 带TLS的HTTP入站(IN)连接路径 | /messages | | MPROXY_HTTP_WITH_TLS_TARGET | 带TLS的HTTP出站(OUT)连接地址 | | | MPROXY_HTTP_WITH_TLS_CERT_FILE | 带TLS的HTTP证书文件路径 | ssl/certs/server.crt | | MPROXY_HTTP_WITH_TLS_KEY_FILE | 带TLS的HTTP密钥文件路径 | ssl/certs/server.key | | MPROXY_HTTP_WITH_TLS_SERVER_CA_FILE | 带TLS的HTTP服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_HTTP_WITH_MTLS_ADDRESS | 带mTLS的HTTP入站(IN)连接监听地址 | :8088 | | MPROXY_HTTP_WITH_MTLS_PATH_PREFIX | 带mTLS的HTTP入站(IN)连接路径 | /messages | | MPROXY_HTTP_WITH_MTLS_TARGET | 带mTLS的HTTP出站(OUT)连接地址 | | | MPROXY_HTTP_WITH_MTLS_CERT_FILE | 带mTLS的HTTP证书文件路径 | ssl/certs/server.crt | | MPROXY_HTTP_WITH_MTLS_KEY_FILE | 带mTLS的HTTP密钥文件路径 | ssl/certs/server.key | | MPROXY_HTTP_WITH_MTLS_SERVER_CA_FILE | 带mTLS的HTTP服务器CA文件路径 | ssl/certs/ca.crt | | MPROXY_HTTP_WITH_MTLS_CLIENT_CA_FILE | 带mTLS的HTTP客户端CA文件路径 | ssl/certs/ca.crt | | MPROXY_HTTP_WITH_MTLS_CERT_VERIFICATION_METHODS | 带mTLS的HTTP证书验证方法,如果没有值或未设置,则mProxy服务器不会对客户端进行验证 | ocsp | | MPROXY_HTTP_WITH_MTLS_OCSP_RESPONDER_URL | 带mTLS的HTTP OCSP响应器URL,当客户端证书AIA中没有可用的OCSP响应器URL时使用 | | | MPROXY_COAP_WITHOUT_DTLS_HOST | 无DTLS的CoAP入站(IN)连接监听主机 | localhost | | MPROXY_COAP_WITHOUT_DTLS_PORT | 无DTLS的CoAP入站(IN)连接监听端口 | 5682 | | MPROXY_COAP_WITHOUT_DTLS_TARGET_HOST | 无DTLS的CoAP出站(OUT)连接监听主机 | localhost | | MPROXY_COAP_WITHOUT_DTLS_TARGET_PORT | 无DTLS的CoAP出站(OUT)连接监听端口 | 5683 | | MPROXY_COAP_WITH_DTLS_HOST | 带DTLS的CoAP入站(IN)连接监听主机 | localhost | | MPROXY_COAP_WITH_DTLS_PORT | 带DTLS的CoAP入站(IN)连接监听端口 | 5684 | | MPROXY_COAP_WITH_DTLS_TARGET_HOST | 带DTLS的CoAP出站(OUT)连接监听主机 | localhost | | MPROXY_COAP_WITH_DTLS_TARGET_PORT | 带DTLS的CoAP出站(OUT)连接监听端口 | 5683 | | MPROXY_COAP_WITH_DTLS_CERT_FILE | 带DTLS的CoAP证书文件路径 | ssl/certs/server.crt | | MPROXY_COAP_WITH_DTLS_KEY_FILE | 带DTLS的CoAP密钥文件路径 | ssl/certs/server.key | | MPROXY_COAP_WITH_DTLS_SERVER_CA_FILE | 带DTLS的CoAP服务器CA文件路径 | ssl/certs/ca.crt | ## mProxy配置环境变量 ### 服务器配置环境变量 - `ADDRESS` : 指定mProxy监听的地址。支持MQTT、MQTT over WebSocket和HTTP代理连接。 - `PATH_PREFIX` : 定义监听MQTT over WebSocket或HTTP连接时的路径前缀。 - `TARGET` : 指定目标服务器的地址,包括任何前缀路径(如果有)。目标服务器可以是MQTT服务器、MQTT over WebSocket或HTTP服务器。 ### TLS配置环境变量 - `CERT_FILE` : TLS证书文件路径。 - `KEY_FILE` : TLS证书密钥文件路径。 - `SERVER_CA_FILE` : 服务器CA证书文件路径。 - `CLIENT_CA_FILE` : 客户端CA证书文件路径。 - `CERT_VERIFICATION_METHODS` : 验证证书的方法。接受的值为`ocsp`或`crl`。 对于`ocsp`值,`tls.Config`尝试从客户端证书的权威信息访问(AIA)部分检索OCSP响应器/服务器URL。如果客户端证书缺少OCSP响应器URL或者您希望使用替代URL,可以使用环境变量`OCSP_RESPONDER_URL`覆盖它。 对于`crl`值,`tls.Config`尝试从客户端证书的CRL分发点部分获取证书撤销列表(CRL)文件。如果客户端证书缺少CRL分发点部分,或者您希望覆盖它,可以使用环境变量`CRL_DISTRIBUTION_POINTS`和`CRL_DISTRIBUTION_POINTS_ISSUER_CERT_FILE`。如果没有任何CRL分发点服务器可用,您可以使用环境变量`OFFLINE_CRL_FILE`和`OFFLINE_CRL_ISSUER_CERT_FILE`指定离线CRL文件。 #### OCSP配置环境变量 - `OCSP_DEPTH` : OCSP方法中客户端证书验证的深度。默认值为0,表示没有限制,所有证书都会被验证。 - `OCSP_RESPONDER_URL` : 覆盖客户端证书AIA部分中存在的OCSP响应器URL。如果为空,则期望从客户端证书的AIA部分获取OCSP响应器URL。 #### CRL配置环境变量 - `CRL_DEPTH`: CRL方法中客户端证书验证的深度。默认值为1,表示只验证叶证书。 - `CRL_DISTRIBUTION_POINTS` : 覆盖证书CRL分发点部分中存在的CRL分发点值。 - `CRL_DISTRIBUTION_POINTS_ISSUER_CERT_FILE` : 用于验证从`CRL_DISTRIBUTION_POINTS`检索的CRL的颁发者证书文件路径。 - `OFFLINE_CRL_FILE` : 离线CRL文件路径,当环境变量或证书的CRL分发点部分都没有CRL分发点服务器时可以使用。 - `OFFLINE_CRL_ISSUER_CERT_FILE` : 用于验证`OFFLINE_CRL_FILE`中指定的离线CRL文件的颁发者证书文件位置。 ## 为环境变量添加前缀 mProxy依赖[caarlos0/env](https://github.com/caarlos0/env)包将环境变量加载到其[配置](https://github.com/arvindh123/mgate/blob/main/config.go#L15)中。 您可以通过将`env.Options`传递给`config.EnvParse`函数来控制这些变量的加载方式。 要为环境变量添加前缀,请使用[caarlos0/env](https://github.com/caarlos0/env)包中的`env.Options{Prefix: "MPROXY_"}`。例如: ```go package main import ( "github.com/caarlos0/env/v11" "github.com/absmach/mgate" ) mqttConfig := mgate.Config{} if err := mqttConfig.EnvParse(env.Options{Prefix: "MPROXY_" }); err != nil { panic(err) } fmt.Printf("%+v\n") ``` 在上面的代码片段中,`mqttConfig.EnvParse`期望所有带有`MPROXY_`前缀的环境变量。 例如: - MPROXY_ADDRESS - MPROXY_PATH_PREFIX - MPROXY_TARGET - MPROXY_CERT_FILE - MPROXY_KEY_FILE - MPROXY_SERVER_CA_FILE - MPROXY_CLIENT_CA_FILE - MPROXY_CERT_VERIFICATION_METHODS - MPROXY_OCSP_DEPTH - MPROXY_OCSP_RESPONDER_URL - MPROXY_CRL_DEPTH - MPROXY_CRL_DISTRIBUTION_POINTS - MPROXY_CRL_DISTRIBUTION_POINTS_ISSUER_CERT_FILE - MPROXY_OFFLINE_CRL_FILE - MPROXY_OFFLINE_CRL_ISSUER_CERT_FILE ## 许可证 [Apache-2.0](LICENSE) [grc]: https://goreportcard.com/badge/github.com/absmach/mgate [LIC]: LICENCE [LIC-BADGE]: https://img.shields.io/badge/License-Apache_2.0-blue.svg