update 2026-06-26 22:13:14

This commit is contained in:
action 2026-06-26 22:13:14 +08:00
parent 555e431af2
commit 6f8ea90b61
6 changed files with 110 additions and 2 deletions

View File

@ -325,4 +325,10 @@ for k, v in pairs(nodes_table) do
end
end
o = s:option(Flag, "hwid", translate("Send HWID"))
o.default = 0
o.description = translate("Some subscription providers may require a hardware identifier (HWID) for authentication.") .. "<br>" ..
translate("Enabling this option will send a hashed HWID when updating subscriptions.") .. "<br>" ..
translate("This may reveal limited hardware information. Enable only if you trust your provider.")
return m

View File

@ -1758,6 +1758,18 @@ msgstr "گره فرود (Landing Node)"
msgid "Only support a layer of proxy."
msgstr "فقط از یک لایه پروکسی پشتیبانی می‌کند."
msgid "Send HWID"
msgstr "ارسال HWID"
msgid "Some subscription providers may require a hardware identifier (HWID) for authentication."
msgstr "برخی ارائه‌دهندگان اشتراک ممکن است برای احراز هویت به شناسه سخت‌افزاری (HWID) نیاز داشته باشند."
msgid "Enabling this option will send a hashed HWID when updating subscriptions."
msgstr "با فعال کردن این گزینه، هنگام به‌روزرسانی اشتراک‌ها یک HWID هش‌شده ارسال خواهد شد."
msgid "This may reveal limited hardware information. Enable only if you trust your provider."
msgstr "این کار ممکن است بخشی از اطلاعات سخت‌افزاری دستگاه را آشکار کند. فقط در صورتی این گزینه را فعال کنید که به ارائه‌دهنده خود اعتماد دارید."
msgid ""
"Chained proxy works only with Xray or Sing-box nodes.<br>"
"You can only use manual or imported nodes as chained nodes."

View File

@ -1759,6 +1759,18 @@ msgstr "Сервер выхода"
msgid "Only support a layer of proxy."
msgstr "Поддерживается только один уровень цепочки."
msgid "Send HWID"
msgstr "Отправлять HWID"
msgid "Some subscription providers may require a hardware identifier (HWID) for authentication."
msgstr "Некоторые поставщики подписок могут требовать аппаратный идентификатор (HWID) для аутентификации."
msgid "Enabling this option will send a hashed HWID when updating subscriptions."
msgstr "При включении этой опции во время обновления подписок будет отправляться хэшированный HWID."
msgid "This may reveal limited hardware information. Enable only if you trust your provider."
msgstr "Это может раскрыть ограниченную информацию об оборудовании. Включайте эту опцию только в том случае, если доверяете своему поставщику."
msgid ""
"Chained proxy works only with Xray or Sing-box nodes.<br>"
"You can only use manual or imported nodes as chained nodes."

View File

@ -1744,6 +1744,18 @@ msgstr "落地节点"
msgid "Only support a layer of proxy."
msgstr "仅支持一层代理。"
msgid "Send HWID"
msgstr "发送 HWID"
msgid "Some subscription providers may require a hardware identifier (HWID) for authentication."
msgstr "某些订阅服务提供商可能需要硬件标识符HWID进行身份验证。"
msgid "Enabling this option will send a hashed HWID when updating subscriptions."
msgstr "启用此选项后,在更新订阅时将发送经过哈希处理的 HWID。"
msgid "This may reveal limited hardware information. Enable only if you trust your provider."
msgstr "这可能会泄露有限的硬件信息。仅在信任您的服务提供商时启用。"
msgid ""
"Chained proxy works only with Xray or Sing-box nodes.<br>"
"You can only use manual or imported nodes as chained nodes."

View File

@ -1750,6 +1750,18 @@ msgstr "落地節點"
msgid "Only support a layer of proxy."
msgstr "仅支持一層代理。"
msgid "Send HWID"
msgstr "傳送 HWID"
msgid "Some subscription providers may require a hardware identifier (HWID) for authentication."
msgstr "部分訂閱服務提供者可能需要硬體識別碼HWID進行驗證。"
msgid "Enabling this option will send a hashed HWID when updating subscriptions."
msgstr "啟用此選項後,更新訂閱時將傳送經過雜湊處理的 HWID。"
msgid "This may reveal limited hardware information. Enable only if you trust your provider."
msgstr "這可能會洩露有限的硬體資訊。請僅在信任您的服務提供者時啟用。"
msgid ""
"Chained proxy works only with Xray or Sing-box nodes.<br>"
"You can only use manual or imported nodes as chained nodes."

View File

@ -1928,7 +1928,7 @@ local function processData(szType, content, add_mode, group, sub_cfg)
return result
end
local function curl(url, file, ua, mode)
local function curl(url, file, ua, mode, hwid)
if not url or url == "" then return 22, 404 end
local curl_args = {
"-fskL", "-w %{http_code}", "--retry 3", "--connect-timeout 3", "-H 'Accept-Encoding: identity'"
@ -1937,6 +1937,9 @@ local function curl(url, file, ua, mode)
ua = (ua == "passwall2") and ("passwall2/" .. api.get_version()) or ua
curl_args[#curl_args + 1] = '--user-agent "' .. ua .. '"'
end
if hwid == "1" then
curl_args[#curl_args + 1] = get_headers()
end
local return_code, result
if mode == "direct" then
return_code, result = api.curl_direct(url, file, curl_args)
@ -1948,6 +1951,57 @@ local function curl(url, file, ua, mode)
return return_code, tonumber(result)
end
function get_headers()
local cache_file = "/tmp/etc/" .. appname .. "_tmp/sub_curl_headers"
if fs.access(cache_file) then
return luci.sys.exec("cat " .. cache_file)
end
local headers = {}
local function readfile(path)
local f = io.open(path, "r")
if not f then return nil end
local c = f:read("*a")
f:close()
return api.trim(c)
end
headers[#headers + 1] = "x-device-os: OpenWrt"
local rel = readfile("/etc/openwrt_release")
local os_ver = rel and rel:match("DISTRIB_RELEASE='([^']+)'")
if os_ver then
headers[#headers + 1] = "x-ver-os: " .. os_ver
end
local model = readfile("/tmp/sysinfo/model")
if model then
headers[#headers + 1] = "x-device-model: " .. model
end
local mac = readfile("/sys/class/net/eth0/address")
if mac and model then
local raw = mac .. "-" .. model
local p = io.popen("printf '%s' '" .. raw:gsub("'", "'\\''") .. "' | sha256sum")
if p then
local hash = p:read("*l")
p:close()
hash = hash and hash:match("^%w+")
if hash then
headers[#headers + 1] = "x-hwid: " .. hash
end
end
end
local out = {}
for i = 1, #headers do
out[i] = "-H '" .. headers[i]:gsub("'", "'\\''") .. "'"
end
local headers_str = table.concat(out, " ")
local f = io.open(cache_file, "w"); if f then f:write(headers_str); f:close() end
return headers_str
end
local function truncate_nodes(group)
for _, config in pairs(CONFIG) do
if config.currentNodes and #config.currentNodes > 0 then
@ -2409,7 +2463,7 @@ local execute = function()
log(1, i18n.translatef("Start subscribing: %s", '' .. remark .. '' .. url .. ' [' .. result .. ']'))
tmp_file = "/tmp/" .. cfgid
local return_code
return_code, value.http_code = curl(url, tmp_file, ua, access_mode)
return_code, value.http_code = curl(url, tmp_file, ua, access_mode, value.hwid)
if return_code ~= 0 then
fail_list[#fail_list + 1] = value
luci.sys.call("rm -f " .. tmp_file)