mosproxy

源码: https://github.com/IrineSistiana/mosproxyarrow-up-right

License: GNU General Public License v3.0arrow-up-right

Docker image: https://github.com/IrineSistiana/mosproxy/pkgs/container/mosproxyarrow-up-right

简介

一个 DNS 转发工具/框架。

  • 支持主流 DNS 协议。(UDP/TCP/TLS/HTTPS/HTTP3/QUIC)

  • 支持转发/复写/缓存 ECS (EDNS0 Client Subnet)。

  • 支持上游负载均衡 (QPS 限制,健康检查,自动 fallback)。

  • 可根据请求的 域名/HTTP Path/SNI/来源 IP 决定转发目的地。

  • 提供 middleware 插件接口可扩展转发逻辑。

  • 支持双向 TLS 验证 (mTLS) 。

  • 内置 prometheus metrics 统计。

性能优化:

  • 网络 IO

    • 所有出站协议会尽可能的连接/socket复用。

    • fasthttparrow-up-right 实现的高性能 HTTP/1 服务端。适合反向代理。

  • 高效的域名和 IP 匹配器。规则会优化成一个二进制索引,0(log(n)) 匹配复杂度,瞬间(百纳秒级别)完成匹配。0 碎片内存,0 GC压力,更少内存占用,以 100w 条规则为例,heap object 数量 300w -> 1 。

  • 缓存:

    • otterarrow-up-right 实现的内存缓存。

    • rueidisarrow-up-right 实现的 redis 缓存。

    • 内存和 redis 缓存可同时启用,组成多级缓存。一级内存,二级 redis。相比单 redis 缓存,因为如果一级内存缓存命中则无需再请求 redis,能大幅降低 mosproxy (约 30%) 和 redis (约 95%) 负载。

    • 支持基于物理地域的缓存 (geo based cache)。可以让相同物理地域(比如,相同省市和运营商)的客户共享缓存。相比传统按照 ECS 网段缓存方案,可将一个地区碎片的 IP 段聚合为一个缓存,提高缓存效率。

    • 缓存数据使用 S2 压缩arrow-up-right 。降低内存占用和约 90% heap object 数量 (n 条缓存 heap object 数量 ~20n -> 2n)。

  • 1vCPU 可承受约 5w/qps 请求量。

命令

mosproxy router -c config.yaml

proxy

如果仅需要简单的将所有请求转发至上游,无需复杂的路由逻辑,可以使用 proxy 子命令在命令行直接启动一个转发服务,无需配置文件。

chevron-rightproxy 子命令帮助 (可能不是最新,以 mosproxy proxy -h 命令输出为准)hashtag

配置

ENV

  • MOSPROXY_JSONLOGGER=true 可以让日志以纯 json 形式输出。性能更好并且便于日志处理。

API

  • GET /metrics: prometheus metrics

  • GET /ctl/reload: 重载资源文件(ecs ip zone,ecs zone overwrite, domain set)。如果成功,返回 200 。否则 500 。只有全部文件成功重载才会应用更改,不会出现重载一半的情况。

域名表文件

支持 3 种匹配规则。

格式: [domain:|full:|regexp:]<规则> # 注释

  • domain: (默认) 域匹配。匹配这个域名和其子域。

  • full: 全匹配。

  • regexp: 正则匹配。

域匹配和全匹配非常高效。所有规则会优化成一个二进制索引,0(log(n)) 匹配复杂度。以载入 Cloudflare radar 全球热门 100w 域名arrow-up-right 为例,文件大小 14M,载入用时约 1s,载入后二进制索引约 40M,匹配用时约 100ns。

正则匹配无法优化,是遍历匹配。会在 域匹配和全匹配 之后匹配。

ECS IP Zone 文件

格式: <起始IP(包含)>,<结束IP(包含)>,<zone标识> # 注释

IP 段不能有重叠。<zone标识> 不要过长,该字符串会成为缓存的 key 的一部分。

示例:

载入时整个文件会优化成一个二进制索引,0(log(n)) 匹配复杂度。100w 条规则索引约占 25M。

IP Zone 会匹配请求发往上游的 ECS 地址,并用 <zone标识> 标记请求。具有相同 <zone标识> 的请求将共享缓存。

ECS Zone Overwrite 文件

格式: <zone标识>,[<CIDR>|"-"] # 注释

示例:

<zone标识> 不可重复。 空 <zone标识> 可匹配没有 <zone标识> 的请求。CIDR 的后缀代表 ECS 的 mask。- 代表不转发 ECS。

具有 <zone标识> 请求转发至上游时将会附带指定的 ECS。

其他

  • golang 支持的所有平台理论上都能编译并且能用,但本项目只针对 linux 开发/优化。

Middleware 自定义请求处理逻辑

接口声明见 https://github.com/IrineSistiana/mosproxy/blob/dev/app/router/router_middleware.goarrow-up-right

示例 https://github.com/IrineSistiana/mosproxy/blob/dev/app/router/middleware/limit/limit.goarrow-up-right

版本状态

alpha