mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-29 12:51:49 +08:00
🎉 Sync 2026-03-30 23:55:08
This commit is contained in:
parent
9283298b33
commit
2bd051c664
@ -7,7 +7,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=filebrowser
|
||||
PKG_VERSION:=0.8.7-beta
|
||||
PKG_VERSION:=1.2.3-stable
|
||||
PKG_RELEASE=1
|
||||
|
||||
ifeq ($(ARCH),aarch64)
|
||||
|
||||
2
luci-app-adguardhome/.gitattributes
vendored
Normal file
2
luci-app-adguardhome/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
201
luci-app-adguardhome/LICENSE
Normal file
201
luci-app-adguardhome/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
56
luci-app-adguardhome/Makefile
Normal file → Executable file
56
luci-app-adguardhome/Makefile
Normal file → Executable file
@ -1,58 +1,14 @@
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
# Copyright 2024- Douglas Orend <doug.orend2@gmail.com>
|
||||
# This is free software, licensed under the Apache License, Version 2.0
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-adguardhome
|
||||
PKG_MAINTAINER:=<https://github.com/rufengsuixing/luci-app-adguardhome>
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
LUCI_TITLE:=LuCI app for AdGuardHome
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+!wget-ssl&&!curl:wget-ssl +xz-utils +xz
|
||||
LUCI_DESCRIPTION:=LuCI support for AdGuardHome
|
||||
LUCI_TITLE:=LuCI support for AdguardHome
|
||||
LUCI_DEPENDS:=+adguardhome +luci-base +curl
|
||||
|
||||
|
||||
define Package/$(PKG_NAME)/config
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_binary
|
||||
bool "Include Binary File"
|
||||
default n
|
||||
endef
|
||||
|
||||
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_binary
|
||||
|
||||
define Package/luci-app-adguardhome/conffiles
|
||||
/usr/share/AdGuardHome/links.txt
|
||||
/etc/config/AdGuardHome
|
||||
/etc/AdGuardHome.yaml
|
||||
endef
|
||||
|
||||
|
||||
define Package/luci-app-adguardhome/postinst
|
||||
#!/bin/sh
|
||||
chmod 755 /usr/share/AdGuardHome/*
|
||||
chmod +x /etc/init.d/AdGuardHome
|
||||
/etc/init.d/AdGuardHome enable >/dev/null 2>&1
|
||||
enable=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null)
|
||||
if [ "$enable" == "1" ]; then
|
||||
/etc/init.d/AdGuardHome reload
|
||||
fi
|
||||
rm -f /tmp/luci-indexcache
|
||||
rm -f /tmp/luci-modulecache/*
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-adguardhome/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/AdGuardHome disable
|
||||
/etc/init.d/AdGuardHome stop
|
||||
uci -q batch <<-EOF >/dev/null 2>&1
|
||||
delete ucitrack.@AdGuardHome[-1]
|
||||
commit ucitrack
|
||||
EOF
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
PKG_MAINTAINER:=Douglas Orend <doug.orend2@gmail.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
13
luci-app-adguardhome/README.md
Normal file
13
luci-app-adguardhome/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# LuCI App AdGuardHome
|
||||
|
||||
**NOTE:** Original Source found for LUCI app [here](https://github.com/openwrt/luci/tree/3253c2644215a1ea8136199044e06ad5e4fd9de9/applications/luci-app-adguardhome) by Duncan Hill (<openwrt-dev@cricalix.net>).
|
||||
|
||||
## Screenshots
|
||||
|
||||
### Configuration Tab
|
||||

|
||||
|
||||
### Status Tab
|
||||

|
||||
|
||||
|
||||
@ -0,0 +1,158 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
'require form';
|
||||
'require view';
|
||||
'require poll';
|
||||
|
||||
const DEFAULT_CONFIG_FILE = '/etc/adguardhome/adguardhome.yaml';
|
||||
const DEFAULT_WORK_DIR = '/var/lib/adguardhome';
|
||||
const DEFAULT_USER = 'adguardhome';
|
||||
const DEFAULT_GROUP = DEFAULT_USER;
|
||||
|
||||
const PATH_REGEX = new RegExp('^/etc(/[^/]+)?/?$');
|
||||
|
||||
function validateConfigFile(_unused, value) {
|
||||
if (value == null || value === '') {
|
||||
return true;
|
||||
}
|
||||
if (!value.startsWith('/')) {
|
||||
return _('Path must be absolute.');
|
||||
}
|
||||
if (value.endsWith('/')) {
|
||||
return _('Path must not end with a slash.');
|
||||
}
|
||||
if (PATH_REGEX.test(value)) {
|
||||
return _('Configuration file must be stored in its own directory, and not in \'/etc\'.');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateWorkDir(_unused, value) {
|
||||
if (value == null || value === '') {
|
||||
return true;
|
||||
}
|
||||
if (!value.startsWith('/')) {
|
||||
return _('Path must be absolute.');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderStatus(status, agh_config) {
|
||||
var spanTemp = '<span style="color:%s"><strong>%s %s</strong></span>';
|
||||
var renderHTML;
|
||||
if (status.running) {
|
||||
var button = String.format(' <a class="btn cbi-button" href="%s" target="_blank" rel="noreferrer noopener">%s</a>',
|
||||
agh_config.web_url, _('Open Web Interface'));
|
||||
renderHTML = spanTemp.format('green', _('adguardhome'), _('RUNNING')) + button;
|
||||
} else {
|
||||
renderHTML = spanTemp.format('red', _('adguardhome'), _('NOT RUNNING'));
|
||||
}
|
||||
|
||||
return renderHTML;
|
||||
}
|
||||
|
||||
return view.extend({
|
||||
load_adguardhome_config: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'get_config'
|
||||
}),
|
||||
load_adguardhome_status: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'get_status'
|
||||
}),
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
this.load_adguardhome_status(),
|
||||
this.load_adguardhome_config()
|
||||
]);
|
||||
},
|
||||
render: function (data) {
|
||||
var status = data[0] || {};
|
||||
var agh_config = data[1] || {};
|
||||
// A basic configuration form; the luci.adguardhome script that
|
||||
// powers the other UI pages needs a username and password to
|
||||
// communicate with the AdguardHome REST API.
|
||||
var s, o;
|
||||
var m = new form.Map('adguardhome', _('AdGuard Home Configuration'),
|
||||
_('默认用户名admin 密码admin')
|
||||
);
|
||||
|
||||
s = m.section(form.TypedSection);
|
||||
s.anonymous = true;
|
||||
|
||||
s.render = function () {
|
||||
setTimeout(function() {
|
||||
poll.add(function () {
|
||||
var view = document.getElementById('service_status');
|
||||
view.innerHTML = renderStatus(status, agh_config);
|
||||
});
|
||||
}, 0);
|
||||
|
||||
return E('div', { class: 'cbi-section', id: 'status_bar' }, [
|
||||
E('p', { id: 'service_status' }, _('Collecting data...'))
|
||||
]);
|
||||
}
|
||||
|
||||
s = m.section(form.NamedSection, 'config', 'adguardhome', _('General settings'));
|
||||
o = s.option(form.Flag, 'enabled', _('Enable'));
|
||||
o.default = o.disabled;
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'config_file', _('Configuration file'));
|
||||
o.datatype = 'string';
|
||||
o.placeholder = DEFAULT_CONFIG_FILE;
|
||||
o.validate = validateConfigFile;
|
||||
|
||||
o = s.option(form.Value, 'work_dir', _('Work Dir'));
|
||||
o.datatype = 'string';
|
||||
o.placeholder = DEFAULT_WORK_DIR;
|
||||
o.validate = validateWorkDir;
|
||||
|
||||
o = s.option(form.Value, 'user', _('Service user'), _('User the service runs under.'));
|
||||
o.datatype = 'string';
|
||||
o.placeholder = DEFAULT_USER;
|
||||
|
||||
o = s.option(form.Value, 'group', _('Service group'), _('Group the service runs under.'));
|
||||
o.datatype = 'string';
|
||||
o.placeholder = DEFAULT_GROUP;
|
||||
|
||||
// 添加重定向模式选择
|
||||
o = s.option(form.ListValue, 'redirect', _('Redirect'), _('AdGuardHome redirect mode'));
|
||||
o.value('none', _('none'));
|
||||
o.value('dnsmasq-upstream', _('Run as dnsmasq upstream server'));
|
||||
o.value('redirect', _('Redirect 53 port to AdGuardHome'));
|
||||
o.value('exchange', _('Use port 53 replace dnsmasq'));
|
||||
o.default = 'none';
|
||||
|
||||
o = s.option(form.Value, 'web_username', _('Username for AdGuard Home'), _('The username you configured when you set up AdGuard Home'));
|
||||
o.default = 'admin';
|
||||
|
||||
o = s.option(form.Value, 'web_password', _('Password for AdGuard Home'), _('The password you configured when you set up AdGuard Home'));
|
||||
o.password = true;
|
||||
o.default = 'admin';
|
||||
|
||||
var ChangePassword = form.Button.extend({
|
||||
set_passwd: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'set_passwd',
|
||||
params: [ 'username', 'hash' ],
|
||||
}),
|
||||
onclick: function() {
|
||||
var username = document.getElementById("widget.cbid.adguardhome.config.web_username").value;
|
||||
var password = document.getElementById("widget.cbid.adguardhome.config.web_password").value;
|
||||
var hash = TwinBcrypt.hashSync(password);
|
||||
return Promise.all([ this.set_passwd( username, hash ) ]);
|
||||
},
|
||||
});
|
||||
o = s.option(ChangePassword, 'change_password', _('Change Password'));
|
||||
|
||||
var BCryptInclude = form.DummyValue.extend({
|
||||
renderWidget: function(section_id, option_index, cfgvalue) {
|
||||
return E('script', { 'type':'text/javascript', 'src':'/luci-static/resources/view/twin-bcrypt.min.js' });
|
||||
}
|
||||
});
|
||||
o = s.option(BCryptInclude, 'misc');
|
||||
|
||||
return m.render();
|
||||
},
|
||||
})
|
||||
@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
'require dom';
|
||||
'require fs';
|
||||
'require poll';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
load: function() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/sbin/logread'), null),
|
||||
L.resolveDefault(fs.stat('/usr/sbin/logread'), null)
|
||||
]).then(function(stat) {
|
||||
var logger = stat[0] ? stat[0].path : stat[1] ? stat[1].path : null;
|
||||
|
||||
return fs.exec_direct(logger, [ '-e', 'AdGuardHome' ]).catch(function(err) {
|
||||
ui.addNotification(null, E('p', {}, _('Unable to load log data: ' + err.message)));
|
||||
return '';
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function(logdata) {
|
||||
var loglines = logdata.trim().split(/\n/).reverse().slice(0, 50);
|
||||
|
||||
return E([], [
|
||||
E('h2', {}, [_('System Log (AdGuard Home)')]),
|
||||
E('div', {}, [_('Showing last 50 lines')]),
|
||||
E('div', { 'id': 'content_syslog' }, [
|
||||
E('textarea', {
|
||||
'id': 'syslog',
|
||||
'style': 'font-size:12px',
|
||||
'readonly': 'readonly',
|
||||
'wrap': 'off',
|
||||
'rows': loglines.length + 1
|
||||
}, [ loglines.join('\n') ])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
handleSave: null,
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
});
|
||||
@ -0,0 +1,171 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
'require view';
|
||||
|
||||
return view.extend({
|
||||
load_adguardhome_config: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'get_config'
|
||||
}),
|
||||
load_adguardhome_status: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'get_status'
|
||||
}),
|
||||
load_adguardhome_statistics: rpc.declare({
|
||||
object: 'luci.adguardhome',
|
||||
method: 'get_statistics'
|
||||
}),
|
||||
|
||||
generic_failure: function(message) {
|
||||
return E('div', {'class': 'error'}, [_('RPC call failure: '), message])
|
||||
},
|
||||
render_list: function ( agh_list ) {
|
||||
var table = E('ul', {});
|
||||
for (var i = 0; i < agh_list.length; i++) {
|
||||
table.appendChild(E('li', {}, agh_list[i]));
|
||||
}
|
||||
return table;
|
||||
},
|
||||
render_status_table: function (status, agh_config) {
|
||||
if (status.error) {
|
||||
return this.generic_failure(status.error)
|
||||
}
|
||||
// Take a hint from the base LuCI module for the Overview page,
|
||||
// declare the fields and use a loop to build the tabular status view.
|
||||
// Written out as key/value pairs, but it's just an iterable of elements.
|
||||
const weburl = agh_config.web_url;
|
||||
const listen_addresses = L.isObject(status.dns_addresses) ? this.render_list(status.dns_addresses) : _('Not found');
|
||||
const bootstrap_dns = L.isObject(agh_config.dns_bootstrap_dns) ? this.render_list(agh_config.dns_bootstrap_dns) : _('Not found');
|
||||
const upstream_dns = L.isObject(agh_config.dns_upstream_dns) ? this.render_list(agh_config.dns_upstream_dns) : _('Not found');
|
||||
const fields = [
|
||||
_('Running'), status.running ? _('Yes') : _('No'),
|
||||
_('Protection enabled'), status.protection_enabled ? _('Yes') : _('No'),
|
||||
_('Statistics period (days)'), agh_config.statistics_interval,
|
||||
_('Web interface'), E('button', { 'class': "cbi-button cbi-button-button" }, E('a', { 'href': weburl, 'target': '_blank' }, weburl)),
|
||||
_('DNS listen port'), status.dns_port,
|
||||
_('DNS listen addresses'), listen_addresses,
|
||||
_('Bootstrap DNS addresses'), bootstrap_dns,
|
||||
_('Upstream DNS addresses'), upstream_dns,
|
||||
_('Version'), status.version,
|
||||
];
|
||||
|
||||
var table = E('table', { 'class': 'table', 'id': 'status' });
|
||||
for (var i = 0; i < fields.length; i += 2) {
|
||||
table.appendChild(E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'width': '33%', 'vertical-align': 'text-top' }, [fields[i]]),
|
||||
E('td', { 'class': 'td left' }, [(fields[i + 1] != null) ? fields[i + 1] : _('Not found')])
|
||||
]));
|
||||
}
|
||||
return table;
|
||||
},
|
||||
render_statistics_table: function (statistics) {
|
||||
// High level statistics
|
||||
if (statistics.error) {
|
||||
return this.generic_failure(statistics.error)
|
||||
}
|
||||
const fields = [
|
||||
_('DNS queries'), statistics.num_dns_queries,
|
||||
_('DNS blocks'), statistics.num_blocked_filtering,
|
||||
_('DNS replacements (safesearch)'), statistics.num_replaced_safesearch,
|
||||
_('DNS replacements (malware/phishing)'), statistics.num_replaced_safebrowsing,
|
||||
_('Average processing time (seconds)'), statistics.avg_processing_time,
|
||||
];
|
||||
|
||||
var table = E('table', { 'class': 'table', 'id': 'statistics' });
|
||||
for (var i = 0; i < fields.length; i += 2) {
|
||||
table.appendChild(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'width': '33%' }, [fields[i]]),
|
||||
E('td', { 'class': 'td left' }, [(fields[i + 1] != null) ? fields[i + 1] : _('Not found')])
|
||||
]));
|
||||
}
|
||||
return table;
|
||||
},
|
||||
render_top_table: function(table_id, objects) {
|
||||
var table = E('table', { 'class': 'table', 'id': table_id });
|
||||
for (var i = 0; i < objects.length; i++) {
|
||||
table.appendChild(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'width': '33%' }, Object.keys(objects[i])[0]),
|
||||
E('td', { 'class': 'td left' }, Object.values(objects[i])[0])
|
||||
])
|
||||
);
|
||||
}
|
||||
return table;
|
||||
},
|
||||
render_top_queries_table: function (statistics) {
|
||||
// Top 5 queried domains table view
|
||||
if (statistics.error) {
|
||||
return this.generic_failure(statistics.error)
|
||||
}
|
||||
if (typeof statistics.top_queried_domains === 'undefined') { return ""; }
|
||||
const top_queries = statistics.top_queried_domains.slice(0, 5);
|
||||
return this.render_top_table('top_queries', top_queries)
|
||||
},
|
||||
render_top_blocked_table: function (statistics) {
|
||||
// Top 5 blocked domains table view
|
||||
if (statistics.error) {
|
||||
return this.generic_failure(statistics.error)
|
||||
}
|
||||
if (typeof statistics.top_blocked_domains === 'undefined') { return ""; }
|
||||
const top_blocked = statistics.top_blocked_domains.slice(0, 5);
|
||||
return this.render_top_table('top_blocked', top_blocked)
|
||||
},
|
||||
// Core LuCI functions from here on.
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
this.load_adguardhome_status(),
|
||||
this.load_adguardhome_statistics(),
|
||||
this.load_adguardhome_config()
|
||||
]);
|
||||
},
|
||||
render: function (data) {
|
||||
// data[0] should be load_adguardhome_status() result
|
||||
var status = data[0] || {};
|
||||
// data[1] should be load_adguardhome_statistics() result
|
||||
var statistics = data[1] || {};
|
||||
// data[2] should be load_adguardhome_config() result
|
||||
var agh_config = data[2] || {};
|
||||
|
||||
// status.auth_error is only filled in when the config fetch failed
|
||||
// to get the credentials. That stops all activity, since the user must
|
||||
// first configure the username and password. Don't even bother trying
|
||||
// to make REST API calls without credentials.
|
||||
if (status.auth_error) {
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h2', _('AdGuard Home Status - Error')),
|
||||
E('div', { 'class': 'error' }, status.auth_error),
|
||||
E('div', { 'class': 'info' }, _('Please open the Configuration section, and provide the credentials.'))
|
||||
])
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
// Render all the status tables as one big block.
|
||||
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
|
||||
E('div', { 'class': 'cbi-section' }, [
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h2', _('AdGuard Home Status')),
|
||||
this.render_status_table(status, agh_config)
|
||||
]),
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h3', _('AdGuard Home Statistics')),
|
||||
this.render_statistics_table(statistics)
|
||||
]),
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h3', _('Top Queried Domains')),
|
||||
this.render_top_queries_table(statistics)
|
||||
]),
|
||||
E('div', { 'class': 'left' }, [
|
||||
E('h3', _('Top Blocked Domains')),
|
||||
this.render_top_blocked_table(statistics)
|
||||
])
|
||||
]),
|
||||
]);
|
||||
},
|
||||
handleSave: null,
|
||||
handleSaveApply: null,
|
||||
handleReset: null
|
||||
})
|
||||
@ -1,126 +0,0 @@
|
||||
module("luci.controller.AdGuardHome", package.seeall)
|
||||
local fs = require "nixio.fs"
|
||||
local http = require "luci.http"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
function index()
|
||||
local page = entry({"admin", "services", "AdGuardHome"},alias("admin", "services", "AdGuardHome", "base"),_("AdGuard Home"))
|
||||
page.order = 11
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-adguardhome" }
|
||||
entry({"admin", "services", "AdGuardHome", "base"}, cbi("AdGuardHome/base"), _("Base Setting"), 1).leaf = true
|
||||
entry({"admin", "services", "AdGuardHome", "log"}, form("AdGuardHome/log"), _("Log"), 2).leaf = true
|
||||
entry({"admin", "services", "AdGuardHome", "manual"}, cbi("AdGuardHome/manual"), _("Manual Config"), 3).leaf = true
|
||||
entry({"admin", "services", "AdGuardHome", "status"}, call("act_status")).leaf = true
|
||||
entry({"admin", "services", "AdGuardHome", "check"}, call("check_update"))
|
||||
entry({"admin", "services", "AdGuardHome", "doupdate"}, call("do_update"))
|
||||
entry({"admin", "services", "AdGuardHome", "getlog"}, call("get_log"))
|
||||
entry({"admin", "services", "AdGuardHome", "dodellog"}, call("do_dellog"))
|
||||
entry({"admin", "services", "AdGuardHome", "reloadconfig"}, call("reload_config"))
|
||||
entry({"admin", "services", "AdGuardHome", "gettemplateconfig"}, call("get_template_config"))
|
||||
end
|
||||
function get_template_config()
|
||||
local b
|
||||
local d=""
|
||||
local file = "/tmp/resolv.conf.d/resolv.conf.auto"
|
||||
if not fs.access(file) then
|
||||
file = "/tmp/resolv.conf.auto"
|
||||
end
|
||||
for cnt in io.lines(file) do
|
||||
b = string.match(cnt, "^[^#]*nameserver%s+([^%s]+)$")
|
||||
if (b ~= nil) then d = d .. " - " .. b .. "\n" end
|
||||
end
|
||||
local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+")
|
||||
local tbl = {}
|
||||
local a=""
|
||||
while (1) do
|
||||
a=f:read("*l")
|
||||
if (a=="#bootstrap_dns") then
|
||||
a=d
|
||||
elseif (a=="#upstream_dns") then
|
||||
a=d
|
||||
elseif (a==nil) then
|
||||
break
|
||||
end
|
||||
table.insert(tbl, a)
|
||||
end
|
||||
f:close()
|
||||
http.prepare_content("text/plain; charset=utf-8")
|
||||
http.write(table.concat(tbl, "\n"))
|
||||
end
|
||||
function reload_config()
|
||||
fs.remove("/tmp/AdGuardHometmpconfig.yaml")
|
||||
http.prepare_content("application/json")
|
||||
http.write('')
|
||||
end
|
||||
function act_status()
|
||||
local e={}
|
||||
local binpath=uci:get("AdGuardHome","AdGuardHome","binpath")
|
||||
e.running=luci.sys.call("pgrep "..binpath.." >/dev/null")==0
|
||||
e.redirect=(fs.readfile("/var/run/AdGredir")=="1")
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(e)
|
||||
end
|
||||
function do_update()
|
||||
fs.writefile("/var/run/lucilogpos","0")
|
||||
http.prepare_content("application/json")
|
||||
http.write('')
|
||||
local arg
|
||||
if luci.http.formvalue("force") == "1" then
|
||||
arg="force"
|
||||
else
|
||||
arg=""
|
||||
end
|
||||
if arg=="force" then
|
||||
luci.sys.exec("kill $(pgrep /usr/share/AdGuardHome/update_core.sh) ; sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &")
|
||||
|
||||
|
||||
else
|
||||
luci.sys.exec("sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &")
|
||||
end
|
||||
end
|
||||
function get_log()
|
||||
local logfile=uci:get("AdGuardHome","AdGuardHome","logfile")
|
||||
if (logfile==nil) then
|
||||
http.write("no log available\n")
|
||||
return
|
||||
elseif (logfile=="syslog") then
|
||||
if not fs.access("/var/run/AdGuardHomesyslog") then
|
||||
luci.sys.exec("(/usr/share/AdGuardHome/getsyslog.sh &); sleep 1;")
|
||||
end
|
||||
logfile="/tmp/AdGuardHometmp.log"
|
||||
fs.writefile("/var/run/AdGuardHomesyslog","1")
|
||||
elseif not fs.access(logfile) then
|
||||
http.write("")
|
||||
return
|
||||
end
|
||||
http.prepare_content("text/plain; charset=utf-8")
|
||||
local fdp = tonumber(fs.readfile("/var/run/lucilogpos")) or 0
|
||||
local f=io.open(logfile, "r+")
|
||||
f:seek("set",fdp)
|
||||
local a=f:read(2048000) or ""
|
||||
fdp=f:seek()
|
||||
fs.writefile("/var/run/lucilogpos",tostring(fdp))
|
||||
f:close()
|
||||
http.write(a)
|
||||
end
|
||||
function do_dellog()
|
||||
local logfile=uci:get("AdGuardHome","AdGuardHome","logfile")
|
||||
fs.writefile(logfile,"")
|
||||
http.prepare_content("application/json")
|
||||
http.write('')
|
||||
end
|
||||
function check_update()
|
||||
http.prepare_content("text/plain; charset=utf-8")
|
||||
local fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0
|
||||
local f=io.open("/tmp/AdGuardHome_update.log", "r+")
|
||||
f:seek("set",fdp)
|
||||
local a=f:read(2048000) or ""
|
||||
fdp=f:seek()
|
||||
fs.writefile("/var/run/lucilogpos",tostring(fdp))
|
||||
f:close()
|
||||
if fs.access("/var/run/update_core") then
|
||||
http.write(a)
|
||||
else
|
||||
http.write(a.."\0")
|
||||
end
|
||||
end
|
||||
@ -1,302 +0,0 @@
|
||||
require("luci.sys")
|
||||
require("luci.util")
|
||||
require("io")
|
||||
local m,s,o,o1
|
||||
local fs=require"nixio.fs"
|
||||
local uci=require"luci.model.uci".cursor()
|
||||
local configpath=uci:get("AdGuardHome","AdGuardHome","configpath") or "/etc/AdGuardHome.yaml"
|
||||
local binpath = uci:get("AdGuardHome", "AdGuardHome", "binpath") or "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
httpport=uci:get("AdGuardHome","AdGuardHome","httpport") or "3000"
|
||||
m = Map("AdGuardHome", "AdGuard Home")
|
||||
m.description = translate("Free and open source, powerful network-wide ads & trackers blocking DNS server.")
|
||||
m:section(SimpleSection).template = "AdGuardHome/AdGuardHome_status"
|
||||
|
||||
s = m:section(TypedSection, "AdGuardHome")
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
---- enable
|
||||
o = s:option(Flag, "enabled", translate("Enable"))
|
||||
o.default = 0
|
||||
o.optional = false
|
||||
---- httpport
|
||||
o =s:option(Value,"httpport",translate("Browser management port"))
|
||||
o.placeholder=3000
|
||||
o.default=3000
|
||||
o.datatype="port"
|
||||
o.optional = false
|
||||
o.description = translate("<input type='button' style='width:210px;border-color:Teal;text-align:center;font-weight:bold;color:red;background: #ffc800;' value='AdGuardHome Web:" .. httpport .. "' onclick=\"window.open('http://'+window.location.hostname+':" .. httpport .. "')\"/>")
|
||||
---- update warning not safe
|
||||
local binmtime=uci:get("AdGuardHome","AdGuardHome","binmtime") or "0"
|
||||
local e=""
|
||||
if not fs.access(configpath) then e = e .. " " .. translate("no config") end
|
||||
if not fs.access(binpath) then
|
||||
e=e.." "..translate("no core")
|
||||
else
|
||||
local version=uci:get("AdGuardHome","AdGuardHome","version")
|
||||
local testtime=fs.stat(binpath,"mtime")
|
||||
if testtime~=tonumber(binmtime) or version==nil then
|
||||
-- local tmp=luci.sys.exec(binpath.." -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o")
|
||||
-- version=string.sub(tmp, 1, -2)
|
||||
version = luci.sys.exec(string.format("echo -n $(%s --version 2>&1 | awk -F 'version ' '{print $2}' | awk -F ',' '{print $1}')", binpath))
|
||||
if version == "" then version = "core error" end
|
||||
uci:set("AdGuardHome", "AdGuardHome", "version", version)
|
||||
uci:set("AdGuardHome", "AdGuardHome", "binmtime", testtime)
|
||||
uci:commit("AdGuardHome")
|
||||
end
|
||||
e=version..e
|
||||
end
|
||||
|
||||
o = s:option(ListValue, "core_version", translate("Core Version"))
|
||||
o:value("latest", translate("Latest Version"))
|
||||
o:value("beta", translate("Beta Version"))
|
||||
o.default = "latest"
|
||||
o = s:option(Button, "restart", translate("Upgrade Core"))
|
||||
o.inputtitle=translate("Update core version")
|
||||
o.template = "AdGuardHome/AdGuardHome_check"
|
||||
o.showfastconfig=(not fs.access(configpath))
|
||||
o.description = string.format(translate("Current core version:") .. "<strong><font id='updateversion' color='green'>%s </font></strong>", e)
|
||||
---- port warning not safe
|
||||
local port=luci.sys.exec("awk '/ port:/{printf($2);exit;}' "..configpath.." 2>nul")
|
||||
if (port=="") then port="?" end
|
||||
---- Redirect
|
||||
o = s:option(ListValue, "redirect", port..translate("Redirect"), translate("AdGuardHome redirect mode"))
|
||||
o.placeholder = "none"
|
||||
o:value("none", translate("none"))
|
||||
o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server"))
|
||||
o:value("redirect", translate("Redirect 53 port to AdGuardHome"))
|
||||
o:value("exchange", translate("Use port 53 replace dnsmasq"))
|
||||
o.default = "none"
|
||||
o.optional = true
|
||||
---- bin path
|
||||
o = s:option(Value, "binpath", translate("Bin Path"), translate("AdGuardHome Bin path if no bin will auto download"))
|
||||
o.default = "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
o.datatype = "string"
|
||||
o.optional = false
|
||||
o.rmempty=false
|
||||
o.validate=function(self, value)
|
||||
if value=="" then return nil end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
fs.rmdir(value)
|
||||
end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
if (m.message) then
|
||||
m.message =m.message.."\nerror!bin path is a dir"
|
||||
else
|
||||
m.message ="error!bin path is a dir"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
--- upx
|
||||
o = s:option(ListValue, "upxflag", translate("use upx to compress bin after download"))
|
||||
o:value("", translate("none"))
|
||||
o:value("-1", translate("compress faster"))
|
||||
o:value("-9", translate("compress better"))
|
||||
o:value("--best", translate("compress best(can be slow for big files)"))
|
||||
o:value("--brute", translate("try all available compression methods & filters [slow]"))
|
||||
o:value("--ultra-brute", translate("try even more compression variants [very slow]"))
|
||||
o.default = ""
|
||||
o.description=translate("bin use less space,but may have compatibility issues")
|
||||
o.rmempty = true
|
||||
---- config path
|
||||
o = s:option(Value, "configpath", translate("Config Path"), translate("AdGuardHome config path"))
|
||||
o.default = "/etc/AdGuardHome.yaml"
|
||||
o.datatype = "string"
|
||||
o.optional = false
|
||||
o.rmempty=false
|
||||
o.validate=function(self, value)
|
||||
if value==nil then return nil end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
fs.rmdir(value)
|
||||
end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!config path is a dir"
|
||||
else
|
||||
m.message ="error!config path is a dir"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
---- work dir
|
||||
o = s:option(Value, "workdir", translate("Work dir"), translate("AdGuardHome work dir include rules,audit log and database"))
|
||||
o.default = "/usr/bin/AdGuardHome"
|
||||
o.datatype = "string"
|
||||
o.optional = false
|
||||
o.rmempty=false
|
||||
o.validate=function(self, value)
|
||||
if value=="" then return nil end
|
||||
if fs.stat(value,"type")=="reg" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!work dir is a file"
|
||||
else
|
||||
m.message ="error!work dir is a file"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
if string.sub(value, -1)=="/" then
|
||||
return string.sub(value, 1, -2)
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
---- log file
|
||||
o = s:option(Value, "logfile", translate("Runtime log file"), translate("AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"))
|
||||
o.datatype = "string"
|
||||
o.rmempty = true
|
||||
o.validate=function(self, value)
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
fs.rmdir(value)
|
||||
end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!log file is a dir"
|
||||
else
|
||||
m.message ="error!log file is a dir"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
---- debug
|
||||
o = s:option(Flag, "verbose", translate("Verbose log"))
|
||||
o.default = 0
|
||||
o.optional = true
|
||||
---- gfwlist
|
||||
local a=luci.sys.call("grep -m 1 -q programadd "..configpath)
|
||||
if (a==0) then
|
||||
a="Added"
|
||||
else
|
||||
a="Not added"
|
||||
end
|
||||
o=s:option(Button,"gfwdel",translate("Del gfwlist"),translate(a))
|
||||
o.optional = true
|
||||
o.inputtitle=translate("Del")
|
||||
o.write=function()
|
||||
luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh del 2>&1")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
|
||||
end
|
||||
o=s:option(Button,"gfwadd",translate("Add gfwlist"),translate(a))
|
||||
o.optional = true
|
||||
o.inputtitle=translate("Add")
|
||||
o.write=function()
|
||||
luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh 2>&1")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome"))
|
||||
end
|
||||
o = s:option(Value, "gfwupstream", translate("Gfwlist upstream dns server"), translate("Gfwlist domain upstream dns service")..translate(a))
|
||||
o.default = "tcp://208.67.220.220:5353"
|
||||
o.datatype = "string"
|
||||
o.optional = true
|
||||
---- chpass
|
||||
o = s:option(Value, "hashpass", translate("Change browser management password"), translate("Press load culculate model and culculate finally save/apply"))
|
||||
o.default = ""
|
||||
o.datatype = "string"
|
||||
o.template = "AdGuardHome/AdGuardHome_chpass"
|
||||
o.optional = true
|
||||
---- upgrade protect
|
||||
o = s:option(MultiValue, "upprotect", translate("Keep files when system upgrade"))
|
||||
o:value("$binpath",translate("core bin"))
|
||||
o:value("$configpath",translate("config file"))
|
||||
o:value("$logfile",translate("log file"))
|
||||
o:value("$workdir/data/sessions.db",translate("sessions.db"))
|
||||
o:value("$workdir/data/stats.db",translate("stats.db"))
|
||||
o:value("$workdir/data/querylog.json",translate("querylog.json"))
|
||||
o:value("$workdir/data/filters",translate("filters"))
|
||||
o.widget = "checkbox"
|
||||
o.default = nil
|
||||
o.optional=true
|
||||
---- wait net on boot
|
||||
o = s:option(Flag, "waitonboot", translate("On boot when network ok restart"))
|
||||
o.default = 1
|
||||
o.optional = true
|
||||
---- backup workdir on shutdown
|
||||
local workdir = uci:get("AdGuardHome", "AdGuardHome", "workdir") or "/usr/bin/AdGuardHome"
|
||||
o = s:option(MultiValue, "backupfile", translate("Backup workdir files when shutdown"))
|
||||
o1 = s:option(Value, "backupwdpath", translate("Backup workdir path"))
|
||||
local name
|
||||
o:value("filters","filters")
|
||||
o:value("stats.db","stats.db")
|
||||
o:value("querylog.json","querylog.json")
|
||||
o:value("sessions.db","sessions.db")
|
||||
o1:depends ("backupfile", "filters")
|
||||
o1:depends ("backupfile", "stats.db")
|
||||
o1:depends ("backupfile", "querylog.json")
|
||||
o1:depends ("backupfile", "sessions.db")
|
||||
for name in fs.glob(workdir.."/data/*")
|
||||
do
|
||||
name=fs.basename (name)
|
||||
if name~="filters" and name~="stats.db" and name~="querylog.json" and name~="sessions.db" then
|
||||
o:value(name,name)
|
||||
o1:depends ("backupfile", name)
|
||||
end
|
||||
end
|
||||
o.widget = "checkbox"
|
||||
o.default = nil
|
||||
o.optional=false
|
||||
o.description=translate("Will be restore when workdir/data is empty")
|
||||
----backup workdir path
|
||||
|
||||
o1.default = "/usr/bin/AdGuardHome"
|
||||
o1.datatype = "string"
|
||||
o1.optional = false
|
||||
o1.validate=function(self, value)
|
||||
if fs.stat(value,"type")=="reg" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!backup dir is a file"
|
||||
else
|
||||
m.message ="error!backup dir is a file"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
if string.sub(value,-1)=="/" then
|
||||
return string.sub(value, 1, -2)
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
----Crontab
|
||||
o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab"))
|
||||
o:value("autoupdate",translate("Auto update core"))
|
||||
o:value("cutquerylog",translate("Auto tail querylog"))
|
||||
o:value("cutruntimelog",translate("Auto tail runtime log"))
|
||||
o:value("autohost",translate("Auto update ipv6 hosts and restart adh"))
|
||||
o:value("autogfw",translate("Auto update gfwlist and restart adh"))
|
||||
o.widget = "checkbox"
|
||||
o.default = nil
|
||||
o.optional=true
|
||||
|
||||
o = s:option(Value, "update_url", translate("Core Update URL"))
|
||||
o.default = "https://github.com/AdguardTeam/AdGuardHome/releases/download/${Cloud_Version}/AdGuardHome_linux_${Arch}.tar.gz"
|
||||
o.placeholder = "https://github.com/AdguardTeam/AdGuardHome/releases/download/${Cloud_Version}/AdGuardHome_linux_${Arch}.tar.gz"
|
||||
o.rmempty = false
|
||||
o.optional = false
|
||||
|
||||
function m.on_commit(map)
|
||||
if (fs.access("/var/run/AdGserverdis")) then
|
||||
io.popen("/etc/init.d/AdGuardHome reload &")
|
||||
return
|
||||
end
|
||||
local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest")
|
||||
if ucitracktest=="1" then
|
||||
return
|
||||
elseif ucitracktest=="0" then
|
||||
io.popen("/etc/init.d/AdGuardHome reload &")
|
||||
else
|
||||
if (fs.access("/var/run/AdGlucitest")) then
|
||||
uci:set("AdGuardHome","AdGuardHome","ucitracktest","0")
|
||||
io.popen("/etc/init.d/AdGuardHome reload &")
|
||||
else
|
||||
fs.writefile("/var/run/AdGlucitest","")
|
||||
if (ucitracktest=="2") then
|
||||
uci:set("AdGuardHome","AdGuardHome","ucitracktest","1")
|
||||
else
|
||||
uci:set("AdGuardHome","AdGuardHome","ucitracktest","2")
|
||||
end
|
||||
end
|
||||
uci:commit("AdGuardHome")
|
||||
end
|
||||
end
|
||||
return m
|
||||
@ -1,16 +0,0 @@
|
||||
local fs = require "nixio.fs"
|
||||
local uci = require"luci.model.uci".cursor()
|
||||
local f, t
|
||||
f = SimpleForm("logview")
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
t=f:field(TextValue,"conf")
|
||||
t.rmempty=true
|
||||
t.rows=20
|
||||
t.template="AdGuardHome/log"
|
||||
t.readonly="readonly"
|
||||
local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") or ""
|
||||
t.timereplace=(logfile~="syslog" and logfile~="" )
|
||||
t.pollcheck=logfile~=""
|
||||
fs.writefile("/var/run/lucilogpos", "0")
|
||||
return f
|
||||
@ -1,96 +0,0 @@
|
||||
local m, s, o
|
||||
local fs = require "nixio.fs"
|
||||
local uci=require"luci.model.uci".cursor()
|
||||
local sys=require"luci.sys"
|
||||
require("string")
|
||||
require("io")
|
||||
require("table")
|
||||
function gen_template_config()
|
||||
local b
|
||||
local d=""
|
||||
local file = "/tmp/resolv.conf.d/resolv.conf.auto"
|
||||
if not fs.access(file) then
|
||||
file = "/tmp/resolv.conf.auto"
|
||||
end
|
||||
for cnt in io.lines(file) do
|
||||
b = string.match(cnt, "^[^#]*nameserver%s+([^%s]+)$")
|
||||
if (b ~= nil) then d = d .. " - " .. b .. "\n" end
|
||||
end
|
||||
local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+")
|
||||
local tbl = {}
|
||||
local a=""
|
||||
while (1) do
|
||||
a=f:read("*l")
|
||||
if (a=="#bootstrap_dns") then
|
||||
a=d
|
||||
elseif (a=="#upstream_dns") then
|
||||
a=d
|
||||
elseif (a==nil) then
|
||||
break
|
||||
end
|
||||
table.insert(tbl, a)
|
||||
end
|
||||
f:close()
|
||||
return table.concat(tbl, "\n")
|
||||
end
|
||||
m = Map("AdGuardHome")
|
||||
local configpath = uci:get("AdGuardHome","AdGuardHome","configpath")
|
||||
local binpath = uci:get("AdGuardHome","AdGuardHome","binpath")
|
||||
s = m:section(TypedSection, "AdGuardHome")
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
--- config
|
||||
o = s:option(TextValue, "escconf")
|
||||
o.rows = 66
|
||||
o.wrap = "off"
|
||||
o.rmempty = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return fs.readfile("/tmp/AdGuardHometmpconfig.yaml") or fs.readfile(configpath) or gen_template_config() or ""
|
||||
end
|
||||
o.validate=function(self, value)
|
||||
fs.writefile("/tmp/AdGuardHometmpconfig.yaml", value:gsub("\r\n", "\n"))
|
||||
if fs.access(binpath) then
|
||||
if (sys.call(binpath .. " -c /tmp/AdGuardHometmpconfig.yaml --check-config 2> /tmp/AdGuardHometest.log") == 0) then return value end
|
||||
else
|
||||
return value
|
||||
end
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome","manual"))
|
||||
return nil
|
||||
end
|
||||
o.write = function(self, section, value)
|
||||
fs.move("/tmp/AdGuardHometmpconfig.yaml",configpath)
|
||||
end
|
||||
o.remove = function(self, section, value) fs.writefile(configpath, "") end
|
||||
|
||||
--- js and reload button
|
||||
o = s:option(DummyValue, "")
|
||||
o.anonymous=true
|
||||
o.template = "AdGuardHome/yamleditor"
|
||||
if not fs.access(binpath) then
|
||||
o.description=translate("WARNING!!! no bin found apply config will not be test")
|
||||
end
|
||||
--- log
|
||||
if (fs.access("/tmp/AdGuardHometmpconfig.yaml")) then
|
||||
local c=fs.readfile("/tmp/AdGuardHometest.log")
|
||||
if (c~="") then
|
||||
o = s:option(TextValue, "")
|
||||
o.readonly=true
|
||||
o.rows = 5
|
||||
o.rmempty = true
|
||||
o.name=""
|
||||
o.cfgvalue = function(self, section)
|
||||
return fs.readfile("/tmp/AdGuardHometest.log")
|
||||
end
|
||||
end
|
||||
end
|
||||
function m.on_commit(map)
|
||||
local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest")
|
||||
if ucitracktest=="1" then
|
||||
return
|
||||
elseif ucitracktest=="0" then
|
||||
io.popen("/etc/init.d/AdGuardHome reload &")
|
||||
else
|
||||
fs.writefile("/var/run/AdGlucitest","")
|
||||
end
|
||||
end
|
||||
return m
|
||||
@ -1,78 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%local fs=require"nixio.fs"%>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" id="apply_update_button" value="<%:Update core version%>" onclick=" return apply_update() "/>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" id="apply_forceupdate_button" value="<%:Force update%>" onclick=" return apply_forceupdate()" style="display:none"/>
|
||||
<% if self.showfastconfig then %>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" id="to_configpage" value="<%:Fast config%>" onclick="location.href='<%=url([[admin]], [[services]], [[AdGuardHome]], [[manual]])%>'"/>
|
||||
<%end%>
|
||||
<div id="logview" style="display:none">
|
||||
<input type="checkbox" id="reversetag" value="reverse" onclick=" return reverselog()" style="vertical-align:middle;height: auto;"><%:reverse%></input>
|
||||
<textarea id="cbid.logview.1.conf" class="cbi-input-textarea" style="width: 100%;display:block;" data-update="change" rows="5" cols="60" readonly="readonly" > </textarea>
|
||||
</div>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var updatebtn = document.getElementById('apply_update_button');
|
||||
var forceupdatebtn = document.getElementById('apply_forceupdate_button');
|
||||
var islogreverse = false;
|
||||
function apply_forceupdate(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[AdGuardHome]], [[doupdate]])%>',{ force: 1 },function(x, data){}
|
||||
);
|
||||
updatebtn.disabled = true;
|
||||
poll_check();
|
||||
return
|
||||
}
|
||||
function reverselog(){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML=lv.innerHTML.split('\n').reverse().join('\n')
|
||||
if (islogreverse){
|
||||
islogreverse=false;
|
||||
}else{
|
||||
islogreverse=true;
|
||||
}
|
||||
return
|
||||
}
|
||||
function apply_update(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[AdGuardHome]], [[doupdate]])%>',null,function(x, data){}
|
||||
);
|
||||
updatebtn.disabled = true;
|
||||
updatebtn.value = '<%:Check...%>';
|
||||
forceupdatebtn.style.display="inline"
|
||||
poll_check();
|
||||
return
|
||||
}
|
||||
function poll_check(){
|
||||
var tag = document.getElementById('logview');
|
||||
tag.style.display="block"
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[AdGuardHome]], [[check]])%>', null,
|
||||
function(x, data) {
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
if (x.responseText && lv) {
|
||||
if (x.responseText=="\u0000"){
|
||||
for(j = 0,len=this.XHR._q.length; j < len; j++) {
|
||||
if (this.XHR._q[j].url == '<%=url([[admin]], [[services]], [[AdGuardHome]], [[check]])%>'){
|
||||
this.XHR._q.splice(j,1);
|
||||
updatebtn.disabled = false;
|
||||
updatebtn.value = '<%:Updated%>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (islogreverse){
|
||||
lv.innerHTML = x.responseText.split('\n').reverse().join('\n')+lv.innerHTML;
|
||||
}else{
|
||||
lv.innerHTML += x.responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
);}
|
||||
<% if fs.access("/var/run/update_core") then %>
|
||||
updatebtn.disabled = true;
|
||||
updatebtn.value = '<%:Check...%>';
|
||||
forceupdatebtn.style.display="inline"
|
||||
poll_check();
|
||||
<%elseif fs.access("/var/run/update_core_error") then %>
|
||||
poll_check();
|
||||
<%end%>
|
||||
//]]>
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,49 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function chpass(btn)
|
||||
{
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:loading...%>';
|
||||
if (typeof bcryptloaded == 'undefined' ){
|
||||
var theHead = document.getElementsByTagName('head').item(0);
|
||||
//创建脚本的dom对象实例
|
||||
var myScript = document.createElement('script');
|
||||
myScript.src = '<%=resource%>/twin-bcrypt.min.js'; //指定脚本路径
|
||||
myScript.type = 'text/javascript'; //指定脚本类型
|
||||
myScript.defer = true; //程序下载完后再解析和执行
|
||||
theHead.appendChild(myScript);
|
||||
bcryptloaded=1;
|
||||
btn.value = '<%:Culculate%>';
|
||||
btn.disabled = false;
|
||||
return
|
||||
}
|
||||
var lv = document.getElementById('cbid.AdGuardHome.AdGuardHome.hashpass');
|
||||
if (lv.value != ""){
|
||||
var hash = TwinBcrypt.hashSync(lv.value);
|
||||
lv.value=hash;
|
||||
btn.value = '<%:Please save/apply%>';
|
||||
}else{
|
||||
btn.value = '<%:is empty%>';
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<input data-update="change"<%=
|
||||
attr("id", cbid) ..
|
||||
attr("name", cbid) ..
|
||||
attr("type", self.password and "password" or "text") ..
|
||||
attr("class", self.password and "cbi-input-password" or "cbi-input-text") ..
|
||||
attr("value", self:cfgvalue(section) or self.default) ..
|
||||
ifattr(self.size, "size") ..
|
||||
ifattr(self.placeholder, "placeholder") ..
|
||||
ifattr(self.readonly, "readonly") ..
|
||||
ifattr(self.maxlength, "maxlength") ..
|
||||
ifattr(self.datatype, "data-type", self.datatype) ..
|
||||
ifattr(self.datatype, "data-optional", self.optional or self.rmempty) ..
|
||||
ifattr(self.combobox_manual, "data-manual", self.combobox_manual) ..
|
||||
ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist })
|
||||
%> />
|
||||
<% if self.password then %><img src="<%=resource%>/cbi/reload.gif" style="vertical-align:middle" title="<%:Reveal/hide password%>" onclick="var e = document.getElementById('<%=cbid%>'); e.type = (e.type=='password') ? 'text' : 'password';" /><% end %>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" id="cbid.AdGuardHome.AdGuardHome.applychpass" value="<%:Load culculate model%>" onclick="return chpass(this)"/>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,27 +0,0 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[AdGuardHome]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('AdGuardHome_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
tb.innerHTML = '<em><b style=color:green>AdGuardHome <%:RUNNING%></b></em>';
|
||||
} else {
|
||||
tb.innerHTML = '<em><b style=color:red>AdGuardHome <%:NOT RUNNING%></b></em>';
|
||||
}
|
||||
if (data.redirect)
|
||||
{
|
||||
tb.innerHTML+='<em><b style=color:green><%:Redirected%></b></em>'
|
||||
} else {
|
||||
tb.innerHTML+='<em><b style=color:red><%:Not redirect%></b></em>'
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="AdGuardHome_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
@ -1,111 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<input type="checkbox" name="NAME" value="reverse" onclick=" return reverselog()" style="vertical-align:middle;height: auto;" checked><%:reverse%></input>
|
||||
<%if self.timereplace then%>
|
||||
<input type="checkbox" name="NAME" value="localtime" onclick=" return chlogtime()" style="vertical-align:middle;height: auto;" checked><%:localtime%></input><br>
|
||||
<%end%>
|
||||
<textarea id="cbid.logview.1.conf" class="cbi-input-textarea" style="width: 100%;display:inline" data-update="change" rows="32" cols="60" readonly="readonly" > </textarea>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" id="apply_update_button" value="<%:dellog%>" onclick=" return apply_del_log() "/>
|
||||
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:download log%>" style=" display:inline;" onclick=" return download_log()" />
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var islogreverse = true;
|
||||
var isutc2local = <%=tostring(self.timereplace)%>;
|
||||
function createAndDownloadFile(fileName, content) {
|
||||
var aTag = document.createElement('a');
|
||||
var blob = new Blob([content]);
|
||||
aTag.download = fileName;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(blob);
|
||||
}
|
||||
function download_log(){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
var dt = new Date();
|
||||
var timestamp = (dt.getMonth()+1)+"-"+dt.getDate()+"-"+dt.getHours()+"_"+dt.getMinutes();
|
||||
createAndDownloadFile("AdGuardHome"+timestamp+".log",lv.innerHTML)
|
||||
return
|
||||
}
|
||||
function apply_del_log(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[AdGuardHome]], [[dodellog]])%>',null,function(x, data){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML="";
|
||||
}
|
||||
);
|
||||
return
|
||||
}
|
||||
function chlogtime(){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
if (isutc2local){
|
||||
lv.innerHTML=line_toUTC(lv.innerHTML).join('\n');
|
||||
isutc2local=false;
|
||||
}else{
|
||||
lv.innerHTML=line_tolocal(lv.innerHTML).join('\n');
|
||||
isutc2local=true;
|
||||
}
|
||||
return
|
||||
}
|
||||
function reverselog(){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML=lv.innerHTML.split('\n').reverse().join('\n')
|
||||
if (islogreverse){
|
||||
islogreverse=false;
|
||||
}else{
|
||||
islogreverse=true;
|
||||
}
|
||||
return
|
||||
}
|
||||
function p(s) {
|
||||
return s < 10 ? '0' + s: s;
|
||||
}
|
||||
function line_tolocal(str){
|
||||
var strt=new Array();
|
||||
str.trim().split('\n').forEach(function(v, i) {
|
||||
var dt = new Date(v.substring(0,19)+" UTC");
|
||||
if (dt != "Invalid Date"){
|
||||
strt[i]=dt.getFullYear()+"/"+p(dt.getMonth()+1)+"/"+p(dt.getDate())+" "+p(dt.getHours())+":"+p(dt.getMinutes())+":"+p(dt.getSeconds())+v.substring(19);
|
||||
}else{
|
||||
strt[i]=v;}})
|
||||
return strt
|
||||
}
|
||||
function line_toUTC(str){
|
||||
var strt=new Array();
|
||||
str.trim().split('\n').forEach(function(v, i) {
|
||||
var dt = new Date(v.substring(0,19))
|
||||
if (dt != "Invalid Date"){
|
||||
strt[i]=dt.getUTCFullYear()+"/"+p(dt.getUTCMonth()+1)+"/"+p(dt.getUTCDate())+" "+p(dt.getUTCHours())+":"+p(dt.getUTCMinutes())+":"+p(dt.getUTCSeconds())+v.substring(19);
|
||||
}else{
|
||||
strt[i]=v;}})
|
||||
return strt
|
||||
}
|
||||
function poll_check(){
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[AdGuardHome]], [[getlog]])%>', null,
|
||||
function(x, data) {
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
if (x.responseText && lv) {
|
||||
if (isutc2local)
|
||||
{
|
||||
var lines=line_toUTC(x.responseText);
|
||||
if (islogreverse){
|
||||
lv.innerHTML = lines.reverse().join('\n')+lv.innerHTML;
|
||||
}else{
|
||||
lv.innerHTML += lines.join('\n');
|
||||
}
|
||||
lv.innerHTML=line_tolocal(lv.innerHTML).join('\n');
|
||||
}else{
|
||||
if (islogreverse){
|
||||
lv.innerHTML = x.responseText.split('\n').reverse().join('\n')+lv.innerHTML;
|
||||
}else{
|
||||
lv.innerHTML += x.responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);}
|
||||
<%if self.pollcheck then%>
|
||||
poll_check();
|
||||
<%else%>
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML="<%:Please add log path in config to enable log%>"
|
||||
<%end%>
|
||||
//]]>
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -1,39 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<script src="/luci-static/resources/codemirror/lib/codemirror.js"></script>
|
||||
<link rel="stylesheet" href="/luci-static/resources/codemirror/lib/codemirror.css"/>
|
||||
<script src="/luci-static/resources/codemirror/mode/yaml/yaml.js"></script>
|
||||
<link rel="stylesheet" href="/luci-static/resources/codemirror/theme/dracula.css"/>
|
||||
<link rel="stylesheet" href="/luci-static/resources/codemirror/addon/fold/foldgutter.css"/>
|
||||
<script src="/luci-static/resources/codemirror/addon/fold/foldcode.js"></script>
|
||||
<script src="/luci-static/resources/codemirror/addon/fold/foldgutter.js"></script>
|
||||
<script src="/luci-static/resources/codemirror/addon/fold/indent-fold.js"></script>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("cbid.AdGuardHome.AdGuardHome.escconf"), {
|
||||
mode: "text/yaml", //实现groovy代码高亮
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true, //显示行号
|
||||
theme: "dracula", //设置主题
|
||||
lineWrapping: true, //代码折叠
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
matchBrackets: true //括号匹配
|
||||
}
|
||||
);
|
||||
function reload_config(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[AdGuardHome]], [[reloadconfig]])%>', null,
|
||||
function(x, data) {
|
||||
location.reload();
|
||||
});}
|
||||
function use_template(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[AdGuardHome]], [[gettemplateconfig]])%>', null,
|
||||
function(x, data) {
|
||||
editor.setValue(x.responseText)
|
||||
});}
|
||||
//]]>
|
||||
</script>
|
||||
<%fs=require"nixio.fs"%>
|
||||
<%if fs.access("/tmp/AdGuardHometmpconfig.yaml") then%>
|
||||
<input type="button" id="apply_update_button" value="<%:Reload Config%>" onclick=" return reload_config() "/>
|
||||
<%end%>
|
||||
<input type="button" id="template_button" value="<%:Use template%>" onclick=" return use_template() "/>
|
||||
<%+cbi/valuefooter%>
|
||||
1
luci-app-adguardhome/po/zh-cn
Symbolic link
1
luci-app-adguardhome/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
@ -1,303 +0,0 @@
|
||||
#/cgi-bin/luci/admin/services/AdGuardHome
|
||||
msgid "Base Setting"
|
||||
msgstr "基础设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "AdGuardHome's version"
|
||||
msgstr "AdGuardHome 版本"
|
||||
|
||||
msgid "Needed to click 'save&apply' to generate the configuration file"
|
||||
msgstr "需要点击“保存并应用”才能生成配置文件"
|
||||
|
||||
msgid "In case of the latest realease is a source code that can not download the binary file"
|
||||
msgstr "防止最新release只有源码,导致下载不成功"
|
||||
|
||||
msgid "Manual Config"
|
||||
msgstr "手动设置"
|
||||
|
||||
msgid "Free and open source, powerful network-wide ads & trackers blocking DNS server."
|
||||
msgstr "全网络广告和跟踪程序拦截DNS服务器,默认账号和密码均为:admin"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Redirected"
|
||||
msgstr "已重定向"
|
||||
|
||||
msgid "Not redirect"
|
||||
msgstr "未重定向"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Browser management port"
|
||||
msgstr "网页管理账号和密码:admin ,端口:"
|
||||
|
||||
msgid "Upgrade Core"
|
||||
msgstr "更新核心"
|
||||
|
||||
#button change
|
||||
msgid "Update core version"
|
||||
msgstr "更新核心版本"
|
||||
|
||||
msgid "Check..."
|
||||
msgstr "检查中..."
|
||||
|
||||
msgid "Updated"
|
||||
msgstr "已更新"
|
||||
|
||||
#button hide
|
||||
msgid "Force update"
|
||||
msgstr "强制更新核心"
|
||||
|
||||
msgid "Fast config"
|
||||
msgstr "快速配置"
|
||||
|
||||
msgid "Core Version"
|
||||
msgstr "核心版本"
|
||||
|
||||
msgid "Latest Version"
|
||||
msgstr "最新版"
|
||||
|
||||
msgid "Beta Version"
|
||||
msgstr "测试版"
|
||||
|
||||
msgid "Current core version:"
|
||||
msgstr "当前核心版本:"
|
||||
|
||||
msgid "core version:"
|
||||
msgstr "核心版本:"
|
||||
|
||||
msgid "no config"
|
||||
msgstr "没有配置文件"
|
||||
|
||||
msgid "no core"
|
||||
msgstr "没有核心"
|
||||
|
||||
#
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
#inlist
|
||||
msgid "none"
|
||||
msgstr "无"
|
||||
|
||||
msgid "Run as dnsmasq upstream server"
|
||||
msgstr "作为dnsmasq的上游服务器"
|
||||
|
||||
msgid "Redirect 53 port to AdGuardHome"
|
||||
msgstr "重定向53端口到AdGuardHome"
|
||||
|
||||
msgid "Use port 53 replace dnsmasq"
|
||||
msgstr "使用53端口替换dnsmasq"
|
||||
|
||||
#
|
||||
msgid "AdGuardHome redirect mode"
|
||||
msgstr "AdGuardHome重定向模式"
|
||||
|
||||
msgid "Bin Path"
|
||||
msgstr "执行文件路径"
|
||||
|
||||
msgid "AdGuardHome Bin path if no bin will auto download"
|
||||
msgstr "AdGuardHome 执行文件路径 如果没有执行文件将自动下载"
|
||||
|
||||
msgid "use upx to compress bin after download"
|
||||
msgstr "下载后使用upx压缩执行文件"
|
||||
|
||||
#inlist
|
||||
msgid "compress faster"
|
||||
msgstr "快速压缩"
|
||||
|
||||
msgid "compress better"
|
||||
msgstr "更好的压缩"
|
||||
|
||||
msgid "compress best(can be slow for big files)"
|
||||
msgstr "最好的压缩(大文件可能慢)"
|
||||
|
||||
msgid "try all available compression methods & filters [slow]"
|
||||
msgstr "尝试所有可能的压缩方法和过滤器[慢]"
|
||||
|
||||
msgid "try even more compression variants [very slow]"
|
||||
msgstr "尝试更多变体压缩手段[很慢]"
|
||||
|
||||
msgid "bin use less space,but may have compatibility issues"
|
||||
msgstr "减小执行文件空间占用,但是可能压缩后有兼容性问题"
|
||||
#
|
||||
msgid "Config Path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "AdGuardHome config path"
|
||||
msgstr "AdGuardHome 配置文件路径"
|
||||
|
||||
msgid "Work dir"
|
||||
msgstr "工作目录"
|
||||
|
||||
msgid "AdGuardHome work dir include rules,audit log and database"
|
||||
msgstr "AdGuardHome 工作目录包含规则,审计日志和数据库"
|
||||
|
||||
msgid "Runtime log file"
|
||||
msgstr "运行日志路径"
|
||||
|
||||
msgid "AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"
|
||||
msgstr "AdGuardHome 运行日志, 如果填 syslog 将写入系统日志; 如果该项为空则不记录运行日志"
|
||||
|
||||
msgid "Verbose log"
|
||||
msgstr "输出详细日志"
|
||||
|
||||
#hide div
|
||||
msgid "Add gfwlist"
|
||||
msgstr "添加 GFW 列表"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "添加"
|
||||
|
||||
msgid "Added"
|
||||
msgstr "已添加"
|
||||
|
||||
msgid "Not added"
|
||||
msgstr "未添加"
|
||||
|
||||
#hide div
|
||||
msgid "Del gfwlist"
|
||||
msgstr "删除gfw列表"
|
||||
|
||||
msgid "Del"
|
||||
msgstr "删除"
|
||||
|
||||
#hide div
|
||||
msgid "Gfwlist upstream dns server"
|
||||
msgstr "gfw列表上游服务器"
|
||||
|
||||
msgid "Gfwlist domain upstream dns service"
|
||||
msgstr "gfw列表域名上游服务器"
|
||||
|
||||
#hide div
|
||||
msgid "Change browser management password"
|
||||
msgstr "更改网页登录密码"
|
||||
|
||||
msgid "Culculate"
|
||||
msgstr "计算"
|
||||
|
||||
##button change
|
||||
msgid "Load culculate model"
|
||||
msgstr "载入计算模块"
|
||||
|
||||
msgid "loading..."
|
||||
msgstr "载入中"
|
||||
|
||||
msgid "Please save/apply"
|
||||
msgstr "请点击[保存/应用]"
|
||||
|
||||
msgid "is empty"
|
||||
msgstr "为空"
|
||||
|
||||
msgid "Press load culculate model and culculate finally save/apply"
|
||||
msgstr "先输入你想要的密码, 点击[载入计算模块], 然后点击[计算], 最后点击下方[保存&应用]"
|
||||
|
||||
#
|
||||
msgid "Keep files when system upgrade"
|
||||
msgstr "系统升级时保留文件"
|
||||
|
||||
#checkbox
|
||||
msgid "core bin"
|
||||
msgstr "核心执行文件"
|
||||
|
||||
msgid "config file"
|
||||
msgstr "配置文件"
|
||||
|
||||
msgid "log file"
|
||||
msgstr "日志文件"
|
||||
|
||||
msgid "querylog.json"
|
||||
msgstr "审计日志.json"
|
||||
|
||||
#
|
||||
msgid "On boot when network ok restart"
|
||||
msgstr "开机后网络准备好时重启"
|
||||
|
||||
msgid "Backup workdir files when shutdown"
|
||||
msgstr "在关机时备份工作目录文件"
|
||||
|
||||
msgid "Will be restore when workdir/data is empty"
|
||||
msgstr "在工作目录/data为空的时候恢复"
|
||||
|
||||
msgid "Backup workdir path"
|
||||
msgstr "工作目录备份路径"
|
||||
|
||||
msgid "Crontab task"
|
||||
msgstr "计划任务"
|
||||
|
||||
msgid "Auto update core"
|
||||
msgstr "自动升级核心"
|
||||
|
||||
msgid "Auto tail querylog"
|
||||
msgstr "自动截短查询日志"
|
||||
|
||||
msgid "Auto tail runtime log"
|
||||
msgstr "自动截短运行日志"
|
||||
|
||||
msgid "Auto update ipv6 hosts and restart adh"
|
||||
msgstr "自动更新ipv6主机并重启adh"
|
||||
|
||||
msgid "Auto update gfwlist and restart adh"
|
||||
msgstr "自动更新gfw列表并重启adh"
|
||||
|
||||
msgid "Please change time and args in crontab"
|
||||
msgstr "请在计划任务中修改时间和参数"
|
||||
|
||||
msgid "Core Update URL"
|
||||
msgstr "核心更新地址"
|
||||
|
||||
#/cgi-bin/luci/admin/services/AdGuardHome/log/
|
||||
msgid "reverse"
|
||||
msgstr "逆序"
|
||||
|
||||
msgid "localtime"
|
||||
msgstr "本地时间"
|
||||
|
||||
msgid "Please add log path in config to enable log"
|
||||
msgstr "请在设置里填写日志路径以启用日志"
|
||||
|
||||
msgid "dellog"
|
||||
msgstr "删除日志"
|
||||
|
||||
msgid "download log"
|
||||
msgstr "下载日志"
|
||||
|
||||
#/cgi-bin/luci//admin/services/AdGuardHome/manual/
|
||||
msgid "Use template"
|
||||
msgstr "使用模板"
|
||||
|
||||
#hide button
|
||||
msgid "Reload Config"
|
||||
msgstr "重新载入配置"
|
||||
|
||||
msgid "WARNING!!! no bin found apply config will not be test"
|
||||
msgstr "警告!!!未找到执行文件,提交配置将不会进行校验"
|
||||
|
||||
#unused
|
||||
msgid "Change browser management username"
|
||||
msgstr "改变网页登录用户名"
|
||||
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Check Config"
|
||||
msgstr "检查配置"
|
||||
|
||||
msgid "unknown"
|
||||
msgstr "未知"
|
||||
|
||||
msgid "Keep database when system upgrade"
|
||||
msgstr "系统升级时保留数据"
|
||||
|
||||
msgid "Boot delay until network ok"
|
||||
msgstr "开机时直到网络准备好再启动"
|
||||
@ -1,303 +0,0 @@
|
||||
#/cgi-bin/luci/admin/services/AdGuardHome
|
||||
msgid "Base Setting"
|
||||
msgstr "基础设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "AdGuardHome's version"
|
||||
msgstr "AdGuardHome 版本"
|
||||
|
||||
msgid "Needed to click 'save&apply' to generate the configuration file"
|
||||
msgstr "需要点击“保存并应用”才能生成配置文件"
|
||||
|
||||
msgid "In case of the latest realease is a source code that can not download the binary file"
|
||||
msgstr "防止最新release只有源码,导致下载不成功"
|
||||
|
||||
msgid "Manual Config"
|
||||
msgstr "手动设置"
|
||||
|
||||
msgid "Free and open source, powerful network-wide ads & trackers blocking DNS server."
|
||||
msgstr "全网络广告和跟踪程序拦截DNS服务器,默认账号和密码均为:admin"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Redirected"
|
||||
msgstr "已重定向"
|
||||
|
||||
msgid "Not redirect"
|
||||
msgstr "未重定向"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Browser management port"
|
||||
msgstr "网页管理账号和密码:admin ,端口:"
|
||||
|
||||
msgid "Upgrade Core"
|
||||
msgstr "更新核心"
|
||||
|
||||
#button change
|
||||
msgid "Update core version"
|
||||
msgstr "更新核心版本"
|
||||
|
||||
msgid "Check..."
|
||||
msgstr "检查中..."
|
||||
|
||||
msgid "Updated"
|
||||
msgstr "已更新"
|
||||
|
||||
#button hide
|
||||
msgid "Force update"
|
||||
msgstr "强制更新核心"
|
||||
|
||||
msgid "Fast config"
|
||||
msgstr "快速配置"
|
||||
|
||||
msgid "Core Version"
|
||||
msgstr "核心版本"
|
||||
|
||||
msgid "Latest Version"
|
||||
msgstr "最新版"
|
||||
|
||||
msgid "Beta Version"
|
||||
msgstr "测试版"
|
||||
|
||||
msgid "Current core version:"
|
||||
msgstr "当前核心版本:"
|
||||
|
||||
msgid "core version:"
|
||||
msgstr "核心版本:"
|
||||
|
||||
msgid "no config"
|
||||
msgstr "没有配置文件"
|
||||
|
||||
msgid "no core"
|
||||
msgstr "没有核心"
|
||||
|
||||
#
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
#inlist
|
||||
msgid "none"
|
||||
msgstr "无"
|
||||
|
||||
msgid "Run as dnsmasq upstream server"
|
||||
msgstr "作为dnsmasq的上游服务器"
|
||||
|
||||
msgid "Redirect 53 port to AdGuardHome"
|
||||
msgstr "重定向53端口到AdGuardHome"
|
||||
|
||||
msgid "Use port 53 replace dnsmasq"
|
||||
msgstr "使用53端口替换dnsmasq"
|
||||
|
||||
#
|
||||
msgid "AdGuardHome redirect mode"
|
||||
msgstr "AdGuardHome重定向模式"
|
||||
|
||||
msgid "Bin Path"
|
||||
msgstr "执行文件路径"
|
||||
|
||||
msgid "AdGuardHome Bin path if no bin will auto download"
|
||||
msgstr "AdGuardHome 执行文件路径 如果没有执行文件将自动下载"
|
||||
|
||||
msgid "use upx to compress bin after download"
|
||||
msgstr "下载后使用upx压缩执行文件"
|
||||
|
||||
#inlist
|
||||
msgid "compress faster"
|
||||
msgstr "快速压缩"
|
||||
|
||||
msgid "compress better"
|
||||
msgstr "更好的压缩"
|
||||
|
||||
msgid "compress best(can be slow for big files)"
|
||||
msgstr "最好的压缩(大文件可能慢)"
|
||||
|
||||
msgid "try all available compression methods & filters [slow]"
|
||||
msgstr "尝试所有可能的压缩方法和过滤器[慢]"
|
||||
|
||||
msgid "try even more compression variants [very slow]"
|
||||
msgstr "尝试更多变体压缩手段[很慢]"
|
||||
|
||||
msgid "bin use less space,but may have compatibility issues"
|
||||
msgstr "减小执行文件空间占用,但是可能压缩后有兼容性问题"
|
||||
#
|
||||
msgid "Config Path"
|
||||
msgstr "配置文件路径"
|
||||
|
||||
msgid "AdGuardHome config path"
|
||||
msgstr "AdGuardHome 配置文件路径"
|
||||
|
||||
msgid "Work dir"
|
||||
msgstr "工作目录"
|
||||
|
||||
msgid "AdGuardHome work dir include rules,audit log and database"
|
||||
msgstr "AdGuardHome 工作目录包含规则,审计日志和数据库"
|
||||
|
||||
msgid "Runtime log file"
|
||||
msgstr "运行日志路径"
|
||||
|
||||
msgid "AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log"
|
||||
msgstr "AdGuardHome 运行日志, 如果填 syslog 将写入系统日志; 如果该项为空则不记录运行日志"
|
||||
|
||||
msgid "Verbose log"
|
||||
msgstr "输出详细日志"
|
||||
|
||||
#hide div
|
||||
msgid "Add gfwlist"
|
||||
msgstr "添加 GFW 列表"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "添加"
|
||||
|
||||
msgid "Added"
|
||||
msgstr "已添加"
|
||||
|
||||
msgid "Not added"
|
||||
msgstr "未添加"
|
||||
|
||||
#hide div
|
||||
msgid "Del gfwlist"
|
||||
msgstr "删除gfw列表"
|
||||
|
||||
msgid "Del"
|
||||
msgstr "删除"
|
||||
|
||||
#hide div
|
||||
msgid "Gfwlist upstream dns server"
|
||||
msgstr "gfw列表上游服务器"
|
||||
|
||||
msgid "Gfwlist domain upstream dns service"
|
||||
msgstr "gfw列表域名上游服务器"
|
||||
|
||||
#hide div
|
||||
msgid "Change browser management password"
|
||||
msgstr "更改网页登录密码"
|
||||
|
||||
msgid "Culculate"
|
||||
msgstr "计算"
|
||||
|
||||
##button change
|
||||
msgid "Load culculate model"
|
||||
msgstr "载入计算模块"
|
||||
|
||||
msgid "loading..."
|
||||
msgstr "载入中"
|
||||
|
||||
msgid "Please save/apply"
|
||||
msgstr "请点击[保存/应用]"
|
||||
|
||||
msgid "is empty"
|
||||
msgstr "为空"
|
||||
|
||||
msgid "Press load culculate model and culculate finally save/apply"
|
||||
msgstr "先输入你想要的密码, 点击[载入计算模块], 然后点击[计算], 最后点击下方[保存&应用]"
|
||||
|
||||
#
|
||||
msgid "Keep files when system upgrade"
|
||||
msgstr "系统升级时保留文件"
|
||||
|
||||
#checkbox
|
||||
msgid "core bin"
|
||||
msgstr "核心执行文件"
|
||||
|
||||
msgid "config file"
|
||||
msgstr "配置文件"
|
||||
|
||||
msgid "log file"
|
||||
msgstr "日志文件"
|
||||
|
||||
msgid "querylog.json"
|
||||
msgstr "审计日志.json"
|
||||
|
||||
#
|
||||
msgid "On boot when network ok restart"
|
||||
msgstr "开机后网络准备好时重启"
|
||||
|
||||
msgid "Backup workdir files when shutdown"
|
||||
msgstr "在关机时备份工作目录文件"
|
||||
|
||||
msgid "Will be restore when workdir/data is empty"
|
||||
msgstr "在工作目录/data为空的时候恢复"
|
||||
|
||||
msgid "Backup workdir path"
|
||||
msgstr "工作目录备份路径"
|
||||
|
||||
msgid "Crontab task"
|
||||
msgstr "计划任务"
|
||||
|
||||
msgid "Auto update core"
|
||||
msgstr "自动升级核心"
|
||||
|
||||
msgid "Auto tail querylog"
|
||||
msgstr "自动截短查询日志"
|
||||
|
||||
msgid "Auto tail runtime log"
|
||||
msgstr "自动截短运行日志"
|
||||
|
||||
msgid "Auto update ipv6 hosts and restart adh"
|
||||
msgstr "自动更新ipv6主机并重启adh"
|
||||
|
||||
msgid "Auto update gfwlist and restart adh"
|
||||
msgstr "自动更新gfw列表并重启adh"
|
||||
|
||||
msgid "Please change time and args in crontab"
|
||||
msgstr "请在计划任务中修改时间和参数"
|
||||
|
||||
msgid "Core Update URL"
|
||||
msgstr "核心更新地址"
|
||||
|
||||
#/cgi-bin/luci/admin/services/AdGuardHome/log/
|
||||
msgid "reverse"
|
||||
msgstr "逆序"
|
||||
|
||||
msgid "localtime"
|
||||
msgstr "本地时间"
|
||||
|
||||
msgid "Please add log path in config to enable log"
|
||||
msgstr "请在设置里填写日志路径以启用日志"
|
||||
|
||||
msgid "dellog"
|
||||
msgstr "删除日志"
|
||||
|
||||
msgid "download log"
|
||||
msgstr "下载日志"
|
||||
|
||||
#/cgi-bin/luci//admin/services/AdGuardHome/manual/
|
||||
msgid "Use template"
|
||||
msgstr "使用模板"
|
||||
|
||||
#hide button
|
||||
msgid "Reload Config"
|
||||
msgstr "重新载入配置"
|
||||
|
||||
msgid "WARNING!!! no bin found apply config will not be test"
|
||||
msgstr "警告!!!未找到执行文件,提交配置将不会进行校验"
|
||||
|
||||
#unused
|
||||
msgid "Change browser management username"
|
||||
msgstr "改变网页登录用户名"
|
||||
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Check Config"
|
||||
msgstr "检查配置"
|
||||
|
||||
msgid "unknown"
|
||||
msgstr "未知"
|
||||
|
||||
msgid "Keep database when system upgrade"
|
||||
msgstr "系统升级时保留数据"
|
||||
|
||||
msgid "Boot delay until network ok"
|
||||
msgstr "开机时直到网络准备好再启动"
|
||||
179
luci-app-adguardhome/po/zh_Hans/adguardhome.po
Normal file
179
luci-app-adguardhome/po/zh_Hans/adguardhome.po
Normal file
@ -0,0 +1,179 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "AdGuard Home"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdGuard Home Configuration"
|
||||
msgstr "配置"
|
||||
|
||||
msgid "AdGuard Home Statistics"
|
||||
msgstr "统计"
|
||||
|
||||
msgid "AdGuard Home Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "AdGuard Home Status - Error"
|
||||
msgstr "状态 - 错误"
|
||||
|
||||
msgid "Average processing time (seconds)"
|
||||
msgstr "平均处理时间(秒)"
|
||||
|
||||
msgid "Bootstrap DNS addresses"
|
||||
msgstr "Bootstrap DNS 地址"
|
||||
|
||||
msgid "Configuration"
|
||||
msgstr "配置"
|
||||
|
||||
msgid "DNS blocks"
|
||||
msgstr "DNS 拦截"
|
||||
|
||||
msgid "DNS listen addresses"
|
||||
msgstr "DNS 监听地址"
|
||||
|
||||
msgid "DNS listen port"
|
||||
msgstr "DNS 监听端口"
|
||||
|
||||
msgid "DNS queries"
|
||||
msgstr "DNS 查询"
|
||||
|
||||
msgid "DNS replacements (malware/phishing)"
|
||||
msgstr "DNS 替换(恶意软件/钓鱼)"
|
||||
|
||||
msgid "DNS replacements (safesearch)"
|
||||
msgstr "DNS 替换(安全搜索)"
|
||||
|
||||
msgid "General settings"
|
||||
msgstr "常规设置"
|
||||
|
||||
msgid "Grant permissions for the AdGuard Home LuCI app"
|
||||
msgstr "授予 AdGuard Home LuCI 应用权限"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "No"
|
||||
msgstr "否"
|
||||
|
||||
msgid "Not found"
|
||||
msgstr "未找到"
|
||||
|
||||
msgid "Password for AdGuard Home"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Please open the Configuration section, and provide the credentials."
|
||||
msgstr "请打开配置部分,并提供凭证。"
|
||||
|
||||
msgid "Protection enabled"
|
||||
msgstr "保护已启用"
|
||||
|
||||
msgid "RPC call failure:"
|
||||
msgstr "RPC 调用失败:"
|
||||
|
||||
msgid "Running"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "Showing last 50 lines"
|
||||
msgstr "显示最近的50行"
|
||||
|
||||
msgid "Statistics period (days)"
|
||||
msgstr "统计周期(天)"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
msgid "System Log (AdGuard Home)"
|
||||
msgstr "系统日志"
|
||||
|
||||
msgid "The password you configured when you set up AdGuard Home"
|
||||
msgstr "您在设置 AdGuard Home 时配置的密码"
|
||||
|
||||
msgid "The username you configured when you set up AdGuard Home"
|
||||
msgstr "您在设置 AdGuard Home 时配置的用户名"
|
||||
|
||||
msgid ""
|
||||
"This application requires the username and password that were configured "
|
||||
"when you set up AdGuard Home, as the REST API for AdGuard Home is password "
|
||||
"protected. The password cannot be read from the YAML configuration file for "
|
||||
"AdGuard Home, as it is encrypted in that store. The credentials supplied "
|
||||
"here will be stored unencrypted in /etc/config/adguardhome on your device."
|
||||
msgstr ""
|
||||
"此应用程序需要您在设置 AdGuard Home 时配置的用户名和密码,因为 AdGuard Home 的 REST API 受密码保护。"
|
||||
"密码无法从 AdGuard Home 的 YAML 配置文件中读取,因为它在存储中是加密的。"
|
||||
"此处提供的凭证将以未加密的形式存储在设备上的 /etc/config/adguardhome 中。"
|
||||
|
||||
msgid "Top Blocked Domains"
|
||||
msgstr "最常被拦截的域名"
|
||||
|
||||
msgid "Top Queried Domains"
|
||||
msgstr "最常查询的域名"
|
||||
|
||||
msgid "Unable to load log data:"
|
||||
msgstr "无法加载日志数据:"
|
||||
|
||||
msgid "Upstream DNS addresses"
|
||||
msgstr "上游 DNS 地址"
|
||||
|
||||
msgid "Username for AdGuard Home"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Version"
|
||||
msgstr "版本"
|
||||
|
||||
msgid "Web interface"
|
||||
msgstr "AdGuardHome 管理界面"
|
||||
|
||||
msgid "Yes"
|
||||
msgstr "是"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Redirect"
|
||||
msgstr "重定向"
|
||||
|
||||
msgid "none"
|
||||
msgstr "无"
|
||||
|
||||
msgid "Run as dnsmasq upstream server"
|
||||
msgstr "作为dnsmasq的上游服务器"
|
||||
|
||||
msgid "Redirect 53 port to AdGuardHome"
|
||||
msgstr "重定向53端口到AdGuardHome"
|
||||
|
||||
msgid "Use port 53 replace dnsmasq"
|
||||
msgstr "使用53端口替换dnsmasq"
|
||||
|
||||
msgid "AdGuardHome redirect mode"
|
||||
msgstr "重定向模式"
|
||||
|
||||
msgid "Change Password"
|
||||
msgstr "修改密码"
|
||||
|
||||
msgid "Work Dir"
|
||||
msgstr "工作目录"
|
||||
|
||||
msgid "Service user"
|
||||
msgstr "以此用户权限运行"
|
||||
|
||||
msgid "Service group"
|
||||
msgstr "以此用户组权限运行"
|
||||
|
||||
msgid "Configuration file"
|
||||
msgstr "配置文件"
|
||||
@ -1,219 +0,0 @@
|
||||
http:
|
||||
address: 0.0.0.0:3000
|
||||
session_ttl: 720h
|
||||
users:
|
||||
- name: admin
|
||||
password: $2y$10$vHRcARdPCieYG3RXWomV5evDYN.Nj/edtwEkQgQJZcK6z7qTLaIc6
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: zh-cn
|
||||
theme: auto
|
||||
debug_pprof: false
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 1745
|
||||
anonymize_client_ip: false
|
||||
protection_enabled: true
|
||||
blocking_mode: default
|
||||
blocking_ipv4: ""
|
||||
blocking_ipv6: ""
|
||||
blocked_response_ttl: 10
|
||||
protection_disabled_until: null
|
||||
parental_block_host: family-block.dns.adguard.com
|
||||
safebrowsing_block_host: standard-block.dns.adguard.com
|
||||
ratelimit: 0
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: false
|
||||
upstream_dns:
|
||||
- 223.5.5.5
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 119.29.29.29
|
||||
- 223.5.5.5
|
||||
all_servers: false
|
||||
fastest_addr: false
|
||||
fastest_timeout: 1s
|
||||
allowed_clients: []
|
||||
disallowed_clients: []
|
||||
blocked_hosts:
|
||||
- version.bind
|
||||
- id.server
|
||||
- hostname.bind
|
||||
trusted_proxies:
|
||||
- 127.0.0.0/8
|
||||
- ::1/128
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: true
|
||||
bogus_nxdomain: []
|
||||
aaaa_disabled: false
|
||||
enable_dnssec: false
|
||||
edns_client_subnet: false
|
||||
max_goroutines: 300
|
||||
ipset: []
|
||||
filtering_enabled: true
|
||||
filters_update_interval: 24
|
||||
parental_enabled: false
|
||||
safesearch_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
safebrowsing_cache_size: 1048576
|
||||
safesearch_cache_size: 1048576
|
||||
parental_cache_size: 1048576
|
||||
cache_time: 30
|
||||
rewrites: []
|
||||
blocked_services: []
|
||||
upstream_timeout: 10s
|
||||
private_networks: []
|
||||
use_private_ptr_resolvers: true
|
||||
local_ptr_upstreams: []
|
||||
tls:
|
||||
enabled: false
|
||||
server_name: ""
|
||||
force_https: false
|
||||
port_https: 443
|
||||
port_dns_over_tls: 853
|
||||
port_dns_over_quic: 784
|
||||
port_dnscrypt: 0
|
||||
dnscrypt_config_file: ""
|
||||
allow_unencrypted_doh: false
|
||||
certificate_chain: ""
|
||||
private_key: ""
|
||||
certificate_path: ""
|
||||
private_key_path: ""
|
||||
filters:
|
||||
- enabled: true
|
||||
url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
|
||||
name: AdGuard DNS filter
|
||||
id: 1228750870
|
||||
- enabled: true
|
||||
url: http://sub.adtchrome.com/adt-chinalist-easylist.txt
|
||||
name: 广告终结者使用的拦截规则,基于ChinaList+EasyList修正维护
|
||||
id: 139789181
|
||||
- enabled: true
|
||||
url: https://easylist-downloads.adblockplus.org/easylist.txt
|
||||
name: EasyList-去除国际网页中大多数广告,包括不需要的框架、图像和对象
|
||||
id: 139789112
|
||||
- enabled: true
|
||||
url: https://easylist-downloads.adblockplus.org/easylistchina.txt
|
||||
name: EasyList China-EasyList针对国内的补充规则
|
||||
id: 139789121
|
||||
- enabled: true
|
||||
url: https://anti-ad.net/adguard.txt
|
||||
name: anti-AD命中率最高列表
|
||||
id: 139789122
|
||||
- enabled: false
|
||||
url: https://raw.iqiq.io/banbendalao/ADgk/master/ADgk.txt
|
||||
name: ADgk去广告easylistchina补充规则
|
||||
id: 139789131
|
||||
- enabled: false
|
||||
url: https://raw.iqiq.io/banbendalao/ADgk/master/kill-baidu-ad.txt
|
||||
name: ADgk百度广告过滤
|
||||
id: 139789133
|
||||
- enabled: false
|
||||
url: https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext
|
||||
name: Peter Lowe’s Ad and tracking server list
|
||||
id: 139789152
|
||||
- enabled: false
|
||||
url: https://easylist.to/easylist/fanboy-social.txt
|
||||
name: Fanboy's Social Blocking List
|
||||
id: 139789153
|
||||
- enabled: false
|
||||
url: https://easylist.to/easylist/fanboy-annoyance.txt
|
||||
name: Fanboy's Annoyance List
|
||||
id: 139789154
|
||||
- enabled: false
|
||||
url: https://secure.fanboy.co.nz/fanboy-cookiemonster.txt
|
||||
name: EasyList Cookie List
|
||||
id: 139789155
|
||||
- enabled: false
|
||||
url: https://fanboy.co.nz/fanboy-antifacebook.txt
|
||||
name: Anti-Facebook List
|
||||
id: 139789161
|
||||
- enabled: false
|
||||
url: https://filters.adtidy.org/extension/ublock/filters/14.txt
|
||||
name: AdGuard Annoyances filter
|
||||
id: 139789162
|
||||
- enabled: false
|
||||
url: https://www.fanboy.co.nz/enhancedstats.txt
|
||||
name: Fanboy's Enhanced Tracking List
|
||||
id: 139789164
|
||||
- enabled: false
|
||||
url: https://filters.adtidy.org/extension/ublock/filters/3.txt
|
||||
name: AdGuard Tracking Protection filter
|
||||
id: 139789165
|
||||
- enabled: false
|
||||
url: https://easylist.to/easylist/easylist.txt
|
||||
name: EasyList
|
||||
id: 139789171
|
||||
- enabled: false
|
||||
url: https://filters.adtidy.org/extension/ublock/filters/11.txt
|
||||
name: AdGuard Mobile Ads filter
|
||||
id: 139789172
|
||||
- enabled: false
|
||||
url: https://filters.adtidy.org/extension/ublock/filters/2_without_easylist.txt
|
||||
name: AdGuard Base filter
|
||||
id: 139789173
|
||||
- enabled: false
|
||||
url: https://easylist-downloads.adblockplus.org/antiadblockfilters.txt
|
||||
name: Adblock Warning Removal List
|
||||
id: 139789174
|
||||
- enabled: false
|
||||
url: https://fanboy.co.nz/fanboy-problematic-sites.txt
|
||||
name: Fanboy's problematic-sites
|
||||
id: 139789175
|
||||
- enabled: false
|
||||
url: https://adaway.org/hosts.txt
|
||||
name: Adaway HOST
|
||||
id: 139789187
|
||||
whitelist_filters: []
|
||||
user_rules:
|
||||
- '@@||taobao.com^$important'
|
||||
- '@@||tmall.com^$important'
|
||||
- '@@||jd.com^important'
|
||||
- '@@||flyme.cn^$important'
|
||||
- '@@||meizu.com^$important'
|
||||
- '@@||wl.jd.com^$important'
|
||||
- '@@||flydigi.com^'
|
||||
- '@@||pv.sohu.com^$important'
|
||||
- /googleads.$~script,domain=~googleads.github.io
|
||||
- /pagead/lvz?
|
||||
- '||google.com/pagead/'
|
||||
- '||static.doubleclick.net^$domain=youtube.com'
|
||||
- '||youtube.com/get_midroll_'
|
||||
- '||5hz.org^'
|
||||
- '@@||000714.xyz^'
|
||||
- '@@||blueskyxn.com^'
|
||||
- '||topnewsfeeds.net^'
|
||||
- '||nbryb.com^'
|
||||
- '||superbdolly.com^'
|
||||
- '||salutationcheerlessdemote.com^'
|
||||
- '||buildingdoodlesquare.com^'
|
||||
- '||colonistnobilityheroic.com^'
|
||||
dhcp:
|
||||
enabled: false
|
||||
interface_name: ""
|
||||
dhcpv4:
|
||||
gateway_ip: ""
|
||||
subnet_mask: ""
|
||||
range_start: ""
|
||||
range_end: ""
|
||||
lease_duration: 86400
|
||||
icmp_timeout_msec: 1000
|
||||
options: []
|
||||
dhcpv6:
|
||||
range_start: ""
|
||||
lease_duration: 86400
|
||||
ra_slaac_only: false
|
||||
ra_allow_slaac: false
|
||||
clients: []
|
||||
log_compress: false
|
||||
log_localtime: false
|
||||
log_max_backups: 0
|
||||
log_max_size: 100
|
||||
log_max_age: 3
|
||||
log_file: ""
|
||||
verbose: false
|
||||
schema_version: 10
|
||||
180
luci-app-adguardhome/root/etc/adguardhome/adguardhome.yaml
Normal file
180
luci-app-adguardhome/root/etc/adguardhome/adguardhome.yaml
Normal file
@ -0,0 +1,180 @@
|
||||
http:
|
||||
pprof:
|
||||
port: 6060
|
||||
enabled: false
|
||||
address: 0.0.0.0:3000
|
||||
session_ttl: 720h
|
||||
users:
|
||||
- name: admin
|
||||
password: $2y$10$.ujnc.Bphsaz4Z.SbOoMiux2z8DxpJUaIrD5gcITed.vKx.qrZSfC
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: ""
|
||||
theme: auto
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 5333
|
||||
anonymize_client_ip: false
|
||||
ratelimit: 20
|
||||
ratelimit_subnet_len_ipv4: 24
|
||||
ratelimit_subnet_len_ipv6: 56
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: true
|
||||
upstream_dns:
|
||||
- https://dns10.quad9.net/dns-query
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 9.9.9.10
|
||||
- 149.112.112.10
|
||||
- 2620:fe::10
|
||||
- 2620:fe::fe:10
|
||||
fallback_dns: []
|
||||
upstream_mode: parallel
|
||||
fastest_timeout: 1s
|
||||
allowed_clients: []
|
||||
disallowed_clients: []
|
||||
blocked_hosts:
|
||||
- version.bind
|
||||
- id.server
|
||||
- hostname.bind
|
||||
trusted_proxies:
|
||||
- 127.0.0.0/8
|
||||
- ::1/128
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: false
|
||||
bogus_nxdomain: []
|
||||
aaaa_disabled: false
|
||||
enable_dnssec: false
|
||||
edns_client_subnet:
|
||||
custom_ip: ""
|
||||
enabled: false
|
||||
use_custom: false
|
||||
max_goroutines: 300
|
||||
handle_ddr: true
|
||||
ipset: []
|
||||
ipset_file: ""
|
||||
bootstrap_prefer_ipv6: false
|
||||
upstream_timeout: 10s
|
||||
private_networks: []
|
||||
use_private_ptr_resolvers: true
|
||||
local_ptr_upstreams: []
|
||||
use_dns64: false
|
||||
dns64_prefixes: []
|
||||
serve_http3: false
|
||||
use_http3_upstreams: false
|
||||
serve_plain_dns: true
|
||||
hostsfile_enabled: true
|
||||
tls:
|
||||
enabled: false
|
||||
server_name: ""
|
||||
force_https: false
|
||||
port_https: 443
|
||||
port_dns_over_tls: 853
|
||||
port_dns_over_quic: 853
|
||||
port_dnscrypt: 0
|
||||
dnscrypt_config_file: ""
|
||||
allow_unencrypted_doh: false
|
||||
certificate_chain: ""
|
||||
private_key: ""
|
||||
certificate_path: ""
|
||||
private_key_path: ""
|
||||
strict_sni_check: false
|
||||
querylog:
|
||||
dir_path: ""
|
||||
ignored: []
|
||||
interval: 2160h
|
||||
size_memory: 1000
|
||||
enabled: true
|
||||
file_enabled: true
|
||||
statistics:
|
||||
dir_path: ""
|
||||
ignored: []
|
||||
interval: 24h
|
||||
enabled: true
|
||||
filters:
|
||||
- enabled: true
|
||||
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
|
||||
name: AdGuard DNS filter
|
||||
id: 1
|
||||
- enabled: false
|
||||
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
|
||||
name: AdAway Default Blocklist
|
||||
id: 2
|
||||
whitelist_filters: []
|
||||
user_rules: []
|
||||
dhcp:
|
||||
enabled: false
|
||||
interface_name: ""
|
||||
local_domain_name: lan
|
||||
dhcpv4:
|
||||
gateway_ip: ""
|
||||
subnet_mask: ""
|
||||
range_start: ""
|
||||
range_end: ""
|
||||
lease_duration: 86400
|
||||
icmp_timeout_msec: 1000
|
||||
options: []
|
||||
dhcpv6:
|
||||
range_start: ""
|
||||
lease_duration: 86400
|
||||
ra_slaac_only: false
|
||||
ra_allow_slaac: false
|
||||
filtering:
|
||||
blocking_ipv4: ""
|
||||
blocking_ipv6: ""
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: UTC
|
||||
ids: []
|
||||
protection_disabled_until: null
|
||||
safe_search:
|
||||
enabled: false
|
||||
bing: true
|
||||
duckduckgo: true
|
||||
ecosia: true
|
||||
google: true
|
||||
pixabay: true
|
||||
yandex: true
|
||||
youtube: true
|
||||
blocking_mode: default
|
||||
parental_block_host: family-block.dns.adguard.com
|
||||
safebrowsing_block_host: standard-block.dns.adguard.com
|
||||
rewrites: []
|
||||
safe_fs_patterns:
|
||||
- /tmp/lib/adguardhome/userfilters/*
|
||||
safebrowsing_cache_size: 1048576
|
||||
safesearch_cache_size: 1048576
|
||||
parental_cache_size: 1048576
|
||||
cache_time: 30
|
||||
filters_update_interval: 24
|
||||
blocked_response_ttl: 10
|
||||
filtering_enabled: true
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
protection_enabled: true
|
||||
clients:
|
||||
runtime_sources:
|
||||
whois: true
|
||||
arp: true
|
||||
rdns: true
|
||||
dhcp: true
|
||||
hosts: true
|
||||
persistent: []
|
||||
log:
|
||||
enabled: true
|
||||
file: ""
|
||||
max_backups: 0
|
||||
max_size: 100
|
||||
max_age: 3
|
||||
compress: false
|
||||
local_time: false
|
||||
verbose: false
|
||||
os:
|
||||
group: ""
|
||||
user: ""
|
||||
rlimit_nofile: 0
|
||||
schema_version: 29
|
||||
@ -1,19 +0,0 @@
|
||||
|
||||
config AdGuardHome 'AdGuardHome'
|
||||
option enabled '0'
|
||||
option httpport '3000'
|
||||
option redirect 'dnsmasq-upstream'
|
||||
option configpath '/etc/AdGuardHome.yaml'
|
||||
option workdir '/tmp/AdGuardHome'
|
||||
option logfile '/tmp/AdGuardHome.log'
|
||||
option verbose '0'
|
||||
option binpath '/usr/bin/AdGuardHome/AdGuardHome'
|
||||
option upxflag '-1'
|
||||
|
||||
option waitonboot '0'
|
||||
option update_url 'https://github.com/AdguardTeam/AdGuardHome/releases/download/${Cloud_Version}/AdGuardHome_linux_${Arch}.tar.gz'
|
||||
option ucitracktest '2'
|
||||
list old_redirect 'dnsmasq-upstream'
|
||||
list old_port '5553'
|
||||
list old_enabled '0'
|
||||
option version 'v0.107.26'
|
||||
@ -1,647 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
START=95
|
||||
STOP=01
|
||||
|
||||
ipt=$(command -v iptables-legacy || command -v iptables)
|
||||
ip6t=$(command -v ip6tables-legacy || command -v ip6tables)
|
||||
CONFIGURATION=AdGuardHome
|
||||
CRON_FILE=/etc/crontabs/root
|
||||
EXTRA_COMMANDS="do_redirect testbackup test_crontab force_reload isrunning"
|
||||
EXTRA_HELP=" do_redirect 0 or 1\
|
||||
testbackup backup or restore\
|
||||
test_crontab
|
||||
force_reload
|
||||
isrunning"
|
||||
|
||||
set_forward_dnsmasq()
|
||||
{
|
||||
local PORT="$1"
|
||||
addr="127.0.0.1#$PORT"
|
||||
OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
|
||||
echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
uci delete dhcp.@dnsmasq[0].server 2>/dev/null
|
||||
uci add_list dhcp.@dnsmasq[0].server=$addr
|
||||
for server in $OLD_SERVER; do
|
||||
if [ "$server" = "$addr" ]; then
|
||||
continue
|
||||
fi
|
||||
# uci add_list dhcp.@dnsmasq[0].server=$server
|
||||
done
|
||||
uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null
|
||||
uci set dhcp.@dnsmasq[0].noresolv=1
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
stop_forward_dnsmasq()
|
||||
{
|
||||
local OLD_PORT="$1"
|
||||
addr="127.0.0.1#$OLD_PORT"
|
||||
OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
|
||||
echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null
|
||||
addrlist="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
|
||||
if [ -z "$addrlist" ] ; then
|
||||
resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
|
||||
[ ! -f "$resolvfile" ] && resolvfile="/tmp/resolv.conf.auto"
|
||||
uci set dhcp.@dnsmasq[0].resolvfile="$resolvfile" 2>/dev/null
|
||||
uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
|
||||
fi
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
set_iptable()
|
||||
{
|
||||
local ipv6_server=$1
|
||||
local tcp_server=$2
|
||||
uci -q batch <<-EOF >/dev/null 2>&1
|
||||
delete firewall.AdGuardHome
|
||||
set firewall.AdGuardHome=include
|
||||
set firewall.AdGuardHome.type=script
|
||||
set firewall.AdGuardHome.path=/usr/share/AdGuardHome/firewall.start
|
||||
set firewall.AdGuardHome.reload=1
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
|
||||
for IP in $IPS
|
||||
do
|
||||
if [ "$tcp_server" == "1" ]; then
|
||||
$ipt -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
|
||||
fi
|
||||
$ipt -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
|
||||
done
|
||||
|
||||
if [ "$ipv6_server" == 0 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
|
||||
for IP in $IPS
|
||||
do
|
||||
if [ "$tcp_server" == "1" ]; then
|
||||
$ipt -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
|
||||
fi
|
||||
$ipt -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
|
||||
clear_iptable()
|
||||
{
|
||||
uci -q batch <<-EOF >/dev/null 2>&1
|
||||
delete firewall.AdGuardHome
|
||||
commit firewall
|
||||
EOF
|
||||
local OLD_PORT="$1"
|
||||
local ipv6_server=$2
|
||||
IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
|
||||
for IP in $IPS
|
||||
do
|
||||
$ipt -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
|
||||
$ipt -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
|
||||
done
|
||||
|
||||
if [ "$ipv6_server" == 0 ]; then
|
||||
return
|
||||
fi
|
||||
echo "warn ip6tables nat mod is needed"
|
||||
IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
|
||||
for IP in $IPS
|
||||
do
|
||||
$ipt -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
|
||||
$ipt -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "$CONFIGURATION"
|
||||
[ "$(uci get AdGuardHome.AdGuardHome.redirect)" == "redirect" ] && procd_add_reload_trigger firewall
|
||||
}
|
||||
|
||||
isrunning(){
|
||||
config_load "${CONFIGURATION}"
|
||||
_isrunning
|
||||
local r=$?
|
||||
([ "$r" == "0" ] && echo "running") || ([ "$r" == "1" ] && echo "not run" ) || echo "no bin"
|
||||
return $r
|
||||
}
|
||||
|
||||
_isrunning(){
|
||||
config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
[ ! -f "$binpath" ] && return 2
|
||||
pgrep $binpath 2>&1 >/dev/null && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
force_reload(){
|
||||
config_load "${CONFIGURATION}"
|
||||
_isrunning && procd_send_signal "$CONFIGURATION" || start
|
||||
}
|
||||
|
||||
get_tz()
|
||||
{
|
||||
SET_TZ=""
|
||||
|
||||
if [ -e "/etc/localtime" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
for tzfile in /etc/TZ /var/etc/TZ
|
||||
do
|
||||
if [ ! -e "$tzfile" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
tz="`cat $tzfile 2>/dev/null`"
|
||||
done
|
||||
|
||||
if [ -z "$tz" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
SET_TZ=$tz
|
||||
}
|
||||
|
||||
rm_port53()
|
||||
{
|
||||
local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
|
||||
dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
|
||||
if [ -z "$dnsmasq_port" ]; then
|
||||
dnsmasq_port="53"
|
||||
fi
|
||||
if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then
|
||||
if [ "$dnsmasq_port" == "53" ]; then
|
||||
dnsmasq_port="1745"
|
||||
fi
|
||||
elif [ "$dnsmasq_port" == "53" ]; then
|
||||
return
|
||||
fi
|
||||
config_editor "dns.port" "$dnsmasq_port" "$configpath"
|
||||
uci set dhcp.@dnsmasq[0].port="53"
|
||||
uci commit dhcp
|
||||
config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
killall -9 $binpath
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
use_port53()
|
||||
{
|
||||
local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
|
||||
dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
|
||||
if [ -z "$dnsmasq_port" ]; then
|
||||
dnsmasq_port="53"
|
||||
fi
|
||||
if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then
|
||||
if [ "$dnsmasq_port" == "53" ]; then
|
||||
AdGuardHome_PORT="1745"
|
||||
fi
|
||||
elif [ "$AdGuardHome_PORT" == "53" ]; then
|
||||
return
|
||||
fi
|
||||
config_editor "dns.port" "53" "$configpath"
|
||||
uci set dhcp.@dnsmasq[0].port="$AdGuardHome_PORT"
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
do_redirect()
|
||||
{
|
||||
config_load "${CONFIGURATION}"
|
||||
_do_redirect $1
|
||||
}
|
||||
|
||||
_do_redirect()
|
||||
{
|
||||
local section="$CONFIGURATION"
|
||||
args=""
|
||||
ipv6_server=1
|
||||
tcp_server=0
|
||||
enabled=$1
|
||||
if [ "$enabled" == "1" ]; then
|
||||
echo -n "1">/var/run/AdGredir
|
||||
else
|
||||
echo -n "0">/var/run/AdGredir
|
||||
fi
|
||||
config_get configpath $CONFIGURATION configpath "/etc/AdGuardHome.yaml"
|
||||
AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1")
|
||||
if [ ! -s "$configpath" ]; then
|
||||
cp -f /usr/share/AdGuardHome/AdGuardHome_template.yaml $configpath
|
||||
fi
|
||||
if [ -z "$AdGuardHome_PORT" ]; then
|
||||
AdGuardHome_PORT="0"
|
||||
fi
|
||||
config_get "redirect" "$section" "redirect" "none"
|
||||
config_get "old_redirect" "$section" "old_redirect" "none"
|
||||
config_get "old_port" "$section" "old_port" "0"
|
||||
config_get "old_enabled" "$section" "old_enabled" "0"
|
||||
uci get dhcp.@dnsmasq[0].port >/dev/null 2>&1 || uci set dhcp.@dnsmasq[0].port="53" >/dev/null 2>&1
|
||||
uci commit dhcp
|
||||
if [ "$old_enabled" = "1" -a "$old_redirect" == "exchange" ]; then
|
||||
AdGuardHome_PORT=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$AdGuardHome_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then
|
||||
if [ "$old_redirect" != "none" ]; then
|
||||
if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then
|
||||
clear_iptable "$old_port" "$ipv6_server"
|
||||
elif [ "$old_redirect" == "dnsmasq-upstream" ]; then
|
||||
stop_forward_dnsmasq "$old_port"
|
||||
elif [ "$old_redirect" == "exchange" ]; then
|
||||
rm_port53
|
||||
fi
|
||||
fi
|
||||
elif [ "$old_enabled" = "1" -a "$enabled" = "1" ]; then
|
||||
if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then
|
||||
clear_iptable "$old_port" "$ipv6_server"
|
||||
fi
|
||||
fi
|
||||
uci delete AdGuardHome.@AdGuardHome[0].old_redirect 2>/dev/null
|
||||
uci delete AdGuardHome.@AdGuardHome[0].old_port 2>/dev/null
|
||||
uci delete AdGuardHome.@AdGuardHome[0].old_enabled 2>/dev/null
|
||||
uci add_list AdGuardHome.@AdGuardHome[0].old_redirect="$redirect" 2>/dev/null
|
||||
uci add_list AdGuardHome.@AdGuardHome[0].old_port="$AdGuardHome_PORT" 2>/dev/null
|
||||
uci add_list AdGuardHome.@AdGuardHome[0].old_enabled="$enabled" 2>/dev/null
|
||||
uci commit AdGuardHome
|
||||
[ "$enabled" == "0" ] && return 1
|
||||
if [ "$AdGuardHome_PORT" == "0" ]; then
|
||||
return 1
|
||||
fi
|
||||
if [ "$redirect" = "redirect" ]; then
|
||||
set_iptable $ipv6_server $tcp_server
|
||||
elif [ "$redirect" = "dnsmasq-upstream" ]; then
|
||||
set_forward_dnsmasq "$AdGuardHome_PORT"
|
||||
elif [ "$redirect" == "exchange" -a "$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)" == "53" ]; then
|
||||
use_port53
|
||||
fi
|
||||
}
|
||||
|
||||
get_filesystem()
|
||||
{
|
||||
# print out path filesystem
|
||||
echo $1 | awk '
|
||||
BEGIN{
|
||||
while (("mount"| getline ret) > 0)
|
||||
{
|
||||
split(ret,d);
|
||||
fs[d[3]]=d[5];
|
||||
m=index(d[1],":")
|
||||
if (m==0)
|
||||
{
|
||||
pt[d[3]]=d[1]
|
||||
}else{
|
||||
pt[d[3]]=substr(d[1],m+1)
|
||||
}}}{
|
||||
split($0,d,"/");
|
||||
if ("/" in fs)
|
||||
{
|
||||
result1=fs["/"];
|
||||
}
|
||||
if ("/" in pt)
|
||||
{
|
||||
result2=pt["/"];
|
||||
}
|
||||
for (i=2;i<=length(d);i++)
|
||||
{
|
||||
p[i]=p[i-1]"/"d[i];
|
||||
if (p[i] in fs)
|
||||
{
|
||||
result1=fs[p[i]];
|
||||
result2=pt[p[i]];
|
||||
}
|
||||
}
|
||||
if (result2 in fs){
|
||||
result=fs[result2]}
|
||||
else{
|
||||
result=result1}
|
||||
print(result);}'
|
||||
}
|
||||
|
||||
config_editor()
|
||||
{
|
||||
awk -v yaml="$1" -v value="$2" -v file="$3" -v ro="$4" '
|
||||
BEGIN{split(yaml,part,"\.");s="";i=1;l=length(part);}
|
||||
{
|
||||
if (match($0,s""part[i]":"))
|
||||
{
|
||||
if (i==l)
|
||||
{
|
||||
split($0,t,": ");
|
||||
if (ro==""){
|
||||
system("sed -i '\''"FNR"c \\"t[1]": "value"'\'' "file);
|
||||
}else{
|
||||
print(t[2]);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
s=s"[- ]{2}";
|
||||
i++;
|
||||
}
|
||||
}' $3
|
||||
}
|
||||
|
||||
boot_service() {
|
||||
rm /var/run/AdGserverdis >/dev/null 2>&1
|
||||
config_load "${CONFIGURATION}"
|
||||
config_get waitonboot $CONFIGURATION waitonboot "0"
|
||||
config_get_bool enabled $CONFIGURATION enabled 0
|
||||
config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
[ -f "$binpath" ] && start_service
|
||||
if [ "$enabled" == "1" ] && [ "$waitonboot" == "1" ]; then
|
||||
procd_open_instance "waitnet"
|
||||
procd_set_param command "/usr/share/AdGuardHome/waitnet.sh"
|
||||
procd_close_instance
|
||||
echo "no net start pinging"
|
||||
fi
|
||||
}
|
||||
|
||||
testbackup(){
|
||||
config_load "${CONFIGURATION}"
|
||||
if [ "$1" == "backup" ]; then
|
||||
backup
|
||||
elif [ "$1" == "restore" ]; then
|
||||
restore
|
||||
fi
|
||||
}
|
||||
|
||||
restore()
|
||||
{
|
||||
config_get workdir $CONFIGURATION workdir "/usr/bin/AdGuardHome"
|
||||
config_get backupwdpath $CONFIGURATION backupwdpath "/usr/bin/AdGuardHome"
|
||||
cp -u -r -f $backupwdpath/data $workdir
|
||||
}
|
||||
|
||||
backup() {
|
||||
config_get backupwdpath $CONFIGURATION backupwdpath "/usr/bin/AdGuardHome"
|
||||
mkdir -p $backupwdpath/data
|
||||
config_get workdir $CONFIGURATION workdir "/usr/bin/AdGuardHome"
|
||||
config_get backupfile $CONFIGURATION backupfile ""
|
||||
for one in $backupfile;
|
||||
do
|
||||
while :
|
||||
do
|
||||
if [ -d "$backupwdpath/data/$one" ]; then
|
||||
cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data 2>&1)
|
||||
else
|
||||
cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data/$one 2>&1)
|
||||
fi
|
||||
echo "$cpret"
|
||||
echo "$cpret" | grep "no space left on device"
|
||||
if [ "$?" == "0" ]; then
|
||||
echo "磁盘已满,删除log重试中"
|
||||
del_querylog && continue
|
||||
rm -f -r $backupwdpath/data/filters
|
||||
rm -f -r $workdir/data/filters && continue
|
||||
echo "backup failed"
|
||||
fi
|
||||
break
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
start_service() {
|
||||
# Reading config
|
||||
rm /var/run/AdGserverdis >/dev/null 2>&1
|
||||
config_load "${CONFIGURATION}"
|
||||
# update password
|
||||
config_get hashpass $CONFIGURATION hashpass ""
|
||||
config_get configpath $CONFIGURATION configpath "/etc/AdGuardHome.yaml"
|
||||
if [ -n "$hashpass" ]; then
|
||||
config_editor "users.password" "$hashpass" "$configpath"
|
||||
uci set $CONFIGURATION.$CONFIGURATION.hashpass=""
|
||||
fi
|
||||
local enabled
|
||||
config_get_bool enabled $CONFIGURATION enabled 0
|
||||
# update crontab
|
||||
do_crontab
|
||||
if [ "$enabled" == "0" ]; then
|
||||
_do_redirect 0
|
||||
return
|
||||
fi
|
||||
#what need to do before reload
|
||||
config_get workdir $CONFIGURATION workdir "/usr/bin/AdGuardHome"
|
||||
|
||||
config_get backupfile $CONFIGURATION backupfile ""
|
||||
mkdir -p $workdir/data
|
||||
if [ -n "$backupfile" ] && [ ! -d "$workdir/data" ]; then
|
||||
restore
|
||||
fi
|
||||
# for overlay data-stk-oo not suppport
|
||||
local cwdfs=$(get_filesystem $workdir)
|
||||
echo "workdir is a $cwdfs filesystem"
|
||||
if [ "$cwdfs" == "jffs2" ]; then
|
||||
echo "fs error ln db to tmp $workdir $cwdfs"
|
||||
logger "AdGuardHome" "warning db redirect to tmp"
|
||||
touch $workdir/data/stats.db
|
||||
if [ ! -L $workdir/data/stats.db ]; then
|
||||
mv -f $workdir/data/stats.db /tmp/stats.db 2>/dev/null
|
||||
ln -s /tmp/stats.db $workdir/data/stats.db 2>/dev/null
|
||||
fi
|
||||
touch $workdir/data/sessions.db
|
||||
if [ ! -L $workdir/data/sessions.db ]; then
|
||||
mv -f $workdir/data/sessions.db /tmp/sessions.db 2>/dev/null
|
||||
ln -s /tmp/sessions.db $workdir/data/sessions.db 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
local ADDITIONAL_ARGS=""
|
||||
config_get binpath $CONFIGURATION binpath "/usr/bin/AdGuardHome/AdGuardHome"
|
||||
|
||||
mkdir -p ${binpath%/*}
|
||||
ADDITIONAL_ARGS="$ADDITIONAL_ARGS -c $configpath"
|
||||
ADDITIONAL_ARGS="$ADDITIONAL_ARGS -w $workdir"
|
||||
config_get httpport $CONFIGURATION httpport 3000
|
||||
ADDITIONAL_ARGS="$ADDITIONAL_ARGS -p $httpport"
|
||||
|
||||
# hack to save config file when upgrade system
|
||||
config_get upprotect $CONFIGURATION upprotect ""
|
||||
eval upprotect=${upprotect// /\\\\n}
|
||||
echo -e "$upprotect">/lib/upgrade/keep.d/luci-app-adguardhome
|
||||
|
||||
config_get logfile $CONFIGURATION logfile ""
|
||||
if [ -n "$logfile" ]; then
|
||||
ADDITIONAL_ARGS="$ADDITIONAL_ARGS -l $logfile"
|
||||
fi
|
||||
|
||||
if [ ! -f "$binpath" ]; then
|
||||
_do_redirect 0
|
||||
/usr/share/AdGuardHome/update_core.sh 2>&1 >/tmp/AdGuardHome_update.log &
|
||||
exit 0
|
||||
fi
|
||||
|
||||
config_get_bool verbose $CONFIGURATION verbose 0
|
||||
if [ "$verbose" -eq 1 ]; then
|
||||
ADDITIONAL_ARGS="$ADDITIONAL_ARGS -v"
|
||||
fi
|
||||
|
||||
procd_open_instance
|
||||
get_tz
|
||||
if [ -n "$SET_TZ" ]; then
|
||||
procd_set_param env TZ="$SET_TZ"
|
||||
fi
|
||||
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
||||
procd_set_param limits core="unlimited" nofile="65535 65535"
|
||||
procd_set_param stderr 1
|
||||
procd_set_param command $binpath $ADDITIONAL_ARGS
|
||||
procd_set_param file "$configpath" "/etc/hosts" "/etc/config/AdGuardHome"
|
||||
procd_close_instance
|
||||
if [ -f "$configpath" ]; then
|
||||
_do_redirect 1
|
||||
else
|
||||
_do_redirect 0
|
||||
config_get "redirect" "AdGuardHome" "redirect" "none"
|
||||
if [ "$redirect" != "none" ]; then
|
||||
procd_open_instance "waitconfig"
|
||||
procd_set_param command "/usr/share/AdGuardHome/watchconfig.sh"
|
||||
procd_close_instance
|
||||
echo "no config start watching"
|
||||
fi
|
||||
fi
|
||||
echo "AdGuardHome service enabled"
|
||||
echo "luci enable switch=$enabled"
|
||||
(sleep 10 && [ -z "$(pgrep $binpath)" ] && logger "AdGuardHome" "no process in 10s cancel redirect" && _do_redirect 0 )&
|
||||
if [[ "`uci get bypass.@global[0].global_server 2>/dev/null`" && "`uci get bypass.@global[0].adguardhome 2>/dev/null`" == 1 && "$(uci get dhcp.@dnsmasq[0].port)" == "53" ]]; then
|
||||
uci -q set AdGuardHome.AdGuardHome.redirect='exchange'
|
||||
uci commit AdGuardHome
|
||||
do_redirect 1
|
||||
fi
|
||||
}
|
||||
|
||||
reload_service()
|
||||
{
|
||||
rm /var/run/AdGlucitest >/dev/null 2>&1
|
||||
echo "AdGuardHome reloading"
|
||||
start
|
||||
}
|
||||
|
||||
del_querylog(){
|
||||
local btarget=$(ls $backupwdpath/data | grep -F "querylog.json" | sort -r | head -n 1)
|
||||
local wtarget=$(ls $workdir/data | grep -F "querylog.json" | sort -r | head -n 1)
|
||||
if [ "$btarget"x == "$wtarget"x ]; then
|
||||
[ -z "$btarget" ] && return 1
|
||||
rm -f $workdir/data/$wtarget
|
||||
rm -f $backupwdpath/data/$btarget
|
||||
return 0
|
||||
fi
|
||||
if [ "$btarget" \> "$wtarget" ]; then
|
||||
rm -f $backupwdpath/data/$btarget
|
||||
return 0
|
||||
else
|
||||
rm -f $workdir/data/$wtarget
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service()
|
||||
{
|
||||
config_load "${CONFIGURATION}"
|
||||
_do_redirect 0
|
||||
do_crontab
|
||||
if [ "$1" != "nobackup" ]; then
|
||||
config_get backupfile $CONFIGURATION backupfile "0"
|
||||
if [ -n "$backupfile" ]; then
|
||||
backup
|
||||
fi
|
||||
fi
|
||||
echo "AdGuardHome service disabled"
|
||||
touch /var/run/AdGserverdis
|
||||
}
|
||||
|
||||
boot() {
|
||||
rc_procd boot_service "$@"
|
||||
if eval "type service_started" 2>/dev/null >/dev/null; then
|
||||
service_started
|
||||
fi
|
||||
}
|
||||
|
||||
test_crontab(){
|
||||
config_load "${CONFIGURATION}"
|
||||
do_crontab
|
||||
}
|
||||
|
||||
do_crontab(){
|
||||
config_get_bool enabled $CONFIGURATION enabled 0
|
||||
config_get crontab $CONFIGURATION crontab ""
|
||||
local findstr default cronenable replace commit
|
||||
local cronreload=0
|
||||
local commit=0
|
||||
findstr="/usr/share/AdGuardHome/update_core.sh"
|
||||
default="30 3 * * * /usr/share/AdGuardHome/update_core.sh 2>&1"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//autoupdate/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
|
||||
config_get workdir $CONFIGURATION workdir "/usr/bin/AdGuardHome"
|
||||
config_get lastworkdir $CONFIGURATION lastworkdir "/usr/bin/AdGuardHome"
|
||||
findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json"
|
||||
#[ -n "$lastworkdir" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastworkdir/data/querylog.json" && [ "$lastworkdir" != "$workdir" ] && replace="${lastworkdir//\//\\/}/${workdir//\//\\/}"
|
||||
default="0 * * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//cutquerylog/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
#[ "$lastworkdir" != "$workdir" ] && uci set AdGuardHome.AdGuardHome.lastworkdir="$workdir" && commit=1
|
||||
|
||||
config_get logfile $CONFIGURATION logfile ""
|
||||
config_get lastlogfile $CONFIGURATION lastlogfile ""
|
||||
findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.logfile)"
|
||||
default="30 3 * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.logfile)"
|
||||
#[ -n "$lastlogfile" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastlogfile" && [ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && replace="${lastlogfile//\//\\/}/${logfile//\//\\/}"
|
||||
[ "$logfile" == "syslog" ] || [ "$logfile" == "" ] || [ "$enabled" == "0" ] || [ "${crontab//cutruntimelog/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
#[ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && uci set AdGuardHome.AdGuardHome.lastlogfile="$logfile" && commit=1
|
||||
|
||||
findstr="/usr/share/AdGuardHome/addhost.sh"
|
||||
default="0 * * * * /usr/share/AdGuardHome/addhost.sh"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//autohost/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
[ "$cronenable" == "0" ] && /usr/share/AdGuardHome/addhost.sh "del" "noreload" || /usr/share/AdGuardHome/addhost.sh "" "noreload"
|
||||
|
||||
findstr="/usr/share/AdGuardHome/gfw2adg.sh"
|
||||
default="30 3 * * * /usr/share/AdGuardHome/gfw2adg.sh"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//autogfw/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
[ "$cronreload" -gt 0 ] && /etc/init.d/cron restart
|
||||
#[ "$commit" -gt 0 ] && uci commit AdGuardHome
|
||||
}
|
||||
|
||||
crontab_editor(){
|
||||
#usage input:
|
||||
#findstr=
|
||||
#default=
|
||||
#cronenable=
|
||||
#replace="${last//\//\\/}/${now//\//\\/}"
|
||||
#output:cronreload:if >1 please /etc/init.d/cron restart manual
|
||||
local testline reload
|
||||
local line="$(grep "$findstr" $CRON_FILE)"
|
||||
[ -n "$replace" ] && [ -n "$line" ] && eval testline="\${line//$replace}" && [ "$testline" != "$line" ] && line="$testline" && reload="1" && replace=""
|
||||
if [ "${line:0:1}" != "#" ]; then
|
||||
if [ $cronenable -eq 1 ]; then
|
||||
[ -z "$line" ] && line="$default" && reload="1"
|
||||
if [ -n "$reload" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "$line" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
fi
|
||||
elif [ -n "$line" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "#$line" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
fi
|
||||
else
|
||||
if [ $cronenable -eq 1 ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "${line:1}" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
elif [ -z "$reload" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "$line" >> $CRON_FILE
|
||||
fi
|
||||
fi
|
||||
}
|
||||
258
luci-app-adguardhome/root/etc/init.d/adguardhome
Executable file
258
luci-app-adguardhome/root/etc/init.d/adguardhome
Executable file
@ -0,0 +1,258 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
# Start after network (19 matches dnsmasq)
|
||||
START=19
|
||||
# Stop before network stops
|
||||
STOP=89
|
||||
|
||||
PROG=/usr/bin/AdGuardHome
|
||||
USE_PROCD=1
|
||||
|
||||
boot() {
|
||||
ADGUARDHOME_BOOT=1
|
||||
start "$@"
|
||||
}
|
||||
|
||||
# Configure DNS to use port 53
|
||||
use_port53() {
|
||||
local dns_port="$1"
|
||||
local adguard_port="$2"
|
||||
local config_file="$3"
|
||||
|
||||
[ "$dns_port" != "53" ] && return
|
||||
|
||||
# Update AdGuardHome config
|
||||
sed -i '/dns:/,/^[^ ]/{ /[[:space:]]*port:/ s/port:[[:space:]]*[0-9]\+/port: 53/ }' "$config_file"
|
||||
|
||||
# Update dnsmasq config
|
||||
uci set "dhcp.@dnsmasq[0].port=$adguard_port"
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
# Restore original port configuration
|
||||
rm_port53() {
|
||||
local current_port="$1"
|
||||
local new_port="$2"
|
||||
local config_file="$3"
|
||||
|
||||
[ "$current_port" != "53" ] && return
|
||||
|
||||
# Update AdGuardHome config
|
||||
sed -i '/dns:/,/^[^ ]/{ /[[:space:]]*port:/ s/port:[[:space:]]*[0-9]\+/port: '"$new_port"'/ }' "$config_file"
|
||||
|
||||
# Restore dnsmasq config
|
||||
uci -q set "dhcp.@dnsmasq[0].port=53"
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
# Set up firewall redirect rules
|
||||
set_redirect() {
|
||||
local dest_port="$1"
|
||||
local section
|
||||
|
||||
# Add new redirect section
|
||||
section=$(uci add firewall redirect)
|
||||
[ -z "$section" ] && return
|
||||
[ "$(uci -q get "firewall.$section.dest_port")" = "$dest_port" ] && return
|
||||
|
||||
# Configure redirect rules
|
||||
uci -q set "firewall.$section.target=DNAT"
|
||||
uci -q set "firewall.$section.name=AdGuard Home"
|
||||
uci -q set "firewall.$section.src=lan"
|
||||
uci -q set "firewall.$section.src_dport=53"
|
||||
uci -q set "firewall.$section.dest_port=$dest_port"
|
||||
|
||||
# Apply changes
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload
|
||||
echo "Firewall rules updated."
|
||||
}
|
||||
|
||||
# Clear all AdGuard Home redirect rules
|
||||
clear_redirect() {
|
||||
local redirects
|
||||
redirects=$(uci show firewall | grep "AdGuard Home" | cut -d'.' -f1-2)
|
||||
[ -z "$redirects" ] && return
|
||||
|
||||
for redirect in $redirects; do
|
||||
uci -q delete "$redirect"
|
||||
echo "Deleted redirect rule: $redirect"
|
||||
done
|
||||
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall reload
|
||||
echo "Firewall rules updated."
|
||||
}
|
||||
|
||||
# Configure dnsmasq to forward requests to AdGuard Home
|
||||
set_forward_dnsmasq() {
|
||||
local port="$1"
|
||||
local current_server="$2"
|
||||
local addr="127.0.0.1#$port"
|
||||
|
||||
echo "$current_server" | grep -q "^$addr" && return
|
||||
|
||||
uci -q add_list dhcp.@dnsmasq[0].server="$addr"
|
||||
uci -q delete "dhcp.@dnsmasq[0].resolvfile"
|
||||
uci set "dhcp.@dnsmasq[0].noresolv=1"
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
# Stop forwarding requests to AdGuard Home
|
||||
stop_forward_dnsmasq() {
|
||||
local port="$1"
|
||||
local current_server="$2"
|
||||
local addr="127.0.0.1#$port"
|
||||
|
||||
echo "$current_server" | grep -q "^$addr" || return
|
||||
|
||||
uci -q delete "dhcp.@dnsmasq[0].server"
|
||||
uci -q delete "dhcp.@dnsmasq[0].noresolv"
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq restart
|
||||
}
|
||||
|
||||
# Start AdGuard Home service
|
||||
start_service() {
|
||||
if [ -n "$ADGUARDHOME_BOOT" ]; then
|
||||
# Do not start yet, wait for triggers
|
||||
return 0
|
||||
fi
|
||||
|
||||
config_load 'adguardhome'
|
||||
|
||||
local config_name='config'
|
||||
local config_file config group user verbose work_dir workdir
|
||||
local gc maxprocs memlimit redirect enabled
|
||||
|
||||
uci_validate_section 'adguardhome' 'adguardhome' "$config_name" \
|
||||
'enabled:bool:0' \
|
||||
'redirect:string:none' \
|
||||
'gc:uinteger:0' \
|
||||
'group:string:adguardhome' \
|
||||
'config:string' \
|
||||
'config_file:string:/etc/adguardhome/adguardhome.yaml' \
|
||||
'jail_mount:list(string)' \
|
||||
'jail_mount_rw:list(string)' \
|
||||
'maxprocs:uinteger:0' \
|
||||
'memlimit:uinteger:0' \
|
||||
'user:string:adguardhome' \
|
||||
'verbose:bool:0' \
|
||||
'workdir:string' \
|
||||
'work_dir:string:/var/lib/adguardhome'
|
||||
|
||||
# Compatibility with older configs
|
||||
[ -n "$config" ] && config_file="$config"
|
||||
[ -n "$workdir" ] && work_dir="$workdir"
|
||||
|
||||
[ "$enabled" -eq 0 ] && return 1
|
||||
|
||||
local config_dir
|
||||
config_dir=$(dirname "$config_file")
|
||||
if [ "$config_dir" = '/etc' ]; then
|
||||
echo 'AdGuard Home config must be stored in its own directory, and not in /etc' >&2
|
||||
return 1
|
||||
fi
|
||||
mkdir -m 0700 -p "$config_dir"
|
||||
chown -R "$user":"$group" "$config_dir"
|
||||
|
||||
mkdir -m 0700 -p "$work_dir"
|
||||
chown -R "$user":"$group" "$work_dir"
|
||||
|
||||
# Get ports configuration
|
||||
local AdGuardHome_PORT=$(awk '/dns:/{f=1} f&&/port:/{split($0,a,": *");print a[2];exit}' "$config_file")
|
||||
local dnsmasq_port=$(uci -q get dhcp.@dnsmasq[0].port)
|
||||
local DNSMASQ_SERVER=$(uci -q get dhcp.@dnsmasq[0].server)
|
||||
|
||||
# Configure redirect mode
|
||||
case "$redirect" in
|
||||
"redirect")
|
||||
set_redirect "$AdGuardHome_PORT"
|
||||
;;
|
||||
"dnsmasq-upstream")
|
||||
set_forward_dnsmasq "$AdGuardHome_PORT" "$DNSMASQ_SERVER"
|
||||
;;
|
||||
"exchange")
|
||||
use_port53 "$dnsmasq_port" "$AdGuardHome_PORT" "$config_file"
|
||||
;;
|
||||
esac
|
||||
|
||||
procd_open_instance adguardhome
|
||||
|
||||
procd_set_param command "$PROG"
|
||||
|
||||
[ "$gc" -le 0 ] || procd_append_param env GOGC="$gc"
|
||||
[ "$maxprocs" -le 0 ] || procd_append_param env GOMAXPROCS="$maxprocs"
|
||||
[ "$memlimit" -le 0 ] || procd_append_param env GOMEMLIMIT="$memlimit"
|
||||
|
||||
procd_append_param command --config "$config_file"
|
||||
procd_append_param command --logfile syslog
|
||||
procd_append_param command --no-check-update
|
||||
[ "$verbose" = 1 ] && procd_append_param command --verbose
|
||||
procd_append_param command --work-dir "$work_dir"
|
||||
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param user "$user"
|
||||
procd_set_param group "$group"
|
||||
procd_set_param capabilities '/etc/capabilities/adguardhome.json'
|
||||
procd_set_param no_new_privs 1
|
||||
procd_set_param respawn
|
||||
|
||||
# log is needed for logging to syslog instead of stdout
|
||||
# procfs is needed to readlink /proc/self/exe
|
||||
procd_add_jail adguardhome log procfs
|
||||
|
||||
# config directory must be writable to write new config files
|
||||
procd_add_jail_mount_rw "$config_dir"
|
||||
procd_add_jail_mount_rw "$work_dir"
|
||||
|
||||
procd_add_jail_mount '/etc/hosts'
|
||||
procd_add_jail_mount '/etc/ssl/certs'
|
||||
config_list_foreach "$config_name" jail_mount procd_add_jail_mount
|
||||
config_list_foreach "$config_name" jail_mount_rw procd_add_jail_mount_rw
|
||||
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
# Stop AdGuard Home service
|
||||
stop_service() {
|
||||
if [ -n "$ADGUARDHOME_BOOT" ]; then
|
||||
# Do not start yet, wait for triggers
|
||||
return 0
|
||||
fi
|
||||
|
||||
local config_file='/etc/adguardhome/adguardhome.yaml'
|
||||
|
||||
config_load 'adguardhome'
|
||||
|
||||
# Get ports configuration
|
||||
local AdGuardHome_PORT=$(awk '/dns:/{f=1} f&&/port:/{split($0,a,": *");print a[2];exit}' "$config_file")
|
||||
local dnsmasq_port=$(uci -q get dhcp.@dnsmasq[0].port)
|
||||
local DNSMASQ_SERVER=$(uci -q get dhcp.@dnsmasq[0].server)
|
||||
|
||||
# Clean up configurations
|
||||
rm_port53 "$AdGuardHome_PORT" "$dnsmasq_port" "$config_file"
|
||||
clear_redirect
|
||||
stop_forward_dnsmasq "$AdGuardHome_PORT" "$DNSMASQ_SERVER"
|
||||
}
|
||||
|
||||
# Reload service
|
||||
reload_service() {
|
||||
restart
|
||||
}
|
||||
|
||||
# Service triggers
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger adguardhome
|
||||
|
||||
# Add interface trigger during boot
|
||||
if [ -n "$ADGUARDHOME_BOOT" ]; then
|
||||
# Wait for interfaces to be up before starting AdGuard Home
|
||||
# Prevents issues like https://github.com/openwrt/packages/issues/21868
|
||||
procd_add_raw_trigger 'interface.*.up' 5000 /etc/init.d/adguardhome restart
|
||||
fi
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-AdGuardHome.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-AdGuardHome.json << EEOF
|
||||
{
|
||||
"config": "AdGuardHome",
|
||||
"init": "AdGuardHome"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
chmod +x /etc/init.d/AdGuardHome
|
||||
uci -q batch <<-EOF >/dev/null 2>&1
|
||||
delete ucitrack.@AdGuardHome[-1]
|
||||
add ucitrack AdGuardHome
|
||||
set ucitrack.@AdGuardHome[-1].init=AdGuardHome
|
||||
commit ucitrack
|
||||
delete AdGuardHome.AdGuardHome.ucitracktest
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
153
luci-app-adguardhome/root/usr/libexec/rpcd/luci.adguardhome
Executable file
153
luci-app-adguardhome/root/usr/libexec/rpcd/luci.adguardhome
Executable file
@ -0,0 +1,153 @@
|
||||
#!/bin/sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
############################################################################################
|
||||
# Functions to parse AdGuardHome YAML file:
|
||||
############################################################################################
|
||||
parse_yaml() {
|
||||
local prefix=$2
|
||||
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
|
||||
sed -ne "s|,$s\]$s\$|]|" \
|
||||
-e ":1;s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s,$s\(.*\)$s\]|\1\2: [\3]\n\1 - \4|;t1" \
|
||||
-e "s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s\]|\1\2:\n\1 - \3|;p" $1 | \
|
||||
sed -ne "s|,$s}$s\$|}|" \
|
||||
-e ":1;s|^\($s\)-$s{$s\(.*\)$s,$s\($w\)$s:$s\(.*\)$s}|\1- {\2}\n\1 \3: \4|;t1" \
|
||||
-e "s|^\($s\)-$s{$s\(.*\)$s}|\1-\n\1 \2|;p" | \
|
||||
sed -ne "s|^\($s\):|\1|" \
|
||||
-e "s|^\($s\)-$s[\"']\(.*\)[\"']$s\$|\1$fs$fs\2|p" \
|
||||
-e "s|^\($s\)-$s\(.*\)$s\$|\1$fs$fs\2|p" \
|
||||
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
|
||||
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" | \
|
||||
awk -F$fs '{
|
||||
indent = length($1)/2;
|
||||
vname[indent] = $2;
|
||||
for (i in vname) {if (i > indent) {delete vname[i]; idx[i]=0}}
|
||||
if(length($2)== 0){ vname[indent]= ++idx[indent] };
|
||||
if (length($3) > 0) {
|
||||
vn=""; for (i=0; i<indent; i++) { vn=(vn)(vname[i])("_")}
|
||||
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, vname[indent], $3);
|
||||
}
|
||||
}'
|
||||
}
|
||||
read_config() {
|
||||
if [ -f /etc/AdGuardHome/AdGuardHome.yaml ]; then
|
||||
parse_yaml /etc/AdGuardHome/AdGuardHome.yaml
|
||||
elif [ -f /etc/adguardhome/adguardhome.yaml ]; then
|
||||
parse_yaml /etc/adguardhome/adguardhome.yaml
|
||||
fi
|
||||
}
|
||||
|
||||
############################################################################################
|
||||
# Parse AGH yaml file and determine necessary variables in order to function:
|
||||
############################################################################################
|
||||
log_error()
|
||||
{
|
||||
logger -p err "[luci.AdGuardHome]: $@"
|
||||
}
|
||||
check_if_empty()
|
||||
{
|
||||
[[ ! -z "$2" ]] && return
|
||||
log_error $1
|
||||
echo "{\"auth_error\":\"$1\"}"
|
||||
exit 1
|
||||
}
|
||||
call_rest_api()
|
||||
{
|
||||
AGH_USER=$(uci get adguardhome.config.web_username 2> /dev/null)
|
||||
check_if_empty "Username not found in uci adguardhome" ${AGH_USER} || exit 1
|
||||
AGH_PASS=$(uci get adguardhome.config.web_password 2> /dev/null)
|
||||
check_if_empty "Password not found in uci adguardhome" ${AGH_PASS} || exit 1
|
||||
CODE=$(curl --silent -L -k -u ${AGH_USER}:${AGH_PASS} ${PROTO}://${HOST}:${PORT}/control/$1 -o $TFILE -w "%{http_code"})
|
||||
if [[ "${CODE}" == "200" ]]; then
|
||||
cat $TFILE | tr -d '\n'
|
||||
else
|
||||
MSG="REST call failed with '$(cat ${TFILE})'. Are the credentials correct?"
|
||||
log_error "$MSG"
|
||||
echo "{\"error\":\"$MSG\"}" > ${TFILE}
|
||||
fi
|
||||
}
|
||||
|
||||
############################################################################################
|
||||
# Function that groups variables starting with specified string into a single JSON object:
|
||||
############################################################################################
|
||||
group_vars() {
|
||||
local LOOK_FOR=${1/_1/}
|
||||
echo -n "\"$LOOK_FOR\":["
|
||||
cat ${TFILE} | grep "${LOOK_FOR}" | while read FOUND; do
|
||||
sed -i "/${FOUND%=*}/d" ${TFILE}
|
||||
echo "${FOUND##*=}"
|
||||
done | sed '$!s/$/,/' | tr -d '\n'
|
||||
echo -n "],"
|
||||
}
|
||||
|
||||
############################################################################################
|
||||
# Parse AGH yaml file and determine necessary variables in order to function:
|
||||
############################################################################################
|
||||
TFILE=/tmp/rpcd-adguardhome-$(date -Ins).tmp
|
||||
trap 'rm ${TFILE}; exit' EXIT
|
||||
read_config > ${TFILE}
|
||||
source ${TFILE}
|
||||
HOST=${http_address%:*}
|
||||
[[ "${HOST}" == "0.0.0.0" ]] && HOST=$(uci get system.@system[0].hostname).$(uci get dhcp.@dnsmasq[0].domain)
|
||||
HOST=$(echo ${HOST} | awk '{print tolower($0)}')
|
||||
PORT=${http_address##*:}
|
||||
PROTO="http"
|
||||
if [[ "${tls_enabled}" == "true" ]]; then
|
||||
PROTO="https"
|
||||
HOST=${tls_server_name}
|
||||
PORT=${tls_port_https}
|
||||
fi
|
||||
[[ -z "${http_address}" ]] && http_address=${bind_host}:${bind_port}
|
||||
|
||||
############################################################################################
|
||||
# Decision-making cade:
|
||||
############################################################################################
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{ "get_config": {}, "get_statistics": {}, "get_status": {}, "set_passwd": {"username":"string", "hash":"string"} }'
|
||||
;;
|
||||
call)
|
||||
case "$2" in
|
||||
get_config)
|
||||
# Start the JSON array:
|
||||
echo -n "{"
|
||||
# Group any variables starting with "dns_" together:
|
||||
grep "_1=\"" ${TFILE} | grep dns_ | while read LINE; do group_vars ${LINE%=*}; done
|
||||
# Return the AGH configuration as a JSON table:
|
||||
cat ${TFILE} | sed "s|^|\"|g" | sed "s|=\"|\":\"|g" | sed "s|\"$|\",|g" | tr -d '\n'
|
||||
# Include web url, then close the JSON array:
|
||||
echo "\"web_url\":\"${PROTO}://${HOST}:${PORT}\"}"
|
||||
;;
|
||||
|
||||
get_statistics)
|
||||
# Return the AGH statistics as a JSON table:
|
||||
call_rest_api stats
|
||||
;;
|
||||
|
||||
get_status)
|
||||
# Return the AGH status as a JSON table:
|
||||
call_rest_api status
|
||||
;;
|
||||
|
||||
set_passwd)
|
||||
# Check if bcrypt-tool is available for use:
|
||||
# Read and load the argument into JSON array:
|
||||
read input
|
||||
json_load "$input"
|
||||
# Get username and password from JSON array and verify they aren't empty:
|
||||
json_get_var AGH_USER "username"
|
||||
check_if_empty "username parameter missing." "${AGH_USER}" || exit 1
|
||||
json_get_var AGH_HASH "hash"
|
||||
check_if_empty "hash parameter missing." "${AGH_HASH}" || exit 1
|
||||
# Change the username in the AGH configuration file:
|
||||
sed -i "s|\- name: .*|\- name: ${AGH_USER} |" /etc/adguardhome/adguardhome.yaml
|
||||
# Calculate and replace password hash in the AGH configuration file:
|
||||
sed -i "s|\password: .*|\password: ${AGH_HASH}|" /etc/adguardhome/adguardhome.yaml
|
||||
# Restart AdGaurdHome:
|
||||
service adguardhome restart
|
||||
# Return success to caller:
|
||||
echo "{\"success\":true}"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@ -1,128 +0,0 @@
|
||||
bind_host: 0.0.0.0
|
||||
bind_port: 3000
|
||||
beta_bind_port: 0
|
||||
users:
|
||||
- name: admin
|
||||
password: $2y$10$vHRcARdPCieYG3RXWomV5evDYN.Nj/edtwEkQgQJZcK6z7qTLaIc6
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: zh-cn
|
||||
theme: auto
|
||||
debug_pprof: false
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 1745
|
||||
anonymize_client_ip: false
|
||||
protection_enabled: true
|
||||
blocking_mode: default
|
||||
blocking_ipv4: ""
|
||||
blocking_ipv6: ""
|
||||
blocked_response_ttl: 10
|
||||
protection_disabled_until: null
|
||||
parental_block_host: family-block.dns.adguard.com
|
||||
safebrowsing_block_host: standard-block.dns.adguard.com
|
||||
ratelimit: 0
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: false
|
||||
upstream_dns:
|
||||
- 223.5.5.5
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 119.29.29.29
|
||||
- 223.5.5.5
|
||||
all_servers: false
|
||||
fastest_addr: false
|
||||
fastest_timeout: 1s
|
||||
allowed_clients: []
|
||||
disallowed_clients: []
|
||||
blocked_hosts:
|
||||
- version.bind
|
||||
- id.server
|
||||
- hostname.bind
|
||||
trusted_proxies:
|
||||
- 127.0.0.0/8
|
||||
- ::1/128
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: true
|
||||
bogus_nxdomain: []
|
||||
aaaa_disabled: false
|
||||
enable_dnssec: false
|
||||
edns_client_subnet: false
|
||||
max_goroutines: 300
|
||||
ipset: []
|
||||
filtering_enabled: true
|
||||
filters_update_interval: 24
|
||||
parental_enabled: false
|
||||
safesearch_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
safebrowsing_cache_size: 1048576
|
||||
safesearch_cache_size: 1048576
|
||||
parental_cache_size: 1048576
|
||||
cache_time: 30
|
||||
rewrites: []
|
||||
blocked_services: []
|
||||
upstream_timeout: 10s
|
||||
private_networks: []
|
||||
use_private_ptr_resolvers: true
|
||||
local_ptr_upstreams: []
|
||||
tls:
|
||||
enabled: false
|
||||
server_name: ""
|
||||
force_https: false
|
||||
port_https: 443
|
||||
port_dns_over_tls: 853
|
||||
port_dns_over_quic: 784
|
||||
port_dnscrypt: 0
|
||||
dnscrypt_config_file: ""
|
||||
allow_unencrypted_doh: false
|
||||
certificate_chain: ""
|
||||
private_key: ""
|
||||
certificate_path: ""
|
||||
private_key_path: ""
|
||||
filters:
|
||||
- enabled: true
|
||||
url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
|
||||
name: AdGuard DNS filter
|
||||
id: 1628750870
|
||||
- enabled: true
|
||||
url: https://anti-ad.net/easylist.txt
|
||||
name: 'CHN: anti-AD'
|
||||
id: 1628750871
|
||||
whitelist_filters: []
|
||||
user_rules:
|
||||
- '@@||taobao.com^$important'
|
||||
- '@@||jd.com^important'
|
||||
- '@@||flyme.cn^$important'
|
||||
- '@@||meizu.com^$important'
|
||||
- '@@||wl.jd.com^$important'
|
||||
- '@@||flydigi.com^'
|
||||
- '@@||pv.sohu.com^$important'
|
||||
dhcp:
|
||||
enabled: false
|
||||
interface_name: ""
|
||||
dhcpv4:
|
||||
gateway_ip: ""
|
||||
subnet_mask: ""
|
||||
range_start: ""
|
||||
range_end: ""
|
||||
lease_duration: 86400
|
||||
icmp_timeout_msec: 1000
|
||||
options: []
|
||||
dhcpv6:
|
||||
range_start: ""
|
||||
lease_duration: 86400
|
||||
ra_slaac_only: false
|
||||
ra_allow_slaac: false
|
||||
clients: []
|
||||
log_compress: false
|
||||
log_localtime: false
|
||||
log_max_backups: 0
|
||||
log_max_size: 100
|
||||
log_max_age: 3
|
||||
log_file: ""
|
||||
verbose: false
|
||||
schema_version: 10
|
||||
@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
checkmd5(){
|
||||
local nowmd5=$(md5sum /etc/hosts)
|
||||
nowmd5=${nowmd5%% *}
|
||||
local lastmd5=$(uci get AdGuardHome.AdGuardHome.hostsmd5 2>/dev/null)
|
||||
if [ "$nowmd5" != "$lastmd5" ]; then
|
||||
uci set AdGuardHome.AdGuardHome.hostsmd5="$nowmd5"
|
||||
uci commit AdGuardHome
|
||||
[ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload
|
||||
fi
|
||||
}
|
||||
|
||||
[ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' /etc/hosts && checkmd5 "$2" && exit 0
|
||||
/usr/bin/awk 'BEGIN{
|
||||
while ((getline < "/tmp/dhcp.leases") > 0)
|
||||
{
|
||||
a[$2]=$4;
|
||||
}
|
||||
while (("ip -6 neighbor show | grep -v fe80" | getline) > 0)
|
||||
{
|
||||
if (a[$5]) {print $1" "a[$5] >"/tmp/tmphost"; }
|
||||
}
|
||||
print "#programaddend" >"/tmp/tmphost";
|
||||
}'
|
||||
grep programaddstart /etc/hosts >/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
sed -i '/programaddstart/,/programaddend/c\#programaddstart' /etc/hosts
|
||||
sed -i '/programaddstart/'r/tmp/tmphost /etc/hosts
|
||||
else
|
||||
echo "#programaddstart" >>/etc/hosts
|
||||
cat /tmp/tmphost >> /etc/hosts
|
||||
fi
|
||||
rm /tmp/tmphost
|
||||
checkmd5 "$2"
|
||||
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
AdGuardHome_enable=$(uci get AdGuardHome.AdGuardHome.enabled)
|
||||
redirect=$(uci get AdGuardHome.AdGuardHome.redirect)
|
||||
|
||||
if [ $AdGuardHome_enable -eq 1 -a "$redirect" == "redirect" ]; then
|
||||
/etc/init.d/AdGuardHome do_redirect 1
|
||||
fi
|
||||
@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
logread -e AdGuardHome > /tmp/AdGuardHometmp.log
|
||||
logread -e AdGuardHome -f >> /tmp/AdGuardHometmp.log &
|
||||
pid=$!
|
||||
echo "1">/var/run/AdGuardHomesyslog
|
||||
while true
|
||||
do
|
||||
sleep 12
|
||||
watchdog=$(cat /var/run/AdGuardHomesyslog)
|
||||
if [ "$watchdog"x == "0"x ]; then
|
||||
kill $pid
|
||||
rm /tmp/AdGuardHometmp.log
|
||||
rm /var/run/AdGuardHomesyslog
|
||||
exit 0
|
||||
else
|
||||
echo "0">/var/run/AdGuardHomesyslog
|
||||
fi
|
||||
done
|
||||
@ -1,89 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
checkmd5(){
|
||||
local nowmd5=$(md5sum /tmp/adguard.list 2>/dev/null)
|
||||
nowmd5=${nowmd5%% *}
|
||||
local lastmd5=$(uci get AdGuardHome.AdGuardHome.gfwlistmd5 2>/dev/null)
|
||||
if [ "$nowmd5" != "$lastmd5" ]; then
|
||||
uci set AdGuardHome.AdGuardHome.gfwlistmd5="$nowmd5"
|
||||
uci commit AdGuardHome
|
||||
[ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload
|
||||
fi
|
||||
}
|
||||
|
||||
configpath=$(uci get AdGuardHome.AdGuardHome.configpath 2>/dev/null)
|
||||
[ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' $configpath && checkmd5 "$2" && exit 0
|
||||
gfwupstream=$(uci get AdGuardHome.AdGuardHome.gfwupstream 2>/dev/null)
|
||||
if [ -z $gfwupstream ]; then
|
||||
gfwupstream="tcp://208.67.220.220:5353"
|
||||
fi
|
||||
if [ ! -f "$configpath" ]; then
|
||||
echo "please make a config first"
|
||||
exit 1
|
||||
fi
|
||||
wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O- | base64 -d > /tmp/gfwlist.txt
|
||||
cat /tmp/gfwlist.txt | awk -v upst="$gfwupstream" 'BEGIN{getline;}{
|
||||
s1=substr($0,1,1);
|
||||
if (s1=="!")
|
||||
{next;}
|
||||
if (s1=="@"){
|
||||
$0=substr($0,3);
|
||||
s1=substr($0,1,1);
|
||||
white=1;}
|
||||
else{
|
||||
white=0;
|
||||
}
|
||||
|
||||
if (s1=="|")
|
||||
{s2=substr($0,2,1);
|
||||
if (s2=="|")
|
||||
{
|
||||
$0=substr($0,3);
|
||||
split($0,d,"/");
|
||||
$0=d[1];
|
||||
}else{
|
||||
split($0,d,"/");
|
||||
$0=d[3];
|
||||
}}
|
||||
else{
|
||||
split($0,d,"/");
|
||||
$0=d[1];
|
||||
}
|
||||
star=index($0,"*");
|
||||
if (star!=0)
|
||||
{
|
||||
$0=substr($0,star+1);
|
||||
dot=index($0,".");
|
||||
if (dot!=0)
|
||||
$0=substr($0,dot+1);
|
||||
else
|
||||
next;
|
||||
s1=substr($0,1,1);
|
||||
}
|
||||
if (s1==".")
|
||||
{fin=substr($0,2);}
|
||||
else{fin=$0;}
|
||||
if (index(fin,".")==0) next;
|
||||
if (index(fin,"%")!=0) next;
|
||||
if (index(fin,":")!=0) next;
|
||||
match(fin,"^[0-9\.]+")
|
||||
if (RSTART==1 && RLENGTH==length(fin)) {print "ipset add gfwlist "fin>"/tmp/doipset.sh";next;}
|
||||
if (fin=="" || finl==fin) next;
|
||||
finl=fin;
|
||||
if (white==0)
|
||||
{print(" - '\''[/"fin"/]"upst"'\''");}
|
||||
else{
|
||||
print(" - '\''[/"fin"/]#'\''");}
|
||||
}END{print(" - '\''[/programaddend/]#'\''")}' > /tmp/adguard.list
|
||||
grep programaddstart $configpath
|
||||
if [ "$?" == "0" ]; then
|
||||
sed -i '/programaddstart/,/programaddend/c\ - '\''\[\/programaddstart\/\]#'\''' $configpath
|
||||
sed -i '/programaddstart/'r/tmp/adguard.list $configpath
|
||||
else
|
||||
sed -i '1i\ - '\''[/programaddstart/]#'\''' /tmp/adguard.list
|
||||
sed -i '/upstream_dns:/'r/tmp/adguard.list $configpath
|
||||
fi
|
||||
checkmd5 "$2"
|
||||
rm -f /tmp/gfwlist.txt /tmp/adguard.list
|
||||
@ -1,3 +0,0 @@
|
||||
https://github.com/AdguardTeam/AdGuardHome/releases/download/${latest_ver}/AdGuardHome_linux_${Arch}.tar.gz
|
||||
https://static.adguard.com/adguardhome/release/AdGuardHome_linux_${Arch}.tar.gz
|
||||
https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_${Arch}.tar.gz
|
||||
@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
tail -n $1 "$2" > /var/run/tailtmp
|
||||
cat /var/run/tailtmp > "$2"
|
||||
rm /var/run/tailtmp
|
||||
@ -1,218 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
update_mode=$1
|
||||
binpath=$(uci get AdGuardHome.AdGuardHome.binpath)
|
||||
if [[ -z ${binpath} ]]; then
|
||||
uci set AdGuardHome.AdGuardHome.binpath="/tmp/AdGuardHome/AdGuardHome"
|
||||
binpath="/tmp/AdGuardHome/AdGuardHome"
|
||||
fi
|
||||
[[ ! -d ${binpath%/*} ]] && mkdir -p ${binpath%/*}
|
||||
upxflag=$(uci get AdGuardHome.AdGuardHome.upxflag 2>/dev/null)
|
||||
|
||||
[[ -z ${upxflag} ]] && upxflag=off
|
||||
enabled=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null)
|
||||
core_version=$(uci get AdGuardHome.AdGuardHome.core_version 2>/dev/null)
|
||||
update_url=$(uci get AdGuardHome.AdGuardHome.update_url 2>/dev/null)
|
||||
|
||||
case "${core_version}" in
|
||||
beta)
|
||||
core_api_url=https://api.github.com/repos/AdguardTeam/AdGuardHome/releases
|
||||
;;
|
||||
*)
|
||||
core_api_url=https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest
|
||||
;;
|
||||
esac
|
||||
|
||||
Check_Task(){
|
||||
running_tasks="$(ps -efww | grep -v grep | grep "AdGuardHome" | grep "update_core" | awk '{print $1}' | wc -l)"
|
||||
case $1 in
|
||||
force)
|
||||
echo -e "执行: 强制更新核心"
|
||||
echo -e "清除 ${running_tasks} 个进程 ..."
|
||||
ps -efww | grep -v grep | grep -v $$ | grep "AdGuardHome" | grep "update_core" | awk '{print $1}' | xargs kill -9 2> /dev/null
|
||||
;;
|
||||
*)
|
||||
[[ ${running_tasks} -gt 2 ]] && echo -e "已经有 ${running_tasks} 个任务正在运行, 请等待其执行结束或将其强行停止!" && EXIT 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
Check_Downloader(){
|
||||
which curl > /dev/null 2>&1 && PKG="curl" && return
|
||||
echo -e "\n未安装 curl"
|
||||
which wget-ssl > /dev/null 2>&1 && PKG="wget-ssl" && return
|
||||
echo "未安装 curl 和 wget, 无法检测更新!" && EXIT 1
|
||||
}
|
||||
|
||||
Check_Updates(){
|
||||
Check_Downloader
|
||||
case "${PKG}" in
|
||||
curl)
|
||||
Downloader="curl -L -k -o"
|
||||
_Downloader="curl -s"
|
||||
;;
|
||||
wget-ssl)
|
||||
Downloader="wget-ssl --no-check-certificate -T 5 -O"
|
||||
_Downloader="wget-ssl -q -O -"
|
||||
;;
|
||||
esac
|
||||
echo "[${PKG}] 开始检查更新, 请耐心等待 ..."
|
||||
Cloud_Version="$(${_Downloader} ${core_api_url} 2>/dev/null | grep 'tag_name' | egrep -o "v[0-9].+[0-9.]" | awk 'NR==1')"
|
||||
[[ -z ${Cloud_Version} ]] && echo -e "\n检查更新失败, 请检查网络或稍后重试!" && EXIT 1
|
||||
if [[ -f ${binpath} ]]; then
|
||||
Current_Version="$(${binpath} --version 2>/dev/null | egrep -o "v[0-9].+[0-9]" | sed -r 's/(.*), c(.*)/\1/')"
|
||||
else
|
||||
Current_Version="未知"
|
||||
fi
|
||||
[[ -z ${Current_Version} ]] && Current_Version="未知"
|
||||
echo -e "\n执行文件路径: ${binpath%/*}\n\n正在检查更新, 请耐心等待 ..."
|
||||
echo -e "\n当前 AdGuardHome 版本: ${Current_Version}\n云端 AdGuardHome 版本: ${Cloud_Version}"
|
||||
if [[ ! "${Cloud_Version}" == "${Current_Version}" || "$1" == force ]]; then
|
||||
Update_Core
|
||||
else
|
||||
echo -e "\n已是最新版本, 无需更新!"
|
||||
EXIT 0
|
||||
fi
|
||||
EXIT 0
|
||||
}
|
||||
|
||||
UPX_Compress(){
|
||||
GET_Arch
|
||||
upx_name="upx-${upx_latest_ver}-${Arch_upx}_linux.tar.xz"
|
||||
echo -e "开始下载 ${upx_name} ...\n"
|
||||
$Downloader /tmp/upx-${upx_latest_ver}-${Arch_upx}_linux.tar.xz "https://github.com/upx/upx/releases/download/v${upx_latest_ver}/${upx_name}"
|
||||
if [[ ! -e /tmp/upx-${upx_latest_ver}-${Arch_upx}_linux.tar.xz ]]; then
|
||||
echo -e "\n${upx_name} 下载失败!\n"
|
||||
EXIT 1
|
||||
else
|
||||
echo -e "\n${upx_name} 下载成功!\n"
|
||||
fi
|
||||
which xz > /dev/null 2>&1 || (opkg list | grep ^xz || opkg update > /dev/null 2>&1 && opkg install xz --force-depends) || (echo "软件包 xz 安装失败!" && EXIT 1)
|
||||
mkdir -p /tmp/upx-${upx_latest_ver}-${Arch_upx}_linux
|
||||
echo -e "正在解压 ${upx_name} ...\n"
|
||||
xz -d -c /tmp/upx-${upx_latest_ver}-${Arch_upx}_linux.tar.xz | tar -x -C "/tmp"
|
||||
[[ ! -f /tmp/upx-${upx_latest_ver}-${Arch_upx}_linux/upx ]] && echo -e "\n${upx_name} 解压失败!" && EXIT 1
|
||||
}
|
||||
|
||||
Update_Core(){
|
||||
rm -r /tmp/AdGuardHome_Update > /dev/null 2>&1
|
||||
mkdir -p "/tmp/AdGuardHome_Update"
|
||||
GET_Arch
|
||||
eval link="${update_url}"
|
||||
echo -e "下载链接:${link}"
|
||||
echo -e "文件名称:${link##*/}"
|
||||
echo -e "\n开始下载 AdGuardHome 核心文件 ...\n"
|
||||
$Downloader /tmp/AdGuardHome_Update/${link##*/} ${link}
|
||||
if [[ $? != 0 ]];then
|
||||
echo -e "\nAdGuardHome 核心下载失败 ..."
|
||||
rm -r /tmp/AdGuardHome_Update
|
||||
EXIT 1
|
||||
fi
|
||||
if [[ ${link##*.} == gz ]]; then
|
||||
echo -e "\n正在解压 AdGuardHome ..."
|
||||
tar -zxf "/tmp/AdGuardHome_Update/${link##*/}" -C "/tmp/AdGuardHome_Update/"
|
||||
if [[ ! -e /tmp/AdGuardHome_Update/AdGuardHome ]]
|
||||
then
|
||||
echo "AdGuardHome 核心解压失败!"
|
||||
rm -rf "/tmp/AdGuardHome_Update" > /dev/null 2>&1
|
||||
EXIT 1
|
||||
fi
|
||||
downloadbin="/tmp/AdGuardHome_Update/AdGuardHome/AdGuardHome"
|
||||
else
|
||||
downloadbin="/tmp/AdGuardHome_Update/${link##*/}"
|
||||
fi
|
||||
chmod +x ${downloadbin}
|
||||
echo -e "\nAdGuardHome 核心体积: $(awk 'BEGIN{printf "%.2fMB\n",'$((`ls -l $downloadbin | awk '{print $5}'`))'/1000000}')"
|
||||
if [[ ${upxflag} != off ]]; then
|
||||
UPX_Compress
|
||||
echo -e "使用 UPX 压缩可能会花很长时间, 期间请耐心等待!\n正在压缩 $downloadbin ..."
|
||||
/tmp/upx-${upx_latest_ver}-${Arch_upx}_linux/upx $upxflag $downloadbin > /dev/null 2>&1
|
||||
echo -e "\n压缩后的核心体积: $(awk 'BEGIN{printf "%.2fMB\n",'$((`ls -l $downloadbin | awk '{print $5}'`))'/1000000}')"
|
||||
else
|
||||
echo "未启用 UPX 压缩, 跳过操作..."
|
||||
fi
|
||||
/etc/init.d/AdGuardHome stop > /dev/null 2>&1
|
||||
echo -e "\n移动 AdGuardHome 核心文件到 ${binpath%/*} ..."
|
||||
mv -f ${downloadbin} ${binpath} > /dev/null 2>&1
|
||||
if [[ ! -s ${binpath} && $? != 0 ]]; then
|
||||
echo -e "AdGuardHome 核心移动失败!\n可能是设备空间不足导致, 请尝试开启 UPX 压缩, 或更改 [执行文件路径] 为 /tmp/AdGuardHome"
|
||||
EXIT 1
|
||||
fi
|
||||
rm -f /tmp/upx*.tar.xz
|
||||
rm -rf /tmp/upx*
|
||||
rm -rf /tmp/AdGuardHome_Update
|
||||
chmod +x ${binpath}
|
||||
if [[ ${enabled} == 1 ]]; then
|
||||
echo -e "\n正在重启 AdGuardHome 服务..."
|
||||
/etc/init.d/AdGuardHome restart
|
||||
fi
|
||||
echo -e "\nAdGuardHome 核心更新成功!"
|
||||
}
|
||||
|
||||
GET_Arch() {
|
||||
Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')"
|
||||
case "${Archt}" in
|
||||
i386)
|
||||
Arch=i386
|
||||
;;
|
||||
i686)
|
||||
Arch=i386
|
||||
;;
|
||||
x86)
|
||||
Arch=amd64
|
||||
;;
|
||||
mipsel)
|
||||
Arch=mipsle_softfloat
|
||||
;;
|
||||
mips)
|
||||
Arch=mips_softfloat
|
||||
;;
|
||||
mips64el)
|
||||
Arch=mips64le_softfloat
|
||||
;;
|
||||
mips64)
|
||||
Arch=mips64_softfloat
|
||||
;;
|
||||
arm)
|
||||
Arch=arm
|
||||
;;
|
||||
armeb)
|
||||
Arch=armeb
|
||||
;;
|
||||
aarch64)
|
||||
Arch=arm64
|
||||
;;
|
||||
*)
|
||||
echo -e "\nAdGuardHome 暂不支持当前的设备架构: [${Archt}]!"
|
||||
EXIT 1
|
||||
esac
|
||||
case "${Archt}" in
|
||||
mipsel)
|
||||
Arch_upx="mipsel"
|
||||
upx_latest_ver="3.95"
|
||||
;;
|
||||
*)
|
||||
Arch_upx="${Arch}"
|
||||
upx_latest_ver="$(${_Downloader} https://api.github.com/repos/upx/upx/releases/latest 2>/dev/null | egrep 'tag_name' | egrep '[0-9.]+' -o 2>/dev/null)"
|
||||
|
||||
esac
|
||||
echo -e "\n当前设备架构: ${Arch}\n"
|
||||
}
|
||||
|
||||
EXIT(){
|
||||
rm -rf /var/run/update_core $LOCKU 2>/dev/null
|
||||
[[ $1 != 0 ]] && touch /var/run/update_core_error
|
||||
exit $1
|
||||
}
|
||||
|
||||
main(){
|
||||
Check_Task ${update_mode}
|
||||
Check_Updates ${update_mode}
|
||||
}
|
||||
|
||||
trap "EXIT 1" SIGTERM SIGINT
|
||||
touch /var/run/update_core
|
||||
rm - rf /var/run/update_core_error 2>/dev/null
|
||||
|
||||
main
|
||||
@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
count=0
|
||||
while :
|
||||
do
|
||||
ping -c 1 -W 1 -q www.baidu.com 1>/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
/etc/init.d/AdGuardHome force_reload
|
||||
break
|
||||
fi
|
||||
ping -c 1 -W 1 -q 202.108.22.5 1>/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
/etc/init.d/AdGuardHome force_reload
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
ping -c 1 -W 1 -q www.google.com 1>/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
/etc/init.d/AdGuardHome force_reload
|
||||
break
|
||||
fi
|
||||
ping -c 1 -W 1 -q 8.8.8.8 1>/dev/null 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
/etc/init.d/AdGuardHome force_reload
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
count=$((count+1))
|
||||
if [ $count -gt 18 ]; then
|
||||
/etc/init.d/AdGuardHome force_reload
|
||||
break
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
configpath=$(uci get AdGuardHome.AdGuardHome.configpath)
|
||||
while :
|
||||
do
|
||||
sleep 10
|
||||
if [ -f "$configpath" ]; then
|
||||
/etc/init.d/AdGuardHome do_redirect 1
|
||||
break
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
@ -0,0 +1,40 @@
|
||||
{
|
||||
"admin/services/adguardhome": {
|
||||
"title": "AdGuard Home",
|
||||
"action": {
|
||||
"type": "firstchild"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-app-adguardhome"
|
||||
],
|
||||
"uci": {
|
||||
"adguardhome": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"admin/services/adguardhome/config": {
|
||||
"title": "Configuration",
|
||||
"order": 1,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/config"
|
||||
}
|
||||
},
|
||||
"admin/services/adguardhome/status": {
|
||||
"title": "Status",
|
||||
"order": 11,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/status"
|
||||
}
|
||||
},
|
||||
"admin/services/adguardhome/logs": {
|
||||
"title": "Logs",
|
||||
"order": 21,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/logs"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,30 @@
|
||||
{
|
||||
"luci-app-adguardhome": {
|
||||
"description": "Grant UCI access for luci-app-adguardhome",
|
||||
"description": "Grant permissions for the AdGuard Home LuCI app",
|
||||
"read": {
|
||||
"uci": [ "AdGuardHome" ]
|
||||
"ubus": {
|
||||
"luci.adguardhome": [
|
||||
"get_config",
|
||||
"get_status",
|
||||
"get_statistics",
|
||||
"set_passwd"
|
||||
]
|
||||
},
|
||||
"uci": [ "adguardhome" ],
|
||||
"file": {
|
||||
"/sbin/logread": [
|
||||
"stat",
|
||||
"exec"
|
||||
],
|
||||
"/sbin/logread -e AdGuardHome": [
|
||||
"exec"
|
||||
],
|
||||
"/etc/init.d/dnsmasq": [ "exec" ],
|
||||
"/etc/init.d/firewall": [ "exec" ]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "AdGuardHome" ]
|
||||
"uci": [ "adguardhome" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
!function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}(function(n){"use strict";function e(e,o,i,t){if(i&&i.call){var l=i;i=null}else l=r(e,i,"rangeFinder");"number"==typeof o&&(o=n.Pos(o,0));var f=r(e,i,"minFoldSize");function d(n){var r=l(e,o);if(!r||r.to.line-r.from.line<f)return null;for(var i=e.findMarksAt(r.from),d=0;d<i.length;++d)if(i[d].__isFold&&"fold"!==t){if(!n)return null;r.cleared=!0,i[d].clear()}return r}var u=d(!0);if(r(e,i,"scanUp"))for(;!u&&o.line>e.firstLine();)o=n.Pos(o.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,e){var o=r(n,e,"widget");if("string"==typeof o){var i=document.createTextNode(o);(o=document.createElement("span")).appendChild(i),o.className="CodeMirror-foldmarker"}else o&&(o=o.cloneNode(!0));return o}(e,i);n.on(a,"mousedown",function(e){c.clear(),n.e_preventDefault(e)});var c=e.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(e,i,"clearOnEnter"),__isFold:!0});c.on("clear",function(o,r){n.signal(e,"unfold",e,o,r)}),n.signal(e,"fold",e,u.from,u.to)}}n.newFoldFunction=function(n,o){return function(r,i){e(r,i,{rangeFinder:n,widget:o})}},n.defineExtension("foldCode",function(n,o,r){e(this,n,o,r)}),n.defineExtension("isFolded",function(n){for(var e=this.findMarksAt(n),o=0;o<e.length;++o)if(e[o].__isFold)return!0}),n.commands.toggleFold=function(n){n.foldCode(n.getCursor())},n.commands.fold=function(n){n.foldCode(n.getCursor(),null,"fold")},n.commands.unfold=function(n){n.foldCode(n.getCursor(),null,"unfold")},n.commands.foldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"fold")})},n.commands.unfoldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"unfold")})},n.registerHelper("fold","combine",function(){var n=Array.prototype.slice.call(arguments,0);return function(e,o){for(var r=0;r<n.length;++r){var i=n[r](e,o);if(i)return i}}}),n.registerHelper("fold","auto",function(n,e){for(var o=n.getHelpers(e,"fold"),r=0;r<o.length;r++){var i=o[r](n,e);if(i)return i}});var o={rangeFinder:n.fold.auto,widget:"↔",minFoldSize:0,scanUp:!1,clearOnEnter:!0};function r(n,e,r){if(e&&void 0!==e[r])return e[r];var i=n.options.foldOptions;return i&&void 0!==i[r]?i[r]:o[r]}n.defineOption("foldOptions",null),n.defineExtension("foldOption",function(n,e){return r(this,n,e)})});
|
||||
@ -1 +0,0 @@
|
||||
.CodeMirror-foldmarker{color:blue;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.CodeMirror-foldgutter{width:.7em}.CodeMirror-foldgutter-open,.CodeMirror-foldgutter-folded{cursor:pointer}.CodeMirror-foldgutter-open:after{content:"\25BE"}.CodeMirror-foldgutter-folded:after{content:"\25B8"}
|
||||
@ -1 +0,0 @@
|
||||
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("./foldcode")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./foldcode"],t):t(CodeMirror)}(function(t){"use strict";t.defineOption("foldGutter",!1,function(o,e,r){r&&r!=t.Init&&(o.clearGutter(o.state.foldGutter.options.gutter),o.state.foldGutter=null,o.off("gutterClick",a),o.off("changes",d),o.off("viewportChange",u),o.off("fold",l),o.off("unfold",l),o.off("swapDoc",d)),e&&(o.state.foldGutter=new function(t){this.options=t,this.from=this.to=0}(function(t){!0===t&&(t={});null==t.gutter&&(t.gutter="CodeMirror-foldgutter");null==t.indicatorOpen&&(t.indicatorOpen="CodeMirror-foldgutter-open");null==t.indicatorFolded&&(t.indicatorFolded="CodeMirror-foldgutter-folded");return t}(e)),f(o),o.on("gutterClick",a),o.on("changes",d),o.on("viewportChange",u),o.on("fold",l),o.on("unfold",l),o.on("swapDoc",d))});var o=t.Pos;function e(t,e){for(var r=t.findMarks(o(e,0),o(e+1,0)),n=0;n<r.length;++n)if(r[n].__isFold){var i=r[n].find(-1);if(i&&i.line===e)return r[n]}}function r(t){if("string"==typeof t){var o=document.createElement("div");return o.className=t+" CodeMirror-guttermarker-subtle",o}return t.cloneNode(!0)}function n(t,n,f){var a=t.state.foldGutter.options,d=n-1,u=t.foldOption(a,"minFoldSize"),l=t.foldOption(a,"rangeFinder"),c="string"==typeof a.indicatorFolded&&i(a.indicatorFolded),s="string"==typeof a.indicatorOpen&&i(a.indicatorOpen);t.eachLine(n,f,function(n){++d;var i=null,f=n.gutterMarkers;if(f&&(f=f[a.gutter]),e(t,d)){if(c&&f&&c.test(f.className))return;i=r(a.indicatorFolded)}else{var p=o(d,0),m=l&&l(t,p);if(m&&m.to.line-m.from.line>=u){if(s&&f&&s.test(f.className))return;i=r(a.indicatorOpen)}}(i||f)&&t.setGutterMarker(n,a.gutter,i)})}function i(t){return new RegExp("(^|\\s)"+t+"(?:$|\\s)\\s*")}function f(t){var o=t.getViewport(),e=t.state.foldGutter;e&&(t.operation(function(){n(t,o.from,o.to)}),e.from=o.from,e.to=o.to)}function a(t,r,n){var i=t.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var a=e(t,r);a?a.clear():t.foldCode(o(r,0),f)}}}function d(t){var o=t.state.foldGutter;if(o){var e=o.options;o.from=o.to=0,clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){f(t)},e.foldOnChangeTimeSpan||600)}}function u(t){var o=t.state.foldGutter;if(o){var e=o.options;clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){var e=t.getViewport();o.from==o.to||e.from-o.to>20||o.from-e.to>20?f(t):t.operation(function(){e.from<o.from&&(n(t,e.from,o.from),o.from=e.from),e.to>o.to&&(n(t,o.to,e.to),o.to=e.to)})},e.updateViewportTimeSpan||400)}}function l(t,o){var e=t.state.foldGutter;if(e){var r=o.line;r>=e.from&&r<e.to&&n(t,r,r+1)}}});
|
||||
@ -1 +0,0 @@
|
||||
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function n(n,t){var i=n.getLine(t),o=i.search(/\S/);return-1==o||/\bcomment\b/.test(n.getTokenTypeAt(e.Pos(t,o+1)))?-1:e.countColumn(i,null,n.getOption("tabSize"))}e.registerHelper("fold","indent",function(t,i){var o=n(t,i.line);if(!(o<0)){for(var r=null,l=i.line+1,f=t.lastLine();l<=f;++l){var u=n(t,l);if(-1==u);else{if(!(u>o))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}})});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var e=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(i,t){var r=i.peek(),n=t.escaped;if(t.escaped=!1,"#"==r&&(0==i.pos||/\s/.test(i.string.charAt(i.pos-1))))return i.skipToEnd(),"comment";if(i.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(t.literal&&i.indentation()>t.keyCol)return i.skipToEnd(),"string";if(t.literal&&(t.literal=!1),i.sol()){if(t.keyCol=0,t.pair=!1,t.pairStart=!1,i.match(/---/))return"def";if(i.match(/\.\.\./))return"def";if(i.match(/\s*-\s+/))return"meta"}if(i.match(/^(\{|\}|\[|\])/))return"{"==r?t.inlinePairs++:"}"==r?t.inlinePairs--:"["==r?t.inlineList++:t.inlineList--,"meta";if(t.inlineList>0&&!n&&","==r)return i.next(),"meta";if(t.inlinePairs>0&&!n&&","==r)return t.keyCol=0,t.pair=!1,t.pairStart=!1,i.next(),"meta";if(t.pairStart){if(i.match(/^\s*(\||\>)\s*/))return t.literal=!0,"meta";if(i.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==t.inlinePairs&&i.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(t.inlinePairs>0&&i.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(i.match(e))return"keyword"}return!t.pair&&i.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(t.pair=!0,t.keyCol=i.indentation(),"atom"):t.pair&&i.match(/^:\s*/)?(t.pairStart=!0,"meta"):(t.pairStart=!1,t.escaped="\\"==r,i.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});
|
||||
@ -1 +0,0 @@
|
||||
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{background-color:#282a36 !important;color:#f8f8f2 !important;border:0}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,0.10)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:white}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-variable-3,.cm-s-dracula span.cm-type{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,0.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:white !important}
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit fe34dd9377e85d328e680a17f53003f5f29ef8b6
|
||||
21
luci-app-cloudreve/Makefile
Normal file
21
luci-app-cloudreve/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2019 Openwrt.org
|
||||
#
|
||||
# This is a free software, use it under Apache Licene 2.0 & GNU General Public License v3.0.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Cloudreve for LuCI
|
||||
LUCI_DEPENDS:=+cloudreve
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_NAME:=luci-app-cloudreve
|
||||
|
||||
define Package/luci-app-cloudreve/conffiles
|
||||
/etc/config/cloudreve
|
||||
/etc/cloudreve/
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
17
luci-app-cloudreve/luasrc/controller/cloudreve.lua
Normal file
17
luci-app-cloudreve/luasrc/controller/cloudreve.lua
Normal file
@ -0,0 +1,17 @@
|
||||
module("luci.controller.cloudreve",package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "nas"}, firstchild(), _("NAS") , 45).dependent = false
|
||||
if not nixio.fs.access("/etc/config/cloudreve")then
|
||||
return
|
||||
end
|
||||
entry({"admin","nas","cloudreve"},cbi("cloudreve"),_("Cloudreve")).acl_depends = { "luci-app-cloudreve" }
|
||||
entry({"admin","nas","cloudreve","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep cloudreve >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
16
luci-app-cloudreve/luasrc/model/cbi/cloudreve.lua
Normal file
16
luci-app-cloudreve/luasrc/model/cbi/cloudreve.lua
Normal file
@ -0,0 +1,16 @@
|
||||
m = Map("cloudreve", translate("Cloudreve"), translate("Self-hosted file management and sharing system, supports multiple storage providers."))
|
||||
|
||||
m:section(SimpleSection).template="cloudreve/cloudreve_status"
|
||||
|
||||
s = m:section(TypedSection, "cloudreve")
|
||||
s.anonymous=true
|
||||
|
||||
enabled = s:option(Flag, "enabled", translate("Enable"))
|
||||
enabled.rmempty = false
|
||||
|
||||
port = s:option(Value,"port",translate("Port"))
|
||||
port.default = "8052"
|
||||
port.placeholder = "8052"
|
||||
port.rmempty = false
|
||||
|
||||
return m
|
||||
@ -0,0 +1,27 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[nas]], [[cloudreve]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('cloudreve_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>Cloudreve <%:RUNNING%></font></b></em><input class="cbi-button mar-10" type="button" value="<%:Open Web Interface%>" onclick="openwebui();" />';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>Cloudreve <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function openwebui(){
|
||||
var url = window.location.host+":<%=luci.sys.exec("uci -q get cloudreve.@cloudreve[0].port"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
window.open('http://'+url,'target','');
|
||||
};
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="cloudreve_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
||||
1
luci-app-cloudreve/po/zh-cn
Symbolic link
1
luci-app-cloudreve/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
27
luci-app-cloudreve/po/zh_Hans/cloudreve.po
Normal file
27
luci-app-cloudreve/po/zh_Hans/cloudreve.po
Normal file
@ -0,0 +1,27 @@
|
||||
msgid "Cloudreve"
|
||||
msgstr "Cloudreve"
|
||||
|
||||
msgid "Self-hosted file management and sharing system, supports multiple storage providers."
|
||||
msgstr "Cloudreve 可助你即刻构建出兼备自用或公用的网盘服务,通过多种存储策略的支持、虚拟文件系统等特性实现灵活的文件管理体验。"
|
||||
|
||||
msgid "Default login username: admin@cloudreve.org, password: password."
|
||||
msgstr "默认登录用户名:admin@cloudreve.org,密码:password。"
|
||||
|
||||
msgid "Open Web Interface"
|
||||
msgstr "打开Web界面"
|
||||
|
||||
msgid "Cloudreve Run Status"
|
||||
msgstr "Cloudreve 运行状态"
|
||||
|
||||
msgid "Running"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "Not running"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
4
luci-app-cloudreve/root/etc/config/cloudreve
Normal file
4
luci-app-cloudreve/root/etc/config/cloudreve
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
config cloudreve
|
||||
option enabled '0'
|
||||
option port '8052'
|
||||
37
luci-app-cloudreve/root/etc/init.d/cloudreve
Executable file
37
luci-app-cloudreve/root/etc/init.d/cloudreve
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
homedir="/etc/cloudreve"
|
||||
|
||||
get_config() {
|
||||
config_get_bool enabled $1 enabled 0
|
||||
config_get port $1 port 8052
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load cloudreve
|
||||
config_foreach get_config cloudreve
|
||||
[ $enabled != 1 ] && return 1
|
||||
mkdir -p "$homedir"
|
||||
if [ -f "$homedir/cloudreve.ini" ]; then
|
||||
sed -i "s/Listen = :[0-9]*/Listen = :$port/g" "$homedir/cloudreve.ini"
|
||||
else
|
||||
cat >"$homedir/cloudreve.ini"<<EOF
|
||||
[System]
|
||||
Debug = false
|
||||
Mode = master
|
||||
Listen = :${port}
|
||||
EOF
|
||||
fi
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/bin/cloudreve -c $homedir/cloudreve.ini
|
||||
procd_set_param stderr 1
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "cloudreve"
|
||||
}
|
||||
21
luci-app-cloudreve/root/etc/uci-defaults/cloudreve
Normal file
21
luci-app-cloudreve/root/etc/uci-defaults/cloudreve
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-cloudreve.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-cloudreve.json << EEOF
|
||||
{
|
||||
"config": "cloudreve",
|
||||
"init": "cloudreve"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@cloudreve[-1]
|
||||
add ucitrack cloudreve
|
||||
set ucitrack.@cloudreve[-1].init=cloudreve
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
chmod +x /etc/init.d/cloudreve >/dev/null 2>&1
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-cloudreve": {
|
||||
"description": "Grant UCI access for luci-app-cloudreve",
|
||||
"read": {
|
||||
"uci": [ "cloudreve" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "cloudreve" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,9 +133,11 @@ o.validate = function(self, value)
|
||||
return value:gsub("%s+", ""):gsub("%z", "")
|
||||
end
|
||||
|
||||
o = s:option(Flag, "allowInsecure", translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
|
||||
o = s:option(Flag, "allowInsecure", translate("allowInsecure"))
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
o.description = translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.") .. "<br>" ..
|
||||
translate("Used when the node link does not include this parameter.")
|
||||
|
||||
o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode"))
|
||||
o.default = "5"
|
||||
|
||||
@ -1063,10 +1063,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'reality', false);
|
||||
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', false);
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0'));
|
||||
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||
opt.set(dom_prefix + 'utls', true);
|
||||
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
|
||||
@ -1317,11 +1314,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'tls_CertSha', queryParam.pcs || '');
|
||||
opt.set(dom_prefix + 'tls_CertByName', queryParam.vcn || '');
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', false);
|
||||
}
|
||||
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0'));
|
||||
opt.set(dom_prefix + 'tcp_fast_open', queryParam.tfo);
|
||||
opt.set(dom_prefix + 'use_finalmask', !!queryParam.fm);
|
||||
opt.set(dom_prefix + 'finalmask', queryParam.fm || "");
|
||||
@ -1353,11 +1346,8 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'uuid', ssm.id);
|
||||
opt.set(dom_prefix + 'tls', ssm.tls === "tls");
|
||||
if (ssm.tls === "tls") {
|
||||
var tls_serverName = ssm.host;
|
||||
if (ssm.sni) {
|
||||
tls_serverName = ssm.sni
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_serverName', tls_serverName);
|
||||
opt.set(dom_prefix + 'tls_serverName', ssm.sni || ssm.host);
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((ssm.allowinsecure ?? '0') === '0' && (ssm.insecure ?? '0') === '0'));
|
||||
}
|
||||
ssm.net = ssm.net.toLowerCase();
|
||||
if (ssm.net === "kcp" || ssm.net === "mkcp")
|
||||
@ -1469,10 +1459,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'reality', false);
|
||||
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', false);
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0'));
|
||||
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||
opt.set(dom_prefix + 'utls', true);
|
||||
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
|
||||
@ -1630,9 +1617,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'port', m.port || "443");
|
||||
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || "");
|
||||
if (queryParam.insecure && queryParam.insecure == "1") {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0'));
|
||||
opt.set(dom_prefix + 'tls_CertSha', queryParam.pcs || '');
|
||||
opt.set(dom_prefix + 'tls_CertByName', queryParam.vcn || '');
|
||||
if (m.hash) {
|
||||
@ -1680,10 +1665,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'tuic_alpn', queryParam.alpn || 'default');
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||
opt.set(dom_prefix + 'tls_disable_sni', queryParam.disable_sni === "1");
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', false);
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0' && (queryParam.allow_insecure ?? '0') === '0'));
|
||||
if (hash) {
|
||||
opt.set('remarks', decodeURIComponent(hash.substr(1)));
|
||||
}
|
||||
@ -1723,10 +1705,7 @@ local current_node = map:get(section)
|
||||
opt.set(dom_prefix + 'reality', false);
|
||||
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
|
||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', false);
|
||||
}
|
||||
opt.set(dom_prefix + 'tls_allowInsecure', !((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0'));
|
||||
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||
opt.set(dom_prefix + 'utls', true);
|
||||
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
|
||||
|
||||
@ -1228,6 +1228,9 @@ msgstr "使用全局配置"
|
||||
msgid "User-Agent"
|
||||
msgstr "用户代理(User-Agent)"
|
||||
|
||||
msgid "Used when the node link does not include this parameter."
|
||||
msgstr "当节点链接未包含该参数时,将使用此设置。"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "添加"
|
||||
|
||||
|
||||
@ -602,14 +602,10 @@ local function processData(szType, content, add_mode, group)
|
||||
if info.tls == "tls" or info.tls == "1" then
|
||||
result.tls = "1"
|
||||
result.tls_serverName = (info.sni and info.sni ~= "") and info.sni or info.host
|
||||
info.allowinsecure = info.allowinsecure or info.insecure
|
||||
if info.allowinsecure and (info.allowinsecure == "1" or info.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = info.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
result.tls_CertSha = info.pcs
|
||||
result.tls_CertByName = info.vcn
|
||||
local insecure = info.allowinsecure or info.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
else
|
||||
result.tls = "0"
|
||||
end
|
||||
@ -894,12 +890,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
end
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure and (params.allowinsecure == "1" or params.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
result.uot = params.udp
|
||||
elseif (params.type ~= "tcp" and params.type ~= "raw") and (params.headerType and params.headerType ~= "none") then
|
||||
result.error_msg = "请更换 Xray 或 Sing-Box 来支持 SS 更多的传输方式。"
|
||||
@ -1003,18 +995,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.tls_serverName = params.peer or params.sni or ""
|
||||
result.tls_CertSha = params.pcs
|
||||
result.tls_CertByName = params.vcn
|
||||
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure then
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
--log(result.remarks .. ' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
|
||||
if not params.type then params.type = "tcp" end
|
||||
params.type = string.lower(params.type)
|
||||
@ -1280,17 +1262,11 @@ local function processData(szType, content, add_mode, group)
|
||||
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
end
|
||||
|
||||
result.port = port
|
||||
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure and (params.allowinsecure == "1" or params.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
|
||||
result.tcp_fast_open = params.tfo
|
||||
result.use_finalmask = (params.fm and params.fm ~= "") and "1" or nil
|
||||
result.finalmask = (params.fm and params.fm ~= "") and api.base64Encode(params.fm) or nil
|
||||
@ -1343,13 +1319,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.hysteria_auth_type = "string"
|
||||
result.hysteria_auth_password = params.auth
|
||||
result.tls_serverName = params.peer or params.sni or ""
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure and (params.allowinsecure == "1" or params.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
--log(result.remarks ..' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
result.alpn = params.alpn
|
||||
result.hysteria_up_mbps = params.upmbps
|
||||
result.hysteria_down_mbps = params.downmbps
|
||||
@ -1394,13 +1365,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.tls_serverName = params.sni
|
||||
result.tls_CertSha = params.pcs
|
||||
result.tls_CertByName = params.vcn
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure and (params.allowinsecure == "1" or params.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
--log(result.remarks ..' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
result.hysteria2_tls_pinSHA256 = params.pinSHA256
|
||||
result.hysteria2_hop = params.mport
|
||||
|
||||
@ -1479,17 +1445,8 @@ local function processData(szType, content, add_mode, group)
|
||||
result.tuic_alpn = params.alpn or "default"
|
||||
result.tuic_congestion_control = params.congestion_control or "cubic"
|
||||
result.tuic_udp_relay_mode = params.udp_relay_mode or "native"
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure then
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
--log(result.remarks .. ' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure or params.allow_insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
elseif szType == "anytls" then
|
||||
if has_singbox then
|
||||
result.type = 'sing-box'
|
||||
@ -1552,18 +1509,8 @@ local function processData(szType, content, add_mode, group)
|
||||
end
|
||||
end
|
||||
result.port = port
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
if params.allowinsecure and (params.allowinsecure == "1" or params.allowinsecure == "0") then
|
||||
result.tls_allowInsecure = params.allowinsecure
|
||||
else
|
||||
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||
end
|
||||
local singbox_version = api.get_app_version("sing-box")
|
||||
local version_ge_1_12 = api.compare_versions(singbox_version:match("[^v]+"), ">=", "1.12.0")
|
||||
if not has_singbox or not version_ge_1_12 then
|
||||
log("跳过节点:" .. result.remarks ..",因 " .. szType .. " 类型的节点需要 Sing-Box 1.12 以上版本支持。")
|
||||
return nil
|
||||
end
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (allowInsecure_default and "1" or "0")
|
||||
end
|
||||
elseif szType == 'naive+https' or szType == 'naive+quic' then
|
||||
if has_singbox then
|
||||
|
||||
@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-ssr-plus
|
||||
PKG_VERSION:=190
|
||||
PKG_RELEASE:=4
|
||||
PKG_RELEASE:=5
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
|
||||
|
||||
@ -372,17 +372,23 @@ if is_finded("xray") then
|
||||
o.default = "100-200"
|
||||
o:depends("fragment", true)
|
||||
|
||||
o = s:option(Value, "fragment_interval", translate("Fragment Interval"), translate("Fragmentation interval (ms)"))
|
||||
o = s:option(Value, "fragment_delay", translate("Fragment Delay"), translate("Fragmentation interval (ms)"))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.default = "10-20"
|
||||
o:depends("fragment", true)
|
||||
|
||||
o = s:option(Value, "fragment_maxSplit", translate("Max Split"), translate("Limit the maximum number of splits."))
|
||||
o.datatype = "or(uinteger,portrange)"
|
||||
o.default = "100-200"
|
||||
o:depends("fragment", true)
|
||||
|
||||
o = s:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions."))
|
||||
o.default = 0
|
||||
|
||||
s = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"))
|
||||
s.description = translate(
|
||||
"<font style='color:red'>" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "</font>" ..
|
||||
"<br/><font><b>" .. translate("Packet or Rand length as a string, e.g., 10-20.") .. "</b></font>" ..
|
||||
"<br/><font><b>" .. translate("For specific usage, see:") .. "</b></font>" ..
|
||||
"<a href='https://xtls.github.io/config/outbounds/freedom.html' target='_blank'>" ..
|
||||
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
|
||||
@ -406,12 +412,13 @@ if is_finded("xray") then
|
||||
o = s:option(ListValue, "type", translate("Type"))
|
||||
o.default = "base64"
|
||||
o:value("rand", "rand")
|
||||
o:value("array", "array")
|
||||
o:value("str", "str")
|
||||
o:value("hex", "hex")
|
||||
o:value("base64", "base64")
|
||||
|
||||
o = s:option(Value, "domainStrategy", translate("Domain Strategy"))
|
||||
o.default = "UseIP"
|
||||
o.default = "AsIs"
|
||||
o:value("AsIs", "AsIs")
|
||||
o:value("UseIP", "UseIP")
|
||||
o:value("UseIPv4", "UseIPv4")
|
||||
@ -419,7 +426,7 @@ if is_finded("xray") then
|
||||
o:value("ForceIPv4", "ForceIPv4")
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "packet", translate("Packet"))
|
||||
o = s:option(Value, "packet", translate("Packet | Rand Length"))
|
||||
o.datatype = "minlength(1)"
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
@ -38,15 +38,18 @@ local function trim(text)
|
||||
return (text:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
-- base64
|
||||
-- base64 解码
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
end
|
||||
text = text:gsub("%z", "")
|
||||
text = text:gsub("%c", "")
|
||||
text = text:gsub("%s", "")
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
text = text:gsub("=", "")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
local result = b64decode(text)
|
||||
@ -57,6 +60,7 @@ local function base64Decode(text)
|
||||
end
|
||||
end
|
||||
|
||||
-- base64 编码
|
||||
local function base64Encode(text)
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
@ -64,9 +68,6 @@ local function base64Encode(text)
|
||||
local result = b64encode(text)
|
||||
if result then
|
||||
result = result:gsub("%z", "")
|
||||
result = result:gsub("/", "_")
|
||||
result = result:gsub("+", "-")
|
||||
result = result:gsub("=", "")
|
||||
return result
|
||||
else
|
||||
return text
|
||||
@ -1212,7 +1213,8 @@ o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
|
||||
o:depends({type = "v2ray", v2ray_protocol = "hysteria2"})
|
||||
|
||||
o = s:option(TextValue, "finalmask", " ")
|
||||
o.description = translate("An FinalMaskObject in JSON format, used for sharing.")
|
||||
o.description = translate("An FinalMaskObject in JSON format, used for sharing.") .. "<br>" ..
|
||||
translate("Custom finalmask overrides mkcp, hysteria2, fragment, noise, and related settings.")
|
||||
o:depends("enable_finalmask", true)
|
||||
o.rows = 10
|
||||
o.wrap = "off"
|
||||
@ -1510,6 +1512,7 @@ o.rmempty = true
|
||||
o.default = ""
|
||||
o:value("", translate("comment_tcpcongestion_disable"))
|
||||
o:value("bbr", translate("BBR"))
|
||||
o:value("brutal", translate("BRUTAL"))
|
||||
o:value("cubic", translate("CUBIC"))
|
||||
o:value("reno", translate("Reno"))
|
||||
o:depends({type = "v2ray", v2ray_protocol = "vless"})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -23,15 +23,20 @@ local xray_version_val = 0
|
||||
local node_id = server_section
|
||||
local remarks = server.alias or ""
|
||||
local b64decode = nixio.bin.b64decode
|
||||
local b64encode = nixio.bin.b64encode
|
||||
|
||||
-- base64 解码
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
end
|
||||
text = text:gsub("%z", "")
|
||||
text = text:gsub("%c", "")
|
||||
text = text:gsub("%s", "")
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
text = text:gsub("=", "")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
local result = b64decode(text)
|
||||
@ -42,6 +47,20 @@ local function base64Decode(text)
|
||||
end
|
||||
end
|
||||
|
||||
-- base64 编码
|
||||
local function base64Encode(text)
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
end
|
||||
local result = b64encode(text)
|
||||
if result then
|
||||
result = result:gsub("%z", "")
|
||||
return result
|
||||
else
|
||||
return text
|
||||
end
|
||||
end
|
||||
|
||||
local function cleanEmptyTables(t)
|
||||
if type(t) ~= "table" then return nil end
|
||||
for k, v in pairs(t) do
|
||||
@ -456,6 +475,8 @@ end
|
||||
} or nil,
|
||||
finalmask = (function()
|
||||
local finalmask = {}
|
||||
local PT = server.v2ray_protocol
|
||||
local TP = server.transport
|
||||
if server.transport == "kcp" then
|
||||
local map = {none = "none", srtp = "header-srtp", utp = "header-utp", ["wechat-video"] = "header-wechat",
|
||||
dtls = "header-dtls", wireguard = "header-wireguard", dns = "header-dns"}
|
||||
@ -473,7 +494,7 @@ end
|
||||
end
|
||||
udp[#udp+1] = c
|
||||
finalmask.udp = udp
|
||||
elseif server.v2ray_protocol == "hysteria2" then
|
||||
elseif PT == "hysteria2" then
|
||||
if (server.flag_obfs == "1" and (server.obfs_type and server.obfs_type ~= "")) then
|
||||
finalmask.udp = {{
|
||||
type = server.obfs_type,
|
||||
@ -507,6 +528,46 @@ end
|
||||
disablePathMTUDiscovery = (server.flag_quicparam == "1" and tostring(server.disablepathmtudiscovery) == "1") and true or nil
|
||||
}
|
||||
end
|
||||
if xray_fragment.fragment == "1" and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then
|
||||
local n_packets = xray_fragment.fragment_packets
|
||||
local n_length = xray_fragment.fragment_length
|
||||
local n_delay = xray_fragment.fragment_delay
|
||||
local n_maxsplit = xray_fragment.fragment_maxSplit
|
||||
--local domainstr = xray_noise.domainStrategy
|
||||
finalmask.tcp = finalmask.tcp or {}
|
||||
finalmask.tcp[#finalmask.tcp + 1] = {
|
||||
type = "fragment",
|
||||
settings = {
|
||||
--domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and domainstr or nil,
|
||||
packets = (n_packets and n_packets ~= "") and n_packets or nil,
|
||||
length = (n_length and n_length ~= "") and n_length or nil,
|
||||
delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay)),
|
||||
maxSplit = (n_maxsplit and n_maxsplit ~= "") and n_maxsplit or nil
|
||||
}
|
||||
}
|
||||
end
|
||||
if xray_fragment.noise == "1" and (TP == "kcp" or (TP == "xhttp" and (server.tls_alpn == "h3" or server.tls_alpn == "h3,h2"))) then
|
||||
if xray_noise.enabled == "1" then
|
||||
local n_type = xray_noise.type
|
||||
local n_delay = xray_noise.delay
|
||||
local n_packet = xray_noise.packet
|
||||
finalmask.udp = finalmask.udp or {}
|
||||
finalmask.udp[#finalmask.udp + 1] = {
|
||||
type = "noise",
|
||||
settings = {
|
||||
reset = 0,
|
||||
noise = {
|
||||
{
|
||||
rand = (n_type == "rand") and (n_packet and (type(n_packet) == "string" and (n_packet:find("-")) and n_packet or tonumber(n_packet))) or nil,
|
||||
type = (type(n_type) == "string" and n_type ~= "rand") and n_type or nil,
|
||||
packet = (n_type ~= "rand") and (n_type ~= "str" and (n_packet and type(n_packet) == "string" and base64Encode(n_packet)) or n_packet) or nil,
|
||||
delay = (type(n_delay) == "string" and string.find(n_delay, "-")) and n_delay or (n_delay and tonumber(n_delay))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
if server.finalmask and server.finalmask ~= "" then
|
||||
local ok, fm = pcall(json.parse, base64Decode(server.finalmask))
|
||||
if ok and type(fm) == "table" then
|
||||
@ -516,7 +577,7 @@ end
|
||||
return cleanEmptyTables(finalmask)
|
||||
end)(),
|
||||
sockopt = {
|
||||
mark = 250,
|
||||
mark = 255,
|
||||
tcpFastOpen = (function()
|
||||
if server.transport == "xhttp" then
|
||||
return (server.fast_open == "1") and true or false
|
||||
@ -545,27 +606,16 @@ end
|
||||
|
||||
-- 添加带有 fragment 设置的 dialerproxy 配置
|
||||
if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.enabled ~= "0") then
|
||||
local n_domainstrategy = xray_noise.domainStrategy
|
||||
table.insert(Xray.outbounds, {
|
||||
protocol = "freedom",
|
||||
tag = (remarks ~= nil and remarks ~= "") and (node_id .. "." .. remarks) or node_id,
|
||||
settings = {
|
||||
domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and xray_noise.domainStrategy,
|
||||
fragment = (xray_fragment.fragment == "1") and {
|
||||
packets = (xray_fragment.fragment_packets and xray_fragment.fragment_packets ~= "") and xray_fragment.fragment_packets or nil,
|
||||
length = (xray_fragment.fragment_length and xray_fragment.fragment_length ~= "") and xray_fragment.fragment_length or nil,
|
||||
interval = (xray_fragment.fragment_interval and xray_fragment.fragment_interval ~= "") and xray_fragment.fragment_interval or nil
|
||||
} or nil,
|
||||
noises = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and {
|
||||
{
|
||||
type = xray_noise.type,
|
||||
packet = xray_noise.packet,
|
||||
delay = xray_noise.delay:find("-") and xray_noise.delay or tonumber(xray_noise.delay)
|
||||
}
|
||||
} or nil
|
||||
domainStrategy = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and n_domainstrategy or nil
|
||||
},
|
||||
streamSettings = {
|
||||
sockopt = {
|
||||
mark = 250,
|
||||
mark = 255,
|
||||
tcpFastOpen = (function()
|
||||
if server.transport == "xhttp" then
|
||||
return (server.fast_open == "1") and true or false
|
||||
|
||||
@ -173,15 +173,18 @@ local function md5(content)
|
||||
-- assert(nixio.errno() == 0)
|
||||
return trim(stdout)
|
||||
end
|
||||
-- base64
|
||||
-- base64 解码
|
||||
local function base64Decode(text)
|
||||
local raw = text
|
||||
if not text then
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
end
|
||||
text = text:gsub("%z", "")
|
||||
text = text:gsub("%c", "")
|
||||
text = text:gsub("%s", "")
|
||||
text = text:gsub("_", "/")
|
||||
text = text:gsub("-", "+")
|
||||
text = text:gsub("=", "")
|
||||
local mod4 = #text % 4
|
||||
text = text .. string.sub('====', mod4 + 1)
|
||||
local result = b64decode(text)
|
||||
@ -191,20 +194,18 @@ local function base64Decode(text)
|
||||
return raw
|
||||
end
|
||||
end
|
||||
-- base64 编码
|
||||
local function base64Encode(text)
|
||||
if not text or text == "" then
|
||||
return ''
|
||||
end
|
||||
local result = b64encode(text)
|
||||
if result then
|
||||
result = result:gsub("%z", "")
|
||||
result = result:gsub("/", "_")
|
||||
result = result:gsub("+", "-")
|
||||
result = result:gsub("=", "")
|
||||
return result
|
||||
else
|
||||
return text
|
||||
end
|
||||
local result = b64encode(text)
|
||||
if result then
|
||||
result = result:gsub("%z", "")
|
||||
return result
|
||||
else
|
||||
return text
|
||||
end
|
||||
end
|
||||
-- 检查数组(table)中是否存在某个字符值
|
||||
-- https://www.04007.cn/article/135.html
|
||||
|
||||
24
luci-app-wizard/Makefile
Normal file
24
luci-app-wizard/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright (C) 2017-2019 Chen Minqiang <ptpt52@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI Support for wizard
|
||||
LUCI_DEPENDS:=
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-wizard
|
||||
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPLv3
|
||||
|
||||
define Package/luci-app-wizard/conffiles
|
||||
/etc/config/wizard
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
3
luci-app-wizard/README.md
Normal file
3
luci-app-wizard/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# luci-app-wizard
|
||||
|
||||
修改自 https://github.com/x-wrt/com.x-wrt/tree/master/luci-app-wizard
|
||||
@ -0,0 +1,160 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require dom';
|
||||
'require poll';
|
||||
'require uci';
|
||||
'require rpc';
|
||||
'require form';
|
||||
'require fs';
|
||||
|
||||
return view.extend({
|
||||
load: async function () {
|
||||
const promises = await Promise.all([
|
||||
fs.exec('/etc/init.d/wizard', ['reconfig']),
|
||||
uci.changes(),
|
||||
L.resolveDefault(uci.load('wireless')),
|
||||
uci.load('wizard'),
|
||||
L.resolveDefault(fs.stat('/www/luci-static/istorex/style.css'), null),
|
||||
L.resolveDefault(fs.stat('/www/luci-static/routerdog/style.css'), null),
|
||||
L.resolveDefault(fs.stat('/usr/sbin/nginx'), null)
|
||||
]);
|
||||
const data = {
|
||||
istorex: promises[4],
|
||||
routerdog: promises[5],
|
||||
nginx: promises[6]
|
||||
};
|
||||
return data;
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var m, s, o;
|
||||
var has_wifi = false;
|
||||
|
||||
if (uci.sections('wireless', 'wifi-device').length > 0) {
|
||||
has_wifi = true;
|
||||
}
|
||||
|
||||
m = new form.Map('wizard', [_('Initial Router Setup')],
|
||||
_('If you are using this router for the first time, please configure it here.'));
|
||||
|
||||
s = m.section(form.NamedSection, 'default', 'wizard');
|
||||
s.addremove = false;
|
||||
s.tab('netsetup', _('Net Settings'), _('Three different ways to access the Internet, please choose according to your own situation.'));
|
||||
|
||||
o = s.taboption('netsetup', form.ListValue, 'wan_proto', _('Protocol'));
|
||||
o.rmempty = false;
|
||||
o.value('dhcp', _('DHCP client'));
|
||||
o.value('pppoe', _('PPPoE'));
|
||||
|
||||
o = s.taboption('netsetup', form.Value, 'wan_pppoe_user', _('PAP/CHAP username'));
|
||||
o.depends('wan_proto', 'pppoe');
|
||||
|
||||
o = s.taboption('netsetup', form.Value, 'wan_pppoe_pass', _('PAP/CHAP password'));
|
||||
o.depends('wan_proto', 'pppoe');
|
||||
o.password = true;
|
||||
|
||||
o = s.taboption('netsetup', form.Value, 'lan_ipaddr', _('IPv4 address'));
|
||||
o.datatype = 'ip4addr';
|
||||
|
||||
o = s.taboption('netsetup', form.Value, 'lan_netmask', _('IPv4 netmask'));
|
||||
o.datatype = 'ip4addr';
|
||||
o.value('255.255.255.0');
|
||||
o.value('255.255.0.0');
|
||||
o.value('255.0.0.0');
|
||||
o.default = '255.255.255.0';
|
||||
|
||||
o = s.taboption('netsetup', form.DynamicList, 'lan_dns', _('Use custom DNS servers'), _('Leave empty to use ISP DNS'));
|
||||
o.datatype = 'ip4addr';
|
||||
o.cast = 'string';
|
||||
|
||||
o = s.taboption('netsetup', form.Flag, 'siderouter', _('Siderouter'),
|
||||
_('Use as downstream router i.e. it will work like a switch'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('netsetup', form.Value, 'lan_gateway', _('IPv4 gateway'));
|
||||
o.depends('siderouter', '1');
|
||||
o.datatype = 'ip4addr';
|
||||
o.placeholder = _('Enter the main router IP');
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('netsetup', form.Flag, 'dhcp', _('DHCP Server'),
|
||||
_('To turn on this DHCP, you need to turn off the DHCP of the main router, and to turn off this DHCP, you need to manually change the gateway and DNS of all Internet devices to the IP of this bypass router'));
|
||||
o.depends('siderouter', '1');
|
||||
o.default = o.enabled;
|
||||
|
||||
o = s.taboption('netsetup', form.Flag, 'ipv6', _('Enable IPv6'), _('Enable/Disable IPv6'));
|
||||
o.default = o.enabled;
|
||||
|
||||
s.tab('firmware', _('Firmware Settings'));
|
||||
|
||||
// o = s.taboption('firmware', form.Flag, 'autoupgrade_pkg', _('Packages Auto Upgrade'),_('谨慎开启'));
|
||||
// o.rmempty = false;
|
||||
|
||||
o = s.taboption('firmware', form.Flag, 'autoupgrade_fm', _('Firmware Upgrade Notice'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('firmware', form.Flag, 'coremark', _('CoreMark'), _('第一次开机后是否运行CPU跑分测试'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.taboption('firmware', form.Flag, 'cookie_p', _('Persistent cookies'),
|
||||
_('Keep the background login state to avoid the need to log in again every time the browser is closed'));
|
||||
o.default = o.enabled;
|
||||
|
||||
o = s.taboption('firmware', form.Flag, 'https', _('Force the use of HTTPS in the backend.'));
|
||||
|
||||
if (data.istorex || data.routerdog){
|
||||
o = s.taboption('firmware', form.ListValue, 'landing_page', _('主题模式'));
|
||||
o.value('default', _('默认'));
|
||||
if (data.routerdog){
|
||||
o.value('routerdog', _('路由狗(专业NAS模式)'));
|
||||
}
|
||||
if (data.istorex){
|
||||
o.value('nas', _('NAS模式'));
|
||||
o.value('next-nas', _('NEXT-NAS模式'));
|
||||
o.value('router', _('路由模式'));
|
||||
}
|
||||
o.default = 'default';
|
||||
}
|
||||
|
||||
if (has_wifi) {
|
||||
s.tab('wifisetup', _('Wireless Settings'), _('Set the router\'s wireless name and password. For more advanced settings, please go to the Network-Wireless page.'));
|
||||
o = s.taboption('wifisetup', form.Value, 'wifi_ssid', _('<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>'));
|
||||
o.datatype = 'maxlength(32)';
|
||||
|
||||
o = s.taboption("wifisetup", form.Value, "wifi_key", _("Key"));
|
||||
o.datatype = 'wpakey';
|
||||
o.password = true;
|
||||
}
|
||||
|
||||
if (data.nginx) {
|
||||
s.tab('shortcuts', _('Shortcuts'), _('比如设置google.com的快捷方式为字母g,则在此路由器网络的任何浏览器中输入g/即可访问google.com'));
|
||||
|
||||
o = s.taboption('shortcuts', form.SectionValue, 'shortcuts', form.GridSection, 'shortcuts', null,
|
||||
_('Shortcuts'));
|
||||
|
||||
s = o.subsection;
|
||||
s.addremove = true;
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Value, 'shortcut', _('Shortcut'));
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'to_url', _('Target URL'));
|
||||
o.rmempty = false;
|
||||
o.placeholder = 'https://example.com';
|
||||
o.validate = function(section_id, value) {
|
||||
if (value.match(/^https?:\/\/.+/i)) {
|
||||
return true;
|
||||
}
|
||||
return _('Please enter a valid URL starting with http:// or https://');
|
||||
};
|
||||
|
||||
o = s.option(form.Value, 'comments', _('Comments'));
|
||||
o.optional = true;
|
||||
}
|
||||
|
||||
setTimeout("document.getElementsByClassName('cbi-button-apply')[0].children[3].children[0].value='1'", 1000)
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
28
luci-app-wizard/luasrc/controller/wizard.lua
Normal file
28
luci-app-wizard/luasrc/controller/wizard.lua
Normal file
@ -0,0 +1,28 @@
|
||||
module("luci.controller.wizard", package.seeall)
|
||||
|
||||
local uci = luci.model.uci.cursor()
|
||||
local http = require "luci.http"
|
||||
|
||||
function index()
|
||||
entry({"admin", "index"}, call("landing_page"), _("Home") , 1).dependent = false
|
||||
end
|
||||
|
||||
function landing_page()
|
||||
local landing_page = uci:get("wizard", "default", "landing_page")
|
||||
if (luci.sys.call("pgrep routergo >/dev/null") == 0 and landing_page == "routerdog") then
|
||||
http.redirect(luci.dispatcher.build_url("admin","routerdog"));
|
||||
elseif luci.sys.call("pgrep quickstart >/dev/null") == 0 then
|
||||
if landing_page == "nas" then
|
||||
http.redirect(luci.dispatcher.build_url("admin","istorex","nas"));
|
||||
elseif landing_page == "next-nas" then
|
||||
http.redirect(luci.dispatcher.build_url("admin","istorex","next-nas"));
|
||||
elseif landing_page == "router" then
|
||||
http.redirect(luci.dispatcher.build_url("admin","istorex","router"));
|
||||
else
|
||||
http.redirect(luci.dispatcher.build_url("admin","quickstart"));
|
||||
end
|
||||
else
|
||||
http.redirect(luci.dispatcher.build_url("admin","status"))
|
||||
end
|
||||
|
||||
end
|
||||
44
luci-app-wizard/po/ru/wizard.po
Normal file
44
luci-app-wizard/po/ru/wizard.po
Normal file
@ -0,0 +1,44 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "Wizard"
|
||||
msgstr "Мастер настройки"
|
||||
|
||||
msgid "Initial Router Setup"
|
||||
msgstr "Мастер настройки маршрутизатора"
|
||||
|
||||
msgid "Net Settings"
|
||||
msgstr "Сетевые настройки"
|
||||
|
||||
msgid "Wireless Settings"
|
||||
msgstr "Настройки беспроводной связи"
|
||||
|
||||
msgid "If you are using this router for the first time, please configure it here."
|
||||
msgstr "Если вы используете этот маршрутизатор в первый раз, пожалуйста, просто настройте его здесь."
|
||||
|
||||
msgid "Three different ways to access the Internet, please choose according to your own situation."
|
||||
msgstr "Существует два различных способа серфинга в Интернете, пожалуйста, выбирайте в соответствии с вашей собственной ситуацией."
|
||||
|
||||
msgid "Set the router's wireless name and password. For more advanced settings, please go to the Network-Wireless page."
|
||||
msgstr "Задайте имя беспроводной сети и пароль маршрутизатора. для получения более подробных настроек, пожалуйста, перейдите на страницу Cеть-Беспроводная связь."
|
||||
|
||||
msgid "Siderouter"
|
||||
msgstr "Вторичный роутер"
|
||||
|
||||
msgid "Enable IPv6"
|
||||
msgstr "Включить IPv6"
|
||||
|
||||
msgid "Enable/Disable IPv6"
|
||||
msgstr "Включение/Отключение IPv6"
|
||||
|
||||
msgid "Firmware Settings"
|
||||
msgstr "Настройки встроенного ПО"
|
||||
|
||||
msgid "Packages Auto Upgrade"
|
||||
msgstr "Автоматическое обновление пакета"
|
||||
|
||||
msgid "Firmware Upgrade Notice"
|
||||
msgstr "Напоминание об обновлении прошивки"
|
||||
|
||||
msgid "Persistent cookies"
|
||||
msgstr "Постоянный вход в систему"
|
||||
1
luci-app-wizard/po/zh-cn
Symbolic link
1
luci-app-wizard/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
75
luci-app-wizard/po/zh_Hans/wizard.po
Normal file
75
luci-app-wizard/po/zh_Hans/wizard.po
Normal file
@ -0,0 +1,75 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "Wizard"
|
||||
msgstr "设置向导"
|
||||
|
||||
msgid "Initial Router Setup"
|
||||
msgstr "路由器设置向导"
|
||||
|
||||
msgid "Net Settings"
|
||||
msgstr "网络设置"
|
||||
|
||||
msgid "Wireless Settings"
|
||||
msgstr "无线设置"
|
||||
|
||||
msgid "If you are using this router for the first time, please configure it here."
|
||||
msgstr "如果你首次使用这个路由器,请在这里简单设置。"
|
||||
|
||||
msgid "Three different ways to access the Internet, please choose according to your own situation."
|
||||
msgstr "二种不同的上网方式,请您根据自身情况进行选择。"
|
||||
|
||||
msgid "Set the router's wireless name and password. For more advanced settings, please go to the Network-Wireless page."
|
||||
msgstr "设置路由器的无线名字和密码,更多高级设置请进入 网络-无线 页面。"
|
||||
|
||||
msgid "Leave empty to use ISP DNS"
|
||||
msgstr "留空则使用阿里DNS"
|
||||
|
||||
msgid "Enter the main router IP"
|
||||
msgstr "请输入主路由IP"
|
||||
|
||||
msgid "Siderouter"
|
||||
msgstr "旁路由模式"
|
||||
|
||||
msgid "To turn on this DHCP, you need to turn off the DHCP of the main router, and to turn off this DHCP, you need to manually change the gateway and DNS of all Internet devices to the IP of this bypass router"
|
||||
msgstr "开启此DHCP则需要关闭主路由的DHCP, 关闭此DHCP则需要手动将所有上网设备的网关和DNS改为此旁路由的IP"
|
||||
|
||||
msgid "Enable IPv6"
|
||||
msgstr "启用IPv6"
|
||||
|
||||
msgid "Enable/Disable IPv6"
|
||||
msgstr "一键开启/关闭 IPv6"
|
||||
|
||||
msgid "Firmware Settings"
|
||||
msgstr "固件设置"
|
||||
|
||||
msgid "Packages Auto Upgrade"
|
||||
msgstr "软件包自动更新"
|
||||
|
||||
msgid "Firmware Upgrade Notice"
|
||||
msgstr "固件更新提醒"
|
||||
|
||||
msgid "Persistent cookies"
|
||||
msgstr "持久化登录"
|
||||
|
||||
msgid "Keep the background login state to avoid the need to log in again every time the browser is closed"
|
||||
msgstr "保持后台登录状态,避免每次关闭浏览器后都需要重新登录"
|
||||
|
||||
msgid "Home"
|
||||
msgstr "首页"
|
||||
|
||||
msgid "Shortcuts"
|
||||
msgstr "快捷访问"
|
||||
|
||||
msgid "Shortcut"
|
||||
msgstr "快捷方式"
|
||||
|
||||
msgid "Target URL"
|
||||
msgstr "目标URL"
|
||||
|
||||
msgid "Please enter a valid URL starting with http:// or https://"
|
||||
msgstr "URL需以http:// 或 https://开头"
|
||||
|
||||
msgid "Force the use of HTTPS in the backend."
|
||||
msgstr "后台强制使用https"
|
||||
|
||||
1
luci-app-wizard/root/etc/config/wizard
Normal file
1
luci-app-wizard/root/etc/config/wizard
Normal file
@ -0,0 +1 @@
|
||||
config wizard 'default'
|
||||
263
luci-app-wizard/root/etc/init.d/wizard
Executable file
263
luci-app-wizard/root/etc/init.d/wizard
Executable file
@ -0,0 +1,263 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=19
|
||||
|
||||
extra_command "reconfig" ""
|
||||
|
||||
boot() {
|
||||
exit 0;
|
||||
}
|
||||
|
||||
add_wizard() {
|
||||
local cfg="$1"
|
||||
local wan_proto wan_pppoe_user wan_pppoe_pass
|
||||
local lan_ipaddr lan_netmask lan_dns lan_gateway dhcp
|
||||
local device ipv6 old_ipv6 wifi_ssid wifi_key old_wifi_ssid old_wifi_key
|
||||
|
||||
config_get wan_proto "$cfg" wan_proto
|
||||
|
||||
device=$(uci get network.wan.device 2>/dev/null)
|
||||
case "${wan_proto}" in
|
||||
dhcp)
|
||||
uci delete network.wan
|
||||
uci set network.wan=interface
|
||||
uci set network.wan.device="$device"
|
||||
uci set network.wan.proto='dhcp'
|
||||
;;
|
||||
pppoe)
|
||||
config_get wan_pppoe_user "$cfg" wan_pppoe_user
|
||||
config_get wan_pppoe_pass "$cfg" wan_pppoe_pass
|
||||
[[ "${wan_pppoe_user} != $(uci -q get network.wan.username)" || "${wan_pppoe_pass} != $(uci -q get network.wan.password)" ]] && {
|
||||
uci delete network.wan
|
||||
uci set network.wan=interface
|
||||
uci set network.wan.proto='pppoe'
|
||||
uci set network.wan.device="$device"
|
||||
uci set network.wan.username="${wan_pppoe_user}"
|
||||
uci set network.wan.password="${wan_pppoe_pass}"
|
||||
[ -n "${ipv6}" ] && {
|
||||
uci -q set network.wan.ipv6='0'
|
||||
uci -q set network.wan.delegate='0'
|
||||
}
|
||||
}
|
||||
;;
|
||||
esac
|
||||
|
||||
config_get lan_ipaddr "$cfg" lan_ipaddr
|
||||
config_get lan_netmask "$cfg" lan_netmask
|
||||
test -n "${lan_ipaddr}" && test -n "${lan_netmask}" && {
|
||||
uci set network.lan.ipaddr="${lan_ipaddr}"
|
||||
uci set network.lan.netmask="${lan_netmask}"
|
||||
}
|
||||
|
||||
config_get siderouter "$cfg" siderouter
|
||||
config_get old_siderouter "$cfg" old_siderouter
|
||||
config_get lan_gateway "$cfg" lan_gateway
|
||||
config_get dhcp "$cfg" dhcp
|
||||
config_get lan_dns "$cfg" lan_dns
|
||||
config_get ipv6 "$cfg" ipv6
|
||||
config_get old_ipv6 "$cfg" old_ipv6
|
||||
config_get autoupgrade_pkg "$cfg" autoupgrade_pkg
|
||||
|
||||
[ "$dhcp" == "0" ] && dhcp="1"
|
||||
if [[ "${lan_gateway}" != "$(uci -q get network.lan.gateway)" || "${dhcp}" != "$(uci -q get dhcp.lan.ignore)" ]]; then
|
||||
if [ "${siderouter}" == "1" ]; then
|
||||
uci -q set network.lan.gateway="${lan_gateway}"
|
||||
[ -n "$lan_dns" ] || lan_dns='223.5.5.5'
|
||||
[ -n "$dhcp" ] && uci -q set dhcp.lan.ignore="1" || uci -q del dhcp.lan.ignore
|
||||
uci -q set firewall.@zone[0].masq='1'
|
||||
uci -q set network.wan.proto='none'
|
||||
elif [ "${siderouter}" == "0" ]; then
|
||||
uci -q del network.lan.gateway
|
||||
uci -q del dhcp.lan.ignore
|
||||
uci -q del network.lan.dns
|
||||
uci -q del firewall.@zone[0].masq
|
||||
uci -q set network.wan.proto='dhcp'
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -n "$lan_dns" ] && {
|
||||
[ "$(uci -q get dhcp.@dnsmasq[0].noresolv)" == 1 ] && {
|
||||
uci -q del dhcp.@dnsmasq[0].noresolv
|
||||
}
|
||||
uci -q set network.wan.peerdns='0'
|
||||
uci -q set network.lan.dns="${lan_dns}"
|
||||
} || {
|
||||
uci -q del network.wan.peerdns
|
||||
uci -q del network.lan.dns
|
||||
}
|
||||
|
||||
if [ "${ipv6}" != "${old_ipv6}" ]; then
|
||||
if [ -n "${ipv6}" ]; then
|
||||
uci -q delete dhcp.lan.ra
|
||||
uci -q delete dhcp.lan.dhcpv6
|
||||
uci -q set network.lan.delegate='0'
|
||||
uci -q set network.wan.ipv6='0'
|
||||
uci -q set network.wan.delegate='0'
|
||||
uci -q delete network.globals.ula_prefix
|
||||
else
|
||||
uci -q set dhcp.lan.ra='hybrid'
|
||||
uci -q set dhcp.lan.dhcpv6='hybrid'
|
||||
uci -q del network.lan.delegate
|
||||
uci -q set network.wan.ipv6='auto'
|
||||
uci -q del network.wan.delegate
|
||||
fi
|
||||
uci -q set wizard.default.old_ipv6="${ipv6}"
|
||||
fi
|
||||
|
||||
wifi_setup_radio(){
|
||||
local radio=$1
|
||||
uci -q get wireless.${radio} >/dev/null 2>&1 && {
|
||||
if [ "$(uci -q get wireless.${radio}.band)" = "5g" ]; then
|
||||
uci -q set wireless.default_${radio}.ssid="${wifi_ssid}_5G"
|
||||
elif [ "$(uci -q get wireless.${radio}.band)" = "2g" ]; then
|
||||
uci -q set wireless.default_${radio}.ssid="${wifi_ssid}_2.4G"
|
||||
fi
|
||||
uci -q set wireless.default_${radio}.device="${radio}"
|
||||
if [ "${wifi_key}" ]; then
|
||||
uci -q set wireless.default_${radio}.encryption='psk2'
|
||||
uci -q set wireless.default_${radio}.key="${wifi_key}"
|
||||
else
|
||||
uci -q set wireless.default_${radio}.encryption='none'
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
config_get wifi_ssid "$cfg" wifi_ssid
|
||||
config_get wifi_key "$cfg" wifi_key
|
||||
config_get old_wifi_ssid "$cfg" old_wifi_ssid
|
||||
config_get old_wifi_key "$cfg" old_wifi_key
|
||||
|
||||
if [[ "${wifi_ssid}" != "${old_wifi_ssid}" || "${wifi_key}" != "${old_wifi_key}" ]]; then
|
||||
test -n "${wifi_ssid}" && {
|
||||
for radio in radio0 radio1 radio2 radio3; do
|
||||
wifi_setup_radio ${radio}
|
||||
done
|
||||
uci commit wireless
|
||||
uci -q set wizard.default.old_wifi_ssid="${wifi_ssid}"
|
||||
uci -q set wizard.default.old_wifi_key="${wifi_key}"
|
||||
}
|
||||
fi
|
||||
|
||||
sethttps
|
||||
|
||||
uci commit wizard
|
||||
uci commit dhcp
|
||||
uci commit firewall
|
||||
uci commit network
|
||||
|
||||
if [ "${autoupgrade_pkg}" != "1" ]; then
|
||||
sed -i '/opkg-upgrade/d' /etc/crontabs/root
|
||||
else
|
||||
grep -q "opkg-upgrade" /etc/crontabs/root || {
|
||||
hour="$(grep -m1 -ao '[4-6]' /dev/urandom | head -n1)"
|
||||
min="$(grep -m1 -ao '[0-5][0-9]' /dev/urandom | head -n1)"
|
||||
echo "$min $hour * * * . /etc/hotplug.d/online/51-opkg-upgrade >/dev/null 2>&1" >> /etc/crontabs/root
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
reconfig() {
|
||||
uci -q set wizard.default.wan_proto="$(uci -q get network.wan.proto)"
|
||||
uci -q set wizard.default.wan_pppoe_user="$(uci -q get network.wan.username)"
|
||||
uci -q set wizard.default.wan_pppoe_pass="$(uci -q get network.wan.password)"
|
||||
uci -q set wizard.default.lan_ipaddr="$(uci -q get network.lan.ipaddr)"
|
||||
uci -q set wizard.default.lan_netmask="$(uci -q get network.lan.netmask)"
|
||||
uci -q set wizard.default.lan_gateway="$(uci -q get network.lan.gateway)"
|
||||
uci -q set wizard.default.lan_dns="$(uci -q get network.lan.dns)"
|
||||
[ "$(uci -q get dhcp.lan.ignore)" ] && uci -q set wizard.default.dhcp="0" || uci -q del wizard.default.dhcp
|
||||
uci commit wizard
|
||||
}
|
||||
|
||||
sethttps() {
|
||||
config_get https "$cfg" https
|
||||
if [ -n "$(command -v nginx)" ]; then
|
||||
if [ -z "`uci -q get nginx._redirect2ssl`" ]; then
|
||||
uci -q set nginx._redirect2ssl=server
|
||||
uci -q set nginx._redirect2ssl.server_name='_redirect2ssl'
|
||||
uci -q set nginx._redirect2ssl.return='302 https://$host$request_uri'
|
||||
uci -q set nginx._redirect2ssl.access_log='off; # logd openwrt'
|
||||
fi
|
||||
if [ "x${https}" = "x1" ] ; then
|
||||
uci -q del nginx.default_server.listen
|
||||
uci -q add_list nginx.default_server.listen='80'
|
||||
uci -q add_list nginx.default_server.listen='[::]:80'
|
||||
uci -q del nginx._redirect2ssl.listen
|
||||
uci -q add_list nginx._redirect2ssl.listen='80 default_server'
|
||||
uci -q add_list nginx._redirect2ssl.listen='[::]:80 default_server'
|
||||
else
|
||||
uci -q del nginx._redirect2ssl.listen
|
||||
uci -q add_list nginx._redirect2ssl.listen='80'
|
||||
uci -q add_list nginx._redirect2ssl.listen='[::]:80'
|
||||
uci -q del nginx.default_server.listen
|
||||
uci -q add_list nginx.default_server.listen='80 default_server'
|
||||
uci -q add_list nginx.default_server.listen='[::]:80 default_server'
|
||||
fi
|
||||
uci commit nginx
|
||||
/etc/init.d/nginx reload
|
||||
elif [ -n "$(command -v lighttpd)" ]; then
|
||||
if [ "x${https}" = "x1" ] ; then
|
||||
sed -i "s/ # url.redirect =/ url.redirect =/" /etc/lighttpd/conf.d/82-https.conf
|
||||
else
|
||||
sed -i "s/ url.redirect =/ # url.redirect =/" /etc/lighttpd/conf.d/82-https.conf
|
||||
fi
|
||||
/etc/init.d/lighttpd reload
|
||||
else
|
||||
if [ "x${https}" = "x1" ] ; then
|
||||
uci -q set uhttpd.main.redirect_https='1'
|
||||
else
|
||||
uci -q set uhttpd.main.redirect_https='0'
|
||||
fi
|
||||
uci commit uhttpd
|
||||
/etc/init.d/uhttpd reload
|
||||
fi
|
||||
}
|
||||
|
||||
process_shortcut() {
|
||||
local shortcut to_url comments lanaddr
|
||||
local cfg="$1"
|
||||
lanaddr="$(uci get network.lan.ipaddr)"
|
||||
[ -n $lanaddr ] && lanaddr="$(echo "$lanaddr" | sed -e "s/\/2\+//")"
|
||||
|
||||
config_get shortcut "$cfg" shortcut
|
||||
config_get to_url "$cfg" to_url
|
||||
config_get comments "$cfg" comments
|
||||
|
||||
uci -q set nginx._sc_$shortcut=server
|
||||
uci -q set nginx._sc_$shortcut.server_name="$shortcut"
|
||||
uci -q add_list nginx._sc_$shortcut.listen="80"
|
||||
uci -q add_list nginx._sc_$shortcut.listen="443"
|
||||
uci -q set nginx._sc_$shortcut.return="302 $to_url"
|
||||
|
||||
uci -q set dhcp._sc_$shortcut=domain
|
||||
uci -q set dhcp._sc_$shortcut.name="$shortcut"
|
||||
uci -q set dhcp._sc_$shortcut.ip="$lanaddr"
|
||||
uci -q set dhcp._sc_$shortcut.comments="$comments"
|
||||
}
|
||||
|
||||
start() {
|
||||
config_load wizard
|
||||
config_foreach add_wizard wizard
|
||||
if [ -n "$(command -v nginx)" ]; then
|
||||
for server in $(uci show nginx | grep '_sc_' | grep '=server' | cut -d. -f2 | cut -d= -f1); do
|
||||
uci delete nginx.$server
|
||||
done
|
||||
for server in $(uci show dhcp | grep '_sc_' | grep '=domain' | cut -d. -f2 | cut -d= -f1); do
|
||||
uci delete dhcp.$server
|
||||
done
|
||||
config_foreach process_shortcut shortcuts
|
||||
uci commit nginx
|
||||
uci commit dhcp
|
||||
/etc/init.d/nginx reload
|
||||
fi
|
||||
(
|
||||
/etc/init.d/network restart
|
||||
/etc/init.d/firewall reload
|
||||
/etc/init.d/dnsmasq reload
|
||||
|
||||
)&
|
||||
}
|
||||
|
||||
restart() {
|
||||
start
|
||||
}
|
||||
23
luci-app-wizard/root/etc/uci-defaults/40-luci-wizard
Normal file
23
luci-app-wizard/root/etc/uci-defaults/40-luci-wizard
Normal file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
[ ! -f "/usr/share/ucitrack/luci-app-wizard.json" ] && {
|
||||
cat > /usr/share/ucitrack/luci-app-wizard.json << EEOF
|
||||
{
|
||||
"config": "wizard",
|
||||
"init": "wizard"
|
||||
}
|
||||
EEOF
|
||||
}
|
||||
|
||||
touch /etc/config/wizard
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@wizard[-1]
|
||||
add ucitrack wizard
|
||||
set ucitrack.@wizard[-1].init=wizard
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
chmod +x /etc/init.d/wizard 2>/dev/null
|
||||
rm -f /tmp/luci-indexcache
|
||||
|
||||
exit 0
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"admin/system/initsetup": {
|
||||
"title": "Wizard",
|
||||
"order": 1,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "wizard/initsetup"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-wizard" ],
|
||||
"uci": { "wizard": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"luci-app-wizard": {
|
||||
"description": "Grant UCI access for luci-app-wizard",
|
||||
"read": {
|
||||
"file": {
|
||||
"/etc/init.d/wizard reconfig": [ "exec" ]
|
||||
},
|
||||
"uci": [ "wizard", "wireless" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "wizard" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"config": "wizard",
|
||||
"init": "wizard"
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user