├── .DS_Store ├── .gitattributes ├── .github ├── .DS_Store ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Bug反馈.md │ ├── Feature_request.md │ └── 新功能请求.md └── workflows │ └── compile_new_ipk.yml ├── .gitignore ├── .images ├── 71361626-81d60900-25ce-11ea-91d5-ac4e35d5c41e.png ├── 71361650-90242500-25ce-11ea-9727-9306a3da1357.png ├── 71361700-b944b580-25ce-11ea-8562-f68c28952b2b.png └── 71361704-bb0e7900-25ce-11ea-8042-6dd396607030.png ├── AdGuardHome └── Makefile ├── README.md └── luci-app-adguardhome ├── .DS_Store ├── Makefile ├── luasrc ├── .DS_Store ├── controller │ └── AdGuardHome.lua ├── model │ └── cbi │ │ └── AdGuardHome │ │ ├── base.lua │ │ ├── log.lua │ │ └── manual.lua └── view │ └── AdGuardHome │ ├── AdGuardHome_check.htm │ ├── AdGuardHome_chpass.htm │ ├── AdGuardHome_status.htm │ ├── log.htm │ └── yamleditor.htm ├── po └── zh-cn │ └── AdGuardHome.po └── root ├── .DS_Store ├── etc ├── config │ └── AdGuardHome ├── init.d │ └── AdGuardHome └── uci-defaults │ └── 40_luci-AdGuardHome ├── usr └── share │ └── AdGuardHome │ ├── AdGuardHome_template.yaml │ ├── addhost.sh │ ├── firewall.start │ ├── getsyslog.sh │ ├── gfw2adg.sh │ ├── links.txt │ ├── tailto.sh │ ├── update_core.sh │ ├── waitnet.sh │ └── watchconfig.sh └── www └── luci-static └── resources ├── codemirror ├── addon │ └── fold │ │ ├── foldcode.js │ │ ├── foldgutter.css │ │ ├── foldgutter.js │ │ └── indent-fold.js ├── lib │ ├── codemirror.css │ └── codemirror.js ├── mode │ └── yaml │ │ └── yaml.js └── theme │ └── dracula.css └── twin-bcrypt.min.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.github/.DS_Store -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report to help me improve AdGuard Home luci 4 | 5 | --- 6 | 7 | ### Prerequisites 8 | 9 | Please answer the following questions for yourself before submitting an issue. **YOU MAY DELETE THE PREREQUISITES SECTION.** 10 | 11 | - [ ] I am running the latest version of luci-app-adguardhome 12 | - [ ] I checked to make sure that this issue has not already been filed 13 | 14 | ### Issue Details 15 | 16 | 17 | 18 | * **Version of AdGuard Home luci:** 19 | * 20 | * **Version of AdGuard Home server:** 21 | * 22 | * **Operating system and version:** 23 | * 24 | 25 | ### Expected Behavior 26 | 27 | 28 | ### Actual Behavior 29 | 30 | 31 | ### Screenshots 32 | 33 | 34 |
Screenshot: 35 | 36 | 37 | 38 |
39 | 40 | ### Additional Information 41 | 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug反馈.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 反馈 3 | about: 建立一个bug反馈帮助我完善luci-app-adguardhome 4 | 5 | --- 6 | 7 | ### 提交之前 8 | 9 | 在你提交问题之前请回答以下问题 10 | **你可以删掉提交之前这个部分** 11 | 12 | - [ ] 我用着最新版的 luci-app-adguardhome 13 | - [ ] 我检查了没有人提交同样的问题 14 | 15 | ### 问题详细信息 16 | 17 | 18 | 19 | * **AdGuard Home luci的版本:** 20 | * 21 | * **AdGuard Home server的版本:** 22 | * 23 | * **操作系统和版本:** 24 | * 25 | 26 | ### 希望的执行结果 27 | 28 | ### 实际的执行结果 29 | 30 | ### 日志(重要) 31 | 32 | 33 | ### 截图 34 | 35 | 36 |
截图: 37 | 38 | 39 | 40 |
41 | 42 | ### 更多的信息 43 | 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for AdGuard Home luci 4 | 5 | --- 6 | 7 | 8 | ### Prerequisites 9 | 10 | Please answer the following questions for yourself before submitting an issue. **YOU MAY DELETE THE PREREQUISITES SECTION.** 11 | 12 | - [ ] I am running the latest version 13 | - [ ] I checked to make sure that this issue has not already been filed 14 | 15 | ### Problem Description 16 | 17 | 18 | ### Proposed Solution 19 | 20 | 21 | ### Alternatives Considered 22 | 23 | 24 | ### Additional Information 25 | 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/新功能请求.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 新功能请求 3 | about: 给AdGuardHome luci 提供一个新的想法 4 | 5 | --- 6 | 7 | 8 | ### 提交之前 9 | 10 | 在你提交问题之前请回答以下问题 11 | **你可以删掉提交之前这个部分** 12 | 13 | - [ ] 我用着最新版的 luci-app-adguardhome 14 | - [ ] 我检查了没有人提交同样的问题 15 | 16 | ### 问题描述 17 | 18 | 19 | ### 新功能描述 20 | 21 | 22 | ### 你能想到的解决方法 23 | 24 | 25 | ### 更多的信息 26 | 27 | -------------------------------------------------------------------------------- /.github/workflows/compile_new_ipk.yml: -------------------------------------------------------------------------------- 1 | name: Compile The New Version Adguardhome 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - 'lluci-app-adguardhome/Makefile' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | Get-Version: 13 | runs-on: ubuntu-latest 14 | outputs: 15 | version: ${{ steps.version.outputs.version }} 16 | current_version: ${{ steps.current_version.outputs.version }} 17 | steps: 18 | - name: Clone Repository 19 | uses: actions/checkout@v3 20 | with: 21 | ref: ${{ github.ref_name }} 22 | 23 | - name: New Version 24 | id: version 25 | run: | 26 | echo "version=$(grep 'PKG_VERSION:=' ./luci-app-adguardhome/Makefile |awk -F '=' '{print $2}')" >> $GITHUB_OUTPUT 27 | echo "New Version: $(grep 'PKG_VERSION:=' ./luci-app-adguardhome/Makefile |awk -F '=' '{print $2}')" 28 | - name: Clone Repository 29 | uses: actions/checkout@v3 30 | with: 31 | ref: master 32 | 33 | - name: Current Version 34 | id: current_version 35 | run: | 36 | echo "version=$(sed -n 1p ./${{ github.ref_name }}/version |awk -F '-' '{print $1}' |awk -F 'v' '{print $2}')" >> $GITHUB_OUTPUT 37 | echo "Current Version: $(sed -n 1p ./${{ github.ref_name }}/version |awk -F '-' '{print $1}' |awk -F 'v' '{print $2}')" 38 | Compile: 39 | runs-on: ubuntu-latest 40 | needs: Get-Version 41 | if: ${{ needs.Get-Version.outputs.version != needs.Get-Version.outputs.current_version }} 42 | steps: 43 | - name: Clone OpenClash dev Repository 44 | uses: actions/checkout@v3 45 | with: 46 | ref: ${{ github.ref_name }} 47 | - name: Apt Update 48 | env: 49 | DEBIAN_FRONTEND: noninteractive 50 | run: | 51 | # sudo apt-get update 52 | sudo apt-get -y install curl git tar wget 53 | - name: Install OpenWrt SDK 54 | run: | 55 | cd .. 56 | mkdir tmp 57 | curl -SLk --connect-timeout 30 --retry 2 "https://archive.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-sdk-23.05.3-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz" -o "./tmp/SDK.tar.xz" 58 | cd \tmp 59 | tar xf SDK.tar.xz 60 | mv "openwrt-sdk-23.05.3-x86-64_gcc-12.3.0_musl.Linux-x86_64" "SDK" 61 | - name: Change Source Codes Version 62 | run: | 63 | echo "v${{ needs.Get-Version.outputs.version }}-beta" > ./version 64 | echo "https://img.shields.io/badge/New Release-v${{ needs.Get-Version.outputs.version }}--beta-orange.svg" >> ./version 65 | - name: Copy Source Codes 66 | run: | 67 | cd .. 68 | mkdir tmp/SDK/package/luci-app-adguardhome 69 | cp -rf "./luci-app-adguardhome/." "./tmp/SDK/package/luci-app-adguardhome/" 70 | - name: Compile IPK 71 | run: | 72 | cd .. 73 | cd tmp/SDK 74 | make package/luci-app-adguardhome/compile V=99 75 | - name: Commit and Push New Version 76 | run: | 77 | rm -rf ./luci-app-adguardhome_* 78 | cd .. 79 | cp "./tmp/SDK/bin/x86_64/packages/base/luci-app-adguardhome_${{ needs.Get-Version.outputs.version }}-beta_all.ipk" "./xiaoxiao29/luci-app-adguardhome_${{ needs.Get-Version.outputs.version }}-beta_all.ipk" 80 | cd \xiaoxiao29 81 | git config user.name 'github-actions[bot]' 82 | git config user.email 'github-actions[bot]@users.noreply.github.com' 83 | git add . 84 | git commit -m "Auto Release: v${{ needs.Get-Version.outputs.version }}-beta" 85 | git push 86 | - name: Switch Repository to Package 87 | uses: actions/checkout@v3 88 | with: 89 | ref: package 90 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.bak 3 | -------------------------------------------------------------------------------- /.images/71361626-81d60900-25ce-11ea-91d5-ac4e35d5c41e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.images/71361626-81d60900-25ce-11ea-91d5-ac4e35d5c41e.png -------------------------------------------------------------------------------- /.images/71361650-90242500-25ce-11ea-9727-9306a3da1357.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.images/71361650-90242500-25ce-11ea-9727-9306a3da1357.png -------------------------------------------------------------------------------- /.images/71361700-b944b580-25ce-11ea-8562-f68c28952b2b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.images/71361700-b944b580-25ce-11ea-8562-f68c28952b2b.png -------------------------------------------------------------------------------- /.images/71361704-bb0e7900-25ce-11ea-8042-6dd396607030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/.images/71361704-bb0e7900-25ce-11ea-8042-6dd396607030.png -------------------------------------------------------------------------------- /AdGuardHome/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015-2016 OpenWrt.org 3 | # This is free software, licensed under the GNU General Public License v2. 4 | # See /LICENSE.txt for more information. 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | PKG_NAME:=AdGuardHome 10 | PKG_VERSION:=0.107.61 11 | PKG_RELEASE:=1 12 | 13 | PKG_SOURCE_PROTO:=git 14 | PKG_SOURCE_VERSION:=v$(PKG_VERSION) 15 | PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome 16 | # sha256sum 17 | PKG_MIRROR_HASH:=8d957f5380d4c3bd09d719992cce7e82a020a543fb7ddcb0e3a35eabc7d0c53d 18 | 19 | PKG_LICENSE:=GPL-3.0-only 20 | PKG_LICENSE_FILES:=LICENSE.txt 21 | PKG_MAINTAINER:=Yang Feng 22 | 23 | PKG_BUILD_DEPENDS:=golang/host node/host 24 | PKG_BUILD_PARALLEL:=1 25 | PKG_USE_MIPS16:=0 26 | 27 | PKG_CONFIG_DEPENDS:= \ 28 | CONFIG_ADGUARDHOME_COMPRESS_GOPROXY \ 29 | CONFIG_ADGUARDHOME_COMPRESS_UPX 30 | 31 | GO_PKG:=github.com/AdguardTeam/AdGuardHome 32 | GO_PKG_EXCLUDES:=dhcpd/standalone 33 | GO_PKG_LDFLAGS:=-s -w 34 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) main.channel=release 35 | 36 | include $(INCLUDE_DIR)/package.mk 37 | include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk 38 | 39 | define Package/AdGuardHome 40 | SECTION:=net 41 | CATEGORY:=Network 42 | TITLE:=Network-wide ads and trackers blocking DNS server 43 | URL:=https://github.com/AdguardTeam/AdGuardHome 44 | DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle 45 | endef 46 | 47 | define Package/AdGuardHome/description 48 | Free and open source, powerful network-wide ads and trackers blocking DNS server. 49 | endef 50 | 51 | define Package/$(PKG_NAME)/config 52 | config ADGUARDHOME_COMPRESS_GOPROXY 53 | bool "Compiling with GOPROXY proxy" 54 | default n 55 | 56 | config ADGUARDHOME_COMPRESS_UPX 57 | bool "Compress executable files with UPX" 58 | default n 59 | endef 60 | 61 | ifeq ($(CONFIG_ADGUARDHOME_COMPRESS_GOPROXY),y) 62 | export GO111MODULE=on 63 | export GOPROXY=https://goproxy.io 64 | endif 65 | 66 | define Build/Compile 67 | ( \ 68 | cd $(PKG_BUILD_DIR) ; \ 69 | npm --prefix client ci ; \ 70 | npm --prefix client run build-prod ; \ 71 | GOOS=$$$$(go env GOOS) GOARCH=$$$$(go env GOARCH) GO111MODULE=off go get -v github.com/gobuffalo/packr/... ; \ 72 | "$$$$(go env GOPATH)/bin/packr" -v -z -i $(PKG_BUILD_DIR)/home ; \ 73 | $(call GoPackage/Build/Compile) ; \ 74 | ) 75 | 76 | ifeq ($(CONFIG_ADGUARDHOME_COMPRESS_UPX),y) 77 | $(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/AdGuardHome 78 | endif 79 | endef 80 | 81 | define Package/AdGuardHome/install 82 | $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) 83 | $(INSTALL_DIR) $(1)/etc/config/adGuardConfig 84 | $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/AdGuardHome $(1)/etc/config/adGuardConfig/AdGuardHome 85 | endef 86 | 87 | $(eval $(call GoBinPackage,AdGuardHome)) 88 | $(eval $(call BuildPackage,AdGuardHome)) 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # luci-app-adguardhome 2 | 复杂的AdGuardHome的openwrt的luci界面 3 | 4 | - 可以管理网页端口 5 | - luci下载/更新核心版本(支持自定义链接下载) 6 | - 如果为tar.gz文件需要与官方的文件结构一致 7 | - 或者直接为主程序二进制 8 | - upx 压缩核心(xz依赖,脚本自动下载,如果opkg源无法连接,请在编译时加入此包) 9 | - dns重定向 10 | - 作为dnsmasq的上游服务器(在AGH中统计到的ip都为127.0.0.1,无法统计客户端及对应调整设置,ssr-plus正常) 11 | - 重定向53端口到 AdGuardHome(ipv6需要开启ipv6 nat redirect 否则如果客户端使用ipv6过滤无效,不以dnsmasq为上游ssr-plus失效) 12 | - 使用53端口替换 dnsmasq(需要设置AGH的dnsip为0.0.0.0, AGH和dnsmasq的端口将被交换,不以dnsmasq为上游ssr-plus失效) 13 | - 自定义执行文件路径(支持tmp,每次重启后自动下载bin) 14 | - 自定义配置文件路径 15 | - 自定义工作路径 16 | - 自定义运行日志路径 17 | - gfwlist 删除/添加/定义上游dns服务器 另外安利一下https://github.com/rufengsuixing/luci-app-autoipsetadder 18 | - 修改网页登陆密码 19 | - 倒序/正序 查看/删除/备份 每3秒更新显示运行日志 + 本地浏览器时区转换 20 | - 手动修改配置文件 21 | - 支持yaml编辑器 22 | - 模板快速配置 23 | - 系统升级保留勾选文件 24 | - 开机启动后当网络准备好时重启adh(3分钟超时,主要用于防止过滤器更新失败) 25 | - 关机时备份勾选的工作目录中的文件(须知:在ipk更新的时候也会触发备份) 26 | - 计划任务(以下为默认值,时间和参数可以在计划任务中调整) 27 | - 自动更新核心(最好谨慎使用)(3:30/天) 28 | - 自动截短查询日志 (每小时 限制到2000行) 29 | - 自动截短运行日志(3:30/天 限制到2000行) 30 | - 自动更新ipv6主机并重启adh (每小时,无更新不重启) 31 | - 自动更新gfw列表并重启adh (3:30/天,无更新不重启) 32 | #### 已知问题: 33 | - db数据库不支持放在不支持mmap的文件系统上比如 jffs2 data-stk-oo,请修改工作目录,本软件如果检测到jffs2会自动ln(软连接)到/tmp,将会导致重启丢失dns数据库 34 | - AdGuardHome 不支持ipset 设置,在使用ipset的情况下,无法替代dnsmasq只能作为dnsmasq上游存在,如果你想要这个功能就去投票吧
35 | https://github.com/AdguardTeam/AdGuardHome/issues/1191 36 | - 反馈出现大量127.0.0.1查询了localhost的请求,问题出现原因是ddns插件,如果不用ddns插件,请删除或者注释掉\etc\hotplug.d\iface\95-ddns的内容,如果还有其他来自本机的异常查询情况,高级玩家可以使用kmod来查找原因https://github.com/rufengsuixing/kmod-plog-port 37 | - 如果出现需要多次提交才有反应的现象请及时提交issue 38 | #### 使用方法 39 | - 下载release,使用opkg安装即可 40 | - 或者编译op时clone本项目加入软件包并勾选 41 | #### 关于压缩 42 | 本着较真的想法,我测试了在jffs2的压缩文件系统上进行upx压缩结果的内存占用与空间占用(单位kb,使用最好压缩)
43 | 文件大小
44 | 源文件 14112 使用upx 压缩后 5309
45 | 实际占用 6260 使用upx 压缩后 5324 差值为 936
46 | VmRSS运存占用值
47 | 不压缩 14380 使用upx 压缩后 18496 差值 -4116
48 | 对于压缩文件系统来说开启收益有,但不大
49 | 如果是非压缩文件系统,性价比还是比较高的
50 | 所以压缩是用运存空间来换rom空间,觉得值得就可以开启 51 | #### 关于ssr配合 52 | - 方法一gfw代理:dns重定向-作为dnsmasq的上游服务器 53 | - 方法二gfw代理:手动设置adh上游dns为自己即127.0.0.1:[自己监听的端口],然后使用 dns重定向-使用53端口替换dnsmasq,(因为端口互换后就是dnsmasq为上游了) 54 | - 方法三国外ip代理:任意重定向方式,adh加入gfw列表,开启计划任务定时更新gfw即可 55 | - 方法四gfw代理:dns重定向-重定向53端口到AdGuardHome,设置adh上游dns 为127.0.0.1:53 56 | #### 项目已经基本稳定,有bug欢迎主动反馈 57 | 58 | Complex openwrt AdGuardHome luci 59 | 60 | - can manage browser port 61 | - download/update core in luci 62 | - compress core with upx 63 | - redirect dns 64 | - as the upstream of dnsmasq 65 | - redirect port 53 to AdGuardHome(ipv6 need to install ipv6 nat redirect or if client use ipv6 redirect is invalid) 66 | - replace dnsmasq with port 53 (need to set AGH,dnsip=0.0.0.0,the port of dnsmasq and AGH will be exchange) 67 | - change bin path 68 | - change config path 69 | - change work dir(support tmp,auto redownload after reboot) 70 | - change runtime log path 71 | - gfwlist query to specific dns server 72 | - modify browser login passord 73 | - Positive/reverse order see/del/backup runtime log which update every 3 second 74 | - modify config manually(support yaml editor) 75 | - use template to fast config(when no config file) 76 | - Keep bin file and config when system upgrade (database and querylog can be choose) 77 | - when boot wait for network access (3min timeout) 78 | - backup workdir when shutdown 79 | #### known issues: 80 | - db database not support filesystem which not support mmap such as jffs2 and data-stk-oo,please modify work dir,if jffs2 is found,will auto ln (soft link)the dbs to /tmp ,will lost dns database after reboot 81 | - AdGuardhome not support ipset,when we use ipset ,it can\`t be the repacement of dnsmasq but the upstream of dnsmasq ,if you want it,vote for it.
82 | https://github.com/AdguardTeam/AdGuardHome/issues/1191
83 | - find so many localhost query from 127.0.0.1,the ddns plugin is the reason,if you don\`t use ddns, please remove or comment \etc\hotplug.d\iface\95-ddns 84 | #### usage 85 | - download release,install it with opkg 86 | - or when make op,clone the code to the package path and set it as y or m 87 | 88 | #### pic 89 | example in zh-cn:
90 | ![Screenshot_2019-12-23 newifi-d1 - 基础设置 - LuCI](.images/71361626-81d60900-25ce-11ea-91d5-ac4e35d5c41e.png) 91 | ![图片](.images/71361650-90242500-25ce-11ea-9727-9306a3da1357.png) 92 | ![Screenshot_2019-12-23 newifi-d1 - 日志 - LuCI(1)](.images/71361700-b944b580-25ce-11ea-8562-f68c28952b2b.png) 93 | ![Screenshot_2019-12-23 newifi-d1 - 手动设置 - LuCI](.images/71361704-bb0e7900-25ce-11ea-8042-6dd396607030.png) 94 | -------------------------------------------------------------------------------- /luci-app-adguardhome/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/luci-app-adguardhome/.DS_Store -------------------------------------------------------------------------------- /luci-app-adguardhome/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Lienol 2 | # 3 | # This is free software, licensed under the Apache License, Version 2.0 . 4 | # 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | PKG_NAME:=luci-app-adguardhome 9 | PKG_VERSION:=1.8 10 | PKG_RELEASE:=11 11 | 12 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) 13 | 14 | include $(INCLUDE_DIR)/package.mk 15 | 16 | define Package/luci-app-adguardhome 17 | SECTION:=luci 18 | CATEGORY:=LuCI 19 | SUBMENU:=3. Applications 20 | TITLE:=LuCI app for adguardhome 21 | PKG_MAINTAINER:= 22 | PKGARCH:=all 23 | DEPENDS:=+!wget&&!curl:wget 24 | endef 25 | 26 | define Package/luci-app-adguardhome/description 27 | LuCI support for adguardhome 28 | endef 29 | 30 | define Build/Prepare 31 | endef 32 | 33 | define Build/Compile 34 | endef 35 | 36 | define Package/luci-app-adguardhome/conffiles 37 | /usr/share/AdGuardHome/links.txt 38 | /etc/config/adGuardConfig/AdGuardHome 39 | endef 40 | 41 | define Package/luci-app-adguardhome/install 42 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci 43 | cp -pR ./luasrc/* $(1)/usr/lib/lua/luci 44 | $(INSTALL_DIR) $(1)/ 45 | cp -pR ./root/* $(1)/ 46 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n 47 | po2lmo ./po/zh-cn/AdGuardHome.po $(1)/usr/lib/lua/luci/i18n/AdGuardHome.zh-cn.lmo 48 | endef 49 | 50 | define Package/luci-app-adguardhome/postinst 51 | #!/bin/sh 52 | /etc/init.d/AdGuardHome enable >/dev/null 2>&1 53 | enable=$(uci get AdGuardHome.AdGuardHome.enabled 2>/dev/null) 54 | if [ "$enable" == "1" ]; then 55 | /etc/init.d/AdGuardHome reload 56 | fi 57 | rm -f /tmp/luci-indexcache 58 | rm -f /tmp/luci-modulecache/* 59 | exit 0 60 | endef 61 | 62 | define Package/luci-app-adguardhome/prerm 63 | #!/bin/sh 64 | if [ -z "$${IPKG_INSTROOT}" ]; then 65 | /etc/init.d/AdGuardHome disable 66 | /etc/init.d/AdGuardHome stop 67 | uci -q batch <<-EOF >/dev/null 2>&1 68 | delete ucitrack.@AdGuardHome[-1] 69 | commit ucitrack 70 | EOF 71 | fi 72 | exit 0 73 | endef 74 | 75 | $(eval $(call BuildPackage,luci-app-adguardhome)) 76 | -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/luci-app-adguardhome/luasrc/.DS_Store -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/controller/AdGuardHome.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.AdGuardHome",package.seeall) 2 | local fs=require"nixio.fs" 3 | local http=require"luci.http" 4 | local uci=require"luci.model.uci".cursor() 5 | function index() 6 | entry({"admin", "services", "AdGuardHome"},alias("admin", "services", "AdGuardHome", "base"),_("AdGuard Home"), 10).dependent = true 7 | entry({"admin","services","AdGuardHome","base"},cbi("AdGuardHome/base"),_("Base Setting"),1).leaf = true 8 | entry({"admin","services","AdGuardHome","log"},form("AdGuardHome/log"),_("Log"),2).leaf = true 9 | entry({"admin","services","AdGuardHome","manual"},cbi("AdGuardHome/manual"),_("Manual Config"),3).leaf = true 10 | entry({"admin","services","AdGuardHome","status"},call("act_status")).leaf=true 11 | entry({"admin", "services", "AdGuardHome", "check"}, call("check_update")) 12 | entry({"admin", "services", "AdGuardHome", "doupdate"}, call("do_update")) 13 | entry({"admin", "services", "AdGuardHome", "getlog"}, call("get_log")) 14 | entry({"admin", "services", "AdGuardHome", "dodellog"}, call("do_dellog")) 15 | entry({"admin", "services", "AdGuardHome", "reloadconfig"}, call("reload_config")) 16 | entry({"admin", "services", "AdGuardHome", "gettemplateconfig"}, call("get_template_config")) 17 | end 18 | function get_template_config() 19 | local b 20 | local d="" 21 | for cnt in io.lines("/tmp/resolv.conf.auto") do 22 | b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$") 23 | if (b~=nil) then 24 | d=d.." - "..b.."\n" 25 | end 26 | end 27 | local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+") 28 | local tbl = {} 29 | local a="" 30 | while (1) do 31 | a=f:read("*l") 32 | if (a=="#bootstrap_dns") then 33 | a=d 34 | elseif (a=="#upstream_dns") then 35 | a=d 36 | elseif (a==nil) then 37 | break 38 | end 39 | table.insert(tbl, a) 40 | end 41 | f:close() 42 | http.prepare_content("text/plain; charset=utf-8") 43 | http.write(table.concat(tbl, "\n")) 44 | end 45 | function reload_config() 46 | fs.remove("/tmp/AdGuardHometmpconfig.yaml") 47 | http.prepare_content("application/json") 48 | http.write('') 49 | end 50 | function act_status() 51 | local e={} 52 | local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") 53 | e.running=luci.sys.call("pgrep "..binpath.." >/dev/null")==0 54 | e.redirect=(fs.readfile("/var/run/AdGredir")=="1") 55 | http.prepare_content("application/json") 56 | http.write_json(e) 57 | end 58 | function do_update() 59 | fs.writefile("/var/run/lucilogpos","0") 60 | http.prepare_content("application/json") 61 | http.write('') 62 | local arg 63 | if luci.http.formvalue("force") == "1" then 64 | arg="force" 65 | else 66 | arg="" 67 | end 68 | if fs.access("/var/run/update_core") then 69 | if arg=="force" then 70 | 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 &") 71 | end 72 | else 73 | luci.sys.exec("sh /usr/share/AdGuardHome/update_core.sh "..arg.." >/tmp/AdGuardHome_update.log 2>&1 &") 74 | end 75 | end 76 | function get_log() 77 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") 78 | if (logfile==nil) then 79 | http.write("no log available\n") 80 | return 81 | elseif (logfile=="syslog") then 82 | if not fs.access("/var/run/AdGuardHomesyslog") then 83 | luci.sys.exec("(/usr/share/AdGuardHome/getsyslog.sh &); sleep 1;") 84 | end 85 | logfile="/tmp/AdGuardHometmp.log" 86 | fs.writefile("/var/run/AdGuardHomesyslog","1") 87 | elseif not fs.access(logfile) then 88 | http.write("") 89 | return 90 | end 91 | http.prepare_content("text/plain; charset=utf-8") 92 | local fdp 93 | if fs.access("/var/run/lucilogreload") then 94 | fdp=0 95 | fs.remove("/var/run/lucilogreload") 96 | else 97 | fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0 98 | end 99 | local f=io.open(logfile, "r+") 100 | f:seek("set",fdp) 101 | local a=f:read(2048000) or "" 102 | fdp=f:seek() 103 | fs.writefile("/var/run/lucilogpos",tostring(fdp)) 104 | f:close() 105 | http.write(a) 106 | end 107 | function do_dellog() 108 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") 109 | fs.writefile(logfile,"") 110 | http.prepare_content("application/json") 111 | http.write('') 112 | end 113 | function check_update() 114 | http.prepare_content("text/plain; charset=utf-8") 115 | local fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0 116 | local f=io.open("/tmp/AdGuardHome_update.log", "r+") 117 | f:seek("set",fdp) 118 | local a=f:read(2048000) or "" 119 | fdp=f:seek() 120 | fs.writefile("/var/run/lucilogpos",tostring(fdp)) 121 | f:close() 122 | if fs.access("/var/run/update_core") then 123 | http.write(a) 124 | else 125 | http.write(a.."\0") 126 | end 127 | end 128 | -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/base.lua: -------------------------------------------------------------------------------- 1 | require("luci.sys") 2 | require("luci.util") 3 | require("io") 4 | local m,s,o,o1 5 | local fs=require"nixio.fs" 6 | local uci=require"luci.model.uci".cursor() 7 | local configpath=uci:get("AdGuardHome","AdGuardHome","configpath") or "/etc/config/adGuardConfig/AdGuardHome.yaml" 8 | local binpath=uci:get("AdGuardHome","AdGuardHome","binpath") or "/etc/config/adGuardConfig/AdGuardHome" 9 | httpport=uci:get("AdGuardHome","AdGuardHome","httpport") or "3000" 10 | m = Map("AdGuardHome", "AdGuard Home") 11 | m.description = translate("Free and open source, powerful network-wide ads & trackers blocking DNS server.") 12 | m:section(SimpleSection).template = "AdGuardHome/AdGuardHome_status" 13 | 14 | s = m:section(TypedSection, "AdGuardHome") 15 | s.anonymous=true 16 | s.addremove=false 17 | ---- enable 18 | o = s:option(Flag, "enabled", translate("Enable")) 19 | o.default = 0 20 | o.optional = false 21 | ---- httpport 22 | o =s:option(Value,"httpport",translate("Browser management port")) 23 | o.placeholder=3000 24 | o.default=3000 25 | o.datatype="port" 26 | o.optional = false 27 | o.description = translate("") 28 | ---- update warning not safe 29 | local binmtime=uci:get("AdGuardHome","AdGuardHome","binmtime") or "0" 30 | local e="" 31 | if not fs.access(configpath) then 32 | e=e.." "..translate("no config") 33 | end 34 | if not fs.access(binpath) then 35 | e=e.." "..translate("no core") 36 | else 37 | local version=uci:get("AdGuardHome","AdGuardHome","version") 38 | local testtime=fs.stat(binpath,"mtime") 39 | if testtime~=tonumber(binmtime) or version==nil then 40 | local tmp=luci.sys.exec(binpath.." -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o") 41 | version=string.sub(tmp, 1, -2) 42 | if version=="" then version="core error" end 43 | uci:set("AdGuardHome","AdGuardHome","version",version) 44 | uci:set("AdGuardHome","AdGuardHome","binmtime",testtime) 45 | uci:save("AdGuardHome") 46 | end 47 | e=version..e 48 | end 49 | o=s:option(Button,"restart",translate("Update")) 50 | o.inputtitle=translate("Update core version") 51 | o.template = "AdGuardHome/AdGuardHome_check" 52 | o.showfastconfig=(not fs.access(configpath)) 53 | o.description=string.format(translate("core version:").."%s ",e) 54 | ---- port warning not safe 55 | local port=luci.sys.exec("awk '/ port:/{printf($2);exit;}' "..configpath.." 2>nul") 56 | if (port=="") then port="?" end 57 | ---- Redirect 58 | o = s:option(ListValue, "redirect", port..translate("Redirect"), translate("AdGuardHome redirect mode")) 59 | o.placeholder = "none" 60 | o:value("none", translate("none")) 61 | o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server")) 62 | o:value("redirect", translate("Redirect 53 port to AdGuardHome")) 63 | o:value("exchange", translate("Use port 53 replace dnsmasq")) 64 | o.default = "none" 65 | o.optional = true 66 | ---- bin path 67 | o = s:option(Value, "binpath", translate("Bin Path"), translate("AdGuardHome Bin path if no bin will auto download")) 68 | o.default = "/etc/config/adGuardConfig/AdGuardHome" 69 | o.datatype = "string" 70 | o.optional = false 71 | o.rmempty=false 72 | o.validate=function(self, value) 73 | if value=="" then return nil end 74 | if fs.stat(value,"type")=="dir" then 75 | fs.rmdir(value) 76 | end 77 | if fs.stat(value,"type")=="dir" then 78 | if (m.message) then 79 | m.message =m.message.."\nerror!bin path is a dir" 80 | else 81 | m.message ="error!bin path is a dir" 82 | end 83 | return nil 84 | end 85 | return value 86 | end 87 | --- upx 88 | o = s:option(ListValue, "upxflag", translate("use upx to compress bin after download")) 89 | o:value("", translate("none")) 90 | o:value("-1", translate("compress faster")) 91 | o:value("-9", translate("compress better")) 92 | o:value("--best", translate("compress best(can be slow for big files)")) 93 | o:value("--brute", translate("try all available compression methods & filters [slow]")) 94 | o:value("--ultra-brute", translate("try even more compression variants [very slow]")) 95 | o.default = "" 96 | o.description=translate("bin use less space,but may have compatibility issues") 97 | o.rmempty = true 98 | ---- config path 99 | o = s:option(Value, "configpath", translate("Config Path"), translate("AdGuardHome config path")) 100 | o.default = "/etc/config/adGuardConfig/AdGuardHome.yaml" 101 | o.datatype = "string" 102 | o.optional = false 103 | o.rmempty=false 104 | o.validate=function(self, value) 105 | if value==nil then return nil end 106 | if fs.stat(value,"type")=="dir" then 107 | fs.rmdir(value) 108 | end 109 | if fs.stat(value,"type")=="dir" then 110 | if m.message then 111 | m.message =m.message.."\nerror!config path is a dir" 112 | else 113 | m.message ="error!config path is a dir" 114 | end 115 | return nil 116 | end 117 | return value 118 | end 119 | ---- work dir 120 | o = s:option(Value, "workdir", translate("Work dir"), translate("AdGuardHome work dir include rules,audit log and database")) 121 | o.default = "/etc/config/adGuardConfig/workspace" 122 | o.datatype = "string" 123 | o.optional = false 124 | o.rmempty=false 125 | o.validate=function(self, value) 126 | if value=="" then return nil end 127 | if fs.stat(value,"type")=="reg" then 128 | if m.message then 129 | m.message =m.message.."\nerror!work dir is a file" 130 | else 131 | m.message ="error!work dir is a file" 132 | end 133 | return nil 134 | end 135 | if string.sub(value, -1)=="/" then 136 | return string.sub(value, 1, -2) 137 | else 138 | return value 139 | end 140 | end 141 | ---- log file 142 | o = s:option(Value, "logfile", translate("Runtime log file"), translate("AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log")) 143 | o.datatype = "string" 144 | o.rmempty = true 145 | o.validate=function(self, value) 146 | if fs.stat(value,"type")=="dir" then 147 | fs.rmdir(value) 148 | end 149 | if fs.stat(value,"type")=="dir" then 150 | if m.message then 151 | m.message =m.message.."\nerror!log file is a dir" 152 | else 153 | m.message ="error!log file is a dir" 154 | end 155 | return nil 156 | end 157 | return value 158 | end 159 | ---- debug 160 | o = s:option(Flag, "verbose", translate("Verbose log")) 161 | o.default = 0 162 | o.optional = true 163 | ---- gfwlist 164 | local a=luci.sys.call("grep -m 1 -q programadd "..configpath) 165 | if (a==0) then 166 | a="Added" 167 | else 168 | a="Not added" 169 | end 170 | o=s:option(Button,"gfwdel",translate("Del gfwlist"),translate(a)) 171 | o.optional = true 172 | o.inputtitle=translate("Del") 173 | o.write=function() 174 | luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh del 2>&1") 175 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome")) 176 | end 177 | o=s:option(Button,"gfwadd",translate("Add gfwlist"),translate(a)) 178 | o.optional = true 179 | o.inputtitle=translate("Add") 180 | o.write=function() 181 | luci.sys.exec("sh /usr/share/AdGuardHome/gfw2adg.sh 2>&1") 182 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome")) 183 | end 184 | o = s:option(Value, "gfwupstream", translate("Gfwlist upstream dns server"), translate("Gfwlist domain upstream dns service")..translate(a)) 185 | o.default = "tcp://223.5.5.5" 186 | o.datatype = "string" 187 | o.optional = true 188 | ---- chpass 189 | o = s:option(Value, "hashpass", translate("Change browser management password"), translate("Press load culculate model and culculate finally save/apply")) 190 | o.default = "" 191 | o.datatype = "string" 192 | o.template = "AdGuardHome/AdGuardHome_chpass" 193 | o.optional = true 194 | ---- upgrade protect 195 | o = s:option(MultiValue, "upprotect", translate("Keep files when system upgrade")) 196 | o:value("$binpath",translate("core bin")) 197 | o:value("$configpath",translate("config file")) 198 | o:value("$logfile",translate("log file")) 199 | o:value("$workdir/data/sessions.db",translate("sessions.db")) 200 | o:value("$workdir/data/stats.db",translate("stats.db")) 201 | o:value("$workdir/data/querylog.json",translate("querylog.json")) 202 | o:value("$workdir/data/filters",translate("filters")) 203 | o.widget = "checkbox" 204 | o.default = nil 205 | o.optional=true 206 | ---- wait net on boot 207 | o = s:option(Flag, "waitonboot", translate("On boot when network ok restart")) 208 | o.default = 1 209 | o.optional = true 210 | ---- backup workdir on shutdown 211 | local workdir=uci:get("AdGuardHome","AdGuardHome","workdir") or "/usr/bin/AdGuardHome" 212 | o = s:option(MultiValue, "backupfile", translate("Backup workdir files when shutdown")) 213 | o1 = s:option(Value, "backupwdpath", translate("Backup workdir path")) 214 | local name 215 | o:value("filters","filters") 216 | o:value("stats.db","stats.db") 217 | o:value("querylog.json","querylog.json") 218 | o:value("sessions.db","sessions.db") 219 | o1:depends ("backupfile", "filters") 220 | o1:depends ("backupfile", "stats.db") 221 | o1:depends ("backupfile", "querylog.json") 222 | o1:depends ("backupfile", "sessions.db") 223 | for name in fs.glob(workdir.."/data/*") 224 | do 225 | name=fs.basename (name) 226 | if name~="filters" and name~="stats.db" and name~="querylog.json" and name~="sessions.db" then 227 | o:value(name,name) 228 | o1:depends ("backupfile", name) 229 | end 230 | end 231 | o.widget = "checkbox" 232 | o.default = nil 233 | o.optional=false 234 | o.description=translate("Will be restore when workdir/data is empty") 235 | ----backup workdir path 236 | 237 | o1.default = "/etc/config/adGuardConfig/workspace" 238 | o1.datatype = "string" 239 | o1.optional = false 240 | o1.validate=function(self, value) 241 | if fs.stat(value,"type")=="reg" then 242 | if m.message then 243 | m.message =m.message.."\nerror!backup dir is a file" 244 | else 245 | m.message ="error!backup dir is a file" 246 | end 247 | return nil 248 | end 249 | if string.sub(value,-1)=="/" then 250 | return string.sub(value, 1, -2) 251 | else 252 | return value 253 | end 254 | end 255 | 256 | ----Crontab 257 | o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab")) 258 | o:value("autoupdate",translate("Auto update core")) 259 | o:value("cutquerylog",translate("Auto tail querylog")) 260 | o:value("cutruntimelog",translate("Auto tail runtime log")) 261 | o:value("autohost",translate("Auto update ipv6 hosts and restart adh")) 262 | o:value("autogfw",translate("Auto update gfwlist and restart adh")) 263 | o.widget = "checkbox" 264 | o.default = nil 265 | o.optional=true 266 | 267 | ----downloadpath 268 | o = s:option(TextValue, "downloadlinks",translate("Download links for update")) 269 | o.optional = false 270 | o.rows = 4 271 | o.wrap = "soft" 272 | o.cfgvalue = function(self, section) 273 | return fs.readfile("/usr/share/AdGuardHome/links.txt") 274 | end 275 | o.write = function(self, section, value) 276 | fs.writefile("/usr/share/AdGuardHome/links.txt", value:gsub("\r\n", "\n")) 277 | end 278 | fs.writefile("/var/run/lucilogpos","0") 279 | function m.on_commit(map) 280 | if (fs.access("/var/run/AdGserverdis")) then 281 | io.popen("/etc/init.d/AdGuardHome reload &") 282 | return 283 | end 284 | local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest") 285 | if ucitracktest=="1" then 286 | return 287 | elseif ucitracktest=="0" then 288 | io.popen("/etc/init.d/AdGuardHome reload &") 289 | else 290 | if (fs.access("/var/run/AdGlucitest")) then 291 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","0") 292 | io.popen("/etc/init.d/AdGuardHome reload &") 293 | else 294 | fs.writefile("/var/run/AdGlucitest","") 295 | if (ucitracktest=="2") then 296 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","1") 297 | else 298 | uci:set("AdGuardHome","AdGuardHome","ucitracktest","2") 299 | end 300 | end 301 | uci:save("AdGuardHome") 302 | end 303 | end 304 | return m -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/log.lua: -------------------------------------------------------------------------------- 1 | local fs=require"nixio.fs" 2 | local uci=require"luci.model.uci".cursor() 3 | local f,t 4 | f=SimpleForm("logview") 5 | f.reset = false 6 | f.submit = false 7 | t=f:field(TextValue,"conf") 8 | t.rmempty=true 9 | t.rows=20 10 | t.template="AdGuardHome/log" 11 | t.readonly="readonly" 12 | local logfile=uci:get("AdGuardHome","AdGuardHome","logfile") or "" 13 | t.timereplace=(logfile~="syslog" and logfile~="" ) 14 | t.pollcheck=logfile~="" 15 | fs.writefile("/var/run/lucilogreload","") 16 | return f 17 | -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/model/cbi/AdGuardHome/manual.lua: -------------------------------------------------------------------------------- 1 | local m, s, o 2 | local fs = require "nixio.fs" 3 | local uci=require"luci.model.uci".cursor() 4 | local sys=require"luci.sys" 5 | require("string") 6 | require("io") 7 | require("table") 8 | function gen_template_config() 9 | local b 10 | local d="" 11 | for cnt in io.lines("/tmp/resolv.conf.auto") do 12 | b=string.match (cnt,"^[^#]*nameserver%s+([^%s]+)$") 13 | if (b~=nil) then 14 | d=d.." - "..b.."\n" 15 | end 16 | end 17 | local f=io.open("/usr/share/AdGuardHome/AdGuardHome_template.yaml", "r+") 18 | local tbl = {} 19 | local a="" 20 | while (1) do 21 | a=f:read("*l") 22 | if (a=="#bootstrap_dns") then 23 | a=d 24 | elseif (a=="#upstream_dns") then 25 | a=d 26 | elseif (a==nil) then 27 | break 28 | end 29 | table.insert(tbl, a) 30 | end 31 | f:close() 32 | return table.concat(tbl, "\n") 33 | end 34 | m = Map("AdGuardHome") 35 | local configpath = uci:get("AdGuardHome","AdGuardHome","configpath") 36 | local binpath = uci:get("AdGuardHome","AdGuardHome","binpath") 37 | s = m:section(TypedSection, "AdGuardHome") 38 | s.anonymous=true 39 | s.addremove=false 40 | --- config 41 | o = s:option(TextValue, "escconf") 42 | o.rows = 66 43 | o.wrap = "off" 44 | o.rmempty = true 45 | o.cfgvalue = function(self, section) 46 | return fs.readfile("/tmp/AdGuardHometmpconfig.yaml") or fs.readfile(configpath) or gen_template_config() or "" 47 | end 48 | o.validate=function(self, value) 49 | fs.writefile("/tmp/AdGuardHometmpconfig.yaml", value:gsub("\r\n", "\n")) 50 | if fs.access(binpath) then 51 | if (sys.call(binpath.." -c /tmp/AdGuardHometmpconfig.yaml --check-config 2> /tmp/AdGuardHometest.log")==0) then 52 | return value 53 | end 54 | else 55 | return value 56 | end 57 | luci.http.redirect(luci.dispatcher.build_url("admin","services","AdGuardHome","manual")) 58 | return nil 59 | end 60 | o.write = function(self, section, value) 61 | fs.move("/tmp/AdGuardHometmpconfig.yaml",configpath) 62 | end 63 | o.remove = function(self, section, value) 64 | fs.writefile(configpath, "") 65 | end 66 | --- js and reload button 67 | o = s:option(DummyValue, "") 68 | o.anonymous=true 69 | o.template = "AdGuardHome/yamleditor" 70 | if not fs.access(binpath) then 71 | o.description=translate("WARNING!!! no bin found apply config will not be test") 72 | end 73 | --- log 74 | if (fs.access("/tmp/AdGuardHometmpconfig.yaml")) then 75 | local c=fs.readfile("/tmp/AdGuardHometest.log") 76 | if (c~="") then 77 | o = s:option(TextValue, "") 78 | o.readonly=true 79 | o.rows = 5 80 | o.rmempty = true 81 | o.name="" 82 | o.cfgvalue = function(self, section) 83 | return fs.readfile("/tmp/AdGuardHometest.log") 84 | end 85 | end 86 | end 87 | function m.on_commit(map) 88 | local ucitracktest=uci:get("AdGuardHome","AdGuardHome","ucitracktest") 89 | if ucitracktest=="1" then 90 | return 91 | elseif ucitracktest=="0" then 92 | io.popen("/etc/init.d/AdGuardHome reload &") 93 | else 94 | fs.writefile("/var/run/AdGlucitest","") 95 | end 96 | end 97 | return m -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_check.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | <%local fs=require"nixio.fs"%> 3 | 4 | 5 | <% if self.showfastconfig then %> 6 | 7 | <%end%> 8 | 12 | 78 | <%+cbi/valuefooter%> -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_chpass.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | 32 | 0, "data-choices", { self.keylist, self.vallist }) 46 | %> /> 47 | <% if self.password then %><% end %> 48 | 49 | <%+cbi/valuefooter%> -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/view/AdGuardHome/AdGuardHome_status.htm: -------------------------------------------------------------------------------- 1 | 22 | 23 |
24 |

25 | <%:Collecting data...%> 26 |

27 |
-------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/view/AdGuardHome/log.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | <%:reverse%> 3 | <%if self.timereplace then%> 4 | <%:localtime%>
5 | <%end%> 6 | 7 | 8 | 9 | 110 | <%+cbi/valuefooter%> -------------------------------------------------------------------------------- /luci-app-adguardhome/luasrc/view/AdGuardHome/yamleditor.htm: -------------------------------------------------------------------------------- 1 | <%+cbi/valueheader%> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 34 | <%fs=require"nixio.fs"%> 35 | <%if fs.access("/tmp/AdGuardHometmpconfig.yaml") then%> 36 | 37 | <%end%> 38 | 39 | <%+cbi/valuefooter%> -------------------------------------------------------------------------------- /luci-app-adguardhome/po/zh-cn/AdGuardHome.po: -------------------------------------------------------------------------------- 1 | #/cgi-bin/luci/admin/services/AdGuardHome 2 | msgid "Base Setting" 3 | msgstr "基础设置" 4 | 5 | msgid "Log" 6 | msgstr "日志" 7 | 8 | msgid "Manual Config" 9 | msgstr "手动设置" 10 | 11 | msgid "Free and open source, powerful network-wide ads & trackers blocking DNS server." 12 | msgstr "免费开源,功能强大的全网络广告和跟踪程序拦截DNS服务器" 13 | 14 | msgid "RUNNING" 15 | msgstr "运行中" 16 | 17 | msgid "NOT RUNNING" 18 | msgstr "未运行" 19 | 20 | msgid "Redirected" 21 | msgstr "已重定向" 22 | 23 | msgid "Not redirect" 24 | msgstr "未重定向" 25 | 26 | msgid "Collecting data..." 27 | msgstr "获取数据中..." 28 | 29 | msgid "Enable" 30 | msgstr "启用" 31 | 32 | msgid "Browser management port" 33 | msgstr "网页管理端口" 34 | 35 | msgid "Update" 36 | msgstr "更新" 37 | #button change 38 | msgid "Update core version" 39 | msgstr "更新核心版本" 40 | 41 | msgid "Check..." 42 | msgstr "检查中..." 43 | 44 | msgid "Updated" 45 | msgstr "已更新" 46 | 47 | #button hide 48 | msgid "Force update" 49 | msgstr "强制更新" 50 | 51 | msgid "Fast config" 52 | msgstr "快速配置" 53 | # 54 | msgid "core version:" 55 | msgstr "核心版本:" 56 | #description change 57 | msgid "no config" 58 | msgstr "没有配置文件" 59 | msgid "no core" 60 | msgstr "没有核心" 61 | # 62 | msgid "Redirect" 63 | msgstr "重定向" 64 | #inlist 65 | msgid "none" 66 | msgstr "无" 67 | 68 | msgid "Run as dnsmasq upstream server" 69 | msgstr "作为dnsmasq的上游服务器" 70 | 71 | msgid "Redirect 53 port to AdGuardHome" 72 | msgstr "重定向53端口到AdGuardHome" 73 | 74 | msgid "Use port 53 replace dnsmasq" 75 | msgstr "使用53端口替换dnsmasq" 76 | # 77 | msgid "AdGuardHome redirect mode" 78 | msgstr "AdGuardHome重定向模式" 79 | 80 | msgid "Bin Path" 81 | msgstr "执行文件路径" 82 | 83 | msgid "AdGuardHome Bin path if no bin will auto download" 84 | msgstr "AdGuardHome 执行文件路径 如果没有执行文件将自动下载" 85 | 86 | msgid "use upx to compress bin after download" 87 | msgstr "下载后使用upx压缩执行文件" 88 | #inlist 89 | msgid "compress faster" 90 | msgstr "快速压缩" 91 | 92 | msgid "compress better" 93 | msgstr "更好的压缩" 94 | 95 | msgid "compress best(can be slow for big files)" 96 | msgstr "最好的压缩(大文件可能慢)" 97 | 98 | msgid "try all available compression methods & filters [slow]" 99 | msgstr "尝试所有可能的压缩方法和过滤器[慢]" 100 | 101 | msgid "try even more compression variants [very slow]" 102 | msgstr "尝试更多变体压缩手段[很慢]" 103 | 104 | msgid "bin use less space,but may have compatibility issues" 105 | msgstr "减小执行文件空间占用,但是可能压缩后有兼容性问题" 106 | # 107 | msgid "Config Path" 108 | msgstr "配置文件路径" 109 | 110 | msgid "AdGuardHome config path" 111 | msgstr "AdGuardHome 配置文件路径" 112 | 113 | msgid "Work dir" 114 | msgstr "工作目录" 115 | 116 | msgid "AdGuardHome work dir include rules,audit log and database" 117 | msgstr "AdGuardHome 工作目录包含规则,审计日志和数据库" 118 | 119 | msgid "Runtime log file" 120 | msgstr "运行日志" 121 | 122 | msgid "AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log" 123 | msgstr "AdGuardHome 运行日志 如果填syslog将写入系统日志;如果空则不记录日志" 124 | 125 | msgid "Verbose log" 126 | msgstr "详细日志" 127 | #hide div 128 | msgid "Add gfwlist" 129 | msgstr "加入gfw列表" 130 | 131 | msgid "Add" 132 | msgstr "添加" 133 | 134 | msgid "Added" 135 | msgstr "已添加" 136 | 137 | msgid "Not added" 138 | msgstr "未添加" 139 | #hide div 140 | msgid "Del gfwlist" 141 | msgstr "删除gfw列表" 142 | 143 | msgid "Del" 144 | msgstr "删除" 145 | #hide div 146 | msgid "Gfwlist upstream dns server" 147 | msgstr "gfw列表上游服务器" 148 | 149 | msgid "Gfwlist domain upstream dns service" 150 | msgstr "gfw列表域名上游服务器" 151 | #hide div 152 | msgid "Change browser management password" 153 | msgstr "改变网页登录密码" 154 | 155 | msgid "Culculate" 156 | msgstr "计算" 157 | ##button change 158 | msgid "Load culculate model" 159 | msgstr "载入计算模块" 160 | 161 | msgid "loading..." 162 | msgstr "载入中" 163 | 164 | msgid "Please save/apply" 165 | msgstr "请提交" 166 | 167 | msgid "is empty" 168 | msgstr "为空" 169 | 170 | msgid "Press load culculate model and culculate finally save/apply" 171 | msgstr "按载入计算模块 然后计算 最后保存/提交" 172 | # 173 | msgid "Keep files when system upgrade" 174 | msgstr "系统升级时保留文件" 175 | #checkbox 176 | msgid "core bin" 177 | msgstr "核心执行文件" 178 | 179 | msgid "config file" 180 | msgstr "配置文件" 181 | 182 | msgid "log file" 183 | msgstr "日志文件" 184 | 185 | msgid "querylog.json" 186 | msgstr "审计日志.json" 187 | # 188 | msgid "On boot when network ok restart" 189 | msgstr "开机后网络准备好时重启" 190 | 191 | msgid "Backup workdir files when shutdown" 192 | msgstr "在关机时备份工作目录文件" 193 | 194 | msgid "Will be restore when workdir/data is empty" 195 | msgstr "在工作目录/data为空的时候恢复" 196 | 197 | msgid "Backup workdir path" 198 | msgstr "工作目录备份路径" 199 | 200 | msgid "Crontab task" 201 | msgstr "计划任务" 202 | 203 | msgid "Auto update core" 204 | msgstr "自动升级核心" 205 | 206 | msgid "Auto tail querylog" 207 | msgstr "自动截短查询日志" 208 | 209 | msgid "Auto tail runtime log" 210 | msgstr "自动截短运行日志" 211 | 212 | msgid "Auto update ipv6 hosts and restart adh" 213 | msgstr "自动更新ipv6主机并重启adh" 214 | 215 | msgid "Auto update gfwlist and restart adh" 216 | msgstr "自动更新gfw列表并重启adh" 217 | 218 | msgid "Please change time and args in crontab" 219 | msgstr "请在计划任务中修改时间和参数" 220 | 221 | msgid "Download links for update" 222 | msgstr "升级用的下载链接" 223 | 224 | #/cgi-bin/luci/admin/services/AdGuardHome/log/ 225 | msgid "reverse" 226 | msgstr "逆序" 227 | 228 | msgid "localtime" 229 | msgstr "本地时间" 230 | 231 | msgid "Please add log path in config to enable log" 232 | msgstr "请在设置里填写日志路径以启用日志" 233 | 234 | msgid "dellog" 235 | msgstr "删除日志" 236 | 237 | msgid "download log" 238 | msgstr "下载日志" 239 | 240 | #/cgi-bin/luci//admin/services/AdGuardHome/manual/ 241 | msgid "Use template" 242 | msgstr "使用模板" 243 | #hide button 244 | msgid "Reload Config" 245 | msgstr "重新载入配置" 246 | 247 | msgid "WARNING!!! no bin found apply config will not be test" 248 | msgstr "警告!!!未找到执行文件,提交配置将不会进行校验" 249 | #unused 250 | msgid "Change browser management username" 251 | msgstr "改变网页登录用户名" 252 | 253 | msgid "Username" 254 | msgstr "用户名" 255 | 256 | msgid "Check Config" 257 | msgstr "检查配置" 258 | 259 | msgid "unknown" 260 | msgstr "未知" 261 | 262 | msgid "Keep database when system upgrade" 263 | msgstr "系统升级时保留数据" 264 | 265 | msgid "Boot delay until network ok" 266 | msgstr "开机时直到网络准备好再启动" -------------------------------------------------------------------------------- /luci-app-adguardhome/root/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoxiao29/luci-app-adguardhome/1497e52aa13fca2851accef13c96b8c558e33911/luci-app-adguardhome/root/.DS_Store -------------------------------------------------------------------------------- /luci-app-adguardhome/root/etc/config/AdGuardHome: -------------------------------------------------------------------------------- 1 | config AdGuardHome 'AdGuardHome' 2 | option enabled '0' 3 | option httpport '3000' 4 | option redirect 'none' 5 | option configpath '/etc/config/adGuardConfig/AdGuardHome.yaml' 6 | option workdir '/etc/config/adGuardConfig/workspace' 7 | option logfile '/tmp/log/AdGuardHome.log' 8 | option verbose '0' 9 | option binpath '/etc/config/adGuardConfig/AdGuardHome' 10 | option upxflag '' 11 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/etc/init.d/AdGuardHome: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | USE_PROCD=1 4 | 5 | START=95 6 | STOP=01 7 | 8 | CONFIGURATION=AdGuardHome 9 | CRON_FILE=/etc/crontabs/root 10 | EXTRA_COMMANDS="do_redirect testbackup test_crontab force_reload isrunning" 11 | EXTRA_HELP=" do_redirect 0 or 1\ 12 | testbackup backup or restore\ 13 | test_crontab 14 | force_reload 15 | isrunning" 16 | set_forward_dnsmasq() 17 | { 18 | local PORT="$1" 19 | addr="127.0.0.1#$PORT" 20 | OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`" 21 | echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1 22 | if [ $? -eq 0 ]; then 23 | return 24 | fi 25 | uci delete dhcp.@dnsmasq[0].server 2>/dev/null 26 | uci add_list dhcp.@dnsmasq[0].server=$addr 27 | for server in $OLD_SERVER; do 28 | if [ "$server" = "$addr" ]; then 29 | continue 30 | fi 31 | uci add_list dhcp.@dnsmasq[0].server=$server 32 | done 33 | uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null 34 | uci set dhcp.@dnsmasq[0].noresolv=1 35 | uci commit dhcp 36 | /etc/init.d/dnsmasq restart 37 | } 38 | 39 | stop_forward_dnsmasq() 40 | { 41 | local OLD_PORT="$1" 42 | addr="127.0.0.1#$OLD_PORT" 43 | OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`" 44 | echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1 45 | if [ $? -ne 0 ]; then 46 | return 47 | fi 48 | 49 | uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null 50 | addrlist="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`" 51 | if [ -z "$addrlist" ] ; then 52 | uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto 2>/dev/null 53 | uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null 54 | fi 55 | uci commit dhcp 56 | /etc/init.d/dnsmasq restart 57 | } 58 | 59 | set_iptable() 60 | { 61 | local ipv6_server=$1 62 | local tcp_server=$2 63 | uci -q batch <<-EOF >/dev/null 2>&1 64 | delete firewall.AdGuardHome 65 | set firewall.AdGuardHome=include 66 | set firewall.AdGuardHome.type=script 67 | set firewall.AdGuardHome.path=/usr/share/AdGuardHome/firewall.start 68 | set firewall.AdGuardHome.reload=1 69 | commit firewall 70 | EOF 71 | 72 | IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`" 73 | for IP in $IPS 74 | do 75 | if [ "$tcp_server" == "1" ]; then 76 | iptables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 77 | fi 78 | iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 79 | done 80 | 81 | if [ "$ipv6_server" == 0 ]; then 82 | return 83 | fi 84 | 85 | IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`" 86 | for IP in $IPS 87 | do 88 | if [ "$tcp_server" == "1" ]; then 89 | ip6tables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 90 | fi 91 | ip6tables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $AdGuardHome_PORT >/dev/null 2>&1 92 | done 93 | 94 | } 95 | 96 | clear_iptable() 97 | { 98 | uci -q batch <<-EOF >/dev/null 2>&1 99 | delete firewall.AdGuardHome 100 | commit firewall 101 | EOF 102 | local OLD_PORT="$1" 103 | local ipv6_server=$2 104 | IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`" 105 | for IP in $IPS 106 | do 107 | iptables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 108 | iptables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 109 | done 110 | 111 | if [ "$ipv6_server" == 0 ]; then 112 | return 113 | fi 114 | echo "warn ip6tables nat mod is needed" 115 | IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`" 116 | for IP in $IPS 117 | do 118 | ip6tables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 119 | ip6tables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1 120 | done 121 | 122 | } 123 | 124 | service_triggers() { 125 | procd_add_reload_trigger "$CONFIGURATION" 126 | [ "$(uci get AdGuardHome.AdGuardHome.redirect)" == "redirect" ] && procd_add_reload_trigger firewall 127 | } 128 | isrunning(){ 129 | config_load "${CONFIGURATION}" 130 | _isrunning 131 | local r=$? 132 | ([ "$r" == "0" ] && echo "running") || ([ "$r" == "1" ] && echo "not run" ) || echo "no bin" 133 | return $r 134 | } 135 | _isrunning(){ 136 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome" 137 | [ ! -f "$binpath" ] && return 2 138 | pgrep $binpath 2>&1 >/dev/null && return 0 139 | return 1 140 | } 141 | force_reload(){ 142 | config_load "${CONFIGURATION}" 143 | _isrunning && procd_send_signal "$CONFIGURATION" || start 144 | } 145 | get_tz() 146 | { 147 | SET_TZ="" 148 | 149 | if [ -e "/etc/localtime" ]; then 150 | return 151 | fi 152 | 153 | for tzfile in /etc/TZ /var/etc/TZ 154 | do 155 | if [ ! -e "$tzfile" ]; then 156 | continue 157 | fi 158 | 159 | tz="`cat $tzfile 2>/dev/null`" 160 | done 161 | 162 | if [ -z "$tz" ]; then 163 | return 164 | fi 165 | 166 | SET_TZ=$tz 167 | } 168 | 169 | rm_port53() 170 | { 171 | local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") 172 | dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) 173 | if [ -z "$dnsmasq_port" ]; then 174 | dnsmasq_port="53" 175 | fi 176 | if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then 177 | if [ "$dnsmasq_port" == "53" ]; then 178 | dnsmasq_port="1745" 179 | fi 180 | elif [ "$dnsmasq_port" == "53" ]; then 181 | return 182 | fi 183 | config_editor "dns.port" "$dnsmasq_port" "$configpath" 184 | uci set dhcp.@dnsmasq[0].port="53" 185 | uci commit dhcp 186 | /etc/init.d/dnsmasq reload 187 | } 188 | 189 | use_port53() 190 | { 191 | local AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") 192 | dnsmasq_port=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) 193 | if [ -z "$dnsmasq_port" ]; then 194 | dnsmasq_port="53" 195 | fi 196 | if [ "$dnsmasq_port" == "$AdGuardHome_PORT" ]; then 197 | if [ "$dnsmasq_port" == "53" ]; then 198 | AdGuardHome_PORT="1745" 199 | fi 200 | elif [ "$AdGuardHome_PORT" == "53" ]; then 201 | return 202 | fi 203 | config_editor "dns.port" "53" "$configpath" 204 | uci set dhcp.@dnsmasq[0].port="$AdGuardHome_PORT" 205 | uci commit dhcp 206 | /etc/init.d/dnsmasq reload 207 | } 208 | do_redirect() 209 | { 210 | config_load "${CONFIGURATION}" 211 | _do_redirect $1 212 | } 213 | _do_redirect() 214 | { 215 | local section="$CONFIGURATION" 216 | args="" 217 | ipv6_server=1 218 | tcp_server=0 219 | enabled=$1 220 | if [ "$enabled" == "1" ]; then 221 | echo -n "1">/var/run/AdGredir 222 | else 223 | echo -n "0">/var/run/AdGredir 224 | fi 225 | config_get configpath $CONFIGURATION configpath "/etc/config/adGuardConfig/AdGuardHome.yaml" 226 | AdGuardHome_PORT=$(config_editor "dns.port" "" "$configpath" "1") 227 | if [ -z "$AdGuardHome_PORT" ]; then 228 | AdGuardHome_PORT="0" 229 | fi 230 | config_get "redirect" "$section" "redirect" "none" 231 | config_get "old_redirect" "$section" "old_redirect" "none" 232 | config_get "old_port" "$section" "old_port" "0" 233 | config_get "old_enabled" "$section" "old_enabled" "0" 234 | uci get dhcp.@dnsmasq[0].port >/dev/null 2>&1 || uci set dhcp.@dnsmasq[0].port="53" >/dev/null 2>&1 235 | if [ "$old_enabled" = "1" -a "$old_redirect" == "exchange" ]; then 236 | AdGuardHome_PORT=$(uci get dhcp.@dnsmasq[0].port 2>/dev/null) 237 | fi 238 | 239 | if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$AdGuardHome_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then 240 | if [ "$old_redirect" != "none" ]; then 241 | if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then 242 | clear_iptable "$old_port" "$ipv6_server" 243 | elif [ "$old_redirect" == "dnsmasq-upstream" ]; then 244 | stop_forward_dnsmasq "$old_port" 245 | elif [ "$old_redirect" == "exchange" ]; then 246 | rm_port53 247 | fi 248 | fi 249 | elif [ "$old_enabled" = "1" -a "$enabled" = "1" ]; then 250 | if [ "$old_redirect" == "redirect" -a "$old_port" != "0" ]; then 251 | clear_iptable "$old_port" "$ipv6_server" 252 | fi 253 | fi 254 | uci delete AdGuardHome.@AdGuardHome[0].old_redirect 2>/dev/null 255 | uci delete AdGuardHome.@AdGuardHome[0].old_port 2>/dev/null 256 | uci delete AdGuardHome.@AdGuardHome[0].old_enabled 2>/dev/null 257 | uci add_list AdGuardHome.@AdGuardHome[0].old_redirect="$redirect" 2>/dev/null 258 | uci add_list AdGuardHome.@AdGuardHome[0].old_port="$AdGuardHome_PORT" 2>/dev/null 259 | uci add_list AdGuardHome.@AdGuardHome[0].old_enabled="$enabled" 2>/dev/null 260 | uci commit AdGuardHome 261 | [ "$enabled" == "0" ] && return 1 262 | if [ "$AdGuardHome_PORT" == "0" ]; then 263 | return 1 264 | fi 265 | if [ "$redirect" = "redirect" ]; then 266 | set_iptable $ipv6_server $tcp_server 267 | elif [ "$redirect" = "dnsmasq-upstream" ]; then 268 | set_forward_dnsmasq "$AdGuardHome_PORT" 269 | elif [ "$redirect" == "exchange" -a "$(uci get dhcp.@dnsmasq[0].port 2>/dev/null)" == "53" ]; then 270 | use_port53 271 | fi 272 | } 273 | get_filesystem() 274 | { 275 | # print out path filesystem 276 | echo $1 | awk ' 277 | BEGIN{ 278 | while (("mount"| getline ret) > 0) 279 | { 280 | split(ret,d); 281 | fs[d[3]]=d[5]; 282 | m=index(d[1],":") 283 | if (m==0) 284 | { 285 | pt[d[3]]=d[1] 286 | }else{ 287 | pt[d[3]]=substr(d[1],m+1) 288 | }}}{ 289 | split($0,d,"/"); 290 | if ("/" in fs) 291 | { 292 | result1=fs["/"]; 293 | } 294 | if ("/" in pt) 295 | { 296 | result2=pt["/"]; 297 | } 298 | for (i=2;i<=length(d);i++) 299 | { 300 | p[i]=p[i-1]"/"d[i]; 301 | if (p[i] in fs) 302 | { 303 | result1=fs[p[i]]; 304 | result2=pt[p[i]]; 305 | } 306 | } 307 | if (result2 in fs){ 308 | result=fs[result2]} 309 | else{ 310 | result=result1} 311 | print(result);}' 312 | } 313 | 314 | config_editor() 315 | { 316 | awk -v yaml="$1" -v value="$2" -v file="$3" -v ro="$4" ' 317 | BEGIN{split(yaml,part,"\.");s="";i=1;l=length(part);} 318 | { 319 | if (match($0,s""part[i]":")) 320 | { 321 | if (i==l) 322 | { 323 | split($0,t,": "); 324 | if (ro==""){ 325 | system("sed -i '\''"FNR"c \\"t[1]": "value"'\'' "file); 326 | }else{ 327 | print(t[2]); 328 | } 329 | exit; 330 | } 331 | s=s"[- ]{2}"; 332 | i++; 333 | } 334 | }' $3 335 | } 336 | 337 | boot_service() { 338 | rm /var/run/AdGserverdis >/dev/null 2>&1 339 | config_load "${CONFIGURATION}" 340 | config_get waitonboot $CONFIGURATION waitonboot "0" 341 | config_get_bool enabled $CONFIGURATION enabled 0 342 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome" 343 | [ -f "$binpath" ] && start_service 344 | if [ "$enabled" == "1" ] && [ "$waitonboot" == "1" ]; then 345 | procd_open_instance "waitnet" 346 | procd_set_param command "/usr/share/AdGuardHome/waitnet.sh" 347 | procd_close_instance 348 | echo "no net start pinging" 349 | fi 350 | } 351 | 352 | testbackup(){ 353 | config_load "${CONFIGURATION}" 354 | if [ "$1" == "backup" ]; then 355 | backup 356 | elif [ "$1" == "restore" ]; then 357 | restore 358 | fi 359 | } 360 | restore() 361 | { 362 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace" 363 | config_get backupwdpath $CONFIGURATION backupwdpath "/etc/config/adGuardConfig/workspace" 364 | cp -u -r -f $backupwdpath/data $workdir 365 | } 366 | backup() { 367 | config_get backupwdpath $CONFIGURATION backupwdpath "/etc/config/adGuardConfig/workspace" 368 | mkdir -p $backupwdpath/data 369 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace" 370 | config_get backupfile $CONFIGURATION backupfile "" 371 | for one in $backupfile; 372 | do 373 | while : 374 | do 375 | if [ -d "$backupwdpath/data/$one" ]; then 376 | cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data 2>&1) 377 | else 378 | cpret=$(cp -u -r -f $workdir/data/$one $backupwdpath/data/$one 2>&1) 379 | fi 380 | echo "$cpret" 381 | echo "$cpret" | grep "no space left on device" 382 | if [ "$?" == "0" ]; then 383 | echo "磁盘已满,删除log重试中" 384 | del_querylog && continue 385 | rm -f -r $backupwdpath/data/filters 386 | rm -f -r $workdir/data/filters && continue 387 | echo "backup failed" 388 | fi 389 | break 390 | done 391 | done 392 | } 393 | start_service() { 394 | # Reading config 395 | rm /var/run/AdGserverdis >/dev/null 2>&1 396 | config_load "${CONFIGURATION}" 397 | # update password 398 | config_get hashpass $CONFIGURATION hashpass "" 399 | config_get configpath $CONFIGURATION configpath "/etc/config/adGuardConfig/AdGuardHome.yaml" 400 | if [ -n "$hashpass" ]; then 401 | config_editor "users.password" "$hashpass" "$configpath" 402 | uci set $CONFIGURATION.$CONFIGURATION.hashpass="" 403 | fi 404 | local enabled 405 | config_get_bool enabled $CONFIGURATION enabled 0 406 | # update crontab 407 | do_crontab 408 | if [ "$enabled" == "0" ]; then 409 | _do_redirect 0 410 | return 411 | fi 412 | #what need to do before reload 413 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace" 414 | 415 | config_get backupfile $CONFIGURATION backupfile "" 416 | mkdir -p $workdir/data 417 | if [ -n "$backupfile" ] && [ ! -d "$workdir/data" ]; then 418 | restore 419 | fi 420 | # for overlay data-stk-oo not suppport 421 | local cwdfs=$(get_filesystem $workdir) 422 | echo "workdir is a $cwdfs filesystem" 423 | if [ "$cwdfs" == "jffs2" ]; then 424 | echo "fs error ln db to tmp $workdir $cwdfs" 425 | logger "AdGuardHome" "warning db redirect to tmp" 426 | touch $workdir/data/stats.db 427 | if [ ! -L $workdir/data/stats.db ]; then 428 | mv -f $workdir/data/stats.db /tmp/stats.db 2>/dev/null 429 | ln -s /tmp/stats.db $workdir/data/stats.db 2>/dev/null 430 | fi 431 | touch $workdir/data/sessions.db 432 | if [ ! -L $workdir/data/sessions.db ]; then 433 | mv -f $workdir/data/sessions.db /tmp/sessions.db 2>/dev/null 434 | ln -s /tmp/sessions.db $workdir/data/sessions.db 2>/dev/null 435 | fi 436 | fi 437 | local ADDITIONAL_ARGS="" 438 | config_get binpath $CONFIGURATION binpath "/etc/config/adGuardConfig/AdGuardHome" 439 | 440 | mkdir -p ${binpath%/*} 441 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -c $configpath" 442 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -w $workdir" 443 | config_get httpport $CONFIGURATION httpport 3000 444 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -p $httpport" 445 | 446 | # hack to save config file when upgrade system 447 | config_get upprotect $CONFIGURATION upprotect "" 448 | eval upprotect=${upprotect// /\\\\n} 449 | echo -e "$upprotect">/lib/upgrade/keep.d/luci-app-adguardhome 450 | 451 | config_get logfile $CONFIGURATION logfile "" 452 | if [ -n "$logfile" ]; then 453 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -l $logfile" 454 | fi 455 | 456 | if [ ! -f "$binpath" ]; then 457 | _do_redirect 0 458 | /usr/share/AdGuardHome/update_core.sh 2>&1 >/tmp/AdGuardHome_update.log & 459 | exit 0 460 | fi 461 | 462 | config_get_bool verbose $CONFIGURATION verbose 0 463 | if [ "$verbose" -eq 1 ]; then 464 | ADDITIONAL_ARGS="$ADDITIONAL_ARGS -v" 465 | fi 466 | 467 | procd_open_instance 468 | get_tz 469 | if [ -n "$SET_TZ" ]; then 470 | procd_set_param env TZ="$SET_TZ" 471 | fi 472 | procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} 473 | procd_set_param limits core="unlimited" nofile="65535 65535" 474 | procd_set_param stderr 1 475 | procd_set_param command $binpath $ADDITIONAL_ARGS 476 | procd_set_param file "$configpath" "/etc/hosts" "/etc/config/AdGuardHome" 477 | procd_close_instance 478 | if [ -f "$configpath" ]; then 479 | _do_redirect 1 480 | else 481 | _do_redirect 0 482 | config_get "redirect" "AdGuardHome" "redirect" "none" 483 | if [ "$redirect" != "none" ]; then 484 | procd_open_instance "waitconfig" 485 | procd_set_param command "/usr/share/AdGuardHome/watchconfig.sh" 486 | procd_close_instance 487 | echo "no config start watching" 488 | fi 489 | fi 490 | echo "AdGuardHome service enabled" 491 | echo "luci enable switch=$enabled" 492 | (sleep 10 && [ -z "$(pgrep $binpath)" ] && logger "AdGuardHome" "no process in 10s cancel redirect" && _do_redirect 0 )& 493 | } 494 | reload_service() 495 | { 496 | rm /var/run/AdGlucitest >/dev/null 2>&1 497 | echo "AdGuardHome reloading" 498 | start 499 | } 500 | 501 | del_querylog(){ 502 | local btarget=$(ls $backupwdpath/data | grep -F "querylog.json" | sort -r | head -n 1) 503 | local wtarget=$(ls $workdir/data | grep -F "querylog.json" | sort -r | head -n 1) 504 | if [ "$btarget"x == "$wtarget"x ]; then 505 | [ -z "$btarget" ] && return 1 506 | rm -f $workdir/data/$wtarget 507 | rm -f $backupwdpath/data/$btarget 508 | return 0 509 | fi 510 | if [ "$btarget" \> "$wtarget" ]; then 511 | rm -f $backupwdpath/data/$btarget 512 | return 0 513 | else 514 | rm -f $workdir/data/$wtarget 515 | return 0 516 | fi 517 | } 518 | stop_service() 519 | { 520 | config_load "${CONFIGURATION}" 521 | _do_redirect 0 522 | do_crontab 523 | if [ "$1" != "nobackup" ]; then 524 | config_get backupfile $CONFIGURATION backupfile "0" 525 | if [ -n "$backupfile" ]; then 526 | backup 527 | fi 528 | fi 529 | echo "AdGuardHome service disabled" 530 | touch /var/run/AdGserverdis 531 | } 532 | boot() { 533 | rc_procd boot_service "$@" 534 | if eval "type service_started" 2>/dev/null >/dev/null; then 535 | service_started 536 | fi 537 | } 538 | test_crontab(){ 539 | config_load "${CONFIGURATION}" 540 | do_crontab 541 | } 542 | do_crontab(){ 543 | config_get_bool enabled $CONFIGURATION enabled 0 544 | config_get crontab $CONFIGURATION crontab "" 545 | local findstr default cronenable replace commit 546 | local cronreload=0 547 | local commit=0 548 | findstr="/usr/share/AdGuardHome/update_core.sh" 549 | default="30 3 * * * /usr/share/AdGuardHome/update_core.sh 2>&1" 550 | [ "$enabled" == "0" ] || [ "${crontab//autoupdate/}" == "$crontab" ] && cronenable=0 || cronenable=1 551 | crontab_editor 552 | 553 | config_get workdir $CONFIGURATION workdir "/etc/config/adGuardConfig/workspace" 554 | config_get lastworkdir $CONFIGURATION lastworkdir "/etc/config/adGuardConfig/workspace" 555 | findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json" 556 | #[ -n "$lastworkdir" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastworkdir/data/querylog.json" && [ "$lastworkdir" != "$workdir" ] && replace="${lastworkdir//\//\\/}/${workdir//\//\\/}" 557 | default="0 * * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.workdir)/data/querylog.json" 558 | [ "$enabled" == "0" ] || [ "${crontab//cutquerylog/}" == "$crontab" ] && cronenable=0 || cronenable=1 559 | crontab_editor 560 | #[ "$lastworkdir" != "$workdir" ] && uci set AdGuardHome.AdGuardHome.lastworkdir="$workdir" && commit=1 561 | 562 | config_get logfile $CONFIGURATION logfile "" 563 | config_get lastlogfile $CONFIGURATION lastlogfile "" 564 | findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* \$(uci get AdGuardHome.AdGuardHome.logfile)" 565 | default="30 3 * * * /usr/share/AdGuardHome/tailto.sh 2000 \$(uci get AdGuardHome.AdGuardHome.logfile)" 566 | #[ -n "$lastlogfile" ] && findstr="/usr/share/AdGuardHome/tailto.sh [0-9]* $lastlogfile" && [ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && replace="${lastlogfile//\//\\/}/${logfile//\//\\/}" 567 | [ "$logfile" == "syslog" ] || [ "$logfile" == "" ] || [ "$enabled" == "0" ] || [ "${crontab//cutruntimelog/}" == "$crontab" ] && cronenable=0 || cronenable=1 568 | crontab_editor 569 | #[ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && uci set AdGuardHome.AdGuardHome.lastlogfile="$logfile" && commit=1 570 | 571 | findstr="/usr/share/AdGuardHome/addhost.sh" 572 | default="0 * * * * /usr/share/AdGuardHome/addhost.sh" 573 | [ "$enabled" == "0" ] || [ "${crontab//autohost/}" == "$crontab" ] && cronenable=0 || cronenable=1 574 | crontab_editor 575 | [ "$cronenable" == "0" ] && /usr/share/AdGuardHome/addhost.sh "del" "noreload" || /usr/share/AdGuardHome/addhost.sh "" "noreload" 576 | 577 | findstr="/usr/share/AdGuardHome/gfw2adg.sh" 578 | default="30 3 * * * /usr/share/AdGuardHome/gfw2adg.sh" 579 | [ "$enabled" == "0" ] || [ "${crontab//autogfw/}" == "$crontab" ] && cronenable=0 || cronenable=1 580 | crontab_editor 581 | [ "$cronreload" -gt 0 ] && /etc/init.d/cron restart 582 | #[ "$commit" -gt 0 ] && uci commit AdGuardHome 583 | } 584 | crontab_editor(){ 585 | #usage input: 586 | #findstr= 587 | #default= 588 | #cronenable= 589 | #replace="${last//\//\\/}/${now//\//\\/}" 590 | #output:cronreload:if >1 please /etc/init.d/cron restart manual 591 | local testline reload 592 | local line="$(grep "$findstr" $CRON_FILE)" 593 | [ -n "$replace" ] && [ -n "$line" ] && eval testline="\${line//$replace}" && [ "$testline" != "$line" ] && line="$testline" && reload="1" && replace="" 594 | if [ "${line:0:1}" != "#" ]; then 595 | if [ $cronenable -eq 1 ]; then 596 | [ -z "$line" ] && line="$default" && reload="1" 597 | if [ -n "$reload" ]; then 598 | sed -i "\,$findstr,d" $CRON_FILE 599 | echo "$line" >> $CRON_FILE 600 | cronreload=$((cronreload+1)) 601 | fi 602 | elif [ -n "$line" ]; then 603 | sed -i "\,$findstr,d" $CRON_FILE 604 | echo "#$line" >> $CRON_FILE 605 | cronreload=$((cronreload+1)) 606 | fi 607 | else 608 | if [ $cronenable -eq 1 ]; then 609 | sed -i "\,$findstr,d" $CRON_FILE 610 | echo "${line:1}" >> $CRON_FILE 611 | cronreload=$((cronreload+1)) 612 | elif [ -z "$reload" ]; then 613 | sed -i "\,$findstr,d" $CRON_FILE 614 | echo "$line" >> $CRON_FILE 615 | fi 616 | fi 617 | 618 | } 619 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 2>&1 4 | delete ucitrack.@AdGuardHome[-1] 5 | add ucitrack AdGuardHome 6 | set ucitrack.@AdGuardHome[-1].init=AdGuardHome 7 | commit ucitrack 8 | delete AdGuardHome.AdGuardHome.ucitracktest 9 | EOF 10 | 11 | rm -f /tmp/luci-indexcache 12 | exit 0 13 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml: -------------------------------------------------------------------------------- 1 | #提交就可以直接用的配置模板文件 2 | #a template config can be use with a apply 3 | bind_host: 0.0.0.0 4 | bind_port: 3000 5 | users: 6 | - name: root 7 | password: $2y$10$FfeQavihMUiXCuJhHuQwy.6EOXDvkXb/S50qI5fXizqarNT/ShhQm 8 | language: "" 9 | rlimit_nofile: 0 10 | dns: 11 | bind_host: 0.0.0.0 12 | port: 5553 13 | statistics_interval: 1 14 | protection_enabled: true 15 | filtering_enabled: true 16 | filters_update_interval: 24 17 | blocking_mode: nxdomain 18 | blocked_response_ttl: 10 19 | querylog_enabled: false 20 | querylog_interval: 1 21 | ratelimit: 0 22 | ratelimit_whitelist: [] 23 | refuse_any: false 24 | bootstrap_dns: 25 | #bootstrap_dns 26 | all_servers: false 27 | allowed_clients: [] 28 | disallowed_clients: [] 29 | blocked_hosts: [] 30 | parental_block_host: "" 31 | safebrowsing_block_host: "" 32 | blocked_services: [] 33 | cache_size: 4194304 34 | parental_sensitivity: 13 35 | parental_enabled: false 36 | safesearch_enabled: false 37 | safebrowsing_enabled: false 38 | safebrowsing_cache_size: 1048576 39 | safesearch_cache_size: 1048576 40 | parental_cache_size: 1048576 41 | cache_time: 30 42 | rewrites: [] 43 | upstream_dns: 44 | #upstream_dns 45 | tls: 46 | enabled: false 47 | server_name: "" 48 | force_https: false 49 | port_https: 443 50 | port_dns_over_tls: 853 51 | certificate_chain: "" 52 | private_key: "" 53 | certificate_path: "" 54 | private_key_path: "" 55 | filters: 56 | - enabled: true 57 | url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt 58 | name: AdGuard Simplified Domain Names filter 59 | id: 1 60 | - enabled: true 61 | url: https://adaway.org/hosts.txt 62 | name: AdAway 63 | id: 2 64 | - enabled: false 65 | url: https://hosts-file.net/ad_servers.txt 66 | name: hpHosts - Ad and Tracking servers only 67 | id: 3 68 | - enabled: true 69 | url: https://www.malwaredomainlist.com/hostslist/hosts.txt 70 | name: MalwareDomainList.com Hosts List 71 | id: 4 72 | - enabled: false 73 | url: https://raw.githubusercontent.com/vokins/yhosts/master/data/tvbox.txt 74 | name: tvbox 75 | id: 1575018007 76 | - enabled: true 77 | url: https://hosts.nfz.moe/full/hosts 78 | name: neoHosts full 79 | id: 1575618240 80 | - enabled: false 81 | url: https://hosts.nfz.moe/basic/hosts 82 | name: neoHosts basic 83 | id: 1575618241 84 | - enabled: false 85 | url: http://sbc.io/hosts/hosts 86 | name: StevenBlack host basic 87 | id: 1575618242 88 | - enabled: false 89 | url: http://sbc.io/hosts/alternates/fakenews-gambling-porn-social/hosts 90 | name: StevenBlack host+fakenews + gambling + porn + social 91 | id: 1575618243 92 | - enabled: false 93 | url: https://cdn.jsdelivr.net/gh/privacy-protection-tools/anti-AD/anti-ad-easylist.txt 94 | name: anti-AD(Adblock+neohosts+yhosts+cjxlist+adhlist) 95 | id: 1577113202 96 | user_rules: [] 97 | dhcp: 98 | enabled: false 99 | interface_name: "" 100 | gateway_ip: "" 101 | subnet_mask: "" 102 | range_start: "" 103 | range_end: "" 104 | lease_duration: 86400 105 | icmp_timeout_msec: 1000 106 | clients: [] 107 | log_file: "" 108 | verbose: false 109 | schema_version: 5 -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | checkmd5(){ 3 | local nowmd5=$(md5sum /etc/hosts) 4 | nowmd5=${nowmd5%% *} 5 | local lastmd5=$(uci get AdGuardHome.AdGuardHome.hostsmd5 2>/dev/null) 6 | if [ "$nowmd5" != "$lastmd5" ]; then 7 | uci set AdGuardHome.AdGuardHome.hostsmd5="$nowmd5" 8 | uci commit AdGuardHome 9 | [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload 10 | fi 11 | } 12 | [ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' /etc/hosts && checkmd5 "$2" && exit 0 13 | /usr/bin/awk 'BEGIN{ 14 | while ((getline < "/tmp/dhcp.leases") > 0) 15 | { 16 | a[$2]=$4; 17 | } 18 | while (("ip -6 neighbor show | grep -v fe80" | getline) > 0) 19 | { 20 | if (a[$5]) {print $1" "a[$5] >"/tmp/tmphost"; } 21 | } 22 | print "#programaddend" >"/tmp/tmphost"; 23 | }' 24 | grep programaddstart /etc/hosts >/dev/null 2>&1 25 | if [ "$?" == "0" ]; then 26 | sed -i '/programaddstart/,/programaddend/c\#programaddstart' /etc/hosts 27 | sed -i '/programaddstart/'r/tmp/tmphost /etc/hosts 28 | else 29 | echo "#programaddstart" >>/etc/hosts 30 | cat /tmp/tmphost >> /etc/hosts 31 | fi 32 | rm /tmp/tmphost 33 | checkmd5 "$2" -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AdGuardHome_enable=$(uci get AdGuardHome.AdGuardHome.enabled) 4 | redirect=$(uci get AdGuardHome.AdGuardHome.redirect) 5 | 6 | if [ $AdGuardHome_enable -eq 1 -a "$redirect" == "redirect" ]; then 7 | /etc/init.d/AdGuardHome do_redirect 1 8 | fi 9 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin" 3 | logread -e AdGuardHome > /tmp/AdGuardHometmp.log 4 | logread -e AdGuardHome -f >> /tmp/AdGuardHometmp.log & 5 | pid=$! 6 | echo "1">/var/run/AdGuardHomesyslog 7 | while true 8 | do 9 | sleep 12 10 | watchdog=$(cat /var/run/AdGuardHomesyslog) 11 | if [ "$watchdog"x == "0"x ]; then 12 | kill $pid 13 | rm /tmp/AdGuardHometmp.log 14 | rm /var/run/AdGuardHomesyslog 15 | exit 0 16 | else 17 | echo "0">/var/run/AdGuardHomesyslog 18 | fi 19 | done -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin" 3 | checkmd5(){ 4 | local nowmd5=$(md5sum /tmp/adguard.list 2>/dev/null) 5 | nowmd5=${nowmd5%% *} 6 | local lastmd5=$(uci get AdGuardHome.AdGuardHome.gfwlistmd5 2>/dev/null) 7 | 8 | if [ "$nowmd5" != "$lastmd5" ]; then 9 | uci set AdGuardHome.AdGuardHome.gfwlistmd5="$nowmd5" 10 | uci commit AdGuardHome 11 | [ "$1" == "noreload" ] || /etc/init.d/AdGuardHome reload 12 | fi 13 | } 14 | 15 | configpath=$(uci get AdGuardHome.AdGuardHome.configpath 2>/dev/null) 16 | [ "$1" == "del" ] && sed -i '/programaddstart/,/programaddend/d' $configpath && checkmd5 "$2" && exit 0 17 | gfwupstream=$(uci get AdGuardHome.AdGuardHome.gfwupstream 2>/dev/null) 18 | 19 | if [ -z $gfwupstream ]; then 20 | gfwupstream="tcp://208.67.220.220:5353" 21 | fi 22 | 23 | if [ ! -f "$configpath" ]; then 24 | echo "please make a config first" 25 | exit 1 26 | fi 27 | 28 | wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O- | base64 -d > /tmp/gfwlist.txt 29 | cat /tmp/gfwlist.txt | awk -v upst="$gfwupstream" 'BEGIN{getline;}{ 30 | s1=substr($0,1,1); 31 | if (s1=="!") 32 | {next;} 33 | if (s1=="@"){ 34 | $0=substr($0,3); 35 | s1=substr($0,1,1); 36 | white=1;} 37 | else{ 38 | white=0; 39 | } 40 | 41 | if (s1=="|") 42 | {s2=substr($0,2,1); 43 | if (s2=="|") 44 | { 45 | $0=substr($0,3); 46 | split($0,d,"/"); 47 | $0=d[1]; 48 | }else{ 49 | split($0,d,"/"); 50 | $0=d[3]; 51 | }} 52 | else{ 53 | split($0,d,"/"); 54 | $0=d[1]; 55 | } 56 | star=index($0,"*"); 57 | if (star!=0) 58 | { 59 | $0=substr($0,star+1); 60 | dot=index($0,"."); 61 | if (dot!=0) 62 | $0=substr($0,dot+1); 63 | else 64 | next; 65 | s1=substr($0,1,1); 66 | } 67 | if (s1==".") 68 | {fin=substr($0,2);} 69 | else{fin=$0;} 70 | if (index(fin,".")==0) next; 71 | if (index(fin,"%")!=0) next; 72 | if (index(fin,":")!=0) next; 73 | match(fin,"^[0-9\.]+") 74 | if (RSTART==1 && RLENGTH==length(fin)) {print "ipset add gfwlist "fin>"/tmp/doipset.sh";next;} 75 | if (fin=="" || finl==fin) next; 76 | finl=fin; 77 | if (white==0) 78 | {print(" - '\''[/"fin"/]"upst"'\''");} 79 | else{ 80 | print(" - '\''[/"fin"/]#'\''");} 81 | }END{print(" - '\''[/programaddend/]#'\''")}' > /tmp/adguard.list 82 | 83 | grep programaddstart $configpath 84 | 85 | if [ "$?" == "0" ]; then 86 | sed -i '/programaddstart/,/programaddend/c\ - '\''\[\/programaddstart\/\]#'\''' $configpath 87 | sed -i '/programaddstart/'r/tmp/adguard.list $configpath 88 | else 89 | sed -i '1i\ - '\''[/programaddstart/]#'\''' /tmp/adguard.list 90 | sed -i '/upstream_dns:/'r/tmp/adguard.list $configpath 91 | fi 92 | 93 | checkmd5 "$2" 94 | 95 | rm -f /tmp/gfwlist.txt /tmp/adguard.list -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt: -------------------------------------------------------------------------------- 1 | https://github.com/AdguardTeam/AdGuardHome/releases/download/${latest_ver}/AdGuardHome_linux_${Arch}.tar.gz 2 | https://static.adguard.com/adguardhome/release/AdGuardHome_linux_${Arch}.tar.gz 3 | #https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_${Arch}.tar.gz -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | tail -n $1 "$2" > /var/run/tailtmp 3 | cat /var/run/tailtmp > "$2" 4 | rm /var/run/tailtmp -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin" 3 | binpath=$(uci get AdGuardHome.AdGuardHome.binpath) 4 | 5 | if [ -z "$binpath" ]; then 6 | uci set AdGuardHome.AdGuardHome.binpath="/tmp/AdGuardHome/AdGuardHome" 7 | binpath="/tmp/AdGuardHome/AdGuardHome" 8 | fi 9 | 10 | mkdir -p ${binpath%/*} 11 | upxflag=$(uci get AdGuardHome.AdGuardHome.upxflag 2>/dev/null) 12 | 13 | check_if_already_running(){ 14 | running_tasks="$(ps |grep "AdGuardHome" |grep "update_core" |grep -v "grep" |awk '{print $1}' |wc -l)" 15 | [ "${running_tasks}" -gt "2" ] && echo -e "\nA task is already running." && EXIT 2 16 | } 17 | 18 | check_wgetcurl(){ 19 | which curl && downloader="curl -L -k --retry 2 --connect-timeout 20 -o" && return 20 | which wget-ssl && downloader="wget-ssl --no-check-certificate -t 2 -T 20 -O" && return 21 | [ -z "$1" ] && opkg update || (echo error opkg && EXIT 1) 22 | [ -z "$1" ] && (opkg remove wget wget-nossl --force-depends ; opkg install wget ; check_wgetcurl 1 ;return) 23 | [ "$1" == "1" ] && (opkg install curl ; check_wgetcurl 2 ; return) 24 | echo error curl and wget && EXIT 1 25 | } 26 | 27 | check_latest_version(){ 28 | check_wgetcurl 29 | latest_ver="$($downloader - https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E 'v[0-9.]+' -o 2>/dev/null)" 30 | 31 | if [ -z "${latest_ver}" ]; then 32 | echo -e "\nFailed to check latest version, please try again later." && EXIT 1 33 | fi 34 | 35 | now_ver="$($binpath -c /dev/null --check-config 2>&1| grep -m 1 -E 'v[0-9.]+' -o)" 36 | 37 | if [ "${latest_ver}"x != "${now_ver}"x ] || [ "$1" == "force" ]; then 38 | echo -e "Local version: ${now_ver}., cloud version: ${latest_ver}." 39 | doupdate_core 40 | else 41 | echo -e "\nLocal version: ${now_ver}, cloud version: ${latest_ver}." 42 | echo -e "You're already using the latest version." 43 | if [ ! -z "$upxflag" ]; then 44 | filesize=$(ls -l $binpath | awk '{ print $5 }') 45 | if [ $filesize -gt 8000000 ]; then 46 | echo -e "start upx may take a long time" 47 | doupx 48 | mkdir -p "/tmp/AdGuardHomeupdate/AdGuardHome" >/dev/null 2>&1 49 | rm -fr /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} 50 | /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $binpath -o /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} 51 | rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux 52 | /etc/init.d/AdGuardHome stop nobackup 53 | rm $binpath 54 | mv -f /tmp/AdGuardHomeupdate/AdGuardHome/${binpath##*/} $binpath 55 | /etc/init.d/AdGuardHome start 56 | echo -e "finished" 57 | fi 58 | fi 59 | EXIT 0 60 | fi 61 | } 62 | 63 | doupx(){ 64 | Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')" 65 | case $Archt in 66 | "i386") 67 | Arch="i386" 68 | ;; 69 | "i686") 70 | Arch="i386" 71 | echo -e "i686 use $Arch may have bug" 72 | ;; 73 | "x86") 74 | Arch="amd64" 75 | ;; 76 | "mipsel") 77 | Arch="mipsel" 78 | ;; 79 | "mips64el") 80 | Arch="mips64el" 81 | Arch="mipsel" 82 | echo -e "mips64el use $Arch may have bug" 83 | ;; 84 | "mips") 85 | Arch="mips" 86 | ;; 87 | "mips64") 88 | Arch="mips64" 89 | Arch="mips" 90 | echo -e "mips64 use $Arch may have bug" 91 | ;; 92 | "arm") 93 | Arch="arm" 94 | ;; 95 | "armeb") 96 | Arch="armeb" 97 | ;; 98 | "aarch64") 99 | Arch="arm64" 100 | ;; 101 | "powerpc") 102 | Arch="powerpc" 103 | ;; 104 | "powerpc64") 105 | Arch="powerpc64" 106 | ;; 107 | *) 108 | echo -e "error not support $Archt if you can use offical release please issue a bug" 109 | EXIT 1 110 | ;; 111 | esac 112 | upx_latest_ver="$($downloader - https://api.github.com/repos/upx/upx/releases/latest 2>/dev/null|grep -E 'tag_name' |grep -E '[0-9.]+' -o 2>/dev/null)" 113 | $downloader /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz "https://github.com/upx/upx/releases/download/v${upx_latest_ver}/upx-${upx_latest_ver}-${Arch}_linux.tar.xz" 2>&1 114 | #tar xvJf 115 | which xz || (opkg list | grep ^xz || opkg update && opkg install xz) || (echo "xz download fail" && EXIT 1) 116 | mkdir -p /tmp/upx-${upx_latest_ver}-${Arch}_linux 117 | xz -d -c /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz| tar -x -C "/tmp" >/dev/null 2>&1 118 | if [ ! -e "/tmp/upx-${upx_latest_ver}-${Arch}_linux/upx" ]; then 119 | echo -e "Failed to download upx." 120 | EXIT 1 121 | fi 122 | rm /tmp/upx-${upx_latest_ver}-${Arch}_linux.tar.xz 123 | } 124 | 125 | doupdate_core(){ 126 | echo -e "Updating core..." 127 | mkdir -p "/tmp/AdGuardHomeupdate" 128 | rm -rf /tmp/AdGuardHomeupdate/* >/dev/null 2>&1 129 | Archt="$(opkg info kernel | grep Architecture | awk -F "[ _]" '{print($2)}')" 130 | case $Archt in 131 | "i386") 132 | Arch="386" 133 | ;; 134 | "i686") 135 | Arch="386" 136 | ;; 137 | "x86") 138 | Arch="amd64" 139 | ;; 140 | "mipsel") 141 | Arch="mipsle" 142 | ;; 143 | "mips64el") 144 | Arch="mips64le" 145 | Arch="mipsle" 146 | echo -e "mips64el use $Arch may have bug" 147 | ;; 148 | "mips") 149 | Arch="mips" 150 | ;; 151 | "mips64") 152 | Arch="mips64" 153 | Arch="mips" 154 | echo -e "mips64 use $Arch may have bug" 155 | ;; 156 | "arm") 157 | Arch="arm" 158 | ;; 159 | "aarch64") 160 | Arch="arm64" 161 | ;; 162 | "powerpc") 163 | Arch="ppc" 164 | echo -e "error not support $Archt" 165 | EXIT 1 166 | ;; 167 | "powerpc64") 168 | Arch="ppc64" 169 | echo -e "error not support $Archt" 170 | EXIT 1 171 | ;; 172 | *) 173 | echo -e "error not support $Archt if you can use offical release please issue a bug" 174 | EXIT 1 175 | ;; 176 | esac 177 | echo -e "start download" 178 | grep -v "^#" /usr/share/AdGuardHome/links.txt >/tmp/run/AdHlinks.txt 179 | while read link 180 | do 181 | eval link="$link" 182 | $downloader /tmp/AdGuardHomeupdate/${link##*/} "$link" 2>&1 183 | if [ "$?" != "0" ]; then 184 | echo "download failed try another download" 185 | rm -f /tmp/AdGuardHomeupdate/${link##*/} 186 | else 187 | local success="1" 188 | break 189 | fi 190 | done < "/tmp/run/AdHlinks.txt" 191 | rm /tmp/run/AdHlinks.txt 192 | [ -z "$success" ] && echo "no download success" && EXIT 1 193 | if [ "${link##*.}" == "gz" ]; then 194 | tar -zxf "/tmp/AdGuardHomeupdate/${link##*/}" -C "/tmp/AdGuardHomeupdate/" 195 | if [ ! -e "/tmp/AdGuardHomeupdate/AdGuardHome" ]; then 196 | echo -e "Failed to download core." 197 | rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1 198 | EXIT 1 199 | fi 200 | downloadbin="/tmp/AdGuardHomeupdate/AdGuardHome/AdGuardHome" 201 | else 202 | downloadbin="/tmp/AdGuardHomeupdate/${link##*/}" 203 | fi 204 | chmod 755 $downloadbin 205 | echo -e "download success start copy" 206 | if [ -n "$upxflag" ]; then 207 | echo -e "start upx may take a long time" 208 | doupx 209 | /tmp/upx-${upx_latest_ver}-${Arch}_linux/upx $upxflag $downloadbin 210 | rm -rf /tmp/upx-${upx_latest_ver}-${Arch}_linux 211 | fi 212 | echo -e "start copy" 213 | /etc/init.d/AdGuardHome stop nobackup 214 | rm "$binpath" 215 | mv -f "$downloadbin" "$binpath" 216 | if [ "$?" == "1" ]; then 217 | echo "mv failed maybe not enough space please use upx or change bin to /tmp/AdGuardHome" 218 | EXIT 1 219 | fi 220 | /etc/init.d/AdGuardHome start 221 | rm -rf "/tmp/AdGuardHomeupdate" >/dev/null 2>&1 222 | echo -e "Succeeded in updating core." 223 | echo -e "Local version: ${latest_ver}, cloud version: ${latest_ver}.\n" 224 | EXIT 0 225 | } 226 | 227 | EXIT(){ 228 | rm /var/run/update_core 2>/dev/null 229 | [ "$1" != "0" ] && touch /var/run/update_core_error 230 | exit $1 231 | } 232 | 233 | main(){ 234 | check_if_already_running 235 | check_latest_version $1 236 | } 237 | trap "EXIT 1" SIGTERM SIGINT 238 | touch /var/run/update_core 239 | rm /var/run/update_core_error 2>/dev/null 240 | main $1 241 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin" 3 | count=0 4 | while : 5 | do 6 | ping -c 1 -W 1 -q www.baidu.com 1>/dev/null 2>&1 7 | if [ "$?" == "0" ]; then 8 | /etc/init.d/AdGuardHome force_reload 9 | break 10 | fi 11 | ping -c 1 -W 1 -q 202.108.22.5 1>/dev/null 2>&1 12 | if [ "$?" == "0" ]; then 13 | /etc/init.d/AdGuardHome force_reload 14 | break 15 | fi 16 | sleep 5 17 | ping -c 1 -W 1 -q www.google.com 1>/dev/null 2>&1 18 | if [ "$?" == "0" ]; then 19 | /etc/init.d/AdGuardHome force_reload 20 | break 21 | fi 22 | ping -c 1 -W 1 -q 8.8.8.8 1>/dev/null 2>&1 23 | if [ "$?" == "0" ]; then 24 | /etc/init.d/AdGuardHome force_reload 25 | break 26 | fi 27 | sleep 5 28 | count=$((count+1)) 29 | if [ $count -gt 18 ]; then 30 | /etc/init.d/AdGuardHome force_reload 31 | break 32 | fi 33 | done 34 | return 0 -------------------------------------------------------------------------------- /luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | PATH="/usr/sbin:/usr/bin:/sbin:/bin" 3 | configpath=$(uci get AdGuardHome.AdGuardHome.configpath) 4 | while : 5 | do 6 | sleep 10 7 | if [ -f "$configpath" ]; then 8 | /etc/init.d/AdGuardHome do_redirect 1 9 | break 10 | fi 11 | done 12 | return 0 -------------------------------------------------------------------------------- /luci-app-adguardhome/root/www/luci-static/resources/codemirror/addon/fold/foldcode.js: -------------------------------------------------------------------------------- 1 | !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.linee.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=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.fromo.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&&ro))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}})}); -------------------------------------------------------------------------------- /luci-app-adguardhome/root/www/luci-static/resources/codemirror/lib/codemirror.css: -------------------------------------------------------------------------------- 1 | .CodeMirror{font-family:monospace;height:500px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:0;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:red}.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none !important;border:none !important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0} 2 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/www/luci-static/resources/codemirror/mode/yaml/yaml.js: -------------------------------------------------------------------------------- 1 | !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")}); -------------------------------------------------------------------------------- /luci-app-adguardhome/root/www/luci-static/resources/codemirror/theme/dracula.css: -------------------------------------------------------------------------------- 1 | .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} 2 | -------------------------------------------------------------------------------- /luci-app-adguardhome/root/www/luci-static/resources/twin-bcrypt.min.js: -------------------------------------------------------------------------------- 1 | /* @license 2 | * Twin-Bcrypt 2.2.0 3 | * https://github.com/fpirsch/twin-bcrypt 4 | * Licence: BSD-3-Clause 5 | */ 6 | !function(r,n){"use strict";function e(r){return y[g]=t.apply(n,r),g++}function t(r){var e=[].slice.call(arguments,1);return function(){"function"==typeof r?r.apply(n,e):new Function(""+r)()}}function o(r){if(m)setTimeout(t(o,r),0);else{var n=y[r];if(n){m=!0;try{n()}finally{a(r),m=!1}}}}function a(r){delete y[r]}function i(){p=function(){var r=e(arguments);return process.nextTick(t(o,r)),r}}function u(){if(r.postMessage&&!r.importScripts){var n=!0,e=r.onmessage;return r.onmessage=function(){n=!1},r.postMessage("","*"),r.onmessage=e,n}}function f(){var n="setImmediate$"+Math.random()+"$",t=function(e){e.source===r&&"string"==typeof e.data&&0===e.data.indexOf(n)&&o(+e.data.slice(n.length))};r.addEventListener?r.addEventListener("message",t,!1):r.attachEvent("onmessage",t),p=function(){var t=e(arguments);return r.postMessage(n+t,"*"),t}}function c(){var r=new MessageChannel;r.port1.onmessage=function(r){var n=r.data;o(n)},p=function(){var n=e(arguments);return r.port2.postMessage(n),n}}function s(){var r=v.documentElement;p=function(){var n=e(arguments),t=v.createElement("script");return t.onreadystatechange=function(){o(n),t.onreadystatechange=null,r.removeChild(t),t=null},r.appendChild(t),n}}function l(){p=function(){var r=e(arguments);return setTimeout(t(o,r),0),r}}if(!r.setImmediate){var p,g=1,y={},m=!1,v=r.document,d=Object.getPrototypeOf&&Object.getPrototypeOf(r);d=d&&d.setTimeout?d:r,"[object process]"==={}.toString.call(r.process)?i():u()?f():r.MessageChannel?c():v&&"onreadystatechange"in v.createElement("script")?s():l(),d.setImmediate=p,d.clearImmediate=a}}(new Function("return this")()),function(r){"object"==typeof exports?r(exports,require("crypto")):r(self.TwinBcrypt={},self.crypto||self.msCrypto)}(function(r,n){"use strict";function e(r){for(var n=unescape(encodeURIComponent(r)),e=n.length,t=new Array(e),o=0;e>o;o++)t[o]=n.charCodeAt(o);return t}function t(r){for(var n=r.length,e=new Array(n),t=0;n>t;t++)e[t]=r.charCodeAt(t);return e}function o(r,n){for(var e,t,o=0,a="";n>o;){if(e=255&r[o++],a+=B[e>>2],e=(3&e)<<4,o>=n){a+=B[e];break}if(t=255&r[o++],e|=t>>4,a+=B[e],e=(15&t)<<2,o>=n){a+=B[e];break}t=255&r[o++],e|=t>>6,a+=B[e],a+=B[63&t]}return a}function a(r){for(var n,e,t=new Array(16),o=0,a=0;;){if(n=D[r.charCodeAt(o++)-46],e=D[r.charCodeAt(o++)-46],t[a++]=255&(n<<2|e>>4),22===o)break;n=e<<4,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e>>2),n=e<<6,e=D[r.charCodeAt(o++)-46],t[a++]=255&(n|e)}return t}function i(r){for(var n=r.length,e=new Array(72),t=0,o=0;72>o;)e[o++]=r[t++],t===n&&(t=0);return e}function u(r,n,e){for(var t=0,o=e>>2;tt;)r[n++]=e[t++]<<24|e[t++]<<16|e[t++]<<8|e[t++]}function c(r){function n(n){for(var e=r,t=G>>2,o=t|O,f=n>>2,c=e[f]^e[t],s=e[1|f];o>t;)s^=(e[c>>>24]+e[a|c>>>16&255]^e[i|c>>>8&255])+e[u|255&c]^e[++t],c^=(e[s>>>24]+e[a|s>>>16&255]^e[i|s>>>8&255])+e[u|255&s]^e[++t];e[f]=s^e[S>>2],e[1|f]=c}function e(n){var e;for(r[L>>2]=0,r[L+4>>2]=0,e=0;M>e;e++)r[G>>2|e]^=r[(n>>2)+e];var t,o,f,c,s,l=r;for(e=0;M>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[G>>2|e]=l[f],r[G>>2|e+1]=c}for(e=0;T>e;e+=2){for(t=G>>2,o=t|O,f=L>>2,c=l[f]^l[t],s=l[1|f];o>t;)s^=(l[c>>>24]+l[a|c>>>16&255]^l[i|c>>>8&255])+l[u|255&c]^l[++t],c^=(l[s>>>24]+l[a|s>>>16&255]^l[i|s>>>8&255])+l[u|255&s]^l[++t];l[f]=s^l[S>>2],l[1|f]=c,r[e]=l[f],r[1|e]=c}}function t(r,n,t){for(var o=0;t>=o&&!(r>n);o++)e(R),e(j),r++;return r}var o=k>>2,a=o+256|0,i=a+256|0,u=i+256|0;return{encrypt:n,expandLoop:t}}function s(stdlib, foreign, heap) {"use asm";var HEAP32=new stdlib.Uint32Array(heap);var BLOWFISH_NUM_ROUNDS=16;var S_offset=0x0000;var S1_offset=0x0400;var S2_offset=0x0800;var S3_offset=0x0C00;var P_offset=0x1000;var P_last_offset=0x1044;var crypt_ciphertext_offset=0x1048;var LR_offset=0x01060;var password_offset=0x1068;var salt_offset=0x10b0;var P_LEN=18;var S_LEN=1024;function encrypt(offset) {offset=offset|0;var i=0;var n=0;var L=0;var R=0;var imax=0;imax=P_offset|BLOWFISH_NUM_ROUNDS<<2;L=HEAP32[offset>>2]|0;R=HEAP32[offset+4>>2]|0;L=L^HEAP32[P_offset>>2];for (i=P_offset; (i|0)<(imax|0);) {i=(i+4)>>>0;R=R^(((HEAP32[(L>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(L>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(L>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(L<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];i=(i+4)>>>0;L=L^(((HEAP32[(R>>>22)>>2]>>>0) +(HEAP32[(S1_offset|(R>>>14&0x3ff))>>2]>>>0) ^(HEAP32[(S2_offset|(R>>>6&0x3ff))>>2])) +(HEAP32[(S3_offset|(R<<2&0x3ff))>>2]>>>0))^HEAP32[i>>2];}HEAP32[offset>>2]=R^HEAP32[P_last_offset>>2];HEAP32[(offset+4)>>2]=L;}function expandKey(offset) {offset=offset|0;var i=0;var off=0;off=P_offset|0;for (i=0; (i|0)<(P_LEN|0); i=(i+1)|0) {HEAP32[off>>2]=HEAP32[off>>2]^HEAP32[offset>>2];offset=(offset+4)|0;off=(off+4)|0;}HEAP32[LR_offset>>2]=0;HEAP32[LR_offset+4>>2]=0;off=P_offset;for (i=0; (i|0)<(P_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}off=S_offset;for (i=0; (i|0)<(S_LEN|0); i=(i+2)|0) {encrypt(LR_offset);HEAP32[off>>2]=HEAP32[LR_offset>>2];HEAP32[off+4>>2]=HEAP32[LR_offset+4>>2];off=(off+8)|0;}}function expandLoop(i, counterEnd, maxIterations) {i=i|0;counterEnd=counterEnd|0;maxIterations=maxIterations|0;var j=0;for (j=0; (j|0) <= (maxIterations|0); j=(j+1)|0) {if ((i>>>0)>(counterEnd>>>0)) break;expandKey(password_offset);expandKey(salt_offset);i=(i+1)>>>0;}return i|0;}return {encrypt: encrypt,expandLoop: expandLoop};} 7 | function l(r,n,e,t){var o,a,i,u=L>>2,f=u+1;for(t[u]=0,t[f]=0,a=0,o=0;M>o;o++)i=n[a++]<<24|n[a++]<<16|n[a++]<<8|n[a++],t[G>>2|o]^=i;for(a=0,o=0;M>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[G>>2|o]=t[u],t[G>>2|o+1]=t[f];var c=k>>2;for(o=0;T>o;o+=2)i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[u]^=i,i=r[a++]<<24|r[a++]<<16|r[a++]<<8|r[a++],a&=65295,t[f]^=i,e.encrypt(L),t[c|o]=t[u],t[c|o+1]=t[f]}function p(r,n,e,t,o,a,i){for(var u=e;t>=u;){if(u=r.expandLoop(u,t,o),a){var f=a(u/(t+1));if(f===!1)return}if(u>t){if(i)return void setImmediate(g.bind(null,r,n,i));return}if(i)return void setImmediate(p.bind(null,r,n,u,t,o,a,i))}}function g(r,n,e){u(n,x,F);var t;for(t=0;64>t;t++)r.encrypt(F+0),r.encrypt(F+8),r.encrypt(F+16);var o,a=0,i=x.length,f=new Array(4*i);for(t=0;i>t;t++)o=n[(F>>2)+t],f[a++]=o>>24,f[a++]=o>>16&255,f[a++]=o>>8&255,f[a++]=255&o;return e&&e(f),f}function y(r,n){return r+o(n,23)}function m(n,o,m,v){var d,h=o.substr(0,29),w=+o.substr(4,2),A=o.substr(7,22);if("string"==typeof n)d=r.encodingMode===r.ENCODING_UTF8?e(n):t(n);else if(Array.isArray(n))d=n.map(function(r){return 255&r});else{if(!(n instanceof Uint8Array))throw new Error("Incorrect arguments");d=Array.prototype.slice.call(n)}d.push(0);var b,E,N=a(A,C),O=31>w?1<>2,N),f(b,R>>2,d),l(N,d,E,b),v?void p(E,b,0,M,T,m,function(r){v(y(h,r))}):(p(E,b,0,M,T,m),y(h,g(E,b)))}function v(r){if(!b)throw new Error("No cryptographically secure pseudorandom number generator available.");if(null==r&&(r=N),r=0|+r,isNaN(r)||4>r||r>31)throw new Error("Invalid cost parameter.");var n="$2y$";return 10>r&&(n+="0"),n+=r+"$",n+=o(b(C),C)}function d(r,n,e){if(n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);return m(r,n,e)}function h(r,n,e,t){if(arguments.length<2)throw new Error("Incorrect arguments");if(2===arguments.length?(t=n,n=e=null):3===arguments.length&&(t=e,e=null,"function"==typeof n&&(e=n,n=null)),n&&"number"!=typeof n){if("string"!=typeof n||!z.test(n))throw new Error("Invalid salt")}else n=v(n);if(!t||"function"!=typeof t)throw new Error("No callback function was given.");m(r,n,e,t)}function w(r,n){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");var e=n.substr(0,n.length-31),t=d(r,e);return t===n}function A(r,n,e,t){if("string"!=typeof n||!Z.test(n))throw new Error("Incorrect arguments");if(t||(t=e,e=null),!t||"function"!=typeof t)throw new Error("No callback function was given.");var o=n.substr(0,n.length-31);h(r,o,e,function(r){t(r===n)})}var b,E="undefined"!=typeof InstallTrigger,I=E;n&&(b=n.randomBytes,n.getRandomValues&&(b=function(r){var e=new Uint8Array(r);return n.getRandomValues(e)}));var C=16,N=10,O=16,$=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],U=[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946,1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055,3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504,976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462],M=$.length,T=U.length,x=[1332899944,1700884034,1701343084,1684370003,1668446532,1869963892],k=0,G=4096,S=4164,F=4168,L=4192,R=4200,j=4272,B="./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",D=[0,1,54,55,56,57,58,59,60,61,62,63,-1,-1,-1,-1,-1,-1,-1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,-1,-1,-1,-1,-1,-1,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,-1,-1,-1,-1,-1],z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu]/,Z=/^\$2[ay]\$(0[4-9]|[12][0-9]|3[01])\$[.\/A-Za-z0-9]{21}[.Oeu][.\/A-Za-z0-9]{30}[.CGKOSWaeimquy26]$/;r.genSalt=v,r.hashSync=d,r.hash=h,r.compareSync=w,r.compare=A,r.ENCODING_UTF8=0,r.ENCODING_RAW=1,r.encodingMode=r.ENCODING_UTF8,r.cryptoRNG=!!b,r.randomBytes=b,r.defaultCost=N,r.version="2.2.0"}); --------------------------------------------------------------------------------