Compare commits

..
109 Commits
Author SHA1 Message Date
action 3cdb943a21 update 2026-11-04 23:55:01
marry-jell / merge (push) Waiting to run
2026-11-04 23:55:01 +08:00
action b1cd3aafd3 update 2026-11-04 12:30:17 2026-11-04 12:30:17 +08:00
action 1b82056d99 update 2026-11-04 05:27:41 2026-11-04 05:27:41 +08:00
action 0350fcc2e5 update 2026-11-03 23:44:20 2026-11-03 23:44:20 +08:00
action 22194cf4dd update 2026-11-03 12:58:57 2026-11-03 12:58:57 +08:00
action 48ba02dbaf update 2026-11-03 07:16:37 2026-11-03 07:16:37 +08:00
action 8a02ade817 update 2026-11-02 20:03:25 2026-11-02 20:03:25 +08:00
action d9d19b2880 update 2026-11-02 11:57:46 2026-11-02 11:57:46 +08:00
action 94c6c47bc2 update 2026-11-02 07:18:00 2026-11-02 07:18:00 +08:00
action 0a468e764f update 2026-11-02 01:31:15 2026-11-02 01:31:15 +08:00
action a9309301b0 update 2026-11-01 17:58:45 2026-11-01 17:58:45 +08:00
cwx a774ac4ce9 Fix git_clone command for luci-app-adguardhome-tk 2026-11-01 17:58:23 +08:00
action db2388ca1f update 2026-11-01 17:54:16 2026-11-01 17:54:17 +08:00
cwx 34a307153c Update git_clone commands in jell.yml 2026-11-01 17:53:50 +08:00
action fcc54fef3b update 2026-11-01 17:51:52 2026-11-01 17:51:52 +08:00
cwx 5256883332 Update AdGuard Home repository in jell.yml
Replaced the AdGuard Home repository URL in the workflow.
2026-11-01 17:51:26 +08:00
action 1afa674165 update 2026-11-01 17:41:31 2026-11-01 17:41:31 +08:00
cwx 98d078dd48 Update AdGuard Home repository in jell.yml
Replaced the AdGuard Home repository URL in the workflow.
2026-11-01 17:41:05 +08:00
action a71748a807 update 2026-11-01 17:09:57 2026-11-01 17:09:57 +08:00
cwx fd8da734bf Update git_sparse_clone commands in jell.yml 2026-11-01 17:09:32 +08:00
action a97651184f update 2026-11-01 11:53:54
marry-jell / merge (push) Canceled after 0s
2026-11-01 11:53:54 +08:00
action 24c9105eb9 update 2026-11-01 06:58:38 2026-11-01 06:58:38 +08:00
action 04b58d28a1 update 2026-10-31 18:07:25 2026-10-31 18:07:25 +08:00
action 6ce64f7ba2 update 2026-10-31 11:45:08 2026-10-31 11:45:08 +08:00
action 4cbbab4563 update 2026-10-31 07:26:01 2026-10-31 07:26:01 +08:00
action 00e269d429 update 2026-10-31 01:37:59 2026-10-31 01:37:59 +08:00
action a60cfc3dee update 2026-10-30 18:48:17 2026-10-30 18:48:17 +08:00
action 850d89d8e3 update 2026-10-30 12:00:24 2026-10-30 12:00:24 +08:00
action 99d6229f91 update 2026-10-30 07:45:21 2026-10-30 07:45:21 +08:00
action 76e81abc86 update 2026-10-30 01:55:00 2026-10-30 01:55:00 +08:00
action 95f76f26d3 update 2026-10-29 18:46:39 2026-10-29 18:46:39 +08:00
action e2f86e09f4 update 2026-10-29 11:59:06 2026-10-29 11:59:06 +08:00
action bc85557d34 update 2026-10-29 07:49:11 2026-10-29 07:49:11 +08:00
action 4b8b360547 update 2026-10-29 01:48:05 2026-10-29 01:48:05 +08:00
action 36d6943a0b update 2026-10-29 01:36:37 2026-10-29 01:36:37 +08:00
cwx 3a91d7a1df Update jell.yml to modify git_sparse_clone entries
Comment out the git_sparse_clone for openwrt-honk and add a new clone for luci-app-honk.
2026-10-29 01:36:03 +08:00
action f01306d457 update 2026-10-28 21:59:16 2026-10-28 21:59:16 +08:00
action d27d8dcd9f update 2026-10-27 17:31:47 2026-10-27 17:31:47 +08:00
action 63a5dffe55 update 2026-10-27 11:22:48 2026-10-27 11:22:48 +08:00
action a4d6470641 update 2026-10-27 07:31:06 2026-10-27 07:31:06 +08:00
action 197c60d843 update 2026-10-27 02:06:14 2026-10-27 02:06:14 +08:00
action 8de6b6ed73 update 2026-10-26 17:35:19 2026-10-26 17:35:19 +08:00
action 2f2bfddf57 update 2026-10-26 10:49:13 2026-10-26 10:49:13 +08:00
action 081b505e64 update 2026-10-26 06:14:13 2026-10-26 06:14:13 +08:00
action 07319b83f4 update 2026-10-26 02:40:26 2026-10-26 02:40:26 +08:00
action bdc73ee156 update 2026-10-25 23:25:42 2026-10-25 23:25:42 +08:00
action 7fca8e9a3a update 2026-10-25 16:53:21 2026-10-25 16:53:21 +08:00
action 91f217be10 update 2026-10-25 10:50:50 2026-10-25 10:50:50 +08:00
action 7d11e45779 update 2026-10-25 06:12:14 2026-10-25 06:12:14 +08:00
action 97b4bdf8c8 update 2026-10-25 02:32:31 2026-10-25 02:32:31 +08:00
action 852fced2b3 update 2026-10-24 23:15:37 2026-10-24 23:15:37 +08:00
action 6d61e8bf50 update 2026-10-24 16:34:19 2026-10-24 16:34:19 +08:00
action b2346e5950 update 2026-10-24 10:57:49 2026-10-24 10:57:49 +08:00
action bb0d48355d update 2026-10-24 06:50:26 2026-10-24 06:50:26 +08:00
action 015941ec68 update 2026-10-24 00:18:10 2026-10-24 00:18:10 +08:00
action 0dc3af034c update 2026-10-23 17:00:19 2026-10-23 17:00:19 +08:00
action 3bae01757c update 2026-10-23 11:01:00 2026-10-23 11:01:00 +08:00
action 990c543d65 update 2026-10-23 06:55:36 2026-10-23 06:55:36 +08:00
action d64c67f0ed update 2026-10-23 00:28:40 2026-10-23 00:28:40 +08:00
action 3f38c69f75 update 2026-10-22 17:05:51 2026-10-22 17:05:51 +08:00
action 06b74cb314 update 2026-10-22 10:57:37 2026-10-22 10:57:37 +08:00
action 72fa0cc54b update 2026-10-22 06:58:37 2026-10-22 06:58:37 +08:00
action 7d3acd4d45 update 2026-10-22 00:28:18 2026-10-22 00:28:18 +08:00
action a9612da342 update 2026-10-21 17:03:19 2026-10-21 17:03:19 +08:00
action 4570f1512e update 2026-10-21 10:58:41 2026-10-21 10:58:41 +08:00
action f144cc6010 update 2026-10-21 06:53:29 2026-10-21 06:53:29 +08:00
action ee55ecd1ef update 2026-10-21 00:12:55 2026-10-21 00:12:55 +08:00
action 57c1b033cd update 2026-10-20 17:03:51 2026-10-20 17:03:51 +08:00
action ab408c1971 update 2026-10-20 11:04:02 2026-10-20 11:04:02 +08:00
action 47987226ff update 2026-10-20 07:15:28 2026-10-20 07:15:28 +08:00
action f322ead2a4 update 2026-10-20 02:12:23 2026-10-20 02:12:23 +08:00
action 313fe55d56 update 2026-10-19 17:31:01 2026-10-19 17:31:01 +08:00
action 6604b3420d update 2026-10-19 10:54:07 2026-10-19 10:54:07 +08:00
action fdd23bf660 update 2026-10-19 06:10:41 2026-10-19 06:10:42 +08:00
action acd7155b51 update 2026-10-19 02:25:00 2026-10-19 02:25:00 +08:00
action 98f89b4fef update 2026-10-18 23:15:13 2026-10-18 23:15:13 +08:00
action 21a5be24ad update 2026-10-18 16:29:22 2026-10-18 16:29:22 +08:00
action e0041d08f8 update 2026-10-18 10:40:47 2026-10-18 10:40:47 +08:00
action e0ea584b8d update 2026-10-18 02:06:11 2026-10-18 02:06:11 +08:00
action b9c5dc7236 update 2026-10-17 22:50:00 2026-10-17 22:50:00 +08:00
action 63dbfd1d1b update 2026-10-17 16:12:15 2026-10-17 16:12:15 +08:00
action fbf8d8b632 update 2026-10-17 10:39:23 2026-10-17 10:39:23 +08:00
action 9d553b1a00 update 2026-10-17 06:25:36 2026-10-17 06:25:36 +08:00
action 544b0b2540 update 2026-10-17 03:19:16 2026-10-17 03:19:16 +08:00
action cb9f7df14a update 2026-10-16 23:56:54 2026-10-16 23:56:54 +08:00
action f87a7ddf22 update 2026-10-16 16:41:18 2026-10-16 16:41:18 +08:00
action 4b2689b979 update 2026-10-16 10:47:46 2026-10-16 10:47:46 +08:00
action e0a60ac545 update 2026-10-16 06:51:30 2026-10-16 06:51:30 +08:00
action 9122882ea3 update 2026-10-16 00:09:36 2026-10-16 00:09:36 +08:00
action eaef2c6d95 update 2026-10-15 16:45:49 2026-10-15 16:45:49 +08:00
action ebedf5b446 update 2026-10-15 10:50:44 2026-10-15 10:50:44 +08:00
action 27917e2b63 update 2026-10-15 06:56:05 2026-10-15 06:56:05 +08:00
action e75bfefc80 update 2026-10-14 17:13:24 2026-10-14 17:13:24 +08:00
action 79897976d6 update 2026-10-14 11:12:00 2026-10-14 11:12:00 +08:00
action c90a1f4fc1 update 2026-10-14 04:56:49 2026-10-14 04:56:49 +08:00
action 1e69cad46b update 2026-10-13 23:30:23 2026-10-13 23:30:23 +08:00
action 09818a2882 update 2026-10-13 13:05:00 2026-10-13 13:05:00 +08:00
action 8c4f64e256 update 2026-10-13 04:47:12 2026-10-13 04:47:12 +08:00
action 681afee1a6 update 2026-10-12 19:35:39 2026-10-12 19:35:39 +08:00
action 1650840a7b update 2026-10-12 11:55:00 2026-10-12 11:55:00 +08:00
action 09632204fd update 2026-10-12 07:23:36 2026-10-12 07:23:36 +08:00
action 5ece75ecfd update 2026-10-12 01:13:21 2026-10-12 01:13:21 +08:00
action 6f8f22eee4 update 2026-10-11 22:01:38 2026-10-11 22:01:38 +08:00
cwx ebe57dfba9 Change branch from master to main for openwrt-honk
Updated branch name from 'master' to 'main' for openwrt-honk repository.
2026-10-11 22:01:10 +08:00
action 4f0804a849 update 2026-10-11 21:59:08 2026-10-11 21:59:08 +08:00
cwx 219ad87c1a Update repository URL for luci-app-honk 2026-10-11 21:58:46 +08:00
action 8ccdf8f9f7 update 2026-10-11 18:30:33 2026-10-11 18:30:33 +08:00
action 93f2a53ca4 update 2026-10-11 11:31:10 2026-10-11 11:31:10 +08:00
action b77f061182 update 2026-10-11 07:08:20 2026-10-11 07:08:20 +08:00
1602 changed files with 390906 additions and 56029 deletions

No files matched your search

+5 -3
View File
@@ -88,8 +88,8 @@ jobs:
git_clone https://github.com/kiddin9/aria2 aria2
git_clone https://github.com/kiddin9/autoshare && mvdir autoshare
git_clone https://github.com/kiddin9/luci-app-wizard
#git_clone https://github.com/kiddin9/openwrt-adguardhome && mvdir openwrt-adguardhome
git_clone https://github.com/w9315273/luci-app-adguardhome
git_clone https://github.com/kenzok78/luci-app-adguardhome
git_clone https://github.com/w9315273/luci-app-adguardhome luci-app-adguardhome-tk
git_clone https://github.com/kiddin9/openwrt-clouddrive2 && mvdir openwrt-clouddrive2
git_clone https://github.com/kiddin9/openwrt-filebrowser && mvdir openwrt-filebrowser
) &
@@ -158,8 +158,10 @@ jobs:
AdGuardHome
git_sparse_clone master https://github.com/kenzok8/small \
dae daed luci-app-daede
git_sparse_clone master https://github.com/QiuSimons/luci-app-honk \
git_sparse_clone main https://github.com/kenzok8/openwrt-honk \
honk luci-app-honk
#git_sparse_clone master https://github.com/QiuSimons/luci-app-honk \
# honk luci-app-honk
git_sparse_clone main https://github.com/djylb/nps-openwrt \
npc luci-app-npc
git_sparse_clone main https://github.com/smallprogram/openwrt-ghfu \
+3 -3
View File
@@ -3,17 +3,17 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=adguardhome
PKG_VERSION:=0.107.79
PKG_VERSION:=0.107.80
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/AdGuardHome/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=5f4fa119f24ea741bb8cecfa74203165fe6b86b904cef05ff429fb227b07d425
PKG_HASH:=c67cf289f1d4b05c78994f4d1d169962540814a212244eb191cd599795d90278
PKG_BUILD_DIR:=$(BUILD_DIR)/AdGuardHome-$(PKG_VERSION)
FRONTEND_DEST:=$(PKG_NAME)-frontend-$(PKG_VERSION).tar.gz
FRONTEND_URL:=https://github.com/AdguardTeam/AdGuardHome/releases/download/v$(PKG_VERSION)/
FRONTEND_HASH:=30184c157d4aefe5371b575a43c0ab5a7314aef039a820cc421ea67bab994ce8
FRONTEND_HASH:=f01f3c7713a8190dd0aaaf18c3f9a0e38235c21d696325bfca9dc681e389d894
PKG_LICENSE:=GPL-3.0-only
PKG_LICENSE_FILES:=LICENSE.txt
+4 -4
View File
@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=alist
PKG_VERSION:=3.64.0
PKG_WEB_VERSION:=3.64.0
PKG_VERSION:=3.66.0
PKG_WEB_VERSION:=3.66.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/AlistGo/alist/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=599065ec4b26375e4012cf212415f4195c9b92864bdcde4105356261920563f4
PKG_HASH:=6ea517d6927d22ba245a149bfde5542f3c60f48f5d610f105f7bab4d8101539b
PKG_LICENSE:=GPL-3.0
PKG_LICENSE_FILE:=LICENSE
@@ -23,7 +23,7 @@ define Download/$(PKG_NAME)-web
FILE:=$(PKG_NAME)-web-$(PKG_WEB_VERSION).tar.gz
URL_FILE:=dist.tar.gz
URL:=https://github.com/AlistGo/alist-web/releases/download/$(PKG_WEB_VERSION)/
HASH:=b80550662de42a2f8a72d35bca8ed66ec9ad0c24a9a02ceec6a01bf5038cf6f4
HASH:=f0e42134d4c2cead509f7847304c0e8b52e299e3cfe6e8ab033fb8c2eb9248df
endef
PKG_BUILD_DEPENDS:=golang/host
+57 -12
View File
@@ -1,19 +1,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=clashoo
PKG_SHORT_SHA:=e4dd968
PKG_COMMIT_DATE:=2026.10.08
PKG_UPSTREAM_VERSION:=1.19.33
PKG_UPSTREAM_TAG:=v$(PKG_UPSTREAM_VERSION)
PKG_SHORT_SHA:=3f27ef3
PKG_VERSION:=$(PKG_COMMIT_DATE)~$(PKG_SHORT_SHA)
PKG_RELEASE:=2
PKG_VERSION:=2026.10.25.$(PKG_UPSTREAM_VERSION)
PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-alpha-$(PKG_SHORT_SHA).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-alpha-$(PKG_SHORT_SHA)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-alpha-$(PKG_SHORT_SHA)
PKG_SOURCE:=$(PKG_NAME)-stable-$(PKG_UPSTREAM_TAG)-$(PKG_SHORT_SHA).tar.gz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-stable-$(PKG_UPSTREAM_TAG)-$(PKG_SHORT_SHA)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-clashoo/releases/download/mihomo-src
PKG_SOURCE_VERSION:=e4dd968de9e10ecc6770acfafd306edeb578eb52
PKG_HASH:=d566a425f6c87b3f0b9e252fc22df040909662ef7fc387a199203f805231bda9
PKG_BUILD_VERSION:=alpha-$(PKG_SHORT_SHA)
PKG_SOURCE_VERSION:=3f27ef39f8c96bbfbc8b0b9bb10f5c9ef60149d8
PKG_HASH:=1ef7a4087f3805bd2624a940e2e43a0bc23719a25465c9f503aa6c11572f1321
PKG_BUILD_VERSION:=$(PKG_UPSTREAM_TAG)
PKG_LICENSE:=GPL3.0+
PKG_MAINTAINER:=kenzok8
@@ -50,8 +51,11 @@ endef
define Package/clashoo/install
$(call GoPackage/Package/Install/Bin,$(1))
$(INSTALL_DIR) $(1)/usr/libexec/clashoo
$(INSTALL_DIR) $(1)/usr/bin
ln -sf /usr/bin/mihomo $(1)/usr/bin/clash-meta
mv -f $(1)/usr/bin/mihomo $(1)/usr/libexec/clashoo/mihomo-stable
ln -sf /usr/libexec/clashoo/mihomo-stable $(1)/usr/bin/mihomo
ln -sf /usr/libexec/clashoo/mihomo-stable $(1)/usr/bin/clash-meta
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
@@ -82,14 +86,55 @@ define Package/clashoo/install
$(RM) $(1)/usr/share/clashoo/core_down_complete
endef
define Package/clashoo/preinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
save_core() {
src="$$1"
dst="$$2"
[ -f "$$src" ] && [ ! -L "$$src" ] || return 0
if [ -e "$$dst" ] || [ -L "$$dst" ]; then return 0; fi
mkdir -p "$$(dirname "$$dst")" || return 1
tmp="$$dst.tmp.$$$$"
cp "$$src" "$$tmp" && chmod 0755 "$$tmp" && cmp -s "$$src" "$$tmp" || {
rm -f "$$tmp"
return 1
}
if command -v sha256sum >/dev/null 2>&1; then
old_hash="$$(sha256sum "$$src" | awk '{print $$1}')"
new_hash="$$(sha256sum "$$tmp" | awk '{print $$1}')"
[ "$$old_hash" = "$$new_hash" ] || {
rm -f "$$tmp"
return 1
}
fi
mv -f "$$tmp" "$$dst"
}
save_core /usr/bin/mihomo /usr/share/clashoo/bin/mihomo-alpha || exit 1
save_core /usr/bin/mihomo-stable /usr/share/clashoo/bin/mihomo-stable || exit 1
if [ -x /usr/bin/clash-meta ] && [ ! -L /usr/bin/clash-meta ] && [ ! -e /usr/share/clashoo/bin/mihomo-stable ]; then
if ! /usr/bin/clash-meta -v 2>/dev/null | grep -Eiq '(alpha|beta|rc|pre|smart)'; then
save_core /usr/bin/clash-meta /usr/share/clashoo/bin/mihomo-stable || exit 1
fi
fi
fi
exit 0
endef
define Package/clashoo/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
[ -x /usr/bin/mihomo ] && [ ! -x /usr/bin/clash-meta ] && ln -sf /usr/bin/mihomo /usr/bin/clash-meta
rm -f /usr/share/clashoo/check_luci_version.sh /usr/share/clashoo/check_clash_meta_version.sh /usr/share/clashoo/check_mihomo_core_version.sh
rm -f /usr/share/clashoo/cuslist.sh /usr/share/clashoo/groups.sh /usr/share/clashoo/load_groups.sh /usr/share/clashoo/panel_diag.sh
rm -f /usr/share/clashoo/rmlist.sh /usr/share/clashoo/uplist.sh /usr/share/clashoo/rpc_restart_async.sh /usr/share/clashoo/rpc_update_china_ip_async.sh
rm -rf /usr/share/clashoo/create
# 旧方案把 stable 内核放在 /usr/bin/mihomo-stable,现方案改用
# /usr/libexec/clashoo/mihomo-stable(随包)+ /usr/share/clashoo/bin/(自定义下载)。
# preinst 已把它抄到 /usr/share/clashoo/bin/mihomo-stable,确认内容相同后才删
# 旧位置;目标已有其他自定义内核时保留旧文件,避免误删。
if [ -f /usr/share/clashoo/bin/mihomo-stable ] && [ -f /usr/bin/mihomo-stable ] && [ ! -L /usr/bin/mihomo-stable ] && cmp -s /usr/bin/mihomo-stable /usr/share/clashoo/bin/mihomo-stable; then
rm -f /usr/bin/mihomo-stable
fi
/usr/share/clashoo/migrate_lan_acl.sh >/dev/null 2>&1 || true
/usr/share/clashoo/migrate_fake_ip_filter.sh >/dev/null 2>&1 || true
/usr/share/clashoo/detect_core_arch.sh >/dev/null 2>&1 || true
+2 -2
View File
@@ -9,7 +9,7 @@ config clashoo 'config'
option dash_port '9090'
option dashboard_panel 'zashboard'
option level 'info'
option core '3'
option core '2'
option allow_lan '1'
option dnsforwader '1'
option subcri 'meta'
@@ -28,7 +28,7 @@ config clashoo 'config'
option listen_port '1053'
option interf '0'
option download_core 'amd64-compatible'
option dcore '3'
option dcore '2'
option same_tag '1'
option geoip_source '3'
option geoip_format 'mmdb'
+331 -69
View File
@@ -169,43 +169,54 @@ cleanup_stale_core_nft() {
}
_core_candidates() {
echo "/usr/bin/mihomo-stable /usr/bin/mihomo /usr/bin/clash-meta /etc/clashoo/clash"
echo "/usr/share/clashoo/bin/mihomo-stable /usr/libexec/clashoo/mihomo-stable /usr/share/clashoo/bin/mihomo-alpha /usr/bin/mihomo /usr/bin/clash-meta /etc/clashoo/clash"
}
_migrate_legacy_mihomo_stable() {
local legacy=/usr/bin/clash-meta version
[ -x /usr/bin/mihomo-stable ] && return 0
local legacy=/usr/bin/clash-meta target=/usr/share/clashoo/bin/mihomo-stable version staged
[ -x "$target" ] && return 0
[ -x "$legacy" ] && [ ! -L "$legacy" ] || return 0
version=$("$legacy" -v 2>/dev/null | head -n 1)
[ -n "$version" ] || return 0
echo "$version" | grep -Eiq '(alpha|beta|rc|pre|smart)' && return 0
cp -f "$legacy" /usr/bin/mihomo-stable 2>/dev/null && chmod 0755 /usr/bin/mihomo-stable
mkdir -p "$(dirname "$target")" || return 1
staged="${target}.$$"
cp -f "$legacy" "$staged" 2>/dev/null && chmod 0755 "$staged" && mv -f "$staged" "$target"
}
_fallback_missing_mihomo_core() {
local selected fallback
is_singbox_selected && return 0
selected="$(uci -q get clashoo.config.core 2>/dev/null)"
case "$selected" in
2)
[ -x /usr/bin/mihomo-stable ] && return 0
[ -x /usr/bin/mihomo ] || return 0
fallback=3
;;
3)
[ -x /usr/bin/mihomo ] && return 0
[ -x /usr/bin/mihomo-stable ] || return 0
fallback=2
;;
*) return 0 ;;
esac
uci -q set clashoo.config.core="$fallback"
uci -q set clashoo.config.dcore="$fallback"
uci -q commit clashoo >/dev/null 2>&1
if [ "$fallback" = "3" ]; then
log_msg "Stable core missing, falling back to Alpha" "稳定版内核缺失,自动回退到 Alpha"
_mihomo_stable_binary() {
local bundled=/usr/libexec/clashoo/mihomo-stable manual=/usr/share/clashoo/bin/mihomo-stable bundled_ver manual_ver
# A successful custom download is an explicit override, even if its version is older.
if [ -x "$manual" ] &&
[ "$(sed -n '1{s/^[[:space:]]*//;s/[[:space:]]*$//;p;}' /usr/share/clashoo/clash_meta_version 2>/dev/null)" = "custom-url" ]; then
echo "$manual"
return 0
fi
[ -x "$bundled" ] || { [ -x "$manual" ] && { echo "$manual"; return 0; }; return 1; }
[ -x "$manual" ] || { echo "$bundled"; return; }
bundled_ver="$("$bundled" -v 2>/dev/null | awk '{for (i = 1; i < NF; i++) if ($i == "Meta") {print $(i + 1); exit}}')"
manual_ver="$("$manual" -v 2>/dev/null | awk '{for (i = 1; i < NF; i++) if ($i == "Meta") {print $(i + 1); exit}}')"
bundled_ver="${bundled_ver#v}"
manual_ver="${manual_ver#v}"
printf '%s\n' "$bundled_ver" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || bundled_ver=""
printf '%s\n' "$manual_ver" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' || manual_ver=""
if [ -n "$bundled_ver" ] && [ -n "$manual_ver" ]; then
if awk -v manual="$manual_ver" -v bundled="$bundled_ver" 'BEGIN {
split(manual, m, "."); split(bundled, b, ".");
for (i = 1; i <= 3; i++) {
if (m[i] + 0 > b[i] + 0) exit 0;
if (m[i] + 0 < b[i] + 0) exit 1;
}
exit 0;
}'; then
echo "$manual"
else
echo "$bundled"
fi
elif [ -n "$manual_ver" ]; then
echo "$manual"
else
log_msg "Alpha core missing, falling back to stable" "Alpha 内核缺失,自动回退到稳定版"
echo "$bundled"
fi
}
@@ -220,11 +231,11 @@ _detect_selected_core() {
return 1
;;
2|mihomo)
[ -x /usr/bin/mihomo-stable ] && echo /usr/bin/mihomo-stable && return
return 1
_mihomo_stable_binary
return $?
;;
3|mihomo-alpha)
[ -x /usr/bin/mihomo ] && echo /usr/bin/mihomo && return
[ -x /usr/share/clashoo/bin/mihomo-alpha ] && echo /usr/share/clashoo/bin/mihomo-alpha && return
return 1
;;
esac
@@ -233,7 +244,7 @@ _detect_selected_core() {
core_supports_advanced_features() {
case "$CLASH" in
*/mihomo|*/mihomo-stable|*/clash-meta|*/smart)
*/mihomo|*/mihomo-stable|*/mihomo-alpha|*/clash-meta|*/smart)
return 0
;;
*)
@@ -724,9 +735,12 @@ cleanup_legacy_startup_backups() {
#===========================================================================================================================
# Historical backup artifacts can clutter LuCI "System -> Startup".
# Keep runtime clean by removing known obsolete backup filenames.
# The old `*bak*` glob also wiped other packages' backups (e.g. wireless.bak),
# so scope it to Clashoo's own script names (legacy `clash`, current `clashoo`).
# `._*` is macOS AppleDouble metadata, never a valid init script, so it stays.
rm -f /etc/init.d/._clash \
/etc/init.d/._* \
/etc/init.d/*bak* >/dev/null 2>&1 || true
/etc/init.d/clash*bak* >/dev/null 2>&1 || true
#===========================================================================================================================
}
@@ -876,6 +890,10 @@ revert_dns() {
add_cron(){
#===========================================================================================================================
# core.log 落在 tmpfs 上,按分钟卡一次大小;内核对日志没有上限,
# 一旦刷屏写满 /tmp,dnsmasq 与配置生成都会跟着挂。
[ -z "$(grep -w "lib/core_log_guard.sh" "$CRON_FILE")" ] && echo "* * * * * sh /usr/share/clashoo/lib/core_log_guard.sh >/dev/null 2>&1" >> "$CRON_FILE"
auto=$(uci get clashoo.config.auto_update 2>/dev/null)
clear=$(uci get clashoo.config.auto_clear_log 2>/dev/null)
if [ "${auto:-0}" -eq 1 ] || [ "${clear:-0}" -eq 1 ]; then
@@ -908,6 +926,7 @@ del_cron(){
sed -i '/update\/update_all.sh/d' "$CRON_FILE"
sed -i '/\/usr\/share\/clash\/update_all.sh/d' "$CRON_FILE"
sed -i '/update\/maintenance_cron.sh/d' "$CRON_FILE"
sed -i '/lib\/core_log_guard.sh/d' "$CRON_FILE"
sed -i '/clashoo.txt/d' "$CRON_FILE"
sed -i '/update\/lgbm_update.sh/d' "$CRON_FILE"
sed -i '/\/usr\/share\/clash\/lgbm_update.sh/d' "$CRON_FILE"
@@ -1049,7 +1068,7 @@ _user_dns_fields() {
command -v yq >/dev/null 2>&1 || return 0
[ -s "$CONFIG_YAML" ] || return 0
for field in nameserver proxy-server-nameserver fallback direct-nameserver \
default-nameserver nameserver-policy respect-rules; do
default-nameserver nameserver-policy proxy-server-nameserver-policy respect-rules; do
case ",$force," in *,"$field",*) continue ;; esac
[ "$(yq -M e "(.dns // {}) | has(\"${field}\")" "$CONFIG_YAML" 2>/dev/null)" = "true" ] &&
out="${out}${out:+,}${field}"
@@ -1091,7 +1110,7 @@ _clashoo_dns_force_fields() {
command -v yq >/dev/null 2>&1 || return 0
[ -s "$CONFIG_YAML" ] || return 0
local managed legacy fields
fields="nameserver,proxy-server-nameserver,direct-nameserver,default-nameserver,nameserver-policy,respect-rules"
fields="nameserver,proxy-server-nameserver,direct-nameserver,default-nameserver,nameserver-policy,proxy-server-nameserver-policy,respect-rules"
managed="$(yq -M e '(.dns."x-clashoo-managed-dns" // false) == true' "$CONFIG_YAML" 2>/dev/null)"
if [ "$managed" = "true" ]; then
printf '%s' "$fields"
@@ -1151,6 +1170,103 @@ _dns_nameserver_inherit_mode() {
printf '%s' inherit
}
# issue #73: mihomo resolves proxy server domains through
# proxy-server-nameserver(-policy) and ignores nameserver-policy there. Airports
# ship their own resolver for node domains (e.g. "+.chylink.xyz" -> DoT) which
# answers with reachable relay IPs, so mirror the entries that match a node
# server domain before mixin drops them.
#
# Everything travels through a private 0700 work dir: large airports can produce
# hundreds of KB of policy entries, which neither argv nor env vars can carry
# (E2BIG), and predictable /tmp names are symlink bait.
_dns_node_policy_workdir=""
_dns_node_policy_cleanup() {
[ -n "${_dns_node_policy_workdir:-}" ] || return 0
rm -rf "$_dns_node_policy_workdir" 2>/dev/null
_dns_node_policy_workdir=""
return 0
}
# Same inputs yml_change feeds mixin: settle FORCE/PRESENT here so the skip
# decision cannot disagree with the config that mixin actually generates.
_dns_node_policy_mode() {
CLASHOO_DNS_FORCE="$(_clashoo_dns_force_fields)"
CLASHOO_DNS_PRESENT="$(_user_dns_fields "$CLASHOO_DNS_FORCE")"
export CLASHOO_DNS_FORCE CLASHOO_DNS_PRESENT
_dns_nameserver_inherit_mode
}
_dns_node_policy_capture() {
_dns_node_policy_cleanup
command -v yq >/dev/null 2>&1 || return 0
command -v ucode >/dev/null 2>&1 || return 0
local helper workdir
helper="${CLASHOO_NODE_DNS_UC:-/usr/share/clashoo/runtime/dns_node_policy.uc}"
[ -r "$helper" ] || return 0
[ -s "$CONFIG_YAML" ] || return 0
# skip mode keeps the source DNS verbatim: mihomo already falls back to the
# normal DNS policy for node domains when no dedicated resolver is generated.
[ "$(_dns_node_policy_mode)" = "skip" ] && return 0
# sweep leftovers from an interrupted start; they are private to root anyway
find "${TMPDIR:-/tmp}" -maxdepth 1 -name 'clashoo-node-dns.*' -mmin +60 \
-exec rm -rf {} + >/dev/null 2>&1
workdir="$(mktemp -d "${TMPDIR:-/tmp}/clashoo-node-dns.XXXXXX" 2>/dev/null)" || return 0
chmod 700 "$workdir" 2>/dev/null
if ! yq -M e -o=json -I0 '({"policies": (.dns."nameserver-policy" // {}), "servers": [(.proxies // [])[] | select(type == "!!map") | .server // ""]})' "$CONFIG_YAML" > "$workdir/source.json" 2>/dev/null ||
[ ! -s "$workdir/source.json" ]; then
rm -rf "$workdir"
return 0
fi
chmod 600 "$workdir/source.json" 2>/dev/null
if ! CLASHOO_NODE_DNS_SOURCE_FILE="$workdir/source.json" ucode "$helper" > "$workdir/policy.json" 2>/dev/null ||
[ ! -s "$workdir/policy.json" ]; then
rm -rf "$workdir"
return 0
fi
chmod 600 "$workdir/policy.json" 2>/dev/null
rm -f "$workdir/source.json"
if [ "$(yq -M e -r 'length' "$workdir/policy.json" 2>/dev/null)" = "0" ]; then
rm -rf "$workdir"
return 0
fi
_dns_node_policy_workdir="$workdir"
return 0
}
_dns_node_policy_apply() {
local policy_file rc
policy_file="${_dns_node_policy_workdir:+"$_dns_node_policy_workdir/policy.json"}"
if [ -z "$policy_file" ] || [ ! -s "$policy_file" ] || ! command -v yq >/dev/null 2>&1; then
_dns_node_policy_cleanup
return 0
fi
# existing keys keep their value; overlapping patterns are left to mihomo
CLASHOO_NODE_DNS_POLICY_FILE="$policy_file" yq -M e -i '(.dns // {}) as $dns |
(load(strenv(CLASHOO_NODE_DNS_POLICY_FILE)) // {}) as $derived |
.dns."proxy-server-nameserver-policy" = ($derived * ($dns."proxy-server-nameserver-policy" // {}))
' "$CONFIG_YAML" 2>/dev/null
rc=$?
# mihomo rejects a node policy without a proxy node resolver
if [ "$(yq -M e -r '((.dns."proxy-server-nameserver" // []) | length)' "$CONFIG_YAML" 2>/dev/null)" = "0" ]; then
yq -M e -i '.dns."proxy-server-nameserver" = (.dns."default-nameserver" // ["223.5.5.5"])' "$CONFIG_YAML" 2>/dev/null || true
fi
_dns_node_policy_cleanup
[ "$rc" = "0" ] && log_msg "Inherited node domain DNS policy from subscription" "已从订阅继承节点域名 DNS 策略"
return 0
}
_dns_proxy_nameservers() {
local i=0 t en a p port s out="" prefix
while :; do
@@ -1481,7 +1597,7 @@ _remap_dns_system_nameserver() {
ip_rules() {
#===========================================================================================================================
sh /usr/share/clashoo/runtime/iprules.sh 2>/dev/null
CLASHOO_CONFIG_YAML="$CONFIG_YAML" sh /usr/share/clashoo/runtime/iprules.sh 2>/dev/null
#===========================================================================================================================
}
@@ -1691,15 +1807,21 @@ _lan_dns_split_enabled() {
yml_dns_change(){
#===========================================================================================================================
dns_port=$(sed -n 's/^[[:space:]]*listen:.*:[[:space:]]*['"'"'"]*\([0-9]\{1,\}\)['"'"'"]*[[:space:]]*$/\1/p' /etc/clashoo/config.yaml 2>/dev/null | head -n1)
dns_port=$(sed -n 's/^[[:space:]]*listen:.*:[[:space:]]*['"'"'"]*\([0-9]\{1,\}\)['"'"'"]*[[:space:]]*$/\1/p' "$CONFIG_YAML" 2>/dev/null | head -n1)
listen_port=$(uci get clashoo.config.listen_port 2>/dev/null)
[ -z "$listen_port" ] && listen_port=5300
if [ -z "$dns_port" ]; then
dns_port="$listen_port"
if grep -q '^dns:' /etc/clashoo/config.yaml && ! grep -q "^ \{0,\}listen:" /etc/clashoo/config.yaml; then
sed -i "/^dns:/a\ listen: 0.0.0.0:${dns_port}" /etc/clashoo/config.yaml 2>/dev/null
if grep -q '^dns:' "$CONFIG_YAML" && ! grep -q "^ \{0,\}listen:" "$CONFIG_YAML"; then
sed -i "/^dns:/a\ listen: 0.0.0.0:${dns_port}" "$CONFIG_YAML" 2>/dev/null
fi
fi
if [ "${CLASHOO_RELOAD_CANDIDATE:-0}" = "1" ]; then
if [ "${dns_port:-0}" -eq 53 ]; then
sed -i "s@^\([[:space:]]*listen:[[:space:]]*\)0\.0\.0\.0:53@\10.0.0.0:${listen_port}@g" "$CONFIG_YAML" || return 1
fi
return 0
fi
dnsforwader=$(uci get clashoo.config.dnsforwader 2>/dev/null)
dnscache=$(uci get clashoo.config.dnscache 2>/dev/null)
if [ "$(uci -q get clashoo.config.enable_dns 2>/dev/null)" = "0" ]; then
@@ -1980,7 +2102,11 @@ _finish_geo_bootstrap() {
read need_mmdb need_geosite < /var/run/clashoo_bootstrap_pending 2>/dev/null
log_msg "Bootstrap: fetching geo data via proxy" "引导模式:正在通过代理补全 Geo 数据"
/usr/share/clashoo/update/geoip.sh >/dev/null 2>&1
if [ "$need_geosite" = "1" ]; then
/usr/share/clashoo/update/geoip.sh --require-geosite >/dev/null 2>&1
else
/usr/share/clashoo/update/geoip.sh >/dev/null 2>&1
fi
still=0
[ "$need_mmdb" = "1" ] && ! _has_valid_local_mmdb && still=1
@@ -2018,12 +2144,12 @@ _start_validate_core() {
echo "Clashoo" > "$REAL_LOG"
return 1
elif [ "${core:-0}" -eq 2 ] && [ ! -x "$CLASH" ]; then
log_msg "mihomo core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 内核: $CLASH"
log_msg "mihomo stable core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 稳定版内核: $CLASH"
sleep 1
echo "Clashoo" > "$REAL_LOG"
return 1
elif [ "${core:-0}" -eq 3 ] && [ ! -x "$CLASH" ]; then
log_msg "mihomo core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo 内核: $CLASH"
log_msg "mihomo Alpha core not found, detected binary is unavailable: $CLASH" "找不到可用的 mihomo Alpha 内核,请在组件更新中安装: $CLASH"
sleep 1
echo "Clashoo" > "$REAL_LOG"
return 1
@@ -2036,30 +2162,33 @@ _start_validate_core() {
}
_start_prepare_config() {
local _reload_candidate="${CLASHOO_RELOAD_CANDIDATE:-0}"
# Core-only: run the imported config verbatim. select_config already copied
# it to /etc/clashoo/config.yaml, so skip every mixin/DNS/rule rewrite below.
[ "$(uci -q get clashoo.config.core_only 2>/dev/null)" = "1" ] && return 0
check >/dev/null 2>&1
check >/dev/null 2>&1 || return 1
_migrate_dns_roles >/dev/null 2>&1
[ "$_reload_candidate" = "1" ] || _migrate_dns_roles >/dev/null 2>&1
enable_dns=$(uci get clashoo.config.enable_dns 2>/dev/null)
if [ -z "$(grep -E "^ {0,}listen:" /etc/clashoo/config.yaml)" ] || [ -z "$(grep -E "^ {0,}enhanced-mode:" /etc/clashoo/config.yaml)" ] || [ -z "$(grep -E "^ {0,}dns:" /etc/clashoo/config.yaml)" ];then
if [ -z "$(grep -E "^ {0,}listen:" "$CONFIG_YAML")" ] || [ -z "$(grep -E "^ {0,}enhanced-mode:" "$CONFIG_YAML")" ] || [ -z "$(grep -E "^ {0,}dns:" "$CONFIG_YAML")" ];then
if [ "${enable_dns:-0}" -eq 0 ];then
[ "$_reload_candidate" = "1" ] && return 1
uci set clashoo.config.enable_dns="1" && uci commit clashoo
log_msg "Enabling Custom Dns" "启用自定义DNS"
fi
fi
if { egrep -q '^ {0,}rule-providers:' "/etc/clashoo/config.yaml" || egrep -q '^ {0,}script:' "/etc/clashoo/config.yaml"; } && ! core_supports_advanced_features; then
if [ -x /usr/bin/mihomo ]; then
uci set clashoo.config.core="3" && uci commit clashoo
elif [ -x /usr/bin/mihomo-stable ]; then
if { egrep -q '^ {0,}rule-providers:' "$CONFIG_YAML" || egrep -q '^ {0,}script:' "$CONFIG_YAML"; } && ! core_supports_advanced_features; then
[ "$_reload_candidate" = "1" ] && return 1
if [ -n "$(_mihomo_stable_binary)" ]; then
uci set clashoo.config.core="2" && uci commit clashoo
elif [ -x /usr/share/clashoo/bin/mihomo-alpha ]; then
uci set clashoo.config.core="3" && uci commit clashoo
else
log_msg "Current config requires mihomo/clash-meta core" "当前配置需要 mihomo 或 clash-meta 内核"
backend_remove_rules >/dev/null 2>&1
@@ -2073,6 +2202,7 @@ _start_prepare_config() {
fi
if [ "$(uci get clashoo.config.p_mode 2>/dev/null)" = "script" ]; then
[ "$_reload_candidate" = "1" ] && return 1
uci set clashoo.config.p_mode="rule" && uci commit clashoo
fi
@@ -2082,13 +2212,15 @@ _start_prepare_config() {
fi
_adapt_dns_loopback_resolver >/dev/null 2>&1
# stage bundled cn.mrs into the core dir; mihomo rejects rule-set paths outside /etc/clashoo
if [ -f /usr/share/clashoo/ruleset/cn.mrs ]; then
if [ "$_reload_candidate" != "1" ] && [ -f /usr/share/clashoo/ruleset/cn.mrs ]; then
if [ ! -f /etc/clashoo/ruleset/cn.mrs ] || [ /usr/share/clashoo/ruleset/cn.mrs -nt /etc/clashoo/ruleset/cn.mrs ]; then
mkdir -p /etc/clashoo/ruleset
cp -f /usr/share/clashoo/ruleset/cn.mrs /etc/clashoo/ruleset/cn.mrs 2>/dev/null
fi
fi
_dns_node_policy_capture
yml_change >/dev/null 2>&1
_dns_node_policy_apply
append_luci_fake_ip_filter_extras >/dev/null 2>&1
normalize_fake_ip_filter >/dev/null 2>&1
drop_legacy_cn_ip_injection >/dev/null 2>&1
@@ -2117,12 +2249,13 @@ _start_prepare_config() {
log_msg "GeoIP database not found, continue without local GeoIP DB" "未找到本地 GeoIP 数据库,继续启动(可在系统页更新 GeoIP)"
fi
_prepare_geo_bootstrap_mode
[ "$_reload_candidate" = "1" ] || _prepare_geo_bootstrap_mode
_remap_dns_system_nameserver >/dev/null 2>&1
ensure_dns_cn_policy_fallback >/dev/null 2>&1
if [ ! -f /etc/clashoo/config.yaml ];then
if [ ! -f "$CONFIG_YAML" ];then
[ "$_reload_candidate" = "1" ] && return 1
log_msg "Cannot find config.yaml" "找不到config.yaml"
backend_remove_rules >/dev/null 2>&1
sleep 1
@@ -2130,10 +2263,10 @@ _start_prepare_config() {
exit 0
fi
yml_dns_change >/dev/null 2>&1
yml_dns_change >/dev/null 2>&1 || return 1
# Sync processed config (with DNS listen injected) to mihomo working directory
cp -f "$CONFIG_YAML" "${CLASH_CONFIG}/config.yaml" 2>/dev/null
[ "$_reload_candidate" = "1" ] || cp -f "$CONFIG_YAML" "${CLASH_CONFIG}/config.yaml" 2>/dev/null
ip_rules >/dev/null 2>&1
}
@@ -2145,12 +2278,25 @@ _core_only_ui_args() {
printf ' -ext-ui %s' "$(shell_quote /etc/clashoo/dashboard)"
}
_mihomo_proxy_dns_valid() {
local config="$1" proxy_count policy_count respect_rules
command -v yq >/dev/null 2>&1 || return 0
[ -s "$config" ] || return 0
proxy_count="$(yq -M e -r '(.dns."proxy-server-nameserver" // []) | length' "$config" 2>/dev/null)"
[ "$proxy_count" = "0" ] || return 0
policy_count="$(yq -M e -r '(.dns."proxy-server-nameserver-policy" // {}) | length' "$config" 2>/dev/null)"
respect_rules="$(yq -M e -r '.dns."respect-rules" // false' "$config" 2>/dev/null)"
[ "$policy_count" = "0" ] && [ "$respect_rules" != "true" ]
}
_start_launch_core() {
local _cmd _core_only
disable_quic_gso=$(uci get clashoo.config.disable_quic_gso 2>/dev/null)
_core_only=$(uci -q get clashoo.config.core_only 2>/dev/null)
mkdir -p "$(dirname "$CORE_LOG_PATH")" >/dev/null 2>&1
touch "$CORE_LOG_PATH" >/dev/null 2>&1
# core.log 在 tmpfs 上,先按大小裁剪,避免上次跑飞的大日志直接卡死启动
sh /usr/share/clashoo/lib/core_log_guard.sh "$CORE_LOG_PATH" >/dev/null 2>&1
# Core-only runs the imported config verbatim, which may reference absolute
# paths (e.g. OpenClash's external-ui /usr/share/openclash/ui). mihomo's
@@ -2158,6 +2304,13 @@ _start_launch_core() {
# in core-only the user is explicitly trusting their own config.
[ "$_core_only" = "1" ] && export SAFE_PATHS="/"
if ! _mihomo_proxy_dns_valid "${CLASH_CONFIG}/config.yaml"; then
log_msg "Proxy node DNS is required by node DNS policy or respect-rules; set a Proxy Node Domain Resolver in LuCI" "节点域名 DNS 策略或 DNS 遵循规则需要代理节点域名解析,请在 LuCI 中配置"
runtime_state_record_health "fail" "preflight:proxy_dns_missing"
echo "Clashoo" > "$REAL_LOG"
return 1
fi
# preflight dry-run with watchdog: bail on bad config without touching
# firewall/dnsmasq, and never let a geo auto-download (mihomo blocks ~90s on
# a missing GeoIP/GeoSite when GitHub is unreachable) freeze startup/UI.
@@ -2182,6 +2335,10 @@ _start_launch_core() {
procd_set_param command /bin/sh -c "$_cmd"
[ "$disable_quic_gso" = "1" ] && procd_set_param env QUIC_GO_DISABLE_GSO=1
[ "$_core_only" = "1" ] && procd_set_param env SAFE_PATHS=/
# 默认 4095 个 fd 顶不住 BT/PCDN 类连接洪水,打爆后核心会陷入
# accept 失败刷屏,与 sing-box 实例保持一致提到 1000000。
procd_set_param limits core="unlimited"
procd_set_param limits nofile="1000000 1000000"
procd_set_param respawn 3600 5 5
procd_close_instance
[ "$disable_quic_gso" = "1" ] && log_msg "Disable quic-go GSO support" "已启用:禁用 quic-go GSO 支持"
@@ -2268,7 +2425,6 @@ start_service(){
sync_legacy_core_field
_migrate_legacy_mihomo_stable
_fallback_missing_mihomo_core
CLASH="$(_detect_selected_core)"
cleanup_legacy_startup_backups
@@ -2465,6 +2621,52 @@ stop_service(){
#===========================================================================================================================
}
_mihomo_reload_api() {
local _path="$1" _response="$2" _dp _ds _lip
_dp="$(uci -q get clashoo.config.dash_port)"; [ -n "$_dp" ] || _dp=9090
_ds="$(uci -q get clashoo.config.dash_pass)"
_lip="$(uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}')"
[ -n "$_lip" ] || _lip=127.0.0.1
MIHOMO_RELOAD_CURL_RC=0
MIHOMO_RELOAD_HTTP_CODE="$(curl -sS -m 5 -o "$_response" -w '%{http_code}' \
-H "Authorization: Bearer ${_ds}" -H "Content-Type: application/json" \
-X PUT -d '{"path":"'"$_path"'"}' \
"http://${_lip}:${_dp}/configs?force=true" 2>/dev/null)" || MIHOMO_RELOAD_CURL_RC=$?
[ "$MIHOMO_RELOAD_CURL_RC" -eq 0 ] || return 1
case "$MIHOMO_RELOAD_HTTP_CODE" in
2??) return 0 ;;
*) return 1 ;;
esac
}
_mihomo_reload_save_dns() {
MIHOMO_DHCP_MODE="$(stat -c %a /etc/config/dhcp)" || return 1
cp /etc/config/dhcp "$1"
}
_mihomo_reload_restore_dns() {
cp "$1" /etc/config/dhcp && chmod "$MIHOMO_DHCP_MODE" /etc/config/dhcp &&
uci -q revert dhcp && _reload_dnsmasq >/dev/null 2>&1
}
_mihomo_reload_restore() {
local _previous="$1" _response="$2" _dns_backup="$3" _peripheral_changed="$4" _restore _failed=0
if ! _mihomo_reload_api "$_previous" "$_response"; then
return 1
fi
if [ "$_peripheral_changed" = "1" ]; then
if _restore="$(mktemp "${CLASH_CONFIG}/.reload-restore.XXXXXX")"; then
cp "$_previous" "$_restore" && mv -f "$_restore" "$CONFIG_YAML" || { rm -f "$_restore"; _failed=1; }
else
_failed=1
fi
_mihomo_reload_restore_dns "$_dns_backup" || _failed=1
backend_remove_rules >/dev/null 2>&1 || _failed=1
backend_apply_rules >/dev/null 2>&1 || _failed=1
fi
return "$_failed"
}
reload_service()
{
if is_singbox_selected; then
@@ -2477,23 +2679,83 @@ reload_service()
start
fi
elif _core_running; then
local _candidate _previous _response _dns_backup _source _pf_rc _error _peripheral_changed
_error=""
resolve_effective_tp_modes
runtime_state_record_preflight "mihomo"
backend_remove_rules 2>/dev/null
( select_config && _start_prepare_config ) >/dev/null 2>&1
# hot-reload via mihomo REST API (config + addtype rules), no process restart or tunnel drop
local _dp _ds _lip
_dp="$(uci -q get clashoo.config.dash_port)"; [ -n "$_dp" ] || _dp=9090
_ds="$(uci -q get clashoo.config.dash_pass)"
_lip="$(uci -q get network.lan.ipaddr 2>/dev/null | awk -F'/' '{print $1}')"
[ -n "$_lip" ] || _lip=127.0.0.1
curl -m 5 -H "Authorization: Bearer ${_ds}" -H "Content-Type: application/json" \
-X PUT -d '{"path":"'"$CONFIG_YAML"'"}' \
"http://${_lip}:${_dp}/configs?force=true" >/dev/null 2>&1
backend_apply_rules 2>/dev/null
if [ "$(uci -q get clashoo.config.core_only 2>/dev/null)" != "1" ]; then
_reload_dnsmasq >/dev/null 2>&1
_candidate="$(mktemp "${CLASH_CONFIG}/.reload-candidate.XXXXXX")" || { _log_runtime_error "Mihomo reload failed: cannot stage candidate"; return 1; }
_previous="$(mktemp "${CLASH_CONFIG}/.reload-previous.XXXXXX")" || { rm -f "$_candidate"; _log_runtime_error "Mihomo reload failed: cannot back up current config"; return 1; }
_response="$(mktemp /tmp/clashoo-reload-response.XXXXXX)" || { rm -f "$_candidate" "$_previous"; _log_runtime_error "Mihomo reload failed: cannot stage API response"; return 1; }
_dns_backup="$(mktemp "${CLASH_CONFIG}/.reload-dhcp.XXXXXX")" || { rm -f "$_candidate" "$_previous" "$_response"; _log_runtime_error "Mihomo reload failed: cannot back up DNS state"; return 1; }
_source="$(uci -q get clashoo.config.use_config 2>/dev/null)"
if [ ! -s "$_source" ]; then
_error="selected config is missing or empty"
elif ! cp "$_source" "$_candidate" || ! cp "$CONFIG_YAML" "$_previous" ||
! _mihomo_reload_save_dns "$_dns_backup"; then
_error="cannot back up current config or DNS state"
elif ! ( CONFIG_YAML="$_candidate"; CLASHOO_RELOAD_CANDIDATE=1; _start_prepare_config ) >/dev/null 2>&1 ||
[ ! -s "$_candidate" ]; then
_error="candidate generation failed; check DNS and core settings"
fi
rm -f "${_candidate}.mixin" 2>/dev/null
if [ -n "$_error" ]; then
_log_runtime_error "Mihomo reload failed: ${_error}; current config preserved"
rm -f "$_candidate" "$_previous" "$_response" "$_dns_backup"
return 1
fi
if ! _mihomo_proxy_dns_valid "$_candidate"; then
_log_runtime_error "Mihomo reload failed: node DNS policy or respect-rules requires a Proxy Node Domain Resolver; current config preserved"
rm -f "$_candidate" "$_previous" "$_response" "$_dns_backup"
return 1
fi
if [ "$(uci -q get clashoo.config.core_only 2>/dev/null)" = "1" ]; then
SAFE_PATHS=/ _run_with_timeout 15 "$CLASH" -d "$CLASH_CONFIG" -f "$_candidate" -t >> "$CORE_LOG_PATH" 2>&1
else
_run_with_timeout 15 "$CLASH" -d "$CLASH_CONFIG" -f "$_candidate" -t >> "$CORE_LOG_PATH" 2>&1
fi
_pf_rc=$?
if [ "$_pf_rc" -ne 0 ]; then
if [ "$_pf_rc" -eq 124 ]; then
_error="Mihomo reload failed: candidate preflight timed out"
else
_error="Mihomo reload failed: candidate config invalid (exit ${_pf_rc}; see core log)"
fi
_log_runtime_error "$_error; current config preserved"
rm -f "$_candidate" "$_previous" "$_response" "$_dns_backup"
return 1
fi
if ! _mihomo_reload_api "$_candidate" "$_response"; then
_error="Mihomo reload failed (curl ${MIHOMO_RELOAD_CURL_RC}, HTTP ${MIHOMO_RELOAD_HTTP_CODE})"
if _mihomo_reload_restore "$_previous" "$_response" "$_dns_backup" 0; then
_log_runtime_error "${_error}; previous config restored"
rm -f "$_candidate" "$_previous" "$_response" "$_dns_backup"
else
_log_runtime_error "${_error}; reload outcome unknown; candidate and backup retained"
rm -f "$_response" "$_dns_backup"
fi
return 1
fi
_peripheral_changed=0
if ! mv -f "$_candidate" "$CONFIG_YAML"; then
_error="Mihomo reload failed: cannot commit candidate config"
elif [ "$(uci -q get clashoo.config.core_only 2>/dev/null)" != "1" ]; then
_peripheral_changed=1
if ! backend_remove_rules >/dev/null 2>&1 || ! backend_apply_rules >/dev/null 2>&1 ||
! yml_dns_change >/dev/null 2>&1 || ! _reload_dnsmasq >/dev/null 2>&1; then
_error="Mihomo reload failed: firewall or DNS update failed"
fi
fi
if [ -n "$_error" ]; then
if _mihomo_reload_restore "$_previous" "$_response" "$_dns_backup" "$_peripheral_changed"; then
_log_runtime_error "${_error}; previous config and settings restored"
rm -f "$_candidate" "$_previous" "$_response" "$_dns_backup"
else
_log_runtime_error "${_error}; rollback incomplete; previous config retained for recovery"
rm -f "$_candidate" "$_response"
fi
return 1
fi
rm -f "$_previous" "$_response" "$_dns_backup" "${CONFIG_YAML}.dns-leak-nameserver"
runtime_state_record_preflight "mihomo"
runtime_run_health_check_settle >/dev/null 2>&1
fi
}
@@ -0,0 +1,28 @@
#!/bin/sh
# clashoo core log size guard
# 用法: core_log_guard.sh [logfile]
#
# core.log 落在 /var/log(= /tmp 下的 tmpfs),没有大小上限时一次 accept
# 失败风暴就能把它写到几百 MB,直接把 /tmp 写满(dnsmasq、配置生成、
# cron 全部失效)。这里在超过上限时就地裁剪,只保留尾部内容。
# 内核进程持有该文件的 O_APPEND fd,所以必须原地重写,不能替换 inode。
set -u
LOG="${1:-/var/log/clashoo/core.log}"
MAX_KB="${CLASHOO_CORE_LOG_MAX_KB:-16384}"
KEEP_KB="${CLASHOO_CORE_LOG_KEEP_KB:-1024}"
[ -f "$LOG" ] || exit 0
size="$(wc -c <"$LOG" 2>/dev/null)"
case "${size:-}" in ''|*[!0-9]*) exit 0 ;; esac
[ "$size" -gt $((MAX_KB * 1024)) ] || exit 0
tmp="${LOG}.trim.$$"
if tail -c $((KEEP_KB * 1024)) "$LOG" >"$tmp" 2>/dev/null && cat "$tmp" >"$LOG" 2>/dev/null; then
rm -f "$tmp"
else
rm -f "$tmp"
: >"$LOG" 2>/dev/null || true
fi
exit 0
@@ -30,6 +30,8 @@ echo "$$" >"$PID_FILE"
while :; do
[ "$(uci -q get clashoo.config.enable 2>/dev/null)" = "1" ] || break
/usr/share/clashoo/net/access_check_cache.sh >/dev/null 2>&1 || true
# 每轮顺手卡一下 core.log 大小(tmpfs 很小,跑飞会写满 /tmp)
sh /usr/share/clashoo/lib/core_log_guard.sh >/dev/null 2>&1 || true
if [ -n "$INTERVAL_FIXED" ]; then
sleep "$INTERVAL_FIXED"
else
@@ -120,7 +120,6 @@ set clashoo_china6 {
2400:5280:1400::/38,
2400:5280:1c00::/38,
2400:5280:3400::/38,
2400:5280:4c00::/38,
2400:5280:5000::/36,
2400:5280:6000::/35,
2400:5280:8000::/34,
@@ -589,6 +588,7 @@ set clashoo_china6 {
2401:8680:4020::/43,
2401:8680:4040::/42,
2401:8680:4080::/41,
2401:8680:4100::/48,
2401:8680:4103::/48,
2401:8680:4104::/46,
2401:8680:4108::/45,
@@ -775,6 +775,7 @@ set clashoo_china6 {
2401:f860:8a::/47,
2401:f860:8c::/46,
2401:f860:91::/48,
2401:f860:93::/48,
2401:f860:95::/48,
2401:f860:96::/48,
2401:f860:98::/45,
@@ -958,6 +959,9 @@ set clashoo_china6 {
2402:7820::/32,
2402:7d00::/32,
2402:7d80::/32,
2402:7da0::/32,
2402:7e20::/32,
2402:7ee0::/32,
2402:8180::/32,
2402:8300::/32,
2402:8380::/32,
@@ -1087,7 +1091,6 @@ set clashoo_china6 {
2402:e2c0::/32,
2402:e3c0::/32,
2402:e480::/32,
2402:e540::/32,
2402:e680::/32,
2402:e740::/32,
2402:e780::/32,
@@ -1253,12 +1256,16 @@ set clashoo_china6 {
2403:6180::/32,
2403:6280::/32,
2403:62c0::/32,
2403:6380::/42,
2403:6380::/44,
2403:6380:20::/44,
2403:6380:33::/48,
2403:6380:34::/46,
2403:6380:38::/45,
2403:6380:41::/48,
2403:6380:44::/46,
2403:6380:48::/45,
2403:6380:50::/44,
2403:6380:70::/44,
2403:6380:60::/43,
2403:6380:80::/41,
2403:6380:100::/40,
2403:6380:200::/39,
@@ -1484,6 +1491,9 @@ set clashoo_china6 {
2404:1e80::/32,
2404:1f40::/32,
2404:21c0::/32,
2404:2280:1000::/36,
2404:2280:2000::/35,
2404:2280:4000::/36,
2404:30c0::/32,
2404:3140::/32,
2404:31c0::/32,
@@ -1765,7 +1775,7 @@ set clashoo_china6 {
2405:84c0:800c::/46,
2405:84c0:8010::/48,
2405:84c0:8019::/48,
2405:84c0:801c::/46,
2405:84c0:801e::/47,
2405:84c0:8020::/47,
2405:84c0:8036::/47,
2405:84c0:8038::/46,
@@ -1780,7 +1790,11 @@ set clashoo_china6 {
2405:84c0:8050::/48,
2405:84c0:8053::/48,
2405:84c0:8058::/45,
2405:84c0:8060::/43,
2405:84c0:8061::/48,
2405:84c0:8062::/47,
2405:84c0:8064::/46,
2405:84c0:8068::/45,
2405:84c0:8070::/44,
2405:84c0:8080::/41,
2405:84c0:8100::/40,
2405:84c0:8200::/39,
@@ -2039,7 +2053,10 @@ set clashoo_china6 {
2406:840:8a0::/43,
2406:840:8c0::/42,
2406:840:900::/40,
2406:840:a00::/44,
2406:840:a01::/48,
2406:840:a02::/47,
2406:840:a04::/46,
2406:840:a08::/45,
2406:840:a12::/47,
2406:840:a14::/46,
2406:840:a18::/45,
@@ -2221,7 +2238,7 @@ set clashoo_china6 {
2406:840:9103::/48,
2406:840:9104::/46,
2406:840:9108::/45,
2406:840:9112::/47,
2406:840:9113::/48,
2406:840:9114::/46,
2406:840:9118::/45,
2406:840:9120::/43,
@@ -2237,7 +2254,8 @@ set clashoo_china6 {
2406:840:9610::/44,
2406:840:9630::/44,
2406:840:9640::/43,
2406:840:9660::/46,
2406:840:9660::/48,
2406:840:9662::/47,
2406:840:9664::/47,
2406:840:9667::/48,
2406:840:9668::/45,
@@ -2266,6 +2284,10 @@ set clashoo_china6 {
2406:840:9968::/46,
2406:840:996d::/48,
2406:840:996e::/47,
2406:840:9970::/46,
2406:840:9974::/47,
2406:840:9976::/48,
2406:840:9978::/45,
2406:840:9981::/48,
2406:840:9982::/47,
2406:840:9984::/46,
@@ -2295,6 +2317,7 @@ set clashoo_china6 {
2406:840:e0cc::/47,
2406:840:e0ce::/48,
2406:840:e0d0::/44,
2406:840:e0e4::/48,
2406:840:e0e6::/47,
2406:840:e0e9::/48,
2406:840:e0ea::/47,
@@ -2385,7 +2408,7 @@ set clashoo_china6 {
2406:840:ea00::/40,
2406:840:eb06::/48,
2406:840:eb09::/48,
2406:840:eb0a::/48,
2406:840:eb0a::/47,
2406:840:eb0c::/47,
2406:840:eb0e::/48,
2406:840:eb10::/44,
@@ -2469,6 +2492,10 @@ set clashoo_china6 {
2406:840:f600::/42,
2406:840:f640::/43,
2406:840:f670::/44,
2406:840:f680::/47,
2406:840:f682::/48,
2406:840:f684::/46,
2406:840:f688::/45,
2406:840:f690::/44,
2406:840:f6a0::/43,
2406:840:f6c0::/42,
@@ -2879,7 +2906,7 @@ set clashoo_china6 {
2406:e780::/32,
2406:e8c0::/32,
2406:ea40::/28,
2406:f280::/33,
2406:f280::/32,
2406:f300::/32,
2406:f4c0::/32,
2406:f7c0::/32,
@@ -3037,28 +3064,10 @@ set clashoo_china6 {
2407:fb80::/32,
2407:fc80::/32,
2407:fd80::/32,
2408:4000::/40,
2408:4000:100::/47,
2408:4000:103::/48,
2408:4000:104::/46,
2408:4000:108::/45,
2408:4000:110::/44,
2408:4000:120::/43,
2408:4000:140::/42,
2408:4000:180::/41,
2408:4000:200::/39,
2408:4000:400::/38,
2408:4000:800::/37,
2408:4000:1000::/36,
2408:4000:2000::/35,
2408:4000:4000::/34,
2408:4000:8000::/33,
2408:4001::/32,
2408:4002::/31,
2408:4004::/30,
2408:4008::/29,
2408:4000::/28,
2408:4010::/30,
2408:4014::/31,
2408:4016:1::/48,
2408:4016:2::/47,
2408:4016:4::/46,
2408:4016:8::/45,
@@ -3121,6 +3130,40 @@ set clashoo_china6 {
240a:a000::/20,
240a:c000::/20,
240b:2000::/22,
240b:4000::/31,
240b:4002::/36,
240b:4002:1000::/44,
240b:4002:1011::/48,
240b:4002:1012::/47,
240b:4002:1014::/46,
240b:4002:1018::/45,
240b:4002:1020::/43,
240b:4002:1040::/42,
240b:4002:1080::/41,
240b:4002:1100::/40,
240b:4002:1200::/39,
240b:4002:1400::/38,
240b:4002:1800::/37,
240b:4002:2000::/35,
240b:4002:4000::/34,
240b:4002:8000::/33,
240b:4004::/31,
240b:4006::/48,
240b:4006:1000::/43,
240b:4006:1020::/44,
240b:4006:1100::/44,
240b:4006:1110::/45,
240b:4006:1118::/46,
240b:4007::/32,
240b:4009::/32,
240b:400b::/32,
240b:400c::/30,
240b:4010:fffe::/47,
240b:4011::/32,
240b:4012::/31,
240b:4014::/30,
240b:4018::/30,
240b:401f::/32,
240b:6000::/20,
240b:8000::/21,
240b:a000::/25,
@@ -3224,8 +3267,6 @@ set clashoo_china6 {
2605:9d80:9042::/48,
2605:9d80:9071::/48,
2605:9d80:9092::/48,
2620:57:4004::/47,
2804:1e48:9002::/48,
2a03:f900::/29,
2a04:3e00::/48,
2a04:3e00:2::/47,
@@ -3240,7 +3281,7 @@ set clashoo_china6 {
2a04:3e00:400::/38,
2a04:3e00:800::/37,
2a04:3e00:1001::/48,
2a04:3e00:1002::/48,
2a04:3e00:1002::/47,
2a04:3e00:1004::/46,
2a04:3e00:1008::/45,
2a04:3e00:1010::/44,
@@ -3264,12 +3305,10 @@ set clashoo_china6 {
2a04:f580:9010::/48,
2a04:f580:9012::/47,
2a04:f580:9020::/48,
2a04:f580:9030::/48,
2a04:f580:9040::/48,
2a04:f580:9050::/48,
2a04:f580:9060::/48,
2a04:f580:9070::/48,
2a04:f580:9080::/48,
2a04:f580:9210::/48,
2a04:f580:9212::/47,
2a04:f580:9220::/48,
@@ -3318,9 +3357,7 @@ set clashoo_china6 {
2a0a:d681:e200::/39,
2a0a:d681:e400::/38,
2a0a:d681:e800::/37,
2a0a:d681:f000::/37,
2a0a:d681:f800::/38,
2a0a:d681:fe00::/40,
2a0a:d681:f000::/36,
2a0a:d682::/33,
2a0a:d682:8000::/34,
2a0a:d682:c000::/36,
@@ -3329,13 +3366,18 @@ set clashoo_china6 {
2a0a:d685::/40,
2a0a:d685:100::/41,
2a0a:d685:180::/42,
2a0a:d685:1c0::/43,
2a0a:d685:1c0::/44,
2a0a:d685:1d1::/48,
2a0a:d685:1d2::/47,
2a0a:d685:1d4::/46,
2a0a:d685:1d8::/45,
2a0a:d685:1e2::/47,
2a0a:d685:1e4::/46,
2a0a:d685:1e8::/45,
2a0a:d685:1f0::/45,
2a0a:d685:1f8::/47,
2a0a:d685:1fa::/48,
2a0a:d685:200::/48,
2a0a:d685:202::/47,
2a0a:d685:204::/46,
2a0a:d685:208::/45,
@@ -3343,7 +3385,16 @@ set clashoo_china6 {
2a0a:d685:220::/43,
2a0a:d685:240::/42,
2a0a:d685:280::/41,
2a0a:d685:400::/38,
2a0a:d685:400::/40,
2a0a:d685:500::/45,
2a0a:d685:508::/48,
2a0a:d685:50a::/47,
2a0a:d685:50c::/46,
2a0a:d685:510::/44,
2a0a:d685:520::/43,
2a0a:d685:540::/42,
2a0a:d685:580::/41,
2a0a:d685:600::/39,
2a0a:d685:800::/37,
2a0a:d685:1000::/36,
2a0a:d685:2000::/35,
@@ -3425,7 +3476,10 @@ set clashoo_china6 {
2a13:1802:2000::/35,
2a13:1802:4000::/34,
2a13:1802:8000::/34,
2a13:1802:c000::/44,
2a13:1802:c000::/48,
2a13:1802:c002::/47,
2a13:1802:c004::/46,
2a13:1802:c008::/45,
2a13:1802:c020::/43,
2a13:1802:c040::/42,
2a13:1802:c080::/41,
@@ -64,6 +64,7 @@ set clashoo_china {
5.10.138.0/23,
5.10.140.0/24,
5.10.143.0/24,
5.181.224.0/23,
8.128.4.0/22,
8.128.32.0/19,
8.128.64.0/19,
@@ -91,11 +92,92 @@ set clashoo_china {
8.168.0.0/15,
8.176.0.0/17,
8.176.128.0/19,
8.208.0.0/17,
8.208.128.0/21,
8.208.140.0/22,
8.208.144.0/20,
8.208.160.0/19,
8.208.192.0/18,
8.209.0.0/19,
8.209.36.0/22,
8.209.40.0/21,
8.209.48.0/20,
8.209.64.0/18,
8.209.128.0/18,
8.209.192.0/24,
8.209.194.0/23,
8.209.196.0/22,
8.209.200.0/21,
8.209.208.0/20,
8.209.224.0/19,
8.210.0.0/16,
8.211.0.0/17,
8.211.128.0/18,
8.211.192.0/19,
8.211.224.0/22,
8.211.232.0/21,
8.211.240.0/20,
8.212.0.0/18,
8.212.64.0/20,
8.212.80.0/21,
8.212.88.0/22,
8.212.92.0/24,
8.212.94.0/23,
8.212.96.0/22,
8.212.104.0/21,
8.212.112.0/20,
8.212.128.0/19,
8.212.160.0/20,
8.212.176.0/21,
8.212.188.0/22,
8.212.192.0/18,
8.213.0.0/16,
8.214.0.0/17,
8.214.128.0/19,
8.214.164.0/22,
8.214.168.0/21,
8.214.176.0/20,
8.214.192.0/18,
8.215.0.0/17,
8.215.128.0/19,
8.215.160.0/22,
8.215.168.0/21,
8.215.176.0/20,
8.215.192.0/18,
8.216.0.0/18,
8.216.64.0/21,
8.216.72.0/22,
8.216.80.0/20,
8.216.96.0/19,
8.216.128.0/17,
8.217.0.0/16,
8.218.0.0/15,
8.220.0.0/18,
8.220.64.0/19,
8.220.96.0/20,
8.220.112.0/21,
8.220.120.0/22,
8.220.128.0/19,
8.220.160.0/21,
8.220.172.0/22,
8.220.176.0/20,
8.220.192.0/19,
8.220.224.0/21,
8.220.232.0/22,
8.220.240.0/21,
8.221.0.0/17,
8.221.128.0/20,
8.221.144.0/21,
8.221.156.0/22,
8.221.160.0/19,
8.221.192.0/18,
8.222.0.0/15,
14.0.0.0/21,
14.0.12.0/22,
14.1.0.0/22,
14.1.24.0/22,
14.1.108.0/22,
14.1.112.0/22,
14.16.0.0/12,
14.102.128.0/22,
14.102.180.0/22,
@@ -308,6 +390,79 @@ set clashoo_china {
42.242.0.0/15,
42.244.0.0/14,
42.248.0.0/13,
43.90.0.0/16,
43.92.0.0/15,
43.94.0.0/18,
43.96.0.0/23,
43.96.2.130/32,
43.96.3.0/24,
43.96.4.0/22,
43.96.8.0/22,
43.96.16.130/32,
43.96.18.0/24,
43.96.20.0/22,
43.96.24.0/22,
43.96.32.0/22,
43.96.36.130/32,
43.96.40.0/24,
43.96.42.0/24,
43.96.44.0/23,
43.96.46.0/24,
43.96.48.0/21,
43.96.59.0/24,
43.96.60.0/24,
43.96.62.0/23,
43.96.64.0/21,
43.96.72.0/22,
43.96.77.131/32,
43.96.78.0/24,
43.96.80.0/23,
43.96.85.0/24,
43.96.86.0/24,
43.96.88.0/23,
43.96.90.0/24,
43.96.92.0/22,
43.96.96.0/23,
43.96.100.0/23,
43.96.103.0/24,
43.96.104.0/23,
43.96.107.0/24,
43.96.109.0/24,
43.96.110.0/23,
43.96.112.0/22,
43.96.116.0/24,
43.96.118.0/23,
43.96.120.0/24,
43.96.122.0/24,
43.96.124.0/23,
43.96.126.0/24,
43.97.0.0/17,
43.98.0.0/15,
43.100.0.0/15,
43.102.0.0/17,
43.102.192.0/18,
43.103.0.0/16,
43.104.0.0/14,
43.108.0.0/16,
43.110.0.0/15,
43.112.0.0/15,
43.114.0.0/16,
43.116.0.0/17,
43.116.160.0/24,
43.116.192.0/18,
43.117.0.0/16,
43.118.0.0/17,
43.118.128.0/18,
43.119.0.0/16,
43.120.0.0/15,
43.122.0.0/16,
43.123.0.0/17,
43.123.128.0/18,
43.124.0.0/16,
43.125.0.0/19,
43.125.32.0/20,
43.125.48.0/21,
43.126.0.0/17,
43.136.0.0/13,
43.144.0.0/15,
43.148.0.0/14,
@@ -458,7 +613,8 @@ set clashoo_china {
43.242.160.0/21,
43.242.168.0/22,
43.242.180.0/22,
43.242.188.0/22,
43.242.189.0/24,
43.242.190.0/23,
43.242.192.0/21,
43.242.204.0/22,
43.242.216.0/21,
@@ -648,6 +804,7 @@ set clashoo_china {
45.117.68.0/22,
45.117.124.0/22,
45.117.252.0/22,
45.119.42.0/23,
45.119.60.0/22,
45.119.64.0/21,
45.119.72.0/22,
@@ -728,6 +885,7 @@ set clashoo_china {
45.127.128.0/22,
45.127.144.0/21,
45.127.156.0/22,
45.199.179.0/24,
45.248.8.0/22,
45.248.80.0/21,
45.248.96.0/20,
@@ -773,6 +931,7 @@ set clashoo_china {
45.251.160.0/19,
45.251.192.0/19,
45.251.224.0/22,
45.251.248.0/23,
45.252.0.0/21,
45.252.9.0/24,
45.252.10.0/23,
@@ -830,8 +989,158 @@ set clashoo_china {
45.255.224.0/20,
45.255.240.0/21,
45.255.248.0/22,
47.52.0.0/16,
47.56.0.0/16,
47.57.0.0/17,
47.57.128.0/18,
47.57.192.0/22,
47.57.196.0/24,
47.57.198.0/23,
47.57.200.0/21,
47.57.208.0/20,
47.57.224.0/19,
47.74.0.0/15,
47.76.0.0/16,
47.77.0.0/20,
47.77.16.0/21,
47.77.24.0/22,
47.77.32.0/19,
47.77.64.0/19,
47.77.96.0/20,
47.77.112.0/23,
47.77.128.0/17,
47.78.0.0/15,
47.80.0.0/14,
47.84.0.0/15,
47.86.0.0/16,
47.87.0.0/20,
47.87.16.0/21,
47.87.32.0/19,
47.87.64.0/21,
47.87.80.0/20,
47.87.96.0/19,
47.87.128.0/20,
47.87.144.0/21,
47.87.156.0/22,
47.87.160.0/19,
47.87.192.0/18,
47.88.0.0/16,
47.89.0.0/18,
47.89.72.0/21,
47.89.80.0/22,
47.89.84.0/24,
47.89.88.0/23,
47.89.90.0/24,
47.89.92.0/22,
47.89.96.0/20,
47.89.122.0/23,
47.89.124.0/23,
47.89.128.0/17,
47.90.0.0/17,
47.90.128.0/19,
47.90.160.0/21,
47.90.168.0/22,
47.90.176.0/20,
47.90.192.0/18,
47.91.0.0/16,
47.92.0.0/14,
47.96.0.0/11,
47.235.0.0/21,
47.235.8.0/22,
47.235.12.0/23,
47.235.16.0/20,
47.236.0.0/17,
47.236.128.0/18,
47.236.192.0/20,
47.236.208.0/21,
47.236.220.0/22,
47.236.224.0/19,
47.237.0.0/17,
47.237.128.0/18,
47.237.192.0/19,
47.237.224.0/20,
47.237.240.0/21,
47.237.249.0/24,
47.237.250.0/23,
47.237.252.0/22,
47.238.0.0/20,
47.238.16.0/21,
47.238.28.0/22,
47.238.32.0/19,
47.238.64.0/18,
47.238.128.0/17,
47.239.0.0/16,
47.240.0.0/14,
47.244.0.0/16,
47.245.0.0/17,
47.245.128.0/20,
47.245.144.0/21,
47.245.152.0/22,
47.245.160.0/19,
47.245.192.0/20,
47.245.208.0/21,
47.245.216.0/22,
47.245.224.0/19,
47.246.32.0/22,
47.246.66.0/23,
47.246.68.0/23,
47.246.72.0/21,
47.246.82.0/23,
47.246.84.0/22,
47.246.88.0/23,
47.246.91.0/24,
47.246.92.0/23,
47.246.96.0/22,
47.246.101.0/24,
47.246.102.0/23,
47.246.104.0/21,
47.246.120.0/24,
47.246.122.0/23,
47.246.124.0/23,
47.246.128.0/23,
47.246.131.0/24,
47.246.132.0/23,
47.246.135.0/24,
47.246.136.0/21,
47.246.144.0/22,
47.246.150.0/23,
47.246.152.0/22,
47.246.157.0/24,
47.246.158.0/23,
47.246.160.0/23,
47.246.162.0/24,
47.246.164.0/22,
47.246.168.0/21,
47.246.176.0/20,
47.246.192.0/20,
47.246.208.0/23,
47.246.212.0/22,
47.246.216.0/22,
47.250.0.0/18,
47.250.68.0/22,
47.250.72.0/21,
47.250.80.0/20,
47.250.96.0/21,
47.250.108.0/22,
47.250.112.0/20,
47.250.128.0/17,
47.251.0.0/17,
47.251.132.0/22,
47.251.136.0/21,
47.251.144.0/20,
47.251.160.0/19,
47.251.196.0/22,
47.251.200.0/21,
47.251.208.0/20,
47.251.224.0/19,
47.252.0.0/16,
47.253.0.0/18,
47.253.64.0/19,
47.253.96.0/20,
47.253.112.0/21,
47.253.120.0/22,
47.253.128.0/17,
47.254.0.0/16,
49.4.0.0/17,
49.4.128.0/22,
49.4.160.0/20,
@@ -897,14 +1206,7 @@ set clashoo_china {
58.240.0.0/12,
59.32.0.0/11,
59.64.0.0/12,
59.80.0.0/15,
59.82.0.0/16,
59.83.0.0/17,
59.83.144.0/20,
59.83.160.0/20,
59.83.192.0/19,
59.83.224.0/21,
59.83.232.0/22,
59.80.0.0/14,
59.107.0.0/17,
59.107.226.0/24,
59.107.255.0/24,
@@ -923,9 +1225,7 @@ set clashoo_china {
59.153.136.0/22,
59.153.152.0/22,
59.153.164.0/22,
59.153.168.0/22,
59.153.173.0/24,
59.153.174.0/23,
59.153.168.0/21,
59.153.176.0/20,
59.153.192.0/22,
59.155.0.0/16,
@@ -978,6 +1278,7 @@ set clashoo_china {
61.232.0.0/14,
61.236.0.0/15,
61.240.0.0/14,
62.182.190.0/23,
62.234.0.0/16,
63.140.0.0/24,
63.140.3.0/24,
@@ -1154,8 +1455,7 @@ set clashoo_china {
103.5.56.0/22,
103.5.152.0/22,
103.5.168.0/22,
103.5.192.0/23,
103.5.194.0/24,
103.5.192.0/22,
103.5.252.0/22,
103.6.76.0/22,
103.6.220.0/22,
@@ -1223,7 +1523,8 @@ set clashoo_china {
103.19.40.0/21,
103.19.64.0/21,
103.19.72.0/22,
103.19.232.0/22,
103.19.233.0/24,
103.19.234.0/23,
103.20.12.0/22,
103.20.32.0/24,
103.20.34.0/23,
@@ -1636,6 +1937,7 @@ set clashoo_china {
103.70.236.0/22,
103.70.252.0/22,
103.71.0.0/22,
103.71.49.0/24,
103.71.68.0/22,
103.71.72.0/22,
103.71.80.0/21,
@@ -1660,7 +1962,10 @@ set clashoo_china {
103.72.234.0/23,
103.72.236.0/22,
103.72.240.0/20,
103.73.0.0/19,
103.73.0.0/21,
103.73.10.0/23,
103.73.12.0/22,
103.73.16.0/20,
103.73.48.0/22,
103.73.116.0/22,
103.73.120.0/22,
@@ -1677,6 +1982,7 @@ set clashoo_china {
103.74.48.0/22,
103.74.56.0/21,
103.74.80.0/22,
103.74.126.0/23,
103.74.148.0/22,
103.74.152.0/21,
103.74.204.0/22,
@@ -1736,7 +2042,7 @@ set clashoo_china {
103.81.120.0/22,
103.81.148.0/22,
103.81.164.0/22,
103.81.184.0/23,
103.81.184.0/22,
103.81.200.0/22,
103.81.232.0/22,
103.82.60.0/22,
@@ -1751,6 +2057,7 @@ set clashoo_china {
103.83.64.0/22,
103.83.72.0/22,
103.83.112.0/22,
103.83.180.0/22,
103.84.0.0/22,
103.84.12.0/22,
103.84.16.0/20,
@@ -1903,7 +2210,7 @@ set clashoo_china {
103.98.232.0/22,
103.98.240.0/20,
103.99.53.0/24,
103.99.54.0/23,
103.99.55.0/24,
103.99.56.0/22,
103.99.62.0/24,
103.99.104.0/22,
@@ -1956,7 +2263,6 @@ set clashoo_china {
103.104.104.0/22,
103.104.152.0/22,
103.104.188.0/22,
103.104.198.0/23,
103.104.252.0/22,
103.105.0.0/21,
103.105.12.0/22,
@@ -2728,8 +3034,7 @@ set clashoo_china {
103.235.85.0/24,
103.235.87.0/24,
103.235.100.0/22,
103.235.132.0/22,
103.235.136.0/21,
103.235.128.0/20,
103.235.144.0/21,
103.235.184.0/22,
103.235.192.0/22,
@@ -2839,6 +3144,7 @@ set clashoo_china {
103.247.200.0/22,
103.247.212.0/22,
103.248.0.0/23,
103.248.64.0/22,
103.248.100.0/22,
103.248.124.0/22,
103.248.152.0/22,
@@ -2953,16 +3259,7 @@ set clashoo_china {
110.6.0.0/15,
110.16.0.0/14,
110.34.40.0/21,
110.40.0.0/15,
110.42.0.0/20,
110.42.16.0/24,
110.42.18.0/23,
110.42.20.0/22,
110.42.24.0/21,
110.42.32.0/19,
110.42.64.0/18,
110.42.128.0/17,
110.43.0.0/16,
110.40.0.0/14,
110.44.12.0/22,
110.44.144.0/20,
110.48.0.0/16,
@@ -2983,20 +3280,7 @@ set clashoo_china {
110.92.68.0/22,
110.93.32.0/19,
110.94.0.0/15,
110.96.0.0/15,
110.98.0.0/16,
110.100.0.0/14,
110.104.0.0/13,
110.112.0.0/13,
110.120.0.0/16,
110.121.0.0/22,
110.121.8.0/21,
110.121.16.0/20,
110.121.32.0/19,
110.121.64.0/18,
110.121.128.0/17,
110.122.0.0/15,
110.124.0.0/14,
110.96.0.0/11,
110.152.0.0/14,
110.156.0.0/15,
110.165.32.0/19,
@@ -3063,7 +3347,7 @@ set clashoo_china {
111.235.160.0/19,
112.0.0.0/10,
112.64.0.0/14,
112.73.232.0/24,
112.73.222.0/24,
112.74.0.0/15,
112.80.0.0/12,
112.96.0.0/13,
@@ -3146,12 +3430,7 @@ set clashoo_china {
114.31.64.0/21,
114.54.0.0/15,
114.60.0.0/14,
114.64.0.0/15,
114.66.0.0/17,
114.66.224.0/22,
114.66.236.0/22,
114.66.240.0/20,
114.67.0.0/16,
114.64.0.0/14,
114.68.0.0/16,
114.79.64.0/18,
114.80.0.0/12,
@@ -3180,7 +3459,8 @@ set clashoo_china {
114.112.240.0/23,
114.112.245.0/24,
114.112.247.0/24,
114.112.248.0/22,
114.112.248.0/23,
114.112.251.0/24,
114.112.252.0/23,
114.113.0.0/17,
114.113.128.0/21,
@@ -3298,6 +3578,7 @@ set clashoo_china {
116.242.0.0/15,
116.244.0.0/14,
116.248.0.0/15,
116.251.64.0/18,
116.252.0.0/15,
116.254.104.0/21,
116.254.128.0/17,
@@ -3337,6 +3618,7 @@ set clashoo_china {
117.120.148.0/22,
117.120.164.0/22,
117.120.184.0/21,
117.120.196.0/22,
117.120.208.0/21,
117.120.216.0/22,
117.120.248.0/21,
@@ -3349,10 +3631,9 @@ set clashoo_china {
117.132.0.0/15,
117.134.0.0/17,
117.134.128.0/18,
117.134.207.0/24,
117.134.208.0/23,
117.134.212.0/23,
117.134.216.0/22,
117.134.218.0/23,
117.134.222.0/23,
117.134.232.0/21,
117.134.240.0/20,
@@ -3442,7 +3723,9 @@ set clashoo_china {
119.19.0.0/16,
119.20.0.0/14,
119.27.64.0/18,
119.27.128.0/17,
119.27.128.0/18,
119.27.208.0/20,
119.27.224.0/20,
119.28.28.0/24,
119.28.240.0/20,
119.29.0.0/16,
@@ -3460,13 +3743,7 @@ set clashoo_china {
119.48.0.0/13,
119.57.0.0/16,
119.58.0.0/16,
119.59.128.0/24,
119.59.130.0/24,
119.59.132.0/22,
119.59.136.0/21,
119.59.144.0/20,
119.59.160.0/19,
119.59.192.0/18,
119.59.128.0/17,
119.60.0.0/15,
119.62.0.0/16,
119.63.32.0/19,
@@ -3487,7 +3764,6 @@ set clashoo_china {
119.161.120.0/21,
119.161.128.0/21,
119.161.144.0/21,
119.161.152.0/23,
119.161.160.0/19,
119.161.192.0/18,
119.162.0.0/15,
@@ -3564,8 +3840,7 @@ set clashoo_china {
121.59.102.0/23,
121.59.104.0/23,
121.59.107.0/24,
121.59.108.0/24,
121.59.110.0/23,
121.59.108.0/22,
121.59.112.0/21,
121.59.121.0/24,
121.59.123.0/24,
@@ -3605,8 +3880,7 @@ set clashoo_china {
122.8.68.0/22,
122.8.76.0/22,
122.8.80.0/23,
122.8.112.0/21,
122.8.124.0/22,
122.8.116.0/22,
122.8.192.0/18,
122.9.0.0/16,
122.10.129.0/24,
@@ -3696,15 +3970,13 @@ set clashoo_china {
123.49.128.0/18,
123.49.192.0/23,
123.49.194.0/24,
123.49.197.0/24,
123.49.198.0/23,
123.49.196.0/22,
123.49.200.0/21,
123.49.208.0/20,
123.49.224.0/21,
123.49.232.0/22,
123.49.236.0/24,
123.49.224.0/20,
123.49.240.0/24,
123.49.242.0/23,
123.49.245.0/24,
123.49.248.0/21,
123.50.160.0/19,
123.52.0.0/14,
@@ -3782,10 +4054,6 @@ set clashoo_china {
124.67.0.0/16,
124.68.16.0/20,
124.68.64.0/18,
124.68.176.0/20,
124.68.224.0/20,
124.68.244.0/22,
124.68.248.0/21,
124.69.0.0/16,
124.70.0.0/16,
124.71.0.0/17,
@@ -3885,6 +4153,15 @@ set clashoo_china {
139.5.212.0/22,
139.5.244.0/22,
139.9.0.0/16,
139.95.0.0/20,
139.95.16.0/22,
139.95.22.0/23,
139.95.24.0/21,
139.95.32.0/21,
139.95.40.0/23,
139.95.64.0/23,
139.95.96.0/22,
139.95.128.0/17,
139.129.0.0/16,
139.148.0.0/16,
139.155.0.0/16,
@@ -3945,14 +4222,7 @@ set clashoo_china {
140.179.0.0/16,
140.205.0.0/16,
140.206.0.0/15,
140.210.0.0/20,
140.210.16.0/21,
140.210.24.0/22,
140.210.28.0/23,
140.210.30.0/24,
140.210.32.0/19,
140.210.64.0/18,
140.210.128.0/17,
140.210.0.0/16,
140.224.0.0/16,
140.237.0.0/16,
140.240.0.0/16,
@@ -3961,11 +4231,12 @@ set clashoo_china {
140.249.0.0/16,
140.250.0.0/16,
140.255.0.0/16,
142.86.192.0/19,
142.86.200.0/21,
142.86.208.0/20,
142.86.224.0/20,
142.86.240.0/21,
142.86.248.0/22,
142.86.254.0/23,
142.86.255.0/24,
143.64.0.0/16,
144.0.0.0/16,
144.7.0.0/16,
@@ -4008,9 +4279,23 @@ set clashoo_china {
146.222.94.0/24,
147.78.132.0/24,
147.78.134.0/24,
147.139.0.0/17,
147.139.128.0/18,
147.139.192.0/19,
147.139.224.0/20,
147.139.240.0/21,
147.139.248.0/22,
148.70.0.0/16,
149.41.64.0/18,
149.41.192.0/19,
149.129.0.0/20,
149.129.16.0/21,
149.129.32.0/19,
149.129.64.0/18,
149.129.128.0/19,
149.129.168.0/21,
149.129.176.0/20,
149.129.192.0/18,
150.0.0.0/16,
150.115.0.0/16,
150.121.0.0/16,
@@ -4068,6 +4353,10 @@ set clashoo_china {
156.107.170.0/24,
156.107.179.0/24,
156.107.181.0/24,
156.227.20.0/24,
156.236.12.0/24,
156.236.17.0/24,
156.245.1.0/24,
157.0.0.0/16,
157.10.34.0/23,
157.10.36.0/23,
@@ -4086,7 +4375,7 @@ set clashoo_china {
157.20.194.0/23,
157.20.246.0/23,
157.61.0.0/16,
157.66.42.0/23,
157.66.43.0/24,
157.66.70.0/23,
157.66.88.0/21,
157.66.164.0/23,
@@ -4144,6 +4433,7 @@ set clashoo_china {
160.202.62.0/24,
160.202.148.0/22,
160.202.152.0/22,
160.202.210.0/23,
160.202.212.0/22,
160.202.216.0/21,
160.202.224.0/19,
@@ -4162,6 +4452,7 @@ set clashoo_china {
160.250.170.0/23,
160.250.214.0/23,
160.250.252.0/23,
161.117.0.0/16,
161.163.0.0/21,
161.163.28.0/23,
161.189.0.0/16,
@@ -4219,9 +4510,7 @@ set clashoo_china {
163.204.0.0/16,
163.223.28.0/23,
163.223.32.0/23,
163.223.72.0/23,
163.223.124.0/23,
163.223.217.0/24,
163.223.222.0/23,
163.227.34.0/23,
163.227.40.0/23,
@@ -4249,6 +4538,29 @@ set clashoo_china {
167.189.0.0/16,
167.220.244.0/22,
168.160.0.0/16,
170.33.15.0/24,
170.33.20.0/22,
170.33.24.0/24,
170.33.29.0/24,
170.33.30.0/23,
170.33.32.0/22,
170.33.41.0/24,
170.33.64.0/23,
170.33.66.0/24,
170.33.68.0/23,
170.33.72.0/23,
170.33.76.0/22,
170.33.80.0/22,
170.33.84.0/24,
170.33.104.0/22,
170.33.112.0/23,
170.33.114.0/24,
170.33.129.0/24,
170.33.130.0/23,
170.33.136.0/23,
170.33.138.0/24,
170.33.168.0/23,
170.33.192.0/23,
170.179.0.0/16,
171.8.0.0/13,
171.34.0.0/15,
@@ -4383,7 +4695,6 @@ set clashoo_china {
183.91.52.0/22,
183.91.56.0/24,
183.91.61.0/24,
183.91.63.0/24,
183.91.128.0/22,
183.91.136.0/21,
183.91.144.0/20,
@@ -4418,6 +4729,7 @@ set clashoo_china {
192.140.160.0/19,
192.140.192.0/20,
192.140.208.0/21,
192.140.244.0/23,
192.144.128.0/17,
192.163.11.0/24,
192.232.34.0/23,
@@ -4427,6 +4739,12 @@ set clashoo_china {
193.119.0.0/19,
194.138.202.0/23,
194.138.245.0/24,
198.11.128.0/20,
198.11.145.0/24,
198.11.146.0/23,
198.11.148.0/22,
198.11.152.0/21,
198.11.160.0/19,
198.175.100.0/22,
198.208.17.0/24,
198.208.19.0/24,
@@ -4797,8 +5115,7 @@ set clashoo_china {
202.143.56.0/21,
202.143.100.0/22,
202.143.104.0/22,
202.144.196.0/23,
202.144.198.0/24,
202.144.196.0/22,
202.146.160.0/20,
202.146.184.0/23,
202.146.186.0/24,
@@ -4838,7 +5155,6 @@ set clashoo_china {
202.164.0.0/20,
202.164.96.0/19,
202.165.176.0/20,
202.165.208.0/21,
202.165.239.0/24,
202.165.240.0/23,
202.165.243.0/24,
@@ -5710,6 +6026,7 @@ set clashoo_china {
203.81.1.0/24,
203.81.2.0/24,
203.81.5.0/24,
203.81.7.0/24,
203.81.16.0/20,
203.81.244.0/22,
203.82.0.0/23,
@@ -5783,17 +6100,7 @@ set clashoo_china {
203.104.32.0/20,
203.105.96.0/19,
203.105.128.0/19,
203.107.0.0/23,
203.107.2.0/24,
203.107.4.0/22,
203.107.8.0/21,
203.107.16.0/20,
203.107.32.0/19,
203.107.69.0/24,
203.107.70.0/23,
203.107.72.0/21,
203.107.80.0/20,
203.107.96.0/19,
203.107.0.0/17,
203.110.160.0/19,
203.110.208.0/20,
203.110.232.0/23,
@@ -5818,8 +6125,7 @@ set clashoo_china {
203.123.58.0/24,
203.128.32.0/19,
203.128.96.0/19,
203.128.225.0/24,
203.128.226.0/23,
203.128.224.0/22,
203.128.228.0/24,
203.128.231.0/24,
203.129.8.0/24,
@@ -5932,6 +6238,7 @@ set clashoo_china {
203.223.16.0/24,
203.223.21.0/24,
203.223.22.0/23,
205.204.96.0/19,
206.109.70.0/23,
206.109.75.0/24,
210.2.0.0/19,
@@ -5987,6 +6294,7 @@ set clashoo_china {
211.144.0.0/14,
211.148.0.0/16,
211.149.0.0/19,
211.149.32.0/22,
211.149.48.0/21,
211.149.64.0/21,
211.149.80.0/21,
@@ -6177,12 +6485,14 @@ set clashoo_china {
223.112.0.0/14,
223.116.0.0/15,
223.121.128.0/17,
223.122.4.0/22,
223.122.12.0/22,
223.122.5.0/24,
223.122.6.0/23,
223.122.13.0/24,
223.122.14.0/23,
223.122.18.0/23,
223.122.20.0/22,
223.122.26.0/23,
223.122.28.0/22,
223.122.28.0/23,
223.123.196.0/22,
223.123.204.0/22,
223.123.208.0/20,
Binary file not shown.
Binary file not shown.
@@ -145,132 +145,70 @@ dns_mihomo_apply_respect_rules() {
# Use fallback DNS for queries; keep bootstrap DNS unchanged.
dns_mihomo_apply_leak_nameservers() {
local cfg="$1" enabled="${2:-0}" state="${1}.dns-leak-nameserver"
local selected="${1}.dns-leak-selected" current="${1}.dns-leak-current" tmp="${1}.$$"
local selected="${1}.dns-leak-selected" tmp="${1}.$$"
# The config is rebuilt from the selected subscription on every run.
# A saved nameserver from an earlier run must never replace its DNS.
rm -f "$state" 2>/dev/null
[ "$enabled" = "1" ] || return 0
[ -f "$cfg" ] || return 0
command -v yq >/dev/null 2>&1 || return 0
if [ "$enabled" = "1" ]; then
yq e -r '.dns.fallback[]' "$cfg" > "$selected" 2>/dev/null || true
if [ ! -s "$selected" ]; then
printf '%s\n' 'https://1.1.1.1/dns-query' 'https://8.8.8.8/dns-query' > "$selected"
fi
yq e -r '.dns.nameserver[]' "$cfg" > "$current" 2>/dev/null || true
if [ ! -f "$state" ] ||
! grep -q 'clashoo:dns_leak_protect_respect_rules' "$cfg" ||
! cmp -s "$current" "$selected"; then
awk '
function indent_len(s) { match(s, /[^ ]/); return RSTART ? RSTART - 1 : length(s) }
/^dns:[[:space:]]*$/ { in_dns = 1; dns_indent = indent_len($0); next }
in_dns && /^[^[:space:]#][^:]*:/ { exit }
in_dns && /^[[:space:]]*nameserver:/ {
print
rest = $0
sub(/^[[:space:]]*nameserver:[[:space:]]*/, "", rest)
sub(/[[:space:]]*(#.*)?$/, "", rest)
if (rest == "") { in_ns = 1; ns_indent = indent_len($0) }
next
}
in_ns {
cur_indent = indent_len($0)
if ($0 ~ /^[[:space:]]*$/ || cur_indent > ns_indent) {
print
next
}
exit
}
' "$cfg" > "$state"
[ -s "$state" ] || printf '__ABSENT__\n' > "$state"
fi
awk -v selected="$selected" '
function indent_len(s) { match(s, /[^ ]/); return RSTART ? RSTART - 1 : length(s) }
function spaces(n, out,i) {
out = ""
for (i = 0; i < n; i++) out = out " "
return out
}
function print_selected(sp, line) {
print sp "nameserver:"
while ((getline line < selected) > 0)
if (line != "") print sp " - " line
close(selected)
inserted = 1
}
/^dns:[[:space:]]*$/ {
in_dns = 1
dns_indent = indent_len($0)
child_indent = -1
print
next
}
in_dns && /^[^[:space:]#][^:]*:/ {
if (!inserted) print_selected(spaces(child_indent > 0 ? child_indent : dns_indent + 2))
in_dns = 0
print
next
}
in_dns && /^[[:space:]]*[^#[:space:]][^:]*:/ && child_indent < 0 {
child_indent = indent_len($0)
}
in_dns && /^[[:space:]]*nameserver:/ {
ns_indent = indent_len($0)
rest = $0
sub(/^[[:space:]]*nameserver:[[:space:]]*/, "", rest)
sub(/[[:space:]]*(#.*)?$/, "", rest)
print_selected(spaces(ns_indent))
if (rest == "") skip_ns = 1
next
}
skip_ns {
cur_indent = indent_len($0)
if ($0 ~ /^[[:space:]]*$/ || cur_indent > ns_indent) next
skip_ns = 0
}
{ print }
END {
if (in_dns && !inserted)
print_selected(spaces(child_indent > 0 ? child_indent : dns_indent + 2))
}
' "$cfg" > "$tmp" && mv "$tmp" "$cfg"
elif [ -f "$state" ]; then
awk -v state="$state" '
function indent_len(s) { match(s, /[^ ]/); return RSTART ? RSTART - 1 : length(s) }
function print_original( line) {
if ((getline line < state) > 0 && line != "__ABSENT__") {
print line
while ((getline line < state) > 0) print line
}
close(state)
restored = 1
}
/^dns:[[:space:]]*$/ { in_dns = 1; print; next }
in_dns && /^[^[:space:]#][^:]*:/ {
if (!restored) print_original()
in_dns = 0
print
next
}
in_dns && /^[[:space:]]*nameserver:/ {
ns_indent = indent_len($0)
rest = $0
sub(/^[[:space:]]*nameserver:[[:space:]]*/, "", rest)
sub(/[[:space:]]*(#.*)?$/, "", rest)
print_original()
if (rest == "") skip_ns = 1
next
}
skip_ns {
cur_indent = indent_len($0)
if ($0 ~ /^[[:space:]]*$/ || cur_indent > ns_indent) next
skip_ns = 0
}
{ print }
END { if (in_dns && !restored) print_original() }
' "$cfg" > "$tmp" && mv "$tmp" "$cfg"
rm -f "$state"
yq e -r '.dns.fallback[]' "$cfg" > "$selected" 2>/dev/null || true
if [ ! -s "$selected" ]; then
printf '%s\n' 'https://1.1.1.1/dns-query' 'https://8.8.8.8/dns-query' > "$selected"
fi
rm -f "$selected" "$current" "$tmp" 2>/dev/null
awk -v selected="$selected" '
function indent_len(s) { match(s, /[^ ]/); return RSTART ? RSTART - 1 : length(s) }
function spaces(n, out,i) {
out = ""
for (i = 0; i < n; i++) out = out " "
return out
}
function print_selected(sp, line) {
print sp "nameserver:"
while ((getline line < selected) > 0)
if (line != "") print sp " - " line
close(selected)
inserted = 1
}
/^dns:[[:space:]]*$/ {
in_dns = 1
dns_indent = indent_len($0)
child_indent = -1
print
next
}
in_dns && /^[^[:space:]#][^:]*:/ {
if (!inserted) print_selected(spaces(child_indent > 0 ? child_indent : dns_indent + 2))
in_dns = 0
print
next
}
in_dns && /^[[:space:]]*[^#[:space:]][^:]*:/ && child_indent < 0 {
child_indent = indent_len($0)
}
in_dns && /^[[:space:]]*nameserver:/ {
ns_indent = indent_len($0)
rest = $0
sub(/^[[:space:]]*nameserver:[[:space:]]*/, "", rest)
sub(/[[:space:]]*(#.*)?$/, "", rest)
print_selected(spaces(ns_indent))
if (rest == "") skip_ns = 1
next
}
skip_ns {
cur_indent = indent_len($0)
if ($0 ~ /^[[:space:]]*$/ || cur_indent > ns_indent) next
skip_ns = 0
}
{ print }
END {
if (in_dns && !inserted)
print_selected(spaces(child_indent > 0 ? child_indent : dns_indent + 2))
}
' "$cfg" > "$tmp" && mv "$tmp" "$cfg"
rm -f "$selected" "$tmp" 2>/dev/null
}
@@ -0,0 +1,118 @@
#!/usr/bin/ucode
'use strict';
import { readfile } from 'fs';
// Mirror node-domain DNS policies from the subscription into
// proxy-server-nameserver-policy (issue #73).
//
// Airports publish their own resolver for node domains, e.g.
// nameserver-policy:
// "+.chylink.xyz": [tls://112.74.48.57:10853]
// which answers with domestic relay IPs. mihomo resolves *proxy server* domains
// through proxy-server-nameserver(-policy) and ignores nameserver-policy there,
// so that resolver is never used and node domains fall back to public DNS -
// which may return overseas CDN IPs that some lines cannot reach at all, leaving
// every node (AnyTLS is TCP-only) timing out.
//
// Input : CLASHOO_NODE_DNS_SOURCE_FILE = path to {"policies": {...}, "servers": [...]}
// (CLASHOO_NODE_DNS_SOURCE with the JSON itself is still accepted)
// Output: JSON map with only the policy entries matching a node server domain
// (nothing is printed when there is no match)
let source = '';
let source_file = getenv('CLASHOO_NODE_DNS_SOURCE_FILE') || '';
if (length(source_file)) {
try {
source = readfile(source_file) || '';
}
catch (e) {
exit(0);
}
}
else {
source = getenv('CLASHOO_NODE_DNS_SOURCE') || '';
}
if (!length(source))
exit(0);
let parsed;
try {
parsed = json(source);
}
catch (e) {
exit(0);
}
if (type(parsed) != 'object')
exit(0);
let policies = parsed.policies;
let servers = parsed.servers;
if (type(policies) != 'object' || type(servers) != 'array')
exit(0);
let domains = [];
let seen = {};
for (let server in servers) {
if (type(server) != 'string' || !length(server))
continue;
server = lc(server);
if (seen[server])
continue;
seen[server] = true;
push(domains, server);
}
if (!length(domains))
exit(0);
// suffix match on a label boundary: node.example.com matches +.example.com
function domain_matches(key, domain) {
let key_len = length(key);
let domain_len = length(domain);
if (!key_len || domain_len < key_len)
return false;
if (domain == key)
return true;
if (substr(domain, domain_len - key_len) != key)
return false;
return substr(domain, domain_len - key_len - 1, 1) == '.';
}
let result = {};
for (let key, value in policies) {
if (type(key) != 'string' || !length(key))
continue;
let lowered = lc(key);
let is_pattern = match(lowered, /^[+*]?\./) != null;
let domain = replace(lowered, /^\+\./, '');
domain = replace(domain, /^\*\./, '');
domain = replace(domain, /^\./, '');
let matched = false;
for (let candidate in domains) {
if (is_pattern ? domain_matches(domain, candidate) : (candidate == lowered)) {
matched = true;
break;
}
}
if (matched)
result[key] = value;
}
if (!length(keys(result)))
exit(0);
print(sprintf('%J', result));
@@ -6,7 +6,7 @@ TMP_PREFIX="/tmp/clashoo_iprules.$$"
CUSTOM_RULE_FILE="${TMP_PREFIX}.ipadd.conf"
RULE="${TMP_PREFIX}.rules_conf.yaml"
CLASH="${TMP_PREFIX}.conf.yaml"
CONFIG_YAML="/etc/clashoo/config.yaml"
CONFIG_YAML="${CLASHOO_CONFIG_YAML:-/etc/clashoo/config.yaml}"
CLASH_CONFIG="${TMP_PREFIX}.config.yaml"
trap 'rm -f "$CUSTOM_RULE_FILE" "$RULE" "$CLASH" "$CLASH_CONFIG"' EXIT
@@ -145,7 +145,7 @@ if (type(inherited_nameserver) != 'array') {
inherited_nameserver = [];
}
let dns_role_fields = ['nameserver', 'proxy-server-nameserver', 'direct-nameserver',
'default-nameserver', 'nameserver-policy', 'respect-rules'];
'default-nameserver', 'nameserver-policy', 'proxy-server-nameserver-policy', 'respect-rules'];
let had_user_dns_roles = false;
for (let f in dns_role_fields)
if (dns_present[f]) had_user_dns_roles = true;
@@ -200,18 +200,23 @@ if (length(bootstrap) && (!dns_present['default-nameserver'] || dns_force['defau
cfg['dns']['default-nameserver'] = bootstrap;
let policies = {};
let proxy_policies = {};
uci.foreach('clashoo', 'dns_policy', function(sec) {
if (b(sec.enabled) == false) return;
if (s(sec.policy_type, 'nameserver-policy') != 'nameserver-policy') return;
let role = s(sec.policy_type, 'nameserver-policy');
if (role != 'nameserver-policy' && role != 'proxy-server-nameserver-policy') return;
let matcher = trim(sec.matcher || '');
let servers = sec.nameserver;
if (type(servers) != 'array') servers = servers != null ? [servers] : [];
if (!length(matcher) || !length(servers)) return;
if (matcher == 'geosite:cn') { matcher = 'rule-set:cn_domain'; need_cn_rs = true; }
policies[matcher] = servers;
if (role == 'nameserver-policy') policies[matcher] = servers;
else proxy_policies[matcher] = servers;
});
if (length(keys(policies)) && (!dns_present['nameserver-policy'] || dns_force['nameserver-policy']))
cfg['dns']['nameserver-policy'] = policies;
if (length(keys(proxy_policies)) && (!dns_present['proxy-server-nameserver-policy'] || dns_force['proxy-server-nameserver-policy']))
cfg['dns']['proxy-server-nameserver-policy'] = proxy_policies;
let respect_rules = a('dns_respect_rules') == null ? true : ab('dns_respect_rules');
if (dns_force['respect-rules'])
@@ -296,20 +296,27 @@ load_github_urls() {
return 0
}
# `~` 是版本里的预发布分隔符,而 release 资产文件名会把它换成 `.`
# (clashoo_2026.10.25.6780eee-r3_x86_64.ipk 对应已安装的 2026.10.25~6780eee-r3)。
# 只比分隔符就会误判成「校验失败」,所以比较前统一归一化,解析时保持文件名原样。
version_equal() {
[ -n "$1" ] && [ "$(printf '%s' "$1" | tr '~' '.')" = "$(printf '%s' "$2" | tr '~' '.')" ]
}
package_version_from_url() {
file="${1##*/}"
case "$file" in
clashoo_*_"$ARCH".ipk)
v="${file#clashoo_}"
v="${v%_${ARCH}.ipk}"
printf '%s\n' "$v" | sed 's/^\([0-9][0-9][0-9][0-9]\.[0-9][0-9]*\.[0-9][0-9]*\)\./\1~/'
printf '%s\n' "${v%_${ARCH}.ipk}"
;;
clashoo_*.ipk) printf '%s\n' "$file" | sed -n 's/^clashoo_\(.*\)_[^_][^_]*\.ipk$/\1/p' | sed 's/^\([0-9][0-9][0-9][0-9]\.[0-9][0-9]*\.[0-9][0-9]*\)\./\1~/' ;;
# 架构名本身可能带下划线(aarch64_generic / arm_cortex-a7_neon-vfpv4),
# 只截到版本号为止,否则尾巴会混进版本串。
clashoo_*.ipk) printf '%s\n' "$file" | sed -n 's/^clashoo_\([^_]*\)_.*\.ipk$/\1/p' ;;
luci-app-clashoo_*.ipk) printf '%s\n' "$file" | sed -n 's/^luci-app-clashoo_\(.*\)_all\.ipk$/\1/p' ;;
luci-i18n-clashoo-zh-cn_*.ipk) printf '%s\n' "$file" | sed -n 's/^luci-i18n-clashoo-zh-cn_\(.*\)_all\.ipk$/\1/p' ;;
clashoo-*.apk)
v="$(printf '%s\n' "$file" | sed -n -e 's/^clashoo-\(.*-r[0-9][0-9]*\)-.*\.apk$/\1/p' -e 's/^clashoo-\(.*-r[0-9][0-9]*\)\.apk$/\1/p' | head -n 1)"
printf '%s\n' "$v" | sed 's/^\([0-9][0-9][0-9][0-9]\.[0-9][0-9]*\.[0-9][0-9]*\)\./\1~/'
printf '%s\n' "$file" | sed -n -e 's/^clashoo-\(.*-r[0-9][0-9]*\)-.*\.apk$/\1/p' -e 's/^clashoo-\(.*-r[0-9][0-9]*\)\.apk$/\1/p' | head -n 1
;;
luci-app-clashoo-*.apk) printf '%s\n' "$file" | sed -n -e 's/^luci-app-clashoo-\(.*-r[0-9][0-9]*\)-.*\.apk$/\1/p' -e 's/^luci-app-clashoo-\(.*-r[0-9][0-9]*\)\.apk$/\1/p' | head -n 1 ;;
luci-i18n-clashoo-zh-cn-*.apk) printf '%s\n' "$file" | sed -n -e 's/^luci-i18n-clashoo-zh-cn-\(.*-r[0-9][0-9]*\)-.*\.apk$/\1/p' -e 's/^luci-i18n-clashoo-zh-cn-\(.*-r[0-9][0-9]*\)\.apk$/\1/p' | head -n 1 ;;
@@ -405,14 +412,14 @@ run_pkg_update() {
core_ver_before="$(installed_package_version clashoo)"
apk_core_ready() {
package_installed clashoo && [ "$(installed_package_version clashoo)" = "$core_ver" ] \
package_installed clashoo && version_equal "$(installed_package_version clashoo)" "$core_ver" \
&& [ -x /etc/init.d/clashoo ] && [ -x /usr/share/clashoo/update/component_update.sh ]
}
apk_luci_ready() {
package_installed luci-app-clashoo && [ "$(installed_package_version luci-app-clashoo)" = "$luci_ver" ] \
package_installed luci-app-clashoo && version_equal "$(installed_package_version luci-app-clashoo)" "$luci_ver" \
&& { [ -z "$I18N_URL" ] || { package_installed luci-i18n-clashoo-zh-cn \
&& [ "$(installed_package_version luci-i18n-clashoo-zh-cn)" = "$i18n_ver" ]; }; } \
&& version_equal "$(installed_package_version luci-i18n-clashoo-zh-cn)" "$i18n_ver"; }; } \
&& [ -r /usr/share/luci/menu.d/luci-app-clashoo.json ] \
&& [ -r /usr/share/rpcd/ucode/luci.clashoo ]
}
@@ -434,7 +441,7 @@ run_pkg_update() {
cur_ver="$(installed_package_version clashoo)"
if [ "$PM" = "apk" ] && apk_update_ready; then
finish 0 "Clashoo 核心已是最新版本"
elif [ "$PM" != "apk" ] && [ -n "$core_ver" ] && [ "$cur_ver" = "$core_ver" ]; then
elif [ "$PM" != "apk" ] && version_equal "$cur_ver" "$core_ver"; then
finish 0 "Clashoo 核心已是最新版本"
fi
else
@@ -442,7 +449,7 @@ run_pkg_update() {
cur_ver="$(installed_package_version luci-app-clashoo)"
if [ "$PM" = "apk" ] && apk_update_ready; then
finish 0 "客户端已是最新版本"
elif [ "$PM" != "apk" ] && [ -n "$luci_ver" ] && [ "$cur_ver" = "$luci_ver" ]; then
elif [ "$PM" != "apk" ] && version_equal "$cur_ver" "$luci_ver"; then
finish 0 "客户端已是最新版本"
fi
fi
@@ -532,11 +539,11 @@ run_pkg_update() {
apk_update_ready || validation_failed
fi
elif [ "$which" = "clashoo" ]; then
package_installed clashoo && [ "$(installed_package_version clashoo)" = "$core_ver" ] \
package_installed clashoo && version_equal "$(installed_package_version clashoo)" "$core_ver" \
&& [ -x /etc/init.d/clashoo ] && [ -x /usr/share/clashoo/update/component_update.sh ] \
|| validation_failed
else
package_installed luci-app-clashoo && [ "$(installed_package_version luci-app-clashoo)" = "$luci_ver" ] \
package_installed luci-app-clashoo && version_equal "$(installed_package_version luci-app-clashoo)" "$luci_ver" \
&& [ -r /usr/share/luci/menu.d/luci-app-clashoo.json ] \
&& [ -r /usr/share/rpcd/ucode/luci.clashoo ] \
|| validation_failed
@@ -1062,10 +1062,10 @@ if [ -n "$CUSTOM_CORE_URL" ]; then
write_log "使用自定义内核下载链接"
URL="$CUSTOM_CORE_URL"
if [ "$CORETYPE" = "3" ]; then
TARGET="/usr/bin/mihomo"
TARGET="/usr/share/clashoo/bin/mihomo-alpha"
VERSION_FILE="/usr/share/clashoo/mihomo_version"
else
TARGET="/usr/bin/mihomo-stable"
TARGET="/usr/share/clashoo/bin/mihomo-stable"
VERSION_FILE="/usr/share/clashoo/clash_meta_version"
fi
TAG="custom"
@@ -1175,7 +1175,7 @@ elif [ "$CORETYPE" = "2" ]; then
[ -z "$TAG" ] && write_log "获取稳定版版本号失败" && exit 1
ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "stable")
URL="https://github.com/MetaCubeX/mihomo/releases/download/${TAG}/${ASSET}"
TARGET="/usr/bin/mihomo-stable"
TARGET="/usr/share/clashoo/bin/mihomo-stable"
VERSION_FILE="/usr/share/clashoo/clash_meta_version"
VERSION_VALUE="$TAG"
else
@@ -1189,7 +1189,7 @@ else
[ -z "$ASSET" ] && ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "alpha")
[ -z "$ASSET" ] && ASSET=$(pick_mihomo_asset "MetaCubeX/mihomo" "$TAG" "$(map_mihomo_arch "$MODELTYPE")" "stable")
URL="https://github.com/MetaCubeX/mihomo/releases/download/${TAG}/${ASSET}"
TARGET="/usr/bin/mihomo"
TARGET="/usr/share/clashoo/bin/mihomo-alpha"
VERSION_FILE="/usr/share/clashoo/mihomo_version"
VERSION_VALUE="$(printf '%s\n' "$ASSET" | sed -n 's#^mihomo-.*-alpha-\([0-9a-fA-F]\{7,\}\)\.gz$#\1#p' | head -n 1)"
[ -z "$VERSION_VALUE" ] && VERSION_VALUE="$TAG"
@@ -12,6 +12,8 @@ cfg_mmdb_url="$(uci -q get clashoo.config.geoip_mmdb_url 2>/dev/null)"
cfg_geosite_url="$(uci -q get clashoo.config.geosite_url 2>/dev/null)"
cfg_geoip_dat_url="$(uci -q get clashoo.config.geoip_dat_url 2>/dev/null)"
cfg_geoip_asn_url="$(uci -q get clashoo.config.geoip_asn_url 2>/dev/null)"
require_geosite=0
[ "$1" = "--require-geosite" ] && require_geosite=1
DEFAULT_MMDB_URL="https://raw.githubusercontent.com/Loyalsoldier/geoip/release/Country.mmdb"
DEFAULT_GEOSITE_URL="https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat"
@@ -36,6 +38,10 @@ cleanup() {
}
config_needs_geosite() {
_cfg="$(uci -q get clashoo.config.use_config 2>/dev/null)"
if [ -s "$_cfg" ] && grep -Eq "^[[:space:]]*-[[:space:]]*[\"']?GEOSITE,|^[[:space:]]*geosite:[[:space:]]*|^[[:space:]]*'geosite:|^[[:space:]]*-[[:space:]]*[\"']?geosite:" "$_cfg"; then
return 0
fi
_cfg="/etc/clashoo/config.yaml"
[ -f "$_cfg" ] || return 1
grep -Eq "^[[:space:]]*-[[:space:]]*[\"']?GEOSITE,|^[[:space:]]*geosite:[[:space:]]*|^[[:space:]]*'geosite:|^[[:space:]]*-[[:space:]]*[\"']?geosite:" "$_cfg"
@@ -133,19 +139,19 @@ download_geosite() {
size=0
if [ -z "$url" ]; then
log "GeoSite.dat skip (url empty)"
return 0
return 1
fi
rm -f "$tmp_target" >/dev/null 2>&1
if ! download_to "$url" "$tmp_target"; then
rm -f "$tmp_target" >/dev/null 2>&1
log "GeoSite.dat update failed"
return 0
return 1
fi
size=$(wc -c <"$tmp_target" 2>/dev/null)
if [ -z "$size" ] || [ "$size" -lt "$GEOSITE_MIN_SIZE" ]; then
log "GeoSite.dat download invalid or incomplete (${size:-0} bytes)"
rm -f "$tmp_target" >/dev/null 2>&1
return 0
return 1
fi
mv -f "$tmp_target" /etc/clashoo/GeoSite.dat >/dev/null 2>&1 || return 1
cp -f /etc/clashoo/GeoSite.dat /etc/clashoo/geosite.dat >/dev/null 2>&1 || true
@@ -248,8 +254,10 @@ if [ "$geoip_source" != "1" ]; then
fi
log "Country.mmdb updated"
if config_needs_geosite; then
download_geosite "$geosite_url"
if [ "$require_geosite" -eq 1 ] || config_needs_geosite; then
if ! download_geosite "$geosite_url"; then
exit 1
fi
else
log "GeoSite.dat skip (no geosite reference in config)"
fi
@@ -257,6 +265,13 @@ if [ "$geoip_source" != "1" ]; then
download_optional "$geoip_asn_url" /etc/clashoo/GeoLite2-ASN.mmdb "GeoLite2-ASN.mmdb"
fi
if [ "$geoip_source" = "1" ] && { [ "$require_geosite" -eq 1 ] || config_needs_geosite; }; then
geosite_url="${cfg_geosite_url:-$DEFAULT_GEOSITE_URL}"
if ! download_geosite "$geosite_url"; then
exit 1
fi
fi
touch /var/run/geoip_down_complete >/dev/null 2>&1
if pidof mihomo >/dev/null 2>&1 || pidof clash-meta >/dev/null 2>&1; then
@@ -32,5 +32,6 @@ fi
if [ "$(uci -q get clashoo.config.auto_clear_log)" = "1" ] && due log_cleanup.status clear_time; then
: >"$LOG_FILE"
sh /usr/share/clashoo/lib/core_log_guard.sh >/dev/null 2>&1
stamp log_cleanup.status
fi
+4 -4
View File
@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dae
PKG_VERSION:=2026.09.24
PKG_RELEASE:=2
PKG_VERSION:=2026.10.30
PKG_RELEASE:=1
PKG_SOURCE:=dae-src-2026.09.24-17135da7c881.tar.gz
PKG_SOURCE:=dae-src-2026.10.30-55c59e68c059.tar.gz
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/dae-src
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=17135da7c881800738cc63566160d4ee6d59a8a70ae5043b8005c5d189b05752
PKG_HASH:=55c59e68c059fff41694c75097004af639d7f58462e35a84d75d3f5f03d4cf12
PKG_LICENSE:=AGPL-3.0-only
PKG_LICENSE_FILE:=LICENSE
+4 -4
View File
@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=daed
PKG_VERSION:=2026.09.24
PKG_RELEASE:=2
PKG_VERSION:=2026.10.30
PKG_RELEASE:=1
PKG_SOURCE:=daed-src-2026.09.24-527bb166b1ae.tar.gz
PKG_SOURCE:=daed-src-2026.10.30-1850c01d032c.tar.gz
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=527bb166b1aea6a54330ebbc8be5b0418baed74636b838aeaa78c17b70f2f996
PKG_HASH:=1850c01d032cebc3d29bd104c7c654ab422ed1199c5207cd952a0d9340e9289b
PKG_LICENSE:=AGPL-3.0-only MIT
PKG_LICENSE_FILES:=LICENSE wing/LICENSE
+2 -2
View File
@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dns2socks-rust
PKG_VERSION:=0.2.6
PKG_VERSION:=0.2.7
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tun2proxy/dns2socks/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=c90e9cf8da4d2b01618110ea8416ff6c53e17efd8319ee5ec12132fd14b35ec0
PKG_HASH:=34ecdeb98281d0873146a08f351e485e7fb9cfacb55ac748ccfe463987f6befd
PKG_BUILD_DIR:=$(BUILD_DIR)/dns2socks-$(PKG_VERSION)
PKG_MAINTAINER:=Zxlhhyccc <zxlhhyccc@gmail.com>
+2 -2
View File
@@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=docker
PKG_VERSION:=29.9.0
PKG_VERSION:=29.9.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/docker/cli/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=853af65a119a538d7402515ad8d8f907effc5abe805b0dd6631ad4b2ecf26d5b
PKG_HASH:=23d7472c80bc7483e57655085d687c631b398837bbc92535528c4582fc17e95b
PKG_BUILD_DIR:=$(BUILD_DIR)/cli-$(PKG_VERSION)
PKG_GIT_SHORT_COMMIT:=$(shell $(CURDIR)/git-short-commit.sh 'github.com/docker/cli' 'v$(PKG_VERSION)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)')
+2 -2
View File
@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dockerd
PKG_VERSION:=29.9.0
PKG_VERSION:=29.9.3
PKG_RELEASE:=1
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
@@ -10,7 +10,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_GIT_URL:=github.com/moby/moby
PKG_GIT_REF:=docker-v$(PKG_VERSION)
PKG_SOURCE_URL:=https://codeload.$(PKG_GIT_URL)/tar.gz/$(PKG_GIT_REF)?
PKG_HASH:=ee76bfc375c4e498e2405a26b2b0792eb3dd999a96b9f521af16989c3b95e9ac
PKG_HASH:=cd6ce54e46ac19f5dd0b5226a9b292965ba542bc16bdf9edbbca946da8930b15
PKG_GIT_SHORT_COMMIT:=$(shell $(CURDIR)/git-short-commit.sh '$(PKG_GIT_URL)' '$(PKG_GIT_REF)' '$(TMP_DIR)/git-short-commit/$(PKG_NAME)-$(PKG_VERSION)')
PKG_MAINTAINER:=Gerard Ryan <G.M0N3Y.2503@gmail.com>
Regular → Executable
+19 -1
View File
@@ -1,3 +1,21 @@
#!/bin/sh
$1 -v 2>&1 | grep -F "$PKG_VERSION"
# frpc/frps both accept "verify -c <file>" to validate a config without
# connecting, which exercises the TOML config loader end-to-end.
case "$1" in
frpc)
conf="/tmp/frpc.$$.toml"
printf 'serverAddr = "127.0.0.1"\nserverPort = 7000\n' > "$conf"
frpc verify -c "$conf" || { echo "FAIL: frpc rejected a valid config"; rm -f "$conf"; exit 1; }
rm -f "$conf"
;;
frps)
conf="/tmp/frps.$$.toml"
printf 'bindPort = 7000\n' > "$conf"
frps verify -c "$conf" || { echo "FAIL: frps rejected a valid config"; rm -f "$conf"; exit 1; }
rm -f "$conf"
;;
*)
exit 0
;;
esac
+2 -2
View File
@@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=geoview
PKG_VERSION:=0.2.6
PKG_VERSION:=0.2.9
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/snowie2000/geoview/tar.gz/$(PKG_VERSION)?
PKG_HASH:=1b46d4255ab22ec433a14f804e9487885cc2693323579c1385d51919838db132
PKG_HASH:=b080a141505a3180c3b81468304864e4373c4868680ff39fb82ee6973e3b5e94
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
+3 -3
View File
@@ -9,9 +9,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git
PKG_SOURCE_DATE:=2026-10-02
PKG_SOURCE_VERSION:=3fef1f00031be0d3505e5338ca671ea3752e6fd8
PKG_MIRROR_HASH:=d5bfd72bd48ec013df53d5457556261c02a18a3dd83e5786dcc3f3a367750feb
PKG_SOURCE_DATE:=2026-10-29
PKG_SOURCE_VERSION:=ed7fee04cb30b96ed40ef188acfad5417349e399
PKG_MIRROR_HASH:=8ac4c439bb3f11e9fc945a509a76dba265e13de6b4f8b965496881696079be9c
PKG_LICENSE:=BSD 3-Clause
PKG_LICENSE_FILES:=LICENSE
+2 -2
View File
@@ -3,7 +3,7 @@
#ifndef OUT_LAST_COMMIT_POSITION_H_
#define OUT_LAST_COMMIT_POSITION_H_
#define LAST_COMMIT_POSITION_NUM 2590
#define LAST_COMMIT_POSITION "2590 (3fef1f00031b)"
#define LAST_COMMIT_POSITION_NUM 2615
#define LAST_COMMIT_POSITION "2615 (ed7fee04cb30)"
#endif // OUT_LAST_COMMIT_POSITION_H_
+2 -2
View File
@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gost
PKG_VERSION:=3.3.0
PKG_VERSION:=3.3.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/go-gost/gost/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=2a65e2da14fef6b6da8d4e32a8bc62e39970dbb141db42bc6f5821f90ac1e9a3
PKG_HASH:=2c79c7675894cfd5849d646f037dc82e4278cd43439e3e0b0160fdf112269564
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
+75 -52
View File
@@ -1,77 +1,79 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2026 kenzok8
include $(TOPDIR)/rules.mk
PKG_NAME:=honk
PKG_VERSION:=2026.10.9_pre3
PKG_VERSION:=2026.11.04
PKG_RELEASE:=1
# Raw upstream release tag. It keeps the dots in qualifiers (e.g. v0.0.1.beta.49)
# because that is what the GitHub release asset name uses.
HONK_RELEASE_TAG:=debug.2026.10.9.native-api.3
HONK_ASSET_TAG:=debug
# Pinned honk-core revision (upstream daeuniverse/honk main), cross-compiled by
# ci/build-core.sh. Every release run publishes its core archives under an
# immutable source-<run_id> tag; the tag and SHA-256 values below are the exact
# assets behind CORE_COMMIT, so a plain feed build downloads and verifies them
# without any generated file. A staged run may still override them through
# honk/generated-stage.mk, which is generated and never committed.
CORE_COMMIT:=88d470c662e0ee7a3de3e67afc6129f67e66c1bf
# SHA256 of each release tarball, kept in sync by scripts/update_honk_version.sh.
HONK_HASH_X86_64:=179dac725195f04899ae871b9fbcf47deec4b99f6b30c539296d31fdcd9a8c2e
HONK_HASH_AARCH64:=6bcf738b8c618d9c87a412fa3dbb976e041349f6614ebd1ea2c7044ede3a4d48
# Immutable source asset tag holding this pin's core archives.
HONK_SOURCE_TAG?=source-41792584995
HONK_SOURCE_URL?=https://github.com/kenzok8/openwrt-honk/releases/download/$(HONK_SOURCE_TAG)
PKG_LICENSE:=AGPL-3.0-only
PKG_LICENSE_FILE:=LICENSE
PKG_MAINTAINER:=luci-app-honk maintainers
-include $(CURDIR)/generated-stage.mk
ifeq ($(ARCH),x86_64)
HONK_TARGET:=x86_64-unknown-linux-musl
HONK_ASSET_X86_64?=honk-core-$(CORE_COMMIT)-x86_64.tar.gz
HONK_ASSET_AARCH64?=honk-core-$(CORE_COMMIT)-aarch64.tar.gz
HONK_ASSET_ARMV7?=honk-core-$(CORE_COMMIT)-armv7.tar.gz
HONK_HASH_X86_64?=5a389e97296f6b5d3aad5a7180a57f9669845f6baa9b52742295de23147ac07e
HONK_HASH_AARCH64?=7261ed6b98b13fa3f7246175b5d9222feecdb3cdf3946b7c0bc296641866b345
HONK_HASH_ARMV7?=1333e0598a493183af58e516173c66b44e692223949247cd32e53934dcebfeb4
# ARCH_PACKAGES is the package arch (e.g. arm_cortex-a7_neon-vfpv4);
# ARCH is the CPU arch (x86_64/aarch64/arm) and coincides for 64-bit.
ifeq ($(ARCH_PACKAGES),x86_64)
HONK_ASSET:=$(HONK_ASSET_X86_64)
HONK_HASH:=$(HONK_HASH_X86_64)
else ifeq ($(ARCH),aarch64)
HONK_TARGET:=aarch64-unknown-linux-musl
else ifeq ($(filter aarch64%,$(ARCH_PACKAGES)),$(ARCH_PACKAGES))
HONK_ASSET:=$(HONK_ASSET_AARCH64)
HONK_HASH:=$(HONK_HASH_AARCH64)
else ifeq ($(filter arm_%,$(ARCH_PACKAGES)),$(ARCH_PACKAGES))
HONK_ASSET:=$(HONK_ASSET_ARMV7)
HONK_HASH:=$(HONK_HASH_ARMV7)
endif
# Default to the stock-malloc build: lower RSS high-water on small gateways.
# Use an empty suffix to switch back to the mimalloc build (faster QUIC).
HONK_SUFFIX:=-stock
HONK_ASSET:=honk-core-$(HONK_ASSET_TAG)-$(HONK_TARGET)$(HONK_SUFFIX).tar.gz
PKG_LICENSE:=AGPL-3.0-only
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=kenzok8
PKG_SOURCE:=$(HONK_ASSET)
PKG_SOURCE_URL:=https://github.com/Glassyiris/honk/releases/download/$(HONK_RELEASE_TAG)/
PKG_SOURCE_URL?=$(HONK_SOURCE_URL)/
PKG_HASH:=$(HONK_HASH)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/honk
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=honk - eBPF transparent proxy engine (dae-compatible)
URL:=https://github.com/Glassyiris/honk
DEPENDS:=@(x86_64||aarch64) \
+ca-bundle +ip-full \
+kmod-sched-core +kmod-sched-bpf +kmod-veth +kmod-nft-queue \
+v2ray-geoip +v2ray-geosite \
+@KERNEL_XDP_SOCKETS \
+HONK_USE_VMLINUX_BTF:vmlinux-btf
TITLE:=Honk transparent proxy core
URL:=https://github.com/daeuniverse/honk
# 不直接依赖 libubox:包名带 ABI 日期戳,会锁死固件;脚本只用 jshn 提供的 jshn.sh。
DEPENDS:=@(x86_64||aarch64||arm) +ca-bundle +ip-full +ubus +kmod-sched-core +kmod-sched-bpf +kmod-veth +kmod-nft-queue +jsonfilter +jshn +sqlite3-cli +usign +coreutils-stat +v2ray-geoip +v2ray-geosite +@KERNEL_DEBUG_INFO_BTF
endef
define Package/honk/config
choice
prompt "BTF source for CO-RE"
default HONK_USE_KERNEL_BTF
depends on PACKAGE_honk
config HONK_USE_KERNEL_BTF
bool "Use kernel BTF (integrated)"
depends on KERNEL_DEBUG_INFO_BTF
config HONK_USE_VMLINUX_BTF
bool "Use vmlinux-btf package"
endchoice
define Package/honk/description
Honk is a transparent proxy core for OpenWrt (x86_64, aarch64, armv7).
endef
define Package/honk/conffiles
/etc/honk/config.dae
/etc/honk/config.d/
/etc/honk/state/
/etc/config/honk
/etc/honk/config.dae
/etc/honk/system.dae
/etc/honk/manual-config.dae
/etc/honk/managed-config.dae
endef
define Build/Prepare
@@ -80,25 +82,46 @@ define Build/Prepare
endef
define Build/Compile
true
endef
define Package/honk/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/honk-core $(1)/usr/bin/honk-core
$(INSTALL_DIR) $(1)/etc/honk/config.d
$(INSTALL_CONF) $(CURDIR)/files/config.dae $(1)/etc/honk/config.dae
$(INSTALL_CONF) $(CURDIR)/files/config.d/node.dae $(1)/etc/honk/config.d/node.dae
$(INSTALL_CONF) $(CURDIR)/files/config.d/route.dae $(1)/etc/honk/config.d/route.dae
$(INSTALL_CONF) $(CURDIR)/files/config.d/dns.dae $(1)/etc/honk/config.d/dns.dae
$(INSTALL_CONF) $(CURDIR)/files/config.d/api.dae $(1)/etc/honk/config.d/api.dae
$(INSTALL_DIR) $(1)/usr/share/licenses/honk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE $(1)/usr/share/licenses/honk/LICENSE
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) $(CURDIR)/files/honk.config $(1)/etc/config/honk
$(INSTALL_DIR) $(1)/etc/honk
$(INSTALL_CONF) $(CURDIR)/files/config.dae $(1)/etc/honk/config.dae
$(INSTALL_CONF) $(CURDIR)/files/system.dae $(1)/etc/honk/system.dae
chmod 0600 $(1)/etc/honk/system.dae
$(INSTALL_DIR) $(1)/etc/honk/state
chmod 0700 $(1)/etc/honk/state
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(CURDIR)/files/honk.init $(1)/etc/init.d/honk
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) $(CURDIR)/files/90-honk-boot $(1)/etc/uci-defaults/90-honk
$(INSTALL_DIR) $(1)/usr/share/honk
$(INSTALL_DATA) $(CURDIR)/files/config.dae $(1)/usr/share/honk/default-config.dae
# Provenance is only generated by a source build; a plain feed build has
# no such file and must still install cleanly.
if [ -f $(CURDIR)/generated-provenance.json ]; then \
$(INSTALL_DATA) $(CURDIR)/generated-provenance.json $(1)/usr/share/honk/provenance.json; \
fi
$(INSTALL_BIN) $(CURDIR)/files/control.sh $(1)/usr/share/honk/control.sh
$(INSTALL_BIN) $(CURDIR)/files/lock.sh $(1)/usr/share/honk/lock.sh
$(INSTALL_BIN) $(CURDIR)/files/lifecycle.sh $(1)/usr/share/honk/lifecycle.sh
$(INSTALL_BIN) $(CURDIR)/files/maintenance.sh $(1)/usr/share/honk/maintenance.sh
$(INSTALL_BIN) $(CURDIR)/files/job.sh $(1)/usr/share/honk/job.sh
$(INSTALL_BIN) $(CURDIR)/files/update.sh $(1)/usr/share/honk/update.sh
$(INSTALL_BIN) $(CURDIR)/files/redact-log.sh $(1)/usr/share/honk/redact-log.sh
$(INSTALL_BIN) $(CURDIR)/files/log-level-filter.sh $(1)/usr/share/honk/log-level-filter.sh
$(INSTALL_DATA) $(CURDIR)/files/log-lines.sh $(1)/usr/share/honk/log-lines.sh
endef
$(eval $(call BuildPackage,honk))
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
# 开机自启是内置行为:装上就 enable,是否真正启动由 honk.main.enabled 决定,
# 不再提供单独的 boot_enabled 开关。
/etc/init.d/honk enable
# 配置模式已取消:只清遗留键,活动配置与启停状态一概不动。
legacy_mode=$(uci -q get honk.main.config_mode 2>/dev/null)
if [ -n "$legacy_mode" ]; then
uci -q delete honk.main.config_mode && uci -q commit honk
fi
exit 0
View File
Whitespace-only changes.
-23
View File
@@ -1,23 +0,0 @@
# dns.dae
dns {
bind: 'tcp+udp://[::]:53530'
client_subnet: auto
#ipversion_prefer: 4
upstream {
local: 'udp://127.0.0.1:53' -> direct
remote: 'tcp+udp://one.one.one.one:53'
}
routing {
request {
qtype(https) -> reject
qname(geosite: gfw) -> remote
fallback: local
}
response {
upstream(remote) -> accept
qname(geosite: private) -> accept
ip(geoip: cn) -> accept
fallback: remote
}
}
}
-35
View File
@@ -1,35 +0,0 @@
# node.dae
node {
node1: 'xxx'
node2: 'xxx'
}
subscription {
# 短形式:默认 86400s 刷新一次
sub: 'http://sub'
# 短形式 + UA:仍然只能默认 86400s
sub_ua: 'http://sub'(honk/1.0 like)
# 块形式:可以自定义定时刷新周期
sub2: {
url: 'http://sub'
ua: 'honk/1.0'
interval: '10000s' # 每 10000 秒刷新一次
}
# 禁用定期刷新
sub3: {
url: 'http://sub'
interval: 0
}
}
group {
proxy {
filter: subtag(sub) && !name(keyword: 'ExpireAt:')
filter: name(node1, node2)
policy: score
}
}
-27
View File
@@ -1,27 +0,0 @@
# route.dae
routing {
pname(dnsmasq, zerotier-one) -> direct(must)
dip(224.0.0.0/3, 'ff00::/8', geoip: private) -> direct
domain(geosite: category-bank-cn, geosite: boc@!cn, geosite: synology) -> direct
# block quic, if u node has poor quic support, enable this line
# l4proto(udp) && dport(443) -> block
domain(geosite: spotify) -> proxy
domain(geosite: category-doh) -> proxy
domain(geosite: tiktok) -> proxy
domain(geosite: category-ai-!cn, geosite: github) -> proxy
domain(geosite: gfw) -> proxy
dip(geoip: telegram) -> proxy
dip(geoip: cn) -> direct
# geoip:cn always using chiness asn, can use domain rule to override
# domain(geosite: cn) -> direct
# using proxy for ssh, http, https, and common ports, avoid (bt, or other p2p)
# dport(22, 80, 443, 8080, 6443, 9090) -> proxy
# fallback: direct
fallback: proxy
}
+29 -26
View File
@@ -1,31 +1,34 @@
# config.dae
# Load all honk files placed in ./config.d/.
include {
config.d/*.dae
system.dae
}
global {
log_level: warn
check_interval: 600s
check_tolerance: 30ms
lan_interface: br-lan
wan_interface: auto
auto_config_kernel_parameter: true
disable_waiting_network: false
data_dir: '/etc/honk'
log_file: '/var/log/honk/honk.log'
store_subscribe: true
# if u not using dns bind, set dial_mode to domain++ prefer
dial_mode: domain
bootstrap_resolver: '223.5.5.5:53'
tcp_check_url: 'https://www.gstatic.com/generate_204'
tcp_check_http_method: HEAD
udp_check_dns: 'dns.google.com:53', '8.8.8.8', '2001:4860:4860::8888'
}
assets {
geodata {
geosite: 'https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/release/geosite.dat'
geoip: 'https://raw.githubusercontent.com/QiuSimons/geoip-moedove/refs/heads/main/geoip.dat'
group {
proxy {
policy: min_moving_avg
}
}
dns {
upstream {
default: 'https://223.5.5.5/dns-query?tls_server_name=dns.alidns.com' -> direct
remote: 'https://8.8.8.8/dns-query?tls_server_name=dns.google' -> proxy
}
routing {
request {
qname(geosite: private) -> asis
qname(geosite: cn) -> default
fallback: remote
}
}
}
routing {
dip(224.0.0.0/3, 'ff00::/8') -> direct
# 路由器自身地址直连,管理面板不被代理;服务启动时按本机地址重写下面区块
# honk:local-direct-begin
# honk:local-direct-end
dip(geoip: private) && !dport(53) -> direct(must)
dip(geoip: cn) && !dport(53) -> direct(must)
domain(geosite: cn) -> direct
fallback: direct
}
+1211
View File
File diff suppressed because it is too large. Load diff
+12 -5
View File
@@ -1,7 +1,14 @@
config honk 'config'
config honk 'main'
option enabled '0'
option advanced '0'
option dashboard 'none'
option boot_enabled '0'
option initialized '0'
option config_file '/etc/honk/config.dae'
option listen_port '9527'
option clash_api_enabled '0'
option clash_api_port '9090'
option clash_api_secret ''
option lan_network 'lan'
option geoip_url ''
option geosite_url ''
option geo_auto '0'
option geo_auto_freq 'daily'
Regular → Executable
+66 -107
View File
@@ -1,122 +1,81 @@
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=96
START=95
STOP=10
extra_command "hot_reload" "Hot-reload service"
. /lib/functions.sh
CONF="honk"
PROG="/usr/bin/honk-core"
# honk-core hardcodes dae-compatible datapath names (dae0/dae0peer + daens);
# these are the real interface/netns names, not leftover dae config.
HONK_HOST_IFACE="dae0"
HONK_PEER_IFACE="dae0peer"
HONK_NETNS_NAME="daens"
HONK_NETNS_PATH="/run/netns/$HONK_NETNS_NAME"
RESOLV_HONK="/tmp/resolv.conf.honk"
HONK_CONTROL=/usr/share/honk/control.sh
HONK_CONFIG=/etc/honk/config.dae
set_chmod_640() {
mkdir -p /etc/honk/config.d /etc/honk/state /var/log/honk
chmod -R u=rwX,go= /etc/honk 2>/dev/null || true
chmod 700 /etc/honk /etc/honk/config.d /etc/honk/state 2>/dev/null || true
}
cleanup_netns() {
ip netns del "$HONK_NETNS_NAME" 2>/dev/null || true
umount "$HONK_NETNS_PATH" 2>/dev/null || true
rm -f "$HONK_NETNS_PATH" 2>/dev/null || true
ip link del "$HONK_HOST_IFACE" 2>/dev/null || true
ip link del "$HONK_PEER_IFACE" 2>/dev/null || true
}
hijack_resolv_conf() {
grep -q ' /tmp/resolv\.conf ' /proc/mounts && return 0
local dns_list WANS
. /lib/functions/network.sh
unset -v __NETWORK_CACHE
__network_ifstatus WANS "" "[@.route[@.target='0.0.0.0' && !@.table]].interface" 2>/dev/null
set -- $WANS
if [ $# -eq 1 ]; then
dns_list=$(ubus call "network.interface.$1" status 2>/dev/null | \
jsonfilter -e '@["dns-server"][*]' 2>/dev/null)
if [ -z "$dns_list" ] && [ -f "/tmp/resolv.conf.d/resolv.conf.auto" ]; then
dns_list=$(awk '/^nameserver/{print $2}' "/tmp/resolv.conf.d/resolv.conf.auto")
fi
fi
[ -z "$dns_list" ] && dns_list="119.29.29.29 223.5.5.5"
[ -f /tmp/resolv.conf ] || touch /tmp/resolv.conf
grep -E '^(search|domain) ' /tmp/resolv.conf > "$RESOLV_HONK" 2>/dev/null
for dns in $dns_list; do
echo "nameserver $dns" >> "$RESOLV_HONK"
done
mount --bind "$RESOLV_HONK" /tmp/resolv.conf
mount -o remount,ro,bind /tmp/resolv.conf
}
restore_resolv_conf() {
while grep -q ' /tmp/resolv\.conf ' /proc/mounts; do
mount -o remount,rw,bind /tmp/resolv.conf 2>/dev/null
umount /tmp/resolv.conf 2>/dev/null || break
done
rm -f "$RESOLV_HONK"
boot() {
# 开机自启内置:只要服务是"已启用 + 已初始化"就起来,
# 用户主动停掉(enabled=0)后重启也不会被强行拉起。
start
}
start_service() {
local enabled config_file
local enabled initialized config_file ready_token ready_hash ready_runtime ready_api_enabled ready_api_listen ready_clash_api_listen ready_clash_api_secret_set old_ready_token
config_load honk
config_get_bool enabled main enabled 0
config_get_bool initialized main initialized 0
[ "$enabled" -eq 1 ] && [ "$initialized" -eq 1 ] || {
logger -t honk "refusing to start before explicit initialization and enablement"
return 1
}
config_get config_file main config_file "$HONK_CONFIG"
[ "$config_file" = "$HONK_CONFIG" ] || {
logger -t honk "refusing non-default config path"
return 1
}
"$HONK_CONTROL" preflight || return 1
"$HONK_CONTROL" local-direct || logger -t honk "local-direct sync skipped"
unset HONK_MAINT_CAP
config_load "$CONF"
config_get_bool enabled "config" "enabled" "0"
[ "$enabled" -eq "1" ] || return 1
config_get config_file "config" "config_file" "/etc/honk/config.dae"
if [ ! -x "$PROG" ]; then
logger -t honk "not starting: $PROG is missing or not executable"
return 1
fi
set_chmod_640
cleanup_netns
hijack_resolv_conf
procd_open_instance "$CONF"
procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray"
procd_set_param command "$PROG" --config "$config_file"
procd_set_param netdev "$HONK_HOST_IFACE" "$HONK_PEER_IFACE"
procd_set_param limits core="unlimited"
procd_set_param limits nofile="1000000 1000000"
procd_set_param term_timeout 8
procd_set_param respawn 3600 5 5
procd_set_param stderr 1
procd_close_instance
}
service_stopped() {
restore_resolv_conf
cleanup_netns
# 所有配置都走 readiness 标记:状态页据此判断真正就绪,而不是只看进程在不在。
ready_token=$(cat /proc/sys/kernel/random/uuid 2>/dev/null) || return 1
case "$ready_token" in *[!0-9a-f-]*|'') return 1 ;; esac
ready_hash=$(sha256sum "$HONK_CONFIG" 2>/dev/null | awk '{print $1}') || return 1
case "$ready_hash" in *[!0-9a-f]*|'') return 1 ;; esac
ready_runtime=$(/usr/bin/honk-core config validate --config "$HONK_CONFIG" 2>/dev/null) || return 1
ready_api_enabled=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.native_api_enabled' 2>/dev/null)
ready_api_listen=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.native_api_listen' 2>/dev/null)
ready_clash_api_listen=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.clash_api_listen' 2>/dev/null)
ready_clash_api_secret_set=$(printf '%s' "$ready_runtime" | jsonfilter -e '@.runtime.clash_api_secret_set' 2>/dev/null)
case "$ready_api_enabled" in true|false) ;; *) return 1 ;; esac
case "$ready_api_listen" in *[!A-Za-z0-9:._-]*) return 1 ;; esac
case "$ready_clash_api_listen" in *[!A-Za-z0-9:._-]*) return 1 ;; esac
case "$ready_clash_api_secret_set" in true|false) ;; *) return 1 ;; esac
mkdir -p /var/run/honk || return 1
chmod 0700 /var/run/honk || return 1
if [ -f /var/run/honk/readiness ] && [ ! -L /var/run/honk/readiness ]; then
read -r old_ready_token _ < /var/run/honk/readiness
case "$old_ready_token" in ''|*[!0-9a-f-]*) ;; *) rm -f "/var/run/honk/core-ready-$old_ready_token" ;; esac
fi
printf '%s %s\n' "$ready_token" "$ready_hash" > /var/run/honk/readiness || return 1
chmod 0600 /var/run/honk/readiness || return 1
procd_open_instance main
procd_set_param command /usr/bin/honk-core --config "$HONK_CONFIG" --disable-timestamp
# One env call, no empty values: procd drops the whole list when a KEY has an
# empty value, which silently stripped the readiness hash the core requires.
ready_env="DAE_LOCATION_ASSET=/usr/share/v2ray"
ready_env="$ready_env HONK_READY_TOKEN=$ready_token HONK_READY_CONFIG_HASH=$ready_hash HONK_READY_API_ENABLED=$ready_api_enabled HONK_READY_CLASH_API_SECRET_SET=$ready_clash_api_secret_set"
[ -n "$ready_api_listen" ] && ready_env="$ready_env HONK_READY_API_LISTEN=$ready_api_listen"
[ -n "$ready_clash_api_listen" ] && ready_env="$ready_env HONK_READY_CLASH_API_LISTEN=$ready_clash_api_listen"
# shellcheck disable=SC2086
procd_set_param env $ready_env
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn 3600 5 5
procd_set_param term_timeout 20
procd_close_instance
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger "$CONF"
}
hot_reload() {
set_chmod_640
if /etc/init.d/honk running; then
"$PROG" reload
else
start
fi
# honk-core has no hot-reload API wired here; a reload is an explicit
# restart so existing connections are cycled. The UI only exposes
# restart, this exists so manual `/etc/init.d/honk reload` is defined.
logger -t honk "reload requested, restarting (no hot-reload)"
restart
}
+127
View File
@@ -0,0 +1,127 @@
#!/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH
umask 077
. /usr/share/libubox/jshn.sh
JOBS=/tmp/honk-jobs
MAINT=/usr/share/honk/maintenance.sh
write_status() {
status_state=$1
status_phase=$2
status_ok=$3
status_message=$4
# jshn 的布尔只认 1/0,传 "true" 会被写进状态文件成 false。
case "$status_ok" in true|1) status_ok=1 ;; *) status_ok=0 ;; esac
status_tmp=$job_dir/status.new
{
json_init
json_add_string state "$status_state"
json_add_string phase "$status_phase"
json_add_boolean ok "$status_ok"
json_add_string message "$status_message"
json_dump
} > "$status_tmp" || return 1
chmod 0600 "$status_tmp" || return 1
mv -f "$status_tmp" "$job_dir/status" || return 1
}
job_id=$1
operation=$2
case "$job_id" in
*[!0-9a-f]*|'') exit 2 ;;
esac
[ "${#job_id}" -eq 32 ] || exit 2
case "$operation" in backup|restore|reset|update_check|update_apply) ;; *) exit 2 ;; esac
job_dir=$JOBS/$job_id
[ -d "$JOBS" ] && [ ! -L "$JOBS" ] && [ -d "$job_dir" ] && [ ! -L "$job_dir" ] || exit 2
[ "$(stat -c '%u:%a' "$JOBS" 2>/dev/null)" = 0:700 ] && [ "$(stat -c '%u:%a' "$job_dir" 2>/dev/null)" = 0:700 ] || exit 2
[ "$(id -u)" = 0 ] || exit 2
write_status running preparing true preparing || exit 1
: > "$job_dir/output" || exit 1
chmod 0600 "$job_dir/output" || exit 1
# stderr 单独存:混进 output 会让结果 JSON 解析失败,报成“操作失败”。
: > "$job_dir/stderr" || exit 1
chmod 0600 "$job_dir/stderr" || exit 1
if [ "$operation" = update_apply ]; then
/usr/share/honk/update.sh apply > "$job_dir/output" 2> "$job_dir/stderr" &
elif [ "$operation" = update_check ]; then
/usr/share/honk/update.sh check > "$job_dir/output" 2> "$job_dir/stderr" &
else
"$MAINT" "$operation" > "$job_dir/output" 2> "$job_dir/stderr" &
fi
maint_pid=$!
logger -t honk-maintenance "$operation started" 2>/dev/null || :
# Total watchdog: never poll forever if maintenance.sh hangs.
_poll_deadline=$(($(date +%s) + 1800))
while kill -0 "$maint_pid" 2>/dev/null; do
if [ "$(date +%s)" -ge "$_poll_deadline" ]; then
logger -t honk-maintenance "$operation timed out after 1800s, killing $maint_pid" 2>/dev/null || :
kill -9 "$maint_pid" 2>/dev/null || :
break
fi
journal_phase=$(sed -n 's/^phase=//p' /etc/.honk-maintenance/journal 2>/dev/null | sed -n '1p')
if [ "$operation" = update_apply ]; then
update_phase=$(cat /etc/.honk-update/phase 2>/dev/null)
case "$update_phase" in
downloading) status_phase=downloading ;;
verifying) status_phase=validating ;;
stopping) status_phase=stopping ;;
installing) status_phase=applying ;;
starting) status_phase=starting ;;
*) status_phase=preparing ;;
esac
elif [ "$operation" = update_check ]; then
status_phase=checking_feed
else case "$journal_phase" in
prepared) status_phase=preparing ;;
stopped) status_phase=stopping ;;
old_moved|new_installed) status_phase=applying ;;
uci_applied) status_phase=validating ;;
service_started) status_phase=starting ;;
rollback_old_start) status_phase=rolling_back ;;
committed) status_phase=committing ;;
*) status_phase=preparing ;;
esac; fi
write_status running "$status_phase" true "$status_phase" || :
sleep 1
done
wait "$maint_pid"
operation_rc=$?
json_load "$(cat "$job_dir/output" 2>/dev/null)" 2>/dev/null || {
if [ -e /etc/.honk-maintenance/journal ] || [ -L /etc/.honk-maintenance/journal ] || [ -d /run/honk.lock ]; then
write_status rollback_required recovery false maintenance_recovery_required
else
write_status failed complete false operation_failed
fi
logger -t honk-maintenance "$operation failed (invalid result)" 2>/dev/null || :
exit 1
}
json_get_var operation_ok ok
json_get_var operation_message message
if [ "$operation_rc" -eq 0 ] && [ "$operation_ok" = 1 ]; then
if [ "$operation" = update_check ]; then
json_add_string state succeeded
json_add_string phase complete
json_add_string job_id "$job_id"
json_dump > "$job_dir/status.new" && chmod 0600 "$job_dir/status.new" && mv -f "$job_dir/status.new" "$job_dir/status" || exit 1
logger -t honk-maintenance "$operation completed" 2>/dev/null || :
exit 0
fi
write_status succeeded complete true "$operation_message"
logger -t honk-maintenance "$operation completed" 2>/dev/null || :
exit 0
fi
case "$operation_message" in
*rollback_failed*|*recovery_required*|*snapshot_retained*)
write_status rollback_required recovery false "$operation_message"
logger -t honk-maintenance "$operation requires recovery" 2>/dev/null || :
exit 1
;;
esac
write_status failed complete false "${operation_message:-operation_failed}"
logger -t honk-maintenance "$operation failed" 2>/dev/null || :
exit 1
+294
View File
@@ -0,0 +1,294 @@
#!/bin/sh
HONK_LIFECYCLE_CORE=/usr/bin/honk-core
HONK_LIFECYCLE_HAVE_TIMEOUT=$(command -v timeout 2>/dev/null)
# 字段归属:自带 global/experimental → file;只 include system.dae(且写法规范)→ system;
# 其余一律 unknown。写法不规范时不猜,直接拒绝。
config_owner() {
config_owner_file=${1:-/etc/honk/config.dae}
[ -f "$config_owner_file" ] && [ ! -L "$config_owner_file" ] || { echo unknown; return 0; }
own=$(awk '/^[[:space:]]*(global|experimental)[[:space:]]*\{/ { print "1"; exit }' "$config_owner_file")
inc=$(awk '
{
line = $0
sub(/\r$/, "", line)
if (!in_block) {
# 只接受「include {」独占一行;同行带内容一律算不规范
if (line ~ /^[[:space:]]*include[[:space:]]*\{[[:space:]]*$/) { in_block = 1; next }
if (line ~ /^[[:space:]]*include[[:space:]]*\{/) { print "irregular"; next }
next
}
if (line ~ /^[[:space:]]*\}[[:space:]]*$/) { in_block = 0; next }
if (line ~ /^[[:space:]]*\}/ || line ~ /\{/) { print "irregular"; next }
entry = line
sub(/#.*/, "", entry)
gsub(/^[[:space:]]+|[[:space:]]+$/, "", entry)
gsub(/["\047]/, "", entry)
if (entry == "") next
if (entry == "system.dae") print "system"
else if (entry ~ /^[A-Za-z0-9._-]+$/) print "other"
else print "irregular"
}
END { if (in_block) print "irregular" }
' "$config_owner_file")
has_system=
has_bad=
case "$inc" in *system*) has_system=1 ;; esac
case "$inc" in *other*|*irregular*) has_bad=1 ;; esac
if [ -n "$own" ]; then
[ -z "$inc" ] && echo file || echo unknown
elif [ -n "$has_bad" ]; then
echo unknown
elif [ -n "$has_system" ]; then
echo system
else
echo unknown
fi
}
# 启动轮询用 0.25 秒粒度,核心就绪后尽快返回;没有 timeout 命令时退回 1 秒。
honk_lifecycle_pause() {
if [ -n "$HONK_LIFECYCLE_HAVE_TIMEOUT" ]; then
timeout 0.25 sleep 1 2>/dev/null
return 0
fi
sleep 1
}
honk_lifecycle_procd_pid() { ubus call service list '{"name":"honk"}' 2>/dev/null | jsonfilter -e '@.honk.instances.main.pid' 2>/dev/null
}
honk_lifecycle_procd_running() {
ubus call service list '{"name":"honk"}' 2>/dev/null | jsonfilter -e '@.honk.instances.main.running' 2>/dev/null
}
honk_lifecycle_managed_pid() {
hlp_pid=$(honk_lifecycle_procd_pid)
[ -n "$hlp_pid" ] && [ -r "/proc/$hlp_pid/cmdline" ] || return 1
hlp_cmd=$(tr '\000' ' ' < "/proc/$hlp_pid/cmdline" 2>/dev/null) || return 1
case "$hlp_cmd" in
*/usr/bin/honk-core\ --config\ /etc/honk/config.dae\ --disable-timestamp*) ;;
*) return 1 ;;
esac
case "$hlp_cmd" in *--mock-ebpf*) return 1 ;; esac
[ "$(readlink -f "/proc/$hlp_pid/exe" 2>/dev/null)" = "$HONK_LIFECYCLE_CORE" ] || return 1
printf '%s\n' "$hlp_pid"
}
honk_lifecycle_starttime() {
[ -r "/proc/$1/stat" ] || return 1
awk '{ sub(/^.*\) /, ""); split($0, fields, /[[:space:]]+/); if (fields[20] ~ /^[0-9]+$/) print fields[20]; else exit 1 }' "/proc/$1/stat" 2>/dev/null
}
honk_lifecycle_listen() {
[ -f /var/run/honk/readiness ] && [ ! -L /var/run/honk/readiness ] || return 1
read -r hlp_token _ < /var/run/honk/readiness || return 1
case "$hlp_token" in ''|*[!0-9a-f-]*) return 1 ;; esac
sed -n 's/^api_listen=//p' "/var/run/honk/core-ready-$hlp_token" 2>/dev/null
}
honk_lifecycle_parse_listen() {
HONK_LIFECYCLE_LISTEN=$(honk_lifecycle_listen)
if [ -z "$HONK_LIFECYCLE_LISTEN" ]; then
HONK_LIFECYCLE_PORT=0
return 0
fi
case "$HONK_LIFECYCLE_LISTEN" in *:*) ;; *) return 1 ;; esac
HONK_LIFECYCLE_PORT=${HONK_LIFECYCLE_LISTEN##*:}
case "$HONK_LIFECYCLE_LISTEN" in ''|*[!A-Za-z0-9:._-]*) return 1 ;; esac
case "$HONK_LIFECYCLE_PORT" in ''|*[!0-9]*) return 1 ;; esac
[ "$HONK_LIFECYCLE_PORT" -ge 1024 ] && [ "$HONK_LIFECYCLE_PORT" -le 65535 ]
}
honk_lifecycle_ready_owned() {
hlp_pid=$1
[ -f /var/run/honk/readiness ] && [ ! -L /var/run/honk/readiness ] || return 1
read -r hlp_token hlp_hash < /var/run/honk/readiness || return 1
case "$hlp_token:$hlp_hash" in *[!0-9a-f:-]*|:*|:|*:) return 1 ;; esac
hlp_marker=/var/run/honk/core-ready-$hlp_token
[ -f "$hlp_marker" ] && [ ! -L "$hlp_marker" ] || return 1
grep -Fqx "pid=$hlp_pid" "$hlp_marker" && \
grep -Fqx "token=$hlp_token" "$hlp_marker" && \
grep -Fqx "config_hash=$hlp_hash" "$hlp_marker" && \
grep -Eq '^api_enabled=(true|false)$' "$hlp_marker" && \
grep -Eq '^clash_api_secret_set=(true|false)$' "$hlp_marker"
}
honk_lifecycle_port_open() {
hlp_port=$1
case "$hlp_port" in ''|*[!0-9]*) return 1 ;; esac
awk -v port="$hlp_port" 'BEGIN { printf "%04X\n", port }' | {
IFS= read -r hlp_hex || exit 1
for hlp_table in /proc/net/tcp /proc/net/tcp6; do
[ -r "$hlp_table" ] || continue
awk -v port="$hlp_hex" 'NR > 1 && toupper($2) ~ (":" port "$") && $4 == "0A" { found = 1 } END { exit !found }' "$hlp_table" && exit 0
done
exit 1
}
}
honk_lifecycle_listener_owned() {
hlp_pid=$1
hlp_port=$2
hlp_hex=$(awk -v port="$hlp_port" 'BEGIN { printf "%04X", port }') || return 1
for hlp_table in /proc/net/tcp /proc/net/tcp6; do
[ -r "$hlp_table" ] || continue
for hlp_inode in $(awk -v port="$hlp_hex" 'NR > 1 && toupper($2) ~ (":" port "$") && $4 == "0A" { print $10 }' "$hlp_table"); do
for hlp_fd in /proc/"$hlp_pid"/fd/*; do
[ "$(readlink "$hlp_fd" 2>/dev/null)" = "socket:[$hlp_inode]" ] && return 0
done
done
done
return 1
}
honk_lifecycle_api_owned() {
hlp_pid=$1
honk_lifecycle_parse_listen || return 1
[ "$HONK_LIFECYCLE_PORT" -gt 0 ] || return 1
honk_lifecycle_listener_owned "$hlp_pid" "$HONK_LIFECYCLE_PORT" && \
curl -fsS --noproxy '*' --connect-timeout 1 --max-time 2 "http://$HONK_LIFECYCLE_LISTEN/api" -o /dev/null 2>/dev/null
}
honk_lifecycle_runtime_owned() {
honk_lifecycle_ready_owned "$1"
}
honk_lifecycle_resources_clear() {
command -v ip >/dev/null 2>&1 || return 1
for hlp_link in dae0 dae0peer; do
ip link show "$hlp_link" >/dev/null 2>&1 && return 1
done
! ip netns list 2>/dev/null | awk '{print $1}' | grep -qx daens
}
honk_lifecycle_drain() {
hlp_timeout=${1:-30}
while [ "$hlp_timeout" -gt 0 ]; do
hlp_wait=0
if [ -n "${HONK_LIFECYCLE_STOP_PID:-}" ] && \
[ "$(honk_lifecycle_starttime "$HONK_LIFECYCLE_STOP_PID" 2>/dev/null)" = "$HONK_LIFECYCLE_STOP_STARTTIME" ]; then
hlp_wait=1
fi
hlp_procd=$(honk_lifecycle_procd_pid)
[ -z "$hlp_procd" ] || hlp_wait=1
hlp_running=$(honk_lifecycle_procd_running)
case "$hlp_running" in true|1) hlp_wait=1 ;; esac
hlp_all=$(pidof honk-core 2>/dev/null)
if [ -n "$hlp_all" ]; then
for hlp_pid in $hlp_all; do
if [ "$hlp_pid" != "${HONK_LIFECYCLE_STOP_PID:-}" ] || \
[ "$(honk_lifecycle_starttime "$hlp_pid" 2>/dev/null)" != "${HONK_LIFECYCLE_STOP_STARTTIME:-}" ]; then
echo "honk lifecycle: unmanaged honk-core process remains" >&2
return 1
fi
done
hlp_wait=1
fi
honk_lifecycle_resources_clear || hlp_wait=1
honk_lifecycle_parse_listen || { echo "honk lifecycle: invalid configured listener" >&2; return 1; }
hlp_port=$HONK_LIFECYCLE_PORT
if honk_lifecycle_port_open "$hlp_port"; then hlp_wait=1; fi
if [ "$hlp_wait" = 0 ]; then
return 0
fi
sleep 1
hlp_timeout=$((hlp_timeout - 1))
done
echo "honk lifecycle: old process or network resources did not drain" >&2
return 1
}
honk_lifecycle_stop() {
hlp_timeout=${1:-30}
HONK_LIFECYCLE_STOP_PID=$(honk_lifecycle_managed_pid 2>/dev/null)
if [ -n "$HONK_LIFECYCLE_STOP_PID" ]; then
HONK_LIFECYCLE_STOP_STARTTIME=$(honk_lifecycle_starttime "$HONK_LIFECYCLE_STOP_PID") || return 1
else
[ -z "$(pidof honk-core 2>/dev/null)" ] || { echo "honk lifecycle: refusing to stop unmanaged honk-core" >&2; return 1; }
[ -z "$(honk_lifecycle_procd_pid)" ] || { echo "honk lifecycle: procd instance is not the expected core" >&2; return 1; }
case "$(honk_lifecycle_procd_running)" in true|1) echo "honk lifecycle: procd instance is still running" >&2; return 1 ;; esac
HONK_LIFECYCLE_STOP_STARTTIME=
fi
if [ -n "$HONK_LIFECYCLE_STOP_PID" ]; then /etc/init.d/honk stop >/dev/null 2>&1 || :; fi
honk_lifecycle_drain "$hlp_timeout"
}
honk_lifecycle_start() {
hlp_timeout=${1:-30}
[ -z "$(pidof honk-core 2>/dev/null)" ] || { echo "honk lifecycle: refusing start while a core process exists" >&2; return 1; }
[ -z "$(honk_lifecycle_procd_pid)" ] || { echo "honk lifecycle: procd instance has not stopped" >&2; return 1; }
case "$(honk_lifecycle_procd_running)" in true|1) echo "honk lifecycle: procd instance is still running" >&2; return 1 ;; esac
honk_lifecycle_resources_clear || { echo "honk lifecycle: network resources have not drained" >&2; return 1; }
honk_lifecycle_parse_listen || { echo "honk lifecycle: invalid configured listener" >&2; return 1; }
hlp_listen=$HONK_LIFECYCLE_LISTEN
hlp_port=$HONK_LIFECYCLE_PORT
if [ -n "${HONK_MAINT_CAP:-}" ]; then export HONK_MAINT_CAP; fi
/etc/init.d/honk start >/dev/null 2>&1
hlp_start_status=$?
unset HONK_MAINT_CAP
[ "$hlp_start_status" = 0 ] || { echo "honk lifecycle: init start failed" >&2; return 1; }
hlp_stable=0
hlp_pid=
hlp_starttime=
# A config the core cannot run crash-loops through procd: every attempt gets a
# new PID, so a fixed timeout would burn the whole budget before the caller can
# be told the start failed. Count distinct PIDs and give up early instead.
hlp_seen_pid=
hlp_attempts=0
hlp_tick=0
while [ "$hlp_timeout" -gt 0 ]; do
hlp_new_pid=$(honk_lifecycle_managed_pid 2>/dev/null)
if [ -n "$hlp_new_pid" ] && [ "$hlp_new_pid" != "$hlp_seen_pid" ]; then
hlp_seen_pid=$hlp_new_pid
hlp_attempts=$((hlp_attempts + 1))
if [ "$hlp_attempts" -gt 3 ]; then
echo "honk lifecycle: core keeps restarting, giving up" >&2
return 1
fi
fi
if [ -n "$hlp_new_pid" ]; then
hlp_new_starttime=$(honk_lifecycle_starttime "$hlp_new_pid") || hlp_new_starttime=
if [ -n "$hlp_new_starttime" ] && \
{ [ -z "${HONK_LIFECYCLE_STOP_PID:-}" ] || [ "$hlp_new_pid:$hlp_new_starttime" != "$HONK_LIFECYCLE_STOP_PID:$HONK_LIFECYCLE_STOP_STARTTIME" ]; } && \
{ honk_lifecycle_ready_owned "$hlp_new_pid"; }; then
if [ "$hlp_pid:$hlp_starttime" = "$hlp_new_pid:$hlp_new_starttime" ]; then
hlp_stable=$((hlp_stable + 1))
else
hlp_pid=$hlp_new_pid
hlp_starttime=$hlp_new_starttime
hlp_stable=1
fi
if [ "$hlp_stable" -ge 3 ]; then
HONK_LIFECYCLE_STOP_PID=$hlp_new_pid
HONK_LIFECYCLE_STOP_STARTTIME=$hlp_new_starttime
return 0
fi
else
hlp_stable=0
hlp_pid=
hlp_starttime=
fi
else
hlp_stable=0
hlp_pid=
hlp_starttime=
fi
honk_lifecycle_pause
hlp_tick=$((hlp_tick + 1))
[ "$hlp_tick" -lt 4 ] || { hlp_tick=0; hlp_timeout=$((hlp_timeout - 1)); }
done
echo "honk lifecycle: new managed core did not become stable and own its API listener" >&2
return 1
}
honk_lifecycle_restart() {
if [ -n "$(honk_lifecycle_managed_pid 2>/dev/null)" ]; then
HONK_LIFECYCLE_WAS_RUNNING=1
else
[ -z "$(pidof honk-core 2>/dev/null)" ] || { echo "honk lifecycle: refusing unmanaged honk-core" >&2; return 1; }
HONK_LIFECYCLE_WAS_RUNNING=0
fi
honk_lifecycle_stop "${1:-30}" && honk_lifecycle_start "${1:-30}"
}
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
HONK_LOCK_DIR=/run/honk.lock
# PID alone is not enough to identify a process (PID reuse race). We store
# "pid starttime" where starttime is field 22 of /proc/pid/stat.
_honk_proc_starttime() {
cut -d' ' -f22 "/proc/$1/stat" 2>/dev/null
}
honk_lock_acquire() {
mkdir "$HONK_LOCK_DIR" 2>/dev/null || return 1
chmod 0700 "$HONK_LOCK_DIR" || { rmdir "$HONK_LOCK_DIR"; return 1; }
printf '%s %s\n' "$$" "$(_honk_proc_starttime $$)" > "$HONK_LOCK_DIR/pid" || { rm -f "$HONK_LOCK_DIR/pid"; rmdir "$HONK_LOCK_DIR"; return 1; }
}
honk_lock_is_stale() {
[ -r "$HONK_LOCK_DIR/pid" ] || return 1
read -r owner owner_start < "$HONK_LOCK_DIR/pid" || return 1
case "$owner" in ''|*[!0-9]*) return 1 ;; esac
# Dead if the PID is gone, or if it was reused by a newer process.
! kill -0 "$owner" 2>/dev/null && return 0
[ "$(_honk_proc_starttime "$owner")" = "$owner_start" ] || return 0
return 1
}
honk_lock_release() {
[ -r "$HONK_LOCK_DIR/pid" ] || return 1
read -r owner owner_start < "$HONK_LOCK_DIR/pid" || return 1
[ "$owner" = "$$" ] && [ "$owner_start" = "$(_honk_proc_starttime $$)" ] || return 1
rm -f "$HONK_LOCK_DIR/pid" && rmdir "$HONK_LOCK_DIR"
}
+57
View File
@@ -0,0 +1,57 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
requested=$1
case "$requested" in all|debug|info|warn|error) ;; *) exit 2 ;; esac
awk -v requested="$requested" '
function rank(level) {
if (level == "DEBUG" || level == "TRACE") return 0
if (level == "INFO" || level == "NOTICE") return 1
if (level == "WARN" || level == "WARNING") return 2
if (level == "ERROR" || level == "FATAL" || level == "CRIT" || level == "CRITICAL" || level == "ALERT" || level == "EMERG") return 3
return -1
}
function from_syslog(header, token, parts, count, level) {
count = split(header, parts, /[[:space:]]+/)
for (i = 1; i <= count; i++) {
token = parts[i]
if (token ~ /^[[:alnum:]_-]+\.(debug|info|notice|warn|warning|err|error|crit|critical|alert|emerg)$/) {
sub(/^.*\./, "", token)
if (token == "err") token = "error"
return rank(toupper(token))
}
}
return -1
}
{
if (requested == "all" || requested == "debug") { print; next }
line = $0
header = line
message = ""
separator = index(line, "]: ")
if (separator > 0) {
header = substr(line, 1, separator + 1)
message = substr(line, separator + 3)
} else {
separator = index(line, ": ")
if (separator > 0) {
header = substr(line, 1, separator - 1)
message = substr(line, separator + 2)
}
}
sub(/^[0-9][0-9][0-9][0-9]-[0-9T:.+Z-]+[[:space:]]+/, "", message)
sub(/^[[:space:]]+/, "", message)
if (match(message, /^(TRACE|DEBUG|INFO|NOTICE|WARN|WARNING|ERROR|FATAL|CRIT|CRITICAL|ALERT|EMERG)([[:space:]:]|$)/)) {
level = message
sub(/[[:space:]:].*$/, "", level)
severity = rank(level)
} else if (match(line, /^<[0-7]>/)) {
priority = substr(line, 2, 1) + 0
severity = priority <= 3 ? 3 : priority == 4 ? 2 : priority <= 6 ? 1 : 0
} else {
severity = from_syslog(header)
}
threshold = requested == "info" ? 1 : requested == "warn" ? 2 : 3
if (severity >= threshold) print
}'
+9
View File
@@ -0,0 +1,9 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
honk_add_log_lines() {
[ -s "$1" ] || return 0
while IFS= read -r line; do
json_add_string "" "$line"
done < "$1"
}
+1206
View File
File diff suppressed because it is too large. Load diff
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
exec sed -E \
-e 's#([[:alnum:]+.-]+://)[^[:space:]"<>]+#\1[redacted]#g' \
-e 's/([Bb]earer[[:space:]]+)[^[:space:],;]+/\1[redacted]/g' \
-e 's/([Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Tt][Oo][Kk][Ee][Nn]|[Ss][Ee][Cc][Rr][Ee][Tt]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn])[^:=]*[=:][[:space:]]*.*/\1=[redacted]/'
+22
View File
@@ -0,0 +1,22 @@
global {
wan_interface: auto
lan_interface: br-lan
log_level: info
dial_mode: domain
allow_insecure: false
auto_config_kernel_parameter: true
data_dir: '/etc/honk'
store_subscribe: true
nfqueue_enable: true
}
experimental {
native_api {
enabled: true
listen: '127.0.0.1:9527'
password_auth: true
allow_anonymous_loopback: false
config_write: true
ui: '/usr/share/doona'
}
}
+292
View File
@@ -0,0 +1,292 @@
#!/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH
umask 077
. /usr/share/libubox/jshn.sh
UPDATE_ROOT=/tmp/honk-update
TRUST_ROOT=/etc/honk/update-trust
FEED_FILE=$TRUST_ROOT/feed.url
MANIFEST_KEY=$TRUST_ROOT/manifest.pub
MANIFEST=$UPDATE_ROOT/manifest.json
SIGNATURE=$UPDATE_ROOT/manifest.json.sig
RECORDS=$UPDATE_ROOT/packages.tsv
UPDATE_LOCK_OWNED=0
CHECK_DIR=
update_lock_acquire() {
. /usr/share/honk/lock.sh || return 1
honk_lock_acquire || return 1
UPDATE_LOCK_OWNED=1
}
update_lock_release() {
[ "$UPDATE_LOCK_OWNED" = 1 ] || return 0
honk_lock_release >/dev/null 2>&1 || return 1
UPDATE_LOCK_OWNED=0
}
discard_check_dir() {
case "$CHECK_DIR" in
"$UPDATE_ROOT"/.check.*)
[ -d "$CHECK_DIR" ] && [ ! -L "$CHECK_DIR" ] && rm -rf "$CHECK_DIR"
;;
esac
CHECK_DIR=
}
cleanup_update() {
discard_check_dir
update_lock_release || :
}
emit_update() {
json_init
json_add_boolean ok "$1"
json_add_boolean available "$2"
json_add_boolean apply_enabled "$3"
json_add_string message "$4"
json_add_string reason "$5"
[ -z "$6" ] || json_add_string version "$6"
json_dump
}
safe_file() {
[ -f "$1" ] && [ ! -L "$1" ] && [ "$(stat -c '%u:%a' "$1" 2>/dev/null)" = "0:$2" ]
}
prepare_update_root() {
if [ -e "$UPDATE_ROOT" ] || [ -L "$UPDATE_ROOT" ]; then
[ -d "$UPDATE_ROOT" ] && [ ! -L "$UPDATE_ROOT" ] && [ "$(stat -c '%u:%a' "$UPDATE_ROOT" 2>/dev/null)" = 0:700 ] || return 1
else
mkdir "$UPDATE_ROOT" && chmod 0700 "$UPDATE_ROOT" || return 1
fi
}
read_trust() {
[ -d "$TRUST_ROOT" ] && [ ! -L "$TRUST_ROOT" ] && [ "$(stat -c '%u:%a' "$TRUST_ROOT" 2>/dev/null)" = 0:700 ] || return 1
safe_file "$FEED_FILE" 600 && safe_file "$MANIFEST_KEY" 600 || return 1
[ "$(wc -c < "$FEED_FILE" | tr -d ' ')" -le 512 ] || return 1
feed_url=$(cat "$FEED_FILE") || return 1
[ -n "$feed_url" ] || return 1
case "$feed_url" in *'?'*|*'#'*|*'@'*|*' '*|*'\'*|*'"'*|*"'"*) return 1 ;; esac
echo "$feed_url" | grep -Eq '^https://[A-Za-z0-9.-]+(:[0-9]+)?(/[A-Za-z0-9._~/%+-]*)?$' || return 1
return 0
}
manifest_field() {
jsonfilter -i "$MANIFEST" -e "$1" 2>/dev/null
}
installed_version() {
awk -v wanted="$1" '
$0 == "P:" wanted { found=1; next }
found && /^V:/ { print substr($0, 3); exit }
found && /^P:/ { exit }
' /lib/apk/db/installed 2>/dev/null
}
validate_manifest() {
validate_url=$1
validate_json=$(cat "$MANIFEST") || return 1
json_load "$validate_json" 2>/dev/null || return 1
json_get_type validate_packages_type packages
[ "$validate_packages_type" = array ] || return 1
json_select packages || return 1
json_get_keys validate_package_keys
[ "$(printf '%s\n' "$validate_package_keys" | wc -w | tr -d ' ')" = 2 ] || return 1
json_select .. || return 1
[ "$(manifest_field '@.schema')" = 1 ] || return 1
[ "$(manifest_field '@.product')" = openwrt-honk ] || return 1
# Target must match this device: map uname -m to manifest arch names.
case "$(uname -m)" in
x86_64) _local_arch=x86_64 ;;
aarch64) _local_arch=aarch64 ;;
armv7l) _local_arch=armv7 ;;
*) return 1 ;;
esac
[ "$(manifest_field '@.target.architecture')" = "$_local_arch" ] || return 1
# OpenWrt version must match: 24.10 (opkg/ipk) or 25.12 (apk).
_local_owrt=$(sed -n 's/^DISTRIB_RELEASE="\([0-9]*\.[0-9]*\).*/\1/p' /etc/openwrt_release 2>/dev/null | head -n 1)
case "$_local_owrt" in 24.10|25.12) ;; *) return 1 ;; esac
[ "$(manifest_field '@.target.openwrt')" = "$_local_owrt" ] || return 1
case "$_local_owrt" in
24.10) [ "$(manifest_field '@.target.package_format')" = ipk ] || return 1 ;;
25.12) [ "$(manifest_field '@.target.package_format')" = apk ] || return 1 ;;
esac
[ "$(manifest_field '@.target.kernel_min')" = 6.12 ] || return 1
[ "$(manifest_field '@.target.requires_btf')" = true ] || return 1
[ "$(manifest_field '@.min_updater_api')" = 1 ] || return 1
[ "$(manifest_field '@.state_schema')" = 2 ] || return 1
# (arch and OpenWrt version already validated against local system above)
[ -r /sys/kernel/btf/vmlinux ] || return 1
kernel_version=$(uname -r | sed 's/-.*//')
kernel_major=${kernel_version%%.*}
kernel_minor=${kernel_version#*.}
kernel_minor=${kernel_minor%%.*}
case "$kernel_major:$kernel_minor" in *[!0-9:]*|:*) return 1 ;; esac
[ "$kernel_major" -gt 6 ] || { [ "$kernel_major" = 6 ] && [ "$kernel_minor" -ge 12 ]; } || return 1
validate_commit=$(manifest_field '@.core.commit')
case "$validate_commit" in *[!0-9a-f]*|'') return 1 ;; esac
[ "${#validate_commit}" -eq 40 ] || return 1
validate_commit=$(manifest_field '@.doona.commit')
case "$validate_commit" in *[!0-9a-f]*|'') return 1 ;; esac
[ "${#validate_commit}" -eq 40 ] || return 1
for validate_sha in \
"$(manifest_field '@.core.artifact_sha256')" \
"$(manifest_field '@.doona.patch_sha256')" \
"$(manifest_field '@.doona.artifact_sha256')" \
"$(manifest_field '@.sdk_sha256')"; do
case "$validate_sha" in *[!0-9a-f]*|'') return 1 ;; esac
[ "${#validate_sha}" -eq 64 ] || return 1
done
validate_version=$(manifest_field '@.packages[0].version')
case "$validate_version" in ''|*[!A-Za-z0-9.+~-]*) return 1 ;; esac
: > "$RECORDS" || return 1
validate_seen=' '
validate_available=0
for validate_index in 0 1; do
validate_name=$(manifest_field "@.packages[$validate_index].name")
validate_version=$(manifest_field "@.packages[$validate_index].version")
validate_arch=$(manifest_field "@.packages[$validate_index].arch")
validate_filename=$(manifest_field "@.packages[$validate_index].filename")
validate_size=$(manifest_field "@.packages[$validate_index].size")
validate_sha=$(manifest_field "@.packages[$validate_index].sha256")
validate_package_url=$(manifest_field "@.packages[$validate_index].url")
case "$validate_name" in honk|luci-app-honk) ;; *) return 1 ;; esac
case "$validate_seen" in *" $validate_name "*) return 1 ;; esac
validate_seen="$validate_seen$validate_name "
case "$validate_version" in ''|*[!A-Za-z0-9.+~-]*) return 1 ;; esac
case "$validate_arch" in x86_64|aarch64|armv7|noarch) ;; *) return 1 ;; esac
case "$validate_name:$validate_arch" in honk:x86_64|honk:aarch64|honk:armv7|luci-app-honk:x86_64|luci-app-honk:aarch64|luci-app-honk:armv7|luci-app-honk:noarch) ;; *) return 1 ;; esac
[ "$validate_filename" = "$validate_name-$validate_version.apk" ] || [ "$validate_filename" = "${validate_name}_${validate_version}_${validate_arch}.ipk" ] || return 1
case "$validate_filename" in *'/'*|*'..'*|*[!A-Za-z0-9.+_-]*) return 1 ;; esac
case "$validate_size" in ''|*[!0-9]*) return 1 ;; esac
[ "$validate_size" -gt 0 ] && [ "$validate_size" -le 134217728 ] || return 1
case "$validate_sha" in *[!0-9a-f]*|'') return 1 ;; esac
[ "${#validate_sha}" -eq 64 ] || return 1
[ "$validate_package_url" = "${validate_url%/}/packages/$validate_filename" ] || return 1
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$validate_name" "$validate_version" "$validate_arch" "$validate_filename" "$validate_size" "$validate_sha" "$validate_package_url" >> "$RECORDS" || return 1
[ "$(installed_version "$validate_name")" = "$validate_version" ] || validate_available=1
done
[ "$(wc -l < "$RECORDS" | tr -d ' ')" = 2 ] || return 1
for validate_required in honk luci-app-honk; do
case "$validate_seen" in *" $validate_required "*) ;; *) return 1 ;; esac
done
update_version=$(awk -F '\t' '$1 == "honk" { print $2; exit }' "$RECORDS")
return 0
}
verify_signed_manifest() {
read_trust || return 2
prepare_update_root || return 3
CHECK_DIR=$(mktemp -d "$UPDATE_ROOT/.check.XXXXXX") || return 3
check_dir=$CHECK_DIR
chmod 0700 "$check_dir" || { discard_check_dir; return 3; }
check_manifest=$check_dir/manifest.json
check_signature=$check_dir/manifest.json.sig
if ! curl -fLsS --proto '=https' --proto-redir '=https' --tlsv1.2 --connect-timeout 4 --max-time 12 --max-filesize 65536 \
"${feed_url%/}/manifest.json" -o "$check_manifest" 2>/dev/null ||
! curl -fLsS --proto '=https' --proto-redir '=https' --tlsv1.2 --connect-timeout 4 --max-time 8 --max-filesize 4096 \
"${feed_url%/}/manifest.json.sig" -o "$check_signature" 2>/dev/null ||
! usign -V -m "$check_manifest" -p "$MANIFEST_KEY" -x "$check_signature" >/dev/null 2>&1; then
discard_check_dir
return 4
fi
MANIFEST=$check_manifest
RECORDS=$check_dir/packages.tsv
if ! validate_manifest "$feed_url"; then
discard_check_dir
return 5
fi
cp "$check_manifest" "$UPDATE_ROOT/manifest.json.new" && cp "$check_signature" "$UPDATE_ROOT/manifest.json.sig.new" || { discard_check_dir; return 3; }
cp "$RECORDS" "$UPDATE_ROOT/packages.tsv.new" || { discard_check_dir; return 3; }
printf '%s\n' "$(date +%s)" > "$UPDATE_ROOT/checked-at.new" || { discard_check_dir; return 3; }
chmod 0600 "$UPDATE_ROOT/manifest.json.new" "$UPDATE_ROOT/manifest.json.sig.new" "$UPDATE_ROOT/packages.tsv.new" "$UPDATE_ROOT/checked-at.new" || { discard_check_dir; return 3; }
mv -f "$UPDATE_ROOT/manifest.json.new" "$UPDATE_ROOT/manifest.json" &&
mv -f "$UPDATE_ROOT/manifest.json.sig.new" "$UPDATE_ROOT/manifest.json.sig" &&
mv -f "$UPDATE_ROOT/packages.tsv.new" "$UPDATE_ROOT/packages.tsv" &&
mv -f "$UPDATE_ROOT/checked-at.new" "$UPDATE_ROOT/checked-at" || { discard_check_dir; return 3; }
discard_check_dir
return 0
}
update_check() {
read_trust || { emit_update true false false no_release trusted_feed_unavailable; return 0; }
update_lock_acquire || { emit_update false false false update_check_failed operation_in_progress; return 1; }
verify_signed_manifest
check_rc=$?
update_lock_release
case "$check_rc" in
2) emit_update true false false no_release trusted_feed_unavailable; return 0 ;;
4) emit_update false false false update_check_failed signed_manifest_unavailable; return 1 ;;
3) emit_update false false false update_check_failed update_storage_unavailable; return 1 ;;
5) emit_update false false false update_check_failed manifest_incompatible; return 1 ;;
0) ;;
*) emit_update false false false update_check_failed manifest_invalid; return 1 ;;
esac
if [ "$validate_available" = 1 ]; then
emit_update true true false update_available rollback_tuple_unavailable "$update_version"
else
emit_update true false false no_update already_current "$update_version"
fi
}
update_gate() {
read_trust || { emit_update true false false no_release trusted_feed_unavailable; return 0; }
update_lock_acquire || { emit_update false false false update_check_failed operation_in_progress; return 1; }
gate_ok=1
gate_available=0
gate_reason=
prepare_update_root || { gate_ok=0; gate_reason=update_storage_unavailable; }
if [ "$gate_ok" = 1 ]; then
for gate_file in "$UPDATE_ROOT/manifest.json" "$UPDATE_ROOT/manifest.json.sig" "$UPDATE_ROOT/packages.tsv" "$UPDATE_ROOT/checked-at"; do
safe_file "$gate_file" 600 || { gate_reason=signed_manifest_missing; break; }
done
fi
if [ "$gate_ok" = 1 ] && [ -z "$gate_reason" ]; then
checked_at=$(cat "$UPDATE_ROOT/checked-at")
case "$checked_at" in ''|*[!0-9]*) gate_reason=signed_manifest_expired ;; esac
if [ -z "$gate_reason" ] && [ $(( $(date +%s) - checked_at )) -gt 600 ]; then gate_reason=signed_manifest_expired; fi
fi
if [ "$gate_ok" = 1 ] && [ -z "$gate_reason" ]; then
usign -V -m "$UPDATE_ROOT/manifest.json" -p "$MANIFEST_KEY" -x "$UPDATE_ROOT/manifest.json.sig" >/dev/null 2>&1 || { gate_ok=0; gate_reason=manifest_signature_invalid; }
fi
if [ "$gate_ok" = 1 ] && [ -z "$gate_reason" ]; then
MANIFEST=$UPDATE_ROOT/manifest.json
RECORDS=$UPDATE_ROOT/packages.tsv
validate_manifest "$feed_url" || { gate_ok=0; gate_reason=manifest_incompatible; }
fi
gate_available=${validate_available:-0}
gate_version=${update_version:-}
update_lock_release
if [ "$gate_ok" != 1 ]; then emit_update false false false update_check_failed "$gate_reason"; return 1; fi
if [ -n "$gate_reason" ]; then emit_update true false false no_release "$gate_reason"; return 0; fi
if [ "$gate_available" = 1 ]; then
emit_update true true false update_available rollback_tuple_unavailable "$gate_version"
else
emit_update true false false no_update already_current "$gate_version"
fi
}
update_apply() {
update_gate >/dev/null || { emit_update false false false update_apply_failed trusted_manifest_invalid; return 1; }
[ "$validate_available" = 1 ] || { emit_update false false false update_apply_failed no_update; return 1; }
# No previous signed package tuple or exercised downgrade path is available yet.
# Keep the backend gate closed even when the update manifest itself is compatible.
emit_update false false false update_apply_failed rollback_tuple_unavailable
return 1
}
trap cleanup_update EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
case "$1" in
check) update_check ;;
gate) update_gate ;;
apply) update_apply ;;
*) emit_update false false false update_check_failed invalid_action; exit 2 ;;
esac
@@ -35,10 +35,6 @@ o:value("tun", "TUN")
o:value("tap", "TAP")
o.rmempty = false
o = s:option(Flag, "lzo", translate("LZO compression"))
o.default = "1"
o.rmempty = false
o = s:option(Flag, "route_nopull", translate("No pull route"))
o.default = "1"
o.rmempty = false
@@ -43,9 +43,6 @@ msgstr "协议"
msgid "Type"
msgstr "类型"
msgid "LZO compression"
msgstr "LZO 压缩"
msgid "No pull route"
msgstr "不拉取路由"
@@ -47,9 +47,6 @@ start_instance() {
local _key="key key"
}
local c_lzo=$(uci -q get ${CONFIG}.${cfgid}.lzo)
[ "${c_lzo}" = "1" ] && local _lzo="comp-lzo"
local c_route_nopull=$(uci -q get ${CONFIG}.${cfgid}.route_nopull)
[ "${c_route_nopull}" = "1" ] && local _route_nopull="route-nopull"
@@ -201,7 +198,6 @@ start_instance() {
${_auth_user_pass}
${_tls_auth}
${_tls_crypt}
${_lzo}
${_route_nopull}
verb 3
@@ -45,10 +45,6 @@ o.placeholder = "255.255.255.0"
o.default = o.placeholder
o.rmempty = false
o = s:taboption("general", Flag, "lzo", translate("LZO compression"))
o.default = "1"
o.rmempty = false
o = s:taboption("general", TextValue, "extra_config", translate("Extra Config"))
o.datatype = "string"
o.rows = 3
@@ -28,9 +28,6 @@ msgstr "IP 段"
msgid "Subnet mask"
msgstr "子网掩码"
msgid "LZO compression"
msgstr "LZO 压缩"
msgid "Extra Config"
msgstr "额外配置"
@@ -6,5 +6,4 @@ config server 'server'
option ipv6 '1'
option ip_segment '172.30.1.0'
option subnet_mask '255.255.255.0'
option lzo '1'
option ddns 'example.com'
@@ -80,8 +80,6 @@ gen_include() {
start_service() {
local enabled=$(uci -q get ${CONFIG}.server.enabled)
[ "${enabled}" -eq 1 ] || return 1
local lzo=$(uci -q get ${CONFIG}.server.lzo)
[ "${lzo}" -eq 1 ] && lzo_conf="comp-lzo"
mkdir -p ${TMP_OVPN_PATH}
_ca=${OVPN_PATH}/ca.crt
@@ -147,7 +145,6 @@ start_service() {
up ${SCRIPT_PATH}/up.sh
down ${SCRIPT_PATH}/down.sh
keepalive 10 120
${lzo_conf}
persist-key
persist-tun
script-security 3
@@ -16,7 +16,6 @@ cat <<-EOF > /tmp/openvpn.ovpn
persist-key
persist-tun
auth-user-pass
comp-lzo
verb 3
<ca>
$(cat /usr/share/openvpn-server/ca.crt)
-46
View File
@@ -1,46 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2009-2013 OpenWrt.org
#
include $(TOPDIR)/rules.mk
PKG_NAME:=BaiduPCS-Go
PKG_VERSION:=3.9.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/qjfoidnh/BaiduPCS-Go/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=de71666e961a3eeb90f8aca7b11934c3f0296d1870e036a7c086ba1decfca8ab
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
GO_PKG:=github.com/qjfoidnh/BaiduPCS-Go
GO_PKG_LDFLAGS_X:=main.Version=v$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
define Package/BaiduPCS-Go
SECTION:=net
CATEGORY:=Network
SUBMENU:=Download Manager
TITLE:=Terminal utility for Baidu Network Disk
URL:=https://github.com/qjfoidnh/BaiduPCS-Go
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
endef
define Package/BaiduPCS-Go/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
$(INSTALL_DIR) $(1)/usr/bin/
$(CP) $(PKG_INSTALL_DIR)/usr/bin/BaiduPCS-Go $(1)/usr/bin/
endef
$(eval $(call GoBinPackage,BaiduPCS-Go))
$(eval $(call BuildPackage,BaiduPCS-Go))
-85
View File
@@ -1,85 +0,0 @@
#
# Copyright (C) 2019 OpenWrt.org
#
# KFERMercer <KFER.Mercer@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=baidupcs-web
PKG_VERSION:=3.7.1
PKG_RELEASE:=2
include $(INCLUDE_DIR)/package.mk
define Package/baidupcs-web
SECTION:=net
CATEGORY:=Network
TITLE:=BaiduPCS-Web is a web controller for BaiduPCS-Go
URL:=https://github.com/Erope/baidupcs-web
endef
define Package/$(PKG_NAME)/description
BaiduPCS-Web is a web controller for BaiduPCS-Go
endef
# 禁止OpenWrt对二进制文件进行strip
STRIP:=true
ifeq ($(ARCH),i386)
PKG_ARCH_BAIDUPCS-WEB:=386
endif
ifeq ($(ARCH),x86_64)
PKG_ARCH_BAIDUPCS-WEB:=amd64
endif
ifeq ($(ARCH),mipsel)
PKG_ARCH_BAIDUPCS-WEB:=mipsle
endif
ifeq ($(ARCH),mips)
PKG_ARCH_BAIDUPCS-WEB:=mipsle
endif
ifeq ($(ARCH),arm)
ifeq ($(BOARD),bcm53xx)
PKG_ARCH_BAIDUPCS-WEB:=armv5
else ifeq ($(BOARD),kirkwood)
PKG_ARCH_BAIDUPCS-WEB:=armv5
else
PKG_ARCH_BAIDUPCS-WEB:=armv7
endif
endif
ifeq ($(ARCH),aarch64)
PKG_ARCH_BAIDUPCS-WEB:=arm64
endif
PKG_SOURCE:=BaiduPCS-Go-v$(PKG_VERSION)-linux-$(PKG_ARCH_BAIDUPCS-WEB).zip
PKG_SOURCE_URL:=https://github.com/coolsnowwolf/baidupcs-web/raw/master/
UNZIP_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/$(PKG_NAME)-unzip
PKG_HASH:=skip
define Build/Prepare
mkdir -vp $(UNZIP_DIR)
unzip -od $(UNZIP_DIR) $(DL_DIR)/$(PKG_SOURCE)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/baidupcs-web/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(UNZIP_DIR)/*/BaiduPCS-Go $(1)/usr/bin/baidupcs-web
chmod 755 $(1)/usr/bin/baidupcs-web
endef
$(eval $(call BuildPackage,baidupcs-web))
-70
View File
@@ -1,70 +0,0 @@
#
# Copyright (C) 2009-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=libcryptopp
PKG_VERSION:=5.6.4
PKG_RELEASE:=2
PKG_SOURCE:=cryptopp$(subst .,,$(PKG_VERSION)).zip
PKG_SOURCE_URL:=http://www.cryptopp.com/
PKG_MD5SUM:=4ee7e5cdd4a45a14756c169eaf2a77fc
PKG_USE_NINJA:=0
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_VERSION)
CMAKE_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/libcryptopp
SECTION:=libs
CATEGORY:=Libraries
DEPENDS:=+libpthread +libstdcpp
TITLE:=Free C++ class library of cryptographic schemes
URL:=http://packages.debian.org/sid/libcrypto++-dev
endef
define Package/libcryptopp/description
Crypto++ is library for creating C++ programs which use cryptographic algorithms.
The library uses a Pipes & Filters architecture with heavy use of templates and
abstract base classes.
endef
#CONFIGURE_ARGS += \
# --enable-static \
# --enable-shared
#TARGET_LDFLAGS += \
# -lpthread
CMAKE_OPTIONS += -DCMAKE_CXX_FLAGS="$(FPIC)"
CMAKE_OPTIONS += -DBUILD_STATIC=ON
CMAKE_OPTIONS += -DBUILD_SHARED=ON
UNPACK_CMD=cd $(PKG_BUILD_DIR) && unzip "$(DL_DIR)/$(PKG_SOURCE)"
define Build/Prepare
$(Build/Prepare/Default)
cd $(PKG_BUILD_DIR) && rm -f GNUmakefile GNUmakefile-cross
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/cryptopp
$(CP) $(PKG_INSTALL_DIR)/usr/include/cryptopp/* $(1)/usr/include/cryptopp/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcryptopp.{a,so*} $(1)/usr/lib/
endef
define Package/libcryptopp/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcryptopp.so* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,libcryptopp))
@@ -1,22 +0,0 @@
#
# <https://github.com/KFERMercer/luci-app-baidupcs-web>
#
# Copyright (C) 2020 KFERMercer <KFER.Mercer@gmail.com>
# Copyright (C) 2020 [CTCGFW] Project OpenWRT
#
# THIS IS FREE SOFTWARE, LICENSED UNDER GPLv3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-baidupcs-web
LUCI_TITLE:=LuCI support for BaiduPCS-Go
LUCI_DEPENDS:=+baidupcs-web +wget +openssl-util
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=6
PKG_MAINTAINER:=<https://github.com/KFERMercer/luci-app-baidupcs-web>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,18 +0,0 @@
module("luci.controller.baidupcs-web", package.seeall)
function index()
if not nixio.fs.access("/etc/config/baidupcs-web") then
return
end
entry({"admin", "nas", "baidupcs-web"}, cbi("baidupcs-web"), _("BaiduPCS Web"), 300).dependent = true
entry({"admin", "nas", "baidupcs-web", "status"}, call("act_status")).leaf = true
end
function act_status()
local e = {}
e.running=luci.sys.call("pgrep baidupcs-web >/dev/null") == 0
-- e.port = luci.sys.exec("uci get baidupcs-web.config.port")
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@@ -1,48 +0,0 @@
--[[
Copyright (C) 2020 KFERMercer <KFER.Mercer@gmail.com>
Copyright (C) 2020 [CTCGFW] Project OpenWRT
THIS IS FREE SOFTWARE, LICENSED UNDER GPLv3
]]--
m = Map("baidupcs-web")
m.title = translate("BaiduPCS-Web")
m.description = translate("基于BaiduPCS-Go, 可以让你高效的使用百度云")
m:section(SimpleSection).template = "baidupcs-web/baidupcs-web_status"
s = m:section(TypedSection, "baidupcs-web")
s.addremove = false
s.anonymous = true
enable = s:option(Flag, "enabled", translate("启用"))
enable.rmempty = false
o = s:option(Value, "port", translate("网页端口"))
o.datatype = "port"
o.placeholder = "5299"
o.default = "5299"
o.rmempty = false
o = s:option(Value, "download_dir", translate("下载目录"))
o.placeholder = "/opt/baidupcsweb-download"
o.default = "/opt/baidupcsweb-download"
o.rmempty = false
o = s:option(Value, "max_download_rate", translate("最大下载速度"))
o.placeholder = "0"
o = s:option(Value, "max_upload_rate", translate("最大上传速度"))
o.placeholder = "0"
o.description = translate("0代表不限制, 单位为每秒的传输速率, 后缀'/s' 可省略, 如 2MB/s, 2MB, 2m, 2mb 均为一个意思")
o = s:option(Value, "max_download_load", translate("同时进行下载文件的最大数量"))
o.placeholder = "1"
o.description = translate("不要太贪心, 当心被封号")
o = s:option(Value, "max_parallel", translate("最大并发连接数"))
o.placeholder = "8"
return m
@@ -1,38 +0,0 @@
<!--
Copyright (C) 2020 KFERMercer <KFER.Mercer@gmail.com>
THIS IS FREE SOFTWARE, LICENSED UNDER GPLv3.
-->
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[nas]], [[baidupcs-web]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('baidupcs-web_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>BaiduPCS-Web <%:RUNNING%></font></b></em><input class="cbi-button mar-10" type="button" value="<%:打开管理页面%>" onclick="openClient();" />';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>BaiduPCS-Web <%:NOT RUNNING%></font></b></em>';
}
}
}
);
function openClient() {
var curWwwPath = window.document.location.href;
var pathName = window.document.location.pathname;
var pos = curWwwPath.indexOf(pathName);
var localhostPath = curWwwPath.substring(0, pos);
var clientPort = window.document.getElementById("cbid.baidupcs-web.config.port").value
var url = localhostPath + ":" + clientPort;
window.open(url)
};
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="baidupcs-web_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
@@ -1,2 +0,0 @@
config baidupcs-web 'config'
@@ -1,34 +0,0 @@
#!/bin/sh /etc/rc.common
START=90
STOP=10
BaiduPCSWeb="/usr/bin/baidupcs-web"
enabled="$(uci -q get baidupcs-web.config.enabled)"
port="$(uci -q get baidupcs-web.config.port)"
download_dir="$(uci -q get baidupcs-web.config.download_dir)"
max_download_rate="$(uci -q get baidupcs-web.config.max_download_rate || echo '0')"
max_upload_rate="$(uci -q get baidupcs-web.config.max_upload_rate || echo '0')"
max_download_load="$(uci -q get baidupcs-web.config.max_download_load || echo '1')"
max_parallel="$(uci -q get baidupcs-web.config.max_parallel || echo '8')"
start() {
stop
[ "$enabled" == "1" ] || exit 0
mkdir -p "${download_dir}"
"${BaiduPCSWeb}" config set \
--savedir "${download_dir}" \
--max_download_rate "${max_download_rate}" \
--max_upload_rate "${max_upload_rate}" \
--max_download_load "${max_download_load}" \
--max_parallel "${max_parallel}" \
--max_upload_parallel "${max_parallel}" \
>/dev/null 2>&1
"${BaiduPCSWeb}" web --port "${port}" --access >/dev/null 2>&1 &
}
stop() {
killall "${BaiduPCSWeb}" >/dev/null 2>&1
}
@@ -1,11 +0,0 @@
{
"luci-app-baidupcs-web": {
"description": "Grant UCI access for luci-app-baidupcs-web",
"read": {
"uci": [ "baidupcs-web" ]
},
"write": {
"uci": [ "baidupcs-web" ]
}
}
}
@@ -1,4 +0,0 @@
{
"config": "baidupcs-web",
"init": "baidupcs-web"
}
@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for MWAN3 Helper
LUCI_DEPENDS:=+luci-app-mwan3 +pdnsd-alt +dnsmasq-full +ipset
LUCI_DEPENDS:=+luci-app-mwan3 +dnsmasq-full +ipset
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-mwan3helper
PKG_VERSION:=1
PKG_RELEASE:=4
PKG_RELEASE:=5
include $(TOPDIR)/feeds/luci/luci.mk
@@ -1,5 +1,3 @@
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.mwan3helper", package.seeall)
function index()
@@ -7,15 +5,6 @@ function index()
return
end
entry({"admin", "services", "mwan3helper"}, alias("admin", "services", "mwan3helper", "client"), _("MWAN3 Helper"), 300).dependent = true
entry({"admin", "services", "mwan3helper", "client"}, cbi("mwan3helper/client"), _("Settings"), 10).leaf = true
entry({"admin", "services", "mwan3helper", "lists"}, cbi("mwan3helper/list"), _("IPSet Lists"), 20).leaf = true
entry({"admin", "services", "mwan3helper", "status"}, call("act_status")).leaf = true
end
function act_status()
local e = {}
e.running = luci.sys.call("pgrep mwan3dns >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
entry({"admin", "services", "mwan3helper"}, alias("admin", "services", "mwan3helper", "list"), _("MWAN3 Helper"), 300).dependent = true
entry({"admin", "services", "mwan3helper", "list"}, cbi("mwan3helper/list")).leaf = true
end
@@ -1,28 +0,0 @@
m = Map("mwan3helper")
m.title = translate("MWAN3 Helper")
m.description = translate("MWAN3 Helper generate IPSets")
m:section(SimpleSection).template = "mwan3helper/mwan3helper_status"
s = m:section(TypedSection, "mwan3helper")
s.addremove = false
s.anonymous = true
o = s:option(Flag, "enabled", translate("Enable GFW IPSet"))
o.description = translate("启用 DNS 防污染并打开GFW IPSet(与SSR的GFW列表模式不能同时开启)")
o.rmempty = false
o = s:option(ListValue, "dns", translate("Anti-pollution DNS Server"))
o:value("208.67.222.222:443", translate("OpenDNS (208.67.222.222)"))
o:value("208.67.220.220:443", translate("OpenDNS (208.67.220.220)"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
return m
@@ -1,35 +1,75 @@
local sys = require "luci.sys"
m = Map("mwan3helper")
m.title = translate("MWAN3 IPSets")
m.title = translate("MWAN3 Helper")
m.description = translate("MWAN3 Helper generate IPSets")
s = m:section(TypedSection, "mwan3helper")
s.addremove = false
s.anonymous = true
o = s:option(DummyValue, "gfwlist", translate("GFW列表"))
o.description = translate("GFW列表数据: 5207 条,IPSET 名称为 gfwlist")
o = s:option(Flag, "enabled", translate("Enable"))
o.rmempty = false
o = s:option(DummyValue, "all_cn", translate("中国所有IP地址"))
o.description = translate("中国所有IP地址路由表数据: 8304 条, IPSET 名称为 cn")
local function get_num(ipset_name)
local base_cmd = "ipset -q list %s | grep -E 'Number of entries:' | awk -F ': ' '{print $2}'"
local num = sys.exec(base_cmd % ipset_name)
if not num or num == "" then
num = 0
end
return num
end
o = s:option(DummyValue, "chinatelecom", translate("中国电信"))
o.description = translate("中国电信路由表数据: 1948 条, IPSET 名称为 ct")
o = s:option(DummyValue, "unicom_cnc", translate("中国联通/网通"))
o.description = translate("中国联通/网通路由表数据: 895 条, IPSET 名称为 cnc")
local data = {
all_cn = {
name = translate("中国所有IP地址"),
ipset_name = "cn",
num = get_num("cn")
},
ct = {
name = translate("中国电信"),
ipset_name = "ct",
num = get_num("ct")
},
cnc = {
name = translate("中国联通"),
ipset_name = "cnc",
num = get_num("cnc")
},
cmcc = {
name = translate("中国移动/铁通"),
ipset_name = "cmcc",
num = get_num("cmcc")
},
cbtn = {
name = translate("中国广电"),
ipset_name = "cbtn",
num = get_num("cbtn")
},
cernet = {
name = translate("中国教育网"),
ipset_name = "cernet",
num = get_num("cernet")
},
gwbn = {
name = translate("长城宽带/鹏博士"),
ipset_name = "gwbn",
num = get_num("gwbn")
},
othernet = {
name = translate("中国其他ISP"),
ipset_name = "othernet",
num = get_num("othernet")
},
}
o = s:option(DummyValue, "cmcc", translate("中国移动"))
o.description = translate("中国移动路由表数据: 55 条, IPSET 名称为 cmcc")
local data_order = {"all_cn", "ct", "cnc", "cmcc", "cbtn", "cernet", "gwbn", "othernet"}
o = s:option(DummyValue, "crtc", translate("中国铁通"))
o.description = translate("中国铁通路由表数据: 16 条, IPSET 名称为 crtc")
o = s:option(DummyValue, "cernet", translate("中国教育网"))
o.description = translate("中国教育网路由表数据: 162 条, IPSET 名称为 cernet")
o = s:option(DummyValue, "gwbn", translate("长城宽带/鹏博士"))
o.description = translate("长城宽带/鹏博士: 94 条, IPSET 名称为 gwbn")
o = s:option(DummyValue, "othernet", translate("中国其他ISP"))
o.description = translate("中国其他ISP: 5134 条, IPSET 名称为 othernet")
for i, v in ipairs(data_order) do
local d = data[v]
o = s:option(DummyValue, v, d.name)
o.description = translatef("%s 条, IPSet 名称为 %s", d.num, d.ipset_name)
end
return m
@@ -1,22 +0,0 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[mwan3helper]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('mwan3helper_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>MWAN3 Helper <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>MWAN3 Helper <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="mwan3helper_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
@@ -1,24 +1,5 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
msgid "MWAN3 Helper"
msgstr "MWAN3 分流助手"
msgid "Settings"
msgstr "设置"
msgid "IPSet Lists"
msgstr "IPSet列表"
msgid "MWAN3 Helper generate IPSets"
msgstr "自动生成中国地址段和各大ISP运营商的 IPSet 地址段,并解决国外域名的污染问题,帮助MWAN3分流 ISP/WireGuard 等"
msgid "Enable GFW IPSet"
msgstr "启用 GFW IPSet"
msgstr "自动生成中国地址段和各大ISP运营商的 IPSet 地址段"
@@ -1,5 +1,3 @@
config mwan3helper 'config'
option dns '208.67.222.222:443'
option enabled '0'
@@ -3,164 +3,26 @@
START=60
DNSMASQ_RESTART=N
DNS_SERVER="208.67.222.222"
start_pdnsd() {
# DNS_SERVER=$(uci get flowoffload.@flow[0].dns_server 2>/dev/null)
[ -d /var/etc ] || mkdir -p /var/etc
if [ ! -f /var/mwan3dns/pdnsd.cache ]; then
mkdir -p /var/mwan3dns
echo -ne "pd13\000\000\000\000" > /var/mwan3dns/pdnsd.cache
chown -R nobody.nogroup /var/mwan3dns
fi
cat > /var/etc/mwan3dns.conf <<EOF
global {
perm_cache=1024; # dns缓存大小,单位KB,建议不要写的太大
cache_dir="/var/mwan3dns"; # 缓存文件的位置
pid_file = /var/run/mwan3dns.pid;
server_ip = 0.0.0.0; # pdnsd监听的网卡,0.0.0.0是全部网卡
server_port=53000; # pdnsd监听的端口,不要和别的服务冲突即可
status_ctl = on;
paranoid=on; # 二次请求模式,如果请求主DNS服务器返回的是垃圾地址,就向备用服务器请求
query_method=udp_only;
neg_domain_pol = off;
par_queries = 400; # 最多同时请求数
min_ttl = 1h; # DNS结果最短缓存时间
max_ttl = 1w; # DNS结果最长缓存时间
timeout = 10; # DNS请求超时时间,单位秒
destroy_ipset() {
for i in "$@"; do
ipset -q -F $i
ipset -q -X $i
done
}
server {
label = "routine";
ip = $DNS_SERVER;
port = 53;
timeout = 5;
reject = 74.125.127.102, # 以下是脏IP,也就是DNS污染一般会返回的结果,如果收到如下DNS结果会触发二次请求(TCP协议一般不会碰到脏IP)
74.125.155.102,
74.125.39.102,
74.125.39.113,
209.85.229.138,
128.121.126.139,
159.106.121.75,
169.132.13.103,
192.67.198.6,
202.106.1.2,
202.181.7.85,
203.161.230.171,
203.98.7.65,
207.12.88.98,
208.56.31.43,
209.145.54.50,
209.220.30.174,
209.36.73.33,
211.94.66.147,
213.169.251.35,
216.221.188.182,
216.234.179.13,
243.185.187.39,
37.61.54.158,
4.36.66.178,
46.82.174.68,
59.24.3.173,
64.33.88.161,
64.33.99.47,
64.66.163.251,
65.104.202.252,
65.160.219.113,
66.45.252.237,
69.55.52.253,
72.14.205.104,
72.14.205.99,
78.16.49.15,
8.7.198.45,
93.46.8.89,
37.61.54.158,
243.185.187.39,
190.93.247.4,
190.93.246.4,
190.93.245.4,
190.93.244.4,
65.49.2.178,
189.163.17.5,
23.89.5.60,
49.2.123.56,
54.76.135.1,
77.4.7.92,
118.5.49.6,
159.24.3.173,
188.5.4.96,
197.4.4.12,
220.250.64.24,
243.185.187.30,
249.129.46.48,
253.157.14.165;
reject_policy = fail;
}
server {
label = "special"; # 这个随便写
ip = 208.67.222.222,208.67.220.220; # 这里为备用DNS服务器的 ip 地址
port = 443; # 推荐使用53以外的端口(DNS服务器必须支持)
proxy_only = on;
timeout = 5;
}
source {
owner=localhost;
// serve_aliases=on;
file="/etc/hosts";
}
rr {
name=localhost;
reverse=on;
a=127.0.0.1;
owner=localhost;
soa=localhost,root.localhost,42,86400,900,86400,86400;
}
EOF
[ -d /var/sbin ] || mkdir -p /var/sbin
[ -f /var/sbin/mwan3dns ] || cp -a /usr/sbin/pdnsd /var/sbin/mwan3dns
/var/sbin/mwan3dns -c /var/etc/mwan3dns.conf -d
echo "Start MWAN3 Helper DNS"
}
stop_pdnsd() {
kill $(pidof mwan3dns) >/dev/null 2>&1 || kill -9 $(ps | grep mwan3dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
echo "Stop MWAN3 Helper DNS"
}
start(){
/etc/mwan3helper/genipset.sh cn '/etc/mwan3helper/all_cn.txt'
/etc/mwan3helper/genipset.sh ct '/etc/mwan3helper/chinatelecom.txt'
/etc/mwan3helper/genipset.sh cnc '/etc/mwan3helper/unicom_cnc.txt'
/etc/mwan3helper/genipset.sh cmcc '/etc/mwan3helper/cmcc.txt'
/etc/mwan3helper/genipset.sh crtc '/etc/mwan3helper/crtc.txt'
/etc/mwan3helper/genipset.sh cernet '/etc/mwan3helper/cernet.txt'
/etc/mwan3helper/genipset.sh gwbn '/etc/mwan3helper/gwbn.txt'
/etc/mwan3helper/genipset.sh othernet '/etc/mwan3helper/othernet.txt'
en=$(uci get mwan3helper.config.enabled 2>/dev/null)
if [ $en -eq 1 ]; then
start_pdnsd
mkdir -p /tmp/etc/dnsmasq-mwan3.d
ipset -N gfwlist hash:net 2>/dev/null
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"gfwlist"'\n",$0)}' /etc/mwan3helper/gfw.txt > /tmp/etc/dnsmasq-mwan3.d/mwan3_gfwlist.conf
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#53000"'\n",$0)}' /etc/mwan3helper/gfw.txt >> /tmp/etc/dnsmasq-mwan3.d/mwan3_gfwlist.conf
cat > /tmp/dnsmasq.d/dnsmasq-mwan3.conf <<EOF
conf-dir=/var/etc/dnsmasq-mwan3.d
EOF
/etc/init.d/dnsmasq restart
fi
}
stop(){
stop_pdnsd
rm -f /tmp/dnsmasq.d/dnsmasq-mwan3.conf
/etc/init.d/dnsmasq restart
en=$(uci -q get mwan3helper.config.enabled || echo "0")
if [ $en -eq 1 ]; then
[ ! -x /etc/mwan3helper/genipset.sh ] && chmod +x /etc/mwan3helper/genipset.sh
/etc/mwan3helper/genipset.sh cn '/etc/mwan3helper/all_cn.txt'
/etc/mwan3helper/genipset.sh ct '/etc/mwan3helper/chinatelecom.txt'
/etc/mwan3helper/genipset.sh cnc '/etc/mwan3helper/unicom_cnc.txt'
/etc/mwan3helper/genipset.sh cmcc '/etc/mwan3helper/cmcc.txt'
/etc/mwan3helper/genipset.sh cbtn '/etc/mwan3helper/chinabtn.txt'
/etc/mwan3helper/genipset.sh cernet '/etc/mwan3helper/cernet.txt'
/etc/mwan3helper/genipset.sh gwbn '/etc/mwan3helper/gwbn.txt'
/etc/mwan3helper/genipset.sh othernet '/etc/mwan3helper/othernet.txt'
else
destroy_ipset cn ct cnc cmcc cbtn cernet gwbn othernet
fi
}
File diff suppressed because it is too large. Load diff
@@ -1,33 +1,23 @@
1.51.0.0/16
1.184.0.0/15
42.201.32.0/19
42.244.0.0/14
43.252.48.0/22
43.252.48.0/24
49.52.0.0/14
49.120.0.0/14
49.140.0.0/15
49.208.0.0/15
58.154.0.0/15
58.192.0.0/15
58.194.0.0/15
58.196.0.0/15
58.198.0.0/15
58.200.0.0/13
59.64.0.0/14
59.68.0.0/14
59.72.0.0/15
59.74.0.0/15
59.76.0.0/16
59.77.0.0/16
59.78.0.0/15
58.192.0.0/12
59.64.0.0/12
101.4.0.0/14
101.76.0.0/15
103.31.48.0/22
103.81.200.0/22
103.87.20.0/22
103.115.120.0/22
103.137.60.0/24
103.165.110.0/23
103.205.162.0/24
103.226.80.0/22
103.252.172.0/22
110.64.0.0/15
111.114.0.0/15
111.116.0.0/15
@@ -41,23 +31,24 @@
115.158.0.0/16
116.13.0.0/16
116.56.0.0/15
116.255.128.0/24
118.202.0.0/15
118.228.0.0/15
118.230.0.0/16
120.94.0.0/16
120.95.0.0/16
120.94.0.0/15
121.48.0.0/15
121.52.160.0/19
121.192.0.0/16
121.193.0.0/16
121.194.0.0/15
121.192.0.0/14
121.248.0.0/14
122.204.0.0/14
125.216.0.0/15
125.218.0.0/16
125.219.0.0/16
125.220.0.0/15
125.222.0.0/15
125.216.0.0/13
162.105.0.0/16
166.111.0.0/16
168.160.0.0/17
168.160.152.0/24
168.160.158.0/23
168.160.160.0/21
168.160.168.0/24
175.185.0.0/16
175.186.0.0/15
180.84.0.0/15
@@ -66,106 +57,33 @@
183.168.0.0/15
183.170.0.0/16
183.172.0.0/14
192.124.154.0/24
202.4.128.0/19
202.38.2.0/23
202.38.64.0/19
202.38.96.0/19
202.38.64.0/18
202.38.135.0/24
202.38.140.0/23
202.38.146.0/23
202.38.184.0/21
202.38.192.0/18
202.112.0.0/16
202.113.0.0/20
202.113.16.0/20
202.113.32.0/19
202.113.64.0/18
202.113.128.0/18
202.113.192.0/19
202.113.224.0/20
202.113.240.0/20
202.114.0.0/19
202.114.32.0/19
202.114.64.0/18
202.114.128.0/17
202.115.0.0/19
202.115.128.0/17
202.116.0.0/19
202.116.32.0/20
202.116.48.0/20
202.116.64.0/19
202.116.96.0/19
202.116.128.0/17
202.117.0.0/18
202.117.64.0/18
202.117.128.0/17
202.118.0.0/19
202.118.32.0/19
202.118.64.0/18
202.118.128.0/17
202.119.0.0/19
202.119.32.0/19
202.119.64.0/20
202.119.80.0/20
202.119.96.0/19
202.119.128.0/17
202.120.0.0/18
202.120.64.0/18
202.120.128.0/17
202.121.0.0/16
202.127.216.0/21
202.106.125.0/24
202.106.126.0/24
202.112.0.0/13
202.120.0.0/15
202.127.224.0/19
202.179.240.0/20
202.192.0.0/13
202.200.0.0/14
202.204.0.0/14
202.192.0.0/12
203.91.120.0/21
210.25.0.0/16
210.26.0.0/15
210.28.0.0/14
210.32.0.0/14
210.36.0.0/14
210.40.0.0/13
211.64.0.0/14
211.68.0.0/15
211.70.0.0/15
211.80.0.0/16
211.81.0.0/16
211.82.0.0/16
211.83.0.0/16
211.84.0.0/15
211.86.0.0/15
218.192.0.0/16
218.193.0.0/16
218.194.0.0/16
218.195.0.0/16
218.196.0.0/14
219.216.0.0/15
219.218.0.0/15
219.220.0.0/16
219.221.0.0/16
219.222.0.0/15
219.224.0.0/15
219.226.0.0/16
219.227.0.0/16
219.228.0.0/15
219.230.0.0/15
210.32.0.0/12
211.64.0.0/13
211.80.0.0/13
218.192.0.0/13
219.216.0.0/13
219.224.0.0/13
219.242.0.0/15
219.244.0.0/14
222.16.0.0/15
222.18.0.0/15
222.20.0.0/15
222.22.0.0/16
222.23.0.0/16
222.24.0.0/15
222.26.0.0/15
222.28.0.0/14
222.192.0.0/14
222.196.0.0/15
222.198.0.0/16
222.199.0.0/16
222.200.0.0/14
222.204.0.0/15
222.206.0.0/15
222.16.0.0/12
222.192.0.0/12
223.2.0.0/15
223.128.0.0/15
@@ -0,0 +1,24 @@
45.253.60.0/22
103.1.20.0/22
103.1.168.0/22
103.89.184.0/21
103.89.192.0/19
103.89.224.0/21
103.222.184.0/22
111.31.196.0/24
111.31.239.0/24
117.124.237.0/24
117.126.0.0/16
163.61.202.0/23
182.51.114.0/23
182.51.116.0/23
182.51.118.0/24
182.51.122.0/23
182.51.124.0/24
202.143.100.0/22
211.89.230.0/23
211.146.0.0/19
211.146.32.0/21
211.148.160.0/19
211.156.128.0/19
221.129.0.0/16
File diff suppressed because it is too large. Load diff
@@ -1,55 +1,319 @@
27.0.160.0/22
36.128.0.0/10
36.192.0.0/16
36.206.0.0/16
36.212.0.0/15
36.214.0.0/16
36.221.0.0/17
39.128.0.0/10
43.239.172.0/22
42.62.0.0/17
42.157.198.0/23
43.193.65.0/24
43.196.232.0/22
43.226.236.0/24
43.228.116.0/22
43.231.32.0/22
43.239.172.0/23
43.240.72.0/23
43.241.49.0/24
43.241.50.0/24
43.243.12.0/22
43.243.128.0/22
43.247.88.0/22
43.248.96.0/21
43.248.116.0/22
43.248.128.0/20
43.248.184.0/21
43.248.196.0/22
43.248.200.0/21
43.251.244.0/22
45.121.68.0/22
45.121.72.0/22
45.121.172.0/22
45.121.176.0/22
45.122.96.0/21
45.123.152.0/22
45.124.36.0/22
45.125.24.0/22
45.253.72.0/22
61.14.240.0/22
61.14.244.0/22
43.254.88.0/22
43.255.84.0/24
43.255.228.0/22
45.113.20.0/22
45.113.200.0/22
45.117.8.0/22
45.119.64.0/22
45.120.100.0/22
45.125.25.0/24
45.248.8.0/22
45.248.204.0/22
45.250.28.0/22
45.250.40.0/22
45.251.96.0/22
52.82.164.0/22
52.82.184.0/23
52.82.188.0/23
52.82.190.0/24
54.222.46.0/23
54.222.48.0/21
54.222.65.0/24
54.222.89.0/24
54.222.96.0/23
54.222.100.0/22
54.222.104.0/21
54.222.112.0/22
54.222.116.0/23
58.67.192.0/19
58.83.0.0/17
58.83.160.0/23
58.83.176.0/23
58.83.192.0/18
59.151.0.0/19
59.151.64.0/18
59.191.0.0/17
61.232.0.0/14
61.237.0.0/16
69.235.184.0/21
101.36.128.0/17
101.125.130.0/24
101.144.0.0/12
101.251.192.0/21
101.251.200.0/22
101.251.224.0/20
101.251.240.0/21
101.251.248.0/22
103.1.10.0/23
103.3.128.0/22
103.8.220.0/22
103.19.232.0/22
103.20.112.0/22
103.21.176.0/22
103.35.104.0/22
103.61.156.0/22
103.61.160.0/22
103.62.24.0/22
103.62.204.0/22
103.62.208.0/22
103.37.47.0/24
103.37.72.0/24
103.40.12.0/22
103.40.192.0/23
103.45.162.0/23
103.46.170.0/23
103.52.176.0/23
103.53.124.0/22
103.59.116.0/22
103.60.164.0/22
103.78.228.0/22
103.82.224.0/22
103.83.72.0/22
103.84.170.0/23
103.85.84.0/22
103.85.172.0/22
103.85.177.0/24
103.85.178.0/23
103.87.180.0/22
103.95.68.0/22
103.101.180.0/22
103.110.132.0/22
103.130.160.0/23
103.143.228.0/23
103.152.29.0/24
103.192.0.0/22
103.192.144.0/22
103.193.140.0/22
103.203.164.0/22
103.205.108.0/22
103.205.116.0/22
103.222.196.0/22
103.205.252.0/22
103.208.12.0/22
103.213.96.0/22
103.215.36.0/22
103.216.4.0/22
103.216.152.0/22
103.219.24.0/21
103.219.32.0/21
103.220.60.0/22
103.229.212.0/22
103.230.236.0/23
103.232.166.0/23
103.233.52.0/22
103.238.132.0/22
103.239.152.0/22
103.239.204.0/22
103.239.244.0/23
103.239.247.0/24
103.252.36.0/22
103.253.232.0/22
106.3.144.0/21
106.13.252.0/22
106.75.0.0/17
110.42.0.0/21
110.42.8.0/22
110.42.12.0/23
110.42.14.0/24
110.56.0.0/13
110.96.0.0/16
110.100.0.0/16
110.112.0.0/15
110.114.0.0/16
110.115.128.0/17
110.116.0.0/16
110.120.0.0/16
110.172.200.0/21
110.199.0.0/16
110.203.0.0/23
110.211.0.0/16
110.218.0.0/15
110.236.0.0/15
111.0.0.0/10
111.132.0.0/16
111.148.0.0/16
111.149.0.0/24
111.223.12.0/22
112.0.0.0/10
113.18.0.0/16
114.112.80.0/20
114.118.104.0/21
114.118.112.0/20
115.180.0.0/17
116.85.16.0/22
116.242.224.0/19
117.48.0.0/18
117.48.64.0/19
117.48.144.0/20
117.48.193.0/24
117.48.194.0/24
117.48.219.0/24
117.48.232.0/22
117.50.0.0/17
117.128.0.0/10
118.26.197.0/24
118.26.198.0/23
118.26.200.0/21
118.26.224.0/20
118.30.0.0/16
118.193.127.0/24
118.195.0.0/17
118.204.0.0/17
119.44.205.0/24
119.161.183.0/24
120.132.0.0/19
120.132.96.0/20
120.132.116.0/24
120.132.120.0/21
120.132.128.0/19
120.132.176.0/20
120.132.192.0/23
120.132.208.0/20
120.132.224.0/19
120.133.0.0/19
120.133.48.0/20
120.133.96.0/19
120.133.224.0/22
120.192.0.0/10
175.176.188.0/22
121.46.16.0/20
121.46.192.0/22
121.70.0.0/17
121.255.0.0/16
122.14.192.0/18
122.70.0.0/15
122.72.3.0/24
122.72.16.0/24
122.72.38.0/24
122.72.112.0/24
122.94.0.0/16
123.58.0.0/20
123.61.0.0/16
123.64.0.0/15
123.66.0.0/16
123.77.0.0/16
123.88.0.0/15
123.90.0.0/16
123.99.192.0/20
123.103.14.0/24
124.201.0.0/17
124.243.192.0/18
124.250.16.0/20
124.250.61.0/24
124.250.120.0/23
124.250.128.0/17
124.251.0.0/19
124.251.56.0/22
124.251.96.0/23
124.251.126.0/23
124.251.128.0/17
125.254.128.0/19
125.254.160.0/21
125.254.176.0/21
125.254.184.0/22
125.254.188.0/23
125.254.190.0/24
139.159.32.0/20
139.220.128.0/17
140.179.224.0/19
140.210.16.0/20
140.210.64.0/19
157.15.104.0/23
157.20.246.0/23
157.66.164.0/23
160.19.76.0/23
160.202.212.0/22
161.207.18.0/23
167.189.0.0/16
180.188.16.0/21
182.50.112.0/20
182.157.0.0/16
182.175.244.0/22
183.84.4.0/22
183.192.0.0/10
192.140.209.0/24
192.140.210.0/23
192.140.212.0/22
202.46.224.0/22
202.123.120.0/22
202.141.176.0/20
203.76.240.0/22
203.130.32.0/22
203.135.104.0/21
203.196.0.0/22
203.196.4.0/24
203.212.12.0/22
211.98.0.0/16
211.99.117.0/24
211.99.118.0/23
211.99.120.0/23
211.99.160.0/22
211.99.188.0/22
211.99.216.0/24
211.103.0.0/17
211.136.0.0/14
211.140.0.0/15
211.142.0.0/17
211.142.128.0/17
211.143.0.0/16
218.200.0.0/14
218.204.0.0/15
218.206.0.0/15
211.136.0.0/13
211.144.159.0/24
211.151.4.0/23
211.151.32.0/19
211.151.64.0/18
211.151.128.0/17
211.152.0.0/19
211.155.236.0/24
218.98.96.0/23
218.98.98.0/24
218.98.100.0/24
218.98.111.0/24
218.98.112.0/23
218.200.0.0/13
218.245.0.0/21
219.83.160.0/21
221.122.0.0/19
221.122.32.0/20
221.122.128.0/17
221.123.128.0/18
221.130.0.0/15
221.172.0.0/16
221.174.0.0/16
221.176.0.0/13
223.64.0.0/11
223.96.0.0/12
223.112.0.0/14
223.116.0.0/15
223.120.128.0/17
223.121.128.0/17
223.122.0.0/15
223.124.0.0/14
222.35.0.0/16
222.42.115.0/24
222.44.0.0/15
222.49.128.0/17
222.50.0.0/16
222.59.128.0/17
223.64.0.0/10
223.160.0.0/20
223.160.16.0/21
223.160.112.0/20
223.160.128.0/22
223.160.134.0/23
223.160.136.0/21
223.160.144.0/20
223.160.160.0/19
223.160.192.0/19
223.160.224.0/21
223.160.232.0/22
223.160.236.0/23
223.161.194.0/23
223.161.196.0/22
223.161.200.0/21
223.161.208.0/20
223.161.224.0/19
223.223.192.0/20
@@ -1,16 +0,0 @@
36.192.0.0/11
43.247.240.0/22
61.232.0.0/14
61.236.0.0/15
101.144.0.0/12
103.3.128.0/22
110.96.0.0/11
110.192.0.0/11
115.180.0.0/15
118.204.0.0/14
120.90.0.0/15
122.64.0.0/11
123.64.0.0/11
211.98.0.0/16
221.172.0.0/14
222.32.0.0/11
File diff suppressed because it is too large. Load diff
@@ -1,290 +1,69 @@
1.94.0.0/15
14.1.24.0/22
14.103.0.0/16
14.196.0.0/15
42.196.0.0/14
43.242.56.0/22
43.242.144.0/22
43.243.144.0/22
43.243.148.0/22
43.247.200.0/22
43.247.204.0/22
43.247.208.0/22
43.247.224.0/22
43.250.16.0/22
43.250.20.0/22
45.121.240.0/22
45.121.244.0/22
45.121.248.0/22
45.121.252.0/22
45.122.4.0/22
45.122.8.0/22
45.122.12.0/22
45.122.16.0/22
45.122.20.0/22
45.122.24.0/22
45.122.28.0/22
45.122.32.0/22
45.122.36.0/22
45.122.40.0/22
45.122.192.0/22
45.122.196.0/22
45.122.200.0/22
45.122.204.0/22
45.122.208.0/22
45.122.212.0/22
45.122.216.0/22
45.123.28.0/22
45.123.32.0/22
45.123.36.0/22
45.123.76.0/22
45.123.80.0/22
45.123.84.0/22
45.123.88.0/22
45.123.204.0/22
45.123.212.0/22
45.123.224.0/22
45.123.228.0/22
45.123.232.0/22
45.123.236.0/22
45.123.240.0/22
45.123.244.0/22
45.123.248.0/22
45.123.252.0/22
45.124.0.0/22
45.124.100.0/22
45.252.152.0/22
45.252.200.0/22
45.252.204.0/22
45.252.208.0/22
45.252.212.0/22
45.252.216.0/22
45.252.220.0/22
45.252.224.0/22
45.253.0.0/22
45.253.4.0/22
45.253.8.0/22
45.253.12.0/22
45.253.16.0/22
45.253.20.0/22
45.253.28.0/22
45.253.36.0/22
45.253.40.0/22
45.253.56.0/22
45.253.76.0/22
45.253.80.0/22
45.253.84.0/22
45.253.92.0/22
45.254.28.0/22
45.254.56.0/22
45.254.96.0/22
45.254.132.0/22
45.254.152.0/22
45.254.180.0/22
45.254.200.0/22
45.254.204.0/22
45.254.208.0/22
45.254.212.0/22
45.254.216.0/22
45.254.220.0/22
45.254.224.0/22
45.254.228.0/22
49.220.0.0/14
59.152.16.0/22
59.152.20.0/22
59.152.24.0/22
59.152.28.0/22
59.152.64.0/22
59.152.68.0/22
59.152.72.0/22
59.152.76.0/22
59.152.112.0/22
59.152.116.0/22
60.194.0.0/15
60.206.0.0/15
61.14.212.0/22
61.14.216.0/22
61.14.220.0/22
101.38.0.0/15
101.40.0.0/15
101.104.0.0/14
101.130.0.0/15
103.23.56.0/22
103.24.184.0/22
103.38.0.0/22
103.38.228.0/22
103.38.232.0/22
103.41.148.0/22
103.41.152.0/22
103.62.72.0/22
103.62.76.0/22
103.62.80.0/22
103.62.84.0/22
103.62.96.0/22
103.62.100.0/22
103.62.104.0/22
103.62.108.0/22
103.62.112.0/22
103.62.116.0/22
103.62.120.0/22
103.62.124.0/22
103.62.128.0/22
103.62.132.0/22
103.63.64.0/22
103.63.68.0/22
103.63.72.0/22
103.63.76.0/22
103.63.80.0/22
103.63.84.0/22
103.63.88.0/22
103.63.140.0/22
103.63.144.0/22
103.63.152.0/22
103.63.196.0/22
103.63.200.0/22
103.63.204.0/22
103.63.208.0/22
103.192.48.0/22
103.192.52.0/22
103.192.56.0/22
103.192.84.0/22
103.192.88.0/22
103.192.92.0/22
103.192.96.0/22
103.192.100.0/22
103.192.104.0/22
103.192.108.0/22
103.192.112.0/22
103.192.216.0/22
103.202.152.0/22
103.202.156.0/22
103.202.160.0/22
103.202.164.0/22
103.202.168.0/22
103.202.172.0/22
103.202.176.0/22
103.202.180.0/22
103.202.184.0/22
103.202.188.0/22
103.202.192.0/22
103.202.196.0/22
103.202.200.0/21
103.202.228.0/22
103.202.236.0/22
103.202.240.0/22
103.202.244.0/22
103.202.248.0/22
103.202.252.0/22
103.203.0.0/22
103.203.4.0/22
103.203.8.0/22
103.203.12.0/22
103.203.16.0/22
103.203.20.0/22
103.203.24.0/22
103.203.28.0/22
103.203.32.0/22
103.203.104.0/22
103.203.108.0/22
103.203.112.0/22
103.203.116.0/22
103.203.120.0/22
103.203.124.0/22
103.203.128.0/22
103.204.88.0/22
103.204.112.0/22
103.204.148.0/22
103.204.152.0/22
103.221.88.0/22
103.221.132.0/22
103.221.156.0/22
103.221.180.0/22
103.221.184.0/22
103.221.188.0/22
103.221.192.0/22
103.221.196.0/22
103.222.0.0/22
103.222.4.0/22
103.222.8.0/22
103.222.12.0/22
103.222.16.0/22
103.222.24.0/22
103.222.28.0/22
103.222.36.0/22
103.222.44.0/22
103.222.48.0/22
103.222.56.0/22
103.222.60.0/22
103.222.64.0/22
103.222.68.0/22
103.222.72.0/22
103.222.76.0/22
103.222.80.0/22
103.222.84.0/22
103.222.88.0/22
103.222.92.0/22
103.222.96.0/22
103.222.100.0/22
103.222.104.0/22
103.222.108.0/22
103.222.200.0/22
103.222.204.0/22
103.222.208.0/22
103.222.212.0/22
103.238.20.0/22
103.238.24.0/22
103.238.40.0/22
115.31.72.0/22
115.31.76.0/22
115.47.0.0/16
115.182.0.0/16
115.183.0.0/16
115.187.0.0/22
115.187.4.0/22
115.187.8.0/22
115.187.12.0/22
115.190.0.0/15
116.199.128.0/19
117.58.0.0/17
117.120.64.0/18
118.28.0.0/15
124.14.0.0/15
124.192.0.0/15
124.200.0.0/13
124.254.0.0/18
175.188.0.0/14
180.88.0.0/14
180.235.112.0/22
202.4.252.0/22
202.160.156.0/22
202.168.136.0/22
202.168.140.0/22
203.78.156.0/22
203.82.112.0/22
203.82.116.0/22
203.82.120.0/22
203.82.124.0/22
203.82.224.0/22
203.82.228.0/22
203.82.232.0/22
203.82.236.0/22
203.86.64.0/20
203.114.80.0/22
203.114.84.0/22
203.114.88.0/22
203.114.92.0/22
203.207.92.0/22
203.207.112.0/20
203.207.192.0/21
203.207.208.0/20
211.101.0.0/18
211.103.128.0/17
211.164.0.0/14
218.249.0.0/16
219.90.68.0/22
219.90.72.0/22
219.90.76.0/22
219.238.0.0/15
220.112.0.0/14
223.208.0.0/14
223.255.0.0/17
60.195.252.0/22
103.155.76.0/23
103.235.144.0/24
113.48.48.0/20
113.48.224.0/20
113.49.16.0/20
113.50.0.0/20
113.50.32.0/24
113.50.48.0/20
113.50.64.0/20
115.182.0.0/19
115.182.32.0/22
115.182.40.0/21
115.182.48.0/20
115.182.64.0/18
115.182.128.0/19
115.182.160.0/20
115.182.192.0/22
115.182.200.0/21
115.182.208.0/20
115.182.224.0/20
118.64.0.0/21
118.64.248.0/21
118.65.0.0/21
118.66.184.0/24
118.66.224.0/20
118.144.64.0/21
118.144.72.0/22
118.144.77.0/24
118.144.78.0/24
118.144.80.0/20
118.145.0.0/19
118.244.192.0/22
118.244.196.0/24
118.244.202.0/23
118.244.205.0/24
118.244.206.0/23
118.244.208.0/20
118.244.224.0/20
121.39.255.0/24
122.49.16.0/20
122.49.32.0/20
123.196.112.0/20
124.14.5.0/24
124.14.8.0/24
124.14.12.0/23
124.14.15.0/24
124.14.22.0/24
124.202.128.0/19
210.74.0.0/22
210.79.224.0/19
211.147.4.0/22
211.154.160.0/22
211.154.168.0/21
211.155.128.0/19
211.161.101.0/24
211.161.102.0/23
211.161.192.0/22
211.161.203.0/24
211.161.209.0/24
211.161.221.0/24
211.165.0.0/16
211.166.0.0/16
218.241.16.0/22
218.241.24.0/22
218.241.152.0/21
219.234.80.0/20
219.238.232.0/21
219.239.92.0/22
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-17
View File
@@ -1,17 +0,0 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI for Nps
LUCI_DEPENDS:=+wget +npc
LUCI_PKGARCH:=all
PKG_VERSION:=1.1
PKG_RELEASE:=6
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -1,17 +0,0 @@
module("luci.controller.nps",package.seeall)
function index()
if not nixio.fs.access("/etc/config/nps") then
return
end
entry({"admin", "services", "nps"}, cbi("nps"), _("Nps Penetrate"), 100).dependent = true
entry({"admin", "services", "nps", "status"}, call("act_status")).leaf = true
end
function act_status()
local e = {}
e.running = luci.sys.call("pgrep npc > /dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@@ -1,54 +0,0 @@
m = Map("nps")
m.title = translate("Nps Penetrate")
m.description = translate("Nps is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.")
m:section(SimpleSection).template = "nps/nps_status"
s = m:section(TypedSection, "nps")
s.addremove = false
s.anonymous = true
enable = s:option(Flag, "enabled", translate("Enable"))
enable.rmempty = false
server = s:option(Value, "server_addr", translate("Server"))
server.description = translate("Must an IPv4 address")
server.datatype = "ipaddr"
server.optional = false
server.rmempty = false
port = s:option(Value, "server_port", translate("Port"))
port.datatype = "port"
port.default = "8024"
port.optional = false
port.rmempty = false
protocol = s:option(ListValue, "protocol", translate("Protocol Type"))
protocol:value("tcp", translate("TCP Protocol"))
protocol:value("kcp", translate("KCP Protocol"))
protocol.default = "tcp"
vkey = s:option(Value, "vkey", translate("vkey"))
vkey.optional = false
vkey.password = true
vkey.rmempty = false
compress = s:option(Flag, "compress", translate("Enable Compression"))
compress.description = translate("The contents will be compressed to speed up the traffic forwarding speed, but this will consume some additional cpu resources.")
compress.default = "1"
compress.rmempty = false
crypt = s:option(Flag, "crypt", translate("Enable Encryption"))
crypt.description = translate("Encrypted the communication between Npc and Nps, will effectively prevent the traffic intercepted.")
crypt.default = "1"
crypt.rmempty = false
log_level = s:option(ListValue, "log_level", translate("Log Level"))
log_level:value("0", "Emergency")
log_level:value("2", "Critical")
log_level:value("3", "Error")
log_level:value("4", "Warning")
log_level:value("7", "Debug")
log_level.default = "3"
return m
@@ -1,22 +0,0 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[nps]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('nps_status');
if (data && tb) {
if (data.running) {
var links = "<em><b><font color=green>Nps <%:RUNNING%></font></b></em>";
tb.innerHTML = links;
} else {
tb.innerHTML = "<em><b><font color=red>Nps <%:NOT RUNNING%></font></b></em>";
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="nps_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
@@ -1,47 +0,0 @@
msgid "Nps Penetrate"
msgstr "Nps 内网穿透"
msgid "Nps is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet."
msgstr "Nps 是一种快速反向代理,可帮助您将 NAT 或防火墙后面的本地服务器公开到 Internet。"
msgid "Must an IPv4 address"
msgstr "必须是 IPv4 地址"
msgid "vkey"
msgstr "密钥(vkey)"
msgid "Enable Compression"
msgstr "使用压缩传输"
msgid "Enable Encryption"
msgstr "使用加密传输"
msgid "The contents will be compressed to speed up the traffic forwarding speed, but this will consume some additional cpu resources."
msgstr "压缩传输内容,加快流量转发速度,会额外消耗 CPU 资源。"
msgid "Encrypted the communication between Npc and Nps, will effectively prevent the traffic intercepted."
msgstr "加密传输 npc 与 nps 之间的通信内容,会有效防止流量被拦截。"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Basic Setting"
msgstr "基本设置"
msgid "Protocol Type"
msgstr "协议类型"
msgid "Server"
msgstr "服务端地址"
msgid "TCP Protocol"
msgstr "TCP"
msgid "KCP Protocol"
msgstr "KCP"
msgid "Log Level"
msgstr "日志级别"
-1
View File
@@ -1 +0,0 @@
zh-cn
@@ -1,11 +0,0 @@
config nps
option enabled '0'
option server_addr '1.1.1.1'
option server_port '8024'
option protocol 'tcp'
option compress '1'
option crypt '1'
option vkey 'aaa'
option log_level '4'
@@ -1,68 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org
START=50
USE_PROCD=1
LOGFILE="/tmp/nps.log"
tmpconf="/tmp/etc/nps.conf"
nps_header() {
local enabled server_addr server_port protocol vkey compress crypt log_level
config_get enabled $1 enabled
config_get server_addr $1 server_addr
config_get server_port $1 server_port
config_get protocol $1 protocol
config_get vkey $1 vkey
config_get compress $1 compress
config_get crypt $1 crypt
config_get log_level $1 log_level
[ -f $tmpconf ] && rm $tmpconf
echo "[common]" >$tmpconf
echo "server_addr=${server_addr}:${server_port}" >>$tmpconf
echo "conn_type=${protocol}" >>$tmpconf
echo "vkey=${vkey}" >>$tmpconf
echo "auto_reconnection=true" >>$tmpconf
nps_write_bool compress $1
nps_write_bool crypt $1
Log_level=$log_level
Enabled=$enabled
}
nps_write_bool() {
local opt="$1"
local config="$2"
local val
config_get_bool val $config "$opt"
if [ "$val" -eq 0 ]; then
echo "${opt}=false" >> $tmpconf
else
echo "${opt}=true" >> $tmpconf
fi
}
start_service() {
config_load nps
config_foreach nps_header nps
if [ "$Enabled" = "1" ];then
logger -t FRPC 'Starting Nps service'
procd_open_instance
procd_set_param command /usr/bin/npc -config=$tmpconf -log_level=$Log_level -log_path=$LOGFILE
#procd_set_param file $tmpconf
procd_set_param respawn
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
fi
}
service_triggers() {
procd_add_reload_trigger "nps"
}
@@ -1,11 +0,0 @@
{
"luci-app-nps": {
"description": "Grant UCI access for luci-app-nps",
"read": {
"uci": [ "nps" ]
},
"write": {
"uci": [ "nps" ]
}
}
}
@@ -1,4 +0,0 @@
{
"config": "nps",
"init": "nps"
}
+2 -19
View File
@@ -7,28 +7,11 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-qbittorrent
PKG_VERSION:=1.0.0
PKG_RELEASE:=4
PKG_RELEASE:=5
LUCI_TITLE:=LuCI support for qBittorrent
LUCI_PKGARCH:=all
LUCI_DEPENDS:= \
+PACKAGE_luci-app-qbittorrent_static:qBittorrent-static \
+PACKAGE_luci-app-qbittorrent_dynamic:qbittorrent
define Package/$(PKG_NAME)/config
choice
prompt "Build Version Selection"
default PACKAGE_luci-app-qbittorrent_dynamic
config PACKAGE_luci-app-qbittorrent_static
bool "Static Build"
depends on arm||aarch64||x86_64
config PACKAGE_luci-app-qbittorrent_dynamic
bool "Dynamic Build"
endchoice
endef
LUCI_DEPENDS:=+qBittorrent-static
include $(TOPDIR)/feeds/luci/luci.mk
Loaded 100 of 1602 files, more files were not shown because too many files have changed in this diff. Show more