luci-app-ssr-plus: add package

This commit is contained in:
CN_SZTL 2019-11-08 22:22:59 +08:00
parent 14372217e3
commit bea1279eec
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
57 changed files with 36101 additions and 0 deletions

View File

@ -0,0 +1,71 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
ifeq ($(ARCH),x86_64)
PKG_ARCH_KCPTUN:=amd64
endif
ifeq ($(ARCH),mipsel)
PKG_ARCH_KCPTUN:=mipsle
endif
ifeq ($(ARCH),mips)
PKG_ARCH_KCPTUN:=mips
endif
ifeq ($(ARCH),i386)
PKG_ARCH_KCPTUN:=386
endif
ifeq ($(ARCH),arm)
PKG_ARCH_KCPTUN:=arm7
endif
ifeq ($(BOARD),bcm53xx)
PKG_ARCH_KCPTUN:=arm6
endif
ifeq ($(BOARD),kirkwood)
PKG_ARCH_KCPTUN:=arm5
endif
ifeq ($(ARCH),aarch64)
PKG_ARCH_KCPTUN:=arm64
endif
PKG_NAME:=kcptun-client
PKG_VERSION:=20190924
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=kcptun-linux-$(PKG_ARCH_KCPTUN)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/xtaci/kcptun/releases/download/v$(PKG_VERSION)
PKG_HASH:=skip
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=Kcptun is a cross-platform proxy software
DEPENDS:=
URL:=https://github.com/xtaci/kcptun
endef
define Package/$(PKG_NAME)/description
Kcptun is a Fast and Reliable ARQ Protocol tunnel
endef
define Build/Prepare
tar -xzvf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/client_linux_$(PKG_ARCH_KCPTUN) $(1)/usr/bin/kcptun-client
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@ -0,0 +1,91 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=1
PKG_RELEASE:=125
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)/config
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
bool "Include Shadowsocks New Version"
default y if x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
default y if x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
bool "Include ShadowsocksR Server"
default y if x86_64
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
bool "Include ShadowsocksR Socks and Tunnel"
default y if x86_64
endef
define Package/luci-app-ssr-plus
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:=SS/SSR/V2Ray LuCI interface
PKGARCH:=all
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local
endef
define Build/Prepare
endef
define Build/Compile
endef
define Package/luci-app-ssr-plus/conffiles
/etc/ssr_ip
/etc/dnsmasq.ssr/gfw_list.conf
endef
define Package/luci-app-ssr-plus/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
$(INSTALL_DIR) $(1)/
cp -pR ./root/* $(1)/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
po2lmo ./po/zh-cn/ssr-plus.po $(1)/usr/lib/lua/luci/i18n/ssr-plus.zh-cn.lmo
endef
define Package/luci-app-ssr-plus/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
( . /etc/uci-defaults/luci-ssr-plus ) && rm -f /etc/uci-defaults/luci-ssr-plus
rm -f /tmp/luci-indexcache
chmod 755 /etc/init.d/shadowsocksr >/dev/null 2>&1
/etc/init.d/shadowsocksr enable >/dev/null 2>&1
fi
exit 0
endef
define Package/luci-app-ssr-plus/prerm
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
/etc/init.d/shadowsocksr disable
/etc/init.d/shadowsocksr stop
fi
exit 0
endef
$(eval $(call BuildPackage,luci-app-ssr-plus))

View File

@ -0,0 +1,192 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.shadowsocksr", package.seeall)
function index()
if not nixio.fs.access("/etc/config/shadowsocksr") then
return
end
entry({"admin", "services", "shadowsocksr"},alias("admin", "services", "shadowsocksr", "client"),_("ShadowSocksR Plus+"), 10).dependent = true
entry({"admin", "services", "shadowsocksr", "client"},cbi("shadowsocksr/client"),_("SSR Client"), 10).leaf = true
entry({"admin", "services", "shadowsocksr", "servers"}, arcombine(cbi("shadowsocksr/servers", {autoapply=true}), cbi("shadowsocksr/client-config")),_("Severs Nodes"), 20).leaf = true
entry({"admin", "services", "shadowsocksr", "control"},cbi("shadowsocksr/control"),_("Access Control"), 30).leaf = true
-- entry({"admin", "services", "shadowsocksr", "list"},form("shadowsocksr/list"),_("GFW List"), 40).leaf = true
entry({"admin", "services", "shadowsocksr", "advanced"},cbi("shadowsocksr/advanced"),_("Advanced Settings"), 50).leaf = true
if nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "services", "shadowsocksr", "server"},arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")),_("SSR Server"), 60).leaf = true
end
entry({"admin", "services", "shadowsocksr", "status"},form("shadowsocksr/status"),_("Status"), 70).leaf = true
entry({"admin", "services", "shadowsocksr", "check"}, call("check_status"))
entry({"admin", "services", "shadowsocksr", "refresh"}, call("refresh_data"))
entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port"))
entry({"admin", "services", "shadowsocksr", "log"},form("shadowsocksr/log"),_("Log"), 80).leaf = true
entry({"admin", "services", "shadowsocksr","run"},call("act_status")).leaf=true
entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping")).leaf=true
end
function act_status()
local e={}
e.running=luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function act_ping()
local e={}
e.index=luci.http.formvalue("index")
e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function check_status()
local set ="/usr/bin/ssr-check www." .. luci.http.formvalue("set") .. ".com 80 3 1"
sret=luci.sys.call(set)
if sret== 0 then
retstring ="0"
else
retstring ="1"
end
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring })
end
function refresh_data()
local set =luci.http.formvalue("set")
local icount =0
if set == "gfw_data" then
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd="wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64"
else
refresh_cmd="wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64"
end
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret== 0 then
luci.sys.call("/usr/bin/ssr-gfw")
icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
if tonumber(icount)>1000 then
oldcount=luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf")
retstring=tostring(math.ceil(tonumber(icount)/2))
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
else
retstring ="-1"
end
elseif set == "ip_data" then
refresh_cmd="wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' 2>/dev/null| awk -F\\| '/CN\\|ipv4/ { printf(\"%s/%d\\n\", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt"
sret=luci.sys.call(refresh_cmd)
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if sret== 0 and tonumber(icount)>1000 then
oldcount=luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
retstring=tostring(tonumber(icount))
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
else
local need_process = 0
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd="wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf"
need_process = 1
else
refresh_cmd="wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf"
end
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret== 0 then
if need_process == 1 then
luci.sys.call("/usr/bin/ssr-ad")
end
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount)>1000 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
oldcount=luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount=0
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
retstring=tostring(math.ceil(tonumber(icount)))
if oldcount==0 then
luci.sys.call("/etc/init.d/dnsmasq restart")
end
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/ad.conf ")
else
retstring ="-1"
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring ,retcount=icount})
end
function check_port()
local set=""
local retstring="<br /><br />"
local s
local server_name = ""
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local iret=1
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_name=s.alias
elseif s.server and s.server_port then
server_name= "%s:%s" %{s.server, s.server_port}
end
iret=luci.sys.call(" ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
ret=socket:connect(s.server,s.server_port)
if tostring(ret) == "true" then
socket:close()
retstring =retstring .. "<font color='green'>[" .. server_name .. "] OK.</font><br />"
else
retstring =retstring .. "<font color='red'>[" .. server_name .. "] Error.</font><br />"
end
if iret== 0 then
luci.sys.call(" ipset del ss_spec_wan_ac " .. s.server)
end
end)
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring })
end

View File

@ -0,0 +1,59 @@
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
m = Map(shadowsocksr)
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
s.anonymous = true
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
o.rmempty = false
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
o.rmempty = false
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 3600
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 5
-- [[ SOCKS5 Proxy ]]--
if nixio.fs.access("/usr/bin/ssr-local") then
s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
s.anonymous = true
o = s:option(ListValue, "server", translate("Server"))
o:value("nil", translate("Disable"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.default = 1080
o.rmempty = false
end
return m

View File

@ -0,0 +1,403 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Licensed to the public under the GNU General Public License v3.
local m, s, o,kcp_enable
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
local function isKcptun(file)
if not fs.access(file, "rwx", "rx", "rx") then
fs.chmod(file, 755)
end
local str = sys.exec(file .. " -v | awk '{printf $1}'")
return (str:lower() == "kcptun")
end
local server_table = {}
local encrypt_methods = {
"none",
"table",
"rc4",
"rc4-md5-6",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local encrypt_methods_ss = {
-- aead
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
-- stream
"table",
"rc4",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
"auth_chain_b",
"auth_chain_c",
"auth_chain_d",
"auth_chain_e",
"auth_chain_f",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
}
local securitys = {
"auto",
"none",
"aes-128-gcm",
"chacha20-poly1305"
}
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
if m.uci:get(shadowsocksr, sid) ~= "servers" then
luci.http.redirect(m.redirect)
return
end
-- [[ Servers Setting ]]--
s = m:section(NamedSection, sid, "servers")
s.anonymous = true
s.addremove = false
o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY URL")
o.rawhtml = true
o.template = "shadowsocksr/ssrurl"
o.value =sid
o = s:option(ListValue, "type", translate("Server Node Type"))
o:value("ssr", translate("ShadowsocksR"))
if nixio.fs.access("/usr/bin/ss-redir") then
o:value("ss", translate("Shadowsocks New Version"))
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
o:value("v2ray", translate("V2Ray"))
end
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
o = s:option(Value, "alias", translate("Alias(optional)"))
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
-- o = s:option(Value, "timeout", translate("Connection Timeout"))
-- o.datatype = "uinteger"
-- o.default = 60
-- o.rmempty = false
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
o.rmempty = true
o:depends("type", "ss")
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(Value, "protocol_param", translate("Protocol param(optional)"))
o:depends("type", "ssr")
o = s:option(ListValue, "obfs", translate("Obfs"))
for _, v in ipairs(obfs) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
o:depends("type", "ssr")
-- AlterId
o = s:option(Value, "alter_id", translate("AlterId"))
o.datatype = "port"
o.default = 16
o.rmempty = true
o:depends("type", "v2ray")
-- VmessId
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
o.rmempty = true
o.default = uuid
o:depends("type", "v2ray")
-- 加密方式
o = s:option(ListValue, "security", translate("Encrypt Method"))
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
o.rmempty = true
o:depends("type", "v2ray")
-- 传输协议
o = s:option(ListValue, "transport", translate("Transport"))
o:value("tcp", "TCP")
o:value("kcp", "mKCP")
o:value("ws", "WebSocket")
o:value("h2", "HTTP/2")
o:value("quic", "QUIC")
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TCP部分 ]]--
-- TCP伪装
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
o:depends("transport", "tcp")
o:value("http", "HTTP")
o:value("none", translate("None"))
o.rmempty = true
-- HTTP域名
o = s:option(Value, "http_host", translate("HTTP Host"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- HTTP路径
o = s:option(Value, "http_path", translate("HTTP Path"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- [[ WS部分 ]]--
-- WS域名
o = s:option(Value, "ws_host", translate("WebSocket Host"))
o:depends("transport", "ws")
o.rmempty = true
-- WS路径
o = s:option(Value, "ws_path", translate("WebSocket Path"))
o:depends("transport", "ws")
o.rmempty = true
-- [[ H2部分 ]]--
-- H2域名
o = s:option(Value, "h2_host", translate("HTTP/2 Host"))
o:depends("transport", "h2")
o.rmempty = true
-- H2路径
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
o:depends("transport", "h2")
o.rmempty = true
-- [[ QUIC部分 ]]--
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("aes-128-gcm", translate("aes-128-gcm"))
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
o = s:option(Value, "quic_key", translate("QUIC Key"))
o:depends("transport", "quic")
o.rmempty = true
o = s:option(ListValue, "quic_guise", translate("Header"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
-- [[ mKCP部分 ]]--
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
o:depends("transport", "kcp")
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
o.rmempty = true
o = s:option(Value, "mtu", translate("MTU"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 1350
o.rmempty = true
o = s:option(Value, "tti", translate("TTI"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 50
o.rmempty = true
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 5
o.rmempty = true
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 20
o.rmempty = true
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Flag, "congestion", translate("Congestion"))
o:depends("transport", "kcp")
o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, "insecure", translate("allowInsecure"))
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TLS ]]--
o = s:option(Flag, "tls", translate("TLS"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
-- [[ Mux ]]--
o = s:option(Flag, "mux", translate("Mux"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
o = s:option(Value, "concurrency", translate("Concurrency"))
o.datatype = "uinteger"
o.rmempty = true
o.default = "8"
o:depends("mux", "1")
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
o.rmempty = true
o.default = "0"
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
o.rmempty = false
o.default = "1"
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.default = 1234
o.rmempty = false
if nixio.fs.access("/usr/bin/kcptun-client") then
kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
kcp_enable.rmempty = true
kcp_enable.default = "0"
kcp_enable:depends("type", "ssr")
kcp_enable:depends("type", "ss")
o = s:option(Value, "kcp_port", translate("KcpTun Port"))
o.datatype = "port"
o.default = 4000
function o.validate(self, value, section)
local kcp_file="/usr/bin/kcptun-client"
local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
if enable == kcp_enable.enabled then
if not fs.access(kcp_file) then
return nil, translate("Haven't a Kcptun executable file")
elseif not isKcptun(kcp_file) then
return nil, translate("Not a Kcptun executable file")
end
end
return value
end
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(Value, "kcp_password", translate("KcpTun Password"))
o.password = true
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(Value, "kcp_param", translate("KcpTun Param"))
o.default = "--nocomp"
o:depends("type", "ssr")
o:depends("type", "ss")
end
return m

View File

@ -0,0 +1,89 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
-- Licensed to the public under the GNU General Public License v3.
local m, s, sec, o, kcp_enable
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local sys = require "luci.sys"
m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings"))
m:section(SimpleSection).template = "shadowsocksr/status"
local server_table = {}
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
-- [[ Global Setting ]]--
s = m:section(TypedSection, "global")
s.anonymous = true
o = s:option(ListValue, "global_server", translate("Main Server"))
o:value("nil", translate("Disable"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o.rmempty = false
o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
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, "threads", translate("Multi Threads Option"))
o:value("0", translate("Auto Threads"))
o:value("1", translate("1 Thread"))
o:value("2", translate("2 Threads"))
o:value("4", translate("4 Threads"))
o:value("8", translate("8 Threads"))
o.default = "0"
o.rmempty = false
o = s:option(ListValue, "run_mode", translate("Running Mode"))
o:value("gfw", translate("GFW List Mode"))
o:value("router", translate("IP Route Mode"))
o:value("all", translate("Global Mode"))
o:value("oversea", translate("Oversea Mode"))
o.default = gfw
o = s:option(ListValue, "dports", translate("Proxy Ports"))
o:value("1", translate("All Ports"))
o:value("2", translate("Only Common Ports"))
o.default = 1
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
o:value("0", translate("Use Local DNS Service listen port 5335"))
o:value("2", translate("Use system DNS"))
o.default = 1
o = s:option(ListValue, "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: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:depends("pdnsd_enable", "1")
return m

View File

@ -0,0 +1,88 @@
local m, s, o
local NXFS = require "nixio.fs"
m = Map("shadowsocksr", translate("IP black-and-white list"))
s = m:section(TypedSection, "access_control")
s.anonymous = true
-- Part of WAN
s:tab("wan_ac", translate("WAN IP AC"))
o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP"))
o.datatype = "ip4addr"
o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP"))
o.datatype = "ip4addr"
-- Part of LAN
s:tab("lan_ac", translate("LAN IP AC"))
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Bypassed Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
-- Part of Self
-- s:tab("self_ac", translate("Router Self AC"))
-- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy"))
-- o:value("1", translatef("Normal Proxy"))
-- o:value("0", translatef("Bypassed Proxy"))
-- o:value("2", translatef("Forwarded Proxy"))
-- o.rmempty = false
s:tab("esc", translate("Bypass Domain List"))
local escconf = "/etc/config/white.list"
o = s:taboption("esc", TextValue, "escconf")
o.rows = 13
o.wrap = "off"
o.rmempty = true
o.cfgvalue = function(self, section)
return NXFS.readfile(escconf) or ""
end
o.write = function(self, section, value)
NXFS.writefile(escconf, value:gsub("\r\n", "\n"))
end
o.remove = function(self, section, value)
NXFS.writefile(escconf, "")
end
s:tab("block", translate("Black Domain List"))
local blockconf = "/etc/config/black.list"
o = s:taboption("block", TextValue, "blockconf")
o.rows = 13
o.wrap = "off"
o.rmempty = true
o.cfgvalue = function(self, section)
return NXFS.readfile(blockconf) or " "
end
o.write = function(self, section, value)
NXFS.writefile(blockconf, value:gsub("\r\n", "\n"))
end
o.remove = function(self, section, value)
NXFS.writefile(blockconf, "")
end
return m

View File

@ -0,0 +1,23 @@
local fs = require "nixio.fs"
local conffile = "/etc/config/gfw.list"
f = SimpleForm("custom", translate("GFW Custom List"), translate("Please refer to the following writing"))
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 13
function t.cfgvalue()
return fs.readfile(conffile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.conf then
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh && /etc/init.d/dnsmasq restart")
end
end
return true
end
return f

View File

@ -0,0 +1,15 @@
local fs = require "nixio.fs"
local conffile = "/tmp/ssrpro.log"
f = SimpleForm("logview")
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 20
function t.cfgvalue()
luci.sys.exec("[ -f /tmp/ssrplus.log ] && sed '1!G;h;$!d' /tmp/ssrplus.log > /tmp/ssrpro.log")
return fs.readfile(conffile) or ""
end
t.readonly="readonly"
return f

View File

@ -0,0 +1,95 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local shadowsocksr = "shadowsocksr"
local sid = arg[1]
local encrypt_methods = {
"rc4-md5",
"rc4-md5-6",
"rc4",
"table",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
}
obfs = {
"plain",
"http_simple",
"http_post",
}
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server")
if m.uci:get(shadowsocksr, sid) ~= "server_config" then
luci.http.redirect(m.redirect)
return
end
-- [[ Server Setting ]]--
s = m:section(NamedSection, sid, "server_config")
s.anonymous = true
s.addremove = false
o = s:option(Flag, "enable", translate("Enable"))
o.default = 1
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.default = 8388
o.rmempty = false
o = s:option(Value, "timeout", translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 60
o.rmempty = false
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = false
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods) do o:value(v) end
o.rmempty = false
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do o:value(v) end
o.rmempty = false
o = s:option(ListValue, "obfs", translate("Obfs"))
for _, v in ipairs(obfs) do o:value(v) end
o.rmempty = false
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
o.rmempty = false
return m

View File

@ -0,0 +1,114 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local m, sec, o
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local ipkg = require("luci.model.ipkg")
m = Map(shadowsocksr, translate("ShadowSocksR Server"))
local encrypt_methods = {
"table",
"rc4",
"rc4-md5",
"rc4-md5-6",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
"tls1.2_ticket_fastauth",
}
-- [[ Global Setting ]]--
sec = m:section(TypedSection, "server_global", translate("Global Setting"))
sec.anonymous = true
o = sec:option(Flag, "enable_server", translate("Enable Server"))
o.rmempty = false
-- [[ Server Setting ]]--
sec = m:section(TypedSection, "server_config", translate("Server Setting"))
sec.anonymous = true
sec.addremove = true
sec.template = "cbi/tblsection"
sec.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/server/%s")
function sec.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(sec.extedit % sid)
return
end
end
o = sec:option(Flag, "enable", translate("Enable"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("0")
end
o.rmempty = false
o = sec:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
function o.cfgvalue(...)
local v = Value.cfgvalue(...)
return v and v:upper() or "?"
end
o = sec:option(DummyValue, "protocol", translate("Protocol"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = sec:option(DummyValue, "obfs", translate("Obfs"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
return m

View File

@ -0,0 +1,122 @@
-- Licensed to the public under the GNU General Public License v3.
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
end)
local fs = require "nixio.fs"
local sys = require "luci.sys"
m = Map(shadowsocksr, translate("Servers subscription and manage"))
-- Server Subscribe
s = m:section(TypedSection, "server_subscribe")
s.anonymous = true
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false
o.description = translate("Auto Update Server subscription, GFW list and CHN route")
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0,23 do
o:value(t, t..":00")
end
o.default=2
o.rmempty = false
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true
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"))
end
o = s:option(Flag, "proxy", translate("Through proxy update"))
o.rmempty = false
o.description = translate("Through proxy update list, Not Recommended ")
o = s:option(Button,"update",translate("Update All Subscribe Severs"))
o.inputstyle = "apply"
o.write = function()
luci.sys.exec("bash /usr/share/shadowsocksr/subscribe.sh >>/tmp/ssrplus.log 2>&1")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
end
o = s:option(Button,"delete",translate("Delete all severs"))
o.inputstyle = "reset"
o.description = string.format(translate("Server Count") .. ": %d", server_count)
o.write = function()
uci:delete_all("shadowsocksr", "servers", function(s) return true end)
uci:save("shadowsocksr")
luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr stop")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
return
end
-- [[ Servers Manage ]]--
s = m:section(TypedSection, "servers")
s.anonymous = true
s.addremove = true
s.sortable = false
s.template = "cbi/tblsection"
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
end
end
o = s:option(DummyValue, "type", translate("Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("")
end
o = s:option(DummyValue, "alias", translate("Alias"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "server", translate("Server Address"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = s:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
if nixio.fs.access("/usr/bin/kcptun-client") then
o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
end
o = s:option(DummyValue, "switch_enable", translate("Auto Switch"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "0"
end
o = s:option(DummyValue,"server",translate("Ping Latency"))
o.template="shadowsocksr/ping"
o.width="10%"
m:append(Template("shadowsocksr/server_list"))
return m

View File

@ -0,0 +1,180 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local IPK_Version="3.0.9"
local m, s, o
local redir_run=0
local reudp_run=0
local sock5_run=0
local server_run=0
local kcptun_run=0
local tunnel_run=0
local udp2raw_run=0
local udpspeeder_run=0
local gfw_count=0
local ad_count=0
local ip_count=0
local gfwmode=0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfwmode=1
end
local shadowsocksr = "shadowsocksr"
-- html constants
font_blue = [[<font color="green">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
local fs = require "nixio.fs"
local sys = require "luci.sys"
local kcptun_version=translate("Unknown")
local kcp_file="/usr/bin/kcptun-client"
if not fs.access(kcp_file) then
kcptun_version=translate("Not exist")
else
if not fs.access(kcp_file, "rwx", "rx", "rx") then
fs.chmod(kcp_file, 755)
end
kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
if not kcptun_version or kcptun_version == "" then
kcptun_version = translate("Unknown")
end
end
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
local icount=sys.exec("busybox ps -w | grep ssr-reudp |grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
else
icount=sys.exec("busybox ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
end
end
if luci.sys.call("busybox ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
redir_run=1
end
if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
sock5_run=1
end
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
kcptun_run=1
end
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
server_run=1
end
if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
tunnel_run=1
end
if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
pdnsd_run=1
end
m = SimpleForm("Version")
m.reset = false
m.submit = false
s=m:field(DummyValue,"redir_run",translate("Global Client"))
s.rawhtml = true
if redir_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
s.rawhtml = true
if reudp_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
s.rawhtml = true
if pdnsd_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/ssr-local") then
s=m:field(DummyValue,"sock5_run",translate("SOCKS5 Proxy"))
s.rawhtml = true
if sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ssr-server") then
s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
s.rawhtml = true
if server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/kcptun-client") then
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
s.rawhtml = true
s.value =kcptun_version
s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
s.rawhtml = true
if kcptun_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"google",translate("Google Connectivity"))
s.value = translate("No Check")
s.template = "shadowsocksr/check"
s=m:field(DummyValue,"baidu",translate("Baidu Connectivity"))
s.value = translate("No Check")
s.template = "shadowsocksr/check"
if gfwmode==1 then
s=m:field(DummyValue,"gfw_data",translate("GFW List Data"))
s.rawhtml = true
s.template = "shadowsocksr/refresh"
s.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
end
s=m:field(DummyValue,"ip_data",translate("China IP Data"))
s.rawhtml = true
s.template = "shadowsocksr/refresh"
s.value =ip_count .. " " .. translate("Records")
s=m:field(DummyValue,"check_port",translate("Check Server Port"))
s.template = "shadowsocksr/checkport"
s.value =translate("No Check")
return m

View File

@ -0,0 +1,38 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function check_connect(btn,urlname)
{
btn.disabled = true;
btn.value = '<%:Check...%>';
murl=urlname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","check")%>',
{ set:murl },
function(x,rv)
{
var s = document.getElementById(urlname+'-status');
if (s)
{
if (rv.ret=="0")
s.innerHTML ="<font color='green'>"+"<%:Connect OK%>"+"</font>";
else
s.innerHTML ="<font color='red'>"+"<%:Connect Error%>"+"</font>";
}
btn.disabled = false;
btn.value = '<%:Check Connect%>';
}
);
return false;
}
//]]></script>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Check Connect%>" onclick="return check_connect(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,36 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function check_port(btn)
{
btn.disabled = true;
btn.value = '<%:Check...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","checkport")%>',
null,
function(x,rv)
{
var s = document.getElementById('<%=self.option%>-status');
if (s)
{
s.innerHTML =rv.ret;
}
btn.disabled = false;
btn.value = '<%:Check Server%>';
}
);
return false;
}
//]]></script>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Check Server%>" onclick="return check_port(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,3 @@
<%+cbi/valueheader%>
<span class="pingtime" hint="<%=self:cfgvalue(section)%>">-- ms</span>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,44 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function refresh_data(btn,dataname)
{
btn.disabled = true;
btn.value = '<%:Refresh...%> ';
murl=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "shadowsocksr","refresh")%>',
{ set:murl },
function(x,rv)
{
var s = document.getElementById(dataname+'-status');
if (s)
{
if (rv.ret=="0")
s.innerHTML ="<font color='green'>"+"<%:No new data!%> "+"</font>";
else if(rv.ret=="-1")
{
s.innerHTML ="<font color='red'>"+"<%:Refresh Error!%> "+"</font>";
}
else
{
s.innerHTML ="<font color='green'>"+"<%:Refresh OK!%> "+"<%:Total Records:%>"+rv.ret+"</font>";
}
}
btn.disabled = false;
btn.value = '<%:Refresh Data %>';
}
);
return false;
}
//]]></script>
<input type="button" class="cbi-button cbi-input-reload" value="<%:Refresh Data%> " onclick="return refresh_data(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,24 @@
<%#
Copyright 2018-2019 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">
//<![CDATA[
var pings = document.getElementsByClassName('pingtime');
for(var i = 0; i < pings.length; i++) {
XHR.get('<%=dsp.build_url("admin/services/shadowsocksr/ping")%>', {
index: i,
domain: pings[i].getAttribute("hint")
},
function(x, result) {
pings[result.index].innerHTML = (result.ping ? result.ping : "--") + " ms";
}
);
}
//]]>
</script>

View File

@ -0,0 +1,204 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function padright(str, cnt, pad) {
return str + Array(cnt + 1).join(pad);
}
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
function b64encutf8safe(str) {
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
}
function b64DecodeUnicode(str) {
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
function b64decutf8safe(str) {
var l;
str = str.replace(/-/g, "+").replace(/_/g, "/");
l = str.length;
l = (4 - l % 4) % 4;
if (l)
str = padright(str, l, "=");
return b64DecodeUnicode(str);
}
function b64encsafe(str) {
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
}
function b64decsafe(str) {
var l;
str = str.replace(/-/g, "+").replace(/_/g, "/");
l = str.length;
l = (4 - l % 4) % 4;
if (l)
str = padright(str, l, "=");
return atob(str);
}
function dictvalue(d, key) {
var v = d[key];
if (typeof (v) == 'undefined' || v == '')
return '';
return b64decsafe(v);
}
function export_ssr_url(btn, urlname, sid) {
var s = document.getElementById(urlname + '-status');
if (!s)
return false;
var v_server = document.getElementById('cbid.shadowsocksr.' + sid + '.server');
var v_port = document.getElementById('cbid.shadowsocksr.' + sid + '.server_port');
var v_protocol = document.getElementById('cbid.shadowsocksr.' + sid + '.protocol');
var v_method = document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method');
var v_obfs = document.getElementById('cbid.shadowsocksr.' + sid + '.obfs');
var v_password = document.getElementById('cbid.shadowsocksr.' + sid + '.password');
var v_obfs_param = document.getElementById('cbid.shadowsocksr.' + sid + '.obfs_param');
var v_protocol_param = document.getElementById('cbid.shadowsocksr.' + sid + '.protocol_param');
var v_alias = document.getElementById('cbid.shadowsocksr.' + sid + '.alias');
var ssr_str = v_server.value + ":" +
v_port.value + ":" +
v_protocol.value + ":" +
v_method.value + ":" +
v_obfs.value + ":" +
b64encsafe(v_password.value) +
"/?obfsparam=" + b64encsafe(v_obfs_param.value) +
"&protoparam=" + b64encsafe(v_protocol_param.value) +
"&remarks=" + b64encutf8safe(v_alias.value);
var textarea = document.createElement("textarea");
textarea.textContent = "ssr://" + b64encsafe(ssr_str);
textarea.style.position = "fixed";
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy"); // Security exception may be thrown by some browsers.
s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>";
} catch (ex) {
s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>";
} finally {
document.body.removeChild(textarea);
}
return false;
}
function import_ssr_url(btn, urlname, sid) {
var s = document.getElementById(urlname + '-status');
if (!s)
return false;
var ssrurl = prompt("在这里黏贴配置链接 ssr:// | ss:// | vmess://", "");
if (ssrurl == null || ssrurl == "") {
s.innerHTML = "<font color='red'>用户取消</font>";
return false;
}
s.innerHTML = "";
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
var ssu = ssrurl.split('://');
console.log(ssu.length);
if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess") || ssu[1] == "") {
s.innerHTML = "<font color='red'>无效格式</font>";
return false;
}
var event = document.createEvent("HTMLEvents");
event.initEvent("change", true, true);
if (ssu[0] == "ssr") {
var sstr = b64decsafe(ssu[1]);
var ploc = sstr.indexOf("/?");
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "ssr";
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
var url0, param = "";
if (ploc > 0) {
url0 = sstr.substr(0, ploc);
param = sstr.substr(ploc + 2);
}
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
if (!ssm || ssm.length < 7)
return false;
var pdict = {};
if (param.length > 2)
{
var a = param.split('&');
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
}
}
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = ssm[1];
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = ssm[2];
document.getElementById('cbid.shadowsocksr.' + sid + '.protocol').value = ssm[3];
document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method').value = ssm[4];
document.getElementById('cbid.shadowsocksr.' + sid + '.obfs').value = ssm[5];
document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = b64decsafe(ssm[6]);
document.getElementById('cbid.shadowsocksr.' + sid + '.obfs_param').value = dictvalue(pdict, 'obfsparam');
document.getElementById('cbid.shadowsocksr.' + sid + '.protocol_param').value = dictvalue(pdict, 'protoparam');
var rem = pdict['remarks'];
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = b64decutf8safe(rem);
s.innerHTML = "<font color='green'>导入ShadowsocksR配置信息成功</font>";
return false;
} else if (ssu[0] == "ss") {
var ploc = ssu[1].indexOf("#");
if (ploc > 0) {
url0 = ssu[1].substr(0, ploc);
param = ssu[1].substr(ploc + 1);
} else {
url0 = ssu[1]
}
var sstr = b64decsafe(url0);
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "ss";
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
var team = sstr.split('@');
console.log(param);
var part1 = team[0].split(':');
var part2 = team[1].split(':');
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = part2[0];
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = part2[1];
document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = part1[1];
document.getElementById('cbid.shadowsocksr.' + sid + '.encrypt_method_ss').value = part1[0];
if (param != undefined) {
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = decodeURI(param);
}
s.innerHTML = "<font color='green'>导入Shadowsocks配置信息成功</font>";
return false;
} else if (ssu[0] == "vmess") {
var sstr = b64DecodeUnicode(ssu[1]);
var ploc = sstr.indexOf("/?");
document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "v2ray";
document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event);
var url0, param = "";
if (ploc > 0) {
url0 = sstr.substr(0, ploc);
param = sstr.substr(ploc + 2);
}
var ssm = JSON.parse(sstr);
document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = ssm.ps;
document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = ssm.add;
document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = ssm.port;
document.getElementById('cbid.shadowsocksr.' + sid + '.alter_id').value = ssm.aid;
document.getElementById('cbid.shadowsocksr.' + sid + '.vmess_id').value = ssm.id;
document.getElementById('cbid.shadowsocksr.' + sid + '.security').value = ssm.type;
document.getElementById('cbid.shadowsocksr.' + sid + '.transport').value = ssm.net;
document.getElementById('cbid.shadowsocksr.' + sid + '.http_host').value = ssm.host;
document.getElementById('cbid.shadowsocksr.' + sid + '.http_path').value = ssm.path;
s.innerHTML = "<font color='green'>导入V2ray配置信息成功</font>";
return false;
}
}
//]]></script>
<input type="button" class="cbi-button cbi-button-apply" value="导入配置信息" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
<span id="<%=self.option%>-status"></span>
<%+cbi/valuefooter%>

View File

@ -0,0 +1,22 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[shadowsocksr]], [[run]])%>', null,
function(x, data) {
var tb = document.getElementById('shadowsocksr_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>ShadowsocksR Plus+ <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>ShadowsocksR Plus+ <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="shadowsocksr_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@ -0,0 +1,531 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "ShadowSocksR Client"
msgstr "ShadowSocksR 客户端"
msgid "Enable"
msgstr "启用"
msgid "Disable"
msgstr "停用"
msgid "Log"
msgstr "日志"
msgid "ShadowSocksR is running"
msgstr "ShadowSocksR 客户端运行中"
msgid "ShadowSocksR is not running"
msgstr "ShadowSocksR 客户端未运行"
msgid "Global Setting"
msgstr "全局设置"
msgid "Global Server"
msgstr "全局服务器"
msgid "ShadowSocksR SOCK5 Proxy is running"
msgstr "ShadowSocksR SOCK5代理运行中"
msgid "UDP Relay Server"
msgstr "UDP中继服务器"
msgid "Same as Global Server"
msgstr "与全局服务器相同"
msgid "Servers Setting"
msgstr "服务器配置"
msgid "Alias(optional)"
msgstr "别名(可选)"
msgid "Onetime Authentication"
msgstr "一次验证"
msgid "Server Address"
msgstr "服务器地址"
msgid "Server Port"
msgstr "服务器端口"
msgid "Local Port"
msgstr "本地端口"
msgid "Connection Timeout"
msgstr "连接超时"
msgid "Password"
msgstr "密码"
msgid "Encrypt Method"
msgstr "加密方式"
msgid "Protocol"
msgstr "传输协议"
msgid "Protocol param(optional)"
msgstr "传输协议参数(可选)"
msgid "Obfs"
msgstr "混淆插件"
msgid "Obfs param(optional)"
msgstr "混淆参数(可选)"
msgid "Enable Tunnel(DNS)"
msgstr "启用隧道DNS转发"
msgid "Tunnel Port"
msgstr "隧道DNS本地端口"
msgid "Forwarding Tunnel"
msgstr "隧道DNS转发地址"
msgid "Access Control"
msgstr "访问控制"
msgid "Interfaces - WAN"
msgstr "接口 - WAN"
msgid "Bypassed IP List"
msgstr "被忽略IP列表"
msgid "NULL - As Global Proxy"
msgstr "留空 - 作为全局代理"
msgid "Bypassed IP"
msgstr "额外被忽略IP"
msgid "Forwarded IP"
msgstr "强制走代理IP"
msgid "Interfaces - LAN"
msgstr "接口 - LAN"
msgid "LAN Access Control"
msgstr "内网访问控制"
msgid "Allow listed only"
msgstr "仅允许列表内"
msgid "Allow all except listed"
msgstr "仅允许列表外"
msgid "LAN Host List"
msgstr "内网主机列表"
msgid "SSR Client"
msgstr "客户端"
msgid "SSR Server"
msgstr "服务端"
msgid "ShadowSocksR Server"
msgstr "ShadowSocksR 服务端"
msgid "ShadowSocksR Server is running"
msgstr "ShadowSocksR 服务端运行中"
msgid "ShadowSocksR Server is not running"
msgstr "ShadowSocksR 服务端未运行"
msgid "Enable Server"
msgstr "启动服务端"
msgid "Server Setting"
msgstr "服务端配置"
msgid "KcpTun Enable"
msgstr "KcpTun 启用"
msgid "bin:/usr/bin/kcptun-client"
msgstr "二进制文件:/usr/bin/kcptun-client"
msgid "KcpTun Port"
msgstr "KcpTun 端口"
msgid "KcpTun Param"
msgstr "KcpTun 参数"
msgid "KcpTun Password"
msgstr "KcpTun 密码"
msgid "Haven't a Kcptun executable file"
msgstr "不存在Kcptun可执行文件请下载Kcptun可执行文件并改名放入/usr/bin/kcptun-client"
msgid "Not a Kcptun executable file"
msgstr "Kcptun可执行文件格式不正确请确认是否正确下载了路由器对应的可执行文件"
msgid "Enable Process Monitor"
msgstr "启用进程监控"
msgid "Edit ShadowSocksR Server"
msgstr "编辑服务器配置"
msgid "Alias"
msgstr "别名"
msgid "SOCKS5 Proxy"
msgstr "SOCKS5代理"
msgid "Server"
msgstr "服务器"
msgid "TCP Fast Open"
msgstr "TCP快速打开"
msgid "Status"
msgstr "状态"
msgid "Unknown"
msgstr "未知"
msgid "Running Status"
msgstr "运行状态"
msgid "Global Client"
msgstr "TCP透明代理"
msgid "Global SSR Server"
msgstr "SSR服务端"
msgid "DNS Tunnel"
msgstr "DNS 隧道"
msgid "IPK Version"
msgstr "IPK 版本号"
msgid "KcpTun Version"
msgstr "KcpTun 版本号"
msgid "Not exist"
msgstr "未安装可执行文件"
msgid "IPK Installation Time"
msgstr "IPK 安装时间"
msgid "Project"
msgstr "项目地址"
msgid "Not Running"
msgstr "未运行"
msgid "Running"
msgstr "运行中"
msgid "Enable GFW mode"
msgstr "启用 GFW 模式"
msgid "Running Mode"
msgstr "运行模式"
msgid "IP Route Mode"
msgstr "绕过中国大陆IP模式"
msgid "GFW List Mode"
msgstr "GFW列表模式"
msgid "Global Mode"
msgstr "全局模式"
msgid "Oversea Mode"
msgstr "海外用户回国模式"
msgid "Router Proxy"
msgstr "路由器访问控制"
msgid "Normal Proxy"
msgstr "正常代理"
msgid "Bypassed Proxy"
msgstr "不走代理"
msgid "Forwarded Proxy"
msgstr "强制走代理"
msgid "UDP Relay"
msgstr "UDP中继"
msgid "Google Connectivity"
msgstr "【谷歌】连通性检查"
msgid "Baidu Connectivity"
msgstr "【百度】连通性检查"
msgid "No Check"
msgstr "未检查"
msgid "Check"
msgstr "检查"
msgid "Connect OK"
msgstr "连接正常"
msgid "Connect Error"
msgstr "连接错误"
msgid "Check..."
msgstr "正在检查.."
msgid "Proxy Check"
msgstr "代理检查"
msgid "GFW List Data"
msgstr "【GFW列表】数据库"
msgid "China IP Data"
msgstr "【国内IP段】数据库"
msgid "Records"
msgstr "条记录"
msgid "Refresh Data"
msgstr "更新数据库"
msgid "Refresh..."
msgstr "正在更新,请稍候.."
msgid "Refresh OK!"
msgstr "更新成功!"
msgid "Refresh Error!"
msgstr "更新失败!"
msgid "No new data!"
msgstr "你已经是最新数据,无需更新!"
msgid "Total Records:"
msgstr "新的总纪录数:"
msgid "Check Server Port"
msgstr "【服务器端口】检查"
msgid "Check Connect"
msgstr "检查连通性"
msgid "Check Server"
msgstr "检查服务器"
msgid "Auto Switch"
msgstr "自动切换"
msgid "Enable Auto Switch"
msgstr "启用自动切换"
msgid "Switch check cycly(second)"
msgstr "自动切换检查周期(秒)"
msgid "Check timout(second)"
msgstr "切换检查超时时间(秒)"
msgid "Enable Process Deamon"
msgstr "启用进程自动守护"
msgid "Advertising Data"
msgstr "【广告屏蔽】数据库"
msgid "DNS Server IP and Port"
msgstr "DNS服务器地址和端口"
msgid "Resolve Dns Mode"
msgstr "DNS解析方式"
msgid "Use SSR DNS Tunnel"
msgstr "使用SSR-DNS隧道"
msgid "Use Pdnsd"
msgstr "使用Pdnsd"
msgid "Use Other DNS Tunnel(Need to install)"
msgstr "使用其他DNS转发(需要自己安装)"
msgid "Import SSR"
msgstr "导入ssr配置信息"
msgid "Export SSR"
msgstr "导出ssr配置信息"
msgid "Import SSR successfully."
msgstr "成功导入SSR。"
msgid "Invalid SSR format."
msgstr "无效的SSR格式。"
msgid "User cancelled."
msgstr "用户已取消。"
msgid "Paste ssr url here"
msgstr "在此处粘贴ssr://网址"
msgid "Unable to copy SSR to clipboard."
msgstr "无法复制SSR网址到剪贴板。"
msgid "Copy SSR to clipboard successfully."
msgstr "成功复制SSR网址到剪贴板。"
msgid "Servers Manage"
msgstr "服务器管理"
msgid "Auto Update"
msgstr "自动更新"
msgid "Through proxy update"
msgstr "通过代理更新"
msgid "GFW List"
msgstr "GFW列表"
msgid "ShadowSocksR Plus+ Settings"
msgstr "ShadowSocksR Plus+ 设置支持SS/SSR/V2RAY"
msgid "Main Server"
msgstr "主服务器"
msgid "Anti-pollution DNS Server"
msgstr "访问国外域名DNS服务器"
msgid "Use Pdnsd tcp query and cache"
msgstr "使用PDNSD TCP查询并缓存"
msgid "DNS Server IP:Port"
msgstr "DNS服务器 IP:Port"
msgid "Update time (every day)"
msgstr "更新时间 (每天)"
msgid "Auto Update Server subscription, GFW list and CHN route"
msgstr "自动更新服务器订阅、GFW列表和 CHN路由表"
msgid "Subscribe URL"
msgstr "SS/SSR/V2RAY订阅URL地址"
msgid "Update"
msgstr "更新"
msgid "Server Count"
msgstr "服务器节点数量"
msgid "IP black-and-white list"
msgstr "黑白名单"
msgid "WAN IP AC"
msgstr "WAN IP访问控制"
msgid "WAN White List IP"
msgstr "不走代理的WAN IP"
msgid "WAN Force Proxy IP"
msgstr "强制走代理的WAN IP"
msgid "LAN Bypassed Host List"
msgstr "不走代理的局域网LAN IP"
msgid "LAN Force Proxy Host List"
msgstr "全局代理的LAN IP"
msgid "Router Self AC"
msgstr "路由器自身代理设置"
msgid "Router Self Proxy"
msgstr "路由器自身代理方式"
msgid "Normal Proxy"
msgstr "跟随全局设置"
msgid "Bypassed Proxy"
msgstr "不走代理"
msgid "Forwarded Proxy"
msgstr "全局代理"
msgid "GFW Custom List"
msgstr "GFW 用户自定义列表"
msgid "Please refer to the following writing"
msgstr "每行一个域名,无需写前面的 HTTP(S):// ,提交后即时生效"
msgid "Servers subscription and manage"
msgstr "服务器节点订阅与管理支持订阅和手动导入SSR链接"
msgid "Through proxy update list, Not Recommended"
msgstr "通过路由器自身代理更新订阅"
msgid "LAN IP AC"
msgstr "LAN IP访问控制"
msgid "Game Mode UDP Server"
msgstr "游戏模式UDP中继服务器"
msgid "Game Mode UDP Relay"
msgstr "游戏模式UDP中继"
msgid "Server failsafe auto swith settings"
msgstr "服务器节点故障自动切换设置"
msgid "Delete all severs"
msgstr "删除所有服务器节点"
msgid "Severs Nodes"
msgstr "服务器节点"
msgid "Use Local DNS Service listen port 5335"
msgstr "使用本机端口为5335的DNS服务"
msgid "Use system DNS"
msgstr "使用系统DNS"
msgid "Server Node Type"
msgstr "服务器节点类型"
msgid "Using incorrect encryption mothod may causes service fail to start"
msgstr "输入不正确的参数组合可能会导致服务无法启动"
msgid "Game Mode Host List"
msgstr "增强游戏模式客户端LAN IP"
msgid "Multi Threads Option"
msgstr "多线程并发转发"
msgid "Auto Threads"
msgstr "自动CPU线程数"
msgid "1 Thread"
msgstr "单线程"
msgid "2 Threads"
msgstr "2 线程"
msgid "4 Threads"
msgstr "4 线程"
msgid "8 Threads"
msgstr "8 线程"
msgid "Proxy Ports"
msgstr "需要代理的端口"
msgid "All Ports"
msgstr "所有端口(默认)"
msgid "Only Common Ports"
msgstr "仅常用端口不走P2P流量到代理"
msgid "Ping Latency"
msgstr "Ping延迟"
msgid "Bypass Domain List"
msgstr "域名白名单"
msgid "Black Domain List"
msgstr "域名黑名单"
msgid "Update Subscribe List"
msgstr "更新订阅URL列表"
msgid "Update subscribe url list first"
msgstr "订阅服务器节点前请先更新订阅URL列表"
msgid "Update All Subscribe Severs"
msgstr "更新所有订阅服务器节点"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
91smartyun.pt
adobe.com
amazonaws.com
ampproject.org
apple.news
aws.amazon.com
azureedge.net
backpackers.com.tw
bitfinex.com
buzzfeed.com
clockwise.ee
cloudfront.net
coindesk.com
coinsquare.io
cryptocompare.com
dropboxstatic.com
eurecom.fr
gdax.com
github.com
kknews.cc
nutaq.com
openairinterface.org
skype.com
sublimetext.com
textnow.com
textnow.me
trouter.io
uploaded.net
whatsapp.com
whatsapp.net
wsj.net
google.com
google.com.hk
gstatic.com
googleusercontent.com
googlepages.com
googlevideo.com
googlecode.com
googleapis.com
googlesource.com
googledrive.com
ggpht.com
youtube.com
youtu.be
ytimg.com
twitter.com
facebook.com
fastly.net
akamai.net
akamaiedge.net
akamaihd.net
edgesuite.net
edgekey.net

View File

@ -0,0 +1,37 @@
config global
option tunnel_forward '8.8.4.4:53'
option tunnel_address '0.0.0.0'
option run_mode 'gfw'
option pdnsd_enable '1'
option monitor_enable '1'
option global_server 'nil'
option enable_switch '1'
option switch_timeout '5'
option switch_time '667'
config socks5_proxy
option server 'nil'
option local_port '1080'
option local_address '0.0.0.0'
config access_control
option wan_bp_list '/etc/china_ssr.txt'
option lan_ac_mode 'b'
option router_proxy '1'
list wan_fw_ips '149.154.160.0/20'
list wan_fw_ips '67.198.55.0/24'
list wan_fw_ips '91.108.4.0/22'
list wan_fw_ips '91.108.56.0/22'
list wan_fw_ips '109.239.140.0/24'
config server_global
option enable_server '0'
config server_subscribe
option proxy '0'
option auto_update_time '2'
option auto_update '1'

View File

@ -0,0 +1,192 @@
server=/v.youku.com/127.0.0.1#5335
server=/api.youku.com/127.0.0.1#5335
server=/v2.tudou.com/127.0.0.1#5335
server=/www.tudou.com/127.0.0.1#5335
server=/s.plcloud.music.qq.com/127.0.0.1#5335
server=/i.y.qq.com/127.0.0.1#5335
server=/hot.vrs.sohu.com/127.0.0.1#5335
server=/live.tv.sohu.com/127.0.0.1#5335
server=/pad.tv.sohu.com/127.0.0.1#5335
server=/my.tv.sohu.com/127.0.0.1#5335
server=/hot.vrs.letv.com/127.0.0.1#5335
server=/data.video.qiyi.com/127.0.0.1#5335
server=/cache.video.qiyi.com/127.0.0.1#5335
server=/cache.vip.qiyi.com/127.0.0.1#5335
server=/vv.video.qq.com/127.0.0.1#5335
server=/tt.video.qq.com/127.0.0.1#5335
server=/ice.video.qq.com/127.0.0.1#5335
server=/tjsa.video.qq.com/127.0.0.1#5335
server=/a10.video.qq.com/127.0.0.1#5335
server=/xyy.video.qq.com/127.0.0.1#5335
server=/vcq.video.qq.com/127.0.0.1#5335
server=/vsh.video.qq.com/127.0.0.1#5335
server=/vbj.video.qq.com/127.0.0.1#5335
server=/bobo.video.qq.com/127.0.0.1#5335
server=/flvs.video.qq.com/127.0.0.1#5335
server=/bkvv.video.qq.com/127.0.0.1#5335
server=/info.zb.qq.com/127.0.0.1#5335
server=/geo.js.kankan.xunlei.com/127.0.0.1#5335
server=/web-play.pptv.com/127.0.0.1#5335
server=/web-play.pplive.cn/127.0.0.1#5335
server=/dyn.ugc.pps.tv/127.0.0.1#5335
server=/v.pps.tv/127.0.0.1#5335
server=/inner.kandian.com/127.0.0.1#5335
server=/ipservice.163.com/127.0.0.1#5335
server=/so.open.163.com/127.0.0.1#5335
server=/zb.s.qq.com/127.0.0.1#5335
server=/ip.kankan.xunlei.com/127.0.0.1#5335
server=/vxml.56.com/127.0.0.1#5335
server=/music.sina.com.cn/127.0.0.1#5335
server=/play.baidu.com/127.0.0.1#5335
server=/v.iask.com/127.0.0.1#5335
server=/tv.weibo.com/127.0.0.1#5335
server=/wtv.v.iask.com/127.0.0.1#5335
server=/video.sina.com.cn/127.0.0.1#5335
server=/www.yinyuetai.com/127.0.0.1#5335
server=/api.letv.com/127.0.0.1#5335
server=/live.gslb.letv.com/127.0.0.1#5335
server=/static.itv.letv.com/127.0.0.1#5335
server=/ip.apps.cntv.cn/127.0.0.1#5335
server=/vdn.apps.cntv.cn/127.0.0.1#5335
server=/vdn.live.cntv.cn/127.0.0.1#5335
server=/vip.sports.cntv.cn/127.0.0.1#5335
server=/a.play.api.3g.youku.com/127.0.0.1#5335
server=/i.play.api.3g.youku.com/127.0.0.1#5335
server=/api.3g.youku.com/127.0.0.1#5335
server=/tv.api.3g.youku.com/127.0.0.1#5335
server=/play.api.3g.youku.com/127.0.0.1#5335
server=/play.api.3g.tudou.com/127.0.0.1#5335
server=/tv.api.3g.tudou.com/127.0.0.1#5335
server=/api.3g.tudou.com/127.0.0.1#5335
server=/api.tv.sohu.com/127.0.0.1#5335
server=/access.tv.sohu.com/127.0.0.1#5335
server=/iface.iqiyi.com/127.0.0.1#5335
server=/iface2.iqiyi.com/127.0.0.1#5335
server=/cache.m.iqiyi.com/127.0.0.1#5335
server=/dynamic.app.m.letv.com/127.0.0.1#5335
server=/dynamic.meizi.app.m.letv.com/127.0.0.1#5335
server=/dynamic.search.app.m.letv.com/127.0.0.1#5335
server=/dynamic.live.app.m.letv.com/127.0.0.1#5335
server=/listso.m.areainfo.ppstream.com/127.0.0.1#5335
server=/epg.api.pptv.com/127.0.0.1#5335
server=/play.api.pptv.com/127.0.0.1#5335
server=/m.letv.com/127.0.0.1#5335
server=/interface.bilibili.com/127.0.0.1#5335
server=/3g.music.qq.com/127.0.0.1#5335
server=/mqqplayer.3g.qq.com/127.0.0.1#5335
server=/proxy.music.qq.com/127.0.0.1#5335
server=/proxymc.qq.com/127.0.0.1#5335
server=/ip2.kugou.com/127.0.0.1#5335
server=/ip.kugou.com/127.0.0.1#5335
server=/client.api.ttpod.com/127.0.0.1#5335
server=/mobi.kuwo.cn/127.0.0.1#5335
server=/mobilefeedback.kugou.com/127.0.0.1#5335
server=/tingapi.ting.baidu.com/127.0.0.1#5335
server=/music.baidu.com/127.0.0.1#5335
server=/serviceinfo.sdk.duomi.com/127.0.0.1#5335
server=/music.163.com/127.0.0.1#5335
server=/www.xiami.com/127.0.0.1#5335
server=/spark.api.xiami.com/127.0.0.1#5335
server=/iplocation.geo.qiyi.com/127.0.0.1#5335
server=/sns.video.qq.com/127.0.0.1#5335
server=/v5.pc.duomi.com/127.0.0.1#5335
server=/tms.is.ysten.com/127.0.0.1#5335
server=/internal.check.duokanbox.com/127.0.0.1#5335
server=/openapi.youku.com/127.0.0.1#5335
server=/y.qq.com/127.0.0.1#5335
ipset=/v.youku.com/oversea
ipset=/api.youku.com/oversea
ipset=/v2.tudou.com/oversea
ipset=/www.tudou.com/oversea
ipset=/s.plcloud.music.qq.com/oversea
ipset=/i.y.qq.com/oversea
ipset=/hot.vrs.sohu.com/oversea
ipset=/live.tv.sohu.com/oversea
ipset=/pad.tv.sohu.com/oversea
ipset=/my.tv.sohu.com/oversea
ipset=/hot.vrs.letv.com/oversea
ipset=/data.video.qiyi.com/oversea
ipset=/cache.video.qiyi.com/oversea
ipset=/cache.vip.qiyi.com/oversea
ipset=/vv.video.qq.com/oversea
ipset=/tt.video.qq.com/oversea
ipset=/ice.video.qq.com/oversea
ipset=/tjsa.video.qq.com/oversea
ipset=/a10.video.qq.com/oversea
ipset=/xyy.video.qq.com/oversea
ipset=/vcq.video.qq.com/oversea
ipset=/vsh.video.qq.com/oversea
ipset=/vbj.video.qq.com/oversea
ipset=/bobo.video.qq.com/oversea
ipset=/flvs.video.qq.com/oversea
ipset=/bkvv.video.qq.com/oversea
ipset=/info.zb.qq.com/oversea
ipset=/geo.js.kankan.xunlei.com/oversea
ipset=/web-play.pptv.com/oversea
ipset=/web-play.pplive.cn/oversea
ipset=/dyn.ugc.pps.tv/oversea
ipset=/v.pps.tv/oversea
ipset=/inner.kandian.com/oversea
ipset=/ipservice.163.com/oversea
ipset=/so.open.163.com/oversea
ipset=/zb.s.qq.com/oversea
ipset=/ip.kankan.xunlei.com/oversea
ipset=/vxml.56.com/oversea
ipset=/music.sina.com.cn/oversea
ipset=/play.baidu.com/oversea
ipset=/v.iask.com/oversea
ipset=/tv.weibo.com/oversea
ipset=/wtv.v.iask.com/oversea
ipset=/video.sina.com.cn/oversea
ipset=/www.yinyuetai.com/oversea
ipset=/api.letv.com/oversea
ipset=/live.gslb.letv.com/oversea
ipset=/static.itv.letv.com/oversea
ipset=/ip.apps.cntv.cn/oversea
ipset=/vdn.apps.cntv.cn/oversea
ipset=/vdn.live.cntv.cn/oversea
ipset=/vip.sports.cntv.cn/oversea
ipset=/a.play.api.3g.youku.com/oversea
ipset=/i.play.api.3g.youku.com/oversea
ipset=/api.3g.youku.com/oversea
ipset=/tv.api.3g.youku.com/oversea
ipset=/play.api.3g.youku.com/oversea
ipset=/play.api.3g.tudou.com/oversea
ipset=/tv.api.3g.tudou.com/oversea
ipset=/api.3g.tudou.com/oversea
ipset=/api.tv.sohu.com/oversea
ipset=/access.tv.sohu.com/oversea
ipset=/iface.iqiyi.com/oversea
ipset=/iface2.iqiyi.com/oversea
ipset=/cache.m.iqiyi.com/oversea
ipset=/dynamic.app.m.letv.com/oversea
ipset=/dynamic.meizi.app.m.letv.com/oversea
ipset=/dynamic.search.app.m.letv.com/oversea
ipset=/dynamic.live.app.m.letv.com/oversea
ipset=/listso.m.areainfo.ppstream.com/oversea
ipset=/epg.api.pptv.com/oversea
ipset=/play.api.pptv.com/oversea
ipset=/m.letv.com/oversea
ipset=/interface.bilibili.com/oversea
ipset=/3g.music.qq.com/oversea
ipset=/mqqplayer.3g.qq.com/oversea
ipset=/proxy.music.qq.com/oversea
ipset=/proxymc.qq.com/oversea
ipset=/ip2.kugou.com/oversea
ipset=/ip.kugou.com/oversea
ipset=/client.api.ttpod.com/oversea
ipset=/mobi.kuwo.cn/oversea
ipset=/mobilefeedback.kugou.com/oversea
ipset=/tingapi.ting.baidu.com/oversea
ipset=/music.baidu.com/oversea
ipset=/serviceinfo.sdk.duomi.com/oversea
ipset=/music.163.com/oversea
ipset=/www.xiami.com/oversea
ipset=/spark.api.xiami.com/oversea
ipset=/iplocation.geo.qiyi.com/oversea
ipset=/sns.video.qq.com/oversea
ipset=/v5.pc.duomi.com/oversea
ipset=/tms.is.ysten.com/oversea
ipset=/internal.check.duokanbox.com/oversea
ipset=/openapi.youku.com/oversea
ipset=/y.qq.com/oversea

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
server=/.t66y.com/127.0.0.1#5335
ipset=/.t66y.com/gfwlist

View File

@ -0,0 +1,554 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
# Copyright (C) 2018 lean <coolsnowwolf@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
START=90
STOP=15
SERVICE_DAEMONIZE=1
NAME=shadowsocksr
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
server_count=0
redir_tcp=0
redir_udp=0
tunnel_enable=0
local_enable=0
kcp_enable_flag=0
kcp_flag=0
pdnsd_enable_flag=0
switch_enable=0
switch_server=$1
MAXFD=32768
CRON_FILE=/etc/crontabs/root
threads=1
uci_get_by_name() {
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
add_cron()
{
sed -i '/ssrplus.log/d' $CRON_FILE
echo '0 1 * * * echo "" > /tmp/ssrplus.log' >> $CRON_FILE
[ -n "$(grep -w "/usr/share/shadowsocksr/subscribe.sh" $CRON_FILE)" ] && sed -i '/\/usr\/share\/shadowsocksr\/subscribe.sh/d' $CRON_FILE
[ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/share/shadowsocksr/subscribe.sh" >> $CRON_FILE
[ -z "$(grep -w "/usr/share/shadowsocksr/update.sh" $CRON_FILE)" ] && echo "0 5 * * * /usr/share/shadowsocksr/update.sh" >> $CRON_FILE
crontab $CRON_FILE
}
del_cron()
{
sed -i '/shadowsocksr/d' $CRON_FILE
sed -i '/ssrplus.log/d' $CRON_FILE
/etc/init.d/cron restart
}
run_mode=$(uci_get_by_type global run_mode)
gen_config_file() {
local host=$(uci_get_by_name $1 server)
if echo $host|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
hostip=${host}
elif [ "$host" != "${host#*:[0-9a-fA-F]}" ] ;then
hostip=${host}
else
hostip=`nslookup ${host} | grep 'Address 1' | sed 's/Address 1: //g'`
if echo $hostip|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
hostip=${hostip}
else
hostip=`cat /etc/ssr_ip`
fi
fi
[ $2 = "0" -a $kcp_flag = "1" ] && hostip="127.0.0.1"
if [ $2 = "0" ] ;then
config_file=$CONFIG_FILE
elif [ $2 = "1" ]; then
config_file=$CONFIG_UDP_FILE
else
config_file=$CONFIG_SOCK5_FILE
fi
if [ $(uci_get_by_name $1 fast_open 0) = "1" ] ;then
fastopen="true";
else
fastopen="false";
fi
local stype=$(uci_get_by_name $1 type)
if [ "$stype" == "ss" ] ;then
cat <<-EOF >$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),
"password": "$(uci_get_by_name $1 password)",
"timeout": $(uci_get_by_name $1 timeout 60),
"method": "$(uci_get_by_name $1 encrypt_method_ss)",
"reuse_port": true,
"fast_open": $fastopen
}
EOF
elif [ "$stype" == "ssr" ] ;then
cat <<-EOF >$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),
"password": "$(uci_get_by_name $1 password)",
"timeout": $(uci_get_by_name $1 timeout 60),
"method": "$(uci_get_by_name $1 encrypt_method)",
"protocol": "$(uci_get_by_name $1 protocol)",
"protocol_param": "$(uci_get_by_name $1 protocol_param)",
"obfs": "$(uci_get_by_name $1 obfs)",
"obfs_param": "$(uci_get_by_name $1 obfs_param)",
"reuse_port": true,
"fast_open": $fastopen
}
EOF
elif [ "$stype" == "v2ray" ] ;then
lua /usr/share/shadowsocksr/genv2config.lua $GLOBAL_SERVER tcp $(uci_get_by_name $1 local_port) > /var/etc/v2-ssr-retcp.json
sed -i 's/\\//g' /var/etc/v2-ssr-retcp.json
fi
}
get_arg_out() {
case "$(uci_get_by_type access_control router_proxy 1)" in
1) echo "-o";;
2) echo "-O";;
esac
}
start_rules() {
local server=$(uci_get_by_name $GLOBAL_SERVER server)
#resolve name
if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
server=${server}
elif [ "$server" != "${server#*:[0-9a-fA-F]}" ] ;then
server=${server}
else
server=`nslookup ${server} | grep 'Address 1' | sed 's/Address 1: //g'`
if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
echo $server >/etc/ssr_ip
else
server=`cat /etc/ssr_ip`
fi
fi
kcp_server=$server
local kcp_enable=$(uci_get_by_name $GLOBAL_SERVER kcp_enable 0)
if [ $kcp_enable = "1" ] ;then
kcp_flag=1
fi
local local_port=$(uci_get_by_name $GLOBAL_SERVER local_port)
local lan_ac_ips=$(uci_get_by_type access_control lan_ac_ips)
local lan_ac_mode="b"
local router_proxy=$(uci_get_by_type access_control router_proxy)
if [ "$GLOBAL_SERVER" = "$UDP_RELAY_SERVER" -a $kcp_flag = 0 ]; then
ARG_UDP="-u"
elif [ -n "$UDP_RELAY_SERVER" ]; then
ARG_UDP="-U"
local udp_server=$(uci_get_by_name $UDP_RELAY_SERVER server)
local udp_local_port=$(uci_get_by_name $UDP_RELAY_SERVER local_port)
fi
if [ -n "$lan_ac_ips" ]; then
case "$lan_ac_mode" in
w|W|b|B) local ac_ips="$lan_ac_mode$lan_ac_ips";;
esac
fi
#deal gfw firewall rule
local gfwmode=""
if [ "$run_mode" = "gfw" ]; then
gfwmode="-g"
elif [ "$run_mode" = "router" ]; then
gfwmode="-r"
elif [ "$run_mode" = "oversea" ]; then
gfwmode="-c"
elif [ "$run_mode" = "all" ]; then
gfwmode="-z"
fi
local dports=$(uci_get_by_type global dports 1)
if [ $dports = "1" ] ;then
proxyport=" "
else
proxyport="-m multiport --dports 22,53,587,465,995,993,143,80,443 "
fi
/usr/bin/ssr-rules \
-s "$server" \
-l "$local_port" \
-S "$udp_server" \
-L "$udp_local_port" \
-a "$ac_ips" \
-i "$(uci_get_by_type access_control wan_bp_list)" \
-b "$(uci_get_by_type access_control wan_bp_ips)" \
-w "$(uci_get_by_type access_control wan_fw_ips)" \
-p "$(uci_get_by_type access_control lan_fp_ips)" \
-G "$(uci_get_by_type access_control lan_gm_ips)" \
-D "$proxyport" \
$(get_arg_out) $gfwmode $ARG_UDP
return $?
}
start_pdnsd() {
local usr_dns="$1"
local usr_port="$2"
local tcp_dns_list="208.67.222.222, 208.67.220.220"
[ -z "$usr_dns" ] && usr_dns="8.8.8.8"
[ -z "$usr_port" ] && usr_port="53"
[ -d /var/etc ] || mkdir -p /var/etc
if [ ! -d /var/pdnsd ];then
mkdir -p /var/pdnsd
echo -ne "pd13\000\000\000\000" >/var/pdnsd/pdnsd.cache
chown -R nobody:nogroup /var/pdnsd
fi
cat > /var/etc/pdnsd.conf <<EOF
global {
perm_cache=1024;
cache_dir="/var/pdnsd";
pid_file = /var/run/pdnsd.pid;
run_as="nobody";
server_ip = 127.0.0.1;
server_port = 5335;
status_ctl = on;
query_method = tcp_only;
min_ttl=1h;
max_ttl=1w;
timeout=10;
neg_domain_pol=on;
proc_limit=2;
procq_limit=8;
}
server {
label= "ssr-usrdns";
ip = $usr_dns;
port = $usr_port;
timeout=6;
uptest=none;
interval=10m;
purge_cache=off;
}
server {
label= "ssr-pdnsd";
ip = $tcp_dns_list;
port = 5353;
timeout=6;
uptest=none;
interval=10m;
purge_cache=off;
}
EOF
/usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d
}
start_redir() {
case "$(uci_get_by_name $GLOBAL_SERVER auth_enable)" in
1|on|true|yes|enabled) ARG_OTA="-A";;
*) ARG_OTA="";;
esac
#deal kcp
local kcp_enable=$(uci_get_by_name $GLOBAL_SERVER kcp_enable 0)
if [ $kcp_enable = "1" ] ;then
[ ! -f "/usr/bin/kcptun-client" ] && return 1
local kcp_str=`/usr/bin/kcptun-client -v |grep kcptun|wc -l`
[ "0" = $kcp_str ] && return 1
local kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
local server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
local password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
local kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
[ "$password" != "" ] && password="--key "${password}
service_start /usr/bin/kcptun-client \
-r $kcp_server:$kcp_port \
-l :$server_port $password $kcp_param
kcp_enable_flag=1
fi
gen_config_file $GLOBAL_SERVER 0
local stype=$(uci_get_by_name $GLOBAL_SERVER type)
if [ "$stype" == "ss" ] ;then
sscmd="/usr/bin/ss-redir"
elif [ "$stype" == "ssr" ] ;then
sscmd="/usr/bin/ssr-redir"
elif [ "$stype" == "v2ray" ] ;then
sscmd="/usr/bin/v2ray/v2ray"
fi
local utype=$(uci_get_by_name $UDP_RELAY_SERVER type)
if [ "$utype" == "ss" ] ;then
ucmd="/usr/bin/ss-redir"
elif [ "$utype" == "ssr" ] ;then
ucmd="/usr/bin/ssr-redir"
elif [ "$utype" == "v2ray" ] ;then
ucmd="/usr/bin/v2ray/v2ray"
fi
if [ "$(uci_get_by_type global threads 0)" = "0" ] ;then
threads=$(cat /proc/cpuinfo | grep 'processor' | wc -l)
else
threads=$(uci_get_by_type global threads)
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
fi
if [ -n "$UDP_RELAY_SERVER" ] ;then
redir_udp=1
if [ "$utype" == "ss" -o "$utype" == "ssr" ] ;then
case "$(uci_get_by_name $UDP_RELAY_SERVER auth_enable)" in
1|on|true|yes|enabled) ARG_OTA="-A";;
*) ARG_OTA="";;
esac
gen_config_file $UDP_RELAY_SERVER 1
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
elif [ "$utype" == "v2ray" ] ; then
lua /usr/share/shadowsocksr/genv2config.lua $UDP_RELAY_SERVER udp $(uci_get_by_name $UDP_RELAY_SERVER local_port) > /var/etc/v2-ssr-reudp.json
sed -i 's/\\//g' /var/etc/v2-ssr-reudp.json
$ucmd -config /var/etc/v2-ssr-reudp.json >/dev/null 2>&1 &
fi
fi
#deal with dns
if [ "$(uci_get_by_type global pdnsd_enable)" = "1" ] ;then
local dnsstr="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
local dnsserver=`echo "$dnsstr"|awk -F ':' '{print $1}'`
local dnsport=`echo "$dnsstr"|awk -F ':' '{print $2}'`
if [ "$run_mode" = "gfw" ]; then
ipset add gfwlist $dnsserver 2>/dev/null
elif [ "$run_mode" = "oversea" ]; then
ipset add oversea $dnsserver 2>/dev/null
else
ipset add ss_spec_wan_ac $dnsserver nomatch 2>/dev/null
fi
start_pdnsd $dnsserver $dnsport
pdnsd_enable_flag=1
fi
if [ "$(uci_get_by_type global enable_switch)" = "1" ] ;then
if [ "$(uci_get_by_name $GLOBAL_SERVER switch_enable)" = "1" ] ;then
if [ -z "$switch_server" ] ;then
local switch_time=$(uci_get_by_type global switch_time)
local switch_timeout=$(uci_get_by_type global switch_timeout)
service_start /usr/bin/ssr-switch start $switch_time $switch_timeout
switch_enable=1
fi
fi
fi
add_cron
return $?
}
gen_service_file() {
if [ $(uci_get_by_name $1 fast_open) = "1" ] ;then
fastopen="true";
else
fastopen="false";
fi
cat <<-EOF >$2
{
"server": "0.0.0.0",
"server_port": $(uci_get_by_name $1 server_port),
"password": "$(uci_get_by_name $1 password)",
"timeout": $(uci_get_by_name $1 timeout 60),
"method": "$(uci_get_by_name $1 encrypt_method)",
"protocol": "$(uci_get_by_name $1 protocol)",
"protocol_param": "$(uci_get_by_name $1 protocol_param)",
"obfs": "$(uci_get_by_name $1 obfs)",
"obfs_param": "$(uci_get_by_name $1 obfs_param)",
"fast_open": $fastopen
}
EOF
}
start_service() {
[ $(uci_get_by_name $1 enable) = "0" ] && return 1
let server_count=server_count+1
if [ $server_count = 1 ] ;then
iptables -N SSR-SERVER-RULE && \
iptables -t filter -I INPUT -j SSR-SERVER-RULE
fi
gen_service_file $1 /var/etc/${NAME}_${server_count}.json
/usr/bin/ssr-server -c /var/etc/${NAME}_${server_count}.json -u -f /var/run/ssr-server${server_count}.pid >/dev/null 2>&1
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
return 0
}
gen_serv_include() {
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
}
start_server() {
SERVER_ENABLE=$(uci_get_by_type server_global enable_server)
[ "$SERVER_ENABLE" = 0 ] && return 0
mkdir -p /var/run /var/etc
config_load $NAME
config_foreach start_service server_config
gen_serv_include
return 0
}
start_local() {
local local_server=$(uci_get_by_type socks5_proxy server)
[ "$local_server" = "nil" ] && return 1
mkdir -p /var/run /var/etc
gen_config_file $local_server 2
/usr/bin/ssr-local -c $CONFIG_SOCK5_FILE -u \
-l $(uci_get_by_type socks5_proxy local_port 1080) \
-b $(uci_get_by_type socks5_proxy local_address 0.0.0.0) \
-f /var/run/ssr-local.pid >/dev/null 2>&1
local_enable=1
}
rules() {
[ "$GLOBAL_SERVER" = "nil" ] && return 1
mkdir -p /var/run /var/etc
UDP_RELAY_SERVER=$(uci_get_by_type global udp_relay_server)
[ "$UDP_RELAY_SERVER" = "same" ] && UDP_RELAY_SERVER=$GLOBAL_SERVER
if start_rules ;then
return 0
else
return 1
fi
}
start() {
if [ -z "$switch_server" ] ;then
GLOBAL_SERVER=$(uci_get_by_type global global_server)
else
GLOBAL_SERVER=$switch_server
switch_enable=1
fi
if rules ;then
start_redir
if ! [ "$(uci_get_by_type global pdnsd_enable)" = "2" ] ;then
mkdir -p /tmp/dnsmasq.d && cp -a /etc/dnsmasq.ssr /tmp/ && cp -a /etc/dnsmasq.oversea /tmp/
if ! [ "$run_mode" = "oversea" ] ;then
cat > /tmp/dnsmasq.d/dnsmasq-ssr.conf <<EOF
conf-dir=/tmp/dnsmasq.ssr
EOF
else
cat > /tmp/dnsmasq.d/dnsmasq-ssr.conf <<EOF
conf-dir=/tmp/dnsmasq.oversea
EOF
fi
/etc/init.d/dnsmasq restart >/dev/null 2>&1
/usr/share/shadowsocksr/gfw2ipset.sh
fi
fi
start_server
start_local
if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then
let total_count=server_count+redir_tcp+redir_udp+tunnel_enable+kcp_enable_flag+local_enable+pdnsd_enable_flag+switch_enable
if [ $total_count -gt 0 ]
then
#param:server(count) redir_tcp(0:no,1:yes) redir_udp tunnel kcp local gfw
service_start /usr/bin/ssr-monitor $server_count $redir_tcp $redir_udp $tunnel_enable $kcp_enable_flag $local_enable $pdnsd_enable_flag $switch_enable
fi
fi
ENABLE_SERVER=$(uci_get_by_type global global_server)
[ "$ENABLE_SERVER" = "nil" ] && return 1
}
boot() {
(/usr/share/shadowsocksr/chinaipset.sh && sleep 5 && start >/dev/null 2>&1) &
}
stop() {
/usr/bin/ssr-rules -f
srulecount=`iptables -L|grep SSR-SERVER-RULE|wc -l`
if [ $srulecount -gt 0 ] ;then
iptables -F SSR-SERVER-RULE
iptables -t filter -D INPUT -j SSR-SERVER-RULE
iptables -X SSR-SERVER-RULE 2>/dev/null
fi
if [ -z "$switch_server" ] ;then
kill -9 $(busybox ps -w | grep ssr-switch | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then
kill -9 $(busybox ps -w | grep ssr-monitor | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
killall -q -9 ssr-monitor
killall -q -9 ss-redir
killall -q -9 ssr-redir
killall -q -9 v2ray
killall -q -9 ssr-server
killall -q -9 kcptun-client
killall -q -9 ssr-local
if [ -f /var/run/pdnsd.pid ] ;then
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
else
kill -9 $(busybox ps -w | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
if [ -f "/tmp/dnsmasq.d/dnsmasq-ssr.conf" ]; then
rm -f /tmp/dnsmasq.d/dnsmasq-ssr.conf
/etc/init.d/dnsmasq restart >/dev/null 2>&1
fi
del_cron
}

View File

@ -0,0 +1,18 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@shadowsocksr[-1]
add ucitrack shadowsocksr
set ucitrack.@shadowsocksr[-1].init=shadowsocksr
commit ucitrack
delete firewall.shadowsocksr
set firewall.shadowsocksr=include
set firewall.shadowsocksr.type=script
set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
set firewall.shadowsocksr.reload=1
commit firewall
EOF
/usr/share/shadowsocksr/gfw2ipset.sh
rm -f /tmp/luci-indexcache
exit 0

View File

@ -0,0 +1,6 @@
#!/bin/sh -e
if [ -f /tmp/adnew.conf ]; then
cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf
fi

View File

@ -0,0 +1,31 @@
#!/bin/sh -e
generate_china_banned()
{
cat $1 | base64 -d > /tmp/gfwlist.txt
rm -f $1
sed -i '/^@@|/d' /tmp/gfwlist.txt
cat /tmp/gfwlist.txt | sort -u |
sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /byr\.cn/d; /jlike\.com/d; /weibo\.com/d; /zhongsou\.com/d; /youdao\.com/d; /sogou\.com/d; /so\.com/d; /soso\.com/d; /aliyun\.com/d; /taobao\.com/d; /jd\.com/d; /qq\.com/d' |
sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
awk '
BEGIN { prev = "________"; } {
cur = $0;
if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
} else {
print cur;
prev = cur;
}
}' | sort -u
}
generate_china_banned /tmp/gfw.b64 > /tmp/gfw.txt
rm -f /tmp/gfwlist.txt
sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/gfwnew.txt
rm -f /tmp/gfw.txt

View File

@ -0,0 +1,132 @@
#!/bin/sh
#
# Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
NAME=shadowsocksr
uci_get_by_name() {
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
server_process_count=$1
redir_tcp_process=$2
redir_udp_process=$3
tunnel_process=$4
kcp_process=$5
local_process=$6
pdnsd_process=$7
if [ -z "$pdnsd_process" ] ;then
pdnsd_process=0
fi
i=0
GLOBAL_SERVER=$(uci_get_by_type global global_server)
server=$(uci_get_by_name $GLOBAL_SERVER server)
lkcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
password=$(uci_get_by_name $GLOBAL_SERVER kcp_password)
kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param)
[ "$password" != "" ] && password="--key "${password}
sock5_port=$(uci_get_by_type socks5_proxy local_port 1080)
if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
server=${server}
else
server=`cat /etc/ssr_ip`
fi
while [ "1" = "1" ] #死循环
do
sleep 30
#redir tcp
if [ $redir_tcp_process -gt 0 ] ;then
icount=`busybox ps -w | grep ssr-retcp |grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr redir tcp error.restart!"
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#redir udp
if [ $redir_udp_process -gt 0 ] ;then
icount=`busybox ps -w | grep ssr-reudp|grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr redir udp error.restart!"
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#tunnel
if [ $tunnel_process -gt 0 ] ;then
icount=`busybox ps -w | grep ssr-tunnel |grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr tunnel error.restart!"
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#server
if [ $server_process_count -gt 0 ] ;then
icount=`busybox ps -w | grep ssr-server |grep -v grep| wc -l`
if [ $icount -lt $server_process_count ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr server error.restart!"
killall -q -9 ssr-server
for i in `seq $server_process_count`
do
/usr/bin/ssr-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ssr-server$i.pid
done
fi
fi
#kcptun
if [ $kcp_process -gt 0 ] ;then
icount=`busybox ps -w | grep kcptun-client |grep -v grep| wc -l`
if [ $icount -lt $kcp_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr kcptun error.restart!"
killall -q -9 kcptun-client
( /usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &)
fi
fi
#local
if [ $local_process -gt 0 ] ;then
icount=`busybox ps -w | grep ssr-local |grep -v grep| wc -l`
if [ $icount -lt $local_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr local error.restart!"
killall -q -9 ssr-local
( /usr/bin/ssr-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ssr-local.pid &)
fi
fi
#pdnsd
if [ $pdnsd_process -gt 0 ] ;then
icount=`busybox ps -w | grep pdnsd |grep -v grep| wc -l`
if [ $icount -lt $pdnsd_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "pdnsd tunnel error.restart!"
if [ -f /var/run/pdnsd.pid ] ;then
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
else
kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
( /usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d &)
fi
fi
done

View File

@ -0,0 +1,389 @@
#!/bin/sh
#
# Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
TAG="_SS_SPEC_RULE_" # comment tag
IPT="iptables -t nat" # alias of iptables
FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
usage() {
cat <<-EOF
Usage: ssr-rules [options]
Valid options are:
-s <server_ip> ip address of shadowsocksr remote server
-l <local_port> port number of shadowsocksr local server
-S <server_ip> ip address of shadowsocksr remote UDP server
-L <local_port> port number of shadowsocksr local UDP server
-i <ip_list_file> a file content is bypassed ip list
-a <lan_ips> lan ip of access control, need a prefix to
define access control mode
-b <wan_ips> wan ip of will be bypassed
-w <wan_ips> wan ip of will be forwarded
-p <fp_lan_ips> lan ip of will be global proxy
-G <gm_lan_ips> lan ip of will be game mode proxy
-D <proxy_ports> proxy ports
-e <extra_options> extra options for iptables
-o apply the rules to the OUTPUT chain
-O apply the global rules to the OUTPUT chain
-u enable udprelay mode, TPROXY is required
-U enable udprelay mode, using different IP
and ports for TCP and UDP
-f flush the rules
-g gfw list mode
-r return china mode
-h show this help message and exit
EOF
exit $1
}
loger() {
# 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
logger -st ssr-rules[$$] -p$1 $2
}
flush_r() {
flush_iptables() {
local ipt="iptables -t $1"
local DAT=$(iptables-save -t $1)
eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/')
for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do
$ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1}
done
}
flush_iptables nat
flush_iptables mangle
ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
ipset -X ss_spec_lan_ac 2>/dev/null
ipset -X ss_spec_wan_ac 2>/dev/null
ipset -X ssr_gen_router 2>/dev/null
ipset -X fplan 2>/dev/null
ipset -X gmlan 2>/dev/null
ipset -X oversea 2>/dev/null
ipset -X whitelist 2>/dev/null
ipset -X blacklist 2>/dev/null
[ -n "$FWI" ] && echo '#!/bin/sh' >$FWI
return 0
}
ipset_r() {
ipset -N gmlan hash:net 2>/dev/null
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done
if [ "$RUNMODE" = "router" ] ;then
ipset -! -R <<-EOF || return 1
create ss_spec_wan_ac hash:net
$(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /")
EOF
ipset -N gfwlist hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_AC
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
$IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
elif [ "$RUNMODE" = "gfw" ] ;then
ipset -N gfwlist hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_AC
$IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
elif [ "$RUNMODE" = "oversea" ] ;then
ipset -N oversea hash:net 2>/dev/null
$IPT -N SS_SPEC_WAN_AC
ipset -N gmlan hash:net 2>/dev/null
for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
elif [ "$RUNMODE" = "all" ] ;then
$IPT -N SS_SPEC_WAN_AC
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
fi
ipset -N fplan hash:net 2>/dev/null
for ip in $LAN_FP_IP; do ipset -! add fplan $ip ; done
$IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW
ipset -N whitelist hash:net 2>/dev/null
ipset -N blacklist hash:net 2>/dev/null
$IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW
$IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN
for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done
for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done
return $?
}
fw_rule() {
$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
$IPT -A SS_SPEC_WAN_FW -d 127.0.0.0/8 -j RETURN
$IPT -A SS_SPEC_WAN_FW -d 169.254.0.0/16 -j RETURN
$IPT -A SS_SPEC_WAN_FW -d 172.16.0.0/12 -j RETURN
$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 $PROXY_PORTS \
-j REDIRECT --to-ports $local_port 2>/dev/null || {
loger 3 "Can't redirect, please check the iptables."
exit 1
}
return $?
}
ac_rule() {
if [ -n "$LAN_AC_IP" ]; then
case "${LAN_AC_IP:0:1}" in
w|W)
MATCH_SET="-m set --match-set ss_spec_lan_ac src"
;;
b|B)
MATCH_SET="-m set ! --match-set ss_spec_lan_ac src"
;;
*)
loger 3 "Bad argument \`-a $LAN_AC_IP\`."
return 2
;;
esac
fi
IFNAME=$(uci get -P/var/state network.lan.ifname 2>/dev/null)
ipset -! -R <<-EOF || return 1
create ss_spec_lan_ac hash:net
$(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done)
EOF
$IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET \
-m comment --comment "$TAG" -j SS_SPEC_WAN_AC
if [ "$OUTPUT" = 1 ]; then
$IPT -I OUTPUT 1 -p tcp $EXT_ARGS \
-m comment --comment "$TAG" -j SS_SPEC_WAN_AC
elif [ "$OUTPUT" = 2 ]; then
ipset -! -R <<-EOF || return 1
create ssr_gen_router hash:net
$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
EOF
$IPT -N SS_SPEC_ROUTER && \
$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
fi
return $?
}
tp_rule() {
[ -n "$TPROXY" ] || return 0
ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100
local ipt="iptables -t mangle"
$ipt -N SS_SPEC_TPROXY
$ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 127.0.0.0/8 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 169.254.0.0/16 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 172.16.0.0/12 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -d $SERVER -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
if [ "$RUNMODE" = "router" ] ;then
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
elif [ "$RUNMODE" = "gfw" ] ;then
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
$ipt -A SS_SPEC_TPROXY -p udp -m set $PROXY_PORTS --match-set gfwlist dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
elif [ "$RUNMODE" = "oversea" ] ;then
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst \
-j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
elif [ "$RUNMODE" = "all" ] ;then
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
fi
$ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \
-m comment --comment "$TAG" -j SS_SPEC_TPROXY
return $?
}
get_wan_ip() {
cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
$server
$SERVER
$WAN_BP_IP
EOF
}
gen_iplist() {
cat <<-EOF
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255
$(get_wan_ip)
$(cat ${IGNORE_LIST:=/dev/null} 2>/dev/null)
EOF
}
gen_spec_iplist() {
cat <<-EOF
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255
$(get_wan_ip)
EOF
}
gen_include() {
[ -n "$FWI" ] || return 0
extract_rules() {
echo "*$1"
iptables-save -t $1 | grep SS_SPEC_ |\
sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/"
echo 'COMMIT'
}
cat <<-EOF >>$FWI
iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
iptables-restore -n <<-EOT
$(extract_rules nat)
$(extract_rules mangle)
EOT
EOF
return 0
}
while getopts ":s:l:S:L:i:e:a:b:w:p:G:D:oOuUfgrczh" arg; do
case "$arg" in
s)
server=$OPTARG
;;
l)
local_port=$OPTARG
;;
S)
SERVER=$OPTARG
;;
L)
LOCAL_PORT=$OPTARG
;;
i)
IGNORE_LIST=$OPTARG
;;
e)
EXT_ARGS=$OPTARG
;;
a)
LAN_AC_IP=$OPTARG
;;
b)
WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done)
;;
w)
WAN_FW_IP=$OPTARG
;;
p)
LAN_FP_IP=$OPTARG
;;
G)
LAN_GM_IP=$OPTARG
;;
D)
PROXY_PORTS=$OPTARG
;;
o)
OUTPUT=1
;;
O)
OUTPUT=2
;;
u)
TPROXY=1
;;
U)
TPROXY=2
;;
g)
RUNMODE=gfw
;;
r)
RUNMODE=router
;;
c)
RUNMODE=oversea
;;
z)
RUNMODE=all
;;
f)
flush_r
exit 0
;;
h)
usage 0
;;
esac
done
if [ -z "$server" -o -z "$local_port" ]; then
usage 2
fi
if [ "$TPROXY" = 1 ]; then
SERVER=$server
LOCAL_PORT=$local_port
elif [ "$TPROXY" = 2 ]; then
: ${SERVER:?"You must assign an ip for the udp relay server."}
: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
fi
flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
[ "$?" = 0 ] || loger 3 "Start failed!"
exit $?

View File

@ -0,0 +1,175 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
cycle_time=60
switch_time=3
normal_flag=0
server_locate=0
server_count=0
NAME=shadowsocksr
ENABLE_SERVER=nil
CONFIG_SWTICH_FILE=/var/etc/${NAME}_t.json
[ -n "$1" ] && cycle_time=$1
[ -n "$2" ] && switch_time=$2
uci_get_by_name() {
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
DEFAULT_SERVER=$(uci_get_by_type global global_server)
CURRENT_SERVER=$DEFAULT_SERVER
#判断代理是否正常
check_proxy() {
/usr/bin/ssr-check www.google.com 80 $switch_time 1
if [ "$?" == "0" ]; then
return 0
else
/usr/bin/ssr-check www.baidu.com 80 $switch_time 1
if [ "$?" == "0" ]; then
#goole不通baidu通则不正常
return 1
else
return 2
fi
fi
return 0
}
test_proxy() {
local servername=$(uci_get_by_name $1 server)
local serverport=$(uci_get_by_name $1 server_port)
ret=$(ping -c 3 $servername | grep 'loss' | awk -F ',' '{ print $3 }' | awk -F "%" '{ print $1 }')
[ -z "$ret" ] && return 1
[ "$ret" -gt "50" ] && return 1
ipset add ss_spec_wan_ac $servername 2>/dev/null
ret=$?
/usr/bin/ssr-check $servername $serverport $switch_time
local ret2=$?
if [ "$ret" = "0" ] ;then
ipset del ss_spec_wan_ac $servername 2>/dev/null
fi
if [ "$ret2" = "0" ] ;then
return 0
else
return 1
fi
}
search_proxy() {
let server_count=server_count+1
[ "$normal_flag" = "1" -a "$server_count" -le "$server_locate" ] && return 0
[ "$(uci_get_by_name $1 switch_enable)" != "1" ] && return 1
[ $ENABLE_SERVER != nil ] && return 0
[ "$1" = "$CURRENT_SERVER" ] && return 0
local servername=$(uci_get_by_name $1 server)
local serverport=$(uci_get_by_name $1 server_port)
ipset add ss_spec_wan_ac $servername 2>/dev/null
ret=$?
/usr/bin/ssr-check $servername $serverport $switch_time
local ret2=$?
if [ "$ret" = "0" ] ;then
ipset del ss_spec_wan_ac $servername 2>/dev/null
fi
if [ "$ret2" = "0" ] ;then
server_locate=$server_count
ENABLE_SERVER=$1
return 0
else
return 1
fi
}
#选择可用的代理
select_proxy() {
config_load $NAME
ENABLE_SERVER=nil
mkdir -p /var/run /var/etc
server_count=0
config_foreach search_proxy servers
}
#切换代理
switch_proxy() {
/etc/init.d/shadowsocksr restart $1
return 0
}
start() {
#不支持kcptun启用时的切换
[ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1
while [ "1" = "1" ] #死循环
do
sleep $cycle_time
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
#判断当前代理是否为缺省服务器
if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ] ;then
#echo "not default proxy"
echo "$(date "+%Y-%m-%d %H:%M:%S") Current server is not default Main server, try to switch back." >> /tmp/ssrplus.log
#检查缺省服务器是否正常
if test_proxy $DEFAULT_SERVER ;then
#echo "switch to default proxy"
echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is avilable." >> /tmp/ssrplus.log
#缺省服务器正常,切换回来
CURRENT_SERVER=$DEFAULT_SERVER
switch_proxy $CURRENT_SERVER
echo "$(date "+%Y-%m-%d %H:%M:%S") switch to default ["$(uci_get_by_name $CURRENT_SERVER server)"] proxy!" >> /tmp/ssrplus.log
continue
else
echo "$(date "+%Y-%m-%d %H:%M:%S") Main server is NOT avilable.Continue using current server." >> /tmp/ssrplus.log
fi
fi
#判断当前代理是否正常
check_proxy
current_ret=$?
if [ "$current_ret" = "1" ] ;then
#当前代理错误,判断有无可用的服务器
#echo "current error"
echo "$(date "+%Y-%m-%d %H:%M:%S") Current server error, try to switch another server." >> /tmp/ssrplus.log
select_proxy
if [ "$ENABLE_SERVER" != nil ] ;then
#有其他服务器可用,进行切换
#echo $(uci_get_by_name $new_proxy server)
echo "$(date "+%Y-%m-%d %H:%M:%S") Another server is avilable, now switching server." >> /tmp/ssrplus.log
CURRENT_SERVER=$ENABLE_SERVER
switch_proxy $CURRENT_SERVER
normal_flag=1
echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR server switch OK" >> /tmp/ssrplus.log
else
switch_proxy $CURRENT_SERVER
normal_flag=1
echo "$(date "+%Y-%m-%d %H:%M:%S") Try restart current server." >> /tmp/ssrplus.log
fi
else
normal_flag=0
echo "$(date "+%Y-%m-%d %H:%M:%S") ShadowsocksR No Problem." >> /tmp/ssrplus.log
fi
done
}

View File

@ -0,0 +1,5 @@
echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset
awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >> /tmp/china.ipset
ipset -! flush china
ipset -! restore < /tmp/china.ipset 2>/dev/null
rm -f /tmp/china.ipset

View File

@ -0,0 +1,95 @@
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" }
}
},
-- 传出连接
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 == "1") and true or false,serverName=server.ws_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))

View File

@ -0,0 +1,12 @@
#!/bin/sh
mkdir -p /tmp/dnsmasq.ssr
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"gfwlist"'\n",$0)}' /etc/config/gfw.list > /tmp/dnsmasq.ssr/custom_forward.conf
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/gfw.list >> /tmp/dnsmasq.ssr/custom_forward.conf
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"blacklist"'\n",$0)}' /etc/config/black.list > /tmp/dnsmasq.ssr/blacklist_forward.conf
awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/black.list >> /tmp/dnsmasq.ssr/blacklist_forward.conf
awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"whitelist"'\n",$0)}' /etc/config/white.list > /tmp/dnsmasq.ssr/whitelist_forward.conf

View File

@ -0,0 +1,259 @@
#!/bin/bash
# Copyright (C) 2017 XiaoShan https://www.mivm.cn
. /usr/share/libubox/jshn.sh
urlsafe_b64decode() {
local d="====" data=$(echo $1 | sed 's/_/\//g; s/-/+/g')
local mod4=$((${#data}%4))
[ $mod4 -gt 0 ] && data=${data}${d:mod4}
echo $data | base64 -d
}
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
echo_date(){
echo $(TZ=UTC-8 date -R +%Y-%m-%d\ %X):$1
}
Server_Update() {
local uci_set="uci -q set $name.$1."
${uci_set}grouphashkey="$ssr_grouphashkey"
${uci_set}hashkey="$ssr_hashkey"
${uci_set}alias="[$ssr_group] $ssr_remarks"
${uci_set}auth_enable="0"
${uci_set}switch_enable="1"
${uci_set}type="$ssr_type"
${uci_set}server="$ssr_host"
${uci_set}server_port="$ssr_port"
${uci_set}local_port="1234"
uci -q get $name.@servers[$1].timeout >/dev/null || ${uci_set}timeout="60"
${uci_set}password="$ssr_passwd"
${uci_set}encrypt_method="$ssr_method"
${uci_set}protocol="$ssr_protocol"
${uci_set}protocol_param="$ssr_protoparam"
${uci_set}obfs="$ssr_obfs"
${uci_set}obfs_param="$ssr_obfsparam"
${uci_set}fast_open="0"
${uci_set}kcp_enable="0"
${uci_set}kcp_port="0"
${uci_set}kcp_param="--nocomp"
if [ "$ssr_type" = "v2ray" ]; then
#v2ray
${uci_set}alter_id="$ssr_alter_id"
${uci_set}vmess_id="$ssr_vmess_id"
${uci_set}transport="$ssr_transport"
${uci_set}tcp_guise="$ssr_tcp_guise"
${uci_set}ws_host="$ssr_ws_host"
${uci_set}ws_path="$ssr_ws_path"
${uci_set}h2_host="$ssr_h2_host"
${uci_set}h2_path="$ssr_h2_path"
${uci_set}tls="$ssr_tls"
${uci_set}security=$ssr_security
${uci_set}alias="$ssr_remarks"
fi
if [ "$ssr_type" = "ss" ]; then
${uci_set}encrypt_method_ss="$ss_method"
${uci_set}alias="$ssr_remarks"
fi
}
name=shadowsocksr
subscribe_url=($(uci get $name.@server_subscribe[0].subscribe_url)) #订阅服务器地址
[ ${#subscribe_url[@]} -eq 0 ] && exit 1
[ $(uci -q get $name.@server_subscribe[0].proxy || echo 0) -eq 0 ] && /etc/init.d/$name stop >/dev/null 2>&1
log_name=${name}_subscribe
for ((o=0;o<${#subscribe_url[@]};o++))
do
echo_date "${subscribe_url[o]} 获取订阅"
echo_date "开始更新在线订阅列表..."
echo_date "尝试下载订阅链接到本地临时文件,请稍等..."
subscribe_data=$(wget-ssl --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]})
curl_code=$?
# 计算group的hashkey
ssr_grouphashkey=$(echo "${subscribe_url[o]}" | md5sum | cut -d ' ' -f1)
if [ ! $curl_code -eq 0 ];then
echo_date "下载订阅失败,自动重试中..."
subscribe_data=$(wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 30 -O- ${subscribe_url[o]})
curl_code=$?
fi
if [ $curl_code -eq 0 ];then
echo_date "下载订阅成功,开始解析节点信息..."
ssr_url=($(echo $subscribe_data | base64 -d | sed 's/\r//g')) # 解码数据并删除 \r 换行符
subscribe_max=$(echo ${ssr_url[0]} | grep -i MAX= | awk -F = '{print $2}')
subscribe_max_x=()
if [ -n "$subscribe_max" ]; then
while [ ${#subscribe_max_x[@]} -ne $subscribe_max ]
do
if [ ${#ssr_url[@]} -ge 10 ]; then
if [ $((${RANDOM:0:2}%2)) -eq 0 ]; then
temp_x=${RANDOM:0:1}
else
temp_x=${RANDOM:0:2}
fi
else
temp_x=${RANDOM:0:1}
fi
[ $temp_x -lt ${#ssr_url[@]} -a -z "$(echo "${subscribe_max_x[*]}" | grep -w $temp_x)" ] && subscribe_max_x[${#subscribe_max_x[@]}]="$temp_x"
done
else
subscribe_max=${#ssr_url[@]}
fi
echo_date "共计$subscribe_max个节点"
ssr_group=$(urlsafe_b64decode $(urlsafe_b64decode ${ssr_url[$((${#ssr_url[@]} - 1))]//ssr:\/\//} | sed 's/&/\n/g' | grep group= | awk -F = '{print $2}'))
if [ -z "$ssr_group" ]; then
ssr_group="default"
fi
if [ -n "$ssr_group" ]; then
subscribe_i=0
subscribe_n=0
subscribe_o=0
subscribe_x=""
temp_host_o=()
curr_ssr=$(uci show $name | grep @servers | grep -c server=)
for ((x=0;x<$curr_ssr;x++)) # 循环已有服务器信息,匹配当前订阅群组
do
temp_alias=$(uci -q get $name.@servers[$x].grouphashkey | grep "$ssr_grouphashkey")
[ -n "$temp_alias" ] && temp_host_o[${#temp_host_o[@]}]=$(uci get $name.@servers[$x].hashkey)
done
for ((x=0;x<$subscribe_max;x++)) # 循环链接
do
[ ${#subscribe_max_x[@]} -eq 0 ] && temp_x=$x || temp_x=${subscribe_max_x[x]}
result=$(echo ${ssr_url[temp_x]} | grep "ss")
subscribe_url_type=$(echo "$ssr_url" | awk -F ':' '{print $1}')
if [ "$subscribe_url_type" = "ss" ]; then
temp_info=${ssr_url[temp_x]//ss:\/\//} # 解码 SS 链接
# 计算hashkey
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
info=$(urlsafe_b64decode $(echo "$temp_info" | awk -F '@' '{print $1}'))
temp_info_array=(${info//:/ })
ssr_type="ss"
ss_method=${temp_info_array[0]}
ssr_passwd=${temp_info_array[1]}
info=$(echo "$temp_info" | awk -F '@' '{print $2}' | awk -F '#' '{print $1}')
temp_info_array=(${info//:/ })
ssr_host=${temp_info_array[0]}
ssr_port=${temp_info_array[1]}
ssr_remarks=$(urldecode $(echo "$temp_info" | awk -F '#' '{print $2}'))
fi
if [ "$subscribe_url_type" = "ssr" ]; then
temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//ssr:\/\//}) # 解码 SSR 链接
# 计算hashkey
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
info=${temp_info///?*/}
temp_info_array=(${info//:/ })
ssr_type="ssr"
ssr_host=${temp_info_array[0]}
ssr_port=${temp_info_array[1]}
ssr_protocol=${temp_info_array[2]}
ssr_method=${temp_info_array[3]}
ssr_obfs=${temp_info_array[4]}
ssr_passwd=$(urlsafe_b64decode ${temp_info_array[5]})
info=${temp_info:$((${#info} + 2))}
info=(${info//&/ })
ssr_protoparam=""
ssr_obfsparam=""
ssr_remarks="$temp_x"
for ((i=0;i<${#info[@]};i++)) # 循环扩展信息
do
temp_info=($(echo ${info[i]} | sed 's/=/ /g'))
case "${temp_info[0]}" in
protoparam)
ssr_protoparam=$(urlsafe_b64decode ${temp_info[1]});;
obfsparam)
ssr_obfsparam=$(urlsafe_b64decode ${temp_info[1]});;
remarks)
ssr_remarks=$(urlsafe_b64decode ${temp_info[1]});;
esac
done
fi
if [ "$subscribe_url_type" = "vmess" ]; then
temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//vmess:\/\//}) # 解码 Vmess 链接
# 计算hashkey
ssr_hashkey=$(echo "$temp_info" | md5sum | cut -d ' ' -f1)
ssr_type="v2ray"
json_load "$temp_info"
json_get_var ssr_host add
json_get_var ssr_port port
json_get_var ssr_alter_id aid
json_get_var ssr_vmess_id id
json_get_var ssr_security security
if [ "$ssr_security" == "" ]; then
ssr_security="auto"
fi
json_get_var ssr_transport net
json_get_var ssr_remarks ps
ssr_tcp_guise="none"
json_get_var ssr_ws_host host
json_get_var ssr_ws_path path
json_get_var ssr_h2_host host
json_get_var ssr_h2_path path
json_get_var ssr_tls tls
if [ "$ssr_tls" == "tls" -o "$ssr_tls" == "1" ]; then
ssr_tls="1"
else
ssr_tls="0"
fi
fi
if [ -z "ssr_remarks" ]; then # 没有备注的话则生成一个
ssr_remarks="$ssr_host:$ssr_port";
fi
uci_name_tmp=$(uci show $name | grep -w "$ssr_hashkey" | awk -F . '{print $2}')
if [ -z "$uci_name_tmp" ]; then # 判断当前服务器信息是否存在
uci_name_tmp=$(uci add $name servers)
subscribe_n=$(($subscribe_n + 1))
fi
Server_Update $uci_name_tmp
subscribe_x=$subscribe_x$ssr_hashkey" "
ssrtype=$(echo $ssr_type | tr '[a-z]' '[A-Z]')
echo_date "$ssrtype节点:【$ssr_remarks"
# SSR
# echo "服务器地址: $ssr_host"
# echo "服务器端口 $ssr_port"
# echo "密码: $ssr_passwd"
# echo "SS加密: $ss_method"
# echo "加密: $ssr_method"
# echo "协议: $ssr_protocol"
# echo "协议参数: $ssr_protoparam"
# echo "混淆: $ssr_obfs"
# echo "混淆参数: $ssr_obfsparam"
# echo "备注: $ssr_remarks"
done
for ((x=0;x<${#temp_host_o[@]};x++)) # 新旧服务器信息匹配,如果旧服务器信息不存在于新服务器信息则删除
do
if [ -z "$(echo "$subscribe_x" | grep -w ${temp_host_o[x]})" ]; then
uci_name_tmp=$(uci show $name | grep ${temp_host_o[x]} | awk -F . '{print $2}')
uci delete $name.$uci_name_tmp
subscribe_o=$(($subscribe_o + 1))
fi
done
echo_date "本次更新订阅来源 【$ssr_group】 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
echo_date "在线订阅列表更新完成!请等待网页自动刷新!"
subscribe_log="$ssr_group 服务器订阅更新成功 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
logger -st $log_name[$$] -p6 "$subscribe_log"
uci commit $name
else
echo_date "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
fi
else
echo_date "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
fi
done
/etc/init.d/$name restart >/dev/null 2>&1

View File

@ -0,0 +1,26 @@
#!/bin/sh
chnroute_data=$(wget -O- -t 3 -T 3 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest)
[ $? -eq 0 ] && {
echo "$chnroute_data" | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt
}
if [ -s "/tmp/china_ssr.txt" ];then
if ( ! cmp -s /tmp/china_ssr.txt /etc/china_ssr.txt );then
mv /tmp/china_ssr.txt /etc/china_ssr.txt
fi
fi
/usr/share/shadowsocksr/chinaipset.sh
wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64
/usr/bin/ssr-gfw
if [ -s "/tmp/gfwnew.txt" ];then
if ( ! cmp -s /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf );then
mv /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf
echo "copy"
fi
fi
/etc/init.d/shadowsocksr restart

View File

@ -0,0 +1,54 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=pdnsd
PKG_VERSION:=1.2.9b-par
PKG_RELEASE=$(PKG_SOURCE_VERSION)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/shadowsocks/pdnsd.git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=a8e46ccba7b0fa2230d6c42ab6dcd92926f6c21d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
# PKG_MIRROR_MD5SUM:=
# CMAKE_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/pdnsd-alt
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
DEPENDS:=+libpthread
TITLE:=Proxy DNS Server
endef
define Package/pdnsd-alt/description
pdnsd, is an IPv6 capable proxy DNS server with permanent caching (the cache
contents are written to hard disk on exit) that is designed to cope with
unreachable or down DNS servers (for example in dial-in networking).
pdnsd can be used with applications that do dns lookups, eg on startup, and
can't be configured to change that behaviour, to prevent the often
minute-long hangs (or even crashes) that result from stalled dns queries.
endef
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
#TARGET_CFLAGS += -ggdb3
CMAKE_OPTIONS += -DDEBUG=1
CONFIGURE_ARGS += \
--with-cachedir=/var/pdnsd
define Package/pdnsd-alt/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/pdnsd $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/pdnsd-ctl/pdnsd-ctl $(1)/usr/bin/
#$(INSTALL_DIR) $(1)/etc/init.d
#$(INSTALL_BIN) ./files/pdnsd.init $(1)/etc/init.d/pdnsd
$(INSTALL_DIR) $(1)/etc
$(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/pdnsd.conf $(1)/etc/
endef
$(eval $(call BuildPackage,pdnsd-alt))

View File

@ -0,0 +1,46 @@
#!/bin/sh /etc/rc.common
START=65
NAME=pdnsd
DESC="proxy DNS server"
DAEMON=/usr/sbin/pdnsd
PID_FILE=/var/run/$NAME.pid
CACHEDIR=/var/pdnsd
CACHE=$CACHEDIR/pdnsd.cache
USER=nobody
GROUP=nogroup
start() {
echo -n "Starting $DESC: $NAME"
gen_cache
$DAEMON --daemon -p $PID_FILE
echo " ."
}
stop() {
echo -n "Stopping $DESC: $NAME"
kill `cat $PID_FILE` > /dev/null 2>&1
rm -rf $PID_FILE
echo " ."
}
restart() {
echo "Restarting $DESC: $NAME... "
stop
sleep 2
start
}
gen_cache()
{
if ! test -f "$CACHE"; then
mkdir -p `dirname $CACHE`
dd if=/dev/zero of="$CACHE" bs=1 count=4 2> /dev/null
chown -R $USER.$GROUP $CACHEDIR
fi
}

View File

@ -0,0 +1,67 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=shadowsocksr-libev
PKG_VERSION:=2.5.6
PKG_RELEASE:=5
PKG_SOURCE_PROTO:=git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/shadowsocksrr/shadowsocksr-libev
PKG_SOURCE_VERSION:=d63ff863800a5645aca4309d5dd5962bd1e95543
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION)
PKG_LICENSE:=GPLv3
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION)
PKG_INSTALL:=1
PKG_FIXUP:=autoreconf
PKG_USE_MIPS16:=0
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/shadowsocksr-libev
SECTION:=net
CATEGORY:=Network
TITLE:=Lightweight Secured Socks5 Proxy
URL:=https://github.com/shadowsocksrr/shadowsocksr-libev
DEPENDS:=+libopenssl +libpthread +libpcre +zlib
endef
Package/shadowsocksr-libev-server = $(Package/shadowsocksr-libev)
Package/shadowsocksr-libev-alt = $(Package/shadowsocksr-libev)
Package/shadowsocksr-libev-ssr-local = $(Package/shadowsocksr-libev)
CONFIGURE_ARGS += --disable-documentation --disable-ssp --disable-assert
define Package/shadowsocksr-libev/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-local $(1)/usr/bin/ssr-local
$(LN) ssr-local $(1)/usr/bin/ssr-tunnel
$(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-check $(1)/usr/bin/ssr-check
endef
define Package/shadowsocksr-libev-alt/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-redir $(1)/usr/bin/ssr-redir
$(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-check $(1)/usr/bin/ssr-check
endef
define Package/shadowsocksr-libev-server/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/server/ss-server $(1)/usr/bin/ssr-server
endef
define Package/shadowsocksr-libev-ssr-local/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ss-local $(1)/usr/bin/ssr-local
$(LN) ssr-local $(1)/usr/bin/ssr-tunnel
endef
$(eval $(call BuildPackage,shadowsocksr-libev))
$(eval $(call BuildPackage,shadowsocksr-libev-alt))
$(eval $(call BuildPackage,shadowsocksr-libev-server))
$(eval $(call BuildPackage,shadowsocksr-libev-ssr-local))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
diff --git a/src/obfs/obfs.c b/src/obfs/obfs.c
index 463359f..4cd750a 100644
--- a/src/obfs/obfs.c
+++ b/src/obfs/obfs.c
@@ -88,7 +88,7 @@
plugin->client_decode = tls12_ticket_auth_client_decode;
return plugin;
- /*} else if (strcmp(plugin_name, "verify_simple") == 0) {
+ } else if (strcmp(plugin_name, "verify_simple") == 0) {
obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs_class));
plugin->init_data = init_data;
plugin->new_obfs = verify_simple_new_obfs;
@@ -115,7 +115,7 @@
plugin->client_udp_pre_encrypt = NULL;
plugin->client_udp_post_decrypt = NULL;
- return plugin;*/
+ return plugin;
} else if (strcmp(plugin_name, "auth_sha1") == 0) {
obfs_class *plugin = (obfs_class *) malloc(sizeof(obfs_class));
plugin->init_data = auth_simple_init_data;

View File

@ -0,0 +1,42 @@
diff --git a/src/utils.c b/src/utils.c
index 94f8a83..01bcbac 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -258,8 +258,6 @@ usage()
{
printf("\n");
printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO);
- printf(
- " maintained by Max Lv <max.c.lv@gmail.com> and Linus Yang <laokongzi@gmail.com>\n\n");
printf(" usage:\n\n");
#ifdef MODULE_LOCAL
printf(" ss-local\n");
@@ -298,6 +296,25 @@ usage()
printf(
" The default cipher is rc4-md5.\n");
printf("\n");
+ printf(
+ " -o <obfs> Obfs of your remote server: plain,\n");
+ printf(
+ " http_simple, http_post and tls1.2_ticket_auth.\n");
+ printf(
+ " -g <obfs-param> Obfs-Param of your remote server.\n");
+ printf(
+ " -O <protocol> Protocol of your remote server: orgin,\n");
+ printf(
+ " auth_sha1, auth_sha1_v2, auth_sha1_v4,\n");
+ printf(
+ " auth_aes128_md5, auth_aes128_sha1,\n");
+ printf(
+ " auth_chain_a, auth_chain_b, auth_chain_c,\n");
+ printf(
+ " auth_chain_d, auth_chain_e and auth_chain_f.\n");
+ printf(
+ " -G <protocol-param> Protocol-Param of your remote server.\n");
+ printf("\n");
printf(
" [-a <user>] Run as another user.\n");
printf(
--
2.19.1

View File

@ -0,0 +1,11 @@
--- a/src/local.c
+++ b/src/local.c
@@ -718,7 +718,7 @@
ss_free(hostname);
} else {
- strncpy(host, ip, sizeof(ip));
+ strncpy(host, ip, INET6_ADDRSTRLEN);
}
}

View File

@ -0,0 +1,69 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=v2ray
PKG_VERSION:=4.20
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=V2Ray is a cross-platform proxy software
DEPENDS:=+ca-certificates
URL:=https://github.com/v2ray/v2ray-core
endef
define Package/$(PKG_NAME)/description
V2Ray is a cross-platform proxy software
endef
V2RAY_BIN:=v2ray
ifeq ($(ARCH),x86_64)
PKG_ARCH_V2RAY:=amd64
endif
ifeq ($(ARCH),mipsel)
PKG_ARCH_V2RAY:=mipsle
endif
ifeq ($(ARCH),mips)
PKG_ARCH_V2RAY:=mips
endif
ifeq ($(ARCH),i386)
PKG_ARCH_V2RAY:=x86
endif
ifeq ($(ARCH),arm)
PKG_ARCH_V2RAY:=arm
ifneq ($(BOARD),bcm53xx)
V2RAY_BIN:=v2ray_armv7
endif
ifeq ($(BOARD),kirkwood)
V2RAY_BIN:=v2ray
endif
endif
ifeq ($(ARCH),aarch64)
PKG_ARCH_V2RAY:=arm64
endif
define Build/Prepare
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin/v2ray
$(INSTALL_BIN) ./files/$(PKG_ARCH_V2RAY)/$(V2RAY_BIN) $(1)/usr/bin/v2ray/v2ray
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.