# 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