diff --git a/README.md b/README.md index 9d6c17f..10b0bc7 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,23 @@ Note also that for current client config, traffic to .cn, .ru, .by and .ir sites [here](https://github.com/EvgenyNerush/coherence-grabber) for details. This makes your server much less attention-grabbing and suspicious, but your connection less anonymous. +### Statistics + +(in bytes) + +Client: +``` +xray api stats --server=127.0.0.1:8080 -name "inbound>>>http>>>traffic>>>downlink" +xray api stats --server=127.0.0.1:8080 -name "inbound>>>http>>>traffic>>>uplink" +xray api stats --server=127.0.0.1:8080 -name "inbound>>>socks>>>traffic>>>downlink" +xray api stats --server=127.0.0.1:8080 -name "inbound>>>socks>>>traffic>>>uplink" +``` +Server: +``` +xray api stats --server=127.0.0.1:8080 -name "user>>>[email]>>>traffic>>>uplink" +xray api stats --server=127.0.0.1:8080 -name "user>>>[email]>>>traffic>>>downlink" +``` + ### Other clients For Windows, MacOS or Android you can try Nekobox, v2rayNG or ? (TODO): tests and config generation for them. diff --git a/ex.sh b/ex.sh index ccfa055..630c859 100755 --- a/ex.sh +++ b/ex.sh @@ -128,7 +128,7 @@ containing only digits 0-9 and letters a-f, for instance Better if it is: hosted by your VPS provider, in the same country, it is popular, and have only ports 80 (http) and 443 (https) open -(can check with `nmap -T4 hostname`) +(can check with nmap -T4 hostname) (1) www.youtube.com (default) (2) www.microsoft.com (3) www.google.com @@ -170,13 +170,18 @@ and have only ports 80 (http) and 443 (https) open email="love@xray.com" # make server config jsonc2json template_config_server.jsonc \ - | jq ".inbounds[].settings.clients[0].id=\"${id}\" - | .inbounds[].settings.clients[0].email=\"${email}\" - | .inbounds[0].streamSettings.realitySettings.dest=\"${fake_site}:443\" - | .inbounds[1].streamSettings.realitySettings.dest=\"${fake_site}:80\" - | .inbounds[].streamSettings.realitySettings.serverNames=${server_names} - | .inbounds[].streamSettings.realitySettings.privateKey=\"${private_key}\" - | .inbounds[].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ]" \ + | jq ".inbounds[1].settings.clients[0].id=\"${id}\" + | .inbounds[2].settings.clients[0].id=\"${id}\" + | .inbounds[1].settings.clients[0].email=\"${email}\" + | .inbounds[2].settings.clients[0].email=\"${email}\" + | .inbounds[1].streamSettings.realitySettings.dest=\"${fake_site}:443\" + | .inbounds[2].streamSettings.realitySettings.dest=\"${fake_site}:80\" + | .inbounds[1].streamSettings.realitySettings.serverNames=${server_names} + | .inbounds[2].streamSettings.realitySettings.serverNames=${server_names} + | .inbounds[1].streamSettings.realitySettings.privateKey=\"${private_key}\" + | .inbounds[2].streamSettings.realitySettings.privateKey=\"${private_key}\" + | .inbounds[1].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ] + | .inbounds[2].streamSettings.realitySettings.shortIds=[ \"${short_id}\" ]" \ > config_server.json # then make the user (not root) the owner of the file [[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" config_server.json @@ -286,7 +291,7 @@ containing only digits 0-9 and letters a-f, for instance " cp config_server.json config_server.json.backup # update server config - cat config_server.json.backup | jq ".inbounds[0].settings.clients += [${client}] | .inbounds[0].streamSettings.realitySettings.shortIds += [\"${short_id}\"]" > config_server.json + cat config_server.json.backup | jq ".inbounds[1].settings.clients += [${client}] | .inbounds[1].streamSettings.realitySettings.shortIds += [\"${short_id}\"]" > config_server.json # then make the user (not root) an owner of a file [[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" config_server.json echo -e "${green}config_client_${username}.json is written, @@ -317,7 +322,7 @@ then short_id=$(jq ".outbounds[0].streamSettings.realitySettings.shortId" $config) cp config_server.json config_server.json.backup # update server config - cat config_server.json.backup | jq "del(.inbounds[0].settings.clients[] | select(.email == \"${username}@example.com\")) | del(.inbounds[0].streamSettings.realitySettings.shortIds[] | select(. == ${short_id}))" > config_server.json + cat config_server.json.backup | jq "del(.inbounds[1].settings.clients[] | select(.email == \"${username}@example.com\")) | del(.inbounds[1].streamSettings.realitySettings.shortIds[] | select(. == ${short_id}))" > config_server.json # then make the user (not root) an owner of a file [[ $SUDO_USER ]] && chown "$SUDO_USER:$SUDO_USER" config_server.json rm config_client_${username}.json diff --git a/template_config_client.jsonc b/template_config_client.jsonc index c2b2a8c..5ffa325 100644 --- a/template_config_client.jsonc +++ b/template_config_client.jsonc @@ -7,8 +7,44 @@ "loglevel": "warning", "dnsLog": false }, + // Turns on traffic statistics, see https://xtls.github.io/en/config/stats.html#statsobject + // and https://xtls.github.io/en/config/policy.html#policyobject + // and special "api" tag below + "stats": { + }, + "policy": { + "levels": { + // default level + "0": { + "statsUserUplink": true, + "statsUserDownlink": true + } + }, + "system": { + "statsInboundUplink": true, + "statsInboundDownlink": true, + "statsOutboundUplink": true, + "statsOutboundDownlink": true + } + }, + // enables API interface https://xtls.github.io/en/config/api.html#apiobject + "api": { + "tag": "api", + "services": [ "StatsService" ] + }, // client-side inbound configuration "inbounds": [ + // gRPC API inbound, used to get statistics + { + "listen": "127.0.0.1", + "port": 8080, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1" + }, + "tag": "api" + }, + // socks proxy { "tag": "socks", "port": 800, @@ -22,12 +58,13 @@ "tls" ] }, - // settings of inbound `protocol` (see above) + // settings of inbound "protocol" (see above) "settings": { "auth": "noauth", "udp": true } }, + // http/https proxy { "tag": "http", "port": 801, @@ -42,7 +79,7 @@ ], "routeOnly": false }, - // settings of inbound `protocol` (see above) + // settings of inbound "protocol" (see above) "settings": { "auth": "noauth", "udp": true @@ -105,6 +142,13 @@ "routing": { "domainStrategy": "AsIs", "rules": [ + { + "type": "field", + "inboundTag": [ + "api" + ], + "outboundTag": "api" + }, { "type": "field", "domain": [ diff --git a/template_config_server.jsonc b/template_config_server.jsonc index 0d540fe..d99ecef 100644 --- a/template_config_server.jsonc +++ b/template_config_server.jsonc @@ -7,11 +7,43 @@ "loglevel": "warning", "dnsLog": false }, + // Turns on traffic statistics, see https://xtls.github.io/en/config/stats.html#statsobject + // and https://xtls.github.io/en/config/policy.html#policyobject + // and special "api" tag below + "stats": { + }, + "policy": { + "levels": { + // default level + "0": { + "statsUserUplink": true, + "statsUserDownlink": true + } + }, + "system": { + "statsInboundUplink": true, + "statsInboundDownlink": true, + "statsOutboundUplink": true, + "statsOutboundDownlink": true + } + }, + // enables API interface https://xtls.github.io/en/config/api.html#apiobject + "api": { + "tag": "api", + "services": [ "StatsService" ] + }, // Forward each inbound connections to corresponding `outboundTag`. If no rules match, // the traffic is sent out by the first outbound in `outbounds` section. "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ + { + "type": "field", + "inboundTag": [ + "api" + ], + "outboundTag": "api" + }, { "type": "field", "port": "80", @@ -64,6 +96,16 @@ }, // server-side inbound configuration "inbounds": [ + // gRPC API inbound, used to get statistics + { + "listen": "127.0.0.1", + "port": 8080, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1" + }, + "tag": "api" + }, // main inbound, clients connect to it { "listen": "0.0.0.0",