From 35a7d2bf4aad4e40bd3328dd8f8230b8557e93d7 Mon Sep 17 00:00:00 2001 From: kenzok8 Date: Mon, 16 Dec 2024 00:24:10 +0800 Subject: [PATCH] update 2024-12-16 00:24:10 --- UA2F/openwrt/Makefile | 2 +- luci-app-nekobox/htdocs/nekobox/mihomo.php | 244 +++++-- .../htdocs/nekobox/subscription.php | 244 +++++-- .../passwall/node_list/link_share_man.htm | 2 +- .../root/usr/share/passwall/app.sh | 78 +- .../usr/share/passwall/helper_dnsmasq.lua | 677 ++++++++++++++++++ .../root/usr/share/passwall/helper_dnsmasq.sh | 26 - .../usr/share/passwall/helper_dnsmasq_add.lua | 506 ------------- .../root/usr/share/passwall/iptables.sh | 55 +- .../root/usr/share/passwall/nftables.sh | 48 +- luci-app-ubuntu2/Makefile | 24 + .../luasrc/controller/ubuntu2.lua | 7 + luci-app-ubuntu2/luasrc/model/cbi/ubuntu2.lua | 63 ++ luci-app-ubuntu2/luasrc/model/ubuntu2.lua | 55 ++ .../luasrc/view/ubuntu2/status.htm | 31 + luci-app-ubuntu2/po/zh-cn/ubuntu2.po | 38 + luci-app-ubuntu2/po/zh_Hans | 1 + luci-app-ubuntu2/root/etc/config/ubuntu2 | 3 + .../root/usr/libexec/istorec/ubuntu2.sh | 87 +++ .../share/rpcd/acl.d/luci-app-ubuntu2.json | 11 + 20 files changed, 1507 insertions(+), 695 deletions(-) create mode 100644 luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua delete mode 100755 luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.sh delete mode 100644 luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua create mode 100644 luci-app-ubuntu2/Makefile create mode 100755 luci-app-ubuntu2/luasrc/controller/ubuntu2.lua create mode 100644 luci-app-ubuntu2/luasrc/model/cbi/ubuntu2.lua create mode 100644 luci-app-ubuntu2/luasrc/model/ubuntu2.lua create mode 100644 luci-app-ubuntu2/luasrc/view/ubuntu2/status.htm create mode 100644 luci-app-ubuntu2/po/zh-cn/ubuntu2.po create mode 120000 luci-app-ubuntu2/po/zh_Hans create mode 100644 luci-app-ubuntu2/root/etc/config/ubuntu2 create mode 100755 luci-app-ubuntu2/root/usr/libexec/istorec/ubuntu2.sh create mode 100644 luci-app-ubuntu2/root/usr/share/rpcd/acl.d/luci-app-ubuntu2.json diff --git a/UA2F/openwrt/Makefile b/UA2F/openwrt/Makefile index 77dbfbbb3..97898fc55 100644 --- a/UA2F/openwrt/Makefile +++ b/UA2F/openwrt/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=UA2F -PKG_VERSION:=4.9.3 +PKG_VERSION:=4.9.5 PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-only diff --git a/luci-app-nekobox/htdocs/nekobox/mihomo.php b/luci-app-nekobox/htdocs/nekobox/mihomo.php index 62983a291..62fb94b3b 100644 --- a/luci-app-nekobox/htdocs/nekobox/mihomo.php +++ b/luci-app-nekobox/htdocs/nekobox/mihomo.php @@ -459,32 +459,97 @@ $cron_result = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $templates = [ '1' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_NoAuto.ini?', - '2' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_MultiCountry.ini?', - '3' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', - '4' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Google.ini?', - '5' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_MultiMode.ini?', - '6' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Netflix.ini?', - '7' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/default_with_clash_adg.yml?', - '8' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Online_Full_Dream.ini?', - '9' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Mini_Dream.ini?', - '10' => 'https://raw.githubusercontent.com/justdoiting/ClashRule/main/GeneralClashRule.ini?', - '11' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-full.ini?', - '12' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine_Full.ini?', - '13' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_dler.ini?', - '14' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_backtocn.in?', - '15' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_AdblockPlus.ini?', - '16' => 'https://raw.githubusercontent.com/youshandefeiyang/webcdn/main/SONY.ini?', - '17' => 'https://raw.githubusercontent.com/cutethotw/ClashRule/main/GeneralClashRule.ini?', - '18' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini?', - '19' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoAuto.ini?', - '20' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_AdblockPlus.ini?', - '21' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini?', - '22' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/ehpo1_main.ini?', - '23' => 'https://github.com/UlinoyaPed/ShellClash/raw/master/rules/ShellClash.ini?', - '24' => 'https://unpkg.com/proxy-script/config/Clash/clash.ini?', - '25' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch.ini?', - '26' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch-Balance.ini?', - '27' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', + '2' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_AdblockPlus.ini?', + '3' => 'https://raw.githubusercontent.com/youshandefeiyang/webcdn/main/SONY.ini', + '4' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/default_with_clash_adg.yml?', + '5' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Online_Full_Dream.ini?', + '6' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Mini_Dream.ini?', + '7' => 'https://raw.githubusercontent.com/justdoiting/ClashRule/main/GeneralClashRule.ini?', + '8' => 'https://raw.githubusercontent.com/cutethotw/ClashRule/main/GeneralClashRule.ini?', + + '9' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini?', + '10' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoAuto.ini?', + '11' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_AdblockPlus.ini?', + '12' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_MultiCountry.ini?', + '13' => 'ttps://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoReject.ini?', + '14' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_NoAuto.ini?', + '15' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', + '16' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Google.ini?', + '17' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_MultiMode.ini?', + '18' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Netflix.ini?', + '19' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini.ini?', + '20' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_AdblockPlus.ini?', + '21' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_Fallback.ini?', + '22' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiCountry.ini?', + '23' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini?', + + '24' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG.ini?', + '25' => 'https://raw.githubusercontent.com/xiaoshenxian233/cool/rule/complex.ini?', + '26' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/special/phaors.ini?', + '27' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_Fallback.ini?', + '28' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_Urltest.ini?', + '29' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_NoAuto.ini?', + '30' => 'https://raw.githubusercontent.com/OoHHHHHHH/ini/master/config.ini?', + '31' => 'https://raw.githubusercontent.com/OoHHHHHHH/ini/master/cfw-tap.ini?', + '32' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-full.ini?', + '33' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-mini-gfw.ini?', + '34' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_new.ini?', + '35' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_backtocn.ini?', + '36' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_clash.ini?', + '37' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_dler.ini?', + '38' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/ehpo1_main.ini?', + '39' => 'https://raw.nameless13.com/api/public/dl/ROzQqi2S/white.ini?', + '40' => 'https://raw.nameless13.com/api/public/dl/ptLeiO3S/mayinggfw.ini?', + '41' => 'https://raw.nameless13.com/api/public/dl/FWSh3dXz/easy3.ini?', + '42' => 'https://raw.nameless13.com/api/public/dl/L_-vxO7I/youtube.ini?', + '43' => 'https://raw.nameless13.com/api/public/dl/zKF9vFbb/easy.ini?', + '44' => 'https://raw.nameless13.com/api/public/dl/E69bzCaE/easy2.ini?', + '45' => 'https://raw.nameless13.com/api/public/dl/XHr0miMg/ipip.ini?', + '46' => 'https://raw.nameless13.com/api/public/dl/BBnfb5lD/MAYINGVIP.ini?', + '47' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine.ini?', + '48' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine_Full.ini?', + '49' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/nzw9314_custom.ini?', + '50' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/maicoo-l_custom.ini?', + '51' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_platinum.ini?', + '52' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_gold.ini?', + '53' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_silver.ini?', + '54' => 'https://unpkg.com/proxy-script/config/Clash/clash.ini?', + '55' => 'https://github.com/UlinoyaPed/ShellClash/raw/master/rules/ShellClash.ini?', + + '56' => 'https://gist.github.com/jklolixxs/16964c46bad1821c70fa97109fd6faa2/raw/EXFLUX.ini?', + '57' => 'https://gist.github.com/jklolixxs/32d4e9a1a5d18a92beccf3be434f7966/raw/NaNoport.ini?', + '58' => 'https://gist.github.com/jklolixxs/dfbe0cf71ffc547557395c772836d9a8/raw/CordCloud.ini?', + '59' => 'https://gist.github.com/jklolixxs/e2b0105c8be6023f3941816509a4c453/raw/BigAirport.ini?', + '60' => 'https://gist.github.com/jklolixxs/9f6989137a2cfcc138c6da4bd4e4cbfc/raw/PaoLuCloud.ini?', + '61' => 'https://gist.github.com/jklolixxs/fccb74b6c0018b3ad7b9ed6d327035b3/raw/WaveCloud.ini?', + '62' => 'https://gist.github.com/jklolixxs/bfd5061dceeef85e84401482f5c92e42/raw/JiJi.ini?', + '63' => 'https://gist.github.com/jklolixxs/6ff6e7658033e9b535e24ade072cf374/raw/SJ.ini?', + '64' => 'https://gist.github.com/jklolixxs/24f4f58bb646ee2c625803eb916fe36d/raw/ImmTelecom.ini?', + '65' => 'https://gist.github.com/jklolixxs/b53d315cd1cede23af83322c26ce34ec/raw/AmyTelecom.ini?', + '66' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/convenience.ini?', + '67' => 'https://gist.github.com/jklolixxs/ff8ddbf2526cafa568d064006a7008e7/raw/Miaona.ini?', + '68' => 'https://gist.github.com/jklolixxs/df8fda1aa225db44e70c8ac0978a3da4/raw/Foo&Friends.ini?', + '69' => 'https://gist.github.com/jklolixxs/b1f91606165b1df82e5481b08fd02e00/raw/ABCloud.ini?', + '70' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/xianyu.ini?', + '71' => 'https://subweb.oss-cn-hongkong.aliyuncs.com/RemoteConfig/customized/convenience.ini?', + '72' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/SSRcloud.ini?', + '73' => 'https://raw.githubusercontent.com/Mazetsz/ACL4SSR/master/Clash/config/V2rayPro.ini?', + '74' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/V2Pro.ini?', + '75' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch.ini?', + '76' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch-Balance.ini?', + '77' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/maying.ini?', + '78' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/ytoo.ini?', + '79' => 'https://raw.nameless13.com/api/public/dl/M-We_Fn7/w8ves.ini?', + '80' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/nyancat.ini?', + '81' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/nexitally.ini?', + '82' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/socloud.ini?', + '83' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/ark.ini?', + '84' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/n3ro_optimized.ini?', + '85' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/scholar_optimized.ini?', + '86' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/flower.ini?', + + '88' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/special/netease.ini?', + '89' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/special/basic.ini?' ]; $emoji = isset($_POST['emoji']) ? $_POST['emoji'] === 'true' : true; @@ -635,33 +700,104 @@ function getSubscriptionUrlFromFile($file) {
@@ -722,6 +858,10 @@ function getSubscriptionUrlFromFile($file) {

注意:在线订阅转换存在隐私泄露风险

+

订阅转换由肥羊提供

+ + 点击访问 +
diff --git a/luci-app-nekobox/htdocs/nekobox/subscription.php b/luci-app-nekobox/htdocs/nekobox/subscription.php index fbeed8c1b..885c31601 100644 --- a/luci-app-nekobox/htdocs/nekobox/subscription.php +++ b/luci-app-nekobox/htdocs/nekobox/subscription.php @@ -199,32 +199,97 @@ function saveSubscriptionContentToYaml($url, $filename) { if ($_SERVER['REQUEST_METHOD'] === 'POST') { $templates = [ '1' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_NoAuto.ini?', - '2' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_MultiCountry.ini?', - '3' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', - '4' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Google.ini?', - '5' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_MultiMode.ini?', - '6' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Netflix.ini?', - '7' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/default_with_clash_adg.yml?', - '8' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Online_Full_Dream.ini?', - '9' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Mini_Dream.ini?', - '10' => 'https://raw.githubusercontent.com/justdoiting/ClashRule/main/GeneralClashRule.ini?', - '11' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-full.ini?', - '12' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine_Full.ini?', - '13' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_dler.ini?', - '14' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_backtocn.in?', - '15' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_AdblockPlus.ini?', - '16' => 'https://raw.githubusercontent.com/youshandefeiyang/webcdn/main/SONY.ini?', - '17' => 'https://raw.githubusercontent.com/cutethotw/ClashRule/main/GeneralClashRule.ini?', - '18' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini?', - '19' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoAuto.ini?', - '20' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_AdblockPlus.ini?', - '21' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini?', - '22' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/ehpo1_main.ini?', - '23' => 'https://github.com/UlinoyaPed/ShellClash/raw/master/rules/ShellClash.ini?', - '24' => 'https://unpkg.com/proxy-script/config/Clash/clash.ini?', - '25' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch.ini?', - '26' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch-Balance.ini?', - '27' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', + '2' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_AdblockPlus.ini?', + '3' => 'https://raw.githubusercontent.com/youshandefeiyang/webcdn/main/SONY.ini', + '4' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/default_with_clash_adg.yml?', + '5' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Online_Full_Dream.ini?', + '6' => 'https://raw.githubusercontent.com/WC-Dream/ACL4SSR/WD/Clash/config/ACL4SSR_Mini_Dream.ini?', + '7' => 'https://raw.githubusercontent.com/justdoiting/ClashRule/main/GeneralClashRule.ini?', + '8' => 'https://raw.githubusercontent.com/cutethotw/ClashRule/main/GeneralClashRule.ini?', + + '9' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini?', + '10' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoAuto.ini?', + '11' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_AdblockPlus.ini?', + '12' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_MultiCountry.ini?', + '13' => 'ttps://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_NoReject.ini?', + '14' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_NoAuto.ini?', + '15' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full.ini?', + '16' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Google.ini?', + '17' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_MultiMode.ini?', + '18' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Full_Netflix.ini?', + '19' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini.ini?', + '20' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_AdblockPlus.ini?', + '21' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_Fallback.ini?', + '22' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiCountry.ini?', + '23' => 'https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini?', + + '24' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG.ini?', + '25' => 'https://raw.githubusercontent.com/xiaoshenxian233/cool/rule/complex.ini?', + '26' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/special/phaors.ini?', + '27' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_Fallback.ini?', + '28' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_Urltest.ini?', + '29' => 'https://raw.githubusercontent.com/flyhigherpi/merlinclash_clash_related/master/Rule_config/ZHANG_Area_NoAuto.ini?', + '30' => 'https://raw.githubusercontent.com/OoHHHHHHH/ini/master/config.ini?', + '31' => 'https://raw.githubusercontent.com/OoHHHHHHH/ini/master/cfw-tap.ini?', + '32' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-full.ini?', + '33' => 'https://raw.githubusercontent.com/lhl77/sub-ini/main/tsutsu-mini-gfw.ini?', + '34' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_new.ini?', + '35' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/connershua_backtocn.ini?', + '36' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_clash.ini?', + '37' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/lhie1_dler.ini?', + '38' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/ehpo1_main.ini?', + '39' => 'https://raw.nameless13.com/api/public/dl/ROzQqi2S/white.ini?', + '40' => 'https://raw.nameless13.com/api/public/dl/ptLeiO3S/mayinggfw.ini?', + '41' => 'https://raw.nameless13.com/api/public/dl/FWSh3dXz/easy3.ini?', + '42' => 'https://raw.nameless13.com/api/public/dl/L_-vxO7I/youtube.ini?', + '43' => 'https://raw.nameless13.com/api/public/dl/zKF9vFbb/easy.ini?', + '44' => 'https://raw.nameless13.com/api/public/dl/E69bzCaE/easy2.ini?', + '45' => 'https://raw.nameless13.com/api/public/dl/XHr0miMg/ipip.ini?', + '46' => 'https://raw.nameless13.com/api/public/dl/BBnfb5lD/MAYINGVIP.ini?', + '47' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine.ini?', + '48' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Examine_Full.ini?', + '49' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/nzw9314_custom.ini?', + '50' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/maicoo-l_custom.ini?', + '51' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_platinum.ini?', + '52' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_gold.ini?', + '53' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/dlercloud_lige_silver.ini?', + '54' => 'https://unpkg.com/proxy-script/config/Clash/clash.ini?', + '55' => 'https://github.com/UlinoyaPed/ShellClash/raw/master/rules/ShellClash.ini?', + + '56' => 'https://gist.github.com/jklolixxs/16964c46bad1821c70fa97109fd6faa2/raw/EXFLUX.ini?', + '57' => 'https://gist.github.com/jklolixxs/32d4e9a1a5d18a92beccf3be434f7966/raw/NaNoport.ini?', + '58' => 'https://gist.github.com/jklolixxs/dfbe0cf71ffc547557395c772836d9a8/raw/CordCloud.ini?', + '59' => 'https://gist.github.com/jklolixxs/e2b0105c8be6023f3941816509a4c453/raw/BigAirport.ini?', + '60' => 'https://gist.github.com/jklolixxs/9f6989137a2cfcc138c6da4bd4e4cbfc/raw/PaoLuCloud.ini?', + '61' => 'https://gist.github.com/jklolixxs/fccb74b6c0018b3ad7b9ed6d327035b3/raw/WaveCloud.ini?', + '62' => 'https://gist.github.com/jklolixxs/bfd5061dceeef85e84401482f5c92e42/raw/JiJi.ini?', + '63' => 'https://gist.github.com/jklolixxs/6ff6e7658033e9b535e24ade072cf374/raw/SJ.ini?', + '64' => 'https://gist.github.com/jklolixxs/24f4f58bb646ee2c625803eb916fe36d/raw/ImmTelecom.ini?', + '65' => 'https://gist.github.com/jklolixxs/b53d315cd1cede23af83322c26ce34ec/raw/AmyTelecom.ini?', + '66' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/convenience.ini?', + '67' => 'https://gist.github.com/jklolixxs/ff8ddbf2526cafa568d064006a7008e7/raw/Miaona.ini?', + '68' => 'https://gist.github.com/jklolixxs/df8fda1aa225db44e70c8ac0978a3da4/raw/Foo&Friends.ini?', + '69' => 'https://gist.github.com/jklolixxs/b1f91606165b1df82e5481b08fd02e00/raw/ABCloud.ini?', + '70' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/xianyu.ini?', + '71' => 'https://subweb.oss-cn-hongkong.aliyuncs.com/RemoteConfig/customized/convenience.ini?', + '72' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/SSRcloud.ini?', + '73' => 'https://raw.githubusercontent.com/Mazetsz/ACL4SSR/master/Clash/config/V2rayPro.ini?', + '74' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/V2Pro.ini?', + '75' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch.ini?', + '76' => 'https://raw.githubusercontent.com/Mazeorz/airports/master/Clash/Stitch-Balance.ini?', + '77' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/maying.ini?', + '78' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/ytoo.ini?', + '79' => 'https://raw.nameless13.com/api/public/dl/M-We_Fn7/w8ves.ini?', + '80' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/nyancat.ini?', + '81' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/nexitally.ini?', + '82' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/socloud.ini?', + '83' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/customized/ark.ini?', + '84' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/n3ro_optimized.ini?', + '85' => 'https://gist.githubusercontent.com/tindy2013/1fa08640a9088ac8652dbd40c5d2715b/raw/scholar_optimized.ini?', + '86' => 'https://subweb.s3.fr-par.scw.cloud/RemoteConfig/customized/flower.ini?', + + '88' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/special/netease.ini?', + '89' => 'https://raw.githubusercontent.com/SleepyHeeead/subconverter-config/master/remote-config/special/basic.ini?' ]; $emoji = isset($_POST['emoji']) ? $_POST['emoji'] === 'true' : true; @@ -382,33 +447,104 @@ function downloadFileWithWget($url, $path) {
@@ -469,6 +605,10 @@ function downloadFileWithWget($url, $path) {

注意:在线订阅转换存在隐私泄露风险,需下载geoip/geosite使用

+

订阅转换由肥羊提供

+ + 点击访问 +
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm b/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm index 3dad68b73..6bcad56da 100644 --- a/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm +++ b/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm @@ -1101,7 +1101,7 @@ local api = require "luci.passwall.api" } } - opt.set(dom_prefix + 'encryption', queryParam.encryption); + opt.set(dom_prefix + 'encryption', queryParam.encryption || "none"); if (queryParam.security) { if (queryParam.security == "tls") { opt.set(dom_prefix + 'tls', true); diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index e9036dc8c..c022dc46f 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -1548,20 +1548,43 @@ start_dns() { [ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!" } - GLOBAL_DNSMASQ_PORT=$(get_new_port 11400) - local GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf - local GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d - source $APP_PATH/helper_dnsmasq.sh copy_instance listen_port=$GLOBAL_DNSMASQ_PORT dnsmasq_conf="${GLOBAL_DNSMASQ_CONF}" dnsmasq_conf_path="${GLOBAL_DNSMASQ_CONF_PATH}" - lua $APP_PATH/helper_dnsmasq_add.lua -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} \ - -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} \ - -TUN_DNS ${TUN_DNS} -REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ - -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ - -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ - -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} - awk '!seen[$0]++' ${GLOBAL_DNSMASQ_CONF} > ${TMP_PATH}/dnsmasq_default.tmp && mv ${TMP_PATH}/dnsmasq_default.tmp ${GLOBAL_DNSMASQ_CONF} - ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid - echo "${GLOBAL_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/var_redirect_dns_port - DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT} + local RUN_NEW_DNSMASQ=1 + if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then + #The old logic will be removed in the future. + #Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices. + [ "1" = "0" ] && { + DIRECT_DNSMASQ_PORT=$(get_new_port 11400) + DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf + lua $APP_PATH/helper_dnsmasq.lua copy_instance -LISTEN_PORT ${DIRECT_DNSMASQ_PORT} -DNSMASQ_CONF ${DIRECT_DNSMASQ_CONF} + ln_run "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid + echo "${DIRECT_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/direct_dnsmasq_port + } + + #Rewrite the default DNS service configuration + #Modify the default dnsmasq service + lua $APP_PATH/helper_dnsmasq.lua stretch + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \ + -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${TUN_DNS} \ + -REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ + -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ + -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + else + #Run a copy dnsmasq instance, DNS hijack for that need proxy devices. + GLOBAL_DNSMASQ_PORT=$(get_new_port 11400) + GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf + GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \ + -LISTEN_PORT ${GLOBAL_DNSMASQ_PORT} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${TUN_DNS} \ + -REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ + -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ + -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} + ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid + echo "${GLOBAL_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/var_redirect_dns_port + DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT} + fi } add_ip2route() { @@ -1752,14 +1775,12 @@ acl_app() { dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1)) local dnsmasq_conf=${acl_path}/dnsmasq.conf local dnsmasq_conf_path=${acl_path}/dnsmasq.d - source $APP_PATH/helper_dnsmasq.sh copy_instance listen_port=$dnsmasq_port dnsmasq_conf="${dnsmasq_conf}" dnsmasq_conf_path="${dnsmasq_conf_path}" - lua $APP_PATH/helper_dnsmasq_add.lua -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} \ - -DNSMASQ_CONF_FILE ${dnsmasq_conf} -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS \ + lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \ + -LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS \ -USE_DIRECT_LIST "${use_direct_list}" -USE_PROXY_LIST "${use_proxy_list}" -USE_BLOCK_LIST "${use_block_list}" -USE_GFW_LIST "${use_gfw_list}" -CHN_LIST "${chn_list}" \ -TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS 0 -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \ -TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \ -NO_LOGIC_LOG 1 - awk '!seen[$0]++' ${dnsmasq_conf} > ${TMP_PATH}/dnsmasq_${sid}.tmp && mv ${TMP_PATH}/dnsmasq_${sid}.tmp ${dnsmasq_conf} ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid echo "${dnsmasq_port}" > ${acl_path}/var_redirect_dns_port eval node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)=${dnsmasq_port} @@ -1930,6 +1951,9 @@ start() { start_dns } [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start + [ ! -s "${GLOBAL_ACL_PATH}/var_redirect_dns_port" ] && { + lua $APP_PATH/helper_dnsmasq.lua logic_restart -LOG 1 + } start_crontab echolog "运行完成!\n" } @@ -1946,6 +1970,9 @@ stop() { unset XRAY_LOCATION_ASSET stop_crontab source $APP_PATH/helper_smartdns.sh del + rm -rf $GLOBAL_DNSMASQ_CONF + rm -rf $GLOBAL_DNSMASQ_CONF_PATH + [ ! -s "${GLOBAL_ACL_PATH}/var_redirect_dns_port" ] && lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0 [ -s "$TMP_PATH/bridge_nf_ipt" ] && sysctl -w net.bridge.bridge-nf-call-iptables=$(cat $TMP_PATH/bridge_nf_ipt) >/dev/null 2>&1 [ -s "$TMP_PATH/bridge_nf_ip6t" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=$(cat $TMP_PATH/bridge_nf_ip6t) >/dev/null 2>&1 rm -rf ${TMP_PATH} @@ -2021,6 +2048,21 @@ DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}" IPT_APPEND_DNS=${LOCAL_DNS} +DNSMASQ_CONF_DIR=/tmp/dnsmasq.d +TMP_DNSMASQ_PATH=${DNSMASQ_CONF_DIR}/${CONFIG} +DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" +if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then + DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")" + if [ -n "$DNSMASQ_CONF_DIR" ]; then + DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/} + TMP_DNSMASQ_PATH=${DNSMASQ_CONF_DIR}/${CONFIG} + else + DNSMASQ_CONF_DIR="/tmp/dnsmasq.d" + fi +fi +GLOBAL_DNSMASQ_CONF=${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf +GLOBAL_DNSMASQ_CONF_PATH=${TMP_DNSMASQ_PATH} + DNS_QUERY_STRATEGY="UseIP" [ "$FILTER_PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIPv4" DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6} diff --git a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua new file mode 100644 index 000000000..2e54acc51 --- /dev/null +++ b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua @@ -0,0 +1,677 @@ +local api = require "luci.passwall.api" +local appname = "passwall" +local uci = api.uci +local sys = api.sys +local fs = api.fs +local datatypes = api.datatypes +local TMP = {} + +local function tinsert(table_name, val) + if table_name and type(table_name) == "table" then + if not TMP[table_name] then + TMP[table_name] = {} + end + if TMP[table_name][val] then + return false + end + table.insert(table_name, val) + TMP[table_name][val] = true + return true + end + return false +end + +local function backup_servers() + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS) + uci:commit(appname) + end +end + +local function restore_servers() + local dns_table = {} + local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server") + if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then + for k, v in ipairs(DNSMASQ_DNS) do + tinsert(dns_table, v) + end + end + local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers") + if OLD_SERVER and #OLD_SERVER > 0 then + for k, v in ipairs(OLD_SERVER) do + tinsert(dns_table, v) + end + uci:delete(appname, "@global[0]", "dnsmasq_servers") + uci:commit(appname) + end + if dns_table and #dns_table > 0 then + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + uci:commit("dhcp") + end +end + +function stretch() + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + local dnsmasq_noresolv = uci:get("dhcp", "@dnsmasq[0]", "noresolv") + local _flag + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if not v:find("/") then + _flag = true + end + end + end + if not _flag and dnsmasq_noresolv == "1" then + uci:delete("dhcp", "@dnsmasq[0]", "noresolv") + local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto" + local file = io.open(RESOLVFILE, "r") + if not file then + RESOLVFILE = "/tmp/resolv.conf.auto" + else + local size = file:seek("end") + file:close() + if size == 0 then + RESOLVFILE = "/tmp/resolv.conf.auto" + end + end + uci:set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE) + uci:commit("dhcp") + end +end + +function restart(var) + local LOG = var["-LOG"] + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + if LOG == "1" then + api.log("重启 dnsmasq 服务") + end +end + +function logic_restart(var) + local LOG = var["-LOG"] + local file = io.open(api.TMP_PATH .. "/default_DNS", "r") + if file then + backup_servers() + --sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1") + local dns_table = {} + local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server") + if dnsmasq_server and #dnsmasq_server > 0 then + for k, v in ipairs(dnsmasq_server) do + if v:find("/") then + tinsert(dns_table, v) + end + end + if dns_table and #dns_table > 0 then + uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table) + uci:commit("dhcp") + end + end + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + restore_servers() + else + sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1") + end + if LOG == "1" then + api.log("重启 dnsmasq 服务") + end +end + +function copy_instance(var) + local LISTEN_PORT = var["-LISTEN_PORT"] + local DNSMASQ_CONF = var["-DNSMASQ_CONF"] + local conf_lines = {} + local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')") + for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do + local filter + if line:find("passwall") then filter = true end + if line:find("ubus") then filter = true end + if line:find("dhcp") then filter = true end + if line:find("server") then filter = true end + if line:find("port") then filter = true end + if not filter then + tinsert(conf_lines, line) + end + end + tinsert(conf_lines, "port=" .. LISTEN_PORT) + if #conf_lines > 0 then + local conf_out = io.open(DNSMASQ_CONF, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:close() + end +end + +function add_rule(var) + local FLAG = var["-FLAG"] + local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"] + local DNSMASQ_CONF_FILE = var["-DNSMASQ_CONF_FILE"] + local LISTEN_PORT = var["-LISTEN_PORT"] + local DEFAULT_DNS = var["-DEFAULT_DNS"] + local LOCAL_DNS = var["-LOCAL_DNS"] + local TUN_DNS = var["-TUN_DNS"] + local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"] + local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"] + local CHINADNS_DNS = var["-CHINADNS_DNS"] + local TCP_NODE = var["-TCP_NODE"] + local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] + local USE_PROXY_LIST = var["-USE_PROXY_LIST"] + local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"] + local USE_GFW_LIST = var["-USE_GFW_LIST"] + local CHN_LIST = var["-CHN_LIST"] + local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"] + local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"] + local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] + local NFTFLAG = var["-NFTFLAG"] + local CACHE_PATH = api.CACHE_PATH + local CACHE_FLAG = "dnsmasq_" .. FLAG + local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG + local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt" + local USE_CHINADNS_NG = "0" + + local list1 = {} + local excluded_domain = {} + local excluded_domain_str = "!" + + local function log(...) + if NO_LOGIC_LOG == "1" then + return + end + api.log(...) + end + + local function check_dns(domain, dns) + if domain == "" or domain:find("#") then + return false + end + if not dns then + return + end + for k,v in ipairs(list1[domain].dns) do + if dns == v then + return true + end + end + return false + end + + local function check_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return false + end + if not ipset then + return + end + for k,v in ipairs(list1[domain].ipsets) do + if ipset == v then + return true + end + end + return false + end + + local function set_domain_address(domain, address) + if domain == "" or domain:find("#") then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + if not list1[domain].address then + list1[domain].address = address + end + end + + local function set_domain_dns(domain, dns) + if domain == "" or domain:find("#") then + return + end + if not dns then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(dns, '[^' .. "," .. ']+') do + if not check_dns(domain, line) then + table.insert(list1[domain].dns, line) + end + end + end + + local function set_domain_ipset(domain, ipset) + if domain == "" or domain:find("#") then + return + end + if not ipset then + return + end + if not list1[domain] then + list1[domain] = { + dns = {}, + ipsets = {} + } + end + for line in string.gmatch(ipset, '[^' .. "," .. ']+') do + if not check_ipset(domain, line) then + table.insert(list1[domain].ipsets, line) + end + end + end + + local function add_excluded_domain(domain) + if domain == "" or domain:find("#") then + return + end + table.insert(excluded_domain, domain) + excluded_domain_str = excluded_domain_str .. "|" .. domain + end + + local function check_excluded_domain(domain) + if domain == "" or domain:find("#") then + return false + end + for k,v in ipairs(excluded_domain) do + if domain:find(v) then + return true + end + end + return false + end + + local cache_text = "" + local nodes_address_md5 = sys.exec("echo -n $(uci show passwall | grep '\\.address') | md5sum") + local new_rules = sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)") + local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. USE_DEFAULT_DNS .. CHINADNS_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. nodes_address_md5 .. new_rules .. NFTFLAG + if fs.access(CACHE_TEXT_FILE) then + for line in io.lines(CACHE_TEXT_FILE) do + cache_text = line + end + end + + if cache_text ~= new_text then + api.remove(CACHE_DNS_PATH .. "*") + end + + local dnsmasq_default_dns + if USE_DEFAULT_DNS ~= "nil" then + if USE_DEFAULT_DNS == "direct" then + dnsmasq_default_dns = LOCAL_DNS + end + if USE_DEFAULT_DNS == "remote" then + dnsmasq_default_dns = TUN_DNS + end + if USE_DEFAULT_DNS == "remote" and CHN_LIST == "direct" then + dnsmasq_default_dns = TUN_DNS + end + end + + local only_global + if DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0" then + --没有启用中国列表和GFW列表时 + dnsmasq_default_dns = TUN_DNS + only_global = 1 + end + if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then + dnsmasq_default_dns = CHINADNS_DNS + USE_CHINADNS_NG = "1" + end + + local setflag_4= (NFTFLAG == "1") and "4#inet#passwall#" or "" + local setflag_6= (NFTFLAG == "1") and "6#inet#passwall#" or "" + + if not fs.access(CACHE_DNS_PATH) then + fs.mkdir(CACHE_DNS_PATH) + + --屏蔽列表 + if USE_CHINADNS_NG == "0" then + if USE_BLOCK_LIST == "1" then + for line in io.lines("/usr/share/passwall/rules/block_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + set_domain_address(line, "") + end + end + end + end + + local fwd_dns + local ipset_flag + local no_ipv6 + + --始终用国内DNS解析节点域名 + if true then + fwd_dns = LOCAL_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + else + uci:foreach(appname, "nodes", function(t) + local function process_address(address) + if address == "engage.cloudflareclient.com" then return end + if datatypes.hostname(address) then + set_domain_dns(address, fwd_dns) + set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6") + end + end + process_address(t.address) + process_address(t.download_address) + end) + log(string.format(" - 节点列表中的域名(vpslist):%s", fwd_dns or "默认")) + end + end + + --直连(白名单)列表 + if USE_DIRECT_LIST == "1" then + if fs.access("/usr/share/passwall/rules/direct_host") then + fwd_dns = LOCAL_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + --始终用国内DNS解析直连(白名单)列表 + for line in io.lines("/usr/share/passwall/rules/direct_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + add_excluded_domain(line) + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6") + end + end + log(string.format(" - 域名白名单(whitelist):%s", fwd_dns or "默认")) + end + end + end + + --代理(黑名单)列表 + if USE_PROXY_LIST == "1" then + if fs.access("/usr/share/passwall/rules/proxy_host") then + fwd_dns = TUN_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + --始终使用远程DNS解析代理(黑名单)列表 + for line in io.lines("/usr/share/passwall/rules/proxy_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + add_excluded_domain(line) + local ipset_flag = setflag_4 .. "passwall_blacklist," .. setflag_6 .. "passwall_blacklist6" + if NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + ipset_flag = setflag_4 .. "passwall_blacklist" + end + if REMOTE_FAKEDNS == "1" then + ipset_flag = nil + end + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, ipset_flag) + end + end + log(string.format(" - 代理域名表(blacklist):%s", fwd_dns or "默认")) + end + end + end + + --GFW列表 + if USE_GFW_LIST == "1" then + if fs.access("/usr/share/passwall/rules/gfwlist") then + fwd_dns = TUN_DNS + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local ipset_flag = setflag_4 .. "passwall_gfwlist," .. setflag_6 .. "passwall_gfwlist6" + if NO_PROXY_IPV6 == "1" then + ipset_flag = setflag_4 .. "passwall_gfwlist" + end + if REMOTE_FAKEDNS == "1" then + ipset_flag = nil + end + local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"') + for line in string.gmatch(gfwlist_str, "[^\r\n]+") do + if line ~= "" then + if NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + end + if dnsmasq_default_dns == fwd_dns then + fwd_dns = nil + else + set_domain_dns(line, fwd_dns) + end + set_domain_ipset(line, ipset_flag) + end + end + log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认")) + end + end + end + + --中国列表 + if CHN_LIST ~= "0" then + if fs.access("/usr/share/passwall/rules/chnlist") then + fwd_dns = nil + if CHN_LIST == "direct" then + fwd_dns = LOCAL_DNS + end + if CHN_LIST == "proxy" then + fwd_dns = TUN_DNS + end + if USE_CHINADNS_NG == "1" then + fwd_dns = nil + end + if fwd_dns then + local ipset_flag = setflag_4 .. "passwall_chnroute," .. setflag_6 .. "passwall_chnroute6" + if CHN_LIST == "proxy" then + if NO_PROXY_IPV6 == "1" then + ipset_flag = setflag_4 .. "passwall_chnroute" + end + if REMOTE_FAKEDNS == "1" then + ipset_flag = nil + end + end + local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"') + for line in string.gmatch(chnlist_str, "[^\r\n]+") do + if line ~= "" then + if CHN_LIST == "proxy" and NO_PROXY_IPV6 == "1" then + set_domain_address(line, "::") + end + if dnsmasq_default_dns == fwd_dns then + fwd_dns = nil + else + set_domain_dns(line, fwd_dns) + end + set_domain_ipset(line, ipset_flag) + end + end + log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认")) + end + end + end + + --分流规则 + if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_CHINADNS_NG == "0" then + local t = uci:get_all(appname, TCP_NODE) + local default_node_id = t["default_node"] or "_direct" + uci:foreach(appname, "shunt_rules", function(s) + local _node_id = t[s[".name"]] or "nil" + if _node_id ~= "nil" and _node_id ~= "_blackhole" then + if _node_id == "_default" then + _node_id = default_node_id + end + + fwd_dns = nil + ipset_flag = nil + no_ipv6 = nil + + if _node_id == "_direct" then + fwd_dns = LOCAL_DNS + if USE_DIRECT_LIST == "1" then + ipset_flag = setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6" + else + ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6" + end + else + fwd_dns = TUN_DNS + ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6" + if NO_PROXY_IPV6 == "1" then + ipset_flag = setflag_4 .. "passwall_shuntlist" + no_ipv6 = true + end + if not only_global then + if REMOTE_FAKEDNS == "1" then + ipset_flag = nil + end + end + end + + local domain_list = s.domain_list or "" + for line in string.gmatch(domain_list, "[^\r\n]+") do + if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then + if line:find("domain:") or line:find("full:") then + line = string.match(line, ":([^:]+)$") + end + line = api.get_std_domain(line) + add_excluded_domain(line) + + if no_ipv6 then + set_domain_address(line, "::") + end + set_domain_dns(line, fwd_dns) + set_domain_ipset(line, ipset_flag) + end + end + if _node_id ~= "_direct" then + log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认")) + end + end + end) + elseif only_global == 1 and NO_PROXY_IPV6 == "1" then + --节点:固定节点 + --代理模式:全局模式 + --过滤代理域名 IPv6:启用 + --禁止解析所有IPv6记录 + list1["#"] = { + dns = {}, + ipsets = {}, + address = "::" + } + end + + if list1 and next(list1) then + local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a") + local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a") + local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a") + local set_name = "ipset" + if NFTFLAG == "1" then + set_name = "nftset" + end + for key, value in pairs(list1) do + if value.address then + local domain = "." .. key + if key == "#" then + domain = key + end + address_out:write(string.format("address=/%s/%s", domain, value.address) .. "\n") + end + if value.dns and #value.dns > 0 then + for i, dns in ipairs(value.dns) do + server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n") + end + end + if value.ipsets and #value.ipsets > 0 then + local ipsets_str = "" + for i, ipset in ipairs(value.ipsets) do + ipsets_str = ipsets_str .. ipset .. "," + end + ipsets_str = ipsets_str:sub(1, #ipsets_str - 1) + ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n") + end + end + address_out:close() + server_out:close() + ipset_out:close() + end + + local f_out = io.open(CACHE_TEXT_FILE, "a") + f_out:write(new_text) + f_out:close() + end + + if USE_CHINADNS_NG == "0" then + if api.is_install("procd\\-ujail") then + fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) + else + api.remove(TMP_DNSMASQ_PATH) + fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) + end + end + + if DNSMASQ_CONF_FILE ~= "nil" then + local conf_lines = {} + if LISTEN_PORT then + --Copy dnsmasq instance + local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')") + for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do + local filter + if line:find("passwall") then filter = true end + if line:find("ubus") then filter = true end + if line:find("dhcp") then filter = true end + if line:find("server") then filter = true end + if line:find("port") then filter = true end + if not filter then + tinsert(conf_lines, line) + end + end + tinsert(conf_lines, "port=" .. LISTEN_PORT) + else + --Modify the default dnsmasq service + end + if USE_CHINADNS_NG == "0" then + tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH)) + end + if dnsmasq_default_dns then + for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do + tinsert(conf_lines, string.format("server=%s", s)) + end + tinsert(conf_lines, "all-servers") + tinsert(conf_lines, "no-poll") + tinsert(conf_lines, "no-resolv") + if USE_CHINADNS_NG == "0" then + log(string.format(" - 默认:%s", dnsmasq_default_dns)) + end + + if FLAG == "default" then + local f_out = io.open("/tmp/etc/passwall/default_DNS", "a") + f_out:write(DEFAULT_DNS) + f_out:close() + end + end + if #conf_lines > 0 then + local conf_out = io.open(DNSMASQ_CONF_FILE, "a") + conf_out:write(table.concat(conf_lines, "\n")) + conf_out:close() + end + end + + if USE_CHINADNS_NG == "0" then + log(" - PassWall必须依赖于Dnsmasq,如果你自行配置了错误的DNS流程,将会导致域名(直连/代理域名)分流失效!!!") + end +end + +_G.stretch = stretch +_G.restart = restart +_G.logic_restart = logic_restart +_G.copy_instance = copy_instance +_G.add_rule = add_rule + +if arg[1] then + local func =_G[arg[1]] + if func then + func(api.get_function_args(arg)) + end +end diff --git a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.sh b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.sh deleted file mode 100755 index 999c9ff5a..000000000 --- a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -copy_instance() { - local listen_port dnsmasq_conf - eval_set_val $@ - [ -s "/tmp/etc/dnsmasq.conf.${DEFAULT_DNSMASQ_CFGID}" ] && { - cp -r /tmp/etc/dnsmasq.conf.${DEFAULT_DNSMASQ_CFGID} $dnsmasq_conf - sed -i "/passwall/d" $dnsmasq_conf - sed -i "/ubus/d" $dnsmasq_conf - sed -i "/dhcp/d" $dnsmasq_conf - sed -i "/port=/d" $dnsmasq_conf - sed -i "/server=/d" $dnsmasq_conf - } - echo "port=${listen_port}" >> $dnsmasq_conf -} - -DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')" - -arg1=$1 -shift -case $arg1 in -copy_instance) - copy_instance $@ - ;; -*) ;; -esac diff --git a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua deleted file mode 100644 index 4aa982b57..000000000 --- a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua +++ /dev/null @@ -1,506 +0,0 @@ -require "luci.sys" -local api = require "luci.passwall.api" -local appname = "passwall" - -local var = api.get_args(arg) -local FLAG = var["-FLAG"] -local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"] -local DNSMASQ_CONF_FILE = var["-DNSMASQ_CONF_FILE"] -local DEFAULT_DNS = var["-DEFAULT_DNS"] -local LOCAL_DNS = var["-LOCAL_DNS"] -local TUN_DNS = var["-TUN_DNS"] -local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"] -local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"] -local CHINADNS_DNS = var["-CHINADNS_DNS"] -local TCP_NODE = var["-TCP_NODE"] -local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] -local USE_PROXY_LIST = var["-USE_PROXY_LIST"] -local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"] -local USE_GFW_LIST = var["-USE_GFW_LIST"] -local CHN_LIST = var["-CHN_LIST"] -local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"] -local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"] -local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] -local NFTFLAG = var["-NFTFLAG"] -local CACHE_PATH = api.CACHE_PATH -local CACHE_FLAG = "dnsmasq_" .. FLAG -local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG -local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt" -local USE_CHINADNS_NG = "0" - -local uci = api.uci -local sys = api.sys -local fs = api.fs -local datatypes = api.datatypes - -local list1 = {} -local excluded_domain = {} -local excluded_domain_str = "!" - -local function log(...) - if NO_LOGIC_LOG == "1" then - return - end - api.log(...) -end - -local function check_dns(domain, dns) - if domain == "" or domain:find("#") then - return false - end - if not dns then - return - end - for k,v in ipairs(list1[domain].dns) do - if dns == v then - return true - end - end - return false -end - -local function check_ipset(domain, ipset) - if domain == "" or domain:find("#") then - return false - end - if not ipset then - return - end - for k,v in ipairs(list1[domain].ipsets) do - if ipset == v then - return true - end - end - return false -end - -local function set_domain_address(domain, address) - if domain == "" or domain:find("#") then - return - end - if not list1[domain] then - list1[domain] = { - dns = {}, - ipsets = {} - } - end - if not list1[domain].address then - list1[domain].address = address - end -end - -local function set_domain_dns(domain, dns) - if domain == "" or domain:find("#") then - return - end - if not dns then - return - end - if not list1[domain] then - list1[domain] = { - dns = {}, - ipsets = {} - } - end - for line in string.gmatch(dns, '[^' .. "," .. ']+') do - if not check_dns(domain, line) then - table.insert(list1[domain].dns, line) - end - end -end - -local function set_domain_ipset(domain, ipset) - if domain == "" or domain:find("#") then - return - end - if not ipset then - return - end - if not list1[domain] then - list1[domain] = { - dns = {}, - ipsets = {} - } - end - for line in string.gmatch(ipset, '[^' .. "," .. ']+') do - if not check_ipset(domain, line) then - table.insert(list1[domain].ipsets, line) - end - end -end - -local function add_excluded_domain(domain) - if domain == "" or domain:find("#") then - return - end - table.insert(excluded_domain, domain) - excluded_domain_str = excluded_domain_str .. "|" .. domain -end - -local function check_excluded_domain(domain) - if domain == "" or domain:find("#") then - return false - end - for k,v in ipairs(excluded_domain) do - if domain:find(v) then - return true - end - end - return false -end - -local cache_text = "" -local nodes_address_md5 = luci.sys.exec("echo -n $(uci show passwall | grep '\\.address') | md5sum") -local new_rules = luci.sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)") -local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. USE_DEFAULT_DNS .. CHINADNS_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. nodes_address_md5 .. new_rules .. NFTFLAG -if fs.access(CACHE_TEXT_FILE) then - for line in io.lines(CACHE_TEXT_FILE) do - cache_text = line - end -end - -if cache_text ~= new_text then - api.remove(CACHE_DNS_PATH .. "*") -end - -local dnsmasq_default_dns -if USE_DEFAULT_DNS ~= "nil" then - if USE_DEFAULT_DNS == "direct" then - dnsmasq_default_dns = LOCAL_DNS - end - if USE_DEFAULT_DNS == "remote" then - dnsmasq_default_dns = TUN_DNS - end - if USE_DEFAULT_DNS == "remote" and CHN_LIST == "direct" then - dnsmasq_default_dns = TUN_DNS - end -end - -local only_global -if DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0" then - --没有启用中国列表和GFW列表时 - dnsmasq_default_dns = TUN_DNS - only_global = 1 -end -if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then - dnsmasq_default_dns = CHINADNS_DNS - USE_CHINADNS_NG = "1" -end - -local setflag_4= (NFTFLAG == "1") and "4#inet#passwall#" or "" -local setflag_6= (NFTFLAG == "1") and "6#inet#passwall#" or "" - -if not fs.access(CACHE_DNS_PATH) then - fs.mkdir(CACHE_DNS_PATH) - - --屏蔽列表 - if USE_CHINADNS_NG == "0" then - if USE_BLOCK_LIST == "1" then - for line in io.lines("/usr/share/passwall/rules/block_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - set_domain_address(line, "") - end - end - end - end - - local fwd_dns - local ipset_flag - local no_ipv6 - - --始终用国内DNS解析节点域名 - if true then - fwd_dns = LOCAL_DNS - if USE_CHINADNS_NG == "1" then - fwd_dns = nil - else - uci:foreach(appname, "nodes", function(t) - local function process_address(address) - if address == "engage.cloudflareclient.com" then return end - if datatypes.hostname(address) then - set_domain_dns(address, fwd_dns) - set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6") - end - end - process_address(t.address) - process_address(t.download_address) - end) - log(string.format(" - 节点列表中的域名(vpslist):%s", fwd_dns or "默认")) - end - end - - --直连(白名单)列表 - if USE_DIRECT_LIST == "1" then - if fs.access("/usr/share/passwall/rules/direct_host") then - fwd_dns = LOCAL_DNS - if USE_CHINADNS_NG == "1" then - fwd_dns = nil - end - if fwd_dns then - --始终用国内DNS解析直连(白名单)列表 - for line in io.lines("/usr/share/passwall/rules/direct_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - add_excluded_domain(line) - set_domain_dns(line, fwd_dns) - set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6") - end - end - log(string.format(" - 域名白名单(whitelist):%s", fwd_dns or "默认")) - end - end - end - - --代理(黑名单)列表 - if USE_PROXY_LIST == "1" then - if fs.access("/usr/share/passwall/rules/proxy_host") then - fwd_dns = TUN_DNS - if USE_CHINADNS_NG == "1" then - fwd_dns = nil - end - if fwd_dns then - --始终使用远程DNS解析代理(黑名单)列表 - for line in io.lines("/usr/share/passwall/rules/proxy_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - add_excluded_domain(line) - local ipset_flag = setflag_4 .. "passwall_blacklist," .. setflag_6 .. "passwall_blacklist6" - if NO_PROXY_IPV6 == "1" then - set_domain_address(line, "::") - ipset_flag = setflag_4 .. "passwall_blacklist" - end - if REMOTE_FAKEDNS == "1" then - ipset_flag = nil - end - set_domain_dns(line, fwd_dns) - set_domain_ipset(line, ipset_flag) - end - end - log(string.format(" - 代理域名表(blacklist):%s", fwd_dns or "默认")) - end - end - end - - --GFW列表 - if USE_GFW_LIST == "1" then - if fs.access("/usr/share/passwall/rules/gfwlist") then - fwd_dns = TUN_DNS - if USE_CHINADNS_NG == "1" then - fwd_dns = nil - end - if fwd_dns then - local ipset_flag = setflag_4 .. "passwall_gfwlist," .. setflag_6 .. "passwall_gfwlist6" - if NO_PROXY_IPV6 == "1" then - ipset_flag = setflag_4 .. "passwall_gfwlist" - end - if REMOTE_FAKEDNS == "1" then - ipset_flag = nil - end - local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"') - for line in string.gmatch(gfwlist_str, "[^\r\n]+") do - if line ~= "" then - if NO_PROXY_IPV6 == "1" then - set_domain_address(line, "::") - end - if dnsmasq_default_dns == fwd_dns then - fwd_dns = nil - else - set_domain_dns(line, fwd_dns) - end - set_domain_ipset(line, ipset_flag) - end - end - log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认")) - end - end - end - - --中国列表 - if CHN_LIST ~= "0" then - if fs.access("/usr/share/passwall/rules/chnlist") then - fwd_dns = nil - if CHN_LIST == "direct" then - fwd_dns = LOCAL_DNS - end - if CHN_LIST == "proxy" then - fwd_dns = TUN_DNS - end - if USE_CHINADNS_NG == "1" then - fwd_dns = nil - end - if fwd_dns then - local ipset_flag = setflag_4 .. "passwall_chnroute," .. setflag_6 .. "passwall_chnroute6" - if CHN_LIST == "proxy" then - if NO_PROXY_IPV6 == "1" then - ipset_flag = setflag_4 .. "passwall_chnroute" - end - if REMOTE_FAKEDNS == "1" then - ipset_flag = nil - end - end - local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"') - for line in string.gmatch(chnlist_str, "[^\r\n]+") do - if line ~= "" then - if CHN_LIST == "proxy" and NO_PROXY_IPV6 == "1" then - set_domain_address(line, "::") - end - if dnsmasq_default_dns == fwd_dns then - fwd_dns = nil - else - set_domain_dns(line, fwd_dns) - end - set_domain_ipset(line, ipset_flag) - end - end - log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认")) - end - end - end - - --分流规则 - if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_CHINADNS_NG == "0" then - local t = uci:get_all(appname, TCP_NODE) - local default_node_id = t["default_node"] or "_direct" - uci:foreach(appname, "shunt_rules", function(s) - local _node_id = t[s[".name"]] or "nil" - if _node_id ~= "nil" and _node_id ~= "_blackhole" then - if _node_id == "_default" then - _node_id = default_node_id - end - - fwd_dns = nil - ipset_flag = nil - no_ipv6 = nil - - if _node_id == "_direct" then - fwd_dns = LOCAL_DNS - if USE_DIRECT_LIST == "1" then - ipset_flag = setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6" - else - ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6" - end - else - fwd_dns = TUN_DNS - ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6" - if NO_PROXY_IPV6 == "1" then - ipset_flag = setflag_4 .. "passwall_shuntlist" - no_ipv6 = true - end - if not only_global then - if REMOTE_FAKEDNS == "1" then - ipset_flag = nil - end - end - end - - local domain_list = s.domain_list or "" - for line in string.gmatch(domain_list, "[^\r\n]+") do - if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then - if line:find("domain:") or line:find("full:") then - line = string.match(line, ":([^:]+)$") - end - line = api.get_std_domain(line) - add_excluded_domain(line) - - if no_ipv6 then - set_domain_address(line, "::") - end - set_domain_dns(line, fwd_dns) - set_domain_ipset(line, ipset_flag) - end - end - if _node_id ~= "_direct" then - log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认")) - end - end - end) - elseif only_global == 1 and NO_PROXY_IPV6 == "1" then - --节点:固定节点 - --代理模式:全局模式 - --过滤代理域名 IPv6:启用 - --禁止解析所有IPv6记录 - list1["#"] = { - dns = {}, - ipsets = {}, - address = "::" - } - end - - if list1 and next(list1) then - local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a") - local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a") - local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a") - local set_name = "ipset" - if NFTFLAG == "1" then - set_name = "nftset" - end - for key, value in pairs(list1) do - if value.address then - local domain = "." .. key - if key == "#" then - domain = key - end - address_out:write(string.format("address=/%s/%s", domain, value.address) .. "\n") - end - if value.dns and #value.dns > 0 then - for i, dns in ipairs(value.dns) do - server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n") - end - end - if value.ipsets and #value.ipsets > 0 then - local ipsets_str = "" - for i, ipset in ipairs(value.ipsets) do - ipsets_str = ipsets_str .. ipset .. "," - end - ipsets_str = ipsets_str:sub(1, #ipsets_str - 1) - ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n") - end - end - address_out:close() - server_out:close() - ipset_out:close() - end - - local f_out = io.open(CACHE_TEXT_FILE, "a") - f_out:write(new_text) - f_out:close() -end - -if USE_CHINADNS_NG == "0" then - if api.is_install("procd\\-ujail") then - fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) - else - api.remove(TMP_DNSMASQ_PATH) - fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH) - end -end - -if DNSMASQ_CONF_FILE ~= "nil" then - local conf_out = io.open(DNSMASQ_CONF_FILE, "a") - if USE_CHINADNS_NG == "0" then - conf_out:write(string.format("conf-dir=%s", TMP_DNSMASQ_PATH) .. "\n") - end - if dnsmasq_default_dns then - for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do - conf_out:write(string.format("server=%s", s) .. "\n") - end - conf_out:write("all-servers" .. "\n") - conf_out:write("no-poll" .. "\n") - conf_out:write("no-resolv" .. "\n") - conf_out:close() - if USE_CHINADNS_NG == "0" then - log(string.format(" - 默认:%s", dnsmasq_default_dns)) - end - - if FLAG == "default" then - local f_out = io.open("/tmp/etc/passwall/default_DNS", "a") - f_out:write(DEFAULT_DNS) - f_out:close() - end - end -end - -if USE_CHINADNS_NG == "0" then - log(" - PassWall必须依赖于Dnsmasq,如果你自行配置了错误的DNS流程,将会导致域名(直连/代理域名)分流失效!!!") -end diff --git a/luci-app-passwall/root/usr/share/passwall/iptables.sh b/luci-app-passwall/root/usr/share/passwall/iptables.sh index f59105cf8..06c9e3871 100755 --- a/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -2,6 +2,7 @@ DIR="$(cd "$(dirname "$0")" && pwd)" MY_PATH=$DIR/iptables.sh +IPSET_LOCALLIST="passwall_locallist" IPSET_LANLIST="passwall_lanlist" IPSET_VPSLIST="passwall_vpslist" IPSET_SHUNTLIST="passwall_shuntlist" @@ -11,6 +12,7 @@ IPSET_BLACKLIST="passwall_blacklist" IPSET_WHITELIST="passwall_whitelist" IPSET_BLOCKLIST="passwall_blocklist" +IPSET_LOCALLIST6="passwall_locallist6" IPSET_LANLIST6="passwall_lanlist6" IPSET_VPSLIST6="passwall_vpslist6" IPSET_SHUNTLIST6="passwall_shuntlist6" @@ -320,23 +322,22 @@ load_acl() { echolog " - ${msg}不代理所有 UDP 端口" fi } - + + local dns_redirect if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then - [ -n "$dns_redirect_port" ] && { - $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN - $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null - $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN - $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null - $ipt_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port - $ip6t_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null - $ipt_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port - $ip6t_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null - } + [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port} else - $ipt_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN - $ip6t_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null - $ipt_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN - $ip6t_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + [ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT} + fi + if [ -n "${dns_redirect}" ]; then + $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN + $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN + $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null + $ipt_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports ${dns_redirect} + $ip6t_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null + $ipt_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports ${dns_redirect} + $ip6t_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null fi [ -n "$tcp_port" -o -n "$udp_port" ] && { @@ -468,7 +469,7 @@ load_acl() { unset ipt_tmp ipt_j _ipt_source msg msg2 done unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface - unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp + unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect done } @@ -505,10 +506,11 @@ load_acl() { $ip6t_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN 2>/dev/null $ipt_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN $ip6t_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN 2>/dev/null - $ipt_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT - $ip6t_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null - $ipt_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT - $ip6t_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + #Only hijack when dest address is local IP + $ipt_n -A PSW_DNS $(comment "默认") -p udp $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A PSW_DNS $(comment "默认") -p udp $(dst $IPSET_LOCALLIST6) --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null + $ipt_n -A PSW_DNS $(comment "默认") -p tcp $(dst $IPSET_LOCALLIST) --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT + $ip6t_n -A PSW_DNS $(comment "默认") -p tcp $(dst $IPSET_LOCALLIST6) --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null } fi @@ -762,6 +764,7 @@ filter_node() { add_firewall_rule() { echolog "开始加载防火墙规则..." + ipset -! create $IPSET_LOCALLIST nethash maxelem 1048576 ipset -! create $IPSET_LANLIST nethash maxelem 1048576 ipset -! create $IPSET_VPSLIST nethash maxelem 1048576 ipset -! create $IPSET_SHUNTLIST nethash maxelem 1048576 timeout 172800 @@ -771,6 +774,7 @@ add_firewall_rule() { ipset -! create $IPSET_WHITELIST nethash maxelem 1048576 timeout 172800 ipset -! create $IPSET_BLOCKLIST nethash maxelem 1048576 timeout 172800 + ipset -! create $IPSET_LOCALLIST6 nethash family inet6 maxelem 1048576 ipset -! create $IPSET_LANLIST6 nethash family inet6 maxelem 1048576 ipset -! create $IPSET_VPSLIST6 nethash family inet6 maxelem 1048576 ipset -! create $IPSET_SHUNTLIST6 nethash family inet6 maxelem 1048576 timeout 172800 @@ -869,6 +873,14 @@ add_firewall_rule() { echolog " - [$?]解析并加入[分流节点] GeoIP 到 IPSET 完成" fi } + + ipset -! -R <<-EOF + $(ip address show | grep -w "inet" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/^/add $IPSET_LOCALLIST /") + EOF + + ipset -! -R <<-EOF + $(ip address show | grep -w "inet6" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/^/add $IPSET_LOCALLIST6 /") + EOF #局域网IP列表 ipset -! -R <<-EOF @@ -1118,6 +1130,7 @@ add_firewall_rule() { if ([ "$TCP_NODE" != "nil" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then [ -n "$DNS_REDIRECT_PORT" ] && { + #Only hijack when dest address is local IP $ipt_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT $ip6t_n -A OUTPUT $(comment "PSW") -p udp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null $ipt_n -A OUTPUT $(comment "PSW") -p tcp -o lo --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT @@ -1328,6 +1341,7 @@ del_firewall_rule() { ip -6 rule del fwmark 1 table 100 2>/dev/null ip -6 route del local ::/0 dev lo table 100 2>/dev/null + destroy_ipset $IPSET_LOCALLIST destroy_ipset $IPSET_LANLIST destroy_ipset $IPSET_VPSLIST destroy_ipset $IPSET_SHUNTLIST @@ -1337,6 +1351,7 @@ del_firewall_rule() { destroy_ipset $IPSET_BLOCKLIST destroy_ipset $IPSET_WHITELIST + destroy_ipset $IPSET_LOCALLIST6 destroy_ipset $IPSET_LANLIST6 destroy_ipset $IPSET_VPSLIST6 destroy_ipset $IPSET_SHUNTLIST6 diff --git a/luci-app-passwall/root/usr/share/passwall/nftables.sh b/luci-app-passwall/root/usr/share/passwall/nftables.sh index dd1717bed..76703bcc8 100755 --- a/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -3,6 +3,7 @@ DIR="$(cd "$(dirname "$0")" && pwd)" MY_PATH=$DIR/nftables.sh NFTABLE_NAME="inet passwall" +NFTSET_LOCALLIST="passwall_locallist" NFTSET_LANLIST="passwall_lanlist" NFTSET_VPSLIST="passwall_vpslist" NFTSET_SHUNTLIST="passwall_shuntlist" @@ -12,6 +13,7 @@ NFTSET_BLACKLIST="passwall_blacklist" NFTSET_WHITELIST="passwall_whitelist" NFTSET_BLOCKLIST="passwall_blocklist" +NFTSET_LOCALLIST6="passwall_locallist6" NFTSET_LANLIST6="passwall_lanlist6" NFTSET_VPSLIST6="passwall_vpslist6" NFTSET_SHUNTLIST6="passwall_shuntlist6" @@ -371,22 +373,21 @@ load_acl() { fi } + local dns_redirect if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then - [ -n "$dns_redirect_port" ] && { - nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" - } + [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port} else - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + [ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT} + fi + if [ -n "${dns_redirect}" ]; then + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp ${_ipt_source} udp dport 53 ip daddr @$NFTSET_LOCALLIST counter redirect to :${dns_redirect} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp ${_ipt_source} tcp dport 53 ip daddr @$NFTSET_LOCALLIST counter redirect to :${dns_redirect} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp ${_ipt_source} udp dport 53 ip6 daddr @$NFTSET_LOCALLIST6 counter redirect to :${dns_redirect} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 ip6 daddr @$NFTSET_LOCALLIST6 counter redirect to :${dns_redirect} comment \"$remarks\"" fi [ -n "$tcp_port" -o -n "$udp_port" ] && { @@ -524,7 +525,7 @@ load_acl() { unset nft_chain nft_j _ipt_source msg msg2 done unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface - unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp + unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect done } @@ -554,14 +555,15 @@ load_acl() { if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then [ -n "$DNS_REDIRECT_PORT" ] && { + #Only hijack when dest address is local IP nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp udp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp udp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp tcp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp tcp dport 53 counter return comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp udp dport 53 ip daddr @$NFTSET_LOCALLIST counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp tcp dport 53 ip daddr @$NFTSET_LOCALLIST counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp udp dport 53 ip daddr @$NFTSET_LOCALLIST6 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp tcp dport 53 ip daddr @$NFTSET_LOCALLIST6 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" } fi @@ -832,6 +834,7 @@ add_firewall_rule() { gen_nft_tables gen_nftset $NFTSET_VPSLIST ipv4_addr 0 0 gen_nftset $NFTSET_GFW ipv4_addr "2d" 0 + gen_nftset $NFTSET_LOCALLIST ipv4_addr 0 "-1" gen_nftset $NFTSET_LANLIST ipv4_addr 0 "-1" $(gen_lanlist) if [ -f $RULES_PATH/chnroute.nft ] && [ -s $RULES_PATH/chnroute.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute.nft) -ge 8 ]; then #echolog "使用缓存加载chnroute..." @@ -846,6 +849,7 @@ add_firewall_rule() { gen_nftset $NFTSET_VPSLIST6 ipv6_addr 0 0 gen_nftset $NFTSET_GFW6 ipv6_addr "2d" 0 + gen_nftset $NFTSET_LOCALLIST6 ipv6_addr 0 "-1" gen_nftset $NFTSET_LANLIST6 ipv6_addr 0 "-1" $(gen_lanlist_6) if [ -f $RULES_PATH/chnroute6.nft ] && [ -s $RULES_PATH/chnroute6.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute6.nft) -ge 8 ]; then #echolog "使用缓存加载chnroute6..." @@ -945,6 +949,9 @@ add_firewall_rule() { fi } + insert_nftset $NFTSET_LOCALLIST "-1" $(ip address show | grep -w "inet" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/ /\n/g") + insert_nftset $NFTSET_LOCALLIST6 "-1" $(ip address show | grep -w "inet6" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/ /\n/g") + # 忽略特殊IP段 local lan_ifname lan_ip lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) @@ -1185,6 +1192,7 @@ add_firewall_rule() { if ([ "$TCP_NODE" != "nil" ] && [ -n "${LOCALHOST_TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${LOCALHOST_UDP_PROXY_MODE}" ]); then [ -n "$DNS_REDIRECT_PORT" ] && { + #Only hijack when dest address is local IP nft "add rule $NFTABLE_NAME nat_output ip protocol udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\"" nft "add rule $NFTABLE_NAME nat_output ip protocol tcp oif lo tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\"" nft "add rule $NFTABLE_NAME nat_output meta l4proto udp oif lo udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"PSW\"" @@ -1393,6 +1401,7 @@ del_firewall_rule() { ip -6 rule del fwmark 1 table 100 2>/dev/null ip -6 route del local ::/0 dev lo table 100 2>/dev/null + destroy_nftset $NFTSET_LOCALLIST destroy_nftset $NFTSET_LANLIST destroy_nftset $NFTSET_VPSLIST destroy_nftset $NFTSET_SHUNTLIST @@ -1402,6 +1411,7 @@ del_firewall_rule() { destroy_nftset $NFTSET_BLOCKLIST destroy_nftset $NFTSET_WHITELIST + destroy_nftset $NFTSET_LOCALLIST6 destroy_nftset $NFTSET_LANLIST6 destroy_nftset $NFTSET_VPSLIST6 destroy_nftset $NFTSET_SHUNTLIST6 diff --git a/luci-app-ubuntu2/Makefile b/luci-app-ubuntu2/Makefile new file mode 100644 index 000000000..3a7c00de1 --- /dev/null +++ b/luci-app-ubuntu2/Makefile @@ -0,0 +1,24 @@ + + +include $(TOPDIR)/rules.mk + +PKG_VERSION:=1.0.3-20241215 +PKG_RELEASE:= + +LUCI_TITLE:=LuCI support for Ubuntu2 +LUCI_PKGARCH:=all +LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd + +define Package/luci-app-ubuntu2/conffiles +/etc/config/ubuntu2 +endef + +define Package/luci-app-ubuntu2/prerm +#!/bin/sh +/usr/libexec/istorec/ubuntu2.sh stop +exit 0 +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-ubuntu2/luasrc/controller/ubuntu2.lua b/luci-app-ubuntu2/luasrc/controller/ubuntu2.lua new file mode 100755 index 000000000..41eb7c3fb --- /dev/null +++ b/luci-app-ubuntu2/luasrc/controller/ubuntu2.lua @@ -0,0 +1,7 @@ + +module("luci.controller.ubuntu2", package.seeall) + +function index() + entry({"admin", "services", "ubuntu2"}, alias("admin", "services", "ubuntu2", "config"), _("Ubuntu2"), 30).dependent = true + entry({"admin", "services", "ubuntu2", "config"}, cbi("ubuntu2")) +end diff --git a/luci-app-ubuntu2/luasrc/model/cbi/ubuntu2.lua b/luci-app-ubuntu2/luasrc/model/cbi/ubuntu2.lua new file mode 100644 index 000000000..754d44358 --- /dev/null +++ b/luci-app-ubuntu2/luasrc/model/cbi/ubuntu2.lua @@ -0,0 +1,63 @@ +--[[ +LuCI - Lua Configuration Interface +]]-- + +local taskd = require "luci.model.tasks" +local docker = require "luci.docker" +local ubuntu2_model = require "luci.model.ubuntu2" +local m, s, o + +m = taskd.docker_map("ubuntu2", "ubuntu2", "/usr/libexec/istorec/ubuntu2.sh", + translate("Ubuntu2"), + translate("Ubuntu2 is a high-Performance ubuntu with web remote desktop. [username: abc, password is empty]") + .. translate("Official website:") .. ' https://www.kasmweb.com') + +local dk = docker.new({socket_path="/var/run/docker.sock"}) +local dockerd_running = dk:_ping().code == 200 +local docker_info = dockerd_running and dk:info().body or {} +local docker_aspace = 0 +if docker_info.DockerRootDir then + local statvfs = nixio.fs.statvfs(docker_info.DockerRootDir) + docker_aspace = statvfs and (statvfs.bavail * statvfs.bsize) or 0 +end + +s = m:section(SimpleSection, translate("Service Status"), translate("Ubuntu2 status:")) +s:append(Template("ubuntu2/status")) + +s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:")) +s.addremove=false +s.anonymous=true + +o = s:option(Value, "https_port", translate("HTTPS Port").."*") +o.default = "3001" +o.datatype = "port" + +o = s:option(Value, "image_name", translate("Image").."*") +o.rmempty = false +o.datatype = "string" +o:value("linkease/desktop-ubuntu2-standard-arm64:latest", "Standard-ARM64") +o:value("linkease/desktop-ubuntu2-standard-amd64:latest", "Standard-AMD64") +if "x86_64" == docker_info.Architecture then + o.default = "linkease/desktop-ubuntu2-standard-amd64:latest" +else + o.default = "linkease/desktop-ubuntu2-standard-arm64:latest" +end + +o = s:option(Value, "password", "PASSWORD") +o.password = true +o.datatype = "string" + +local blocks = ubuntu2_model.blocks() +local home = ubuntu2_model.home() + +o = s:option(Value, "config_path", translate("Config path").."*") +o.rmempty = false +o.datatype = "string" + +local paths, default_path = ubuntu2_model.find_paths(blocks, home, "Configs") +for _, val in pairs(paths) do + o:value(val, val) +end +o.default = default_path + +return m diff --git a/luci-app-ubuntu2/luasrc/model/ubuntu2.lua b/luci-app-ubuntu2/luasrc/model/ubuntu2.lua new file mode 100644 index 000000000..ca73ae84a --- /dev/null +++ b/luci-app-ubuntu2/luasrc/model/ubuntu2.lua @@ -0,0 +1,55 @@ +local util = require "luci.util" +local jsonc = require "luci.jsonc" + +local ubuntu2 = {} + +ubuntu2.blocks = function() + local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r") + local vals = {} + if f then + local ret = f:read("*all") + f:close() + local obj = jsonc.parse(ret) + for _, val in pairs(obj["blockdevices"]) do + local fsize = val["fssize"] + if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then + -- fsize > 1G + vals[#vals+1] = val["mountpoint"] + end + end + end + return vals +end + +ubuntu2.home = function() + local uci = require "luci.model.uci".cursor() + local home_dirs = {} + home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root") + home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs") + home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public") + home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads") + home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches") + return home_dirs +end + +ubuntu2.find_paths = function(blocks, home_dirs, path_name) + local default_path = '' + local configs = {} + + default_path = home_dirs[path_name] .. "/Ubuntu2" + if #blocks == 0 then + table.insert(configs, default_path) + else + for _, val in pairs(blocks) do + table.insert(configs, val .. "/" .. path_name .. "/Ubuntu2") + end + local without_conf_dir = "/root/" .. path_name .. "/Ubuntu2" + if default_path == without_conf_dir then + default_path = configs[1] + end + end + + return configs, default_path +end + +return ubuntu2 diff --git a/luci-app-ubuntu2/luasrc/view/ubuntu2/status.htm b/luci-app-ubuntu2/luasrc/view/ubuntu2/status.htm new file mode 100644 index 000000000..b28901828 --- /dev/null +++ b/luci-app-ubuntu2/luasrc/view/ubuntu2/status.htm @@ -0,0 +1,31 @@ +<% +local util = require "luci.util" +local container_status = util.trim(util.exec("/usr/libexec/istorec/ubuntu2.sh status")) +local container_install = (string.len(container_status) > 0) +local container_running = container_status == "running" +-%> +
+ +
+ <% if container_running then %> + + <% else %> + + <% end %> +
+
+<% +if container_running then + local port=util.trim(util.exec("/usr/libexec/istorec/ubuntu2.sh port")) + if port == "" then + port="8096" + end +-%> +
+ +
+ + +
+
+<% end %> diff --git a/luci-app-ubuntu2/po/zh-cn/ubuntu2.po b/luci-app-ubuntu2/po/zh-cn/ubuntu2.po new file mode 100644 index 000000000..5f03c0997 --- /dev/null +++ b/luci-app-ubuntu2/po/zh-cn/ubuntu2.po @@ -0,0 +1,38 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Official website:" +msgstr "官方网站:" + +msgid "Ubuntu2 is a high-Performance ubuntu with web remote desktop. [username: abc, password is empty]" +msgstr "Ubuntu2 是带浏览器桌面的高性能 Ubuntu. [用户名: abc, 密码为空]。" + +msgid "Config path" +msgstr "配置文件路径" + +msgid "HTTPS Port" +msgstr "HTTPS 端口" + +msgid "Service Status" +msgstr "服务状态" + +msgid "Ubuntu2 status:" +msgstr "Ubuntu2 的状态信息如下:" + +msgid "Setup" +msgstr "安装配置" + +msgid "The following parameters will only take effect during installation or upgrade:" +msgstr "以下参数只在安装或者升级时才会生效:" + +msgid "Status" +msgstr "状态" + +msgid "Ubuntu2 is running" +msgstr "Ubuntu2 运行中" + +msgid "Ubuntu2 is not running" +msgstr "Ubuntu2 未运行" + +msgid "Open Ubuntu2" +msgstr "打开 Ubuntu2" diff --git a/luci-app-ubuntu2/po/zh_Hans b/luci-app-ubuntu2/po/zh_Hans new file mode 120000 index 000000000..41451e4a1 --- /dev/null +++ b/luci-app-ubuntu2/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-ubuntu2/root/etc/config/ubuntu2 b/luci-app-ubuntu2/root/etc/config/ubuntu2 new file mode 100644 index 000000000..1ef2ec380 --- /dev/null +++ b/luci-app-ubuntu2/root/etc/config/ubuntu2 @@ -0,0 +1,3 @@ +config main + # option 'config_path' '' + diff --git a/luci-app-ubuntu2/root/usr/libexec/istorec/ubuntu2.sh b/luci-app-ubuntu2/root/usr/libexec/istorec/ubuntu2.sh new file mode 100755 index 000000000..574174700 --- /dev/null +++ b/luci-app-ubuntu2/root/usr/libexec/istorec/ubuntu2.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# Author Xiaobao(xiaobao@linkease.com) + +ACTION=${1} +shift 1 + +do_install() { + local https_port=`uci get ubuntu2.@main[0].https_port 2>/dev/null` + local image_name=`uci get ubuntu2.@main[0].image_name 2>/dev/null` + local config=`uci get ubuntu2.@main[0].config_path 2>/dev/null` + if [ -z ${IMAGE_NAME} ]; then + local arch=`uname -m` + if [ "$arch" = "x86_64" ]; then + IMAGE_NAME=linkease/desktop-ubuntu2-standard-amd64:latest + else + IMAGE_NAME=linkease/desktop-ubuntu2-standard-arm64:latest + fi + fi + + echo "docker pull ${image_name}" + docker pull ${image_name} + docker rm -f ubuntu2 + + if [ -z "$config" ]; then + echo "config path is empty!" + exit 1 + fi + + # not conflict with jellyfin + [ -z "$https_port" ] && https_port=3001 + + local cmd="docker run --restart=unless-stopped -d --user 0:0 -e START_DOCKER=false -v \"$config:/config\" \ + --privileged --device /dev/fuse --security-opt apparmor=unconfined --shm-size=512m \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --dns=172.17.0.1 \ + -p $https_port:3001 " + + if [ -d /dev/dri ]; then + cmd="$cmd\ + --device /dev/dri:/dev/dri " + fi + + local tz="`uci get system.@system[0].zonename | sed 's/ /_/g'`" + [ -z "$tz" ] || cmd="$cmd -e TZ=$tz" + + cmd="$cmd -v /mnt:/mnt" + mountpoint -q /mnt && cmd="$cmd:rslave" + cmd="$cmd --name ubuntu2 \"$image_name\"" + + echo "$cmd" + eval "$cmd" +} + +usage() { + echo "usage: $0 sub-command" + echo "where sub-command is one of:" + echo " install Install the ubuntu2" + echo " upgrade Upgrade the ubuntu2" + echo " rm/start/stop/restart Remove/Start/Stop/Restart the ubuntu2" + echo " status Ubuntu2 status" + echo " port Ubuntu2 port" +} + +case ${ACTION} in + "install") + do_install + ;; + "upgrade") + do_install + ;; + "rm") + docker rm -f ubuntu2 + ;; + "start" | "stop" | "restart") + docker ${ACTION} ubuntu2 + ;; + "status") + docker ps --all -f 'name=^/ubuntu2$' --format '{{.State}}' + ;; + "port") + docker ps --all -f 'name=^/ubuntu2$' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*->3001/tcp' | sed 's/0.0.0.0:\([0-9]*\)->.*/\1/' + ;; + *) + usage + exit 1 + ;; +esac diff --git a/luci-app-ubuntu2/root/usr/share/rpcd/acl.d/luci-app-ubuntu2.json b/luci-app-ubuntu2/root/usr/share/rpcd/acl.d/luci-app-ubuntu2.json new file mode 100644 index 000000000..9013d6b96 --- /dev/null +++ b/luci-app-ubuntu2/root/usr/share/rpcd/acl.d/luci-app-ubuntu2.json @@ -0,0 +1,11 @@ +{ + "luci-app-ubuntu2": { + "description": "Grant UCI access for luci-app-ubuntu2", + "read": { + "uci": [ "ubuntu2" ] + }, + "write": { + "uci": [ "ubuntu2" ] + } + } +}