利用v2ray api实现流量统计以及增删用户

首先需要知道的是v2ray(下面简写“v2”)的配置文件格式为json,形式如下:

{
  "log": {},
  "api": {},
  "dns": {},
  "stats": {},
  "routing": {},
  "policy": {},
  "reverse": {},
  "inbounds": [],
  "outbounds": [],
  "transport": {}
}

v2配置很多但总体就上面几大类,把握这个有助于你写配置。简单解释下这几个含义:

log:日志配置

api:配置远程控制api

dns:配置内置的dns服务器

stats:配置数据统计

routing:配置路由

policy:配置本地策略

reverse:配置反向代理

inbounds:配置入站连接

outbounds:配置出站连接

transport:配置如何与其它服务器建立和使用网络连接

这里我们要说的是api,来实现用户流量的统计和用户的增删。

配置文件

我们先要配置v2文件。要实现流量统计功能,配置内需要确保存在以下配置:

  1. "stats":{} 对象的存在
  2. "policy" 中的统计开关为 true。全局统计的开关在 "system" 下,用户统计的开关在 "levels" 下
  3. 全局统计在相应的入站出站要有 tag
  4. 用户统计在 "clients" 里面要有 email

要使用 api 查询流量,配置内需要确保存在以下配置:

  1. "api" 配置对象里面有 StatsService
  2. 专用的 dokodemo-door 协议的入口,tag 为 api
  3. routing 里面有 inboundTag:api -> outboundTag:api 的规则

配置示例

{
    "stats": {},
    "api": {
        "tag": "api",
        "services": [
            "StatsService"
        ]
    },
    "policy": {
        "levels": {
            "0": {
                "statsUserUplink": true,
                "statsUserDownlink": true
            }
        },
        "system": {
            "statsInboundUplink": true,
            "statsInboundDownlink": true,
            "statsOutboundUplink": true,
            "statsOutboundDownlink": true
        }
    },
    "inbounds": [
        {
            "tag": "tcp",
            "port": 3307,
            "protocol": "vmess",
            "settings": {
                "clients": [
                    {
                        "email": "auser",
                        "id": "e731f153-4f31-49d3-9e8f-ff8f396135ef",
                        "level": 0,
                        "alterId": 64
                    },
                    {
                        "email": "buser",
                        "id": "e731f153-4f31-49d3-9e8f-ff8f396135ee",
                        "level": 0,
                        "alterId": 64
                    }
                ]
            }
        },
        {
            "listen": "127.0.0.1",
            "port": 10085,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "127.0.0.1"
            },
            "tag": "api"
        }
    ],
    "outbounds": [
        {
            "tag": "direct",
            "protocol": "freedom",
            "settings": {}
        }
    ],
    "routing": {
        "settings": {
            "rules": [
                {
                    "inboundTag": [
                        "api"
                    ],
                    "outboundTag": "api",
                    "type": "field"
                }
            ]
        },
        "strategy": "rules"
    }
}

v2会附带安装v2ctl工具,v2ctl支持多个参数其中一个参数是api,借此我们可以实现流量统计。server参数端口为dokodemo-door的端口。

v2ctl api --server=127.0.0.1:10085 StatsService.QueryStats 'pattern: "" reset: false'
v2ctl api --server=127.0.0.1:10085 StatsService.GetStats 'name: "inbound>>>statin>>>traffic>>>downlink" reset: false'

虽然有v2ctl这个现成工具,但我们还是需要自己写脚本,因为v2ctl只能流量统计,用户的增删还实现不了。v2的api其实是打开了一个 grpc 协议的查询接口,我们只要借助任何一个支持grpc协议的语言就能调用。支持grpc协议的有很多,只要安装中间件,php都可跑。我们这里选择官方支持内存占用小的go语言。

go语言实现

先安装go语言,把go放入系统环境。然后下载v2和grpc的包。

go get -insecure v2ray.com/core
go get google.golang.org/grpc

开始写脚本,下面的代码参考了文章:调用 V2Ray 提供的 API 接口进行用户增删及流量统计查询操作。为了适合我的v2和go运行做了一点修改,增加了部分代码实现用户流量查询。

package main
import (
        "context"
        "fmt"
        "log"
        "google.golang.org/grpc"
        "v2ray.com/core/app/proxyman/command"
        statsService "v2ray.com/core/app/stats/command"
        "v2ray.com/core/common/protocol"
        "v2ray.com/core/common/serial"
        "v2ray.com/core/proxy/vmess"
)
const (
        API_ADDRESS = "127.0.0.1"
        API_PORT    = 10085
        INBOUND_TAG = "tcp"
        LEVEL   = 0
        EMAIL   = "[email protected]"
        UUID    = "2601070b-ab53-4352-a290-1d44414581ee"
        ALTERID = 32
)
func addUser(c command.HandlerServiceClient) {
        resp, err := c.AlterInbound(context.Background(), &command.AlterInboundRequest{
                Tag: INBOUND_TAG,
                Operation: serial.ToTypedMessage(&command.AddUserOperation{
                        User: &protocol.User{
                                Level: LEVEL,
                                Email: EMAIL,
                                Account: serial.ToTypedMessage(&vmess.Account{
                                        Id:               UUID,
                                        AlterId:          ALTERID,
                                        SecuritySettings: &protocol.SecurityConfig{Type: protocol.SecurityType_AUTO},
                                }),
                        },
                }),
        })
        if err != nil {
                log.Printf("failed to call grpc command: %v", err)
        } else {
                log.Printf("ok: %v", resp)
        }
}
func removeUser(c command.HandlerServiceClient) {
        resp, err := c.AlterInbound(context.Background(), &command.AlterInboundRequest{
                Tag: INBOUND_TAG,
                Operation: serial.ToTypedMessage(&command.RemoveUserOperation{
                        Email: EMAIL,
                }),
        })
        if err != nil {
                log.Printf("failed to call grpc command: %v", err)
        } else {
                log.Printf("ok: %v", resp)
        }
}
func queryUserTraffic(c statsService.StatsServiceClient) {
        resp, err := c.QueryStats(context.Background(), &statsService.QueryStatsRequest{
                Pattern: "user>>>[email protected]>>>traffic>>>uplink", // 筛选用户表达式
                Reset_:  false,  // 查询完成后是否重置流量
        })
        if err != nil {
                log.Printf("failed to call grpc command: %v", err)
        }
        // 获取返回值中的流量信息
        stat := resp.GetStat()
        // 返回的是一个数组,对其进行遍历输出
        for _, e := range stat {
                fmt.Println(e)
        }
}

func main() {
        cmdConn, err := grpc.Dial(fmt.Sprintf("%s:%d", API_ADDRESS, API_PORT), grpc.WithInsecure())
        if err != nil {
                panic(err)
        }
        //hsClient := command.NewHandlerServiceClient(cmdConn)
        hsClient_traffic := statsService.NewStatsServiceClient(cmdConn)
        //addUser(hsClient)
        //removeUser(hsClient)
        queryUserTraffic(hsClient_traffic)
}

动手能力强的就可以参考sspanel、v2board等前端面板提供的网页api实现v2后端接入,sspanel的可以直接参考它提供的python版ss后端代码写:sspanel配套ss后端。目前v2后端市面上均收费,价格在60-80刀/年,200-300刀/永久,小机场还是有经济压力的,而免费版不到100个用户又是不够用。上面代码实现了流量统计和用户增删,这两个功能其实可以当做一个简单的后端运行了。上报用户ip、审计、限速等功能如果能再完善,基本就算是个完整功能的后端了。

文章来源于互联网:利用v2ray api实现流量统计以及增删用户

♨ 本站资源均来源于互联网,如有侵权请联系站长,将第一时间删除;
♨ 本站资源售价只是赞助,收取费用仅维持本站的日常运营及外购所需;
♨ 资源仅供学习参考请,勿商用或其它非法用途,否则一切后果用户自负。
阿里码库 » 利用v2ray api实现流量统计以及增删用户

发表评论