From a9b565b00149378bf55fbe78d20197b90f5b339e Mon Sep 17 00:00:00 2001 From: zuiwuchang Date: Fri, 1 Dec 2023 10:22:21 +0800 Subject: [PATCH] getdefualt and dns --- README.md | 5 + bin/js/main.js | 135 +++++++++++++++++++++++ bin/js/xray/inbounds.js | 18 ++- bin/js/xray/routing.js | 64 ++++++----- bin/main.d.ts | 34 ++++++ bin/ts/main.ts | 137 ++++++++++++++++++++++- bin/ts/xray/inbounds.ts | 16 +++ bin/ts/xray/routing.ts | 24 +++- bin/ts/xray/userdata.ts | 15 +++ db/data/settings.go | 231 ++++++++++++++++++++------------------- js/js.go | 42 +++++++ m/web/api/v1/settings.go | 28 ++++- script/conf.sh | 2 +- script/pack.sh | 2 +- 14 files changed, 599 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 4c74d10..e7a5daa 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,10 @@ export interface Provider { * @param opts 生成設定檔的原始參數 */ serve(cnf: string, opts: ConfigureOptions): ServeResult + /** + * 返回默認設定 + */ + getDefault?: () => Default } ``` @@ -156,6 +160,7 @@ export interface Provider { * **metadata** 返回了一個元信息,網頁 ui 會依據它爲各種協議生成輸入 ui,同時系統也會依據它的定義來解析與生成代理節點的訂閱信息 * **configure** 這個函數應該爲 xray 生成設定檔案的內容,以供後續使用它來啓動 xray * **serve** 這個函數應該返回啓動 xray 的命令,cnf 是存儲了 configure 生成內容的檔案路徑 +* **getDefault** 從 v0.0.6 開始支持,如果提供了在用戶請求重置 /settings/general 頁面數據時會由這個函數返回響應內容 一些系統支持設置透明代理(目前官方只維護了 linux windows 腳本),你可以修改下述三個函數來自定義如何啓動與關閉你所在平臺的透明代理 diff --git a/bin/js/main.js b/bin/js/main.js index fe11052..f932ed2 100644 --- a/bin/js/main.js +++ b/bin/js/main.js @@ -215,4 +215,139 @@ ${s} } return core.lookupHost(address); } + /** + * 返回默認設定 + */ + getDefault() { + return { + url: 'https://www.youtube.com/', + run: true, + firewall: false, + strategy: 4, + userdata: `// 爲代理設置訪問用戶名密碼 +local accounts = [ + { + // 用戶名 + user: 'killer', + // 密碼 + password: '19890604', + }, +]; +{ + // 日誌設定 + log: { + // 要記錄的日誌等級 + // level: 'debug', // 調試程序時用到的輸出信息 + // level: 'info', // 運行時的狀態信息 + // level: 'warning', // 認的設定,發生了一些不影響正常運作的問題時輸出的訊息,但有可能影響使用者的體驗 + // level: 'error', // 遇到了無法正常運作的問題,需要立即解決 + // level: 'none', // 不記錄任何內容 + + // 如果爲 true 啓用 dns 查詢日誌 + // log: true, + }, + // socks 代理設定 + socks: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 socks 代理 + port: 1080, + // 如果爲 true 則允許代理 udp + udp: true, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // http 代理設定 + http: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 http 代理 + // port: 8118, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // 提供無污染的 dns 服務 + dns: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 dns 服務 + // port: 10053, + }, + // 透明代理設定 + proxy: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 透明代理 + port: 12345, + // 如果爲 true,則在 linnux 下使用 tproxy 作爲全局代理,否則使用 redirect 作爲全局代理 + tproxy: true, + // tproxy mark + mark: 99, + // 只有在 linux 下使用 redirect 模式時有效,如果設置會攔截連接 53 端口的 udp/tcp 重定向到此值 + // dns: '127.0.0.1:10053', + // 目前在 windows 下使用 tun2socks 實現透明代理,這裏是需要提供的一些網卡相關設定 + tun2socks: { + // socks5 代理地址 ip:port,默認爲 127.0.0.1:\${userdata.proxy.port} + // socks5: '192.168.1.1:1080', + // 系統默認上網網關 ip + gateway: '192.168.1.1', + // 虛擬網卡使用的 dns 服務器 ip 地址,不能帶端口 + dns: '8.8.8.8', + // tun2socks 虛擬網卡 ip + addr: '192.168.123.1', + // tun2socks 虛擬網卡 子網掩碼 + mask: '255.255.255.0', + } + }, + routing: { + // 爲 bt 設置出棧 tag + bittorrent: 'out-freedom', // 不使用代理 + // bittorrent: 'out-blackhole', // 阻止訪問 + // bittorrent: 'out-proxy', // 使用代理 + + // 要代理訪問的 ip,忽略策略設定,這些 ip 將始終被代理訪問 + /** + proxyIP: [ + // '8.8.8.8', + ],/**/ + // 要代理訪問的 域名,忽略策略設定,這些 域名 將始終被代理訪問 + /** + proxyDomain: [ + 'geosite:apple', + 'geosite:google', + 'geosite:microsoft', + 'geosite:facebook', + 'geosite:twitter', + 'geosite:telegram', + 'geosite:geolocation-!cn', + 'geosite:tld-!cn', + ],/**/ + + // 要直接訪問的 ip,忽略策略設定,這些 ip 將始終被直接訪問 + /** + directIP: [ + 'geoip:private', + 'geoip:cn', + ],/**/ + // 要直接訪問的 域名,忽略策略設定,這些 域名 將始終被直接訪問 + /** + directDomain: [ + 'geosite:cn', + ],/**/ + + // 要禁止訪問的 ip,忽略策略設定,這些 ip 將始終被禁止訪問 + /** + blockIP: [ + // 'geoip:cn', + ],/**/ + // 要禁止訪問的 域名,忽略策略設定,這些 域名 將始終被禁止訪問 + /**/ + blockDomain: [ + 'geosite:category-ads', + // 'geosite:category-ads-all', + ],/**/ + } +}`, + }; + } } diff --git a/bin/js/xray/inbounds.js b/bin/js/xray/inbounds.js index 454afe0..5976726 100644 --- a/bin/js/xray/inbounds.js +++ b/bin/js/xray/inbounds.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.generateInbounds = void 0; const utils_1 = require("./utils"); function generateInbounds(opts) { - var _a, _b, _c, _d, _e, _f, _g, _h, _j; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; const inbounds = []; let port = opts.environment.port; if ((0, utils_1.isPort)(port)) { @@ -111,6 +111,22 @@ function generateInbounds(opts) { }); } } + port = (_k = userdata === null || userdata === void 0 ? void 0 : userdata.dns) === null || _k === void 0 ? void 0 : _k.port; + if ((0, utils_1.isPort)(port)) { + const dns = userdata.dns; + inbounds.push({ + protocol: 'dokodemo-door', + tag: 'in-dns', + listen: (_l = dns === null || dns === void 0 ? void 0 : dns.bind) !== null && _l !== void 0 ? _l : '0.0.0.0', + port: port, + settings: { + address: '8.8.8.8', + port: 53, + network: 'tcp,udp', + followRedirect: true, + }, + }); + } } return inbounds; } diff --git a/bin/js/xray/routing.js b/bin/js/xray/routing.js index fb46866..417f603 100644 --- a/bin/js/xray/routing.js +++ b/bin/js/xray/routing.js @@ -4,15 +4,16 @@ exports.generateRouting = void 0; const utils_1 = require("./utils"); const rule_1 = require("./strategy/rule"); function generateRouting(opts) { - var _a, _b, _c, _d, _e; + var _a, _b, _c, _d, _e, _f; if ((0, utils_1.isPort)((_a = opts.environment.port) !== null && _a !== void 0 ? _a : 0)) { return; } const strategy = opts.strategy; - const tproxy = ((_c = (_b = opts.userdata) === null || _b === void 0 ? void 0 : _b.proxy) === null || _c === void 0 ? void 0 : _c.tproxy) ? true : false; - const rules = [ - // 攔截域名解析 - !tproxy || (0, utils_1.isWindows)() ? { + const userdata = opts === null || opts === void 0 ? void 0 : opts.userdata; + const rules = []; + if ((0, utils_1.isPort)((_b = userdata === null || userdata === void 0 ? void 0 : userdata.proxy) === null || _b === void 0 ? void 0 : _b.port)) { + const tproxy = ((_c = userdata === null || userdata === void 0 ? void 0 : userdata.proxy) === null || _c === void 0 ? void 0 : _c.tproxy) ? true : false; + rules.push(!tproxy || (0, utils_1.isWindows)() ? { type: 'field', inboundTag: ['in-proxy'], outboundTag: 'out-proxy', @@ -21,35 +22,42 @@ function generateRouting(opts) { inboundTag: ['in-proxy'], port: 53, outboundTag: 'out-dns', - }, - { - type: 'field', - ip: [ - // google - '8.8.8.8', - // cloudflare - '1.1.1.1', - ], - outboundTag: 'out-proxy', - }, - { + }); + } + if ((0, utils_1.isPort)((_d = userdata === null || userdata === void 0 ? void 0 : userdata.dns) === null || _d === void 0 ? void 0 : _d.port)) { + rules.push({ type: 'field', - ip: [ - '119.29.29.29', - '223.5.5.5', - '127.0.0.1', - '::1', // ipv6 本機 - ], - outboundTag: 'out-freedom', - }, - ]; + inboundTag: ['in-dns'], + outboundTag: 'out-dns', + }); + } + // 攔截域名解析 + rules.push({ + type: 'field', + ip: [ + // google + '8.8.8.8', + // cloudflare + '1.1.1.1', + ], + outboundTag: 'out-proxy', + }, { + type: 'field', + ip: [ + '119.29.29.29', + '223.5.5.5', + '127.0.0.1', + '::1', // ipv6 本機 + ], + outboundTag: 'out-freedom', + }); // 代理訪問 let proxy = new rule_1.Rule().pushDomain(strategy.proxyDomain).pushIP(strategy.proxyIP); // 直接連接 let direct = new rule_1.Rule().pushDomain(strategy.directDomain).pushIP(strategy.directIP); // 阻止訪問 let block = new rule_1.Rule().pushDomain(strategy.blockDomain).pushIP(strategy.blockIP); - const routing = (_d = opts.userdata) === null || _d === void 0 ? void 0 : _d.routing; + const routing = (_e = opts.userdata) === null || _e === void 0 ? void 0 : _e.routing; if (routing) { block.pushDomain(routing.blockDomain).pushIP(routing.blockIP); switch (strategy.value) { @@ -69,7 +77,7 @@ function generateRouting(opts) { pushRules(rules, 'out-blackhole', block); // bt 下載 if (routing) { - const bittorrent = (_e = routing.bittorrent) !== null && _e !== void 0 ? _e : ''; + const bittorrent = (_f = routing.bittorrent) !== null && _f !== void 0 ? _f : ''; if (bittorrent != '') { rules.push({ type: 'field', diff --git a/bin/main.d.ts b/bin/main.d.ts index 5ee04fd..cb6e0e4 100644 --- a/bin/main.d.ts +++ b/bin/main.d.ts @@ -422,6 +422,35 @@ declare module 'xray/webui' { */ userdata?: T } + export interface Default { + /** + * 測試請求的網址 + */ + url: string + /** + * 是否自動啓動 xray + */ + run: boolean + /** + * 是否自動啓動透明代理 + */ + firewall: boolean + /** + * 策略 + * + * 1 默認的代理規則 + * 2 全域代理 + * 3 略過區域網路的代理(僅對公網ip使用代理) + * 4 代理優先(略過區域網路和西朝鮮的代理) + * 5 直連優先 (僅對非西朝鮮公網使用代理) + * 6 直接連接 + */ + strategy: 1 | 2 | 3 | 4 | 5 | 6 + /** + * 用戶設定 + */ + userdata: string + } /** * 爲網頁 ui 提供了各種功能的具體實現 */ @@ -465,5 +494,10 @@ declare module 'xray/webui' { * @param opts 生成設定檔的原始參數 */ serve(cnf: string, opts: ConfigureOptions): ServeResult + + /** + * 返回默認設定 + */ + getDefault?: () => Default } } \ No newline at end of file diff --git a/bin/ts/main.ts b/bin/ts/main.ts index d0e5be7..86c83d8 100644 --- a/bin/ts/main.ts +++ b/bin/ts/main.ts @@ -1,5 +1,5 @@ import * as core from "xray/core"; -import { ConfigureOptions, ConfigureResult, Metadata, Provider, ServeResult, TurnOptions } from "xray/webui"; +import { ConfigureOptions, ConfigureResult, Default, Metadata, Provider, ServeResult, TurnOptions } from "xray/webui"; import { vless } from "./metadata/vless"; import { vmess } from "./metadata/vmess"; import { trojan } from "./metadata/trojan"; @@ -181,4 +181,139 @@ ${s} } return core.lookupHost(address) } + /** + * 返回默認設定 + */ + getDefault(): Default { + return { + url: 'https://www.youtube.com/', + run: true, + firewall: false, + strategy: 4, + userdata: `// 爲代理設置訪問用戶名密碼 +local accounts = [ + { + // 用戶名 + user: 'killer', + // 密碼 + password: '19890604', + }, +]; +{ + // 日誌設定 + log: { + // 要記錄的日誌等級 + // level: 'debug', // 調試程序時用到的輸出信息 + // level: 'info', // 運行時的狀態信息 + // level: 'warning', // 認的設定,發生了一些不影響正常運作的問題時輸出的訊息,但有可能影響使用者的體驗 + // level: 'error', // 遇到了無法正常運作的問題,需要立即解決 + // level: 'none', // 不記錄任何內容 + + // 如果爲 true 啓用 dns 查詢日誌 + // log: true, + }, + // socks 代理設定 + socks: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 socks 代理 + port: 1080, + // 如果爲 true 則允許代理 udp + udp: true, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // http 代理設定 + http: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 http 代理 + // port: 8118, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // 提供無污染的 dns 服務 + dns: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 dns 服務 + // port: 10053, + }, + // 透明代理設定 + proxy: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 透明代理 + port: 12345, + // 如果爲 true,則在 linnux 下使用 tproxy 作爲全局代理,否則使用 redirect 作爲全局代理 + tproxy: true, + // tproxy mark + mark: 99, + // 只有在 linux 下使用 redirect 模式時有效,如果設置會攔截連接 53 端口的 udp/tcp 重定向到此值 + // dns: '127.0.0.1:10053', + // 目前在 windows 下使用 tun2socks 實現透明代理,這裏是需要提供的一些網卡相關設定 + tun2socks: { + // socks5 代理地址 ip:port,默認爲 127.0.0.1:\${userdata.proxy.port} + // socks5: '192.168.1.1:1080', + // 系統默認上網網關 ip + gateway: '192.168.1.1', + // 虛擬網卡使用的 dns 服務器 ip 地址,不能帶端口 + dns: '8.8.8.8', + // tun2socks 虛擬網卡 ip + addr: '192.168.123.1', + // tun2socks 虛擬網卡 子網掩碼 + mask: '255.255.255.0', + } + }, + routing: { + // 爲 bt 設置出棧 tag + bittorrent: 'out-freedom', // 不使用代理 + // bittorrent: 'out-blackhole', // 阻止訪問 + // bittorrent: 'out-proxy', // 使用代理 + + // 要代理訪問的 ip,忽略策略設定,這些 ip 將始終被代理訪問 + /** + proxyIP: [ + // '8.8.8.8', + ],/**/ + // 要代理訪問的 域名,忽略策略設定,這些 域名 將始終被代理訪問 + /** + proxyDomain: [ + 'geosite:apple', + 'geosite:google', + 'geosite:microsoft', + 'geosite:facebook', + 'geosite:twitter', + 'geosite:telegram', + 'geosite:geolocation-!cn', + 'geosite:tld-!cn', + ],/**/ + + // 要直接訪問的 ip,忽略策略設定,這些 ip 將始終被直接訪問 + /** + directIP: [ + 'geoip:private', + 'geoip:cn', + ],/**/ + // 要直接訪問的 域名,忽略策略設定,這些 域名 將始終被直接訪問 + /** + directDomain: [ + 'geosite:cn', + ],/**/ + + // 要禁止訪問的 ip,忽略策略設定,這些 ip 將始終被禁止訪問 + /** + blockIP: [ + // 'geoip:cn', + ],/**/ + // 要禁止訪問的 域名,忽略策略設定,這些 域名 將始終被禁止訪問 + /**/ + blockDomain: [ + 'geosite:category-ads', + // 'geosite:category-ads-all', + ],/**/ + } +}`, + } + } } diff --git a/bin/ts/xray/inbounds.ts b/bin/ts/xray/inbounds.ts index 7fb9df4..7b21294 100644 --- a/bin/ts/xray/inbounds.ts +++ b/bin/ts/xray/inbounds.ts @@ -107,6 +107,22 @@ export function generateInbounds(opts: ConfigureOptions): Array): Routing | und return } const strategy = opts.strategy - const tproxy = opts.userdata?.proxy?.tproxy ? true : false - const rules: Array = [ - // 攔截域名解析 - !tproxy || isWindows() ? { + const userdata = opts?.userdata + + const rules: Array = [] + if (isPort(userdata?.proxy?.port)) { + const tproxy = userdata?.proxy?.tproxy ? true : false + rules.push(!tproxy || isWindows() ? { type: 'field', inboundTag: ['in-proxy'], outboundTag: 'out-proxy', @@ -104,7 +106,17 @@ export function generateRouting(opts: ConfigureOptions): Routing | und inboundTag: ['in-proxy'], port: 53, outboundTag: 'out-dns', - }, + }) + } + if (isPort(userdata?.dns?.port)) { + rules.push({ + type: 'field', + inboundTag: ['in-dns'], + outboundTag: 'out-dns', + }) + } + // 攔截域名解析 + rules.push( { type: 'field', ip: [ @@ -125,7 +137,7 @@ export function generateRouting(opts: ConfigureOptions): Routing | und ], outboundTag: 'out-freedom', }, - ] + ) // 代理訪問 let proxy = new StrategyRule().pushDomain(strategy.proxyDomain).pushIP(strategy.proxyIP) // 直接連接 diff --git a/bin/ts/xray/userdata.ts b/bin/ts/xray/userdata.ts index a88cfcf..860ab76 100644 --- a/bin/ts/xray/userdata.ts +++ b/bin/ts/xray/userdata.ts @@ -19,6 +19,17 @@ export interface Socks { */ accounts?: Array } +export interface DNS { + /** + * 監聽地址 + * @default '0.0.0.0' + */ + bind?: string + /** + * 監聽端口,如果 < 1 則不啓用 dns 服務 + */ + port?: number +} export interface HTTP { /** * 監聽地址 @@ -131,6 +142,10 @@ export interface Userdata { * http 代理設定 */ http?: HTTP + /** + * 提供無污染的 dns 服務 + */ + dns?: DNS /** * 透明代理設定 */ diff --git a/db/data/settings.go b/db/data/settings.go index f3ecfad..f19ee4a 100644 --- a/db/data/settings.go +++ b/db/data/settings.go @@ -110,118 +110,125 @@ func (g *General) ResetDefault() { const DefaultUserdata = `// 爲代理設置訪問用戶名密碼 local accounts = [ - { - // 用戶名 - user: 'killer', - // 密碼 - password: '19890604', - }, + { + // 用戶名 + user: 'killer', + // 密碼 + password: '19890604', + }, ]; { - // 日誌設定 - log: { - // 要記錄的日誌等級 - // level: 'debug', // 調試程序時用到的輸出信息 - // level: 'info', // 運行時的狀態信息 - // level: 'warning', // 認的設定,發生了一些不影響正常運作的問題時輸出的訊息,但有可能影響使用者的體驗 - // level: 'error', // 遇到了無法正常運作的問題,需要立即解決 - // level: 'none', // 不記錄任何內容 - - // 如果爲 true 啓用 dns 查詢日誌 - // log: true, - }, - // socks 代理設定 - socks: { - // 監聽地址,默認 '127.0.0.1' - // bind: '0.0.0.0', - // 監聽端口,如果無效 則不啓用 socks 代理 - port: 1080, - // 如果爲 true 則允許代理 udp - udp: true, - // 用戶數組默認不需要認證 - // accounts: accounts, - }, - // http 代理設定 - http: { - // 監聽地址,默認 '127.0.0.1' - // bind: '0.0.0.0', - // 監聽端口,如果無效 則不啓用 http 代理 - // port: 8118, - // 用戶數組默認不需要認證 - // accounts: accounts, - }, - // 透明代理設定 - proxy: { - // 監聽地址,默認 '0.0.0.0' - // bind: '127.0.0.1', - // 監聽端口,如果無效 則不啓用 透明代理 - port: 12345, - // 如果爲 true,則在 linnux 下使用 tproxy 作爲全局代理,否則使用 redirect 作爲全局代理 - tproxy: true, - // tproxy mark - mark: 99, - // 只有在 linux 下使用 redirect 模式時有效,如果設置會攔截連接 53 端口的 udp/tcp 重定向到此值 - // dns: '127.0.0.1:10053', - // 目前在 windows 下使用 tun2socks 實現透明代理,這裏是需要提供的一些網卡相關設定 - tun2socks: { - // socks5 代理地址 ip:port,默認爲 127.0.0.1:${userdata.proxy.port} - // socks5: '192.168.1.1:1080', - // 系統默認上網網關 ip - gateway: '192.168.1.1', - // 虛擬網卡使用的 dns 服務器 ip 地址,不能帶端口 - dns: '8.8.8.8', - // tun2socks 虛擬網卡 ip - addr: '192.168.123.1', - // tun2socks 虛擬網卡 子網掩碼 - mask: '255.255.255.0', - } - }, - routing: { - // 爲 bt 設置出棧 tag - bittorrent: 'out-freedom', // 不使用代理 - // bittorrent: 'out-blackhole', // 阻止訪問 - // bittorrent: 'out-proxy', // 使用代理 - - // 要代理訪問的 ip,忽略策略設定,這些 ip 將始終被代理訪問 - /** - proxyIP: [ - // '8.8.8.8', - ],/**/ - // 要代理訪問的 域名,忽略策略設定,這些 域名 將始終被代理訪問 - /** - proxyDomain: [ - 'geosite:apple', - 'geosite:google', - 'geosite:microsoft', - 'geosite:facebook', - 'geosite:twitter', - 'geosite:telegram', - 'geosite:geolocation-!cn', - 'geosite:tld-!cn', - ],/**/ - - // 要直接訪問的 ip,忽略策略設定,這些 ip 將始終被直接訪問 - /** - directIP: [ - 'geoip:private', - 'geoip:cn', - ],/**/ - // 要直接訪問的 域名,忽略策略設定,這些 域名 將始終被直接訪問 - /** - directDomain: [ - 'geosite:cn', - ],/**/ - - // 要禁止訪問的 ip,忽略策略設定,這些 ip 將始終被禁止訪問 - /** - blockIP: [ - // 'geoip:cn', - ],/**/ - // 要禁止訪問的 域名,忽略策略設定,這些 域名 將始終被禁止訪問 - /**/ - blockDomain: [ - 'geosite:category-ads', - // 'geosite:category-ads-all', - ],/**/ - } + // 日誌設定 + log: { + // 要記錄的日誌等級 + // level: 'debug', // 調試程序時用到的輸出信息 + // level: 'info', // 運行時的狀態信息 + // level: 'warning', // 認的設定,發生了一些不影響正常運作的問題時輸出的訊息,但有可能影響使用者的體驗 + // level: 'error', // 遇到了無法正常運作的問題,需要立即解決 + // level: 'none', // 不記錄任何內容 + + // 如果爲 true 啓用 dns 查詢日誌 + // log: true, + }, + // socks 代理設定 + socks: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 socks 代理 + port: 1080, + // 如果爲 true 則允許代理 udp + udp: true, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // http 代理設定 + http: { + // 監聽地址,默認 '127.0.0.1' + // bind: '0.0.0.0', + // 監聽端口,如果無效 則不啓用 http 代理 + // port: 8118, + // 用戶數組默認不需要認證 + // accounts: accounts, + }, + // 提供無污染的 dns 服務 + dns: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 dns 服務 + // port: 10053, + }, + // 透明代理設定 + proxy: { + // 監聽地址,默認 '0.0.0.0' + // bind: '127.0.0.1', + // 監聽端口,如果無效 則不啓用 透明代理 + port: 12345, + // 如果爲 true,則在 linnux 下使用 tproxy 作爲全局代理,否則使用 redirect 作爲全局代理 + tproxy: true, + // tproxy mark + mark: 99, + // 只有在 linux 下使用 redirect 模式時有效,如果設置會攔截連接 53 端口的 udp/tcp 重定向到此值 + // dns: '127.0.0.1:10053', + // 目前在 windows 下使用 tun2socks 實現透明代理,這裏是需要提供的一些網卡相關設定 + tun2socks: { + // socks5 代理地址 ip:port,默認爲 127.0.0.1:${userdata.proxy.port} + // socks5: '192.168.1.1:1080', + // 系統默認上網網關 ip + gateway: '192.168.1.1', + // 虛擬網卡使用的 dns 服務器 ip 地址,不能帶端口 + dns: '8.8.8.8', + // tun2socks 虛擬網卡 ip + addr: '192.168.123.1', + // tun2socks 虛擬網卡 子網掩碼 + mask: '255.255.255.0', + } + }, + routing: { + // 爲 bt 設置出棧 tag + bittorrent: 'out-freedom', // 不使用代理 + // bittorrent: 'out-blackhole', // 阻止訪問 + // bittorrent: 'out-proxy', // 使用代理 + + // 要代理訪問的 ip,忽略策略設定,這些 ip 將始終被代理訪問 + /** + proxyIP: [ + // '8.8.8.8', + ],/**/ + // 要代理訪問的 域名,忽略策略設定,這些 域名 將始終被代理訪問 + /** + proxyDomain: [ + 'geosite:apple', + 'geosite:google', + 'geosite:microsoft', + 'geosite:facebook', + 'geosite:twitter', + 'geosite:telegram', + 'geosite:geolocation-!cn', + 'geosite:tld-!cn', + ],/**/ + + // 要直接訪問的 ip,忽略策略設定,這些 ip 將始終被直接訪問 + /** + directIP: [ + 'geoip:private', + 'geoip:cn', + ],/**/ + // 要直接訪問的 域名,忽略策略設定,這些 域名 將始終被直接訪問 + /** + directDomain: [ + 'geosite:cn', + ],/**/ + + // 要禁止訪問的 ip,忽略策略設定,這些 ip 將始終被禁止訪問 + /** + blockIP: [ + // 'geoip:cn', + ],/**/ + // 要禁止訪問的 域名,忽略策略設定,這些 域名 將始終被禁止訪問 + /**/ + blockDomain: [ + 'geosite:category-ads', + // 'geosite:category-ads-all', + ],/**/ + } }` diff --git a/js/js.go b/js/js.go index 207a4e4..07528a1 100644 --- a/js/js.go +++ b/js/js.go @@ -139,6 +139,29 @@ func (vm *Runtime) assertFunction(name string) (self goja.Value, f, destroy goja f = callable return } +func (vm *Runtime) findFunction(name string) (self goja.Value, f, destroy goja.Callable, e error) { + self, e = vm.create(goja.Undefined()) + if e != nil { + return + } + o, ok := self.(*goja.Object) + if !ok { + e = errors.New(`script method create must return Provider`) + return + } + val := o.Get(`destroy`) + callable, ok := goja.AssertFunction(val) + if ok { + destroy = callable + } + + val = o.Get(name) + callable, ok = goja.AssertFunction(val) + if ok { + f = callable + } + return +} func (vm *Runtime) TurnOn(rawURL string, u *url.URL) error { return vm.turn(rawURL, u, `turnOn`) } @@ -727,3 +750,22 @@ func (vm *Runtime) Start(ctx context.Context, info *data.Last) (cmd *exec.Cmd, e cmd = exec.Command(obj.Name, obj.Args...) return } +func (vm *Runtime) GetDefault() (text string, ok bool, e error) { + self, f, destroy, e := vm.assertFunction(`getDefault`) + if e != nil { + return + } else if destroy != nil { + defer destroy(self) + } + if f != nil { + var val goja.Value + val, e = f(self) + val, e = vm.stringify(vm.json, val) + if e != nil { + return + } + text = val.String() + ok = true + } + return +} diff --git a/m/web/api/v1/settings.go b/m/web/api/v1/settings.go index 02071bc..dbbd81a 100644 --- a/m/web/api/v1/settings.go +++ b/m/web/api/v1/settings.go @@ -13,8 +13,10 @@ import ( "github.com/gin-gonic/gin" "github.com/google/go-jsonnet" + "github.com/zuiwuchang/xray_webui/configure" "github.com/zuiwuchang/xray_webui/db/data" "github.com/zuiwuchang/xray_webui/db/manipulator" + "github.com/zuiwuchang/xray_webui/js" "github.com/zuiwuchang/xray_webui/log" "github.com/zuiwuchang/xray_webui/m/web" "github.com/zuiwuchang/xray_webui/utils" @@ -59,12 +61,30 @@ func (h *Settings) Register(router *gin.RouterGroup) { r.POST(`element_import/:subscription`, h.ImportElement) } func (h *Settings) GetDefault(c *gin.Context) { - h.SetHTTPCacheMaxAge(c, h.maxage) - h.ServeLazyJSON(c, ``, h.general.Load().(time.Time), func() (any, error) { + // h.SetHTTPCacheMaxAge(c, h.maxage) + // h.ServeLazyJSON(c, ``, h.general.Load().(time.Time), func() (any, error) { + // var resp data.General + // resp.ResetDefault() + // return resp, nil + // }) + vm, e := js.New(configure.Default().System.Script) + if e != nil { + c.String(http.StatusInternalServerError, e.Error()) + return + } + js, ok, e := vm.GetDefault() + if e != nil { + c.String(http.StatusInternalServerError, e.Error()) + return + } + if ok { + c.Writer.Header().Set(`Content-Type`, `application/json; charset=utf-8`) + c.String(http.StatusOK, js) + } else { var resp data.General resp.ResetDefault() - return resp, nil - }) + c.JSON(http.StatusOK, &resp) + } } func (h *Settings) GetGeneral(c *gin.Context) { h.SetHTTPCacheMaxAge(c, h.maxage) diff --git a/script/conf.sh b/script/conf.sh index c3bfe1f..810da13 100644 --- a/script/conf.sh +++ b/script/conf.sh @@ -1,7 +1,7 @@ Target="xray-webui" Docker="king011/xray-webui" Dir=$(cd "$(dirname $BASH_SOURCE)/.." && pwd) -Version="v0.0.5" +Version="v0.0.6" View=1 Platforms=( darwin/amd64 diff --git a/script/pack.sh b/script/pack.sh index c31692b..2960b0d 100755 --- a/script/pack.sh +++ b/script/pack.sh @@ -55,5 +55,5 @@ for i in ${!Platforms[@]};do platform=${Platforms[i]} step=i+1 echo "step $step/$steps" - "$BashDir/go.sh" -p "$pack" -P "$platform" + "$BashDir/go.sh" -p "$pack" -P "$platform" -u done \ No newline at end of file