mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-04 02:23:56 +08:00
update 2026-10-27 11:22:48
This commit is contained in:
1 parent
a4d6470641
commit
63a5dffe55
4907 files changed
+2036791
No files matched your search
@@ -0,0 +1,189 @@
|
||||
# 模板用户名为 admin 密码为 admin
|
||||
# The username is admin and the password is admin.
|
||||
# 保存并应用就可以直接用的配置模板文件
|
||||
# a template config can be use with a apply
|
||||
http:
|
||||
pprof:
|
||||
port: 6060
|
||||
enabled: false
|
||||
address: 0.0.0.0:3000
|
||||
session_ttl: 720h
|
||||
users:
|
||||
- name: admin
|
||||
password: $2y$10$iGkTW98QtGEZn4I/GC0J4eQhfuLQ53v7L4DDVauEJyWylJrXWwWeO
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: ""
|
||||
theme: auto
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 3053
|
||||
anonymize_client_ip: false
|
||||
ratelimit: 20
|
||||
ratelimit_subnet_len_ipv4: 24
|
||||
ratelimit_subnet_len_ipv6: 56
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: true
|
||||
upstream_dns:
|
||||
- https://dns.cloudflare.com/dns-query
|
||||
- '#'
|
||||
- '# 对 ts.net 相关域名启用 DNS 分流, 交由 Tailscale 解析, 如不使用 Tailscale 可以删除.'
|
||||
- '# Enable DNS conditional forwarding for ts.net via Tailscale; remove if Tailscale is not used.'
|
||||
- '[/ts.net/]100.100.100.100'
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
fallback_dns:
|
||||
- quic://dns.adguard-dns.com
|
||||
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_enabled: true
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: false
|
||||
cache_optimistic_answer_ttl: 30s
|
||||
cache_optimistic_max_age: 12h
|
||||
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
|
||||
pending_requests:
|
||||
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
|
||||
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/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
|
||||
rewrites_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: 32
|
||||
@@ -0,0 +1,10 @@
|
||||
table inet adguardhome {
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
|
||||
__AGH_WAN_RETURN_LINE__
|
||||
|
||||
fib daddr type local udp dport 53 redirect to :__AGH_PORT__
|
||||
fib daddr type local tcp dport 53 redirect to :__AGH_PORT__
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/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 2>/dev/null)
|
||||
if [ "${watchdog}x" = "0x" ]; then
|
||||
kill "$pid"
|
||||
rm /tmp/AdGuardHometmp.log
|
||||
rm /var/run/AdGuardHomesyslog
|
||||
exit 0
|
||||
else
|
||||
echo "0" > /var/run/AdGuardHomesyslog
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,164 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
update_mode=$1
|
||||
|
||||
# Keep the lock file: unlinking it would allow a second lock on a new inode.
|
||||
exec 9>/var/lock/AdGuardHome-update.lock || exit 1
|
||||
# Allow a brief status probe to finish before treating the lock as busy.
|
||||
if ! flock -w 1 9; then
|
||||
printf '%s\n' '已经有更新任务正在运行,请等待其结束。'
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Only the lock owner may reset the log and update status.
|
||||
exec >/tmp/AdGuardHome_update.log 2>&1
|
||||
cleanup() {
|
||||
local result=$?
|
||||
trap - EXIT
|
||||
[ "$result" -ne 0 ] && touch /var/run/update_core_error
|
||||
rm -f /var/run/update_core
|
||||
exit "$result"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
trap 'exit 1' TERM INT HUP
|
||||
rm -f /var/run/update_core_error
|
||||
touch /var/run/update_core
|
||||
binpath=$(uci get AdGuardHome.AdGuardHome.binpath 2>/dev/null)
|
||||
if [ -z "$binpath" ]; then
|
||||
uci set AdGuardHome.AdGuardHome.binpath="/tmp/AdGuardHome/AdGuardHome"
|
||||
binpath="/tmp/AdGuardHome/AdGuardHome"
|
||||
fi
|
||||
[ ! -d "${binpath%/*}" ] && mkdir -p "${binpath%/*}"
|
||||
enabled=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null)
|
||||
core_api_url="https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest"
|
||||
|
||||
Check_Updates(){
|
||||
downloader_cmd="uclient-fetch"
|
||||
downloader_opts="-T 5 -q -O"
|
||||
downloader_quiet_opts="-q -O -"
|
||||
printf "%s\n" "开始检查更新, 请耐心等待 ..."
|
||||
Cloud_Version="$(${downloader_cmd} ${downloader_quiet_opts} "$core_api_url" 2>/dev/null | sed -n 's/.*"tag_name":[ ]*"\(v[^"]*\)".*/\1/p' | head -n 1)"
|
||||
[ -z "$Cloud_Version" ] && printf "\n检查更新失败, 请检查网络或稍后重试!\n" && EXIT 1
|
||||
if [ -f "$binpath" ]; then
|
||||
Current_Version="$($binpath --version 2>/dev/null | sed -n 's/.*\(v[0-9][0-9.]*\).*/\1/p' | head -n 1)"
|
||||
else
|
||||
Current_Version="未知"
|
||||
fi
|
||||
[ -z "$Current_Version" ] && Current_Version="未知"
|
||||
printf "\n执行文件路径: %s\n\n正在检查更新, 请耐心等待 ...\n" "${binpath%/*}"
|
||||
printf "\n当前 AdGuardHome 版本: %s\n云端 AdGuardHome 版本: %s\n" "$Current_Version" "$Cloud_Version"
|
||||
if [ "$Cloud_Version" != "$Current_Version" ] || [ "$1" = force ]; then
|
||||
Update_Core
|
||||
else
|
||||
printf "\n已是最新版本, 无需更新!\n"
|
||||
EXIT 0
|
||||
fi
|
||||
EXIT 0
|
||||
}
|
||||
|
||||
Update_Core(){
|
||||
rm -rf /tmp/AdGuardHome_Update > /dev/null 2>&1
|
||||
mkdir -p "/tmp/AdGuardHome_Update"
|
||||
GET_Arch
|
||||
link="https://github.com/AdguardTeam/AdGuardHome/releases/download/${Cloud_Version}/AdGuardHome_linux_${Arch}.tar.gz"
|
||||
printf "%s\n" "下载链接:${link}"
|
||||
printf "%s\n" "文件名称:${link##*/}"
|
||||
printf "\n开始下载 AdGuardHome 核心文件 ...\n\n"
|
||||
${downloader_cmd} ${downloader_opts} "/tmp/AdGuardHome_Update/${link##*/}" "$link" > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "\nAdGuardHome 核心下载失败,请检查网络、系统时间及 CA 证书 ...\n"
|
||||
rm -rf /tmp/AdGuardHome_Update
|
||||
EXIT 1
|
||||
fi
|
||||
if [ "${link##*.}" = "gz" ]; then
|
||||
printf "\n正在解压 AdGuardHome ...\n"
|
||||
tar -zxf "/tmp/AdGuardHome_Update/${link##*/}" -C "/tmp/AdGuardHome_Update/"
|
||||
if [ ! -e /tmp/AdGuardHome_Update/AdGuardHome ]
|
||||
then
|
||||
printf "%s\n" "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"
|
||||
size_bytes=$(wc -c < "$downloadbin" 2>/dev/null || echo 0)
|
||||
printf "\nAdGuardHome 核心体积: %s\n" "$(awk -v bytes="$size_bytes" 'BEGIN{printf "%.2fMB", bytes/1000000}')"
|
||||
/etc/init.d/AdGuardHome stop 9>&- > /dev/null 2>&1
|
||||
printf "\n移动 AdGuardHome 核心文件到 %s ...\n" "${binpath%/*}"
|
||||
if ! mv -f "$downloadbin" "$binpath" > /dev/null 2>&1 || [ ! -s "$binpath" ]; then
|
||||
printf "AdGuardHome 核心移动失败!\n可能是设备空间不足导致, 请尝试更改 [执行文件路径] 为 /tmp/AdGuardHome\n"
|
||||
EXIT 1
|
||||
fi
|
||||
rm -rf /tmp/AdGuardHome_Update
|
||||
chmod +x "$binpath"
|
||||
if [ "$enabled" = 1 ]; then
|
||||
printf "\n正在重启 AdGuardHome 服务...\n"
|
||||
/etc/init.d/AdGuardHome restart 9>&- > /dev/null 2>&1
|
||||
fi
|
||||
printf "\nAdGuardHome 核心更新成功!\n"
|
||||
}
|
||||
|
||||
GET_Arch() {
|
||||
if command -v apk > /dev/null 2>&1; then
|
||||
PM="apk"
|
||||
elif command -v opkg > /dev/null 2>&1; then
|
||||
PM="opkg"
|
||||
else
|
||||
printf "%s\n" "未找到包管理器 (apk/opkg)!" && EXIT 1
|
||||
fi
|
||||
case "${PM}" in
|
||||
apk)
|
||||
Archt="$(apk info -a kernel 2>/dev/null | grep Architecture | awk -F ":[ ]*" '{print $2}')"
|
||||
[ -z "$Archt" ] && Archt="$(uname -m)"
|
||||
;;
|
||||
opkg)
|
||||
Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')"
|
||||
;;
|
||||
esac
|
||||
case "${Archt}" in
|
||||
i386)
|
||||
Arch=i386
|
||||
;;
|
||||
i686)
|
||||
Arch=i386
|
||||
;;
|
||||
x86|x86_64)
|
||||
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
|
||||
;;
|
||||
*)
|
||||
printf "\nAdGuardHome 暂不支持当前的设备架构: [%s]!\n" "$Archt"
|
||||
EXIT 1
|
||||
esac
|
||||
printf "\n当前设备架构: %s\n" "$Arch"
|
||||
}
|
||||
|
||||
EXIT(){
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
Check_Updates "$update_mode"
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/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
|
||||
exit 0
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"admin/services/AdGuardHome": {
|
||||
"title": "AdGuard Home",
|
||||
"order": 12,
|
||||
"action": {
|
||||
"type": "firstchild"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-adguardhome" ]
|
||||
}
|
||||
},
|
||||
"admin/services/AdGuardHome/base": {
|
||||
"title": "Base Setting",
|
||||
"order": 1,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/base"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-adguardhome" ]
|
||||
}
|
||||
},
|
||||
"admin/services/AdGuardHome/log": {
|
||||
"title": "Log",
|
||||
"order": 3,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/log"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-adguardhome" ]
|
||||
}
|
||||
},
|
||||
"admin/services/AdGuardHome/manual": {
|
||||
"title": "Manual Config",
|
||||
"order": 2,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "adguardhome/manual"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-app-adguardhome" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"luci-app-adguardhome": {
|
||||
"description": "Grant UCI access for luci-app-adguardhome",
|
||||
"read": {
|
||||
"file": {
|
||||
"/var/run/AdGredir": [ "read" ]
|
||||
},
|
||||
"ubus": {
|
||||
"service": [ "list" ],
|
||||
"luci.adguardhome": [ "getCoreInfo", "getRedirectStatus", "getCoreUpdate", "getInterfaces", "getRuntimeLog", "getManualConfig" ]
|
||||
},
|
||||
"uci": [ "AdGuardHome" ]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.adguardhome": [ "setVerboseLog", "startCoreUpdate", "changeWebPassword", "clearRuntimeLog", "setManualConfig" ]
|
||||
},
|
||||
"uci": [ "AdGuardHome" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
#!/usr/bin/ucode
|
||||
'use strict';
|
||||
|
||||
import { stat, open, popen, readfile, writefile, unlink, lsdir } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
|
||||
function shellQuote(value) {
|
||||
return "'" + replace(value, /'/g, "'\\''") + "'";
|
||||
}
|
||||
|
||||
function coreUpdateRunning() {
|
||||
// The kernel releases the lock even if the updater is killed.
|
||||
const result = system(['/usr/bin/flock', '-n', '-E', '2',
|
||||
'/var/lock/AdGuardHome-update.lock', '/bin/true'], 3000);
|
||||
if (result != 0 && result != 2)
|
||||
die('Unable to check core update lock');
|
||||
return result == 2;
|
||||
}
|
||||
|
||||
return {
|
||||
'luci.adguardhome': {
|
||||
getRedirectStatus: {
|
||||
call: function() {
|
||||
const conf = cursor();
|
||||
function option(name, fallback) {
|
||||
const value = conf.get('AdGuardHome', 'AdGuardHome', name);
|
||||
return (type(value) == 'array' ? value[0] : value) || fallback;
|
||||
}
|
||||
const result = {
|
||||
mode: option('redirect', 'none'),
|
||||
enabled: option('enabled', '0') == '1',
|
||||
applied_mode: option('old_redirect', 'none'),
|
||||
applied_enabled: option('old_enabled', '0') == '1',
|
||||
binpath: option('binpath', '/usr/bin/AdGuardHome/AdGuardHome'),
|
||||
redirected: trim(readfile('/var/run/AdGredir') || '') == '1'
|
||||
};
|
||||
conf.unload('AdGuardHome');
|
||||
const lock = system(['/usr/bin/flock', '-n', '-E', '2',
|
||||
'/var/lock/AdGuardHome-redirect.lock', '/bin/true'], 3000);
|
||||
if (lock != 0 && lock != 2)
|
||||
die('Unable to check redirect status');
|
||||
result.busy = lock == 2;
|
||||
return result;
|
||||
}
|
||||
},
|
||||
getManualConfig: {
|
||||
call: function() {
|
||||
const conf = cursor();
|
||||
const configpath = conf.get('AdGuardHome', 'AdGuardHome', 'configpath') ||
|
||||
'/etc/AdGuardHome.yaml';
|
||||
conf.unload('AdGuardHome');
|
||||
|
||||
const template = readfile('/usr/share/AdGuardHome/AdGuardHome_template.yaml') || '';
|
||||
const current = readfile(configpath);
|
||||
if (current != null)
|
||||
return { content: current, template: template, source: 'current' };
|
||||
if (stat(configpath) != null)
|
||||
return { content: '', template: template, source: 'error' };
|
||||
return {
|
||||
content: template,
|
||||
template: template,
|
||||
source: template ? 'template' : 'missing'
|
||||
};
|
||||
}
|
||||
},
|
||||
setManualConfig: {
|
||||
args: { content: '' },
|
||||
call: function(request) {
|
||||
const content = request.args.content;
|
||||
if (content == null)
|
||||
return { saved: false, reason: 'invalid_content' };
|
||||
|
||||
const conf = cursor();
|
||||
const configpath = conf.get('AdGuardHome', 'AdGuardHome', 'configpath') ||
|
||||
'/etc/AdGuardHome.yaml';
|
||||
const binpath = conf.get('AdGuardHome', 'AdGuardHome', 'binpath') ||
|
||||
'/usr/bin/AdGuardHome/AdGuardHome';
|
||||
conf.unload('AdGuardHome');
|
||||
|
||||
const temporaryConfig = '/tmp/AdGuardHometmpconfig.yaml';
|
||||
const validationLog = '/tmp/AdGuardHometest.log';
|
||||
if (writefile(temporaryConfig, replace(content, /\r\n/g, '\n')) == null)
|
||||
return { saved: false, reason: 'write_failed' };
|
||||
|
||||
if (stat(binpath)?.type == 'file') {
|
||||
const valid = system(['/bin/sh', '-c', '"$1" -c "$2" --check-config > "$3" 2>&1',
|
||||
'sh', binpath, temporaryConfig, validationLog], 30000) == 0;
|
||||
if (!valid)
|
||||
return { saved: false, reason: 'validation_failed', log: readfile(validationLog) || '' };
|
||||
}
|
||||
|
||||
if (writefile(configpath, readfile(temporaryConfig) || '') == null)
|
||||
return { saved: false, reason: 'save_failed' };
|
||||
unlink(temporaryConfig);
|
||||
if (system(['/etc/init.d/AdGuardHome', 'reload'], 30000) != 0)
|
||||
return { saved: false, reason: 'reload_failed' };
|
||||
return { saved: true };
|
||||
}
|
||||
},
|
||||
getInterfaces: {
|
||||
call: function() {
|
||||
return { interfaces: lsdir('/sys/class/net') || [] };
|
||||
}
|
||||
},
|
||||
getCoreInfo: {
|
||||
call: function() {
|
||||
const conf = cursor();
|
||||
const binpath = conf.get('AdGuardHome', 'AdGuardHome', 'binpath') ||
|
||||
'/usr/bin/AdGuardHome/AdGuardHome';
|
||||
const configpath = conf.get('AdGuardHome', 'AdGuardHome', 'configpath') ||
|
||||
'/etc/AdGuardHome.yaml';
|
||||
const result = {
|
||||
core_exists: stat(binpath)?.type == 'file',
|
||||
config_exists: stat(configpath)?.type == 'file',
|
||||
version: null
|
||||
};
|
||||
|
||||
if (result.core_exists) {
|
||||
// Pass the configured path as a positional argument; capture both output streams.
|
||||
const proc = popen('/bin/sh -c \'"$1" --version 2>&1\' sh ' + shellQuote(binpath), 'r');
|
||||
if (proc) {
|
||||
const output = proc.read('all') || '';
|
||||
proc.close();
|
||||
result.version = match(output, /version ([^, \t\r\n]+)/)?.[1] || null;
|
||||
}
|
||||
}
|
||||
|
||||
conf.unload('AdGuardHome');
|
||||
return result;
|
||||
}
|
||||
},
|
||||
getCoreUpdate: {
|
||||
call: function() {
|
||||
const running = coreUpdateRunning();
|
||||
const failed = stat('/var/run/update_core_error') != null ||
|
||||
(!running && stat('/var/run/update_core') != null);
|
||||
const log = readfile('/tmp/AdGuardHome_update.log', 131072) || '';
|
||||
|
||||
return {
|
||||
state: running ? 'running' : failed ? 'failure' : log ? 'finished' : 'idle',
|
||||
log: log
|
||||
};
|
||||
}
|
||||
},
|
||||
startCoreUpdate: {
|
||||
args: { force: false },
|
||||
call: function(request) {
|
||||
if (coreUpdateRunning())
|
||||
return { started: false, reason: 'busy' };
|
||||
|
||||
const command = request.args.force
|
||||
? '/bin/sh /usr/share/AdGuardHome/update_core.sh force >/dev/null 2>&1 </dev/null &'
|
||||
: '/bin/sh /usr/share/AdGuardHome/update_core.sh >/dev/null 2>&1 </dev/null &';
|
||||
|
||||
return { started: system(['/bin/sh', '-c', command], 3000) == 0 };
|
||||
}
|
||||
},
|
||||
changeWebPassword: {
|
||||
args: { hash: '' },
|
||||
call: function(request) {
|
||||
const hash = request.args.hash;
|
||||
if (!match(hash, /^\$2[aby]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{53}$/))
|
||||
return { changed: false, reason: 'invalid_hash' };
|
||||
|
||||
const conf = cursor();
|
||||
const configpath = conf.get('AdGuardHome', 'AdGuardHome', 'configpath') ||
|
||||
'/etc/AdGuardHome.yaml';
|
||||
if (stat(configpath)?.type != 'file')
|
||||
return { changed: false, reason: 'no_config' };
|
||||
|
||||
if (!conf.set('AdGuardHome', 'AdGuardHome', 'hashpass', hash) ||
|
||||
!conf.commit('AdGuardHome'))
|
||||
return { changed: false, reason: 'save_failed' };
|
||||
conf.unload('AdGuardHome');
|
||||
|
||||
if (system(['/etc/init.d/AdGuardHome', 'reload'], 30000) != 0)
|
||||
return { changed: false, reason: 'reload_failed' };
|
||||
|
||||
if (index(readfile(configpath) || '', hash) < 0)
|
||||
return { changed: false, reason: 'verify_failed' };
|
||||
return { changed: true };
|
||||
}
|
||||
},
|
||||
setVerboseLog: {
|
||||
args: { enabled: false },
|
||||
call: function(request) {
|
||||
const conf = cursor();
|
||||
if (!conf.set('AdGuardHome', 'AdGuardHome', 'verbose', request.args.enabled ? '1' : '0') ||
|
||||
!conf.commit('AdGuardHome'))
|
||||
return { saved: false, applied: false };
|
||||
conf.unload('AdGuardHome');
|
||||
return {
|
||||
saved: true,
|
||||
applied: system(['/etc/init.d/AdGuardHome', 'reload'], 30000) == 0
|
||||
};
|
||||
}
|
||||
},
|
||||
getRuntimeLog: {
|
||||
args: { offset: 0, identity: '' },
|
||||
call: function(request) {
|
||||
const conf = cursor();
|
||||
const logfile = conf.get('AdGuardHome', 'AdGuardHome', 'logfile') || '';
|
||||
conf.unload('AdGuardHome');
|
||||
if (!logfile)
|
||||
return { enabled: false, localtime: false, content: '', offset: 0 };
|
||||
|
||||
let source = logfile;
|
||||
if (logfile == 'syslog') {
|
||||
source = '/tmp/AdGuardHometmp.log';
|
||||
writefile('/var/run/AdGuardHomesyslog', '1');
|
||||
if (stat(source)?.type != 'file')
|
||||
system(['/bin/sh', '-c', '/bin/sh /usr/share/AdGuardHome/getsyslog.sh >/dev/null 2>&1 &'], 3000);
|
||||
}
|
||||
|
||||
// Bound memory and start with the most recent 256 KiB on a new view.
|
||||
const limit = 262144;
|
||||
const info = stat(source);
|
||||
const identity = info ? source + ':' + info.dev.major + ':' + info.dev.minor + ':' + info.inode : '';
|
||||
let offset = int(request.args.offset) || 0;
|
||||
let reset = request.args.identity != identity || offset < 0 || offset > (info?.size || 0);
|
||||
if (reset)
|
||||
offset = 0;
|
||||
if (info && info.size - offset > limit) {
|
||||
offset = info.size - limit;
|
||||
reset = true;
|
||||
}
|
||||
|
||||
let content = '';
|
||||
if (info?.type == 'file') {
|
||||
const file = open(source, 'r');
|
||||
if (!file)
|
||||
die('Unable to open runtime log');
|
||||
const positioned = file.seek(offset);
|
||||
const chunk = positioned ? file.read(limit) : null;
|
||||
file.close();
|
||||
if (chunk == null)
|
||||
die('Unable to read runtime log');
|
||||
content = chunk;
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: true,
|
||||
localtime: logfile != 'syslog',
|
||||
// ubus strings stop at NUL; cleared files can contain sparse zero-filled gaps.
|
||||
content_b64: b64enc(content),
|
||||
offset: offset + length(content),
|
||||
identity: identity,
|
||||
reset: reset
|
||||
};
|
||||
}
|
||||
},
|
||||
clearRuntimeLog: {
|
||||
call: function() {
|
||||
const conf = cursor();
|
||||
const logfile = conf.get('AdGuardHome', 'AdGuardHome', 'logfile') || '';
|
||||
conf.unload('AdGuardHome');
|
||||
if (!logfile)
|
||||
return { cleared: false, reason: 'no_logfile' };
|
||||
|
||||
const source = logfile == 'syslog' ? '/tmp/AdGuardHometmp.log' : logfile;
|
||||
return { cleared: writefile(source, '') != null };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user