Compare commits

...

2 Commits

Author SHA1 Message Date
gitea-action
9b84c4d395 dns2socks-rust: sync upstream
Signed-off-by: gitea-action <git@cooluc.com>
2025-05-10 21:31:44 +08:00
gitea-action
6541a21b62 luci-app-ssr-plus: sync upstream
last commit: 912720fc0b
2025-05-10 21:25:30 +08:00
24 changed files with 6493 additions and 2032 deletions

55
dns2socks-rust/Makefile Normal file
View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2017-2024 Zxlhhyccc <zxlhhyccc@gmail.com>
# Copyright (C) 2021-2024 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=dns2socks-rust
PKG_VERSION:=0.2.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/tun2proxy/dns2socks.git
PKG_SOURCE_DATE:=2025-03-19
PKG_SOURCE_VERSION:=5f5805bc5eba6530cec27f76860db1e19c1f2382
PKG_MIRROR_HASH:=f45ff9bff184f6eddbc444fc9a0611a47043e3b3422b7c33459bf7e03f37c37e
PKG_MAINTAINER:=Zxlhhyccc <zxlhhyccc@gmail.com>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=rust/host
PKG_BUILD_PARALLEL:=1
#RUST_PKG:=dns2socks
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk
define Package/dns2socks-rust
SECTION:=net
CATEGORY:=Network
SUBMENU:=IP Addresses and Names
TITLE:=DNS forwards to SOCKS5 server
URL:=https://github.com/tun2proxy/dns2socks.git
DEPENDS:=$$(RUST_ARCH_DEPENDS)
endef
define Package/dns2socks-rust/description
This is a DNS server that forwards DNS requests to a SOCKS5 server.
endef
define Build/Compile
$(call Build/Compile/Cargo,,--all-features)
endef
define Package/dns2socks-rust/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/target/$(RUSTC_TARGET_ARCH)/release/dns2socks $(1)/usr/bin/dns2socks-rust
endef
$(eval $(call BuildPackage,dns2socks-rust))

View File

@ -2,16 +2,21 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=189 PKG_VERSION:=189
PKG_RELEASE:=3 PKG_RELEASE:=7
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS_RUST \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_DNS2TCP \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_DNSPROXY \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
@ -29,23 +34,24 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/TUIC/ShadowTLS/Hysteria/Socks5/Tun LuCI interface LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Tuic/ShadowTLS/Hysteria/Socks5/Tun LuCI interface
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
LUCI_DEPENDS:= \ LUCI_DEPENDS:= \
+coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +ipset +kmod-ipt-nat \ +coreutils +coreutils-base64 +dns2tcp +dnsmasq-full +@PACKAGE_dnsmasq_full_ipset +ipset +kmod-ipt-nat +jq \
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \ +ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \
+tcping +resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \ +tcping +resolveip +shadowsocksr-libev-ssr-check +wget-ssl \
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-mbedtls:libustream-mbedtls \
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl:libustream-openssl \
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-wolfssl:libustream-wolfssl \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \ +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \ +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \ +PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \
+PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS:dns2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS_RUST:dns2socks-rust \
+PACKAGE_$(PKG_NAME)_INCLUDE_DNSPROXY:dnsproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:mosdns \
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \ +PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
+PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client:tuic-client \ +PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client:tuic-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS:shadow-tls \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS:shadow-tls \
+PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks:ipt2socks \ +PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \ +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \ +PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
@ -65,20 +71,7 @@ LUCI_DEPENDS:= \
define Package/$(PKG_NAME)/config define Package/$(PKG_NAME)/config
select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
choice
prompt "Uclient SSL Lib Selection"
default PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl
config PACKAGE_$(PKG_NAME)_INCLUDE_libustream-mbedtls
bool "libustream-mbedtls"
config PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl
bool "libustream-openssl"
config PACKAGE_$(PKG_NAME)_INCLUDE_PACKAGE_libustream-wolfssl
bool "libustream-wolfssl"
endchoice
choice choice
prompt "Shadowsocks Client Selection" prompt "Shadowsocks Client Selection"
@ -134,21 +127,37 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
bool "Include ChinaDNS-NG" bool "Include ChinaDNS-NG"
default n default n
config PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS
bool "Include DNS2socks"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS_RUST
bool "Include DNS2socks-Rust"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_DNSPROXY
bool "Include DNSproxy"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS
bool "Include MosDNS"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
bool "Include Hysteria" bool "Include Hysteria"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
default n default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client config PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client
bool "Include tuic-client" bool "Include Tuic-Client"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
select PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks select PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks
depends on aarch64||arm||i386||x86_64 depends on aarch64||arm||i386||x86_64
depends on !(TARGET_x86_geode||TARGET_x86_legacy) depends on !(TARGET_x86_geode||TARGET_x86_legacy)
default n default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS
bool "Include shadow-TLS" bool "Include Shadow-TLS"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
select PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client select PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client
depends on aarch64||arm||x86_64 depends on aarch64||arm||x86_64

View File

@ -96,7 +96,7 @@ function check_port()
local retstring = "<br /><br />" local retstring = "<br /><br />"
local s local s
local server_name = "" local server_name = ""
local uci = luci.model.uci.cursor() local uci = require "luci.model.uci".cursor()
local iret = 1 local iret = 1
uci:foreach("shadowsocksr", "servers", function(s) uci:foreach("shadowsocksr", "servers", function(s)
if s.alias then if s.alias then

View File

@ -1,9 +1,27 @@
local m, s, o local m, s, o
local uci = luci.model.uci.cursor() local uci = require "luci.model.uci".cursor()
-- 获取 LAN IP 地址
function lanip()
local lan_ip
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F '/' '{print $1}' | tr -d '\n'")
if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip address show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) | grep -w 'inet' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n'")
end
if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip addr show | grep -w 'inet' | grep 'global' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1 | tr -d '\n'")
end
return lan_ip
end
local lan_ip = lanip()
local server_table = {} local server_table = {}
local type_table = {} local type_table = {}
local function is_finded(e) local function is_finded(e)
return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end end
uci:foreach("shadowsocksr", "servers", function(s) uci:foreach("shadowsocksr", "servers", function(s)
@ -66,6 +84,7 @@ o:value("https://fastly.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/chin
o.default = "https://ispip.clang.cn/all_cn.txt" o.default = "https://ispip.clang.cn/all_cn.txt"
o = s:option(Flag, "netflix_enable", translate("Enable Netflix Mode")) o = s:option(Flag, "netflix_enable", translate("Enable Netflix Mode"))
o.description = translate("When disabled shunt mode, will same time stopped shunt service.")
o.rmempty = false o.rmempty = false
o = s:option(Value, "nfip_url", translate("nfip_url")) o = s:option(Value, "nfip_url", translate("nfip_url"))
@ -75,6 +94,134 @@ o.default = "https://fastly.jsdelivr.net/gh/QiuSimons/Netflix_IP/NF_only.txt"
o.description = translate("Customize Netflix IP Url") o.description = translate("Customize Netflix IP Url")
o:depends("netflix_enable", "1") o:depends("netflix_enable", "1")
o = s:option(ListValue, "shunt_dns_mode", translate("DNS Query Mode For Shunt Mode"))
if is_finded("dns2socks") then
o:value("1", translate("Use DNS2SOCKS query and cache"))
end
if is_finded("dns2socks-rust") then
o:value("2", translate("Use DNS2SOCKS-RUST query and cache"))
end
if is_finded("mosdns") then
o:value("3", translate("Use MosDNS query"))
end
if is_finded("dnsproxy") then
o:value("4", translate("Use DNSPROXY query and cache"))
end
if is_finded("chinadns-ng") then
o:value("5", translate("Use ChinaDNS-NG query and cache"))
end
o:depends("netflix_enable", "1")
o.default = 1
o = s:option(Value, "shunt_dnsserver", translate("Anti-pollution DNS Server For Shunt Mode"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
o:depends("shunt_dns_mode", "1")
o:depends("shunt_dns_mode", "2")
o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)")
o.datatype = "ip4addrport"
o = s:option(ListValue, "shunt_mosdns_dnsserver", translate("Anti-pollution DNS Server"))
o:value("tcp://8.8.4.4:53,tcp://8.8.8.8:53", translate("Google Public DNS"))
o:value("tcp://208.67.222.222:53,tcp://208.67.220.220:53", translate("OpenDNS"))
o:value("tcp://209.244.0.3:53,tcp://209.244.0.4:53", translate("Level 3 Public DNS-1 (209.244.0.3-4)"))
o:value("tcp://4.2.2.1:53,tcp://4.2.2.2:53", translate("Level 3 Public DNS-2 (4.2.2.1-2)"))
o:value("tcp://4.2.2.3:53,tcp://4.2.2.4:53", translate("Level 3 Public DNS-3 (4.2.2.3-4)"))
o:value("tcp://1.1.1.1:53,tcp://1.0.0.1:53", translate("Cloudflare DNS"))
o:depends("shunt_dns_mode", "3")
o.description = translate("Custom DNS Server for MosDNS")
o = s:option(Flag, "shunt_mosdns_ipv6", translate("Disable IPv6 In MosDNS Query Mode (Shunt Mode)"))
o:depends("shunt_dns_mode", "3")
o.rmempty = false
o.default = "0"
if is_finded("dnsproxy") then
o = s:option(ListValue, "shunt_parse_method", translate("Select DNS parse Mode"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("When use DNS list file, please ensure list file exists and is formatted correctly.") .. "</li>" ..
"<li>" .. translate("Tips: Dnsproxy DNS Parse List Path:") ..
" <a href='http://" .. lan_ip .. "/cgi-bin/luci/admin/services/shadowsocksr/control' target='_blank'>" ..
translate("Click here to view or manage the DNS list file") .. "</a>" .. "</li>" ..
"</ul>"
)
o:value("single_dns", translate("Set Single DNS"))
o:value("parse_file", translate("Use DNS List File"))
o:depends("shunt_dns_mode", "4")
o.rmempty = true
o.default = "single_dns"
o = s:option(Value, "dnsproxy_shunt_forward", translate("Anti-pollution DNS Server"))
o:value("sdns://AgUAAAAAAAAABzguOC40LjQgsKKKE4EwvtIbNjGjagI2607EdKSVHowYZtyvD9iPrkkHOC44LjQuNAovZG5zLXF1ZXJ5", translate("Google DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAAACC2vD25TAYM7EnyCH8Xw1-0g5OccnTsGH9vQUUH0njRtAxkbnMudHduaWMudHcKL2Rucy1xdWVyeQ", translate("TWNIC-101 DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAADzE4NS4yMjIuMjIyLjIyMiAOp5Svj-oV-Fz-65-8H2VKHLKJ0egmfEgrdPeAQlUFFA8xODUuMjIyLjIyMi4yMjIKL2Rucy1xdWVyeQ", translate("dns.sb DNSCrypt SDNS"))
o:value("sdns://AgMAAAAAAAAADTE0OS4xMTIuMTEyLjkgsBkgdEu7dsmrBT4B4Ht-BQ5HPSD3n3vqQ1-v5DydJC8SZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk", translate("Quad9 DNSCrypt SDNS"))
o:value("sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20", translate("AdGuard DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAABzEuMC4wLjGgENk8mGSlIfMGXMOlIlCcKvq7AVgcrZxtjon911-ep0cg63Ul-I8NlFj4GplQGb_TTLiczclX57DvMV8Q-JdjgRgSZG5zLmNsb3VkZmxhcmUuY29tCi9kbnMtcXVlcnk", translate("Cloudflare DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAADjEwNC4xNi4yNDkuMjQ5ABJjbG91ZGZsYXJlLWRucy5jb20KL2Rucy1xdWVyeQ", translate("cloudflare-dns.com DNSCrypt SDNS"))
o:depends("shunt_parse_method", "single_dns")
o.description = translate("Custom DNS Server (support: IP:Port or tls://IP:Port or https://IP/dns-query and other format).")
o = s:option(ListValue, "shunt_upstreams_logic_mode", translate("Defines the upstreams logic mode"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("Defines the upstreams logic mode, possible values: load_balance, parallel, fastest_addr (default: load_balance).") .. "</li>" .. "<li>" .. translate("When two or more DNS servers are deployed, enable this function.") .. "</li>" ..
"</ul>"
)
o:value("load_balance", translate("load_balance"))
o:value("parallel", translate("parallel"))
o:value("fastest_addr", translate("fastest_addr"))
o:depends("shunt_parse_method", "parse_file")
o.rmempty = true
o.default = "load_balance"
o = s:option(Flag, "shunt_dnsproxy_ipv6", translate("Disable IPv6 query mode"))
o.description = translate("When disabled, all AAAA requests are not resolved.")
o:depends("shunt_parse_method", "single_dns")
o:depends("shunt_parse_method", "parse_file")
o.rmempty = false
o.default = "1"
end
if is_finded("chinadns-ng") then
o = s:option(Value, "chinadns_ng_shunt_dnsserver", translate("Anti-pollution DNS Server For Shunt Mode"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
o:depends("shunt_dns_mode", "5")
o.description = translate(
"<ul>" ..
"<li>" .. translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)") .. "</li>" ..
"<li>" .. translate("Muitiple DNS server can saperate with ','") .. "</li>" ..
"</ul>"
)
o = s:option(ListValue, "chinadns_ng_shunt_proto", translate("ChinaDNS-NG shunt query protocol"))
o:value("none", translate("UDP/TCP upstream"))
o:value("tcp", translate("TCP upstream"))
o:value("udp", translate("UDP upstream"))
o:value("tls", translate("DoT upstream (Need use wolfssl version)"))
o:depends("shunt_dns_mode", "5")
end
o = s:option(Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses")) o = s:option(Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"))
o.rmempty = false o.rmempty = false
o.default = "1" o.default = "1"
@ -130,15 +277,15 @@ o.rmempty = false
o.cfgvalue = function(self, section) o.cfgvalue = function(self, section)
local enabled = m:get(section, "enabled") local enabled = m:get(section, "enabled")
if enabled == "0" then if enabled == "0" then
return m:get(section, "old_server") or "same" return m:get(section, "old_server")
end end
return Value.cfgvalue(self, section) or "same" -- Default to `same` when enabled return Value.cfgvalue(self, section)-- Default to `same` when enabled
end end
o.write = function(self, section, value) o.write = function(self, section, value)
local enabled = m:get(section, "enabled") local enabled = m:get(section, "enabled")
if enabled == "0" then if enabled == "0" then
local old_server = Value.cfgvalue(self, section) or "same" local old_server = Value.cfgvalue(self, section)
if old_server ~= "nil" then if old_server ~= "nil" then
m:set(section, "old_server", old_server) m:set(section, "old_server", old_server)
end end
@ -163,6 +310,7 @@ for key, server_type in pairs(type_table) do
o:depends("server", key) o:depends("server", key)
end end
end end
o:depends({server = "same", disable = true})
-- Socks User -- Socks User
o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when Socks5 Auth Mode is password valid, Mandatory.")) o = s:option(Value, "socks5_user", translate("Socks5 User"), translate("Only when Socks5 Auth Mode is password valid, Mandatory."))
@ -185,6 +333,7 @@ for key, server_type in pairs(type_table) do
o:depends("server", key) o:depends("server", key)
end end
end end
o:depends({server = "same", disable = true})
end end
-- Local Port -- Local Port
@ -248,6 +397,7 @@ o = s:option(ListValue, "type", translate("Type"))
o.default = "base64" o.default = "base64"
o:value("rand", "rand") o:value("rand", "rand")
o:value("str", "str") o:value("str", "str")
o:value("hex", "hex")
o:value("base64", "base64") o:value("base64", "base64")
o = s:option(Value, "domainStrategy", translate("Domain Strategy")) o = s:option(Value, "domainStrategy", translate("Domain Strategy"))

View File

@ -6,19 +6,29 @@ require "luci.sys"
require "luci.http" require "luci.http"
require "luci.jsonc" require "luci.jsonc"
require "luci.model.ipkg" require "luci.model.ipkg"
require "luci.model.uci"
local uci = require "luci.model.uci".cursor()
local m, s, o local m, s, o
local sid = arg[1] local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid") local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
-- 确保正确判断程序是否存在
local function is_finded(e) local function is_finded(e)
return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end end
local function is_installed(e) local function is_installed(e)
return luci.model.ipkg.installed(e) return luci.model.ipkg.installed(e)
end end
local has_ss_rust = is_finded("sslocal") or is_finded("ssserver")
local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local")
-- 读取当前存储的 ss_type
local ss_type = uci:get_first("shadowsocksr", "server_subscribe", "ss_type")
local server_table = {} local server_table = {}
local encrypt_methods = { local encrypt_methods = {
-- ssr -- ssr
@ -79,7 +89,7 @@ local encrypt_methods_ss = {
"camellia-256-cfb", "camellia-256-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf" ]] "chacha20-ietf" ]]--
} }
local protocol = { local protocol = {
@ -134,7 +144,7 @@ s = m:section(NamedSection, sid, "servers")
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN URL") o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN/HYSTERIA2 URL")
o.rawhtml = true o.rawhtml = true
o.template = "shadowsocksr/ssrurl" o.template = "shadowsocksr/ssrurl"
o.value = sid o.value = sid
@ -146,11 +156,8 @@ end
if is_finded("ssr-redir") then if is_finded("ssr-redir") then
o:value("ssr", translate("ShadowsocksR")) o:value("ssr", translate("ShadowsocksR"))
end end
if is_finded("ss-local") or is_finded("ss-redir") then if has_ss_rust or has_ss_libev then
o:value("ss", translate("Shadowsocks-libev Version")) o:value("ss", translate("ShadowSocks"))
end
if is_finded("sslocal") or is_finded("ssmanager") then
o:value("ss", translate("Shadowsocks-rust Version"))
end end
if is_finded("trojan") then if is_finded("trojan") then
o:value("trojan", translate("Trojan")) o:value("trojan", translate("Trojan"))
@ -159,7 +166,7 @@ if is_finded("naive") then
o:value("naiveproxy", translate("NaiveProxy")) o:value("naiveproxy", translate("NaiveProxy"))
end end
if is_finded("hysteria") then if is_finded("hysteria") then
o:value("hysteria", translate("Hysteria")) o:value("hysteria2", translate("Hysteria2"))
end end
if is_finded("tuic-client") then if is_finded("tuic-client") then
o:value("tuic", translate("TUIC")) o:value("tuic", translate("TUIC"))
@ -187,11 +194,51 @@ end
o:depends("type", "tun") o:depends("type", "tun")
o.description = translate("Redirect traffic to this network interface") o.description = translate("Redirect traffic to this network interface")
-- 新增一个选择框,用于选择 Shadowsocks 版本
o = s:option(ListValue, "has_ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translate("ShadowSocks Node Use Version")))
o.description = translate("Selection ShadowSocks Node Use Version.")
-- 设置默认 Shadowsocks 版本
-- 动态添加选项
if has_ss_rust then
o:value("ss-rust", translate("ShadowSocks-rust Version"))
end
if has_ss_libev then
o:value("ss-libev", translate("ShadowSocks-libev Version"))
end
-- 设置默认值
if ss_type == "ss-rust" then
o.default = "ss-rust"
elseif ss_type == "ss-libev" then
o.default = "ss-libev"
end
o:depends("type", "ss")
o.write = function(self, section, value)
-- 更新 Shadowsocks 节点的 has_ss_type
uci:foreach("shadowsocksr", "servers", function(s)
local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型
if node_type == "ss" then -- 仅修改 Shadowsocks 节点
local old_value = uci:get("shadowsocksr", s[".name"], "has_ss_type")
if old_value ~= value then
uci:set("shadowsocksr", s[".name"], "has_ss_type", value)
end
end
end)
-- 更新 server_subscribe 的 ss_type
local old_value = uci:get("shadowsocksr", "server_subscribe", "ss_type")
if old_value ~= value then
uci:set("shadowsocksr", "@server_subscribe[0]", "ss_type", value)
end
-- 更新当前 section 的 has_ss_type
Value.write(self, section, value)
end
o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol")) o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol"))
o:value("vless", translate("VLESS")) o:value("vless", translate("VLESS"))
o:value("vmess", translate("VMess")) o:value("vmess", translate("VMess"))
o:value("trojan", translate("Trojan")) o:value("trojan", translate("Trojan"))
o:value("shadowsocks", translate("Shadowsocks")) o:value("shadowsocks", translate("ShadowSocks"))
if is_finded("xray") then if is_finded("xray") then
o:value("wireguard", translate("WireGuard")) o:value("wireguard", translate("WireGuard"))
end end
@ -207,7 +254,7 @@ o:depends("type", "ss")
o:depends("type", "v2ray") o:depends("type", "v2ray")
o:depends("type", "trojan") o:depends("type", "trojan")
o:depends("type", "naiveproxy") o:depends("type", "naiveproxy")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o:depends("type", "tuic") o:depends("type", "tuic")
o:depends("type", "shadowtls") o:depends("type", "shadowtls")
o:depends("type", "socks5") o:depends("type", "socks5")
@ -220,7 +267,7 @@ o:depends("type", "ss")
o:depends("type", "v2ray") o:depends("type", "v2ray")
o:depends("type", "trojan") o:depends("type", "trojan")
o:depends("type", "naiveproxy") o:depends("type", "naiveproxy")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o:depends("type", "tuic") o:depends("type", "tuic")
o:depends("type", "shadowtls") o:depends("type", "shadowtls")
o:depends("type", "socks5") o:depends("type", "socks5")
@ -262,7 +309,12 @@ o:depends("type", "ssr")
o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method")) o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ss) do for _, v in ipairs(encrypt_methods_ss) do
o:value(v) if v == "none" then
o.default = "none"
o:value("none", translate("none"))
else
o:value(v, translate(v))
end
end end
o.rmempty = true o.rmempty = true
o:depends("type", "ss") o:depends("type", "ss")
@ -279,8 +331,14 @@ o.rmempty = true
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
o.default = "1" o.default = "1"
-- [[ Enable Shadowsocks Plugin ]]--
o = s:option(Flag, "enable_plugin", translate("Enable Plugin"))
o.rmempty = true
o:depends("type", "ss")
o.default = "0"
-- Shadowsocks Plugin -- Shadowsocks Plugin
o = s:option(Value, "plugin", translate("Obfs")) o = s:option(ListValue, "plugin", translate("Obfs"))
o:value("none", translate("None")) o:value("none", translate("None"))
if is_finded("obfs-local") then if is_finded("obfs-local") then
o:value("obfs-local", translate("obfs-local")) o:value("obfs-local", translate("obfs-local"))
@ -291,12 +349,17 @@ end
if is_finded("xray-plugin") then if is_finded("xray-plugin") then
o:value("xray-plugin", translate("xray-plugin")) o:value("xray-plugin", translate("xray-plugin"))
end end
o:value("custom", translate("Custom"))
o.rmempty = true o.rmempty = true
o:depends("type", "ss") o:depends({enable_plugin = true})
o = s:option(Value, "custom_plugin", translate("Custom Plugin Path"))
o.placeholder = "/path/to/custom-plugin"
o:depends({plugin = "custom"})
o = s:option(Value, "plugin_opts", translate("Plugin Opts")) o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
o.rmempty = true o.rmempty = true
o:depends("type", "ss") o:depends({enable_plugin = true})
o = s:option(ListValue, "protocol", translate("Protocol")) o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do for _, v in ipairs(protocol) do
@ -321,100 +384,101 @@ o:depends("type", "ssr")
-- [[ Hysteria2 ]]-- -- [[ Hysteria2 ]]--
o = s:option(Value, "hy2_auth", translate("Users Authentication")) o = s:option(Value, "hy2_auth", translate("Users Authentication"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = false o.rmempty = false
o = s:option(Flag, "flag_port_hopping", translate("Enable Port Hopping")) o = s:option(Flag, "flag_port_hopping", translate("Enable Port Hopping"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o = s:option(Value, "port_range", translate("Port Range")) o = s:option(Value, "port_range", translate("Port hopping range"))
o:depends({type = "hysteria", flag_port_hopping = true}) o.description = translate("Format as 10000:20000 or 10000-20000 Multiple groups are separated by commas (,).")
o.datatype = "portrange" o:depends({type = "hysteria2", flag_port_hopping = true})
--o.datatype = "portrange"
o.rmempty = true o.rmempty = true
o = s:option(Flag, "flag_transport", translate("Enable Transport Protocol Settings")) o = s:option(Flag, "flag_transport", translate("Enable Transport Protocol Settings"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o = s:option(ListValue, "transport_protocol", translate("Transport Protocol")) o = s:option(ListValue, "transport_protocol", translate("Transport Protocol"))
o:depends({type = "hysteria", flag_transport = true}) o:depends({type = "hysteria2", flag_transport = true})
o:value("udp", translate("UDP")) o:value("udp", translate("UDP"))
o.default = "udp" o.default = "udp"
o.rmempty = true o.rmempty = true
o = s:option(Value, "hopinterval", translate("Port Hopping Interval(Unit:Second)")) o = s:option(Value, "hopinterval", translate("Port Hopping Interval(Unit:Second)"))
o:depends({type = "hysteria", flag_transport = true, flag_port_hopping = true}) o:depends({type = "hysteria2", flag_transport = true, flag_port_hopping = true})
o.datatype = "uinteger" o.datatype = "uinteger"
o.rmempty = true o.rmempty = true
o.default = "30" o.default = "30"
o = s:option(Flag, "flag_obfs", translate("Enable Obfuscation")) o = s:option(Flag, "flag_obfs", translate("Enable Obfuscation"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o = s:option(Flag, "lazy_mode", translate("Enable Lazy Mode")) o = s:option(Flag, "lazy_mode", translate("Enable Lazy Mode"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o = s:option(Value, "obfs_type", translate("Obfuscation Type")) o = s:option(Value, "obfs_type", translate("Obfuscation Type"))
o:depends({type = "hysteria", flag_obfs = "1"}) o:depends({type = "hysteria2", flag_obfs = "1"})
o.rmempty = true o.rmempty = true
o.default = "salamander" o.default = "salamander"
o = s:option(Value, "salamander", translate("Obfuscation Password")) o = s:option(Value, "salamander", translate("Obfuscation Password"))
o:depends({type = "hysteria", flag_obfs = "1"}) o:depends({type = "hysteria2", flag_obfs = "1"})
o.rmempty = true o.rmempty = true
o.default = "cry_me_a_r1ver" o.default = "cry_me_a_r1ver"
o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters")) o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters"))
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o = s:option(Flag, "disablepathmtudiscovery", translate("Disable QUIC path MTU discovery")) o = s:option(Flag, "disablepathmtudiscovery", translate("Disable QUIC path MTU discovery"))
o:depends({type = "hysteria",flag_quicparam = "1"}) o:depends({type = "hysteria2",flag_quicparam = "1"})
o.rmempty = true o.rmempty = true
o.default = false o.default = false
--[[Hysteria2 QUIC parameters setting]] --[[Hysteria2 QUIC parameters setting]]
o = s:option(Value, "initstreamreceivewindow", translate("QUIC initStreamReceiveWindow")) o = s:option(Value, "initstreamreceivewindow", translate("QUIC initStreamReceiveWindow"))
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o.datatype = "uinteger" o.datatype = "uinteger"
o.rmempty = true o.rmempty = true
o.default = "8388608" o.default = "8388608"
o = s:option(Value, "maxstreamseceivewindow", translate("QUIC maxStreamReceiveWindow")) o = s:option(Value, "maxstreamseceivewindow", translate("QUIC maxStreamReceiveWindow"))
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o.datatype = "uinteger" o.datatype = "uinteger"
o.rmempty = true o.rmempty = true
o.default = "8388608" o.default = "8388608"
o = s:option(Value, "initconnreceivewindow", translate("QUIC initConnReceiveWindow")) o = s:option(Value, "initconnreceivewindow", translate("QUIC initConnReceiveWindow"))
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o.datatype = "uinteger" o.datatype = "uinteger"
o.rmempty = true o.rmempty = true
o.default = "20971520" o.default = "20971520"
o = s:option(Value, "maxconnreceivewindow", translate("QUIC maxConnReceiveWindow")) o = s:option(Value, "maxconnreceivewindow", translate("QUIC maxConnReceiveWindow"))
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o.datatype = "uinteger" o.datatype = "uinteger"
o.rmempty = true o.rmempty = true
o.default = "20971520" o.default = "20971520"
o = s:option(Value, "maxidletimeout", translate("QUIC maxIdleTimeout(Unit:second)")) o = s:option(Value, "maxidletimeout", translate("QUIC maxIdleTimeout(Unit:second)"))
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o.rmempty = true o.rmempty = true
o.datatype = "uinteger" o.datatype = "uinteger"
o.default = "30" o.default = "30"
o = s:option(Value, "keepaliveperiod", translate("The keep-alive period.(Unit:second)")) o = s:option(Value, "keepaliveperiod", translate("The keep-alive period.(Unit:second)"))
o.description = translate("Default value 0 indicatesno heartbeat.") o.description = translate("Default value 0 indicatesno heartbeat.")
o:depends({type = "hysteria", flag_quicparam = "1"}) o:depends({type = "hysteria2", flag_quicparam = "1"})
o:depends({type = "v2ray", v2ray_protocol = "wireguard"}) o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
o.rmempty = true o.rmempty = true
o.datatype = "uinteger" o.datatype = "uinteger"
@ -454,7 +518,7 @@ o.default = ""
o = s:option(ListValue, "chain_type", translate("Shadow-TLS ChainPoxy type")) o = s:option(ListValue, "chain_type", translate("Shadow-TLS ChainPoxy type"))
o:depends("type", "shadowtls") o:depends("type", "shadowtls")
if is_finded("sslocal") then if is_finded("sslocal") then
o:value("sslocal", translate("Shadowsocks-rust Version")) o:value("sslocal", translate("ShadowSocks-rust Version"))
end end
if is_finded("xray") or is_finded("v2ray") then if is_finded("xray") or is_finded("v2ray") then
o:value("vmess", translate("Vmess Protocol")) o:value("vmess", translate("Vmess Protocol"))
@ -888,14 +952,14 @@ o.rmempty = true
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity(Default:Mbps)")) o = s:option(Value, "uplink_capacity", translate("Uplink Capacity(Default:Mbps)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o:depends("transport", "kcp") o:depends("transport", "kcp")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.default = 5 o.default = 5
o.rmempty = true o.rmempty = true
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity(Default:Mbps)")) o = s:option(Value, "downlink_capacity", translate("Downlink Capacity(Default:Mbps)"))
o.datatype = "uinteger" o.datatype = "uinteger"
o:depends("transport", "kcp") o:depends("transport", "kcp")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.default = 20 o.default = 20
o.rmempty = true o.rmempty = true
@ -968,7 +1032,7 @@ o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", reality = false})
o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", reality = false}) o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", reality = false})
o:depends({type = "v2ray", v2ray_protocol = "http", reality = false}) o:depends({type = "v2ray", v2ray_protocol = "http", reality = false})
o:depends("type", "trojan") o:depends("type", "trojan")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
-- [[ TLS部分 ]] -- -- [[ TLS部分 ]] --
o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket")) o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket"))
@ -1055,12 +1119,12 @@ o.rmempty = true
o = s:option(Flag, "insecure", translate("allowInsecure")) o = s:option(Flag, "insecure", translate("allowInsecure"))
o.rmempty = false o.rmempty = false
o:depends("tls", true) o:depends("tls", true)
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.") o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.")
-- [[ Hysteria2 TLS pinSHA256 ]] -- -- [[ Hysteria2 TLS pinSHA256 ]] --
o = s:option(Value, "pinsha256", translate("Certificate fingerprint")) o = s:option(Value, "pinsha256", translate("Certificate fingerprint"))
o:depends({type = "hysteria", insecure = true }) o:depends({type = "hysteria2", insecure = true })
o.rmempty = true o.rmempty = true
@ -1076,6 +1140,7 @@ o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "splithttp"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"}) o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"}) o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"})
o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"}) o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"})
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
o:depends({type = "v2ray", v2ray_protocol = "trojan"}) o:depends({type = "v2ray", v2ray_protocol = "trojan"})
o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"}) o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
o:depends({type = "v2ray", v2ray_protocol = "socks"}) o:depends({type = "v2ray", v2ray_protocol = "socks"})
@ -1167,7 +1232,7 @@ o = s:option(Flag, "certificate", translate("Self-signed Certificate"))
o.rmempty = true o.rmempty = true
o.default = "0" o.default = "0"
o:depends("type", "tuic") o:depends("type", "tuic")
o:depends({type = "hysteria", insecure = false}) o:depends({type = "hysteria2", insecure = false})
o:depends({type = "trojan", tls = true, insecure = false}) o:depends({type = "trojan", tls = true, insecure = false})
o:depends({type = "v2ray", v2ray_protocol = "vmess", tls = true, insecure = false}) o:depends({type = "v2ray", v2ray_protocol = "vmess", tls = true, insecure = false})
o:depends({type = "v2ray", v2ray_protocol = "vless", tls = true, insecure = false}) o:depends({type = "v2ray", v2ray_protocol = "vless", tls = true, insecure = false})
@ -1209,9 +1274,9 @@ end
o = s:option(Value, "certpath", translate("Current Certificate Path")) o = s:option(Value, "certpath", translate("Current Certificate Path"))
o:depends("certificate", 1) o:depends("certificate", 1)
o:value("/etc/ssl/private/ca.pem") o:value("/etc/ssl/private/ca.crt")
o.description = translate("Please confirm the current certificate path") o.description = translate("Please confirm the current certificate path")
o.default = "/etc/ssl/private/ca.pem" o.default = "/etc/ssl/private/ca.crt"
o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support.")) o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
o.rmempty = true o.rmempty = true
@ -1219,7 +1284,7 @@ o.default = "0"
o:depends("type", "ssr") o:depends("type", "ssr")
o:depends("type", "ss") o:depends("type", "ss")
o:depends("type", "trojan") o:depends("type", "trojan")
o:depends("type", "hysteria") o:depends("type", "hysteria2")
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch")) o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
o.rmempty = false o.rmempty = false
@ -1255,3 +1320,5 @@ if is_finded("kcptun-client") then
end end
return m return m

View File

@ -3,11 +3,28 @@
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
local m, s, sec, o local m, s, sec, o
local uci = luci.model.uci.cursor() local uci = require "luci.model.uci".cursor()
-- 获取 LAN IP 地址
function lanip()
local lan_ip
lan_ip = luci.sys.exec("uci -q get network.lan.ipaddr 2>/dev/null | awk -F '/' '{print $1}' | tr -d '\n'")
if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip address show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) | grep -w 'inet' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n'")
end
if not lan_ip or lan_ip == "" then
lan_ip = luci.sys.exec("ip addr show | grep -w 'inet' | grep 'global' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1 | tr -d '\n'")
end
return lan_ip
end
local lan_ip = lanip()
local validation = require "luci.cbi.datatypes" local validation = require "luci.cbi.datatypes"
local function is_finded(e) local function is_finded(e)
return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end end
m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings")) m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"))
@ -48,20 +65,20 @@ for _, key in pairs(key_table) do
o:value(key, server_table[key]) o:value(key, server_table[key])
end end
if uci:get_first("shadowsocksr", 'global', 'netflix_enable', '0') ~= '0' then if uci:get_first("shadowsocksr", 'global', 'netflix_enable', '0') == '1' then
o = s:option(ListValue, "netflix_server", translate("Netflix Node")) o = s:option(ListValue, "netflix_server", translate("Netflix Node"))
o:value("nil", translate("Disable")) o:value("nil", translate("Disable"))
o:value("same", translate("Same as Global Server")) o:value("same", translate("Same as Global Server"))
for _, key in pairs(key_table) do for _, key in pairs(key_table) do
o:value(key, server_table[key]) o:value(key, server_table[key])
end end
o.default = "nil" o.default = "nil"
o.rmempty = false o.rmempty = false
o = s:option(Flag, "netflix_proxy", translate("External Proxy Mode")) o = s:option(Flag, "netflix_proxy", translate("External Proxy Mode"))
o.rmempty = false o.rmempty = false
o.description = translate("Forward Netflix Proxy through Main Proxy") o.description = translate("Forward Netflix Proxy through Main Proxy")
o.default = "0" o.default = "0"
end end
o = s:option(ListValue, "threads", translate("Multi Threads Option")) o = s:option(ListValue, "threads", translate("Multi Threads Option"))
@ -94,8 +111,24 @@ cp.placeholder = "e.g., 80,443,8080"
o.default = 1 o.default = 1
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode")) o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
o:value("1", translate("Use DNS2TCP query")) if is_finded("dns2tcp") then
o:value("2", translate("Use DNS2SOCKS query and cache")) o:value("1", translate("Use DNS2TCP query"))
end
if is_finded("dns2socks") then
o:value("2", translate("Use DNS2SOCKS query and cache"))
end
if is_finded("dns2socks-rust") then
o:value("3", translate("Use DNS2SOCKS-RUST query and cache"))
end
if is_finded("mosdns") then
o:value("4", translate("Use MOSDNS query (Not Support Oversea Mode)"))
end
if is_finded("dnsproxy") then
o:value("5", translate("Use DNSPROXY query and cache"))
end
if is_finded("chinadns-ng") then
o:value("6", translate("Use ChinaDNS-NG query and cache"))
end
o:value("0", translate("Use Local DNS Service listen port 5335")) o:value("0", translate("Use Local DNS Service listen port 5335"))
o.default = 1 o.default = 1
@ -115,10 +148,102 @@ o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)"))
o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)")) o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)"))
o:depends("pdnsd_enable", "1") o:depends("pdnsd_enable", "1")
o:depends("pdnsd_enable", "2") o:depends("pdnsd_enable", "2")
o:depends("pdnsd_enable", "3")
o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)") o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)")
o.datatype = "ip4addrport" o.datatype = "ip4addrport"
o = s:option(ListValue, "tunnel_forward_mosdns", translate("Anti-pollution DNS Server"))
o:value("tcp://8.8.4.4:53,tcp://8.8.8.8:53", translate("Google Public DNS"))
o:value("tcp://208.67.222.222:53,tcp://208.67.220.220:53", translate("OpenDNS"))
o:value("tcp://209.244.0.3:53,tcp://209.244.0.4:53", translate("Level 3 Public DNS-1 (209.244.0.3-4)"))
o:value("tcp://4.2.2.1:53,tcp://4.2.2.2:53", translate("Level 3 Public DNS-2 (4.2.2.1-2)"))
o:value("tcp://4.2.2.3:53,tcp://4.2.2.4:53", translate("Level 3 Public DNS-3 (4.2.2.3-4)"))
o:value("tcp://1.1.1.1:53,tcp://1.0.0.1:53", translate("Cloudflare DNS"))
o:depends("pdnsd_enable", "4")
o.description = translate("Custom DNS Server for MosDNS")
o = s:option(Flag, "mosdns_ipv6", translate("Disable IPv6 in MOSDNS query mode"))
o:depends("pdnsd_enable", "4")
o.rmempty = false
o.default = "1"
if is_finded("dnsproxy") then
o = s:option(ListValue, "parse_method", translate("Select DNS parse Mode"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("When use DNS list file, please ensure list file exists and is formatted correctly.") .. "</li>" ..
"<li>" .. translate("Tips: Dnsproxy DNS Parse List Path:") ..
" <a href='http://" .. lan_ip .. "/cgi-bin/luci/admin/services/shadowsocksr/control' target='_blank'>" ..
translate("Click here to view or manage the DNS list file") .. "</a>" .. "</li>" ..
"</ul>"
)
o:value("single_dns", translate("Set Single DNS"))
o:value("parse_file", translate("Use DNS List File"))
o:depends("pdnsd_enable", "5")
o.rmempty = true
o.default = "single_dns"
o = s:option(Value, "dnsproxy_tunnel_forward", translate("Anti-pollution DNS Server"))
o:value("sdns://AgUAAAAAAAAABzguOC40LjQgsKKKE4EwvtIbNjGjagI2607EdKSVHowYZtyvD9iPrkkHOC44LjQuNAovZG5zLXF1ZXJ5", translate("Google DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAAACC2vD25TAYM7EnyCH8Xw1-0g5OccnTsGH9vQUUH0njRtAxkbnMudHduaWMudHcKL2Rucy1xdWVyeQ", translate("TWNIC-101 DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAADzE4NS4yMjIuMjIyLjIyMiAOp5Svj-oV-Fz-65-8H2VKHLKJ0egmfEgrdPeAQlUFFA8xODUuMjIyLjIyMi4yMjIKL2Rucy1xdWVyeQ", translate("dns.sb DNSCrypt SDNS"))
o:value("sdns://AgMAAAAAAAAADTE0OS4xMTIuMTEyLjkgsBkgdEu7dsmrBT4B4Ht-BQ5HPSD3n3vqQ1-v5DydJC8SZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk", translate("Quad9 DNSCrypt SDNS"))
o:value("sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20", translate("AdGuard DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAABzEuMC4wLjGgENk8mGSlIfMGXMOlIlCcKvq7AVgcrZxtjon911-ep0cg63Ul-I8NlFj4GplQGb_TTLiczclX57DvMV8Q-JdjgRgSZG5zLmNsb3VkZmxhcmUuY29tCi9kbnMtcXVlcnk", translate("Cloudflare DNSCrypt SDNS"))
o:value("sdns://AgcAAAAAAAAADjEwNC4xNi4yNDkuMjQ5ABJjbG91ZGZsYXJlLWRucy5jb20KL2Rucy1xdWVyeQ", translate("cloudflare-dns.com DNSCrypt SDNS"))
o:depends("parse_method", "single_dns")
o.description = translate("Custom DNS Server (support: IP:Port or tls://IP:Port or https://IP/dns-query and other format).")
o = s:option(ListValue, "upstreams_logic_mode", translate("Defines the upstreams logic mode"))
o.description = translate(
"<ul>" ..
"<li>" .. translate("Defines the upstreams logic mode, possible values: load_balance, parallel, fastest_addr (default: load_balance).") .. "</li>" ..
"<li>" .. translate("When two or more DNS servers are deployed, enable this function.") .. "</li>" ..
"</ul>"
)
o:value("load_balance", translate("load_balance"))
o:value("parallel", translate("parallel"))
o:value("fastest_addr", translate("fastest_addr"))
o:depends("parse_method", "parse_file")
o.rmempty = true
o.default = "load_balance"
o = s:option(Flag, "dnsproxy_ipv6", translate("Disable IPv6 query mode"))
o.description = translate("When disabled, all AAAA requests are not resolved.")
o:depends("parse_method", "single_dns")
o:depends("parse_method", "parse_file")
o.rmempty = false
o.default = "1"
end
if is_finded("chinadns-ng") then if is_finded("chinadns-ng") then
o = s:option(Value, "chinadns_ng_tunnel_forward", translate("Anti-pollution DNS Server"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
o:depends("pdnsd_enable", "6")
o.description = translate(
"<ul>" ..
"<li>" .. translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)") .. "</li>" ..
"<li>" .. translate("Muitiple DNS server can saperate with ','") .. "</li>" ..
"</ul>"
)
o = s:option(ListValue, "chinadns_ng_proto", translate("ChinaDNS-NG query protocol"))
o:value("none", translate("UDP/TCP upstream"))
o:value("tcp", translate("TCP upstream"))
o:value("udp", translate("UDP upstream"))
o:value("tls", translate("DoT upstream (Need use wolfssl version)"))
o:depends("pdnsd_enable", "6")
o = s:option(Value, "chinadns_forward", translate("Domestic DNS Server")) o = s:option(Value, "chinadns_forward", translate("Domestic DNS Server"))
o:value("", translate("Disable ChinaDNS-NG")) o:value("", translate("Disable ChinaDNS-NG"))
o:value("wan", translate("Use DNS from WAN")) o:value("wan", translate("Use DNS from WAN"))
@ -132,6 +257,9 @@ if is_finded("chinadns-ng") then
o:value("1.2.4.8:53", translate("CNNIC SDNS (1.2.4.8)")) o:value("1.2.4.8:53", translate("CNNIC SDNS (1.2.4.8)"))
o:depends({pdnsd_enable = "1", run_mode = "router"}) o:depends({pdnsd_enable = "1", run_mode = "router"})
o:depends({pdnsd_enable = "2", run_mode = "router"}) o:depends({pdnsd_enable = "2", run_mode = "router"})
o:depends({pdnsd_enable = "3", run_mode = "router"})
o:depends({pdnsd_enable = "5", run_mode = "router"})
o:depends({pdnsd_enable = "6", run_mode = "router"})
o.description = translate("Custom DNS Server format as IP:PORT (default: disabled)") o.description = translate("Custom DNS Server format as IP:PORT (default: disabled)")
o.validate = function(self, value, section) o.validate = function(self, value, section)
if (section and value) then if (section and value) then

View File

@ -3,6 +3,10 @@ require "nixio.fs"
require "luci.sys" require "luci.sys"
local m, s, o local m, s, o
local function is_finded(e)
return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end
m = Map("shadowsocksr") m = Map("shadowsocksr")
s = m:section(TypedSection, "access_control") s = m:section(TypedSection, "access_control")
@ -141,6 +145,24 @@ o.remove = function(self, section, value)
nixio.fs.writefile(netflixconf, "") nixio.fs.writefile(netflixconf, "")
end end
if is_finded("dnsproxy") then
s:tab("dnsproxy", translate("Dnsproxy Parse List"))
local dnsproxyconf = "/etc/ssrplus/dnsproxy_dns.list"
o = s:taboption("dnsproxy", TextValue, "dnsproxyconf", "", "<font style=color:red>" .. translate("Specifically for edit dnsproxy DNS parse files.") .. "</font>")
o.rows = 13
o.wrap = "off"
o.rmempty = true
o.cfgvalue = function(self, section)
return nixio.fs.readfile(dnsproxyconf) or " "
end
o.write = function(self, section, value)
nixio.fs.writefile(dnsproxyconf, value:gsub("\r\n", "\n"))
end
o.remove = function(self, section, value)
nixio.fs.writefile(dnsproxyconf, "")
end
end
if luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 then if luci.sys.call('[ -f "/www/luci-static/resources/uci.js" ]') == 0 then
m.apply_on_parse = true m.apply_on_parse = true
function m.on_apply(self) function m.on_apply(self)

View File

@ -86,7 +86,7 @@ o.rmempty = false
o = s:option(ListValue, "type", translate("Server Type")) o = s:option(ListValue, "type", translate("Server Type"))
o:value("socks5", translate("Socks5")) o:value("socks5", translate("Socks5"))
if nixio.fs.access("/usr/bin/ssserver") or nixio.fs.access("/usr/bin/ss-server") then if nixio.fs.access("/usr/bin/ssserver") or nixio.fs.access("/usr/bin/ss-server") then
o:value("ss", translate("Shadowsocks")) o:value("ss", translate("ShadowSocks"))
end end
if nixio.fs.access("/usr/bin/ssr-server") then if nixio.fs.access("/usr/bin/ssr-server") then
o:value("ssr", translate("ShadowsocksR")) o:value("ssr", translate("ShadowsocksR"))
@ -143,7 +143,7 @@ end
o.rmempty = false o.rmempty = false
o:depends("type", "ssr") o:depends("type", "ssr")
o = s:option(Value, "obfs_param", translate("Obfs param(optional)")) o = s:option(Value, "obfs_param", translate("Obfs param (optional)"))
o:depends("type", "ssr") o:depends("type", "ssr")
o = s:option(Flag, "fast_open", translate("TCP Fast Open")) o = s:option(Flag, "fast_open", translate("TCP Fast Open"))

View File

@ -120,15 +120,9 @@ function o.cfgvalue(...)
end end
o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method")) o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
function o.cfgvalue(...) function o.cfgvalue(self, section)
local v = Value.cfgvalue(...) local method = self.map:get(section, "encrypt_method") or self.map:get(section, "encrypt_method_ss")
return v and v:upper() or "-" return method and method:upper() or "-"
end
o = sec:option(DummyValue, "encrypt_method_ss", translate("Encrypt Method"))
function o.cfgvalue(...)
local v = Value.cfgvalue(...)
return v and v:upper() or "-"
end end
o = sec:option(DummyValue, "protocol", translate("Protocol")) o = sec:option(DummyValue, "protocol", translate("Protocol"))

View File

@ -1,10 +1,39 @@
-- Licensed to the public under the GNU General Public License v3. -- Licensed to the public under the GNU General Public License v3.
require "luci.http" require "luci.http"
require "luci.sys"
require "luci.dispatcher" require "luci.dispatcher"
require "luci.model.uci" require "luci.model.uci"
local m, s, o local uci = require "luci.model.uci".cursor()
local uci = luci.model.uci.cursor()
local m, s, o, node
local server_count = 0 local server_count = 0
-- 确保正确判断程序是否存在
local function is_finded(e)
return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end
local has_ss_rust = is_finded("sslocal") or is_finded("ssserver")
local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local")
local ss_type_list = {}
if has_ss_rust then
table.insert(ss_type_list, { id = "ss-rust", name = translate("ShadowSocks-rust Version") })
end
if has_ss_libev then
table.insert(ss_type_list, { id = "ss-libev", name = translate("ShadowSocks-libev Version") })
end
-- 如果用户没有手动设置,则自动选择
if ss_type == "" then
if has_ss_rust then
ss_type = "ss-rust"
elseif has_ss_libev then
ss_type = "ss-libev"
end
end
uci:foreach("shadowsocksr", "servers", function(s) uci:foreach("shadowsocksr", "servers", function(s)
server_count = server_count + 1 server_count = server_count + 1
end) end)
@ -48,6 +77,30 @@ o.default = 30
o.rmempty = true o.rmempty = true
o:depends("auto_update", "1") o:depends("auto_update", "1")
-- 确保 ss_type_list 不为空
if #ss_type_list > 0 then
o = s:option(ListValue, "ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translate("ShadowSocks Node Use Version")))
o.description = translate("Selection ShadowSocks Node Use Version.")
for _, v in ipairs(ss_type_list) do
o:value(v.id, v.name) -- 存储 "ss-libev" / "ss-rust",但 UI 显示完整名称
end
o.default = ss_type -- 设置默认值
o.write = function(self, section, value)
-- 更新 Shadowsocks 节点的 has_ss_type
uci:foreach("shadowsocksr", "servers", function(s)
local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型
if node_type == "ss" then -- 仅修改 Shadowsocks 节点
local old_value = uci:get("shadowsocksr", s[".name"], "has_ss_type")
if old_value ~= value then
uci:set("shadowsocksr", s[".name"], "has_ss_type", value)
end
end
end)
-- 更新当前 section 的 ss_type
Value.write(self, section, value)
end
end
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL")) o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true o.rmempty = true
@ -67,6 +120,11 @@ o.write = function()
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers")) luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
end end
o = s:option(Flag, "allow_insecure", translate("Allow subscribe Insecure nodes By default"))
o.rmempty = false
o.description = translate("Subscribe nodes allows insecure connection as TLS client (insecure)")
o.default = "0"
o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch")) o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
o.rmempty = false o.rmempty = false
o.description = translate("Subscribe new add server default Auto-Switch on") o.description = translate("Subscribe new add server default Auto-Switch on")

View File

@ -15,7 +15,7 @@ local ad_count = 0
local ip_count = 0 local ip_count = 0
local nfip_count = 0 local nfip_count = 0
local Process_list = luci.sys.exec("busybox ps -w") local Process_list = luci.sys.exec("busybox ps -w")
local uci = luci.model.uci.cursor() local uci = require "luci.model.uci".cursor()
-- html constants -- html constants
font_blue = [[<b style=color:green>]] font_blue = [[<b style=color:green>]]
style_blue = [[<b style=color:red>]] style_blue = [[<b style=color:red>]]
@ -92,7 +92,11 @@ if Process_list:find("ssr.server") then
server_run = 1 server_run = 1
end end
if Process_list:find("ssrplus/bin/dns2tcp") or (Process_list:find("ssrplus.dns") and Process_list:find("dns2socks.127.0.0.1.*127.0.0.1.5335")) then if Process_list:find("ssrplus/bin/dns2tcp") or
Process_list:find("ssrplus/bin/mosdns") or
Process_list:find("dnsproxy.*127.0.0.1.*5335") or
Process_list:find("chinadns.*127.0.0.1.*5335") or
(Process_list:find("ssrplus.dns") and Process_list:find("dns2socks.*127.0.0.1.*127.0.0.1.5335")) then
pdnsd_run = 1 pdnsd_run = 1
end end

View File

@ -4,7 +4,7 @@
-%> -%>
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
window.addEventListener('load',function(){ window.addEventListener('load', function () {
const doms = document.getElementsByClassName('pingtime'); const doms = document.getElementsByClassName('pingtime');
const ports = document.getElementsByClassName("socket-connected"); const ports = document.getElementsByClassName("socket-connected");
const transports = document.getElementsByClassName("transport"); const transports = document.getElementsByClassName("transport");
@ -17,7 +17,7 @@
const transport = transports[index]; const transport = transports[index];
const wsPath = wsPaths[index]; const wsPath = wsPaths[index];
const tls = tlss[index]; const tls = tlss[index];
if (!dom) res() if (!dom) res();
port.innerHTML = '<font color="#0072c3">connect</font>'; port.innerHTML = '<font color="#0072c3">connect</font>';
XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', { XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', {
index, index,
@ -34,7 +34,7 @@
if (result.ping < 200) col = '#ff7700'; if (result.ping < 200) col = '#ff7700';
if (result.ping < 100) col = '#249400'; if (result.ping < 100) col = '#249400';
} }
dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>` dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>`;
if (result.socket) { if (result.socket) {
port.innerHTML = '<font color="#249400">ok</font>'; port.innerHTML = '<font color="#249400">ok</font>';
} else { } else {
@ -42,19 +42,19 @@
} }
res(); res();
}); });
}) });
} };
let task = -1; let task = -1;
const thread = () => { const thread = () => {
task = task + 1 task = task + 1;
if (doms[task]) { if (doms[task]) {
xhr(task).then(thread); xhr(task).then(thread);
} }
} };
for (let i = 0; i < 20; i++) { for (let i = 0; i < 20; i++) {
thread() thread();
} }
}) });
function cbi_row_drop(fromId, toId, store, isToBottom) { function cbi_row_drop(fromId, toId, store, isToBottom) {
var fromNode = document.getElementById(fromId); var fromNode = document.getElementById(fromId);
@ -85,9 +85,20 @@
if (input) input.value = ids.join(" "); if (input) input.value = ids.join(" ");
return false; return false;
} }
// set tr draggable // set tr draggable
function enableDragForTable(table_selecter, store) { function enableDragForTable(table_selector, store) {
var trs = document.querySelectorAll(table_selecter + " tr"); // 添加 CSS 样式
const style = document.createElement("style");
style.textContent = `
tr[draggable="true"] {
cursor: move;
user-select: none;
}
`;
document.head.appendChild(style);
var trs = document.querySelectorAll(table_selector + " tr");
if (!trs || trs.length.length < 3) { if (!trs || trs.length.length < 3) {
return; return;
} }
@ -103,12 +114,12 @@
ev.dataTransfer.dropEffect = "move"; ev.dataTransfer.dropEffect = "move";
} }
function moveToTop(id) { function moveToTop(id) {
var top = document.querySelectorAll(table_selecter + " tr")[2]; var top = document.querySelectorAll(table_selector + " tr")[2];
cbi_row_drop(id, top.id, store); cbi_row_drop(id, top.id, store);
} }
function moveToBottom(id) { function moveToBottom(id) {
console.log('moveToBottom:', id); //console.log('moveToBottom:', id);
var trList = document.querySelectorAll(table_selecter + " tr"); var trList = document.querySelectorAll(table_selector + " tr");
var bottom = trList[trList.length - 1]; var bottom = trList[trList.length - 1];
cbi_row_drop(id, bottom.id, store, true); cbi_row_drop(id, bottom.id, store, true);
} }
@ -137,9 +148,11 @@
} }
} }
} }
// enable // enable
enableDragForTable( enableDragForTable(
"#cbi-shadowsocksr-servers table", "#cbi-shadowsocksr-servers table",
"cbi.sts.shadowsocksr.servers" "cbi.sts.shadowsocksr.servers"
); );
//]]>
</script> </script>

View File

@ -1,6 +1,12 @@
<%+cbi/valueheader%> <%+cbi/valueheader%>
<%
local map = self.map
local ss_type = map:get("@server_subscribe[0]", "ss_type")
-%>
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
let ss_type = "<%=ss_type%>"
function padright(str, cnt, pad) { function padright(str, cnt, pad) {
return str + Array(cnt + 1).join(pad); return str + Array(cnt + 1).join(pad);
} }
@ -93,7 +99,8 @@ function import_ssr_url(btn, urlname, sid) {
var event = document.createEvent("HTMLEvents"); var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true); event.initEvent("change", true, true);
switch (ssu[0]) { switch (ssu[0]) {
case "hysteria": case "hysteria2":
case "hy2":
try { try {
var url = new URL("http://" + ssu[1]); var url = new URL("http://" + ssu[1]);
var params = url.searchParams; var params = url.searchParams;
@ -102,23 +109,53 @@ function import_ssr_url(btn, urlname, sid) {
return false; return false;
} }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0]; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = (ssu[0] === "hy2") ? "hysteria2" : ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hysteria_protocol')[0].value = params.get("protocol") || "udp"; if (params.get("lazy") === "1") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_type')[0].value = params.get("auth") ? "2" : "0"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.lazy_mode')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_type')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.lazy_mode')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.auth_payload')[0].value = params.get("auth") || ""; }
document.getElementsByName('cbid.shadowsocksr.' + sid + '.uplink_capacity')[0].value = params.get("upmbps") || ""; if (params.get("mport")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.downlink_capacity')[0].value = params.get("downmbps") || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_port_hopping')[0].checked = true; // 设置 flag_transport 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("obfsParam") || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_port_hopping')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("peer") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_tls_alpn')[0].value = params.get("alpn") || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.port_range')[0].value = params.get("mport") || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = params.get("insecure") ? true : false; }
if (params.get("protocol")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].checked = true; // 设置 flag_transport 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport_protocol')[0].value = params.get("protocol") || "udp";
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].value = decodeURIComponent(url.username);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.uplink_capacity')[0].value = params.get("upmbps") || "5";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.downlink_capacity')[0].value = params.get("downmbps") || "20";
if (params.get("obfs")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_obfs')[0].checked = true; // 设置 flag_obfs 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_obfs')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_type')[0].value = params.get("obfs") || "salamander";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.salamander')[0].value = params.get("obfs-password") || "cry_me_a_r1ver";
}
if (params.get("sni")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true; // 设置 flag_obfs 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni") || "";
}
if (params.get("insecure") === "1") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event);
if (params.get("sni")) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.pinsha256')[0].value = params.get("pinsha256") || "";
}
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
return false; return false;
case "ss": case "ss":
var url0, param = ""; var url0, param = "";
@ -133,38 +170,59 @@ function import_ssr_url(btn, urlname, sid) {
if (sipIndex != -1) { if (sipIndex != -1) {
// SIP002 // SIP002
var userInfo = b64decsafe(url0.substr(0, sipIndex)); var userInfo = b64decsafe(url0.substr(0, sipIndex));
// console.log("userInfo:", userInfo); // 打印解析后的 userInfo
var temp = url0.substr(sipIndex + 1).split("/?"); var temp = url0.substr(sipIndex + 1).split("/?");
var serverInfo = temp[0].split(":"); var serverInfo = temp[0].split(":");
var server = serverInfo[0]; var server = serverInfo[0];
var port = serverInfo[1].replace("/",""); var port = serverInfo[1].replace("/","");
var method, password, plugin, pluginOpts; var method, password, enable_plugin, plugin, pluginOpts;
// 解析 plugin 参数
if (temp[1]) { if (temp[1]) {
var pluginInfo = decodeURIComponent(temp[1]); var pluginInfo = decodeURIComponent(temp[1]);
var pluginIndex = pluginInfo.indexOf(";"); // 使用正则匹配 plugin 参数
var pluginNameInfo = pluginInfo.substr(0, pluginIndex); var pluginNameInfo = pluginInfo.match(/plugin=([^&]+)/);
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1); if (pluginNameInfo) {
pluginOpts = pluginInfo.substr(pluginIndex + 1); var pluginParams = pluginNameInfo[1].split(";");
plugin = pluginParams.shift(); // 获取 plugin
pluginOpts = pluginParams.length > 0 ? pluginParams.join(";") : "";
} }
}
// 解析 userInfo解析加密方法和密码
var userInfoSplitIndex = userInfo.indexOf(":"); var userInfoSplitIndex = userInfo.indexOf(":");
if (userInfoSplitIndex != -1) { if (userInfoSplitIndex !== -1) {
method = userInfo.substr(0, userInfoSplitIndex); method = userInfo.substr(0, userInfoSplitIndex); // 提取加密方法
password = userInfo.substr(userInfoSplitIndex + 1); password = userInfo.substr(userInfoSplitIndex + 1); // 提取密码
if (!method || method.trim() === "") {
method = "none"; // 如果加密方法为空,设置为 "none"
} }
}
var has_ss_type = (ss_type === "ss-rust") ? "ss-rust" : "ss-libev";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0]; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].value = has_ss_type;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].dispatchEvent(event);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port; document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].dispatchEvent(event);
if (plugin && plugin !== "none") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = true; // 设置 enable_plugin 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "none"; document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event);
if (plugin != undefined) { if (plugin !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || ""; document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
} }
if (param != undefined) { } else {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = false;
}
if (param !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
} else { } else {
var sstr = b64decsafe(url0); var sstr = b64decsafe(url0);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0]; document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
@ -172,14 +230,18 @@ function import_ssr_url(btn, urlname, sid) {
var team = sstr.split('@'); var team = sstr.split('@');
var part1 = team[0].split(':'); var part1 = team[0].split(':');
var part2 = team[1].split(':'); var part2 = team[1].split(':');
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = part2[0]; var method = (part1[0] && part1[0].trim() !== "") ? part1[0].trim() : "none";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = part2[1]; var password = part1[1] || "";
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = part1[1]; var server = part2[0];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = part1[0]; var port = part2[1];
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method;
if (param != undefined) { if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param); document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
} }
s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>"; s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
} }
return false; return false;
case "ssr": case "ssr":
@ -518,3 +580,5 @@ function import_ssr_url(btn, urlname, sid) {
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" /> <input type="button" class="btn cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
<span id="<%=self.option%>-status"></span> <span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -166,7 +166,7 @@ _exit() {
} }
first_type() { first_type() {
type -t -p "/bin/${1}" -p "${TMP_BIN_PATH}/${1}" -p "${1}" "$@" | head -n1 type -t -p "/bin/${1}" -p "/usr/bin/${1}" -p "${TMP_BIN_PATH}/${1}" -p "${1}" "$@" | head -n1
} }
ln_start_bin() { ln_start_bin() {
@ -190,17 +190,30 @@ ln_start_bin() {
${file_func:-echolog " - ${ln_name}"} "$@" >/dev/null 2>&1 & ${file_func:-echolog " - ${ln_name}"} "$@" >/dev/null 2>&1 &
} }
add_dns_into_ipset() {
case "$1" in
gfw) ipset add gfwlist ${2%:*} 2>/dev/null ;;
oversea) ipset add oversea ${2%:*} 2>/dev/null ;;
*) ipset add ss_spec_wan_ac ${2%:*} nomatch 2>/dev/null ;;
esac
}
start_dns() { start_dns() {
local ssrplus_dns="$(uci_get_by_type global pdnsd_enable 0)" local ssrplus_dns="$(uci_get_by_type global pdnsd_enable 0)"
local dnsserver="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)" local dnsproxy_dnsserver="$(uci_get_by_type global parse_method)"
if [ -n "$dnsproxy_dnsserver" ] && [ "$dnsproxy_dnsserver" != "parse_file" ]; then
dnsserver="$(uci_get_by_type global dnsproxy_tunnel_forward 8.8.4.4:53)"
elif [ -n "$ssrplus_dns" ] && [ "$ssrplus_dns" = "6" ]; then
dnsserver="$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53)"
else
dnsserver="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
fi
local run_mode="$(uci_get_by_type global run_mode)" local run_mode="$(uci_get_by_type global run_mode)"
if [ "$ssrplus_dns" != "0" ]; then if [ "$ssrplus_dns" != "0" ]; then
case "$run_mode" in if [ -n "$dnsserver" ]; then
gfw) ipset add gfwlist ${dnsserver%:*} 2>/dev/null ;; add_dns_into_ipset $run_mode $dnsserver
oversea) ipset add oversea ${dnsserver%:*} 2>/dev/null ;; fi
*) ipset add ss_spec_wan_ac ${dnsserver%:*} nomatch 2>/dev/null ;;
esac
case "$ssrplus_dns" in case "$ssrplus_dns" in
1) 1)
ln_start_bin $(first_type dns2tcp) dns2tcp -L 127.0.0.1#$dns_port -R ${dnsserver/:/#} ln_start_bin $(first_type dns2tcp) dns2tcp -L 127.0.0.1#$dns_port -R ${dnsserver/:/#}
@ -211,6 +224,123 @@ start_dns() {
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q
pdnsd_enable_flag=2 pdnsd_enable_flag=2
;; ;;
3)
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
ln_start_bin $(first_type dns2socks-rust) dns2socks-rust -s socks5://127.0.0.1:$tmp_dns_port -d $dnsserver -l 127.0.0.1:$dns_port -f -c
echolog "DNS2SOCKS Rust query and cache Started!"
pdnsd_enable_flag=3
;;
4)
local mosdns_ipv6="$(uci_get_by_type global mosdns_ipv6)"
local mosdns_dnsserver="$(uci_get_by_type global tunnel_forward_mosdns)"
output=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do
dnsserver=${i%:*}
dnsserver=${i##*/}
add_dns_into_ipset $run_mode $dnsserver
echo " - addr: $i"
echo " enable_pipeline: true"
done)
awk -v line=14 -v text="$output" 'NR == line+1 {print text} 1' /etc/ssrplus/mosdns-config.yaml | sed "s/DNS_PORT/$dns_port/g" > $TMP_PATH/mosdns-config.yaml
if [ "$mosdns_ipv6" == "0" ]; then
sed -i "s/DNS_MODE/main_sequence_with_IPv6/g" $TMP_PATH/mosdns-config.yaml
else
sed -i "s/DNS_MODE/main_sequence_disable_IPv6/g" $TMP_PATH/mosdns-config.yaml
fi
ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config.yaml
pdnsd_enable_flag=4
;;
5)
dnsproxy_ipv6="$(uci_get_by_type global dnsproxy_ipv6)"
if [ "$dnsproxy_ipv6" -eq "1" ]; then
disabled_ipv6="--ipv6-disabled"
fi
if [ "$dnsproxy_dnsserver" != "parse_file" ]; then
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsserver $disabled_ipv6 --cache --cache-min-ttl=3600
else
dnsproxy_dnsserver_file="$TMP_PATH/dnsproxy_dns.list"
cleaned_file="$TMP_PATH/cleaned_dns.list"
temp_file="$TMP_PATH/temp_dns.list"
> "$cleaned_file"
# 清理输入文件并去重
while IFS= read -r line || [ -n "$line" ]; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
[ -z "$line" ] && continue
echo "$line" | grep -qE '^#' && continue
echo "$line" >> "$cleaned_file"
done < "/etc/ssrplus/dnsproxy_dns.list"
# 获取清理后文件的MD5
cleaned_md5=$(md5sum "$cleaned_file" | awk '{print $1}')
if [ ! -f "$dnsproxy_dnsserver_file" ]; then
cp "$cleaned_file" "$dnsproxy_dnsserver_file"
else
target_md5=$(md5sum "$dnsproxy_dnsserver_file" | awk '{print $1}')
if [ "$cleaned_md5" != "$target_md5" ]; then
> "$temp_file"
# 保留目标文件中也存在于清理文件的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if grep -qixF "$line" "$cleaned_file" && ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$dnsproxy_dnsserver_file"
# 添加清理文件中有但目标文件没有的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$cleaned_file"
temp_md5=$(md5sum "$temp_file" | awk '{print $1}')
if [ "$temp_md5" != "$target_md5" ]; then
mv "$temp_file" "$dnsproxy_dnsserver_file"
else
rm -f "$temp_file"
fi
fi
fi
rm -f "$cleaned_file"
if [ -n "$dnsproxy_dnsserver_file" ] && [ -s "$dnsproxy_dnsserver_file" ]; then
local upstreams_logic_mode="$(uci_get_by_type global upstreams_logic_mode)"
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsproxy_dnsserver_file $disabled_ipv6 --cache --cache-min-ttl=3600 --upstream-mode=$upstreams_logic_mode
fi
fi
echolog "DNSPROXY query and cache Started!"
pdnsd_enable_flag=5
;;
6)
local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)"
local chinadns_ng_dns=""
# 遍历每个 DNS 服务器
IFS=',' # 设置分隔符为逗号
for chinadns_ng_server in $dnsserver; do
# 处理单个服务器地址
local chinadns_ng_ip="${chinadns_ng_server%%:*}"
local chinadns_ng_port="${chinadns_ng_server##*:}"
[ "$chinadns_ng_ip" = "$chinadns_ng_port" ] && chinadns_ng_port="53"
chinadns_ng_tls_port="853"
# 根据协议类型格式化服务器地址
case "$chinadns_ng_proto" in
"none")
chinadns_ng_server="${chinadns_ng_ip}#${chinadns_ng_port}"
;;
"tls")
chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_tls_port}"
;;
*)
chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_port}"
;;
esac
# 添加到参数列表
chinadns_ng_dns="${chinadns_ng_dns} -t ${chinadns_ng_server}"
done
unset IFS # 恢复默认分隔符
dnsserver="$chinadns_ng_dns"
ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_dns_port -l $dns_port -p 3 -d gfw $dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20
echolog "ChinaDNS-NG query and cache Started!"
pdnsd_enable_flag=6
;;
esac esac
if [ "$run_mode" = "router" ]; then if [ "$run_mode" = "router" ]; then
@ -294,7 +424,7 @@ gen_service_file() { #1-server.type 2-cfgname 3-file_path
get_name() { get_name() {
case "$1" in case "$1" in
ss) echo "Shadowsocks" ;; ss) echo "ShadowSocks" ;;
ssr) echo "ShadowsocksR" ;; ssr) echo "ShadowsocksR" ;;
esac esac
} }
@ -365,7 +495,7 @@ gen_config_file() { #server1 type2 code3 local_port4 socks_port5 chain6 threads5
;; ;;
esac esac
;; ;;
hysteria) hysteria2)
lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 >$config_file lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 >$config_file
;; ;;
tuic) tuic)
@ -406,11 +536,23 @@ gen_config_file() { #server1 type2 code3 local_port4 socks_port5 chain6 threads5
start_udp() { start_udp() {
local type=$(uci_get_by_name $UDP_RELAY_SERVER type) local type=$(uci_get_by_name $UDP_RELAY_SERVER type)
local has_ss_type=$(uci_get_by_type server_subscribe ss_type)
redir_udp=1 redir_udp=1
case "$type" in case "$type" in
ss | ssr) ss | ssr)
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port
ss_program="$(first_type ${type}local ${type}-redir)" if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
ss_program="$(first_type ${type}-redir)"
elif [ "$has_ss_type" = "ss-rust" ]; then
ss_program="$(first_type ${type}local)"
fi
echolog "$(get_name $type) program is: $ss_program"
# 获取当前软链接指向的执行文件路径
old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null)
# **当新旧执行文件路径不同时,删除旧链接**
if [ "$old_ss_program" != "$ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-redir"
fi
ln_start_bin $ss_program ${type}-redir -c $udp_config_file ln_start_bin $ss_program ${type}-redir -c $udp_config_file
echolog "UDP TPROXY Relay:$(get_name $type) Started!" echolog "UDP TPROXY Relay:$(get_name $type) Started!"
;; ;;
@ -430,7 +572,7 @@ start_udp() {
redir_udp=0 redir_udp=0
ARG_UDP="" ARG_UDP=""
;; ;;
hysteria) hysteria2)
gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port gen_config_file $UDP_RELAY_SERVER $type 2 $tmp_udp_port
ln_start_bin $(first_type hysteria) hysteria client --config $udp_config_file ln_start_bin $(first_type hysteria) hysteria client --config $udp_config_file
echolog "UDP TPROXY Relay:$($(first_type "hysteria") version | grep Version | awk '{print "Hysteria2: " $2}') Started!" echolog "UDP TPROXY Relay:$($(first_type "hysteria") version | grep Version | awk '{print "Hysteria2: " $2}') Started!"
@ -479,27 +621,211 @@ start_udp() {
esac esac
} }
shunt_dns_command() {
local shunt_dns_mode="$(uci_get_by_type global shunt_dns_mode)"
local shunt_dnsproxy_dnsserver="$(uci_get_by_type global shunt_parse_method)"
if [ -n "$shunt_dnsproxy_dnsserver" ] && [ "$shunt_dnsproxy_dnsserver" != "parse_file" ]; then
shunt_dnsserver="$(uci_get_by_type global dnsproxy_shunt_forward 8.8.4.4:53)"
elif [ -n "shunt_dns_mode" ] && [ "$shunt_dns_mode" = "5" ]; then
shunt_dnsserver="$(uci_get_by_type global chinadns_ng_shunt_dnsserver 8.8.4.4:53)"
else
shunt_dnsserver="$(uci_get_by_type global shunt_dnsserver 8.8.4.4:53)"
fi
local tmp_port=$1
case "$shunt_dns_mode" in
1)
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port $shunt_dnsserver 127.0.0.1:$tmp_shunt_dns_port -q
;;
2)
ln_start_bin $(first_type dns2socks-rust) dns2socks-rust -s socks5://127.0.0.1:$tmp_port -d $shunt_dnsserver -l 127.0.0.1:$tmp_shunt_dns_port -f -c
echolog "DNS2SOCKS Rust Shunt query Started!"
;;
3)
local shunt_mosdns_ipv6="$(uci_get_by_type global shunt_mosdns_ipv6)"
local shunt_mosdns_dnsserver="$(uci_get_by_type global shunt_mosdns_dnsserver)"
output=$(for i in $(echo $shunt_mosdns_dnsserver | sed "s/,/ /g"); do
echo " - addr: $i"
echo " socks5: \"127.0.0.1:$tmp_port\""
echo " enable_pipeline: true"
done)
awk -v line=14 -v text="$output" 'NR == line+1 {print text} 1' /etc/ssrplus/mosdns-config.yaml | sed "s/DNS_PORT/$tmp_shunt_dns_port/g" > $TMP_PATH/mosdns-config-shunt.yaml
if [ "$shunt_mosdns_ipv6" == "0" ]; then
sed -i "s/DNS_MODE/main_sequence_with_IPv6/g" $TMP_PATH/mosdns-config-shunt.yaml
else
sed -i "s/DNS_MODE/main_sequence_disable_IPv6/g" $TMP_PATH/mosdns-config-shunt.yaml
fi
ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config-shunt.yaml
;;
4)
shunt_dnsproxy_ipv6="$(uci_get_by_type global shunt_dnsproxy_ipv6)"
if [ "$shunt_dnsproxy_ipv6" -eq "1" ]; then
shunt_disabled_ipv6="--ipv6-disabled"
fi
if [ "$shunt_dnsproxy_dnsserver" != "parse_file" ]; then
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_port -p $tmp_shunt_dns_port -u $shunt_dnsserver $shunt_disabled_ipv6 --cache --cache-min-ttl=3600
else
shunt_dnsproxy_dnsserver_file="$TMP_PATH/dnsproxy_dns.list"
cleaned_file="$TMP_PATH/cleaned_dns_servers.list"
temp_file="$TMP_PATH/temp_dns_servers.list"
> "$cleaned_file"
# 清理输入文件并去重
while IFS= read -r line || [ -n "$line" ]; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
[ -z "$line" ] && continue
echo "$line" | grep -qE '^#' && continue
echo "$line" >> "$cleaned_file"
done < "/etc/ssrplus/dnsproxy_dns.list"
# 获取清理后文件的MD5
cleaned_md5=$(md5sum "$cleaned_file" | awk '{print $1}')
if [ ! -f "$shunt_dnsproxy_dnsserver_file" ]; then
cp "$cleaned_file" "$shunt_dnsproxy_dnsserver_file"
else
target_md5=$(md5sum "$shunt_dnsproxy_dnsserver_file" | awk '{print $1}')
if [ "$cleaned_md5" != "$target_md5" ]; then
> "$temp_file"
# 保留目标文件中也存在于清理文件的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if grep -qixF "$line" "$cleaned_file" && ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$shunt_dnsproxy_dnsserver_file"
# 添加清理文件中有但目标文件没有的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$cleaned_file"
temp_md5=$(md5sum "$temp_file" | awk '{print $1}')
if [ "$temp_md5" != "$target_md5" ]; then
mv "$temp_file" "$shunt_dnsproxy_dnsserver_file"
else
rm -f "$temp_file"
fi
fi
fi
rm -f "$cleaned_file"
if [ -n "$shunt_dnsproxy_dnsserver_file" ] && [ -s "$shunt_dnsproxy_dnsserver_file" ]; then
local shunt_upstreams_logic_mode="$(uci_get_by_type global shunt_upstreams_logic_mode)"
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_port -p $tmp_shunt_dns_port -u $shunt_dnsproxy_dnsserver_file $shunt_disabled_ipv6 --cache --cache-min-ttl=3600 --upstream-mode=$shunt_upstreams_logic_mode
fi
fi
echolog "DNSPROXY shunt query and cache Started!"
;;
5)
local chinadns_ng_shunt_proto="$(uci_get_by_type global chinadns_ng_shunt_proto)"
local chinadns_ng_shunt_dns=""
# 遍历每个 DNS 服务器
IFS=',' # 设置分隔符为逗号
for chinadns_ng_shunt_server in $shunt_dnsserver; do
# 处理单个服务器地址
local chinadns_ng_shunt_ip="${chinadns_ng_shunt_server%%:*}"
local chinadns_ng_shunt_port="${chinadns_ng_shunt_server##*:}"
[ "$chinadns_ng_shunt_ip" = "$chinadns_ng_shunt_port" ] && chinadns_ng_shunt_port="53"
chinadns_ng_shunt_tls_port="853"
# 根据协议类型格式化服务器地址
case "$chinadns_ng_shunt_proto" in
"none")
chinadns_ng_shunt_server="${chinadns_ng_shunt_ip}#${chinadns_ng_shunt_port}"
;;
"tls")
chinadns_ng_shunt_server="${chinadns_ng_shunt_proto}://${chinadns_ng_shunt_ip}#${chinadns_ng_shunt_tls_port}"
;;
*)
chinadns_ng_shunt_server="${chinadns_ng_shunt_proto}://${chinadns_ng_shunt_ip}#${chinadns_ng_shunt_port}"
;;
esac
# 添加到参数列表
chinadns_ng_shunt_dns="${chinadns_ng_shunt_dns} -t ${chinadns_ng_shunt_server}"
done
unset IFS # 恢复默认分隔符
shunt_dnsserver="$chinadns_ng_shunt_dns"
# 启动 chinadns-ng
ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_port -l $tmp_shunt_dns_port -p 3 -d gfw $shunt_dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20
echolog "ChinaDNS-NG shunt query and cache Started!"
;;
esac
}
shunt_dns_config_file_port() {
if [ "$LOCAL_SERVER" == "$SHUNT_SERVER" ]; then
# NetFlix 和 全局socks 节点相同
if [ "$(uci_get_by_type socks5_proxy socks5_auth nil)" != "noauth" ]; then
# 全局socks 有密码NetFlix 不能使用 auth 验证,需更换为新端口并使用无密码的 socks 配置用于分流
# 新增NetFlix dns 使用端口
local port=$tmp_shunt_local_port
jq --arg port "$port" '.inbounds |= .[0:1] + [{"protocol":"socks","port":($port | tonumber),"settings":{"udp":true,"auth":"noauth"}}] + .[1:]' "$shunt_config_file" > "$shunt_config_file.tmp" && mv "$shunt_config_file.tmp" $shunt_config_file
echo $port # 返回端口号
return 0 # 成功返回
else
sed -i -e '/"mixed"/d' $shunt_config_file
fi
else
# NetFlix 和 全局 socks 节点不相同
if [ "$(uci_get_by_type socks5_proxy socks5_auth nil)" != "noauth" ]; then
# 全局socks 有密码NetFlix不能使用auth验证需设置为无密码的socks配置用于分流
# 删除 NetFlix dns 端口密码验证
sed -i \
-e '/"mixed"/d' \
-e 's/"auth"\s*:\s*"password"/\"auth\": \"noauth\"/g' \
-e '/"accounts": \[/,/\]/d' $shunt_config_file
else
sed -i -e '/"mixed"/d' $shunt_config_file
fi
fi
# 使用传入的端口
echo $1 # 返回传入的端口号
return 0 # 成功返回
}
start_shunt() { start_shunt() {
local type=$(uci_get_by_name $SHUNT_SERVER type) local type=$(uci_get_by_name $SHUNT_SERVER type)
local has_ss_type=$(uci_get_by_type server_subscribe ss_type)
case "$type" in case "$type" in
ss | ssr) ss | ssr)
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
ss_program="$(first_type ${type}local ${type}-redir)" if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
ss_program="$(first_type ${type}-redir)"
elif [ "$has_ss_type" = "ss-rust" ]; then
ss_program="$(first_type ${type}local)"
fi
echolog "$(get_name $type) program is: $ss_program"
# 获取当前软链接指向的执行文件路径
old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null)
# **当新旧执行文件路径不同时,删除旧链接**
if [ "$old_ss_program" != "$ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-redir"
fi
ln_start_bin $ss_program ${type}-redir -c $shunt_config_file ln_start_bin $ss_program ${type}-redir -c $shunt_config_file
if [ -n "$tmp_local_port" ]; then if [ -n "$tmp_local_port" ]; then
local tmp_port=$tmp_local_port local tmp_port=$tmp_local_port
else else
local tmp_port=$tmp_shunt_local_port local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type ${type}local ${type}-local) ${type}-local -c $shunt_dns_config_file if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
dns_ss_program="$(first_type ${type}-local)"
elif [ "$has_ss_type" = "ss-rust" ]; then
dns_ss_program="$(first_type ${type}local)"
fi fi
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q # 获取当前软链接指向的执行文件路径
old_dns_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-local" 2>/dev/null)
if [ "$old_dns_ss_program" != "$dns_ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-local"
fi
ln_start_bin $dns_ss_program ${type}-local -c $shunt_dns_config_file
fi
shunt_dns_command $tmp_port
echolog "shunt:$(get_name $type) Started!" echolog "shunt:$(get_name $type) Started!"
;; ;;
v2ray) v2ray)
local tmp_port=${tmp_local_port:-$tmp_shunt_local_port} local tmp_port=${tmp_local_port:-$tmp_shunt_local_port}
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port
# 处理配置文件中的 NetFlix 端口
tmp_port=$(shunt_dns_config_file_port $tmp_port)
ln_start_bin $(first_type xray v2ray) v2ray run -c $shunt_config_file ln_start_bin $(first_type xray v2ray) v2ray run -c $shunt_config_file
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "shunt:$($(first_type xray v2ray) version | head -1) Started!" echolog "shunt:$($(first_type xray v2ray) version | head -1) Started!"
;; ;;
trojan) trojan)
@ -511,7 +837,7 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type trojan) $type --config $shunt_dns_config_file ln_start_bin $(first_type trojan) $type --config $shunt_dns_config_file
fi fi
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "shunt:$($(first_type trojan) --version 2>&1 | head -1) Started!" echolog "shunt:$($(first_type trojan) --version 2>&1 | head -1) Started!"
;; ;;
naiveproxy) naiveproxy)
@ -523,11 +849,11 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type naive) naive --config $shunt_dns_config_file ln_start_bin $(first_type naive) naive --config $shunt_dns_config_file
fi fi
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "shunt:$($(first_type "naive") --version 2>&1 | head -1) Started!" echolog "shunt:$($(first_type "naive") --version 2>&1 | head -1) Started!"
redir_udp=0 redir_udp=0
;; ;;
hysteria) hysteria2)
if [ -n "$tmp_local_port" ]; then if [ -n "$tmp_local_port" ]; then
local tmp_port=$tmp_local_port local tmp_port=$tmp_local_port
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port
@ -536,7 +862,7 @@ start_shunt() {
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port
fi fi
ln_start_bin $(first_type hysteria) hysteria client --config $shunt_config_file ln_start_bin $(first_type hysteria) hysteria client --config $shunt_config_file
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "shunt:$($(first_type hysteria) version | grep Version | awk '{print "Hysteria2: " $2}') Started!" echolog "shunt:$($(first_type hysteria) version | grep Version | awk '{print "Hysteria2: " $2}') Started!"
;; ;;
tuic) tuic)
@ -548,7 +874,7 @@ start_shunt() {
[ -n "$tmp_local_port" ] && tmp_port=$tmp_local_port || tmp_port=$tmp_shunt_local_port [ -n "$tmp_local_port" ] && tmp_port=$tmp_local_port || tmp_port=$tmp_shunt_local_port
gen_config_file $SHUNT_SERVER $type 3 $tmp_port # make a tuic socks :304 gen_config_file $SHUNT_SERVER $type 3 $tmp_port # make a tuic socks :304
ln_start_bin $(first_type tuic-client) tuic-client --config $shunt_dns_config_file ln_start_bin $(first_type tuic-client) tuic-client --config $shunt_dns_config_file
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "Netflix Separated Shunt Server:tuic-client $($(first_type tuic-client) --version) Started!" echolog "Netflix Separated Shunt Server:tuic-client $($(first_type tuic-client) --version) Started!"
# FIXME: ipt2socks cannot handle udp reply from tuic # FIXME: ipt2socks cannot handle udp reply from tuic
#redir_udp=0 #redir_udp=0
@ -558,7 +884,7 @@ start_shunt() {
gen_config_file $SHUNT_SERVER $type 3 "10${tmp_shunt_port}" $tmp_port chain/$tmp_shunt_port #make a redir:303 and a socks:304 gen_config_file $SHUNT_SERVER $type 3 "10${tmp_shunt_port}" $tmp_port chain/$tmp_shunt_port #make a redir:303 and a socks:304
#echo "debug \$tmp_port=$tmp_port, \$tmp_shunt_port=${tmp_shunt_port}, \$tmp_shunt_local_port=$tmp_shunt_local_port" #echo "debug \$tmp_port=$tmp_port, \$tmp_shunt_port=${tmp_shunt_port}, \$tmp_shunt_local_port=$tmp_shunt_local_port"
ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:"${tmp_port}" 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
local chain_type=$(uci_get_by_name $SHUNT_SERVER chain_type) local chain_type=$(uci_get_by_name $SHUNT_SERVER chain_type)
case ${chain_type} in case ${chain_type} in
vmess) vmess)
@ -584,7 +910,7 @@ start_shunt() {
# local tmp_port=$tmp_shunt_local_port # local tmp_port=$tmp_shunt_local_port
# ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus # ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus
# fi # fi
# ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q # shunt_dns_command $tmp_port
# echolog "shunt:$type REDIRECT/TPROXY Started!" # echolog "shunt:$type REDIRECT/TPROXY Started!"
# ;; # ;;
*) *)
@ -596,7 +922,7 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus
fi fi
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q shunt_dns_command $tmp_port
echolog "shunt:$type REDIRECT/TPROXY Started!" echolog "shunt:$type REDIRECT/TPROXY Started!"
;; ;;
esac esac
@ -608,10 +934,22 @@ start_local() {
local local_port=$(uci_get_by_type socks5_proxy local_port) local local_port=$(uci_get_by_type socks5_proxy local_port)
[ "$LOCAL_SERVER" == "$SHUNT_SERVER" ] && tmp_local_port=$local_port [ "$LOCAL_SERVER" == "$SHUNT_SERVER" ] && tmp_local_port=$local_port
local type=$(uci_get_by_name $LOCAL_SERVER type) local type=$(uci_get_by_name $LOCAL_SERVER type)
local has_ss_type=$(uci_get_by_type server_subscribe ss_type)
case "$type" in case "$type" in
ss | ssr) ss | ssr)
gen_config_file $LOCAL_SERVER $type 4 $local_port gen_config_file $LOCAL_SERVER $type 4 $local_port
ss_program="$(first_type ${type}local ${type}-local)" if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
ss_program="$(first_type ${type}-local)"
elif [ "$has_ss_type" = "ss-rust" ]; then
ss_program="$(first_type ${type}local)"
fi
echolog "$(get_name $type) program is: $ss_program"
# 获取当前软链接指向的执行文件路径
old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-local" 2>/dev/null)
# **当 新旧执行文件路径不同时,删除旧链接**
if [ "$old_ss_program" != "$ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-local"
fi
ln_start_bin $ss_program ${type}-local -c $local_config_file ln_start_bin $ss_program ${type}-local -c $local_config_file
echolog "Global_Socks5:$(get_name $type) Started!" echolog "Global_Socks5:$(get_name $type) Started!"
;; ;;
@ -632,7 +970,7 @@ start_local() {
ln_start_bin $(first_type naive) naive --config $local_config_file ln_start_bin $(first_type naive) naive --config $local_config_file
echolog "Global_Socks5:$($(first_type naive) --version | head -1) Started!" echolog "Global_Socks5:$($(first_type naive) --version | head -1) Started!"
;; ;;
hysteria) hysteria2)
if [ "$_local" == "2" ]; then if [ "$_local" == "2" ]; then
gen_config_file $LOCAL_SERVER $type 4 0 $local_port gen_config_file $LOCAL_SERVER $type 4 0 $local_port
ln_start_bin $(first_type hysteria) hysteria client --config $local_config_file ln_start_bin $(first_type hysteria) hysteria client --config $local_config_file
@ -702,12 +1040,24 @@ Start_Run() {
fi fi
local tcp_port=$(uci_get_by_name $GLOBAL_SERVER local_port) local tcp_port=$(uci_get_by_name $GLOBAL_SERVER local_port)
local type=$(uci_get_by_name $GLOBAL_SERVER type) local type=$(uci_get_by_name $GLOBAL_SERVER type)
local has_ss_type=$(uci_get_by_type server_subscribe ss_type)
case "$type" in case "$type" in
ss | ssr) ss | ssr)
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port gen_config_file $GLOBAL_SERVER $type 1 $tcp_port
ss_program="$(first_type ${type}local ${type}-redir)" if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
ss_program="$(first_type ${type}-redir)"
elif [ "$has_ss_type" = "ss-rust" ]; then
ss_program="$(first_type ${type}local)"
fi
echolog "$(get_name $type) program is: $ss_program"
# 获取当前软链接指向的执行文件路径
old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-redir" 2>/dev/null)
# **当新旧执行文件路径不同时,删除旧链接**
if [ "$old_ss_program" != "$ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-redir"
fi
for i in $(seq 1 $threads); do for i in $(seq 1 $threads); do
ln_start_bin "$ss_program" ${type}-redir -c $tcp_config_file ln_start_bin $ss_program ${type}-redir -c $tcp_config_file
done done
echolog "Main node:$(get_name $type) $threads Threads Started!" echolog "Main node:$(get_name $type) $threads Threads Started!"
;; ;;
@ -728,7 +1078,7 @@ Start_Run() {
ln_start_bin $(first_type naive) naive $tcp_config_file ln_start_bin $(first_type naive) naive $tcp_config_file
echolog "Main node:$($(first_type naive) --version 2>&1 | head -1) , $threads Threads Started!" echolog "Main node:$($(first_type naive) --version 2>&1 | head -1) , $threads Threads Started!"
;; ;;
hysteria) hysteria2)
gen_config_file $GLOBAL_SERVER $type 1 $tcp_port $socks_port gen_config_file $GLOBAL_SERVER $type 1 $tcp_port $socks_port
ln_start_bin $(first_type hysteria) hysteria client --config $tcp_config_file ln_start_bin $(first_type hysteria) hysteria client --config $tcp_config_file
echolog "Main node:$($(first_type hysteria) version | grep Version | awk '{print "Hysteria2: " $2}') Started!" echolog "Main node:$($(first_type hysteria) version | grep Version | awk '{print "Hysteria2: " $2}') Started!"
@ -797,7 +1147,13 @@ load_config() {
else else
GLOBAL_SERVER=$switch_server GLOBAL_SERVER=$switch_server
fi fi
if [ "$(uci_get_by_type socks5_proxy enabled 0)" == "1" ]; then
# 只有开启 全局socks 才需要取值
LOCAL_SERVER=$(uci_get_by_type socks5_proxy server nil) LOCAL_SERVER=$(uci_get_by_type socks5_proxy server nil)
else
# 没有开启 设置为 nil
LOCAL_SERVER=nil
fi
if [ "$GLOBAL_SERVER" == "nil" ]; then if [ "$GLOBAL_SERVER" == "nil" ]; then
mode="tcp,udp" mode="tcp,udp"
_local="2" _local="2"
@ -806,7 +1162,13 @@ load_config() {
return 1 return 1
fi fi
UDP_RELAY_SERVER=$(uci_get_by_type global udp_relay_server nil) UDP_RELAY_SERVER=$(uci_get_by_type global udp_relay_server nil)
if [ "$(uci_get_by_type global netflix_enable 0)" == "1" ]; then
# 只有开启 NetFlix分流 才需要取值
SHUNT_SERVER=$(uci_get_by_type global netflix_server nil) SHUNT_SERVER=$(uci_get_by_type global netflix_server nil)
else
# 没有开启 设置为 nil
SHUNT_SERVER=nil
fi
tcp_config_file=$TMP_PATH/tcp-only-ssr-retcp.json tcp_config_file=$TMP_PATH/tcp-only-ssr-retcp.json
case "$UDP_RELAY_SERVER" in case "$UDP_RELAY_SERVER" in
nil) nil)
@ -895,11 +1257,28 @@ start_server() {
server_service() { server_service() {
[ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1 [ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1
let server_count=server_count+1 let server_count=server_count+1
if [ "$server_count" == "1" ]; then
if ! (iptables-save -t filter | grep SSR-SERVER-RULE >/dev/null); then
iptables -N SSR-SERVER-RULE && iptables -t filter -I INPUT -j SSR-SERVER-RULE
fi
fi
local type=$(uci_get_by_name $1 type) local type=$(uci_get_by_name $1 type)
local has_ss_type=$(uci_get_by_type server_subscribe ss_type)
case "$type" in case "$type" in
ss | ssr) ss | ssr)
gen_service_file ${type} $1 $TMP_PATH/ssr-server$server_count.json gen_service_file ${type} $1 $TMP_PATH/ssr-server$server_count.json
ln_start_bin $(first_type ${type}server ${type}-server) ${type}-server -c $TMP_PATH/ssr-server$server_count.json if [ "$has_ss_type" = "ss-libev" -o "$type" = "ssr" ]; then
ss_program="$(first_type ${type}-server)"
elif [ "$has_ss_type" = "ss-rust" ]; then
ss_program="$(first_type ${type}server)"
fi
# 获取当前软链接指向的执行文件路径
old_ss_program=$(readlink -f "$TMP_PATH/bin/${type}-server" 2>/dev/null)
# **当新旧执行文件路径不同时,删除旧链接**
if [ "$old_ss_program" != "$ss_program" ]; then
rm -rf "$TMP_PATH/bin/${type}-server"
fi
ln_start_bin $ss_program ${type}-server -c $TMP_PATH/ssr-server$server_count.json
echolog "Server: $(get_name ${type}) Server$server_count Started!" echolog "Server: $(get_name ${type}) Server$server_count Started!"
;; ;;
socks5) socks5)
@ -922,9 +1301,28 @@ start_server() {
fi fi
return 0 return 0
} }
gen_serv_include() {
local FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null)
[ -n "$FWI" ] || return 0
if [ ! -f $FWI ]; then
echo '#!/bin/sh' >$FWI
fi
extract_rules() {
echo "*filter"
iptables-save -t filter | grep SSR-SERVER-RULE | sed -e "s/^-A INPUT/-I INPUT/"
echo 'COMMIT'
}
cat <<-EOF >>$FWI
iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c
iptables-restore -n <<-EOT
$(extract_rules)
EOT
EOF
}
config_load $NAME config_load $NAME
config_foreach server_service server_config config_foreach server_service server_config
gen_serv_include
return 0 return 0
} }
@ -1082,7 +1480,12 @@ stop() {
uci -q commit "dhcp" uci -q commit "dhcp"
fi fi
if [ -f "$DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf" ]; then if [ -f "$DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf" ]; then
rm -rf $DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf $TMP_DNSMASQ_PATH $TMP_PATH/*-ssr-*.json $TMP_PATH/ssr-server*.json rm -rf $DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf \
$TMP_DNSMASQ_PATH \
$TMP_PATH/*-ssr-*.json \
$TMP_PATH/ssr-server*.json \
$TMP_PATH/*-config-*.json
/etc/init.d/dnsmasq restart >/dev/null 2>&1 /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi fi
uci -q delete firewall.shadowsocksr_server uci -q delete firewall.shadowsocksr_server
@ -1100,3 +1503,4 @@ reset() {
cp /usr/share/shadowsocksr/shadowsocksr.config /etc/config/shadowsocksr cp /usr/share/shadowsocksr/shadowsocksr.config /etc/config/shadowsocksr
unset_lock unset_lock
} }

View File

@ -0,0 +1,17 @@
# cloudflare-dns.com
sdns://AgcAAAAAAAAADjEwNC4xNi4yNDkuMjQ5ABJjbG91ZGZsYXJlLWRucy5jb20KL2Rucy1xdWVyeQ
# Google
sdns://AgUAAAAAAAAABzguOC40LjQgsKKKE4EwvtIbNjGjagI2607EdKSVHowYZtyvD9iPrkkHOC44LjQuNAovZG5zLXF1ZXJ5
# dns.sb
sdns://AgcAAAAAAAAADzE4NS4yMjIuMjIyLjIyMiAOp5Svj-oV-Fz-65-8H2VKHLKJ0egmfEgrdPeAQlUFFA8xODUuMjIyLjIyMi4yMjIKL2Rucy1xdWVyeQ
# Quad9
sdns://AgMAAAAAAAAADTE0OS4xMTIuMTEyLjkgsBkgdEu7dsmrBT4B4Ht-BQ5HPSD3n3vqQ1-v5DydJC8SZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk
sdns://AQMAAAAAAAAADDkuOS45Ljk6ODQ0MyBnyEe4yHWM0SAkVUO-dWdG3zTfHYTAC4xHA2jfgh2GPhkyLmRuc2NyeXB0LWNlcnQucXVhZDkubmV0
# AdGuard
sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20
# Cloudflare
sdns://AgcAAAAAAAAABzEuMC4wLjGgENk8mGSlIfMGXMOlIlCcKvq7AVgcrZxtjon911-ep0cg63Ul-I8NlFj4GplQGb_TTLiczclX57DvMV8Q-JdjgRgSZG5zLmNsb3VkZmxhcmUuY29tCi9kbnMtcXVlcnk
# TWNIC-101
sdns://AgcAAAAAAAAAACC2vD25TAYM7EnyCH8Xw1-0g5OccnTsGH9vQUUH0njRtAxkbnMudHduaWMudHcKL2Rucy1xdWVyeQ
# cs-tx
sdns://AQYAAAAAAAAADTIwOS41OC4xNDcuMzYgMTNyrVlWMsJBa4cvCY-FG925ZShMbL6aTxkJZDDbqVoeMi5kbnNjcnlwdC1jZXJ0LmNyeXB0b3N0b3JtLmlz

View File

@ -0,0 +1,43 @@
log:
level: info
plugins:
- tag: lazy_cache
type: cache
args:
size: 8000
lazy_cache_ttl: 86400
- tag: forward_google
type: forward
args:
concurrent: 2
upstreams:
- tag: main_sequence_disable_IPv6
type: sequence
args:
- exec: $lazy_cache
- exec: prefer_ipv4
- exec: $forward_google
- matches:
- qtype 28 65
exec: reject 0
- tag: main_sequence_with_IPv6
type: sequence
args:
- exec: $lazy_cache
- exec: $forward_google
- tag: udp_server
type: udp_server
args:
entry: DNS_MODE
listen: 0.0.0.0:DNS_PORT
- tag: tcp_server
type: tcp_server
args:
entry: DNS_MODE
listen: 0.0.0.0:DNS_PORT

View File

@ -95,7 +95,7 @@ while [ "1" == "1" ]; do #死循环
#dns2socks #dns2socks
elif [ "$pdnsd_process" -eq 2 ]; then elif [ "$pdnsd_process" -eq 2 ]; then
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l) icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l)
if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它 if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "dns2socks $dnsserver tunnel error.restart!" logger -t "$NAME" "dns2socks $dnsserver tunnel error.restart!"
echolog "dns2socks $dnsserver tunnel error.restart!" echolog "dns2socks $dnsserver tunnel error.restart!"
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
@ -104,8 +104,128 @@ while [ "1" == "1" ]; do #死循环
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q
fi fi
#dns2socks-rust
elif [ "$pdnsd_process" -eq 3 ]; then
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks-rust -s socks5://127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l)
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "dns2socks-rust $dnsserver tunnel error.restart!"
echolog "dns2socks-rust $dnsserver tunnel error.restart!"
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
kill -9 $(busybox ps -w | grep ssrplus-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
kill -9 $(busybox ps -w | grep "dns2socks-rust -s socks5://127.0.0.1 $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
ln_start_bin $(first_type dns2socks) dns2socks-rust -s socks5://127.0.0.1:$tmp_dns_port -d $dnsserver -l 127.0.0.1:$dns_port -f -c
fi fi
#chinadns-ng #mosdns
elif [ "$pdnsd_process" -eq 4 ]; then
icount=$(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | wc -l)
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "mosdns tunnel error.restart!"
echolog "mosdns tunnel error.restart!"
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
ln_start_bin $(first_type mosdns) mosdns start -c /etc/mosdns/config.yaml
#dnsproxy
elif [ "$pdnsd_process" -eq 5 ]; then
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dnsproxy -l 127.0.0.1 -p $tmp_dns_port" | grep -v grep | wc -l)
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "dnsproxy $dnsserver tunnel error.restart!"
echolog "dnsproxy $dnsserver tunnel error.restart!"
local dnsproxy_dnsserver="$(uci_get_by_type global parse_method)"
if [ -n "$dnsproxy_dnsserver" ] && [ "$dnsproxy_dnsserver" != "parse_file" ]; then
dnsserver="$(uci_get_by_type global dnsproxy_tunnel_forward 8.8.4.4:53)"
fi
kill -9 $(busybox ps -w | grep "dnsproxy -l 127.0.0.1 -p $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
dnsproxy_ipv6="$(uci_get_by_type global dnsproxy_ipv6)"
disabled_ipv6="--ipv6-disabled"
fi
if [ "$dnsproxy_dnsserver" != "parse_file" ]; then
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsserver $disabled_ipv6 --cache --cache-min-ttl=3600
else
dnsproxy_dnsserver_file="$TMP_PATH/dnsproxy_dns.list"
cleaned_file="$TMP_PATH/cleaned_dns.list"
temp_file="$TMP_PATH/temp_dns.list"
> "$cleaned_file"
# 清理输入文件并去重
while IFS= read -r line || [ -n "$line" ]; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
[ -z "$line" ] && continue
echo "$line" | grep -qE '^#' && continue
echo "$line" >> "$cleaned_file"
done < "/etc/ssrplus/dnsproxy_dns.list"
# 获取清理后文件的MD5
cleaned_md5=$(md5sum "$cleaned_file" | awk '{print $1}')
if [ ! -f "$dnsproxy_dnsserver_file" ]; then
cp "$cleaned_file" "$dnsproxy_dnsserver_file"
else
target_md5=$(md5sum "$dnsproxy_dnsserver_file" | awk '{print $1}')
if [ "$cleaned_md5" != "$target_md5" ]; then
> "$temp_file"
# 保留目标文件中也存在于清理文件的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if grep -qixF "$line" "$cleaned_file" && ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$dnsproxy_dnsserver_file"
# 添加清理文件中有但目标文件没有的记录(去重)
while IFS= read -r line; do
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
if ! grep -qixF "$line" "$temp_file"; then
echo "$line" >> "$temp_file"
fi
done < "$cleaned_file"
temp_md5=$(md5sum "$temp_file" | awk '{print $1}')
if [ "$temp_md5" != "$target_md5" ]; then
mv "$temp_file" "$dnsproxy_dnsserver_file"
else
rm -f "$temp_file"
fi
fi
fi
rm -f "$cleaned_file"
if [ -n "$dnsproxy_dnsserver_file" ] && [ -s "$dnsproxy_dnsserver_file" ]; then
local upstreams_logic_mode="$(uci_get_by_type global upstreams_logic_mode)"
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsproxy_dnsserver_file $disabled_ipv6 --cache --cache-min-ttl=3600 --upstream-mode=$upstreams_logic_mode
fi
fi
fi
#chinadns-ng(proxy)
elif [ "$pdnsd_process" -eq 6 ]; then
icount=$(busybox ps -w | grep -e ssrplus-dns -e "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | wc -l)
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
logger -t "$NAME" "chinadns-ng $dnsserver tunnel error.restart!"
echolog "chinadns-ng $dnsserver tunnel error.restart!"
dnsserver=$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53)
kill -9 $(busybox ps -w | grep "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)"
local chinadns_ng_dns=""
IFS=','
for chinadns_ng_server in $dnsserver; do
local chinadns_ng_ip="${chinadns_ng_server%%:*}"
local chinadns_ng_port="${chinadns_ng_server##*:}"
[ "$chinadns_ng_ip" = "$chinadns_ng_port" ] && chinadns_ng_port="53"
chinadns_ng_tls_port="853"
case "$chinadns_ng_proto" in
"none")
chinadns_ng_server="${chinadns_ng_ip}#${chinadns_ng_port}"
;;
"tls")
chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_tls_port}"
;;
*)
chinadns_ng_server="${chinadns_ng_proto}://${chinadns_ng_ip}#${chinadns_ng_port}"
;;
esac
chinadns_ng_dns="${chinadns_ng_dns} -t ${chinadns_ng_server}"
done
unset IFS
dnsserver="$chinadns_ng_dns"
ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_dns_port -l $dns_port -p 3 -d gfw $dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20
fi
fi
#chinadns-ng(china)
if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then
icount=$(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l) icount=$(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l)
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它 if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它

View File

@ -184,11 +184,11 @@ if proto and proto:find("tcp") and socks_port ~= "0" then
-- socks -- socks
protocol = "socks", protocol = "socks",
port = tonumber(socks_port), port = tonumber(socks_port),
settings = (socks_server.server ~= "same") and { settings = {
auth = socks_server.socks5_auth, auth = socks_server.socks5_auth or "noauth",
udp = true, udp = true,
mixed = (socks_server.socks5_mixed == '1') and true or false, mixed = ((socks_server.socks5_mixed == '1') and true or false) or (socks_server.server == 'same') and nil,
accounts = (socks_server.socks5_auth ~= "noauth") and { accounts = (socks_server.server ~= "same" and (socks_server.socks5_auth and socks_server.socks5_auth ~= "noauth")) and {
{ {
user = socks_server.socks5_user, user = socks_server.socks5_user,
pass = socks_server.socks5_pass pass = socks_server.socks5_pass
@ -310,7 +310,7 @@ end
} or nil, } or nil,
sockopt = { sockopt = {
mark = 250, mark = 250,
tcpFastOpen = (server.tcpfastOpen == "1") and true or false, -- XHTTP Tcp Fast Open tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法 tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
@ -350,7 +350,7 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
streamSettings = { streamSettings = {
sockopt = { sockopt = {
mark = 250, mark = 250,
tcpFastOpen = (server.tcpfastOpen == "1") and true or false, -- XHTTP Tcp Fast Open tcpFastOpen = ((server.transport == "xhttp" and server.tcpfastopen == "1") and true or false) or (server.transport ~= "xhttp") and nil, -- XHTTP Tcp Fast Open
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP Penetrate = (server.mptcp == "1") and true or nil, -- Penetrate MPTCP
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法 tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
@ -411,18 +411,18 @@ local ss = {
fast_open = (server.fast_open == "1") and true or false, fast_open = (server.fast_open == "1") and true or false,
reuse_port = true reuse_port = true
} }
local hysteria = { local hysteria2 = {
server = (server.server_port and (server.port_range and (server.server .. ":" .. server.server_port .. "," .. server.port_range) or (server.server .. ":" .. server.server_port) or (server.port_range and server.server .. ":" .. server.port_range or server.server .. ":443"))), server = (server.server_port and (server.port_range and (server.server .. ":" .. server.server_port .. "," .. string.gsub(server.port_range, ":", "-")) or (server.server .. ":" .. server.server_port) or (server.port_range and server.server .. ":" .. string.gsub(server.port_range, ":", "-") or server.server .. ":443"))),
bandwidth = (server.uplink_capacity or server.downlink_capacity) and { bandwidth = (server.uplink_capacity or server.downlink_capacity) and {
up = tonumber(server.uplink_capacity) and tonumber(server.uplink_capacity) .. " mbps" or nil, up = tonumber(server.uplink_capacity) and tonumber(server.uplink_capacity) .. " mbps" or nil,
down = tonumber(server.downlink_capacity) and tonumber(server.downlink_capacity) .. " mbps" or nil down = tonumber(server.downlink_capacity) and tonumber(server.downlink_capacity) .. " mbps" or nil
}, } or nil,
socks5 = (proto:find("tcp") and tonumber(socks_port) and tonumber(socks_port) ~= 0) and { socks5 = (proto:find("tcp") and tonumber(socks_port) and tonumber(socks_port) ~= 0) and {
listen = "0.0.0.0:" .. tonumber(socks_port), listen = "0.0.0.0:" .. tonumber(socks_port),
disable_udp = false disable_udp = false
} or nil, } or nil,
transport = (server.transport_protocol) and { transport = server.transport_protocol and {
type = (server.transport_protocol) or udp, type = server.transport_protocol or "udp",
udp = (server.port_range and (server.hopinterval) and { udp = (server.port_range and (server.hopinterval) and {
hopInterval = (server.port_range and (tonumber(server.hopinterval) .. "s") or nil) hopInterval = (server.port_range and (tonumber(server.hopinterval) .. "s") or nil)
} or nil) } or nil)
@ -579,8 +579,12 @@ function config:handleIndex(index)
local switch = { local switch = {
ss = function() ss = function()
ss.protocol = socks_port ss.protocol = socks_port
if server.plugin and server.plugin ~= "none" then if server.enable_plugin == "1" and server.plugin and server.plugin ~= "none" then
if server.plugin == "custom" then
ss.plugin = server.custom_plugin
else
ss.plugin = server.plugin ss.plugin = server.plugin
end
ss.plugin_opts = server.plugin_opts or nil ss.plugin_opts = server.plugin_opts or nil
end end
print(json.stringify(ss, 1)) print(json.stringify(ss, 1))
@ -602,8 +606,8 @@ function config:handleIndex(index)
naiveproxy = function() naiveproxy = function()
print(json.stringify(naiveproxy, 1)) print(json.stringify(naiveproxy, 1))
end, end,
hysteria = function() hysteria2 = function()
print(json.stringify(hysteria, 1)) print(json.stringify(hysteria2, 1))
end, end,
shadowtls = function() shadowtls = function()
local chain_switch = { local chain_switch = {
@ -637,3 +641,4 @@ function config:handleIndex(index)
end end
local f = config:new() local f = config:new()
f:handleIndex(server.type) f:handleIndex(server.type)

View File

@ -1,5 +1,7 @@
#!/bin/sh #!/bin/sh
. $IPKG_INSTROOT/etc/init.d/shadowsocksr . $IPKG_INSTROOT/etc/init.d/shadowsocksr
netflix() { netflix() {
if [ -f "$TMP_DNSMASQ_PATH/gfw_list.conf" ]; then if [ -f "$TMP_DNSMASQ_PATH/gfw_list.conf" ]; then
for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
@ -14,7 +16,14 @@ else
cp -rf /etc/ssrplus/gfw_list.conf $TMP_DNSMASQ_PATH/ cp -rf /etc/ssrplus/gfw_list.conf $TMP_DNSMASQ_PATH/
cp -rf /etc/ssrplus/gfw_base.conf $TMP_DNSMASQ_PATH/ cp -rf /etc/ssrplus/gfw_base.conf $TMP_DNSMASQ_PATH/
fi fi
case "$(uci_get_by_type global netflix_server nil)" in if [ "$(uci_get_by_type global netflix_enable 0)" == "1" ]; then
# 只有开启 NetFlix分流 才需要取值
SHUNT_SERVER=$(uci_get_by_type global netflix_server nil)
else
# 没有开启 设置为 nil
SHUNT_SERVER=nil
fi
case "$SHUNT_SERVER" in
nil) nil)
rm -f $TMP_DNSMASQ_PATH/netflix_forward.conf rm -f $TMP_DNSMASQ_PATH/netflix_forward.conf
;; ;;
@ -25,12 +34,14 @@ $(uci_get_by_type global global_server nil) | $switch_server | same)
netflix $tmp_shunt_dns_port netflix $tmp_shunt_dns_port
;; ;;
esac esac
for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done # 此处使用while方式读取 防止 /etc/ssrplus/ 目录下的 black.list white.list deny.list 等2个或多个文件一行中存在空格 比如:# abc.com 而丢失server
for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/black.list
for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/black.list
for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/white.list
for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/white.list
for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/deny.list
while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/deny.list
# 此处直接使用 cat 因为有 sed '/#/d' 删除了 数据
cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nipset=\/&\/blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nipset=\/&\/blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf
cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf
cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/&\//" >$TMP_DNSMASQ_PATH/denylist.conf
@ -45,3 +56,4 @@ if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
else else
rm -f $TMP_DNSMASQ_PATH/ad.conf rm -f $TMP_DNSMASQ_PATH/ad.conf
fi fi

View File

@ -10,6 +10,7 @@ require "luci.util"
require "luci.sys" require "luci.sys"
require "luci.jsonc" require "luci.jsonc"
require "luci.model.ipkg" require "luci.model.ipkg"
-- these global functions are accessed all the time by the event handler -- these global functions are accessed all the time by the event handler
-- so caching them is worth the effort -- so caching them is worth the effort
local tinsert = table.insert local tinsert = table.insert
@ -21,14 +22,26 @@ local cache = {}
local nodeResult = setmetatable({}, {__index = cache}) -- update result local nodeResult = setmetatable({}, {__index = cache}) -- update result
local name = 'shadowsocksr' local name = 'shadowsocksr'
local uciType = 'servers' local uciType = 'servers'
local ucic = luci.model.uci.cursor() local ucic = require "luci.model.uci".cursor()
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0') local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1') local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
local allow_insecure = ucic:get_first(name, 'server_subscribe', 'allow_insecure', '0')
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {}) local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量') local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '') local save_words = ucic:get_first(name, 'server_subscribe', 'save_words', '')
local v2_ss = luci.sys.exec('type -t -p ss-redir sslocal') ~= "" and "ss" or "v2ray" -- 读取 ss_type 设置
local ss_type = ucic:get_first(name, 'server_subscribe', 'ss_type', 'ss-rust')
-- 根据 ss_type 选择对应的程序
local ss_program = ""
if ss_type == "ss-rust" then
ss_program = "sslocal" -- Rust 版本使用 sslocal
elseif ss_type == "ss-libev" then
ss_program = "ss-redir" -- Libev 版本使用 ss-redir
end
local v2_ss = luci.sys.exec('type -t -p ' .. ss_program .. ' 2>/dev/null') ~= "" and "ss" or "v2ray"
local has_ss_type = luci.sys.exec('type -t -p ' .. ss_program .. ' 2>/dev/null') ~= "" and ss_type
local v2_tj = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray" local v2_tj = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray"
local hy2_type = luci.sys.exec('type -t -p hysteria') ~= "" and "hysteria2"
local log = function(...) local log = function(...)
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " ")) print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({...}, " "))
end end
@ -62,11 +75,20 @@ local encrypt_methods_ss = {
"camellia-256-cfb", "camellia-256-cfb",
"salsa20", "salsa20",
"chacha20", "chacha20",
"chacha20-ietf" ]] "chacha20-ietf" ]]--
} }
-- 分割字符串 -- 分割字符串
local function split(full, sep) local function split(full, sep)
full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0 if full == nil or type(full) ~= "string" then
-- print("Debug: split() received nil or non-string value")
return {}
end
full = full:gsub("%z", ""):gsub("^%s+", ""):gsub("%s+$", "") -- 去除首尾空白字符和\0
if full == "" then
-- print("Debug: split() received empty string after trimming")
return {}
end
sep = sep or "," -- 默认分隔符
local off, result = 1, {} local off, result = 1, {}
while true do while true do
local nStart, nEnd = full:find(sep, off) local nStart, nEnd = full:find(sep, off)
@ -141,10 +163,65 @@ local function checkTabValue(tab)
end end
return revtab return revtab
end end
-- JSON完整性检查
local function isCompleteJSON(str)
-- 检查JSON格式
if type(str) ~= "string" or str:match("^%s*$") then
return false
end
-- 尝试解析JSON验证完整性
local success, _ = pcall(jsonParse, str)
return success
end
-- 处理数据 -- 处理数据
local function processData(szType, content) local function processData(szType, content)
local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'} local result = {type = szType, local_port = 1234, kcp_param = '--nocomp'}
if szType == 'ssr' then -- 检查JSON的格式如不完整丢弃
if not isCompleteJSON(content) then
return nil
end
if szType == "hysteria2" or szType == "hy2" then
local url = URL.parse("http://" .. content)
local params = url.query
-- 调试输出所有参数
-- log("Hysteria2 原始参数:")
-- for k,v in pairs(params) do
-- log(k.."="..v)
-- end
result.alias = url.fragment and UrlDecode(url.fragment) or nil
result.type = hy2_type
result.server = url.host
result.server_port = url.port
if params.protocol then
result.flag_transport = "1"
result.transport_protocol = params.protocol or "udp"
end
result.hy2_auth = url.user
result.uplink_capacity = params.upmbps or "5"
result.downlink_capacity = params.downmbps or "20"
if params.obfs then
result.flag_obfs = "1"
result.obfs_type = params.obfs
result.salamander = params["obfs-password"] or params["obfs_password"]
end
if params.sni then
result.tls = "1"
result.tls_host = params.sni
end
if params.insecure then
result.insecure = "1"
if params.sni then
result.pinsha256 = params.pinSHA256
end
end
if params.mport then
result.flag_port_hopping = "1"
result.port_range = params.mport
end
elseif szType == 'ssr' then
local dat = split(content, "/%?") local dat = split(content, "/%?")
local hostInfo = split(dat[1], ':') local hostInfo = split(dat[1], ':')
result.type = 'ssr' result.type = 'ssr'
@ -166,8 +243,13 @@ local function processData(szType, content)
result.alias = "[" .. group .. "] " result.alias = "[" .. group .. "] "
end end
result.alias = result.alias .. base64Decode(params.remarks) result.alias = result.alias .. base64Decode(params.remarks)
elseif szType == 'vmess' then elseif szType == "vmess" then
local info = jsonParse(content) -- 解析正常节点
local success, info = pcall(jsonParse, content)
if not success or type(info) ~= "table" then
return nil
end
-- 处理有效数据
result.type = 'v2ray' result.type = 'v2ray'
result.v2ray_protocol = 'vmess' result.v2ray_protocol = 'vmess'
result.server = info.add result.server = info.add
@ -257,7 +339,7 @@ local function processData(szType, content)
elseif info.host then elseif info.host then
result.tls_host = info.host result.tls_host = info.host
end end
result.insecure = 1 result.insecure = allow_insecure
else else
result.tls = "0" result.tls = "0"
end end
@ -268,26 +350,41 @@ local function processData(szType, content)
idx_sp = content:find("#") idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1) alias = content:sub(idx_sp + 1, -1)
end end
local info = content:sub(1, idx_sp - 1) local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content)
local hostInfo = split(base64Decode(info), "@") local hostInfo = split(base64Decode(info), "@")
if #hostInfo < 2 then
--log("SS节点格式错误解码后内容:", base64Decode(info))
return nil
end
local host = split(hostInfo[2], ":") local host = split(hostInfo[2], ":")
if #host < 2 then
--log("SS节点主机格式错误:", hostInfo[2])
return nil
end
-- 提取用户信息
local userinfo = base64Decode(hostInfo[1]) local userinfo = base64Decode(hostInfo[1])
local method = userinfo:sub(1, userinfo:find(":") - 1) local method, password = userinfo:match("^([^:]*):(.*)$")
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo) -- 填充结果
result.alias = UrlDecode(alias) result.alias = UrlDecode(alias)
result.type = v2_ss result.type = v2_ss
result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil result.v2ray_protocol = (v2_ss == "v2ray") and "shadowsocks" or nil
result.has_ss_type = has_ss_type
result.encrypt_method_ss = method result.encrypt_method_ss = method
result.password = password result.password = password
result.server = host[1] result.server = host[1]
if host[2]:find("/%?") then -- 处理端口和插件
local query = split(host[2], "/%?") local port_part = host[2]
if port_part:find("/%?") then
local query = split(port_part, "/%?")
result.server_port = query[1] result.server_port = query[1]
if query[2] then
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
if #t >= 2 then
params[t[1]] = t[2] params[t[1]] = t[2]
end end
end
if params.plugin then if params.plugin then
local plugin_info = UrlDecode(params.plugin) local plugin_info = UrlDecode(params.plugin)
local idx_pn = plugin_info:find(";") local idx_pn = plugin_info:find(";")
@ -296,17 +393,25 @@ local function processData(szType, content)
result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info) result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
else else
result.plugin = plugin_info result.plugin = plugin_info
result.plugin_opts = ""
end end
-- 部分机场下发的插件名为 simple-obfs这里应该改为 obfs-local -- 部分机场下发的插件名为 simple-obfs这里应该改为 obfs-local
if result.plugin == "simple-obfs" then if result.plugin == "simple-obfs" then
result.plugin = "obfs-local" result.plugin = "obfs-local"
end end
-- 如果插件不为 none确保 enable_plugin 为 1
if result.plugin ~= "none" and result.plugin ~= "" then
result.enable_plugin = 1
end
end
end end
else else
result.server_port = host[2]:gsub("/","") result.server_port = port_part:gsub("/","")
end end
-- 检查加密方法
if not checkTabValue(encrypt_methods_ss)[method] then if not checkTabValue(encrypt_methods_ss)[method] then
-- 1202 年了还不支持 SS AEAD 的屑机场 -- 1202 年了还不支持 SS AEAD 的屑机场
-- log("不支持的SS加密方法:", method)
result.server = nil result.server = nil
end end
elseif szType == "sip008" then elseif szType == "sip008" then
@ -343,37 +448,61 @@ local function processData(szType, content)
local params = {} local params = {}
local idx_sp = 0 local idx_sp = 0
local alias = "" local alias = ""
-- 提取别名(如果存在)
if content:find("#") then if content:find("#") then
idx_sp = content:find("#") idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1) alias = content:sub(idx_sp + 1, -1)
end end
local info = content:sub(1, idx_sp - 1) local info = content:sub(1, idx_sp > 0 and idx_sp - 1 or #content)
local hostInfo = split(info, "@") local hostInfo = split(info, "@")
-- 基础验证
if #hostInfo < 2 then
--log("Trojan节点格式错误: 缺少@符号")
return nil
end
local userinfo = hostInfo[1] local userinfo = hostInfo[1]
local password = userinfo local hostPort = hostInfo[2]
-- 分离服务器地址和端口 -- 分离服务器地址和端口
local host = split(hostInfo[2], ":") local hostParts = split(hostPort, ":")
local server = host[1]
local port = host[2] local server = hostParts[1]
local port = hostParts[2]
-- 验证服务器地址和端口
if #hostParts < 2 then
--log("Trojan节点格式错误: 缺少端口号")
return nil
end
result.alias = UrlDecode(alias) result.alias = UrlDecode(alias)
result.type = v2_tj result.type = v2_tj
result.v2ray_protocol = "trojan" result.v2ray_protocol = "trojan"
result.server = server result.server = server
result.password = password result.password = userinfo
-- 默认设置
-- 按照官方的建议 默认验证ssl证书 -- 按照官方的建议 默认验证ssl证书
result.insecure = "0" result.insecure = "0"
result.tls = "1" result.tls = "1"
-- 解析查询参数(如果存在)
if port:find("?") then if port:find("?") then
local query = split(port, "?") local queryParts = split(port, "?")
result.server_port = query[1] result.server_port = queryParts[1]
for _, v in pairs(split(query[2], '&')) do
-- 解析查询参数
for _, v in pairs(split(queryParts[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
if #t >= 2 then
params[t[1]] = t[2] params[t[1]] = t[2]
end end
end
-- 处理参数
if params.alpn then if params.alpn then
-- 处理 alpn 参数 -- 处理 alpn 参数
result.xhttp_alpn = params.alpn result.xhttp_alpn = params.alpn
@ -551,7 +680,10 @@ local function processData(szType, content)
end end
-- wget -- wget
local function wget(url) local function wget(url)
local stdout = luci.sys.exec('wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -O- "' .. url .. '"') -- 清理URL中的隐藏字符
url = url:gsub("%s+$", ""):gsub("^%s+", ""):gsub("%z", "")
local stdout = luci.sys.exec('wget-ssl --timeout=20 --tries=3 -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36" --no-check-certificate -O- "' .. url .. '"')
return trim(stdout) return trim(stdout)
end end
@ -661,7 +793,7 @@ local execute = function()
if result then if result then
-- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场 -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
if not result.server or not result.server_port or result.alias == "NULL" or check_filer(result) or result.server:match("[^0-9a-zA-Z%-_%.%s]") or cache[groupHash][result.hashkey] then if not result.server or not result.server_port or result.alias == "NULL" or check_filer(result) or result.server:match("[^0-9a-zA-Z%-_%.%s]") or cache[groupHash][result.hashkey] then
log('丢弃无效节点: ' .. result.type .. ' 节点, ' .. result.alias) log('丢弃无效节点: ' .. result.alias)
else else
-- log('成功解析: ' .. result.type ..' 节点, ' .. result.alias) -- log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
result.grouphashkey = groupHash result.grouphashkey = groupHash

View File

@ -8,7 +8,7 @@ require "luci.sys"
require "luci.model.uci" require "luci.model.uci"
local icount = 0 local icount = 0
local args = arg[1] local args = arg[1]
local uci = luci.model.uci.cursor() local uci = require "luci.model.uci".cursor()
-- 以下设置更新数据库至 DNSMASQ 配置路径 -- 以下设置更新数据库至 DNSMASQ 配置路径
-- 获取 DNSMASQ 配置 ID -- 获取 DNSMASQ 配置 ID

View File

@ -1,20 +1,8 @@
diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile diff --git a/luci-app-ssr-plus/Makefile b/luci-app-ssr-plus/Makefile
index b469328..3a0b055 100644 index 697d594..ce23c14 100644
--- a/luci-app-ssr-plus/Makefile --- a/luci-app-ssr-plus/Makefile
+++ b/luci-app-ssr-plus/Makefile +++ b/luci-app-ssr-plus/Makefile
@@ -9,10 +9,9 @@ PKG_CONFIG_DEPENDS:= \ @@ -29,6 +29,7 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG \
- CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client \
- CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS \
+ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
@@ -25,14 +24,15 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin \
@ -22,29 +10,7 @@ index b469328..3a0b055 100644
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
@@ -62,6 +63,7 @@ LUCI_DEPENDS:= \
-LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/Tuic/ShadowTLS/Hysteria/Socks5/Tun LuCI interface
+LUCI_TITLE:=SS/SSR/V2Ray/Trojan/NaiveProxy/TUIC/ShadowTLS/Hysteria/Socks5/Tun LuCI interface
LUCI_PKGARCH:=all
LUCI_DEPENDS:= \
- +coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +@PACKAGE_dnsmasq_full_ipset +ipset +kmod-ipt-nat \
+ +coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +ipset +kmod-ipt-nat \
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \
+tcping +resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-mbedtls:libustream-mbedtls \
@@ -43,10 +43,9 @@ LUCI_DEPENDS:= \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \
- +PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS:mosdns \
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
+PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client:tuic-client \
- +PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS:shadow-tls \
+ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS:shadow-tls \
+PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
@@ -58,6 +57,7 @@ LUCI_DEPENDS:= \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server:shadowsocks-rust-ssserver \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Server:shadowsocks-rust-ssserver \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs:simple-obfs \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Simple_Obfs:simple-obfs \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin:v2ray-plugin \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin:v2ray-plugin \
@ -52,15 +18,7 @@ index b469328..3a0b055 100644
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \
@@ -65,7 +65,6 @@ LUCI_DEPENDS:= \ @@ -73,7 +75,7 @@ select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
define Package/$(PKG_NAME)/config
-select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
choice
prompt "Uclient SSL Lib Selection"
@@ -83,7 +82,7 @@ endchoice
choice choice
prompt "Shadowsocks Client Selection" prompt "Shadowsocks Client Selection"
@ -69,7 +27,7 @@ index b469328..3a0b055 100644
default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Client config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Client
@@ -100,8 +99,8 @@ endchoice @@ -90,8 +92,8 @@ endchoice
choice choice
prompt "Shadowsocks Server Selection" prompt "Shadowsocks Server Selection"
@ -80,36 +38,16 @@ index b469328..3a0b055 100644
default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_NONE_Server
@@ -135,25 +134,21 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG @@ -139,7 +141,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_DNSPROXY
bool "Include ChinaDNS-NG"
default n
-config PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS config PACKAGE_$(PKG_NAME)_INCLUDE_MosDNS
- bool "Include MosDNS" bool "Include MosDNS"
- default y if aarch64||arm||i386||x86_64 - default y if aarch64||arm||i386||x86_64
- + default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
bool "Include Hysteria" bool "Include Hysteria"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG @@ -187,6 +189,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Tuic_Client
- bool "Include Tuic-Client"
+ bool "Include tuic-client"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
select PACKAGE_$(PKG_NAME)_INCLUDE_IPT2Socks
depends on aarch64||arm||i386||x86_64
depends on !(TARGET_x86_geode||TARGET_x86_legacy)
default n
-config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS
- bool "Include Shadow-TLS"
+config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow-TLS
+ bool "Include shadow-TLS"
select PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
select PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client
depends on aarch64||arm||x86_64
@@ -185,6 +180,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_V2ray_Plugin
bool "Include Shadowsocks V2ray Plugin" bool "Include Shadowsocks V2ray Plugin"
default n default n
@ -121,7 +59,7 @@ index b469328..3a0b055 100644
bool "Include ShadowsocksR Libev Client" bool "Include ShadowsocksR Libev Client"
default y default y
diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua diff --git a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua
index 31989b0..75e141f 100644 index 4ba5d06..636566c 100644
--- a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua --- a/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua
+++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua +++ b/luci-app-ssr-plus/luasrc/controller/shadowsocksr.lua
@@ -7,7 +7,7 @@ function index() @@ -7,7 +7,7 @@ function index()
@ -133,62 +71,12 @@ index 31989b0..75e141f 100644
page.dependent = true page.dependent = true
page.acl_depends = { "luci-app-ssr-plus" } page.acl_depends = { "luci-app-ssr-plus" }
entry({"admin", "services", "shadowsocksr", "client"}, cbi("shadowsocksr/client"), _("SSR Client"), 10).leaf = true entry({"admin", "services", "shadowsocksr", "client"}, cbi("shadowsocksr/client"), _("SSR Client"), 10).leaf = true
diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua
index 6bd7aaa..3c96aad 100644
--- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua
+++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua
@@ -75,45 +75,6 @@ o.default = "https://fastly.jsdelivr.net/gh/QiuSimons/Netflix_IP/NF_only.txt"
o.description = translate("Customize Netflix IP Url")
o:depends("netflix_enable", "1")
-o = s:option(ListValue, "shunt_dns_mode", translate("DNS Query Mode For Shunt Mode"))
-o:value("1", translate("Use DNS2SOCKS query and cache"))
-if is_finded("mosdns") then
-o:value("2", translate("Use MOSDNS query"))
-end
-o:depends("netflix_enable", "1")
-o.default = 1
-
-o = s:option(Value, "shunt_dnsserver", translate("Anti-pollution DNS Server For Shunt Mode"))
-o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
-o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
-o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
-o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
-o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
-o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
-o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
-o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
-o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
-o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
-o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
-o:depends("shunt_dns_mode", "1")
-o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)")
-o.datatype = "ip4addrport"
-
-o = s:option(ListValue, "shunt_mosdns_dnsserver", translate("Anti-pollution DNS Server"))
-o:value("tcp://8.8.4.4:53,tcp://8.8.8.8:53", translate("Google Public DNS"))
-o:value("tcp://208.67.222.222:53,tcp://208.67.220.220:53", translate("OpenDNS"))
-o:value("tcp://209.244.0.3:53,tcp://209.244.0.4:53", translate("Level 3 Public DNS-1 (209.244.0.3-4)"))
-o:value("tcp://4.2.2.1:53,tcp://4.2.2.2:53", translate("Level 3 Public DNS-2 (4.2.2.1-2)"))
-o:value("tcp://4.2.2.3:53,tcp://4.2.2.4:53", translate("Level 3 Public DNS-3 (4.2.2.3-4)"))
-o:value("tcp://1.1.1.1:53,tcp://1.0.0.1:53", translate("Cloudflare DNS"))
-o:depends("shunt_dns_mode", "2")
-o.description = translate("Custom DNS Server for mosdns")
-
-o = s:option(Flag, "shunt_mosdns_ipv6", translate("Disable IPv6 In MOSDNS Query Mode (Shunt Mode)"))
-o:depends("shunt_dns_mode", "2")
-o.rmempty = false
-o.default = "0"
-
o = s:option(Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"))
o.rmempty = false
o.default = "1"
diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua
index 26de9ba..b24183e 100644 index 0bf9474..c6194fa 100644
--- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua --- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua
+++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua +++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua
@@ -10,7 +10,7 @@ local function is_finded(e) @@ -27,7 +27,7 @@ local function is_finded(e)
return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
end end
-m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"), translate("<h3>Support SS/SSR/V2RAY/XRAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc.</h3>")) -m = Map("shadowsocksr", translate("ShadowSocksR Plus+ Settings"), translate("<h3>Support SS/SSR/V2RAY/XRAY/TROJAN/NAIVEPROXY/SOCKS5/TUN etc.</h3>"))
@ -196,60 +84,6 @@ index 26de9ba..b24183e 100644
m:section(SimpleSection).template = "shadowsocksr/status" m:section(SimpleSection).template = "shadowsocksr/status"
local server_table = {} local server_table = {}
@@ -48,7 +48,7 @@ for _, key in pairs(key_table) do
o:value(key, server_table[key])
end
-if uci:get_first("shadowsocksr", 'global', 'netflix_enable', '0') == '1' then
+if uci:get_first("shadowsocksr", 'global', 'netflix_enable', '0') ~= '0' then
o = s:option(ListValue, "netflix_server", translate("Netflix Node"))
o:value("nil", translate("Disable"))
o:value("same", translate("Same as Global Server"))
@@ -96,9 +96,6 @@ o.default = 1
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
o:value("1", translate("Use DNS2TCP query"))
o:value("2", translate("Use DNS2SOCKS query and cache"))
-if is_finded("mosdns") then
-o:value("3", translate("Use MOSDNS query (Not Support Oversea Mode)"))
-end
o:value("0", translate("Use Local DNS Service listen port 5335"))
o.default = 1
@@ -121,21 +118,6 @@ o:depends("pdnsd_enable", "2")
o.description = translate("Custom DNS Server format as IP:PORT (default: 8.8.4.4:53)")
o.datatype = "ip4addrport"
-o = s:option(ListValue, "tunnel_forward_mosdns", translate("Anti-pollution DNS Server"))
-o:value("tcp://8.8.4.4:53,tcp://8.8.8.8:53", translate("Google Public DNS"))
-o:value("tcp://208.67.222.222:53,tcp://208.67.220.220:53", translate("OpenDNS"))
-o:value("tcp://209.244.0.3:53,tcp://209.244.0.4:53", translate("Level 3 Public DNS-1 (209.244.0.3-4)"))
-o:value("tcp://4.2.2.1:53,tcp://4.2.2.2:53", translate("Level 3 Public DNS-2 (4.2.2.1-2)"))
-o:value("tcp://4.2.2.3:53,tcp://4.2.2.4:53", translate("Level 3 Public DNS-3 (4.2.2.3-4)"))
-o:value("tcp://1.1.1.1:53,tcp://1.0.0.1:53", translate("Cloudflare DNS"))
-o:depends("pdnsd_enable", "3")
-o.description = translate("Custom DNS Server for mosdns")
-
-o = s:option(Flag, "mosdns_ipv6", translate("Disable IPv6 in MOSDNS query mode"))
-o:depends("pdnsd_enable", "3")
-o.rmempty = false
-o.default = "1"
-
if is_finded("chinadns-ng") then
o = s:option(Value, "chinadns_forward", translate("Domestic DNS Server"))
o:value("", translate("Disable ChinaDNS-NG"))
diff --git a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua
index c7e84ec..83a88a2 100644
--- a/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua
+++ b/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/status.lua
@@ -92,7 +92,7 @@ if Process_list:find("ssr.server") then
server_run = 1
end
-if Process_list:find("ssrplus/bin/dns2tcp") or Process_list:find("ssrplus/bin/mosdns") or (Process_list:find("ssrplus.dns") and Process_list:find("dns2socks.127.0.0.1.*127.0.0.1.5335")) then
+if Process_list:find("ssrplus/bin/dns2tcp") or (Process_list:find("ssrplus.dns") and Process_list:find("dns2socks.127.0.0.1.*127.0.0.1.5335")) then
pdnsd_run = 1
end
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm
index 4a16adc..5f6a673 100644 index 4a16adc..5f6a673 100644
--- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/check.htm
@ -310,13 +144,13 @@ index ff0c486..1882ac5 100644
return false; return false;
} }
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm
index d0b77f1..259cb7f 100644 index 2ba1be9..ed7148f 100644
--- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm
+++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/server_list.htm
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
const wsPath = wsPaths[index]; const wsPath = wsPaths[index];
const tls = tlss[index]; const tls = tlss[index];
if (!dom) res() if (!dom) res();
- port.innerHTML = '<font style=\"color:#0072c3\">connect</font>'; - port.innerHTML = '<font style=\"color:#0072c3\">connect</font>';
+ port.innerHTML = '<font color="#0072c3">connect</font>'; + port.innerHTML = '<font color="#0072c3">connect</font>';
XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', { XHR.get('<%=luci.dispatcher.build_url("admin/services/shadowsocksr/ping")%>', {
@ -326,8 +160,8 @@ index d0b77f1..259cb7f 100644
if (result.ping < 200) col = '#ff7700'; if (result.ping < 200) col = '#ff7700';
if (result.ping < 100) col = '#249400'; if (result.ping < 100) col = '#249400';
} }
- dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>` - dom.innerHTML = `<font style=\"color:${col}\">${(result.ping ? result.ping : "--") + " ms"}</font>`;
+ dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>` + dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>`;
if (result.socket) { if (result.socket) {
- port.innerHTML = '<font style=\"color:#249400\">ok</font>'; - port.innerHTML = '<font style=\"color:#249400\">ok</font>';
+ port.innerHTML = '<font color="#249400">ok</font>'; + port.innerHTML = '<font color="#249400">ok</font>';
@ -338,10 +172,10 @@ index d0b77f1..259cb7f 100644
res(); res();
}); });
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
index 1ae02e4..b8f9db4 100644 index cf4ca1f..04f2896 100644
--- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm --- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
+++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm +++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm
@@ -69,9 +69,9 @@ function export_ssr_url(btn, urlname, sid) { @@ -75,9 +75,9 @@ function export_ssr_url(btn, urlname, sid) {
textarea.select(); textarea.select();
try { try {
document.execCommand("copy"); // Security exception may be thrown by some browsers. document.execCommand("copy"); // Security exception may be thrown by some browsers.
@ -353,7 +187,7 @@ index 1ae02e4..b8f9db4 100644
} finally { } finally {
document.body.removeChild(textarea); document.body.removeChild(textarea);
} }
@@ -83,7 +83,7 @@ function import_ssr_url(btn, urlname, sid) { @@ -89,7 +89,7 @@ function import_ssr_url(btn, urlname, sid) {
if (!s) return false; if (!s) return false;
var ssrurl = prompt("<%:Paste sharing link here%>", ""); var ssrurl = prompt("<%:Paste sharing link here%>", "");
if (ssrurl == null || ssrurl == "") { if (ssrurl == null || ssrurl == "") {
@ -362,34 +196,7 @@ index 1ae02e4..b8f9db4 100644
return false; return false;
} }
s.innerHTML = ""; s.innerHTML = "";
@@ -118,7 +118,7 @@ function import_ssr_url(btn, urlname, sid) { @@ -274,7 +274,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = params.get("insecure") ? true : false;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
- s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
+ s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
return false;
case "ss":
var url0, param = "";
@@ -164,7 +164,7 @@ function import_ssr_url(btn, urlname, sid) {
if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
}
- s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
+ s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
} else {
var sstr = b64decsafe(url0);
document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
@@ -179,7 +179,7 @@ function import_ssr_url(btn, urlname, sid) {
if (param != undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
}
- s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
+ s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
}
return false;
case "ssr":
@@ -212,7 +212,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam'); document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
var rem = pdict['remarks']; var rem = pdict['remarks'];
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem); if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem);
@ -398,7 +205,7 @@ index 1ae02e4..b8f9db4 100644
return false; return false;
case "trojan": case "trojan":
try { try {
@@ -305,7 +305,7 @@ function import_ssr_url(btn, urlname, sid) { @@ -367,7 +367,7 @@ function import_ssr_url(btn, urlname, sid) {
break; break;
} }
@ -407,7 +214,7 @@ index 1ae02e4..b8f9db4 100644
return false; return false;
case "vmess": case "vmess":
var sstr = b64DecodeUnicode(ssu[1]); var sstr = b64DecodeUnicode(ssu[1]);
@@ -388,7 +388,7 @@ function import_ssr_url(btn, urlname, sid) { @@ -450,7 +450,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xmux')[0].checked = true; document.getElementsByName('cbid.shadowsocksr.' + sid + '.xmux')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xmux')[0].dispatchEvent(event); document.getElementsByName('cbid.shadowsocksr.' + sid + '.xmux')[0].dispatchEvent(event);
} }
@ -416,7 +223,7 @@ index 1ae02e4..b8f9db4 100644
return false; return false;
case "vless": case "vless":
try { try {
@@ -506,10 +506,10 @@ function import_ssr_url(btn, urlname, sid) { @@ -568,10 +568,10 @@ function import_ssr_url(btn, urlname, sid) {
} }
break; break;
} }
@ -429,237 +236,16 @@ index 1ae02e4..b8f9db4 100644
return false; return false;
} }
} }
diff --git a/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po b/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po
index 11440b6..400c875 100644
--- a/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po
+++ b/luci-app-ssr-plus/po/zh_Hans/ssr-plus.po
@@ -606,27 +606,6 @@ msgstr "使用 DNS2TCP 查询"
msgid "Use DNS2SOCKS query and cache"
msgstr "使用 DNS2SOCKS 查询并缓存"
-msgid "Use MOSDNS query (Not Support Oversea Mode)"
-msgstr "使用 MOSDNS 查询 (不支持海外用户回国模式)"
-
-msgid "Disable IPv6 in MOSDNS query mode"
-msgstr "禁止 MOSDNS 返回 IPv6 记录"
-
-msgid "DNS Query Mode For Shunt Mode"
-msgstr "分流模式下的 DNS 查询模式"
-
-msgid "Anti-pollution DNS Server For Shunt Mode"
-msgstr "分流模式下的访问国外域名 DNS 服务器"
-
-msgid "Use MOSDNS query"
-msgstr "使用 MOSDNS 查询"
-
-msgid "Custom DNS Server for mosdns"
-msgstr "MOSDNS 自定义 DNS 服务器"
-
-msgid "Disable IPv6 In MOSDNS Query Mode (Shunt Mode)"
-msgstr "禁止 MOSDNS 返回 IPv6 记录 (分流模式)"
-
msgid "DNS Server IP:Port"
msgstr "DNS 服务器 IP:Port"
diff --git a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr diff --git a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr
index 537baf1..83807d1 100755 index 22b6c7c..f086636 100755
--- a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr --- a/luci-app-ssr-plus/root/etc/init.d/shadowsocksr
+++ b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/luci-app-ssr-plus/root/etc/init.d/shadowsocksr
@@ -190,23 +190,17 @@ ln_start_bin() { @@ -1287,8 +1287,18 @@ start_server() {
${file_func:-echolog " - ${ln_name}"} "$@" >/dev/null 2>&1 &
}
-add_dns_into_ipset() {
- case "$1" in
- gfw) ipset add gfwlist ${2%:*} 2>/dev/null ;;
- oversea) ipset add oversea ${2%:*} 2>/dev/null ;;
- *) ipset add ss_spec_wan_ac ${2%:*} nomatch 2>/dev/null ;;
- esac
-}
-
start_dns() {
local ssrplus_dns="$(uci_get_by_type global pdnsd_enable 0)"
local dnsserver="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
local run_mode="$(uci_get_by_type global run_mode)"
if [ "$ssrplus_dns" != "0" ]; then
- if [ -n "$dnsserver" ]; then
- add_dns_into_ipset $run_mode $dnsserver
- fi
+ case "$run_mode" in
+ gfw) ipset add gfwlist ${dnsserver%:*} 2>/dev/null ;;
+ oversea) ipset add oversea ${dnsserver%:*} 2>/dev/null ;;
+ *) ipset add ss_spec_wan_ac ${dnsserver%:*} nomatch 2>/dev/null ;;
+ esac
case "$ssrplus_dns" in
1)
ln_start_bin $(first_type dns2tcp) dns2tcp -L 127.0.0.1#$dns_port -R ${dnsserver/:/#}
@@ -217,26 +211,6 @@ start_dns() {
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q
pdnsd_enable_flag=2
;;
- 3)
- local mosdns_ipv6="$(uci_get_by_type global mosdns_ipv6)"
- local mosdns_dnsserver="$(uci_get_by_type global tunnel_forward_mosdns)"
- output=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do
- dnsserver=${i%:*}
- dnsserver=${i##*/}
- add_dns_into_ipset $run_mode $dnsserver
- echo " - addr: $i"
- echo " enable_pipeline: true"
- done)
-
- awk -v line=14 -v text="$output" 'NR == line+1 {print text} 1' /etc/ssrplus/mosdns-config.yaml | sed "s/DNS_PORT/$dns_port/g" > $TMP_PATH/mosdns-config.yaml
- if [ "$mosdns_ipv6" == "0" ]; then
- sed -i "s/DNS_MODE/main_sequence_with_IPv6/g" $TMP_PATH/mosdns-config.yaml
- else
- sed -i "s/DNS_MODE/main_sequence_disable_IPv6/g" $TMP_PATH/mosdns-config.yaml
- fi
- ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config.yaml
- pdnsd_enable_flag=3
- ;;
esac
if [ "$run_mode" = "router" ]; then
@@ -505,33 +479,6 @@ start_udp() {
esac
}
-shunt_dns_command() {
- local shunt_dns_mode="$(uci_get_by_type global shunt_dns_mode)"
- local shunt_dnsserver="$(uci_get_by_type global shunt_dnsserver)"
- case "$shunt_dns_mode" in
- 1)
- ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port $shunt_dnsserver 127.0.0.1:$tmp_shunt_dns_port -q
- ;;
- 2)
- local shunt_mosdns_ipv6="$(uci_get_by_type global shunt_mosdns_ipv6)"
- local shunt_mosdns_dnsserver="$(uci_get_by_type global shunt_mosdns_dnsserver)"
- output=$(for i in $(echo $shunt_mosdns_dnsserver | sed "s/,/ /g"); do
- echo " - addr: $i"
- echo " socks5: \"127.0.0.1:$tmp_port\""
- echo " enable_pipeline: true"
- done)
- awk -v line=14 -v text="$output" 'NR == line+1 {print text} 1' /etc/ssrplus/mosdns-config.yaml | sed "s/DNS_PORT/$tmp_shunt_dns_port/g" > $TMP_PATH/mosdns-config-shunt.yaml
-
- if [ "$shunt_mosdns_ipv6" == "0" ]; then
- sed -i "s/DNS_MODE/main_sequence_with_IPv6/g" $TMP_PATH/mosdns-config-shunt.yaml
- else
- sed -i "s/DNS_MODE/main_sequence_disable_IPv6/g" $TMP_PATH/mosdns-config-shunt.yaml
- fi
- ln_start_bin $(first_type mosdns) mosdns start -c $TMP_PATH/mosdns-config-shunt.yaml
- ;;
- esac
-}
-
start_shunt() {
local type=$(uci_get_by_name $SHUNT_SERVER type)
case "$type" in
@@ -545,14 +492,14 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type ${type}local ${type}-local) ${type}-local -c $shunt_dns_config_file
fi
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$(get_name $type) Started!"
;;
v2ray)
local tmp_port=${tmp_local_port:-$tmp_shunt_local_port}
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port
ln_start_bin $(first_type xray v2ray) v2ray run -c $shunt_config_file
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$($(first_type xray v2ray) version | head -1) Started!"
;;
trojan)
@@ -564,7 +511,7 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type trojan) $type --config $shunt_dns_config_file
fi
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$($(first_type trojan) --version 2>&1 | head -1) Started!"
;;
naiveproxy)
@@ -576,7 +523,7 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type naive) naive --config $shunt_dns_config_file
fi
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$($(first_type "naive") --version 2>&1 | head -1) Started!"
redir_udp=0
;;
@@ -589,7 +536,7 @@ start_shunt() {
gen_config_file $SHUNT_SERVER $type 3 $tmp_shunt_port $tmp_port
fi
ln_start_bin $(first_type hysteria) hysteria client --config $shunt_config_file
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$($(first_type hysteria) version | grep Version | awk '{print "Hysteria2: " $2}') Started!"
;;
tuic)
@@ -601,7 +548,7 @@ start_shunt() {
[ -n "$tmp_local_port" ] && tmp_port=$tmp_local_port || tmp_port=$tmp_shunt_local_port
gen_config_file $SHUNT_SERVER $type 3 $tmp_port # make a tuic socks :304
ln_start_bin $(first_type tuic-client) tuic-client --config $shunt_dns_config_file
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "Netflix Separated Shunt Server:tuic-client $($(first_type tuic-client) --version) Started!"
# FIXME: ipt2socks cannot handle udp reply from tuic
#redir_udp=0
@@ -611,7 +558,7 @@ start_shunt() {
gen_config_file $SHUNT_SERVER $type 3 "10${tmp_shunt_port}" $tmp_port chain/$tmp_shunt_port #make a redir:303 and a socks:304
#echo "debug \$tmp_port=$tmp_port, \$tmp_shunt_port=${tmp_shunt_port}, \$tmp_shunt_local_port=$tmp_shunt_local_port"
ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:"${tmp_port}" 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
local chain_type=$(uci_get_by_name $SHUNT_SERVER chain_type)
case ${chain_type} in
vmess)
@@ -637,7 +584,7 @@ start_shunt() {
# local tmp_port=$tmp_shunt_local_port
# ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus
# fi
- # shunt_dns_command
+ # ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
# echolog "shunt:$type REDIRECT/TPROXY Started!"
# ;;
*)
@@ -649,7 +596,7 @@ start_shunt() {
local tmp_port=$tmp_shunt_local_port
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_port shunt-dns-ssr-plus
fi
- shunt_dns_command
+ ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_port 8.8.8.8:53 127.0.0.1:$tmp_shunt_dns_port -q
echolog "shunt:$type REDIRECT/TPROXY Started!"
;;
esac
@@ -948,11 +895,6 @@ start_server() {
server_service() {
[ "$(uci_get_by_name $1 enable 0)" == "0" ] && return 1
let server_count=server_count+1
- if [ "$server_count" == "1" ]; then
- if ! (iptables-save -t filter | grep SSR-SERVER-RULE >/dev/null); then
- iptables -N SSR-SERVER-RULE && iptables -t filter -I INPUT -j SSR-SERVER-RULE
- fi
- fi
local type=$(uci_get_by_name $1 type)
case "$type" in
ss | ssr)
@@ -966,32 +908,23 @@ start_server() {
echolog "Server:Socks5 Server$server_count Started!" echolog "Server:Socks5 Server$server_count Started!"
;; ;;
esac esac
- iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $(uci_get_by_name $1 server_port) -j ACCEPT - iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $(uci_get_by_name $1 server_port) -j ACCEPT
- iptables -t filter -A SSR-SERVER-RULE -p udp --dport $(uci_get_by_name $1 server_port) -j ACCEPT - iptables -t filter -A SSR-SERVER-RULE -p udp --dport $(uci_get_by_name $1 server_port) -j ACCEPT
- return 0
- }
- gen_serv_include() {
- local FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null)
- [ -n "$FWI" ] || return 0
- if [ ! -f $FWI ]; then
- echo '#!/bin/sh' >$FWI
+ ssr_server_port=$(uci show shadowsocksr | grep 'server_config.*server_port' | awk -F"'" '{print $2}' | tr "\n" " ") + ssr_server_port=$(uci show shadowsocksr | grep 'server_config.*server_port' | awk -F"'" '{print $2}' | tr "\n" " ")
+ if [ -n "$ssr_server_port" ]; then + if [ -n "$ssr_server_port" ]; then
+ uci -q delete firewall.shadowsocksr_server + uci -q delete firewall.shadowsocksr_server
@ -671,28 +257,11 @@ index 537baf1..83807d1 100755
+ uci set firewall.shadowsocksr_server.enabled="1" + uci set firewall.shadowsocksr_server.enabled="1"
+ uci commit firewall + uci commit firewall
+ /etc/init.d/firewall reload >/dev/null 2>&1 + /etc/init.d/firewall reload >/dev/null 2>&1
fi + fi
- extract_rules() {
- echo "*filter"
- iptables-save -t filter | grep SSR-SERVER-RULE | sed -e "s/^-A INPUT/-I INPUT/"
- echo 'COMMIT'
- }
- cat <<-EOF >>$FWI
- iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c
- iptables-restore -n <<-EOT
- $(extract_rules)
- EOT
- EOF
+ return 0
}
config_load $NAME
config_foreach server_service server_config
- gen_serv_include
return 0 return 0
} }
gen_serv_include() {
@@ -1124,12 +1057,6 @@ stop() { @@ -1445,12 +1455,6 @@ stop() {
unlock unlock
set_lock set_lock
/usr/bin/ssr-rules -f /usr/bin/ssr-rules -f
@ -705,7 +274,7 @@ index 537baf1..83807d1 100755
if [ -z "$switch_server" ]; then if [ -z "$switch_server" ]; then
$PS -w | grep -v "grep" | grep ssr-switch | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 & $PS -w | grep -v "grep" | grep ssr-switch | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
rm -f /var/lock/ssr-switch.lock rm -f /var/lock/ssr-switch.lock
@@ -1140,7 +1067,7 @@ stop() { @@ -1461,7 +1465,7 @@ stop() {
( \ ( \
# Graceful kill first, so programs have the chance to stop its subprocesses # Graceful kill first, so programs have the chance to stop its subprocesses
$PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill >/dev/null 2>&1 ; \ $PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill >/dev/null 2>&1 ; \
@ -714,8 +283,8 @@ index 537baf1..83807d1 100755
# Force kill hanged programs # Force kill hanged programs
$PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 ; \ $PS -w | grep -v "grep" | grep "$TMP_PATH" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 ; \
) )
@@ -1158,6 +1085,9 @@ stop() { @@ -1484,6 +1488,9 @@ stop() {
rm -rf $DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf $TMP_DNSMASQ_PATH $TMP_PATH/*-ssr-*.json $TMP_PATH/ssr-server*.json
/etc/init.d/dnsmasq restart >/dev/null 2>&1 /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi fi
+ uci -q delete firewall.shadowsocksr_server + uci -q delete firewall.shadowsocksr_server
@ -724,55 +293,6 @@ index 537baf1..83807d1 100755
del_cron del_cron
unset_lock unset_lock
} }
diff --git a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml b/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml
deleted file mode 100644
index a0b9f5c..0000000
--- a/luci-app-ssr-plus/root/etc/ssrplus/mosdns-config.yaml
+++ /dev/null
@@ -1,43 +0,0 @@
-log:
- level: info
-plugins:
- - tag: lazy_cache
- type: cache
- args:
- size: 8000
- lazy_cache_ttl: 86400
-
- - tag: forward_google
- type: forward
- args:
- concurrent: 2
- upstreams:
-
- - tag: main_sequence_disable_IPv6
- type: sequence
- args:
- - exec: $lazy_cache
- - exec: prefer_ipv4
- - exec: $forward_google
- - matches:
- - qtype 28 65
- exec: reject 0
-
- - tag: main_sequence_with_IPv6
- type: sequence
- args:
- - exec: $lazy_cache
- - exec: $forward_google
-
- - tag: udp_server
- type: udp_server
- args:
- entry: DNS_MODE
- listen: 0.0.0.0:DNS_PORT
-
- - tag: tcp_server
- type: tcp_server
- args:
- entry: DNS_MODE
- listen: 0.0.0.0:DNS_PORT
-
diff --git a/luci-app-ssr-plus/root/etc/ssrplus/white.list b/luci-app-ssr-plus/root/etc/ssrplus/white.list diff --git a/luci-app-ssr-plus/root/etc/ssrplus/white.list b/luci-app-ssr-plus/root/etc/ssrplus/white.list
index 9055fcb..8c3ca2b 100644 index 9055fcb..8c3ca2b 100644
--- a/luci-app-ssr-plus/root/etc/ssrplus/white.list --- a/luci-app-ssr-plus/root/etc/ssrplus/white.list
@ -821,24 +341,3 @@ index 9055fcb..8c3ca2b 100644
+worldbank.org +worldbank.org
+worldscientific.com +worldscientific.com
+www-cdn.icloud.com.akadns.net +www-cdn.icloud.com.akadns.net
diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-monitor b/luci-app-ssr-plus/root/usr/bin/ssr-monitor
index f637d50..fb9ed57 100755
--- a/luci-app-ssr-plus/root/usr/bin/ssr-monitor
+++ b/luci-app-ssr-plus/root/usr/bin/ssr-monitor
@@ -104,16 +104,6 @@ while [ "1" == "1" ]; do #死循环
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q
fi
- #mosdns
- elif [ "$pdnsd_process" -eq 3 ]; then
- icount=$(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | wc -l)
- if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
- logger -t "$NAME" "mosdns tunnel error.restart!"
- echolog "mosdns tunnel error.restart!"
- dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
- kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
- ln_start_bin $(first_type mosdns) mosdns start -c /etc/mosdns/config.yaml
- fi
fi
#chinadns-ng
if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then