Browse Source

v2ray Add HTTP Obfuscation support

Mattraks 5 years ago
parent
commit
2f63c3fb82

+ 29 - 34
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua

@@ -1,20 +1,16 @@
 -- Licensed to the public under the GNU General Public License v3.
-
+require "luci.http"
+require "luci.dispatcher"
+require "luci.model.uci"
 local m, s, o
 local shadowsocksr = "shadowsocksr"
-
 local uci = luci.model.uci.cursor()
 local server_count = 0
 uci:foreach("shadowsocksr", "servers", function(s)
-  server_count = server_count + 1
+	server_count = server_count + 1
 end)
 
-local fs  = require "nixio.fs"
-local sys = require "luci.sys"
-
-local ucic = luci.model.uci.cursor()
-
-m = Map(shadowsocksr,  translate("Servers subscription and manage"))
+m = Map(shadowsocksr, translate("Servers subscription and manage"))
 
 -- Server Subscribe
 
@@ -28,7 +24,7 @@ o.description = translate("Auto Update Server subscription, GFW list and CHN rou
 
 o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
 for t = 0,23 do
-o:value(t, t..":00")
+	o:value(t, t..":00")
 end
 o.default=2
 o.rmempty = false
@@ -44,7 +40,7 @@ o = s:option(Button,"update_Sub",translate("Update Subscribe List"))
 o.inputstyle = "reload"
 o.description = translate("Update subscribe url list first")
 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
 
 o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
@@ -58,25 +54,25 @@ o.description = translate("Through proxy update list, Not Recommended ")
 
 
 o = s:option(Button,"subscribe", translate("Update All Subscribe Severs"))
-o.rawhtml  = true
+o.rawhtml = true
 o.template = "shadowsocksr/subscribe"
 
 o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
 o.inputstyle = "reset"
-o.description = string.format(translate("Server Count") ..  ": %d", server_count)
+o.description = string.format(translate("Server Count") .. ": %d", server_count)
 o.write = function()
-uci:delete_all("shadowsocksr", "servers", function(s)
-  if s.hashkey or s.isSubscribe then
-    return true
-  else
-    return false
-  end
-end)
-uci:save("shadowsocksr") 
-uci:commit("shadowsocksr")
-luci.sys.exec("/etc/init.d/shadowsocksr restart")
-luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
-return
+	uci:delete_all("shadowsocksr", "servers", function(s)
+		if s.hashkey or s.isSubscribe then
+			return true
+		else
+			return false
+		end
+	end)
+	uci:save("shadowsocksr")
+	uci:commit("shadowsocksr")
+	luci.sys.exec("/etc/init.d/shadowsocksr restart")
+	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
+	return
 end
 
 -- [[ Servers Manage ]]--
@@ -85,12 +81,12 @@ s.anonymous = true
 s.addremove = true
 s.template = "cbi/tblsection"
 s.sortable = true
-s.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/servers/%s")
+s.extedit = luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers", "%s")
 function s.create(...)
 	local sid = TypedSection.create(...)
 	if sid then
 		luci.http.redirect(s.extedit % sid)
-	return
+		return
 	end
 end
 
@@ -117,15 +113,14 @@ o = s:option(DummyValue, "server", translate("Ping Latency"))
 o.template="shadowsocksr/ping"
 o.width="10%"
 
-
 node = s:option(Button,"apply_node",translate("Apply"))
 node.inputstyle = "apply"
 node.write = function(self, section)
-  ucic:set("shadowsocksr", '@global[0]', 'global_server', section)
-  ucic:save("shadowsocksr") 
-  ucic:commit("shadowsocksr")
-  luci.sys.exec("/etc/init.d/shadowsocksr restart")
-  luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client"))
+	uci:set("shadowsocksr", '@global[0]', 'global_server', section)
+	uci:save("shadowsocksr")
+	uci:commit("shadowsocksr")
+	luci.sys.exec("/etc/init.d/shadowsocksr restart")
+	luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client"))
 end
 
 o = s:option(Flag, "switch_enable", translate("Auto Switch"))
@@ -136,4 +131,4 @@ end
 
 m:append(Template("shadowsocksr/server_list"))
 
-return m
+return m

+ 2 - 0
luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm

@@ -262,6 +262,8 @@
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value = ssm.net;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
 			if (ssm.net == "tcp") {
+			if (ssm.type && ssm.type ~= "http") {ssm.type = "none"}
+			document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = ssm.type;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = ssm.host;
 			document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = ssm.path;
 			}

+ 2 - 2
luci-app-ssr-plus/root/etc/init.d/shadowsocksr

@@ -239,7 +239,7 @@ start_rules() {
 	-S "$udp_server" \
 	-L "$udp_local_port" \
 	-a "$ac_ips" \
-	-i "$(uci_get_by_type access_control wan_bp_list)" \
+	-i "/etc/ssr/china_ssr.txt" \
 	-b "$(uci_get_by_type access_control wan_bp_ips)" \
 	-w "$(uci_get_by_type access_control wan_fw_ips)" \
 	-B "$(uci_get_by_type access_control lan_bp_ips)" \
@@ -652,7 +652,7 @@ start() {
 
 		if [ "$NETFLIX_SERVER" != "nil" ]; then
 			if [ "$NETFLIX_SERVER" != "$GLOBAL_SERVER" ]; then
-				cat /etc/config/netflix.list | while read line || [ -n "$line" ]; do
+				cat /etc/ssr/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/ssr/netflix.list >/tmp/dnsmasq.ssr/netflix_forward.conf

+ 9 - 1
luci-app-ssr-plus/root/etc/uci-defaults/luci-ssr-plus

@@ -11,6 +11,14 @@ set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
 set firewall.shadowsocksr.reload=1
 commit firewall
 EOF
+chmod 0755 etc/init.d/shadowsocksr /usr/bin/ssr-* /usr/share/shadowsocksr/*.sh
+chmod 0644 /etc/ssr/* \
+/usr/share/shadowsocksr/*.lua \
+/usr/share/rpcd/acl.d/luci-app-ssr-plus.json \
+/usr/lib/lua/luci/controller/shadowsocksr.lua \
+/usr/lib/lua/luci/model/cbi/shadowsocksr/*.lua \
+/usr/lib/lua/luci/view/shadowsocksr/*.htm
+chmod 0600 /etc/config/shadowsocksr
 touch /etc/ssr/china_ssr.txt
 touch /etc/ssr/white.list
 touch /etc/ssr/black.list
@@ -19,4 +27,4 @@ touch /etc/ssr/netflixip.list
 touch /etc/ssr/ad.conf
 touch /etc/ssr/gfw_list.conf
 rm -rf /tmp/luci-modulecache /tmp/luci-indexcache
-exit 0
+exit 0

+ 91 - 83
luci-app-ssr-plus/root/usr/share/shadowsocksr/genv2config.lua

@@ -4,99 +4,107 @@ local server_section = arg[1]
 local proto = arg[2]
 local local_port = arg[3] or "0"
 local socks_port = arg[4] or "0"
-
 local server = ucursor:get_all("shadowsocksr", server_section)
-
 local v2ray = {
 log = {
-	-- error = "/var/ssrplus.log",
-	loglevel = "warning"
+-- error = "/var/ssrplus.log",
+loglevel = "warning"
 },
- -- 传入连接
- inbound = (local_port ~= "0") and {
-     port = local_port,
-     protocol = "dokodemo-door",
-     settings = {
-         network = proto,
-         followRedirect = true
-     },
-     sniffing = {
-         enabled = true,
-         destOverride = { "http", "tls" }
-     }
- } or nil,
- -- 开启 socks 代理 
- inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
-   {
-     protocol = "socks",
-     port = socks_port,
-     settings = {
-       auth = "noauth",
-       udp = true
-     }
-   }
- } or nil,
- -- 传出连接
-	outbound = {
-		protocol = "vmess",
+-- 传入连接
+inbound = (local_port ~= "0") and {
+	port = local_port,
+	protocol = "dokodemo-door",
+	settings = {
+		network = proto,
+		followRedirect = true
+	},
+	sniffing = {
+		enabled = true,
+		destOverride = { "http", "tls" }
+	}
+} or nil,
+-- 开启 socks 代理
+inboundDetour = (proto == "tcp" and socks_port ~= "0") and {
+	{
+	protocol = "socks",
+	port = socks_port,
 		settings = {
-			vnext = {
-				{
-					address = server.server,
-					port = tonumber(server.server_port),
-					users = {
-						{
-							id = server.vmess_id,
-							alterId = tonumber(server.alter_id),
-							security = server.security
-						}
+			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,
+	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,},
+		tcpSettings = (server.transport == "tcp") and {
+			header = {
+				type = server.tcp_guise,
+				request = {
+					path = server.http_path or {"/"},
+					headers = {
+						Host = server.http_host or {}
+					}
+				} or {}
+			}
+		} or nil,
+		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,
-			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)
-		}
+		} 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
 	},
-
-	-- 额外传出连接
-	outboundDetour = {
+	mux = {
+		enabled = (server.mux == "1") and true or false,
+		concurrency = tonumber(server.concurrency)
+	}
+},
+-- 额外传出连接
+outboundDetour = {
 		{
 			protocol = "freedom",
 			tag = "direct",
@@ -104,4 +112,4 @@ log = {
 		}
 	}
 }
-print(json.stringify(v2ray, 1))
+print(json.stringify(v2ray, 1))

+ 33 - 33
luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua

@@ -3,34 +3,32 @@
 -- This file is part of the luci-app-ssr-plus subscribe.lua
 -- @author William Chan <[email protected]>
 ------------------------------------------------
-require 'nixio'
-require 'luci.util'
-require 'luci.jsonc'
-require 'luci.sys'
-require 'uci'
+require "luci.model.uci"
+require "nixio"
+require "luci.util"
+require "luci.sys"
+require "luci.jsonc"
 -- these global functions are accessed all the time by the event handler
 -- so caching them is worth the effort
-local luci = luci
 local tinsert = table.insert
 local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
 local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
 local b64decode = nixio.bin.b64decode
 local cache = {}
-local nodeResult = setmetatable({}, { __index = cache })  -- update result
+local nodeResult = setmetatable({}, { __index = cache }) -- update result
 local name = 'shadowsocksr'
 local uciType = 'servers'
 local ucic = luci.model.uci.cursor()
 local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
 local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
 local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
-local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', 'QQ群')
-
+local filter_words = ucic:get_first(name, 'server_subscribe', 'filter_words', '过期时间/剩余流量')
 local log = function(...)
 	print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
 end
 -- 分割字符串
 local function split(full, sep)
-	full = full:gsub("%z", "")  -- 这里不是很清楚 有时候结尾带个\0
+	full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0
 	local off, result = 1, {}
 	while true do
 		local nStart, nEnd = full:find(sep, off)
@@ -74,7 +72,7 @@ local function trim(text)
 end
 -- md5
 local function md5(content)
-	local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \"  -f1')
+	local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
 	-- assert(nixio.errno() == 0)
 	return trim(stdout)
 end
@@ -119,7 +117,7 @@ local function processData(szType, content)
 		result.protocol_param = base64Decode(params.protoparam)
 		local group = base64Decode(params.group)
 		if group then
-			result.alias = "["  .. group .. "] "
+			result.alias = "[" .. group .. "] "
 		end
 		result.alias = result.alias .. base64Decode(params.remarks)
 	elseif szType == 'vmess' then
@@ -131,7 +129,6 @@ local function processData(szType, content)
 		result.alter_id = info.aid
 		result.vmess_id = info.id
 		result.alias = info.ps
-		result.insecure = 1
 		-- result.mux = 1
 		-- result.concurrency = 8
 		if info.net == 'ws' then
@@ -143,6 +140,9 @@ local function processData(szType, content)
 			result.h2_path = info.path
 		end
 		if info.net == 'tcp' then
+			if info.type and info.type ~= "http" then
+				info.type = "none"
+			end
 			result.tcp_guise = info.type
 			result.http_host = info.host
 			result.http_path = info.path
@@ -167,6 +167,7 @@ local function processData(szType, content)
 		if info.tls == "tls" or info.tls == "1" then
 			result.tls = "1"
 			result.tls_host = info.host
+			result.insecure = 1
 		else
 			result.tls = "0"
 		end
@@ -244,12 +245,10 @@ local function processData(szType, content)
 				local t = split(v, '=')
 				params[t[1]] = t[2]
 			end
-			
 			if params.peer then
 				-- 未指定peer(sni)默认使用remote addr
 				result.tls_host = params.peer
 			end
-			
 			if params.allowInsecure == "1" then
 				result.insecure = "1"
 			else
@@ -280,15 +279,15 @@ local function wget(url)
 end
 
 local function check_filer(result)
-  do 
-    local filter_word = split(filter_words, "/")
-    for i, v in pairs(filter_word) do
-        if result.alias:find(v) then
-          log('订阅节点关键字过滤:“' .. v ..'” ,该节点被丢弃')
-          return true
-        end
-    end 
-  end
+	do
+		local filter_word = split(filter_words, "/")
+		for i, v in pairs(filter_word) do
+			if result.alias:find(v) then
+				log('订阅节点关键字过滤:“' .. v ..'” ,该节点被丢弃')
+				return true
+			end
+		end
+	end
 end
 
 local execute = function()
@@ -313,10 +312,10 @@ local execute = function()
 					nodes = base64Decode(raw:sub(nEnd + 1, #raw))
 					nodes = jsonParse(nodes)
 					local extra = {
-						airport = nodes.airport,
-						port = nodes.port,
-						encryption = nodes.encryption,
-						password = nodes.password
+					airport = nodes.airport,
+					port = nodes.port,
+					encryption = nodes.encryption,
+					password = nodes.password
 					}
 					local servers = {}
 					-- SS里面包着 干脆直接这样
@@ -349,10 +348,11 @@ local execute = function()
 						-- log(result)
 						if result then
 							if
-                not result.server or
-                check_filer(result) or
-                result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
-							then
+								not result.server or
+								not result.server_port or
+								check_filer(result) or
+								result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞,就算中文域也有Puny Code SB 机场
+								then
 								log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
 							else
 								log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
@@ -385,7 +385,7 @@ local execute = function()
 					local dat = nodeResult[old.grouphashkey][old.hashkey]
 					ucic:tset(name, old['.name'], dat)
 					-- 标记一下
-					setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index =  { _ignore = true } })
+					setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
 				end
 			else
 				if not old.alias then