update 2024-12-21 20:22:12

This commit is contained in:
actions-user 2024-12-21 20:22:12 +08:00
parent 357f36dc05
commit aede9e2cfd
7 changed files with 266 additions and 26 deletions

View File

@ -8,6 +8,7 @@ local uci = luci.model.uci.cursor() -- in funtion index()
local http = require "luci.http"
local util = require "luci.util"
local i18n = require "luci.i18n"
local fs = require "nixio.fs"
function index()
if not nixio.fs.access("/etc/config/passwall") then
@ -46,7 +47,7 @@ function index()
entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true
entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true
entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true
entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Watch Logs"), 999).leaf = true
entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Log Maint"), 999).leaf = true
--[[ Server ]]
entry({"admin", "services", appname, "server"}, cbi(appname .. "/server/index"), _("Server-Side"), 99).leaf = true
@ -90,6 +91,9 @@ function index()
entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true
entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true
end
--[[Backup]]
entry({"admin", "services", appname, "backup"}, call("create_backup")).leaf = true
end
local function http_write_json(content)
@ -500,9 +504,29 @@ function read_rulelist(list)
else
rule_path = "/usr/share/passwall/rules/chnroute"
end
if api.fs.access(rule_path) then
luci.http.prepare_content("text/plain")
luci.http.write(api.fs.readfile(rule_path))
if fs.access(rule_path) then
http.prepare_content("text/plain")
http.write(fs.readfile(rule_path))
end
end
function create_backup()
local backup_files = {
"/etc/config/passwall",
"/etc/config/passwall_server",
"/usr/share/passwall/rules/block_host",
"/usr/share/passwall/rules/block_ip",
"/usr/share/passwall/rules/direct_host",
"/usr/share/passwall/rules/direct_ip",
"/usr/share/passwall/rules/proxy_host",
"/usr/share/passwall/rules/proxy_ip"
}
local tar_file = "/tmp/passwall-backup.tar.gz"
fs.remove(tar_file)
local cmd = "tar -czf " .. tar_file .. " " .. table.concat(backup_files, " ")
api.sys.call(cmd)
http.header("Content-Disposition", "attachment; filename=passwall-backup.tar.gz")
http.prepare_content("application/octet-stream")
http.write(fs.readfile(tar_file))
fs.remove(tar_file)
end

View File

@ -1,8 +1,72 @@
local api = require "luci.passwall.api"
local http = require "luci.http"
local appname = "passwall"
local fs = api.fs
local sys = api.sys
f = SimpleForm(appname)
f.reset = false
f.submit = false
f:append(Template(appname .. "/log/log"))
return f
fb = SimpleForm('backup-restore')
fb.reset = false
fb.submit = false
s = fb:section(SimpleSection, translate("Backup and Restore"), translate("Backup or Restore Client and Server Configurations."))
o = s:option(DummyValue, '', nil)
o.template = appname .. "/log/backup_restore"
local backup_files = {
"/etc/config/passwall",
"/etc/config/passwall_server",
"/usr/share/passwall/rules/block_host",
"/usr/share/passwall/rules/block_ip",
"/usr/share/passwall/rules/direct_host",
"/usr/share/passwall/rules/direct_ip",
"/usr/share/passwall/rules/proxy_host",
"/usr/share/passwall/rules/proxy_ip"
}
local file_path = '/tmp/passwall_upload.tar.gz'
local temp_dir = '/tmp/passwall_bak'
local fd
http.setfilehandler(function(meta, chunk, eof)
if not fd and meta and meta.name == "ulfile" and chunk then
sys.call("rm -rf " .. temp_dir)
fs.remove(file_path)
fd = nixio.open(file_path, "w")
sys.call("echo '' > /tmp/log/passwall.log")
end
if fd and chunk then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
if fs.access(file_path) then
api.log(" * PassWall 配置文件上传成功…")
sys.call("mkdir -p " .. temp_dir)
if sys.call("tar -xzf " .. file_path .. " -C " .. temp_dir) == 0 then
for _, backup_file in ipairs(backup_files) do
local temp_file = temp_dir .. backup_file
if fs.access(temp_file) then
sys.call("cp -f " .. temp_file .. " " .. backup_file)
end
end
api.log(" * PassWall 配置还原成功…")
api.log(" * 重启 PassWall 服务中…\n")
sys.call('/etc/init.d/passwall restart > /dev/null 2>&1 &')
sys.call('/etc/init.d/passwall_server restart > /dev/null 2>&1 &')
else
api.log(" * PassWall 配置文件解压失败,请重试!")
end
else
api.log(" * PassWall 配置文件上传失败,请重试!")
end
sys.call("rm -rf " .. temp_dir)
fs.remove(file_path)
end
end)
return f, fb

View File

@ -47,16 +47,9 @@ local api = require "luci.passwall.api"
<script>
var origin = window.location.origin;
var reset_url = origin + "<%=api.url("reset_config")%>";
var hide_url = origin + "<%=api.url("hide")%>";
var show_url = origin + "<%=api.url("show")%>";
function reset(url) {
if (confirm('<%:Are you sure to reset?%>') == true) {
window.location.href = reset_url;
}
}
function hide(url) {
if (confirm('<%:Are you sure to hide?%>') == true) {
window.location.href = hide_url;
@ -66,7 +59,6 @@ local api = require "luci.passwall.api"
var dom = document.getElementById("faq_reset");
if (dom) {
var li = "";
li += "<a href='#' class='reset-title' onclick='reset()'>" + "<%: Restore to default configuration:%>"+ "</a>" + "<br />" + " <%: Browser access: %>" + "<a href='#' onclick='reset()'>" + reset_url + "</a>" + "<br />";
li += "<a href='#' class='reset-title' onclick='hide()'>" + "<%: Hide in main menu:%>"+ "</a>" + "<br />" + "<%: Browser access: %>" + "<a href='#' onclick='hide()'>" + hide_url + "</a>" + "<br />";
li += "<a href='#' class='reset-title'>" + "<%: Show in main menu:%>"+ "</a>" + "<br />" +"<%: Browser access: %>" + "<a href='#'>" + show_url + "</a>" + "<br />";
dom.innerHTML = li;

View File

@ -0,0 +1,130 @@
<%
local api = require "luci.passwall.api"
-%>
<%+cbi/valueheader%>
<div class="cbi-value" id="_backup_div">
<label class="cbi-value-title"><%:Create Backup File%></label>
<div class="cbi-value-field">
<input type="button" class="btn cbi-button cbi-input-apply" onclick="dl_backup()" value="<%:DL Backup%>" />
</div>
</div>
<div class="cbi-value" id="_upload_div">
<label class="cbi-value-title"><%:Restore Backup File%></label>
<div class="cbi-value-field">
<input type="button" class="btn cbi-button cbi-input-apply" id="upload-btn" value="<%:RST Backup%>" />
</div>
</div>
<div class="cbi-value" id="_reset_div">
<label class="cbi-value-title"><%:Restore to default configuration%></label>
<div class="cbi-value-field">
<input type="button" class="btn cbi-button cbi-button-remove" onclick="do_reset()" value="<%:Do Reset%>" />
</div>
</div>
<div id="upload-modal" class="up-modal" style="display:none;">
<div class="up-modal-content">
<h3><%:Restore Backup File%></h3>
<div class="cbi-value" id="_upload_div">
<div class="up-cbi-value-field">
<input class="cbi-input-file" type="file" id="ulfile" name="ulfile" accept=".tar.gz" required />
<br />
<div class="up-button-container">
<input type="submit" class="btn cbi-button cbi-input-apply" value="<%:UL Restore%>" />
<button class="btn cbi-button cbi-button-remove" id="upload-close"><%:CLOSE WIN%></button>
</div>
</div>
</div>
</div>
</div>
<style>
.up-modal {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border: 2px solid #ccc;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
z-index: 1000;
}
.up-modal-content {
width: 100%;
max-width: 400px;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.up-button-container {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 250px;
}
.up-cbi-value-field {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
</style>
<script>
document.getElementById("upload-btn").addEventListener("click", function() {
document.getElementById("upload-modal").style.display = "block";
});
document.getElementById("upload-close").addEventListener("click", function() {
document.getElementById("upload-modal").style.display = "none";
});
function dl_backup(btn) {
fetch('<%= api.url("backup") %>', {
method: 'POST'
})
.then(response => {
if (!response.ok) {
throw new Error("备份失败!");
}
return response.blob();
})
.then(blob => {
const date = new Date().toISOString().slice(0, 10).replace(/-/g, '');
const filename = `passwall-${date}-backup.tar.gz`;
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
})
.catch(error => alert(error.message));
}
function do_reset(btn) {
if (confirm("<%: Do you want to restore the client to default settings?%>")) {
setTimeout(function () {
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
var xhr1 = new XMLHttpRequest();
xhr1.open("GET",'<%= api.url("clear_log") %>', true);
xhr1.send();
var xhr2 = new XMLHttpRequest();
xhr2.open("GET",'<%= api.url("reset_config") %>', true);
xhr2.send();
}
}, 1000);
}
}
</script>
<%+cbi/valuefooter%>

View File

@ -52,9 +52,6 @@ msgstr "规则列表"
msgid "Access control"
msgstr "访问控制"
msgid "Watch Logs"
msgstr "查看日志"
msgid "Node Config"
msgstr "节点配置"
@ -238,9 +235,6 @@ msgstr "清空 NFTSET"
msgid "Try this feature if the rule modification does not take effect."
msgstr "如果修改规则后没有生效,请尝试此功能。"
msgid "Are you sure to reset?"
msgstr "你确定要恢复吗?"
msgid "Are you sure to hide?"
msgstr "你确定要隐藏吗?"
@ -265,9 +259,6 @@ msgstr "对于移动设备,可通过重新接入网络的方式清除。比如
msgid "Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed."
msgstr "请确认您设备的网络设置,客户端 DNS 服务器和默认网关应均指向本路由器,以确保 DNS 查询正确路由。"
msgid "Restore to default configuration:"
msgstr "恢复默认配置:"
msgid "Browser access:"
msgstr "浏览器访问:"
@ -1758,3 +1749,42 @@ msgstr "总行数:"
msgid "Read List"
msgstr "读取列表"
msgid "Log Maint"
msgstr "日志维护"
msgid "Backup and Restore"
msgstr "备份还原"
msgid "Backup or Restore Client and Server Configurations."
msgstr "备份或还原客户端及服务端配置。"
msgid "Create Backup File"
msgstr "创建备份文件"
msgid "Restore Backup File"
msgstr "恢复备份文件"
msgid "DL Backup"
msgstr "下载备份"
msgid "RST Backup"
msgstr "恢复备份"
msgid "UL Restore"
msgstr "上传恢复"
msgid "CLOSE WIN"
msgstr "关闭窗口"
msgid "Restore to default configuration"
msgstr "恢复默认配置"
msgid "Do Reset"
msgstr "执行重置"
msgid "Do you want to restore the client to default settings?"
msgstr "是否要恢复客户端默认配置?"
msgid "Are you sure you want to restore the client to default settings?"
msgstr "是否真的要恢复客户端默认配置?"

View File

@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sing-box
PKG_VERSION:=1.10.4
PKG_VERSION:=1.10.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=2253aabe7d847eb8385fdc66879eb5d748255b663fe77a1dbb2b2c780f015163
PKG_HASH:=ca0385b45d160c2c2a1d0e09665f4f04caac27cb3dd9d6132173316dfd873b75
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=LICENSE

View File

@ -21,13 +21,13 @@ define Download/geoip
HASH:=3f72cea0044a747fcb28cce36f70946c9e664c55949046fd22679090edc264b9
endef
GEOSITE_VER:=20241210004721
GEOSITE_VER:=20241221105938
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE)
HASH:=e414da6132d8b406827b827f246c3fe9759530d61f191b866836fe4d0a7b13a4
HASH:=aa65cee72dd6afbf9dd4c474b4ff28ceb063f6abf99249a084091adb4f282f09
endef
GEOSITE_IRAN_VER:=202412160039