1778682052
This commit is contained in:
@@ -0,0 +1,631 @@
|
||||
# 任务
|
||||
|
||||
- [x] 开发:参加 IBS 项目晨会,同步昨日问题跟进事项。(李春良 0.5)
|
||||
- [x] 联调:IBS 7.20.0 版本联调,HCDN业务标准化接入-典基平面接入与基础数据模型扩展。(张鹏豪 5)
|
||||
- [x] 开发:monitor 邮件问题,新增日志及 sendIllegalDomainEmail 测试接口。(张鹏豪 1)
|
||||
- [x] 测试:新增的参数“IsCreditControl”为非枚举值时,增加校验。(郑子雯 1)
|
||||
- [x] 测试:企业月流量中分发平面下拉框信息与实际分发平面信息不对等。(李英浩 0.5)
|
||||
|
||||
# 日志
|
||||
|
||||
现在想要讨论一个新功能的方案,关于配置。也是代理工具主要的一个部分。
|
||||
|
||||
当前我有两个主要的功能模块:
|
||||
|
||||
1. 控制(这个模块填写的配置链接获取的必须是完整的配置包含节点信息的。)
|
||||
2. 日志
|
||||
|
||||
首先节点的来源从一个 clash 订阅获取,这里我我希望实现类似于 Sub-Store 那种效果(此项目在 D:\MyCode\Study\Sub-Store 中,你可以翻看实现逻辑),这个功能点就是从一个 clash 顺利转换出各种协议的 sing-box 节点备用。
|
||||
|
||||
用户可以提供一个自己的预填模版(没有节点信息):类似:
|
||||
|
||||
```
|
||||
{
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "mixed-in",
|
||||
"type": "mixed",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 20122
|
||||
},
|
||||
{
|
||||
"tag": "tun-in",
|
||||
"type": "tun",
|
||||
"address": ["172.18.0.1/30"],
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"route_exclude_address": ["111.1.51.182/32", "112.17.28.117/32"],
|
||||
"stack": "mixed",
|
||||
"platform": {
|
||||
"http_proxy": {
|
||||
"enabled": true,
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 20122
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "默认",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "✈️ Telegram",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "▶️ YouTube",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "📺 Netflix",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "🌐 Google",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "🤖 AI",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "💭 X",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "♾️ Meta",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "🎬 TikTok",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "💰 PayPal",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": [
|
||||
"默认",
|
||||
"🇺🇸 美国",
|
||||
"🇭🇰 香港",
|
||||
"🇹🇼 台湾",
|
||||
"🇸🇬 新加坡",
|
||||
"🇯🇵 日本",
|
||||
"公益",
|
||||
"直连"
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "🇺🇸 美国",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": ["🇺🇸 美国自动♻️"]
|
||||
},
|
||||
{
|
||||
"tag": "🇭🇰 香港",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": ["🇭🇰 香港自动♻️"]
|
||||
},
|
||||
{
|
||||
"tag": "🇹🇼 台湾",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": []
|
||||
},
|
||||
{
|
||||
"tag": "🇸🇬 新加坡",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": []
|
||||
},
|
||||
{
|
||||
"tag": "🇯🇵 日本",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": []
|
||||
},
|
||||
{
|
||||
"tag": "🇺🇸 美国自动♻️",
|
||||
"type": "urltest",
|
||||
"outbounds": [],
|
||||
"url": "http://www.apple.com/library/test/success.html",
|
||||
"interrupt_exist_connections": true
|
||||
},
|
||||
{
|
||||
"tag": "🇭🇰 香港自动♻️",
|
||||
"type": "urltest",
|
||||
"outbounds": [],
|
||||
"url": "http://www.apple.com/library/test/success.html",
|
||||
"interrupt_exist_connections": true
|
||||
},
|
||||
{
|
||||
"tag": "公益",
|
||||
"type": "selector",
|
||||
"interrupt_exist_connections": true,
|
||||
"outbounds": []
|
||||
},
|
||||
{
|
||||
"tag": "直连",
|
||||
"type": "direct"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"action": "hijack-dns",
|
||||
"port": 53
|
||||
},
|
||||
{
|
||||
"action": "reject",
|
||||
"network": "udp",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"action": "reject",
|
||||
"protocol": "quic"
|
||||
},
|
||||
{
|
||||
"action": "hijack-dns",
|
||||
"protocol": "dns"
|
||||
},
|
||||
{
|
||||
"type": "logical",
|
||||
"mode": "or",
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": ["excalicode.org"]
|
||||
},
|
||||
{
|
||||
"ip_cidr": ["82.158.226.4"]
|
||||
}
|
||||
],
|
||||
"outbound": "直连"
|
||||
},
|
||||
{
|
||||
"rule_set": ["Telegram", "Telegram_Ip"],
|
||||
"outbound": "✈️ Telegram"
|
||||
},
|
||||
{
|
||||
"rule_set": ["Youtube"],
|
||||
"outbound": "▶️ YouTube"
|
||||
},
|
||||
{
|
||||
"rule_set": ["Netflix"],
|
||||
"outbound": "📺 Netflix"
|
||||
},
|
||||
{
|
||||
"rule_set": ["Google"],
|
||||
"outbound": "🌐 Google"
|
||||
},
|
||||
{
|
||||
"rule_set": ["OpenAI", "Claude", "Gemini"],
|
||||
"outbound": "🤖 AI"
|
||||
},
|
||||
{
|
||||
"rule_set": ["X"],
|
||||
"outbound": "💭 X"
|
||||
},
|
||||
{
|
||||
"rule_set": ["FaceBook"],
|
||||
"outbound": "♾️ Meta"
|
||||
},
|
||||
{
|
||||
"rule_set": ["TikTok"],
|
||||
"outbound": "🎬 TikTok"
|
||||
},
|
||||
{
|
||||
"rule_set": ["PayPal"],
|
||||
"outbound": "💰 PayPal"
|
||||
},
|
||||
{
|
||||
"rule_set": [
|
||||
"GeoSite-Private",
|
||||
"GeoSite-CN",
|
||||
"GeoIP-Private",
|
||||
"GeoIP-CN"
|
||||
],
|
||||
"outbound": "直连"
|
||||
}
|
||||
],
|
||||
"rule_set": [
|
||||
{
|
||||
"tag": "Work",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/Docker7530/netbox/refs/heads/main/sing-box/rule_set/work.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Telegram",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-telegram.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Telegram_Ip",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/DustinWin/ruleset_geodata/refs/heads/sing-box-ruleset/telegramip.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Youtube",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-youtube.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Netflix",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-netflix.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Google",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-google.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "OpenAI",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-openai.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Claude",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-anthropic.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "Gemini",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-google-gemini.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "X",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-x.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "FaceBook",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-facebook.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "TikTok",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-tiktok.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "PayPal",
|
||||
"type": "remote",
|
||||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/refs/heads/rule-set/geosite-paypal.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "GeoSite-Private",
|
||||
"type": "remote",
|
||||
"url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/private.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "GeoSite-CN",
|
||||
"type": "remote",
|
||||
"url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/cn.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "GeoIP-Private",
|
||||
"type": "remote",
|
||||
"url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geoip/private.srs",
|
||||
"download_detour": "默认"
|
||||
},
|
||||
{
|
||||
"tag": "GeoIP-CN",
|
||||
"type": "remote",
|
||||
"url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geoip/cn.srs",
|
||||
"download_detour": "默认"
|
||||
}
|
||||
],
|
||||
"auto_detect_interface": true,
|
||||
"default_domain_resolver": {
|
||||
"server": "Local-DNS"
|
||||
}
|
||||
},
|
||||
"dns": {
|
||||
"servers": [
|
||||
{
|
||||
"tag": "Local-DNS",
|
||||
"type": "https",
|
||||
"domain_resolver": "Hosts",
|
||||
"server": "doh.pub"
|
||||
},
|
||||
{
|
||||
"tag": "Fakeip-DNS",
|
||||
"type": "fakeip",
|
||||
"inet4_range": "198.18.0.0/15",
|
||||
"inet6_range": "fc00::/18"
|
||||
},
|
||||
{
|
||||
"tag": "Work-Test-DNS",
|
||||
"type": "udp",
|
||||
"server": "172.22.102.231",
|
||||
"bind_interface": "wg0"
|
||||
},
|
||||
{
|
||||
"tag": "Work-Oa-DNS",
|
||||
"type": "udp",
|
||||
"server": "10.54.2.232",
|
||||
"bind_interface": "wg0"
|
||||
},
|
||||
{
|
||||
"tag": "Hosts",
|
||||
"type": "hosts",
|
||||
"predefined": {
|
||||
"doh.pub": ["1.12.12.21", "120.53.53.53"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": [
|
||||
{
|
||||
"domain": ["koms.komect.net"],
|
||||
"server": "Work-Oa-DNS"
|
||||
},
|
||||
{
|
||||
"rule_set": ["Work"],
|
||||
"server": "Work-Test-DNS"
|
||||
},
|
||||
{
|
||||
"rule_set": ["GeoSite-Private", "GeoSite-CN"],
|
||||
"server": "Local-DNS"
|
||||
},
|
||||
{
|
||||
"query_type": ["A", "AAAA"],
|
||||
"server": "Fakeip-DNS"
|
||||
}
|
||||
],
|
||||
"strategy": "prefer_ipv4"
|
||||
},
|
||||
"experimental": {
|
||||
"clash_api": {
|
||||
"external_controller": "0.0.0.0:9595",
|
||||
"external_ui": "ui",
|
||||
"external_ui_download_url": "https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
|
||||
"external_ui_download_detour": "默认",
|
||||
"secret": ""
|
||||
},
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_fakeip": true,
|
||||
"store_rdrc": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
这个东西先设计为通过 URL 拉取的形式吧类似与这种:
|
||||
|
||||
```
|
||||
https://raw.githubusercontent.com/Docker7530/netbox/refs/heads/main/sing-box/config/config_sub.json
|
||||
```
|
||||
|
||||
然后重点来了,我想给用户一个脚本区域。实现节点和模版配置的拼接类似:
|
||||
|
||||
```
|
||||
const CONFIG = {
|
||||
name: "all",
|
||||
type: "collection",
|
||||
includeUnsupportedProxy: false,
|
||||
groups: [
|
||||
{
|
||||
outbound: "🇭🇰 香港",
|
||||
tags: String.raw`^(?!.*公益).*(港|hk|hongkong|kong kong|🇭🇰)`,
|
||||
},
|
||||
{
|
||||
outbound: "🇹🇼 台湾",
|
||||
tags: String.raw`^(?!.*公益).*(台|tw|taiwan|🇹🇼)`,
|
||||
},
|
||||
{
|
||||
outbound: "🇯🇵 日本",
|
||||
tags: String.raw`^(?!.*公益).*(日本|jp|japan|🇯🇵)`,
|
||||
},
|
||||
{
|
||||
outbound: "🇸🇬 新加坡",
|
||||
tags: String.raw`^(?!.*公益).*(新|sg|singapore|🇸🇬)`,
|
||||
},
|
||||
{
|
||||
outbound: "🇺🇸 美国",
|
||||
tags: String.raw`^(?!.*公益).*(美|us|unitedstates|united states|🇺🇸)`,
|
||||
},
|
||||
{ outbound: "公益", tags: String.raw`公益` },
|
||||
],
|
||||
};
|
||||
|
||||
const args = (typeof $arguments === "object" && $arguments) || {};
|
||||
|
||||
const subscriptionName =
|
||||
(typeof args.name === "string" && args.name.trim()) || CONFIG.name;
|
||||
|
||||
const t = args.type?.trim?.().toLowerCase?.();
|
||||
const subscriptionType =
|
||||
t === "s" || t === "subscription" ? "subscription" : CONFIG.type;
|
||||
|
||||
const rawConfig = $content ?? $files?.[0];
|
||||
const parser = ProxyUtils.JSON5 || JSON;
|
||||
const config = parser.parse(rawConfig);
|
||||
|
||||
if (!Array.isArray(config.outbounds)) {
|
||||
throw new TypeError("配置文件格式错误: outbounds 字段缺失或不是数组");
|
||||
}
|
||||
|
||||
const proxies = await produceArtifact({
|
||||
name: subscriptionName,
|
||||
type: subscriptionType,
|
||||
platform: "sing-box",
|
||||
produceType: "internal",
|
||||
produceOpts: {
|
||||
"include-unsupported-proxy": CONFIG.includeUnsupportedProxy,
|
||||
},
|
||||
});
|
||||
|
||||
const rules = CONFIG.groups.map((rule) => ({
|
||||
outboundReg: new RegExp(rule.outbound, "i"),
|
||||
tagReg: new RegExp(rule.tags, "i"),
|
||||
}));
|
||||
|
||||
for (const outbound of config.outbounds) {
|
||||
if (!Array.isArray(outbound.outbounds)) continue;
|
||||
const targetRules = rules.filter(({ outboundReg }) =>
|
||||
outboundReg.test(outbound.tag)
|
||||
);
|
||||
for (const { tagReg } of targetRules) {
|
||||
const matchedTags = proxies
|
||||
.filter(({ tag }) => tagReg.test(tag))
|
||||
.map(({ tag }) => tag);
|
||||
if (matchedTags.length > 0) {
|
||||
outbound.outbounds.push(...matchedTags);
|
||||
} else if (!outbound.outbounds.includes("直连")) {
|
||||
outbound.outbounds.push("直连");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.outbounds.push(...proxies);
|
||||
|
||||
$content = JSON.stringify(config, null, 2);
|
||||
|
||||
```
|
||||
|
||||
这是我在 substore 的实现效果,你可以更具咋们当前的项目设计一下这个脚本操作怎么暴露给用户合适。更高级,现代化,符合咋们的项目。
|
||||
|
||||
然后还有个问题,这里生成的配置怎么和 控制模块结合,是以控制模块选择应用的形式还是怎么合适。先出一版设计方案。
|
||||
|
||||
---
|
||||
|
||||
招聘【全栈工程师】全职/兼职
|
||||
|
||||
1. 工作内容:宠物类小程序全栈维护,前端后端及开发 bug 修复
|
||||
2. 工作待遇:工资面谈,创始股权激励
|
||||
3. 要求:熟悉 ai 工作原理,有 5 年以上全栈经验,5-10 年技术开发经验
|
||||
4. 工作时间:弹性工作制,时间灵活
|
||||
5. 工作地点:接受线上办公
|
||||
6. 联系方式:18613375551
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
curl --location 'http://localhost:8082/api/monitor/ops/illegal/domain/email/send?email=15033848944%40163.com' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '[
|
||||
{
|
||||
"provider": "阿里云",
|
||||
"domain": "example.com"
|
||||
},
|
||||
{
|
||||
"provider": "腾讯云",
|
||||
"domain": "test.com"
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
# 总结
|
||||
Reference in New Issue
Block a user