Files
3x-ui-agent/tools/census/census.sql
T

166 lines
11 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ITEM6 B0 存量普查(只读计数版)
-- 用途:为第 6 条 sing-box 迁移的 N1-N10 风险项取得现网确切存量数字。
-- 纪律:全部语句只输出计数/分组计数,不输出任何设置内容、凭据、地址。
-- 跑法(在 HW-SG 上,对现网库的副本跑,不要直连生产文件):
-- cp /etc/x-ui/x-ui.db /tmp/census.db
-- sqlite3 /tmp/census.db < census.sql > census-out.txt
-- 把 census-out.txt 整份贴回即可。
--
-- 防御式 JSON 读法:所有 json_extract 都套
-- case when json_valid(列) then 列 end
-- 存量里存在 stream_settings='' 的行(备份库实证),裸 json_extract 会
-- 报 malformed JSON 中断整份脚本;套上后非法/空 JSON 一律按"无此字段"计。
-- 若某条报 "no such table"(如老库无 agent_nodes),把该条结果记为
-- 「表不存在」贴回,不要中断其余条目。
.mode list
.headers off
-- Q00 入站总量与启用分布
select 'Q00_total_inbounds', count(*) from inbounds;
select 'Q00_enabled', count(*) from inbounds where enable;
-- Q01 各协议入站数(ITEM6-SCOPE §4.1 全协议面)
select 'Q01_protocol', protocol, count(*) from inbounds group by protocol order by count(*) desc;
-- Q02 传输分布(stream_settings.network;空串/无 stream 的单列)
select 'Q02_network', coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.network'), '(none)') as net, count(*)
from inbounds group by net order by count(*) desc;
-- Q03 安全层分布
select 'Q03_security', coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security'), '(none)') as sec, count(*)
from inbounds group by sec order by count(*) desc;
-- Q04 N8: xhttp 存量
select 'Q04_xhttp', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.network') = 'xhttp';
-- Q05 N8: kcp(mKCP) 存量
select 'Q05_kcp', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.network') = 'kcp';
-- Q06 N6: Shadowsocks method 分组(sing-box 已移除 cfb/ctr 类须单列)
select 'Q06_ss_method', coalesce(json_extract(case when json_valid(settings) then settings end, '$.method'), '(missing)') as method, count(*)
from inbounds where protocol = 'shadowsocks' group by method order by count(*) desc;
-- Q07 Hysteria 版本分组(v1/v2 分发两个 sing-box type)
select 'Q07_hysteria_version', coalesce(cast(json_extract(case when json_valid(settings) then settings end, '$.version') as text), '(missing)') as ver, count(*)
from inbounds where protocol = 'hysteria' group by ver;
-- Q08 N5: trojan 客户带 flow 的入站数
select 'Q08_trojan_flow_inbounds', count(*) from inbounds i
where i.protocol = 'trojan' and exists (
select 1 from json_each(case when json_valid(i.settings) then json_extract(i.settings, '$.clients') end) je
where coalesce(json_extract(je.value, '$.flow'), '') <> '');
-- Q09 vless flow 分布(vision / udp443 待归一 / 无 flow 三档,按入站计)
select 'Q09_vless_flow_vision', count(*) from inbounds i
where i.protocol = 'vless' and exists (
select 1 from json_each(case when json_valid(i.settings) then json_extract(i.settings, '$.clients') end) je
where json_extract(je.value, '$.flow') = 'xtls-rprx-vision');
select 'Q09_vless_flow_udp443', count(*) from inbounds i
where i.protocol = 'vless' and exists (
select 1 from json_each(case when json_valid(i.settings) then json_extract(i.settings, '$.clients') end) je
where json_extract(je.value, '$.flow') = 'xtls-rprx-vision-udp443');
-- Q10 N3: vlessenc(settings.decryption 非 none)在用入站数
select 'Q10_vlessenc', count(*) from inbounds
where protocol = 'vless'
and coalesce(json_extract(case when json_valid(settings) then settings end, '$.decryption'), 'none') not in ('', 'none');
-- Q11 N4: vless 客户带 reverse 的入站数
select 'Q11_vless_reverse_inbounds', count(*) from inbounds i
where i.protocol = 'vless' and exists (
select 1 from json_each(case when json_valid(i.settings) then json_extract(i.settings, '$.clients') end) je
where json_extract(je.value, '$.reverse') is not null);
-- Q12 N1: fallbacks 存量(表形态 + settings 内嵌形态,两处都要)
select 'Q12_fallback_rows', count(*) from inbound_fallbacks;
select 'Q12_fallback_masters', count(distinct master_id) from inbound_fallbacks;
select 'Q12_fallback_children', count(distinct child_id) from inbound_fallbacks;
select 'Q12_fallback_embedded', count(*) from inbounds
where json_type(case when json_valid(settings) then settings end, '$.fallbacks') = 'array'
and json_array_length(case when json_valid(settings) then settings end, '$.fallbacks') > 0;
-- Q13 N9: finalmask 存量(入站 stream 级 + hosts 覆写级)
select 'Q13_finalmask_inbounds', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.finalmask') is not null;
select 'Q13_finalmask_salamander', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.finalmask') is not null
and stream_settings like '%salamander%';
select 'Q13_finalmask_hosts', count(*) from hosts where coalesce(final_mask, '') <> '';
-- Q14 N10: Reality 高级字段在用计数(只数"设了的行数",不出值)
select 'Q14_reality_total', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality';
select 'Q14_reality_xver_nonzero', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.xver'), 0) <> 0;
select 'Q14_reality_mldsa65seed', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.mldsa65Seed'), '') <> '';
select 'Q14_reality_mldsa65verify', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.settings.mldsa65Verify'), '') <> '';
select 'Q14_reality_minclientver', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.minClientVer'), '') <> '';
select 'Q14_reality_maxclientver', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.maxClientVer'), '') <> '';
select 'Q14_reality_maxtimediff', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.maxTimediff'), 0) <> 0;
select 'Q14_reality_limitfallback', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and (json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.limitFallbackUpload') is not null
or json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.limitFallbackDownload') is not null);
select 'Q14_reality_masterkeylog', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.masterKeyLog'), '') <> '';
select 'Q14_reality_show_on', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.security') = 'reality'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.realitySettings.show'), 0) <> 0;
-- Q15 sockopt 存量(入站 stream 级 + hosts 覆写级)
select 'Q15_sockopt_inbounds', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.sockopt') is not null;
select 'Q15_sockopt_hosts', count(*) from hosts where coalesce(sockopt_params, '') <> '';
-- Q16 sniffing:启用数、destOverride 分组、fakedns 在用数
select 'Q16_sniff_enabled', count(*) from inbounds
where coalesce(json_extract(case when json_valid(sniffing) then sniffing end, '$.enabled'), 0) <> 0;
select 'Q16_sniff_destoverride', coalesce(json_extract(case when json_valid(sniffing) then sniffing end, '$.destOverride'), '(none)') as dest, count(*)
from inbounds group by dest order by count(*) desc;
select 'Q16_sniff_fakedns', count(*) from inbounds where sniffing like '%fakedns%';
-- Q17 Q4: agent 出口覆盖填写数(agent_nodes.outbounds / routing_rules 非空行数)
select 'Q17_agent_nodes', count(*) from agent_nodes;
select 'Q17_agent_outbounds_set', count(*) from agent_nodes where coalesce(trim(outbounds), '') <> '';
select 'Q17_agent_routing_set', count(*) from agent_nodes where coalesce(trim(routing_rules), '') <> '';
-- Q18 N2/Q5: tun / tunnel 入站(本地 node_id 为空 vs 挂 agent 分开计)
select 'Q18_local_protocols', protocol, count(*) from inbounds
where protocol in ('tun', 'tunnel') group by protocol;
select 'Q18_tun_tunnel_on_agent', count(*) from inbounds
where protocol in ('tun', 'tunnel') and node_id is not null and node_id <> 0;
-- Q19 杂项小损项存量:SS ivCheck / HTTP allowTransparent / gRPC multiMode
select 'Q19_ss_ivcheck_on', count(*) from inbounds
where protocol = 'shadowsocks'
and coalesce(json_extract(case when json_valid(settings) then settings end, '$.ivCheck'), 0) <> 0;
select 'Q19_http_transparent_on', count(*) from inbounds
where protocol = 'http'
and coalesce(json_extract(case when json_valid(settings) then settings end, '$.allowTransparent'), 0) <> 0;
select 'Q19_grpc_multimode_on', count(*) from inbounds
where json_extract(case when json_valid(stream_settings) then stream_settings end, '$.network') = 'grpc'
and coalesce(json_extract(case when json_valid(stream_settings) then stream_settings end, '$.grpcSettings.multiMode'), 0) <> 0;
-- Q20 模板键体量(只出长度,语义 diff 由 B1 迁移报告做)
select 'Q20_template_len', length(value) from settings where key = 'xrayTemplateConfig';
-- Q21 P9 转发启用数(inbounds.forwarding 非空且 mode=forward 的行数)
select 'Q21_forwarding_on', count(*) from inbounds
where coalesce(forwarding, '') <> ''
and coalesce(json_extract(case when json_valid(forwarding) then forwarding end, '$.mode'), '') = 'forward';