luci-app-ssr-plus: add Netflix shunting mode for SS/SSR/V2

This commit is contained in:
lean 2020-03-16 23:49:17 +08:00
parent ffda8423f9
commit a331de62e6
10 changed files with 240 additions and 39 deletions

View File

@ -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

View File

@ -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"))

View File

@ -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

View File

@ -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"))

View File

@ -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 分流域名列表"

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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."

View File

@ -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))