diff --git a/package/lean/luci-app-ssr-plus/Makefile b/package/lean/luci-app-ssr-plus/Makefile index 72ae55d2f..41fe2adc5 100644 --- a/package/lean/luci-app-ssr-plus/Makefile +++ b/package/lean/luci-app-ssr-plus/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ssr-plus -PKG_VERSION:=167 +PKG_VERSION:=168 PKG_RELEASE:=2 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) @@ -40,19 +40,16 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server bool "Include ShadowsocksR Server" default y if x86||x86_64||arm||aarch64 - -config PACKAGE_$(PKG_NAME)_INCLUDE_DNS2SOCKS - bool "Include DNS2SOCKS" - default y if x86||x86_64||arm||aarch64 endef - + define Package/$(PKG_NAME) SECTION:=luci CATEGORY:=LuCI SUBMENU:=3. Applications TITLE:=SS/SSR/V2Ray/Trojan LuCI interface PKGARCH:=all - DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua +microsocks +ipt2socks \ + DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +pdnsd-alt +wget +lua \ + +microsocks +ipt2socks +dns2socks +shadowsocks-libev-ss-local +shadowsocksr-libev-ssr-local \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \ +PACKAGE_$(PKG_NAME)_INCLUDE_Simple_obfs:simple-obfs \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_plugin:v2ray-plugin \ @@ -75,6 +72,7 @@ define Package/$(PKG_NAME)/conffiles /etc/config/shadowsocksr /etc/config/white.list /etc/config/black.list +/etc/config/netflix.list /etc/dnsmasq.ssr/ad.conf /etc/dnsmasq.ssr/gfw_list.conf endef diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua index 5e6ededd9..39925f3bd 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client.lua @@ -43,6 +43,12 @@ o:value("", translate("Disable")) o:value("same", translate("Same as Global Server")) for _,key in pairs(key_table) do o:value(key,server_table[key]) end +o = s:option(ListValue, "netflix_server", translate("Netflix Node")) +o:value("same", translate("Same as Global Server")) +for _,key in pairs(key_table) do o:value(key,server_table[key]) end +o.default = "nil" +o.rmempty = false + o = s:option(ListValue, "threads", translate("Multi Threads Option")) o:value("0", translate("Auto Threads")) o:value("1", translate("1 Thread")) diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua index 91cf55d75..cbe1aaaee 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/control.lua @@ -101,4 +101,21 @@ o.remove = function(self, section, value) NXFS.writefile(blockconf, "") end +s:tab("netflix", translate("Netflix Domain List")) + +local netflixconf = "/etc/config/netflix.list" +o = s:taboption("netflix", TextValue, "netflixconf") +o.rows = 13 +o.wrap = "off" +o.rmempty = true +o.cfgvalue = function(self, section) + return NXFS.readfile(netflixconf) or " " +end +o.write = function(self, section, value) + NXFS.writefile(netflixconf, value:gsub("\r\n", "\n")) +end +o.remove = function(self, section, value) + NXFS.writefile(netflixconf, "") +end + return m diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua index bd43feeeb..60e24da36 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua @@ -92,7 +92,7 @@ end o = s:option(DummyValue, "type", translate("Type")) function o.cfgvalue(...) - return string.upper(Value.cfgvalue(...) or "") + return Value.cfgvalue(...) or "" end o = s:option(DummyValue, "alias", translate("Alias")) diff --git a/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po index 01c8c7213..eb618afff 100644 --- a/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po +++ b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po @@ -639,3 +639,9 @@ msgstr "允许从 WAN 访问" msgid "Redirect traffic to this network interface" msgstr "分流到这个网络接口" + +msgid "Netflix Node" +msgstr "Netflix 分流服务器" + +msgid "Netflix Domain List" +msgstr "Netflix 分流域名列表" diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/netflix.list b/package/lean/luci-app-ssr-plus/root/etc/config/netflix.list new file mode 100644 index 000000000..134d715a0 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/etc/config/netflix.list @@ -0,0 +1,11 @@ +netflix.com +netflix.net +nflximg.net +nflxvideo.net +nflxso.net +nflxext.com +hulu.com +huluim.com +hbonow.com +hbogo.com +hbo.com diff --git a/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr index 63cbef98f..30de38e9d 100644 --- a/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr +++ b/package/lean/luci-app-ssr-plus/root/etc/config/shadowsocksr @@ -14,6 +14,8 @@ config global option adblock_url 'https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf' option chnroute '0' option chnroute_url 'https://ispip.clang.cn/all_cn.txt' + option netflix_server 'same' + config socks5_proxy option socks '0' diff --git a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index 03394f140..d39344893 100755 --- a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -17,6 +17,7 @@ EXTRA_COMMANDS=rules CONFIG_FILE=/var/etc/${NAME}.json CONFIG_UDP_FILE=/var/etc/${NAME}_u.json CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json +CONFIG_NETFLIX_FILE=/var/etc/${NAME}_n.json server_count=0 redir_tcp=0 redir_udp=0 @@ -81,6 +82,8 @@ gen_config_file() { config_file=$CONFIG_FILE elif [ "$2" == "1" ]; then config_file=$CONFIG_UDP_FILE + elif [ "$2" == "2" ]; then + config_file=$CONFIG_NETFLIX_FILE else config_file=$CONFIG_SOCK5_FILE fi @@ -96,7 +99,7 @@ gen_config_file() { "server": "$hostip", "server_port": $(uci_get_by_name $1 server_port), "local_address": "0.0.0.0", - "local_port": $(uci_get_by_name $1 local_port), + "local_port": $3, "password": "$(uci_get_by_name $1 password)", "timeout": $(uci_get_by_name $1 timeout 60), "method": "$(uci_get_by_name $1 encrypt_method_ss)", @@ -117,7 +120,7 @@ gen_config_file() { "server": "$hostip", "server_port": $(uci_get_by_name $1 server_port), "local_address": "0.0.0.0", - "local_port": $(uci_get_by_name $1 local_port), + "local_port": $3, "password": "$(uci_get_by_name $1 password)", "timeout": $(uci_get_by_name $1 timeout 60), "method": "$(uci_get_by_name $1 encrypt_method)", @@ -280,7 +283,8 @@ start_redir() { -l :$server_port $password $kcp_param kcp_enable_flag=1 fi - gen_config_file $GLOBAL_SERVER 0 + + gen_config_file $GLOBAL_SERVER 0 $(uci_get_by_name $GLOBAL_SERVER local_port 1234) local stype=$(uci_get_by_name $GLOBAL_SERVER type) if [ "$stype" == "ss" ]; then sscmd="/usr/bin/ss-redir" @@ -296,6 +300,29 @@ start_redir() { elif [ "$stype" == "tun" ]; then sscmd="/usr/sbin/redsocks2" fi + + NETFLIX_SERVER=$(uci_get_by_type global netflix_server same) + [ "$NETFLIX_SERVER" == "same" ] && NETFLIX_SERVER=$GLOBAL_SERVER + gen_config_file $NETFLIX_SERVER 2 4321 + gen_config_file $NETFLIX_SERVER 3 1088 + local ntype=$(uci_get_by_name $NETFLIX_SERVER type) + if [ "$ntype" == "ss" ]; then + ncmd="/usr/bin/ss-redir" + sssock="/usr/bin/ss-local" + elif [ "$ntype" == "ssr" ]; then + ncmd="/usr/bin/ssr-redir" + sssock="/usr/bin/ssr-local" + elif [ "$ntype" == "v2ray" ]; then + ncmd="/usr/bin/v2ray/v2ray" + [ ! -f "$ncmd" ] && ncmd="/usr/bin/v2ray" + elif [ "$ntype" == "trojan" ]; then + ncmd="/usr/sbin/trojan" + elif [ "$ntype" == "socks5" ]; then + ncmd="/usr/sbin/redsocks2" + elif [ "$ntype" == "tun" ]; then + ncmd="/usr/sbin/redsocks2" + fi + local utype=$(uci_get_by_name $UDP_RELAY_SERVER type) if [ "$utype" == "ss" ]; then ucmd="/usr/bin/ss-redir" @@ -318,34 +345,48 @@ start_redir() { fi redir_tcp=1 if [ "$stype" == "ss" -o "$stype" == "ssr" ]; then - local last_config_file=$CONFIG_FILE - local pid_file="/var/run/ssr-retcp.pid" - for i in $(seq 1 $threads); do - $sscmd -c $CONFIG_FILE $ARG_OTA -f /var/run/ssr-retcp_$i.pid >/dev/null 2>&1 - done - echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR $threads Threads Started!" >>/tmp/ssrplus.log - elif [ "$stype" == "v2ray" ]; then - $sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 & - echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) Started!" >>/tmp/ssrplus.log - elif [ "$stype" == "trojan" ]; then - for i in $(seq 1 $threads); do - $sscmd --config /var/etc/trojan-ssr-retcp.json >/dev/null 2>&1 & - done - echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd --version 2>&1 | head -1) , $threads Threads Started!" >>/tmp/ssrplus.log - elif [ "$stype" == "socks5" ]; then - /usr/share/shadowsocksr/genred2config.sh "/var/etc/redsocks-ssr-retcp.conf" socks5 tcp $(uci_get_by_name $GLOBAL_SERVER local_port) $(uci_get_by_name $GLOBAL_SERVER server) $(uci_get_by_name $GLOBAL_SERVER server_port) \ - $(uci_get_by_name $GLOBAL_SERVER auth_enable 0) $(uci_get_by_name $GLOBAL_SERVER username) $(uci_get_by_name $GLOBAL_SERVER password) - for i in $(seq 1 $threads); do - $sscmd -c /var/etc/redsocks-ssr-retcp.conf >/dev/null 2>&1 - done - echo "$(date "+%Y-%m-%d %H:%M:%S") Socks5 REDIRECT/TPROXY $threads Threads Started!" >>/tmp/ssrplus.log - elif [ "$stype" == "tun" ]; then - /usr/share/shadowsocksr/genred2config.sh "/var/etc/redsocks-ssr-retcp.conf" vpn $(uci_get_by_name $GLOBAL_SERVER iface "br-lan") $(uci_get_by_name $GLOBAL_SERVER local_port) - for i in $(seq 1 $threads); do - $sscmd -c /var/etc/redsocks-ssr-retcp.conf >/dev/null 2>&1 - done - echo "$(date "+%Y-%m-%d %H:%M:%S") Network Tunnel REDIRECT $threads Threads Started!" >>/tmp/ssrplus.log + local last_config_file=$CONFIG_FILE + local pid_file="/var/run/ssr-retcp.pid" + for i in $(seq 1 $threads); do + $sscmd -c $CONFIG_FILE $ARG_OTA -f /var/run/ssr-retcp_$i.pid >/dev/null 2>&1 + done + echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR $threads Threads Started!" >>/tmp/ssrplus.log + elif [ "$stype" == "v2ray" ]; then + $sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 & + echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) Started!" >>/tmp/ssrplus.log + elif [ "$stype" == "trojan" ]; then + for i in $(seq 1 $threads); do + $sscmd --config /var/etc/trojan-ssr-retcp.json >/dev/null 2>&1 & + done + echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd --version 2>&1 | head -1) , $threads Threads Started!" >>/tmp/ssrplus.log + elif [ "$stype" == "socks5" ]; then + /usr/share/shadowsocksr/genred2config.sh "/var/etc/redsocks-ssr-retcp.conf" socks5 tcp $(uci_get_by_name $GLOBAL_SERVER local_port) \ + $(uci_get_by_name $GLOBAL_SERVER server) $(uci_get_by_name $GLOBAL_SERVER server_port) \ + $(uci_get_by_name $GLOBAL_SERVER auth_enable 0) $(uci_get_by_name $GLOBAL_SERVER username) $(uci_get_by_name $GLOBAL_SERVER password) + for i in $(seq 1 $threads); do + $sscmd -c /var/etc/redsocks-ssr-retcp.conf >/dev/null 2>&1 + done + echo "$(date "+%Y-%m-%d %H:%M:%S") Socks5 REDIRECT/TPROXY $threads Threads Started!" >>/tmp/ssrplus.log + elif [ "$stype" == "tun" ]; then + /usr/share/shadowsocksr/genred2config.sh "/var/etc/redsocks-ssr-retcp.conf" vpn $(uci_get_by_name $GLOBAL_SERVER iface "br-lan") $(uci_get_by_name $GLOBAL_SERVER local_port) + for i in $(seq 1 $threads); do + $sscmd -c /var/etc/redsocks-ssr-retcp.conf >/dev/null 2>&1 + done + echo "$(date "+%Y-%m-%d %H:%M:%S") Network Tunnel REDIRECT $threads Threads Started!" >>/tmp/ssrplus.log fi + + + if [ "$ntype" == "ss" -o "$ntype" == "ssr" ]; then + $sssock -c /var/etc/shadowsocksr_s.json $ARG_OTA -f /var/run/ssr-socksdns.pid >/dev/null 2>&1 + dns2socks 127.0.0.1:1088 8.8.8.8:53 127.0.0.1:5555 -q >/dev/null 2>&1 & + $ncmd -c /var/etc/shadowsocksr_n.json $ARG_OTA -f /var/run/ssr-netflix.pid >/dev/null 2>&1 + elif [ "$stype" == "v2ray" ]; then + lua /usr/share/shadowsocksr/genv2nfconfig.lua $NETFLIX_SERVER tcp 4321 >/var/etc/v2-ssr-netflix.json + $ncmd -config /var/etc/v2-ssr-netflix.json >/dev/null 2>&1 & + dns2socks 127.0.0.1:1088 8.8.8.8:53 127.0.0.1:5555 -q >/dev/null 2>&1 & + fi + + if [ -n "$UDP_RELAY_SERVER" ]; then redir_udp=1 if [ "$utype" == "ss" -o "$utype" == "ssr" ]; then @@ -353,7 +394,7 @@ start_redir() { 1 | on | true | yes | enabled) ARG_OTA="-A" ;; *) ARG_OTA="" ;; esac - gen_config_file $UDP_RELAY_SERVER 1 + gen_config_file $UDP_RELAY_SERVER 1 $(uci_get_by_name $UDP_RELAY_SERVER local_port 1234) last_config_file=$CONFIG_UDP_FILE pid_file="/var/run/ssr-reudp.pid" $ucmd -c $last_config_file $ARG_OTA -U -f /var/run/ssr-reudp.pid >/dev/null 2>&1 @@ -534,6 +575,15 @@ start() { rm -f /tmp/dnsmasq.ssr/ad.conf fi /usr/share/shadowsocksr/gfw2ipset.sh + + cat /etc/config/netflix.list | while read line || [ -n "$line" ]; + do + sed -i "/$line/d" /tmp/dnsmasq.ssr/gfw_list.conf + done + + awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"netflix"'\n",$0)}' /etc/config/netflix.list > /tmp/dnsmasq.ssr/netflix_forward.conf + awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5555"'\n",$0)}' /etc/config/netflix.list >> /tmp/dnsmasq.ssr/netflix_forward.conf + /etc/init.d/dnsmasq restart >/dev/null 2>&1 fi start_server @@ -591,6 +641,8 @@ stop() { killall -q -9 trojan killall -q -9 ipt2socks killall -q -9 ssr-server + killall -q -9 ssr-local + killall -q -9 ss-local killall -q -9 kcptun-client killall -q -9 dns2socks killall -q -9 microsocks diff --git a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules index 140da4ce6..121fc3474 100755 --- a/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules +++ b/package/lean/luci-app-ssr-plus/root/usr/bin/ssr-rules @@ -71,6 +71,7 @@ flush_r() { ipset -X oversea 2>/dev/null ipset -X whitelist 2>/dev/null ipset -X blacklist 2>/dev/null + ipset -X netflix 2>/dev/null [ -n "$FWI" ] && echo '#!/bin/sh' >$FWI return 0 } @@ -123,6 +124,7 @@ ipset_r() { } fw_rule() { + ipset -N netflix hash:net 2>/dev/null $IPT -N SS_SPEC_WAN_FW $IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN @@ -132,6 +134,7 @@ fw_rule() { $IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN $IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN + $IPT -A SS_SPEC_WAN_FW -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports 4321 $IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS \ -j REDIRECT --to-ports $local_port 2>/dev/null || { loger 3 "Can't redirect, please check the iptables." diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2nfconfig.lua b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2nfconfig.lua new file mode 100644 index 000000000..c37eb3509 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2nfconfig.lua @@ -0,0 +1,106 @@ +local ucursor = require "luci.model.uci".cursor() +local json = require "luci.jsonc" +local server_section = arg[1] +local proto = arg[2] +local local_port = arg[3] + +local server = ucursor:get_all("shadowsocksr", server_section) + +local v2ray = { +log = { + -- error = "/var/ssrplus.log", + loglevel = "warning" +}, + -- 传入连接 + inbound = { + port = local_port, + protocol = "dokodemo-door", + settings = { + network = proto, + followRedirect = true + }, + sniffing = { + enabled = true, + destOverride = { "http", "tls" } + } + }, + -- 同时开启 socks 代理 + inboundDetour = (proto == "tcp") and { + { + protocol = "socks", + port = 1088, + settings = { + auth = "noauth", + udp = true + } + } + } or nil, + -- 传出连接 + outbound = { + protocol = "vmess", + settings = { + vnext = { + { + address = server.server, + port = tonumber(server.server_port), + users = { + { + id = server.vmess_id, + alterId = tonumber(server.alter_id), + security = server.security + } + } + } + } + }, + -- 底层传输配置 + streamSettings = { + network = server.transport, + security = (server.tls == '1') and "tls" or "none", + tlsSettings = {allowInsecure = (server.insecure ~= "0") and true or false,serverName=server.tls_host,}, + kcpSettings = (server.transport == "kcp") and { + mtu = tonumber(server.mtu), + tti = tonumber(server.tti), + uplinkCapacity = tonumber(server.uplink_capacity), + downlinkCapacity = tonumber(server.downlink_capacity), + congestion = (server.congestion == "1") and true or false, + readBufferSize = tonumber(server.read_buffer_size), + writeBufferSize = tonumber(server.write_buffer_size), + header = { + type = server.kcp_guise + } + } or nil, + wsSettings = (server.transport == "ws") and (server.ws_path ~= nil or server.ws_host ~= nil) and { + path = server.ws_path, + headers = (server.ws_host ~= nil) and { + Host = server.ws_host + } or nil, + } or nil, + httpSettings = (server.transport == "h2") and { + path = server.h2_path, + host = server.h2_host, + } or nil, + quicSettings = (server.transport == "quic") and { + security = server.quic_security, + key = server.quic_key, + header = { + type = server.quic_guise + } + } or nil + }, + mux = { + enabled = (server.mux == "1") and true or false, + concurrency = tonumber(server.concurrency) + } + }, + + -- 额外传出连接 + outboundDetour = { + { + protocol = "freedom", + tag = "direct", + settings = { keep = "" } + } + } +} +print(json.stringify(v2ray, 1))