找回密码
 立即注册
首页 业界区 业界 VKProxy已提供命令行工具,镜像和简单的ui ...

VKProxy已提供命令行工具,镜像和简单的ui

穆望 2025-6-14 13:36:57
VKProxy 是使用c#开发的基于 Kestrel 实现 L4/L7的代理
经过6个月业余时间偶尔缝缝补补,已经达到能跑的地步了  (感兴趣的同学烦请点个github小赞赞呢)
相关使用写了一些简单的文档说明

  • 安装
  • 通过UI站点配置
  • 不同监听场景如何配置
  • 如何为HTTP配置路由复杂匹配
  • 如何为HTTP配置请求和响应转换
这里列举一下新增的安装使用方式
dotnet tool

提供简单的命令行工具,可以在本地进行相关测试
  1. dotnet tool install --global VKProxy.Cli
复制代码
不过目前只支持 net9.0 (net10 正式发布后会切换制net10)
安装后可以使用如下命令
  1. vkproxy -h
  2. // it will output
  3. --config (-c)       json file config, like /xx/app.json
  4. --socks5            use simple socks5 support
  5. --etcd              etcd address, like http://127.0.0.1:2379
  6. --etcd-prefix       default is /ReverseProxy/
  7. --etcd-delay        delay change config when etcd change, default is 00:00:01
  8. --help (-h)         show all options
  9. View more at https://fs7744.github.io/VKProxy.Doc/docs/introduction.html
复制代码
如果使用json文件配置

配置项很多,可参考后续具体配置项说明
这里举个例子
创建json文件
  1. {
  2.   "ReverseProxy": {
  3.     "Listen": {
  4.       "http": {
  5.         "Protocols": [
  6.           "Http1"
  7.         ],
  8.         "Address": [
  9.           "127.0.0.1:5001"
  10.         ]
  11.       }
  12.     },
  13.     "Routes": {
  14.       "HTTPTEST": {
  15.         "Match": {
  16.           "Hosts": [
  17.             "*com"
  18.           ],
  19.           "Paths": [
  20.             "/ws*"
  21.           ],
  22.           "Statement": "Method = 'GET'"
  23.         },
  24.         "ClusterId": "apidemo",
  25.         "Timeout": "00:10:11"
  26.       }
  27.     },
  28.     "Clusters": {
  29.       "apidemo": {
  30.         "LoadBalancingPolicy": "RoundRobin",
  31.         "HealthCheck": {
  32.           "Active": {
  33.             "Enable": true,
  34.             "Policy": "Http",
  35.             "Path": "/test",
  36.             "Query": "?a=d",
  37.             "Method": "post"
  38.           }
  39.         },
  40.         "Destinations": [
  41.           {
  42.             "Address": "http://127.0.0.1:1104"
  43.           },
  44.           {
  45.             "Address": "https://google.com"
  46.           }
  47.         ]
  48.       }
  49.     }
  50.   }
  51. }
复制代码
然后启动
  1. vkproxy -c D:\code\test\proxy\config.json
  2. // 启动后会看到类似如下的内容
  3. info: VKProxy.Server.ReverseProxy[3]
  4.       Listening on: [Key: http,Protocols: HTTP1,EndPoint: 127.0.0.1:5001]
  5. info: Microsoft.Hosting.Lifetime[0]
  6.       Application started. Press Ctrl+C to shut down.
  7. info: Microsoft.Hosting.Lifetime[0]
  8.       Hosting environment: Production
  9. info: Microsoft.Hosting.Lifetime[0]
  10.       Content root path: D:\code\test\proxy
  11. warn: VKProxy.Server.ReverseProxy[5]
  12.       Active health failed, can not connect socket 127.0.0.1:1104 No connection could be made because the target machine actively refused it. (127.0.0.1:1104).
复制代码
使用 etcd 配置

在多实例的情况,同一份配置分发就比较麻烦, 这里提供 ui 可以配置etcd + agent 从etcd读取配置 方便大家使用
ui使用可以参考 UI配置站点
用tool 启动 agent 可以这样使用
  1. vkproxy --etcd http://127.0.0.1:2379 --etcd-prefix /ReverseProxy/
  2. // 启动后会看到类似如下的内容
  3. info: VKProxy.Server.ReverseProxy[3]
  4.       Listening on: [Key: http,Protocols: HTTP1,EndPoint: 127.0.0.1:5001]
  5. info: Microsoft.Hosting.Lifetime[0]
  6.       Application started. Press Ctrl+C to shut down.
  7. info: Microsoft.Hosting.Lifetime[0]
  8.       Hosting environment: Production
  9. info: Microsoft.Hosting.Lifetime[0]
  10.       Content root path: D:\code\test\proxy
  11. warn: VKProxy.Server.ReverseProxy[5]
  12.       Active health failed, can not connect socket 127.0.0.1:1104 No connection could be made because the target machine actively refused it. (127.0.0.1:1104).
复制代码
Docker

当大家基本代理功能足够时,简化大家使用成本/快速构建的默认已构建镜像
所有的镜像可以在 docker hub vkproxy agent 找到
提供如下环境变量

  • VKPROXY_CONFIG
    json file config, like /xx/app.json
    example VKPROXY_CONFIG=/xx/app.json
  • VKPROXY_SOCKS5
    use simple socks5 support
    example VKPROXY_SOCKS5=true
  • ETCD_CONNECTION_STRING
    etcd address, like http://127.0.0.1:2379
    example ETCD_CONNECTION_STRING=http://127.0.0.1:2379
  • ETCD_PREFIX
    default is /ReverseProxy/
    example ETCD_PREFIX=/ReverseProxy/
  • ETCD_DELAY
    delay change config when etcd change, default is 00:00:01
    example ETCD_DELAY=00:00:01
如果使用json文件配置

配置项很多,可参考后续具体配置项说明
这里举个例子
创建json文件
  1. {
  2.   "ReverseProxy": {
  3.     "Listen": {
  4.       "http": {
  5.         "Protocols": [
  6.           "Http1"
  7.         ],
  8.         "Address": [
  9.           "127.0.0.1:5001"
  10.         ]
  11.       }
  12.     },
  13.     "Routes": {
  14.       "HTTPTEST": {
  15.         "Match": {
  16.           "Hosts": [
  17.             "*com"
  18.           ],
  19.           "Paths": [
  20.             "/ws*"
  21.           ],
  22.           "Statement": "Method = 'GET'"
  23.         },
  24.         "ClusterId": "apidemo",
  25.         "Timeout": "00:10:11"
  26.       }
  27.     },
  28.     "Clusters": {
  29.       "apidemo": {
  30.         "LoadBalancingPolicy": "RoundRobin",
  31.         "HealthCheck": {
  32.           "Active": {
  33.             "Enable": true,
  34.             "Policy": "Http",
  35.             "Path": "/test",
  36.             "Query": "?a=d",
  37.             "Method": "post"
  38.           }
  39.         },
  40.         "Destinations": [
  41.           {
  42.             "Address": "http://127.0.0.1:1104"
  43.           },
  44.           {
  45.             "Address": "https://google.com"
  46.           }
  47.         ]
  48.       }
  49.     }
  50.   }
  51. }
复制代码
然后启动
  1. docker run --rm -v /mnt/d/code/test/proxy:/config -e VKPROXY_CONFIG=/config/config
  2. .json -e ETCD_CONNECTION_STRING= --network host a.newegg.org/docker-hub-remote/vkproxy/agent:0.0.0.6
  3. // 启动后会看到类似如下的内容
  4. info: VKProxy.Server.ReverseProxy[3]
  5.       Listening on: [Key: http,Protocols: HTTP1,EndPoint: 127.0.0.1:5001]
  6. info: Microsoft.Hosting.Lifetime[0]
  7.       Application started. Press Ctrl+C to shut down.
  8. info: Microsoft.Hosting.Lifetime[0]
  9.       Hosting environment: Production
  10. info: Microsoft.Hosting.Lifetime[0]
  11.       Content root path: /app
  12. warn: VKProxy.Server.ReverseProxy[5]
  13.       Active health failed, can not connect socket [2404:6800:4012:7::200e]:443 Network is unreachable ([2404:6800:4012:7::200e]:443).
  14. warn: VKProxy.Server.ReverseProxy[5]
  15.       Active health failed, can not connect socket 127.0.0.1:1104 Connection refused (127.0.0.1:1104).
复制代码
使用 etcd 配置

在多实例的情况,同一份配置分发就比较麻烦, 这里提供 ui 可以配置etcd + agent 从etcd读取配置 方便大家使用
ui使用可以参考 UI配置站点
用 docker 启动 agent 可以这样使用
  1. docker run --rm -e ETCD_CONNECTION_STRING=http://127.0.0.1:2379 --network host vkproxy/agent:0.0.0.6
  2. // 启动后会看到类似如下的内容
  3. info: VKProxy.Server.ReverseProxy[3]
  4.       Listening on: [Key: http,Protocols: HTTP1,EndPoint: 127.0.0.1:5001]
  5. info: Microsoft.Hosting.Lifetime[0]
  6.       Application started. Press Ctrl+C to shut down.
  7. info: Microsoft.Hosting.Lifetime[0]
  8.       Hosting environment: Production
  9. info: Microsoft.Hosting.Lifetime[0]
  10.       Content root path: D:\code\test\proxy
  11. warn: VKProxy.Server.ReverseProxy[5]
  12.       Active health failed, can not connect socket 127.0.0.1:1104 No connection could be made because the target machine actively refused it. (127.0.0.1:1104).
复制代码
通过UI站点配置

由于文件配置存在一定使用难度,所以也有提供简单的 ui配置站点VKProxy.Web
[!WARNING]
由于文件分发会导致大家部署多实例的难度,所以 ui 站点目前只支持 etcd 作为配置源, 同时服务器参数相关无法通过ui站点配置, 请使用文件会程序配置 参见服务器参数
首先启动一个 etcd (可参考 Run etcd clusters inside containers)
  1. export NODE1=127.0.0.1
  2. ETCD_VERSION=v3.4.37
  3. REGISTRY=quay.io/coreos/etcd
  4. # available from v3.2.5
  5. REGISTRY=gcr.io/etcd-development/etcd
  6. docker run \
  7.   -p 2379:2379 \
  8.   -p 2380:2380 \
  9.   --volume=${DATA_DIR}:/etcd-data \
  10.   --name etcd ${REGISTRY}:${ETCD_VERSION} \
  11.   /usr/local/bin/etcd \
  12.   --data-dir=/etcd-data --name node1 \
  13.   --initial-advertise-peer-urls http://${NODE1}:2380 --listen-peer-urls http://0.0.0.0:2380 \
  14.   --advertise-client-urls http://${NODE1}:2379 --listen-client-urls http://0.0.0.0:2379 \
  15.   --initial-cluster node1=http://${NODE1}:2380
复制代码
VKProxy agent 启动参考 安装
UI 所有的镜像可以在 docker hub vkproxy ui 找到
UI docker 部署
参数可以使用如下

  • ETCD_CONNECTION_STRING
    etcd address, like http://127.0.0.1:2379
    example ETCD_CONNECTION_STRING=http://127.0.0.1:2379
  • ETCD_PREFIX
    default is /ReverseProxy/
    example ETCD_PREFIX=/ReverseProxy/
  • ASPNETCORE_URLS
    example ASPNETCORE_URLS=http://*:80
举例:
  1. docker run --rm -e ETCD_CONNECTION_STRING=http://127.0.0.1:2379 -e ASPNETCORE_URLS=http://*:8770 --network host vkproxy/ui:0.0.0.7
  2. // 启动后会看到类似输出
  3. warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]
  4.       Overriding HTTP_PORTS '8080' and HTTPS_PORTS ''. Binding to values defined by URLS instead 'http://*:8770'.
  5. info: Microsoft.Hosting.Lifetime[14]
  6.       Now listening on: http://[::]:8770
  7. info: Microsoft.Hosting.Lifetime[0]
  8.       Application started. Press Ctrl+C to shut down.
  9. info: Microsoft.Hosting.Lifetime[0]
  10.       Hosting environment: Production
  11. info: Microsoft.Hosting.Lifetime[0]
  12.       Content root path: /app
复制代码
然后你就可以在浏览器 访问 http://127.0.0.1:8770 使用 UI 了
1.jpeg

定制化扩展

为了方便大家使用 KVProxy 在一些场景,默认功能无法满足时,可以通过自定义扩展实现自己的需求。
同时也是遵照 asp.net core 设计理念,提供了两种扩展方式
中间件管道

中间件是一种装配到应用管道以处理请求和响应的软件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。
请求委托用于生成请求管道。 请求委托处理每个 HTTP/tcp/udp 请求。
具体概念可参考ASP.NET Core 中间件
2.png

KVProxy 添加了 udp 和 tcp 的特殊中间件
具体参见如何通过中间件定制化功能
还有一个socks5的示例以供大家参考如何利用中间件扩展实现socks5
特定功能策略增加

有些特定功能策略比较难以直接使用中间件扩展,这里列举主要部分
(其实由于基于依赖注入,天生解耦,所以内部实现基本都可以覆盖或者添加新实现)

  • 如何扩展服务发现
  • 如何扩展负载均衡策略
  • 如何扩展主动健康检查策略
  • 如何扩展HTTP转换器
ReverseProxyFeature

除了两大扩展方式之外,还有一个接口数据在运行时有表明当前路由匹配情况
  1. public interface IReverseProxyFeature  // http 路由会使用该接口
  2. {
  3.     public RouteConfig Route { get; set; } // 匹配上的路由,如为 null 则未匹配任何路由
  4.     public DestinationState? SelectedDestination { get; set; } // 在选中健康的目标地址后,对应配置会设置在这里
  5. }
  6. public interface IL4ReverseProxyFeature : IReverseProxyFeature // tcp / udp 路由会使用该接口
  7. {
  8.     public bool IsDone { get; set; }  // 表明是否已经处理,当为 true 时,KVProxy 内置L4代理将不会进行代理
  9.     public bool IsSni { get; set; }   // 表明是否为 tcp sni 代理模式
  10.     public SniConfig? SelectedSni { get; set; }  // 为 tcp sni 代理模式时的配置
  11. }
复制代码
运行时可通过 feature 获取, 比如
  1. // http
  2. internal class EchoHttpMiddleware : IMiddleware
  3. {
  4.     public async Task InvokeAsync(HttpContext context, RequestDelegate next)
  5.     {
  6.         var f = context.Features.Get<IReverseProxyFeature>();
  7.     }
  8. }
  9. //tcp
  10. internal class EchoTcpProxyMiddleware : ITcpProxyMiddleware
  11. {
  12.     public Task InitAsync(ConnectionContext context, CancellationToken token, TcpDelegate next)
  13.     {
  14.         var f = context.Features.Get<IL4ReverseProxyFeature>();
  15.     }
  16.     public Task<ReadOnlyMemory<byte>> OnRequestAsync(ConnectionContext context, ReadOnlyMemory<byte> source, CancellationToken token, TcpProxyDelegate next)
  17.     {
  18.         var f = context.Features.Get<IL4ReverseProxyFeature>();
  19.     }
  20.     public Task<ReadOnlyMemory<byte>> OnResponseAsync(ConnectionContext context, ReadOnlyMemory<byte> source, CancellationToken token, TcpProxyDelegate next)
  21.     {
  22.         logger.LogInformation($"tcp {DateTime.Now} {context.Features.Get<IL4ReverseProxyFeature>()?.SelectedDestination?.EndPoint.ToString()} reponse size: {source.Length}");
  23.     }
  24. }
  25. //udp
  26. internal class EchoUdpProxyMiddleware : IUdpProxyMiddleware
  27. {
  28.     public Task InitAsync(UdpConnectionContext context, CancellationToken token, UdpDelegate next)
  29.     {
  30.         var f = context.Features.Get<IL4ReverseProxyFeature>();
  31.     }
  32.     public Task<ReadOnlyMemory<byte>> OnRequestAsync(UdpConnectionContext context, ReadOnlyMemory<byte> source, CancellationToken token, UdpProxyDelegate next)
  33.     {
  34.         var f = context.Features.Get<IL4ReverseProxyFeature>();
  35.     }
  36.     public Task<ReadOnlyMemory<byte>> OnResponseAsync(UdpConnectionContext context, ReadOnlyMemory<byte> source, CancellationToken token, UdpProxyDelegate next)
  37.     {
  38.         logger.LogInformation($"udp {DateTime.Now} {context.Features.Get<IL4ReverseProxyFeature>()?.SelectedDestination?.EndPoint.ToString()} reponse size: {source.Length}");
  39.     }
  40. }
复制代码
不建议大家直接修改 IReverseProxyFeature 的值,可能会破坏路由
可扩展套接字应用程序框架

除了代理功能外,由于通过反射释放了Kestrel的能力,你也可以把 VKProxy 当成可扩展套接字应用程序框架使用
使用它轻松构建始终连接的套接字应用程序,而无需考虑如何使用套接字,如何维护套接字连接以及套接字如何工作。
(在Kestrel基础上开发,理论可以帮大家节省一些比如直接socket要自己管理 socket之类的事情)
具体可以参考可扩展套接字应用程序框架
2025年后续大概就继续添加限流 追踪啊之类功能吧

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册