├── root
├── etc
│ ├── dnsmasq.ssr
│ │ ├── ad.conf
│ │ └── gfw_list.conf
│ ├── uci-defaults
│ │ └── luci-ssr-plus
│ ├── config
│ │ ├── gfw.list
│ │ └── shadowsocksr
│ ├── dnsmasq.oversea
│ │ └── oversea_list.conf
│ └── init.d
│ │ └── shadowsocksr
└── usr
│ ├── bin
│ ├── ssr-switch
│ ├── ssr-monitor
│ ├── ssr-ad
│ ├── ssr-gfw
│ └── ssr-rules
│ └── share
│ └── shadowsocksr
│ ├── gfw2ipset.sh
│ ├── chinaipset.sh
│ ├── update.sh
│ ├── genv2config.lua
│ └── subscribe.sh
├── README.md
├── luasrc
├── controller
│ └── shadowsocksr.lua
├── model
│ └── cbi
│ │ └── shadowsocksr
│ │ ├── log.lua
│ │ ├── list.lua
│ │ ├── control.lua
│ │ ├── advanced.lua
│ │ ├── server-config.lua
│ │ ├── server.lua
│ │ ├── servers.lua
│ │ ├── client.lua
│ │ ├── status.lua
│ │ └── client-config.lua
└── view
│ └── shadowsocksr
│ ├── status.htm
│ ├── checkport.htm
│ ├── check.htm
│ ├── refresh.htm
│ └── ssrurl.htm
├── Makefile
└── po
└── zh-cn
└── ssr-plus.po
/root/etc/dnsmasq.ssr/ad.conf:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Lean-luci-app-ssr-plus
2 | 为了世界和平(手动狗头)
3 | 大雕删除了这份宝贵的源码,在这里做个备份
4 |
--------------------------------------------------------------------------------
/root/etc/dnsmasq.ssr/gfw_list.conf:
--------------------------------------------------------------------------------
1 | server=/.t66y.com/127.0.0.1#5335
2 | ipset=/.t66y.com/gfwlist
3 |
--------------------------------------------------------------------------------
/root/usr/bin/ssr-switch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/P0lari5/luci-app-ssr-plus/HEAD/root/usr/bin/ssr-switch
--------------------------------------------------------------------------------
/root/usr/bin/ssr-monitor:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/P0lari5/luci-app-ssr-plus/HEAD/root/usr/bin/ssr-monitor
--------------------------------------------------------------------------------
/luasrc/controller/shadowsocksr.lua:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/P0lari5/luci-app-ssr-plus/HEAD/luasrc/controller/shadowsocksr.lua
--------------------------------------------------------------------------------
/root/usr/bin/ssr-ad:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | if [ -f /tmp/adnew.conf ]; then
4 | cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf
5 | fi
6 |
7 |
--------------------------------------------------------------------------------
/root/usr/share/shadowsocksr/gfw2ipset.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | awk '!/^$/&&!/^#/{printf("ipset=/.%s/'"gfwlist"'\n",$0)}' /etc/config/gfw.list > /etc/dnsmasq.ssr/custom_forward.conf
4 | awk '!/^$/&&!/^#/{printf("server=/.%s/'"127.0.0.1#5335"'\n",$0)}' /etc/config/gfw.list >> /etc/dnsmasq.ssr/custom_forward.conf
5 |
6 |
--------------------------------------------------------------------------------
/root/usr/share/shadowsocksr/chinaipset.sh:
--------------------------------------------------------------------------------
1 | echo "create china hash:net family inet hashsize 1024 maxelem 65536" > /tmp/china.ipset
2 | awk '!/^$/&&!/^#/{printf("add china %s'" "'\n",$0)}' /etc/china_ssr.txt >> /tmp/china.ipset
3 | ipset -! flush china
4 | ipset -! restore < /tmp/china.ipset 2>/dev/null
5 | rm -f /tmp/china.ipset
6 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/log.lua:
--------------------------------------------------------------------------------
1 | local fs = require "nixio.fs"
2 | local conffile = "/tmp/ssrpro.log"
3 |
4 | f = SimpleForm("logview")
5 |
6 | t = f:field(TextValue, "conf")
7 | t.rmempty = true
8 | t.rows = 20
9 | function t.cfgvalue()
10 | luci.sys.exec("[ -f /tmp/ssrplus.log ] && sed '1!G;h;$!d' /tmp/ssrplus.log > /tmp/ssrpro.log")
11 | return fs.readfile(conffile) or ""
12 | end
13 | t.readonly="readonly"
14 |
15 | return f
--------------------------------------------------------------------------------
/root/etc/uci-defaults/luci-ssr-plus:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | uci -q batch <<-EOF >/dev/null
4 | delete ucitrack.@shadowsocksr[-1]
5 | add ucitrack shadowsocksr
6 | set ucitrack.@shadowsocksr[-1].init=shadowsocksr
7 | commit ucitrack
8 | delete firewall.shadowsocksr
9 | set firewall.shadowsocksr=include
10 | set firewall.shadowsocksr.type=script
11 | set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
12 | set firewall.shadowsocksr.reload=1
13 | commit firewall
14 | EOF
15 |
16 | /usr/share/shadowsocksr/gfw2ipset.sh
17 | rm -f /tmp/luci-indexcache
18 | exit 0
19 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/list.lua:
--------------------------------------------------------------------------------
1 | local fs = require "nixio.fs"
2 | local conffile = "/etc/config/gfw.list"
3 |
4 | f = SimpleForm("custom", translate("GFW Custom List"), translate("Please refer to the following writing"))
5 |
6 | t = f:field(TextValue, "conf")
7 | t.rmempty = true
8 | t.rows = 13
9 | function t.cfgvalue()
10 | return fs.readfile(conffile) or ""
11 | end
12 |
13 | function f.handle(self, state, data)
14 | if state == FORM_VALID then
15 | if data.conf then
16 | fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
17 | luci.sys.call("/usr/share/shadowsocksr/gfw2ipset.sh && /etc/init.d/dnsmasq restart")
18 | end
19 | end
20 | return true
21 | end
22 |
23 | return f
--------------------------------------------------------------------------------
/luasrc/view/shadowsocksr/status.htm:
--------------------------------------------------------------------------------
1 |
17 |
18 |
23 |
--------------------------------------------------------------------------------
/luasrc/view/shadowsocksr/checkport.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
31 |
32 | <%=self.value%>
33 |
34 |
35 |
36 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/root/usr/share/shadowsocksr/update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | chnroute_data=$(wget -O- -t 3 -T 3 http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest)
4 | [ $? -eq 0 ] && {
5 | echo "$chnroute_data" | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt
6 | }
7 |
8 | if [ -s "/tmp/china_ssr.txt" ];then
9 | if ( ! cmp -s /tmp/china_ssr.txt /etc/china_ssr.txt );then
10 | mv /tmp/china_ssr.txt /etc/china_ssr.txt
11 | fi
12 | fi
13 |
14 | /usr/share/shadowsocksr/chinaipset.sh
15 |
16 | wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfw.b64
17 | /usr/bin/ssr-gfw
18 |
19 | if [ -s "/tmp/gfwnew.txt" ];then
20 | if ( ! cmp -s /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf );then
21 | mv /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf
22 | echo "copy"
23 | fi
24 | fi
25 |
26 | /etc/init.d/shadowsocksr restart
--------------------------------------------------------------------------------
/root/etc/config/gfw.list:
--------------------------------------------------------------------------------
1 | 91smartyun.pt
2 | adobe.com
3 | amazonaws.com
4 | ampproject.org
5 | apple.news
6 | aws.amazon.com
7 | azureedge.net
8 | backpackers.com.tw
9 | bitfinex.com
10 | buzzfeed.com
11 | clockwise.ee
12 | cloudfront.net
13 | coindesk.com
14 | coinsquare.io
15 | cryptocompare.com
16 | dropboxstatic.com
17 | eurecom.fr
18 | gdax.com
19 | github.com
20 | kknews.cc
21 | nutaq.com
22 | openairinterface.org
23 | skype.com
24 | sublimetext.com
25 | textnow.com
26 | textnow.me
27 | trouter.io
28 | uploaded.net
29 | whatsapp.com
30 | whatsapp.net
31 | wsj.net
32 | google.com
33 | google.com.hk
34 | gstatic.com
35 | googleusercontent.com
36 | googlepages.com
37 | googlevideo.com
38 | googlecode.com
39 | googleapis.com
40 | googlesource.com
41 | googledrive.com
42 | ggpht.com
43 | youtube.com
44 | youtu.be
45 | ytimg.com
46 | twitter.com
47 | facebook.com
48 | fastly.net
49 | akamai.net
50 | akamaiedge.net
51 | akamaihd.net
52 | edgesuite.net
53 | edgekey.net
--------------------------------------------------------------------------------
/root/etc/config/shadowsocksr:
--------------------------------------------------------------------------------
1 |
2 | config global
3 | option tunnel_forward '8.8.4.4:53'
4 | option tunnel_address '0.0.0.0'
5 | option run_mode 'gfw'
6 | option pdnsd_enable '1'
7 | option monitor_enable '1'
8 | option global_server 'nil'
9 | option enable_switch '1'
10 | option switch_timeout '5'
11 | option switch_time '667'
12 |
13 | config socks5_proxy
14 | option server 'nil'
15 | option local_port '1080'
16 | option local_address '0.0.0.0'
17 |
18 | config access_control
19 | option wan_bp_list '/etc/china_ssr.txt'
20 | option lan_ac_mode 'b'
21 | option router_proxy '1'
22 | list wan_fw_ips '149.154.160.0/20'
23 | list wan_fw_ips '67.198.55.0/24'
24 | list wan_fw_ips '91.108.4.0/22'
25 | list wan_fw_ips '91.108.56.0/22'
26 | list wan_fw_ips '109.239.140.0/24'
27 |
28 | config server_global
29 | option enable_server '0'
30 |
31 | config server_subscribe
32 | option proxy '0'
33 | option auto_update_time '2'
34 | option auto_update '1'
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/luasrc/view/shadowsocksr/check.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
33 |
34 |
35 |
36 | <%=self.value%>
37 |
38 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/root/usr/bin/ssr-gfw:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 |
3 | generate_china_banned()
4 | {
5 |
6 | cat $1 | base64 -d > /tmp/gfwlist.txt
7 | rm -f $1
8 | sed -i '/^@@|/d' /tmp/gfwlist.txt
9 |
10 | cat /tmp/gfwlist.txt | sort -u |
11 | sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
12 | 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' |
13 | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
14 | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
15 | awk '
16 | BEGIN { prev = "________"; } {
17 | cur = $0;
18 | if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
19 | } else {
20 | print cur;
21 | prev = cur;
22 | }
23 | }' | sort -u
24 |
25 | }
26 |
27 | generate_china_banned /tmp/gfw.b64 > /tmp/gfw.txt
28 | rm -f /tmp/gfwlist.txt
29 | sed '/.*/s/.*/server=\/\.&\/127.0.0.1#5335\nipset=\/\.&\/gfwlist/' /tmp/gfw.txt >/tmp/gfwnew.txt
30 | rm -f /tmp/gfw.txt
31 |
32 |
--------------------------------------------------------------------------------
/luasrc/view/shadowsocksr/refresh.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
39 |
40 |
41 |
42 | <%=self.value%>
43 |
44 | <%+cbi/valuefooter%>
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/control.lua:
--------------------------------------------------------------------------------
1 | local m, s, o
2 |
3 | m = Map("shadowsocksr", translate("IP black-and-white list"))
4 |
5 | s = m:section(TypedSection, "access_control")
6 | s.anonymous = true
7 |
8 | -- Part of WAN
9 | s:tab("wan_ac", translate("WAN IP AC"))
10 |
11 | o = s:taboption("wan_ac", DynamicList, "wan_bp_ips", translate("WAN White List IP"))
12 | o.datatype = "ip4addr"
13 |
14 | o = s:taboption("wan_ac", DynamicList, "wan_fw_ips", translate("WAN Force Proxy IP"))
15 | o.datatype = "ip4addr"
16 |
17 | -- Part of LAN
18 | s:tab("lan_ac", translate("LAN IP AC"))
19 |
20 | o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Bypassed Host List"))
21 | o.datatype = "ipaddr"
22 | luci.ip.neighbors({ family = 4 }, function(entry)
23 | if entry.reachable then
24 | o:value(entry.dest:string())
25 | end
26 | end)
27 |
28 | o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
29 | o.datatype = "ipaddr"
30 | luci.ip.neighbors({ family = 4 }, function(entry)
31 | if entry.reachable then
32 | o:value(entry.dest:string())
33 | end
34 | end)
35 |
36 | o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
37 | o.datatype = "ipaddr"
38 | luci.ip.neighbors({ family = 4 }, function(entry)
39 | if entry.reachable then
40 | o:value(entry.dest:string())
41 | end
42 | end)
43 |
44 | -- Part of Self
45 | -- s:tab("self_ac", translate("Router Self AC"))
46 | -- o = s:taboption("self_ac",ListValue, "router_proxy", translate("Router Self Proxy"))
47 | -- o:value("1", translatef("Normal Proxy"))
48 | -- o:value("0", translatef("Bypassed Proxy"))
49 | -- o:value("2", translatef("Forwarded Proxy"))
50 | -- o.rmempty = false
51 |
52 | return m
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/advanced.lua:
--------------------------------------------------------------------------------
1 | local shadowsocksr = "shadowsocksr"
2 | local uci = luci.model.uci.cursor()
3 | local server_table = {}
4 |
5 | uci:foreach(shadowsocksr, "servers", function(s)
6 | if s.alias then
7 | server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
8 | elseif s.server and s.server_port then
9 | server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
10 | end
11 | end)
12 |
13 | local key_table = {}
14 | for key,_ in pairs(server_table) do
15 | table.insert(key_table,key)
16 | end
17 |
18 | table.sort(key_table)
19 |
20 | m = Map(shadowsocksr)
21 |
22 | s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
23 | s.anonymous = true
24 |
25 | o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
26 | o.rmempty = false
27 |
28 | o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
29 | o.rmempty = false
30 |
31 | o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
32 | o.datatype = "uinteger"
33 | o:depends("enable_switch", "1")
34 | o.default = 3600
35 |
36 | o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
37 | o.datatype = "uinteger"
38 | o:depends("enable_switch", "1")
39 | o.default = 5
40 |
41 | -- [[ SOCKS5 Proxy ]]--
42 | if nixio.fs.access("/usr/bin/ssr-local") then
43 | s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
44 | s.anonymous = true
45 |
46 | o = s:option(ListValue, "server", translate("Server"))
47 | o:value("nil", translate("Disable"))
48 | for _,key in pairs(key_table) do o:value(key,server_table[key]) end
49 | o.default = "nil"
50 | o.rmempty = false
51 |
52 | o = s:option(Value, "local_port", translate("Local Port"))
53 | o.datatype = "port"
54 | o.default = 1080
55 | o.rmempty = false
56 |
57 | end
58 |
59 | return m
60 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/server-config.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2017 yushi studio
2 | -- Licensed to the public under the GNU General Public License v3.
3 |
4 | local m, s, o
5 | local shadowsocksr = "shadowsocksr"
6 | local sid = arg[1]
7 |
8 | local encrypt_methods = {
9 | "rc4-md5",
10 | "rc4-md5-6",
11 | "rc4",
12 | "table",
13 | "aes-128-cfb",
14 | "aes-192-cfb",
15 | "aes-256-cfb",
16 | "aes-128-ctr",
17 | "aes-192-ctr",
18 | "aes-256-ctr",
19 | "bf-cfb",
20 | "camellia-128-cfb",
21 | "camellia-192-cfb",
22 | "camellia-256-cfb",
23 | "cast5-cfb",
24 | "des-cfb",
25 | "idea-cfb",
26 | "rc2-cfb",
27 | "seed-cfb",
28 | "salsa20",
29 | "chacha20",
30 | "chacha20-ietf",
31 | }
32 |
33 | local protocol = {
34 | "origin",
35 | }
36 |
37 | obfs = {
38 | "plain",
39 | "http_simple",
40 | "http_post",
41 | }
42 |
43 | m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
44 |
45 | m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/server")
46 | if m.uci:get(shadowsocksr, sid) ~= "server_config" then
47 | luci.http.redirect(m.redirect)
48 | return
49 | end
50 |
51 |
52 |
53 |
54 | -- [[ Server Setting ]]--
55 | s = m:section(NamedSection, sid, "server_config")
56 | s.anonymous = true
57 | s.addremove = false
58 |
59 | o = s:option(Flag, "enable", translate("Enable"))
60 | o.default = 1
61 | o.rmempty = false
62 |
63 | o = s:option(Value, "server_port", translate("Server Port"))
64 | o.datatype = "port"
65 | o.default = 8388
66 | o.rmempty = false
67 |
68 | o = s:option(Value, "timeout", translate("Connection Timeout"))
69 | o.datatype = "uinteger"
70 | o.default = 60
71 | o.rmempty = false
72 |
73 | o = s:option(Value, "password", translate("Password"))
74 | o.password = true
75 | o.rmempty = false
76 |
77 | o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
78 | for _, v in ipairs(encrypt_methods) do o:value(v) end
79 | o.rmempty = false
80 |
81 | o = s:option(ListValue, "protocol", translate("Protocol"))
82 | for _, v in ipairs(protocol) do o:value(v) end
83 | o.rmempty = false
84 |
85 |
86 | o = s:option(ListValue, "obfs", translate("Obfs"))
87 | for _, v in ipairs(obfs) do o:value(v) end
88 | o.rmempty = false
89 |
90 | o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
91 |
92 | o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
93 | o.rmempty = false
94 |
95 | return m
96 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | include $(TOPDIR)/rules.mk
2 |
3 | PKG_NAME:=luci-app-ssr-plus
4 | PKG_VERSION:=1
5 | PKG_RELEASE:=96
6 |
7 | PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
8 | CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
9 | CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \
10 | CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
11 | CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
12 |
13 | include $(INCLUDE_DIR)/package.mk
14 |
15 | define Package/$(PKG_NAME)/config
16 | config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
17 | bool "Include Shadowsocks New Version"
18 | default n
19 |
20 | config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
21 | bool "Include V2ray"
22 | default n
23 |
24 | config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
25 | bool "Include Kcptun"
26 | default n
27 |
28 | config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
29 | bool "Include ShadowsocksR Server"
30 | default n
31 |
32 | config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
33 | bool "Include ShadowsocksR Socks and Tunnel"
34 | default n
35 | endef
36 |
37 | define Package/luci-app-ssr-plus
38 | SECTION:=luci
39 | CATEGORY:=LuCI
40 | SUBMENU:=3. Applications
41 | TITLE:=SS/SSR/V2Ray LuCI interface
42 | PKGARCH:=all
43 | DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget \
44 | +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
45 | +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
46 | +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
47 | +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
48 | +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local
49 | endef
50 |
51 | define Build/Prepare
52 | endef
53 |
54 | define Build/Compile
55 | endef
56 |
57 | define Package/luci-app-ssr-plus/install
58 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci
59 | cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
60 | $(INSTALL_DIR) $(1)/
61 | cp -pR ./root/* $(1)/
62 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
63 | po2lmo ./po/zh-cn/ssr-plus.po $(1)/usr/lib/lua/luci/i18n/ssr-plus.zh-cn.lmo
64 | endef
65 |
66 | define Package/luci-app-ssr-plus/postinst
67 | #!/bin/sh
68 | if [ -z "$${IPKG_INSTROOT}" ]; then
69 | ( . /etc/uci-defaults/luci-ssr-plus ) && rm -f /etc/uci-defaults/luci-ssr-plus
70 | rm -f /tmp/luci-indexcache
71 | chmod 755 /etc/init.d/shadowsocksr >/dev/null 2>&1
72 | /etc/init.d/shadowsocksr enable >/dev/null 2>&1
73 | fi
74 | exit 0
75 | endef
76 |
77 | define Package/luci-app-ssr-plus/prerm
78 | #!/bin/sh
79 | if [ -z "$${IPKG_INSTROOT}" ]; then
80 | /etc/init.d/shadowsocksr disable
81 | /etc/init.d/shadowsocksr stop
82 | fi
83 | exit 0
84 | endef
85 |
86 | $(eval $(call BuildPackage,luci-app-ssr-plus))
87 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/server.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2017 yushi studio
2 | -- Licensed to the public under the GNU General Public License v3.
3 |
4 | local m, sec, o
5 | local shadowsocksr = "shadowsocksr"
6 | local uci = luci.model.uci.cursor()
7 | local ipkg = require("luci.model.ipkg")
8 |
9 |
10 | m = Map(shadowsocksr, translate("ShadowSocksR Server"))
11 |
12 | local encrypt_methods = {
13 | "table",
14 | "rc4",
15 | "rc4-md5",
16 | "rc4-md5-6",
17 | "aes-128-cfb",
18 | "aes-192-cfb",
19 | "aes-256-cfb",
20 | "aes-128-ctr",
21 | "aes-192-ctr",
22 | "aes-256-ctr",
23 | "bf-cfb",
24 | "camellia-128-cfb",
25 | "camellia-192-cfb",
26 | "camellia-256-cfb",
27 | "cast5-cfb",
28 | "des-cfb",
29 | "idea-cfb",
30 | "rc2-cfb",
31 | "seed-cfb",
32 | "salsa20",
33 | "chacha20",
34 | "chacha20-ietf",
35 | }
36 |
37 | local protocol = {
38 | "origin",
39 | "verify_deflate",
40 | "auth_sha1_v4",
41 | "auth_aes128_sha1",
42 | "auth_aes128_md5",
43 | "auth_chain_a",
44 | }
45 |
46 | obfs = {
47 | "plain",
48 | "http_simple",
49 | "http_post",
50 | "random_head",
51 | "tls1.2_ticket_auth",
52 | "tls1.2_ticket_fastauth",
53 | }
54 |
55 |
56 |
57 |
58 |
59 | -- [[ Global Setting ]]--
60 | sec = m:section(TypedSection, "server_global", translate("Global Setting"))
61 | sec.anonymous = true
62 |
63 |
64 |
65 | o = sec:option(Flag, "enable_server", translate("Enable Server"))
66 | o.rmempty = false
67 |
68 | -- [[ Server Setting ]]--
69 | sec = m:section(TypedSection, "server_config", translate("Server Setting"))
70 | sec.anonymous = true
71 | sec.addremove = true
72 | sec.template = "cbi/tblsection"
73 | sec.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/server/%s")
74 | function sec.create(...)
75 | local sid = TypedSection.create(...)
76 | if sid then
77 | luci.http.redirect(sec.extedit % sid)
78 | return
79 | end
80 | end
81 |
82 | o = sec:option(Flag, "enable", translate("Enable"))
83 | function o.cfgvalue(...)
84 | return Value.cfgvalue(...) or translate("0")
85 | end
86 | o.rmempty = false
87 |
88 | o = sec:option(DummyValue, "server_port", translate("Server Port"))
89 | function o.cfgvalue(...)
90 | return Value.cfgvalue(...) or "?"
91 | end
92 |
93 |
94 | o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
95 | function o.cfgvalue(...)
96 | local v = Value.cfgvalue(...)
97 | return v and v:upper() or "?"
98 | end
99 |
100 | o = sec:option(DummyValue, "protocol", translate("Protocol"))
101 | function o.cfgvalue(...)
102 | return Value.cfgvalue(...) or "?"
103 | end
104 |
105 |
106 |
107 | o = sec:option(DummyValue, "obfs", translate("Obfs"))
108 | function o.cfgvalue(...)
109 | return Value.cfgvalue(...) or "?"
110 | end
111 |
112 |
113 |
114 | return m
115 |
--------------------------------------------------------------------------------
/root/usr/share/shadowsocksr/genv2config.lua:
--------------------------------------------------------------------------------
1 | local ucursor = require "luci.model.uci".cursor()
2 | local json = require "luci.jsonc"
3 | local server_section = arg[1]
4 | local proto = arg[2]
5 | local local_port = arg[3]
6 |
7 | local server = ucursor:get_all("shadowsocksr", server_section)
8 |
9 | local v2ray = {
10 | log = {
11 | -- error = "/var/ssrplus.log",
12 | loglevel = "warning"
13 | },
14 | -- 传入连接
15 | inbound = {
16 | port = local_port,
17 | protocol = "dokodemo-door",
18 | settings = {
19 | network = proto,
20 | followRedirect = true
21 | },
22 | sniffing = {
23 | enabled = true,
24 | destOverride = { "http", "tls" }
25 | }
26 | },
27 | -- 传出连接
28 | outbound = {
29 | protocol = "vmess",
30 | settings = {
31 | vnext = {
32 | {
33 | address = server.server,
34 | port = tonumber(server.server_port),
35 | users = {
36 | {
37 | id = server.vmess_id,
38 | alterId = tonumber(server.alter_id),
39 | security = server.security
40 | }
41 | }
42 | }
43 | }
44 | },
45 | -- 底层传输配置
46 | streamSettings = {
47 | network = server.transport,
48 | security = (server.tls == '1') and "tls" or "none",
49 | tlsSettings = {allowInsecure = (server.insecure == "1") and true or false,},
50 | kcpSettings = (server.transport == "kcp") and {
51 | mtu = tonumber(server.mtu),
52 | tti = tonumber(server.tti),
53 | uplinkCapacity = tonumber(server.uplink_capacity),
54 | downlinkCapacity = tonumber(server.downlink_capacity),
55 | congestion = (server.congestion == "1") and true or false,
56 | readBufferSize = tonumber(server.read_buffer_size),
57 | writeBufferSize = tonumber(server.write_buffer_size),
58 | header = {
59 | type = server.kcp_guise
60 | }
61 | } or nil,
62 | wsSettings = (server.transport == "ws") and {
63 | path = server.ws_path,
64 | headers = (server.ws_host ~= nil) and {
65 | Host = server.ws_host
66 | } or nil,
67 | } or nil,
68 | httpSettings = (server.transport == "h2") and {
69 | path = server.h2_path,
70 | host = server.h2_host,
71 | } or nil,
72 | quicSettings = (server.transport == "quic") and {
73 | security = server.quic_security,
74 | key = server.quic_key,
75 | header = {
76 | type = server.quic_guise
77 | }
78 | } or nil
79 | },
80 | mux = {
81 | enabled = (server.mux == "1") and true or false,
82 | concurrency = tonumber(server.concurrency)
83 | }
84 | },
85 |
86 | -- 额外传出连接
87 | outboundDetour = {
88 | {
89 | protocol = "freedom",
90 | tag = "direct",
91 | settings = { keep = "" }
92 | }
93 | }
94 | }
95 | print(json.stringify(v2ray, 1))
96 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/servers.lua:
--------------------------------------------------------------------------------
1 | -- Licensed to the public under the GNU General Public License v3.
2 |
3 | local m, s, o
4 | local shadowsocksr = "shadowsocksr"
5 |
6 | local uci = luci.model.uci.cursor()
7 | local server_count = 0
8 | uci:foreach("shadowsocksr", "servers", function(s)
9 | server_count = server_count + 1
10 | end)
11 |
12 | m = Map(shadowsocksr, translate("Servers subscription and manage"))
13 |
14 | -- Server Subscribe
15 |
16 | s = m:section(TypedSection, "server_subscribe")
17 | s.anonymous = true
18 |
19 | o = s:option(Flag, "auto_update", translate("Auto Update"))
20 | o.rmempty = false
21 | o.description = translate("Auto Update Server subscription, GFW list and CHN route")
22 |
23 |
24 | o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
25 | for t = 0,23 do
26 | o:value(t, t..":00")
27 | end
28 | o.default=2
29 | o.rmempty = false
30 |
31 | o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
32 | o.rmempty = true
33 |
34 | o = s:option(Flag, "proxy", translate("Through proxy update"))
35 | o.rmempty = false
36 | o.description = translate("Through proxy update list, Not Recommended ")
37 |
38 | o = s:option(Button,"update",translate("Update"))
39 | o.inputstyle = "reload"
40 | o.write = function()
41 | luci.sys.call("bash /usr/share/shadowsocksr/subscribe.sh >>/tmp/ssrplus.log 2>&1")
42 | luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
43 | end
44 |
45 | o = s:option(Button,"delete",translate("Delete all severs"))
46 | o.inputstyle = "reset"
47 | o.description = string.format(translate("Server Count") .. ": %d", server_count)
48 | o.write = function()
49 | uci:delete_all("shadowsocksr", "servers", function(s) return true end)
50 | luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr stop")
51 | luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
52 | end
53 |
54 | -- [[ Servers Manage ]]--
55 | s = m:section(TypedSection, "servers")
56 | s.anonymous = true
57 | s.addremove = true
58 | s.sortable = false
59 | s.template = "cbi/tblsection"
60 | s.extedit = luci.dispatcher.build_url("admin/services/shadowsocksr/servers/%s")
61 | function s.create(...)
62 | local sid = TypedSection.create(...)
63 | if sid then
64 | luci.http.redirect(s.extedit % sid)
65 | return
66 | end
67 | end
68 |
69 | o = s:option(DummyValue, "type", translate("Type"))
70 | function o.cfgvalue(...)
71 | return Value.cfgvalue(...) or translate("")
72 | end
73 |
74 | o = s:option(DummyValue, "alias", translate("Alias"))
75 | function o.cfgvalue(...)
76 | return Value.cfgvalue(...) or translate("None")
77 | end
78 |
79 | o = s:option(DummyValue, "server", translate("Server Address"))
80 | function o.cfgvalue(...)
81 | return Value.cfgvalue(...) or "?"
82 | end
83 |
84 | o = s:option(DummyValue, "server_port", translate("Server Port"))
85 | function o.cfgvalue(...)
86 | return Value.cfgvalue(...) or "?"
87 | end
88 |
89 | if nixio.fs.access("/usr/bin/kcptun-client") then
90 |
91 | o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
92 | function o.cfgvalue(...)
93 | return Value.cfgvalue(...) or "?"
94 | end
95 |
96 | end
97 |
98 | o = s:option(DummyValue, "switch_enable", translate("Auto Switch"))
99 | function o.cfgvalue(...)
100 | return Value.cfgvalue(...) or "0"
101 | end
102 |
103 | return m
104 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/client.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2017 yushi studio github.com/ywb94
2 | -- Copyright (C) 2018 lean github.com/coolsnowwolf
3 | -- Licensed to the public under the GNU General Public License v3.
4 |
5 | local m, s, sec, o, kcp_enable
6 | local shadowsocksr = "shadowsocksr"
7 | local uci = luci.model.uci.cursor()
8 |
9 | local sys = require "luci.sys"
10 |
11 | m = Map(shadowsocksr, translate("ShadowSocksR Plus+ Settings"))
12 |
13 | m:section(SimpleSection).template = "shadowsocksr/status"
14 |
15 | local server_table = {}
16 | uci:foreach(shadowsocksr, "servers", function(s)
17 | if s.alias then
18 | server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
19 | elseif s.server and s.server_port then
20 | server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
21 | end
22 | end)
23 |
24 | local key_table = {}
25 | for key,_ in pairs(server_table) do
26 | table.insert(key_table,key)
27 | end
28 |
29 | table.sort(key_table)
30 |
31 | -- [[ Global Setting ]]--
32 | s = m:section(TypedSection, "global")
33 | s.anonymous = true
34 |
35 | o = s:option(ListValue, "global_server", translate("Main Server"))
36 | o:value("nil", translate("Disable"))
37 | for _,key in pairs(key_table) do o:value(key,server_table[key]) end
38 | o.default = "nil"
39 | o.rmempty = false
40 |
41 | o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
42 | o:value("", translate("Disable"))
43 | o:value("same", translate("Same as Global Server"))
44 | for _,key in pairs(key_table) do o:value(key,server_table[key]) end
45 |
46 | o = s:option(ListValue, "threads", translate("Multi Threads Option"))
47 | o:value("0", translate("Auto Threads"))
48 | o:value("1", translate("1 Thread"))
49 | o:value("2", translate("2 Threads"))
50 | o:value("4", translate("4 Threads"))
51 | o:value("8", translate("8 Threads"))
52 | o.default = "0"
53 | o.rmempty = false
54 |
55 | o = s:option(ListValue, "run_mode", translate("Running Mode"))
56 | o:value("gfw", translate("GFW List Mode"))
57 | o:value("router", translate("IP Route Mode"))
58 | o:value("all", translate("Global Mode"))
59 | o:value("oversea", translate("Oversea Mode"))
60 | o.default = gfw
61 |
62 | o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
63 | o:value("1", translate("Use Pdnsd tcp query and cache"))
64 | o:value("0", translate("Use Local DNS Service listen port 5335"))
65 | o.default = 1
66 |
67 | o = s:option(ListValue, "tunnel_forward", translate("Anti-pollution DNS Server"))
68 | o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
69 | o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
70 | o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
71 | o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
72 | o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
73 | o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
74 | o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
75 | o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
76 | o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
77 | o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
78 | o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
79 | o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)"))
80 | o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)"))
81 | o:depends("pdnsd_enable", "1")
82 |
83 | return m
84 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/status.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2017 yushi studio
2 | -- Licensed to the public under the GNU General Public License v3.
3 |
4 | local IPK_Version="3.0.9"
5 | local m, s, o
6 | local redir_run=0
7 | local reudp_run=0
8 | local sock5_run=0
9 | local server_run=0
10 | local kcptun_run=0
11 | local tunnel_run=0
12 | local udp2raw_run=0
13 | local udpspeeder_run=0
14 | local gfw_count=0
15 | local ad_count=0
16 | local ip_count=0
17 | local gfwmode=0
18 |
19 | if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
20 | gfwmode=1
21 | end
22 |
23 | local shadowsocksr = "shadowsocksr"
24 | -- html constants
25 | font_blue = [[]]
26 | font_off = [[]]
27 | bold_on = [[]]
28 | bold_off = [[]]
29 |
30 | local fs = require "nixio.fs"
31 | local sys = require "luci.sys"
32 | local kcptun_version=translate("Unknown")
33 | local kcp_file="/usr/bin/kcptun-client"
34 | if not fs.access(kcp_file) then
35 | kcptun_version=translate("Not exist")
36 | else
37 | if not fs.access(kcp_file, "rwx", "rx", "rx") then
38 | fs.chmod(kcp_file, 755)
39 | end
40 | kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
41 | if not kcptun_version or kcptun_version == "" then
42 | kcptun_version = translate("Unknown")
43 | end
44 |
45 | end
46 |
47 | if gfwmode==1 then
48 | gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
49 | if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
50 | ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
51 | end
52 | end
53 |
54 | if nixio.fs.access("/etc/china_ssr.txt") then
55 | ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
56 | end
57 |
58 | local icount=sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l")
59 | if tonumber(icount)>0 then
60 | reudp_run=1
61 | else
62 | icount=sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
63 | if tonumber(icount)>0 then
64 | reudp_run=1
65 | end
66 | end
67 |
68 |
69 | if luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
70 | redir_run=1
71 | end
72 |
73 | if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
74 | sock5_run=1
75 | end
76 |
77 | if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
78 | kcptun_run=1
79 | end
80 |
81 | if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
82 | server_run=1
83 | end
84 |
85 | if luci.sys.call("ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
86 | tunnel_run=1
87 | end
88 |
89 | if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
90 | pdnsd_run=1
91 | end
92 |
93 | m = SimpleForm("Version")
94 | m.reset = false
95 | m.submit = false
96 |
97 | s=m:field(DummyValue,"redir_run",translate("Global Client"))
98 | s.rawhtml = true
99 | if redir_run == 1 then
100 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
101 | else
102 | s.value = translate("Not Running")
103 | end
104 |
105 | s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
106 | s.rawhtml = true
107 | if reudp_run == 1 then
108 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
109 | else
110 | s.value = translate("Not Running")
111 | end
112 |
113 | s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
114 | s.rawhtml = true
115 | if pdnsd_run == 1 then
116 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
117 | else
118 | s.value = translate("Not Running")
119 | end
120 |
121 | if nixio.fs.access("/usr/bin/ssr-local") then
122 | s=m:field(DummyValue,"sock5_run",translate("SOCKS5 Proxy"))
123 | s.rawhtml = true
124 | if sock5_run == 1 then
125 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
126 | else
127 | s.value = translate("Not Running")
128 | end
129 | end
130 |
131 | if nixio.fs.access("/usr/bin/ssr-server") then
132 | s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
133 | s.rawhtml = true
134 | if server_run == 1 then
135 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
136 | else
137 | s.value = translate("Not Running")
138 | end
139 | end
140 |
141 | if nixio.fs.access("/usr/bin/kcptun-client") then
142 | s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
143 | s.rawhtml = true
144 | s.value =kcptun_version
145 |
146 | s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
147 | s.rawhtml = true
148 | if kcptun_run == 1 then
149 | s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
150 | else
151 | s.value = translate("Not Running")
152 | end
153 | end
154 |
155 | s=m:field(DummyValue,"google",translate("Google Connectivity"))
156 | s.value = translate("No Check")
157 | s.template = "shadowsocksr/check"
158 |
159 | s=m:field(DummyValue,"baidu",translate("Baidu Connectivity"))
160 | s.value = translate("No Check")
161 | s.template = "shadowsocksr/check"
162 |
163 | if gfwmode==1 then
164 | s=m:field(DummyValue,"gfw_data",translate("GFW List Data"))
165 | s.rawhtml = true
166 | s.template = "shadowsocksr/refresh"
167 | s.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
168 |
169 | end
170 |
171 | s=m:field(DummyValue,"ip_data",translate("China IP Data"))
172 | s.rawhtml = true
173 | s.template = "shadowsocksr/refresh"
174 | s.value =ip_count .. " " .. translate("Records")
175 |
176 | s=m:field(DummyValue,"check_port",translate("Check Server Port"))
177 | s.template = "shadowsocksr/checkport"
178 | s.value =translate("No Check")
179 |
180 | return m
181 |
--------------------------------------------------------------------------------
/luasrc/view/shadowsocksr/ssrurl.htm:
--------------------------------------------------------------------------------
1 | <%+cbi/valueheader%>
2 |
3 |
134 |
135 |
136 |
137 | <%:ssr://%>
138 |
139 | <%+cbi/valuefooter%>
140 |
--------------------------------------------------------------------------------
/root/usr/share/shadowsocksr/subscribe.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (C) 2017 XiaoShan https://www.mivm.cn
3 |
4 | . /usr/share/libubox/jshn.sh
5 |
6 | urlsafe_b64decode() {
7 | local d="====" data=$(echo $1 | sed 's/_/\//g; s/-/+/g')
8 | local mod4=$((${#data}%4))
9 | [ $mod4 -gt 0 ] && data=${data}${d:mod4}
10 | echo $data | base64 -d
11 | }
12 |
13 | echo_date(){
14 | echo $(TZ=UTC-8 date -R +%Y-%m-%d\ %X):$1
15 | }
16 |
17 | Server_Update() {
18 | local uci_set="uci -q set $name.$1."
19 | ${uci_set}alias="[$ssr_group] $ssr_remarks"
20 | ${uci_set}auth_enable="0"
21 | ${uci_set}switch_enable="1"
22 | ${uci_set}type="$ssr_type"
23 | ${uci_set}server="$ssr_host"
24 | ${uci_set}server_port="$ssr_port"
25 | ${uci_set}local_port="1234"
26 | uci -q get $name.@servers[$1].timeout >/dev/null || ${uci_set}timeout="60"
27 | ${uci_set}password="$ssr_passwd"
28 | ${uci_set}encrypt_method="$ssr_method"
29 | ${uci_set}protocol="$ssr_protocol"
30 | ${uci_set}protocol_param="$ssr_protoparam"
31 | ${uci_set}obfs="$ssr_obfs"
32 | ${uci_set}obfs_param="$ssr_obfsparam"
33 | ${uci_set}fast_open="0"
34 | ${uci_set}kcp_enable="0"
35 | ${uci_set}kcp_port="0"
36 | ${uci_set}kcp_param="--nocomp"
37 |
38 | #v2ray
39 | ${uci_set}alter_id="$ssr_alter_id"
40 | ${uci_set}vmess_id="$ssr_vmess_id"
41 | ${uci_set}security="$ssr_security"
42 | ${uci_set}transport="$ssr_transport"
43 | ${uci_set}tcp_guise="$ssr_tcp_guise"
44 | }
45 |
46 | name=shadowsocksr
47 | subscribe_url=($(uci get $name.@server_subscribe[0].subscribe_url))
48 | [ ${#subscribe_url[@]} -eq 0 ] && exit 1
49 | [ $(uci -q get $name.@server_subscribe[0].proxy || echo 0) -eq 0 ] && /etc/init.d/$name stop >/dev/null 2>&1
50 | log_name=${name}_subscribe
51 | for ((o=0;o<${#subscribe_url[@]};o++))
52 | do
53 | echo_date "从 ${subscribe_url[o]} 获取订阅"
54 | echo_date "开始更新在线订阅列表..."
55 | echo_date "开始下载订阅链接到本地临时文件,请稍等..."
56 | subscribe_data=$(wget-ssl --user-agent="User-Agent: Mozilla" --no-check-certificate -T 3 -O- ${subscribe_url[o]})
57 | curl_code=$?
58 | if [ ! $curl_code -eq 0 ];then
59 | echo_date "下载订阅成功..."
60 | echo_date "开始解析节点信息..."
61 | subscribe_data=$(wget-ssl --no-check-certificate -T 3 -O- ${subscribe_url[o]})
62 | curl_code=$?
63 | fi
64 | if [ $curl_code -eq 0 ];then
65 | ssr_url=($(echo $subscribe_data | base64 -d | sed 's/\r//g')) # 解码数据并删除 \r 换行符
66 | subscribe_max=$(echo ${ssr_url[0]} | grep -i MAX= | awk -F = '{print $2}')
67 | subscribe_max_x=()
68 | if [ -n "$subscribe_max" ]; then
69 | while [ ${#subscribe_max_x[@]} -ne $subscribe_max ]
70 | do
71 | if [ ${#ssr_url[@]} -ge 10 ]; then
72 | if [ $((${RANDOM:0:2}%2)) -eq 0 ]; then
73 | temp_x=${RANDOM:0:1}
74 | else
75 | temp_x=${RANDOM:0:2}
76 | fi
77 | else
78 | temp_x=${RANDOM:0:1}
79 | fi
80 | [ $temp_x -lt ${#ssr_url[@]} -a -z "$(echo "${subscribe_max_x[*]}" | grep -w $temp_x)" ] && subscribe_max_x[${#subscribe_max_x[@]}]="$temp_x"
81 | done
82 | else
83 | subscribe_max=${#ssr_url[@]}
84 | fi
85 | echo_date "共计$subscribe_max个节点"
86 | ssr_group=$(urlsafe_b64decode $(urlsafe_b64decode ${ssr_url[$((${#ssr_url[@]} - 1))]//ssr:\/\//} | sed 's/&/\n/g' | grep group= | awk -F = '{print $2}'))
87 | if [ -z "$ssr_group" ]; then
88 | ssr_group="default"
89 | fi
90 | if [ -n "$ssr_group" ]; then
91 | subscribe_i=0
92 | subscribe_n=0
93 | subscribe_o=0
94 | subscribe_x=""
95 | temp_host_o=()
96 | curr_ssr=$(uci show $name | grep @servers | grep -c server=)
97 | for ((x=0;x<$curr_ssr;x++)) # 循环已有服务器信息,匹配当前订阅群组
98 | do
99 | temp_alias=$(uci -q get $name.@servers[$x].alias | grep "\[$ssr_group\]")
100 | [ -n "$temp_alias" ] && temp_host_o[${#temp_host_o[@]}]=$(uci get $name.@servers[$x].server)
101 | done
102 | for ((x=0;x<$subscribe_max;x++)) # 循环链接
103 | do
104 | [ ${#subscribe_max_x[@]} -eq 0 ] && temp_x=$x || temp_x=${subscribe_max_x[x]}
105 | result=$(echo ${ssr_url[temp_x]} | grep "ssr")
106 | if [[ "$result" != "" ]]
107 | then
108 | temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//ssr:\/\//}) # 解码 SSR 链接
109 |
110 | info=${temp_info///?*/}
111 | temp_info_array=(${info//:/ })
112 | ssr_type="ssr"
113 | ssr_host=${temp_info_array[0]}
114 | ssr_port=${temp_info_array[1]}
115 | ssr_protocol=${temp_info_array[2]}
116 | ssr_method=${temp_info_array[3]}
117 | ssr_obfs=${temp_info_array[4]}
118 | ssr_passwd=$(urlsafe_b64decode ${temp_info_array[5]})
119 | info=${temp_info:$((${#info} + 2))}
120 | info=(${info//&/ })
121 | ssr_protoparam=""
122 | ssr_obfsparam=""
123 | ssr_remarks="$temp_x"
124 | for ((i=0;i<${#info[@]};i++)) # 循环扩展信息
125 | do
126 | temp_info=($(echo ${info[i]} | sed 's/=/ /g'))
127 | case "${temp_info[0]}" in
128 | protoparam)
129 | ssr_protoparam=$(urlsafe_b64decode ${temp_info[1]})
130 | ;;
131 | obfsparam)
132 | ssr_obfsparam=$(urlsafe_b64decode ${temp_info[1]})
133 | ;;
134 | remarks)
135 | ssr_remarks=$(urlsafe_b64decode ${temp_info[1]})
136 | ;;
137 | esac
138 | done
139 | else
140 | temp_info=$(urlsafe_b64decode ${ssr_url[temp_x]//vmess:\/\//}) # 解码 Vmess 链接
141 | ssr_type="v2ray"
142 | json_load "$temp_info"
143 | json_get_var ssr_host add
144 | json_get_var ssr_port port
145 | json_get_var ssr_alter_id aid
146 | json_get_var ssr_vmess_id id
147 | json_get_var ssr_security type
148 | json_get_var ssr_transport net
149 | json_get_var ssr_remarks ps
150 | ssr_tcp_guise="none"
151 | fi
152 |
153 |
154 | uci_name_tmp=$(uci show $name | grep -w $ssr_host | awk -F . '{print $2}')
155 | if [ -z "$uci_name_tmp" ]; then # 判断当前服务器信息是否存在
156 | uci_name_tmp=$(uci add $name servers)
157 | subscribe_n=$(($subscribe_n + 1))
158 | fi
159 | Server_Update $uci_name_tmp
160 | subscribe_x=$subscribe_x$ssr_host" "
161 | ssrtype=$(echo $ssr_type | tr '[a-z]' '[A-Z]')
162 | echo_date "$ssrtype节点:【$ssr_remarks】"
163 |
164 | # echo "服务器地址: $ssr_host"
165 | # echo "服务器端口 $ssr_port"
166 | # echo "密码: $ssr_passwd"
167 | # echo "加密: $ssr_method"
168 | # echo "协议: $ssr_protocol"
169 | # echo "协议参数: $ssr_protoparam"
170 | # echo "混淆: $ssr_obfs"
171 | # echo "混淆参数: $ssr_obfsparam"
172 | # echo "备注: $ssr_remarks"
173 | done
174 | for ((x=0;x<${#temp_host_o[@]};x++)) # 新旧服务器信息匹配,如果旧服务器信息不存在于新服务器信息则删除
175 | do
176 | if [ -z "$(echo "$subscribe_x" | grep -w ${temp_host_o[x]})" ]; then
177 | uci_name_tmp=$(uci show $name | grep ${temp_host_o[x]} | awk -F . '{print $2}')
178 | uci delete $name.$uci_name_tmp
179 | subscribe_o=$(($subscribe_o + 1))
180 | fi
181 | done
182 | echo_date "本次更新订阅来源 【$ssr_group】 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
183 | echo_date "在线订阅列表更新完成!请等待网页自动刷新!"
184 | subscribe_log="$ssr_group 服务器订阅更新成功 服务器数量: ${#ssr_url[@]} 新增服务器: $subscribe_n 删除服务器: $subscribe_o"
185 | logger -st $log_name[$$] -p6 "$subscribe_log"
186 | uci commit $name
187 | else
188 | echo_date "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
189 | logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据解析失败 无法获取 Group"
190 | fi
191 | else
192 | echo_date "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
193 | logger -st $log_name[$$] -p3 "${subscribe_url[$o]} 订阅数据获取失败 错误代码: $curl_code"
194 | fi
195 | done
196 | /etc/init.d/$name restart >/dev/null 2>&1
197 |
--------------------------------------------------------------------------------
/root/etc/dnsmasq.oversea/oversea_list.conf:
--------------------------------------------------------------------------------
1 | server=/v.youku.com/127.0.0.1#5335
2 | server=/api.youku.com/127.0.0.1#5335
3 | server=/v2.tudou.com/127.0.0.1#5335
4 | server=/www.tudou.com/127.0.0.1#5335
5 | server=/s.plcloud.music.qq.com/127.0.0.1#5335
6 | server=/i.y.qq.com/127.0.0.1#5335
7 | server=/hot.vrs.sohu.com/127.0.0.1#5335
8 | server=/live.tv.sohu.com/127.0.0.1#5335
9 | server=/pad.tv.sohu.com/127.0.0.1#5335
10 | server=/my.tv.sohu.com/127.0.0.1#5335
11 | server=/hot.vrs.letv.com/127.0.0.1#5335
12 | server=/data.video.qiyi.com/127.0.0.1#5335
13 | server=/cache.video.qiyi.com/127.0.0.1#5335
14 | server=/cache.vip.qiyi.com/127.0.0.1#5335
15 | server=/vv.video.qq.com/127.0.0.1#5335
16 | server=/tt.video.qq.com/127.0.0.1#5335
17 | server=/ice.video.qq.com/127.0.0.1#5335
18 | server=/tjsa.video.qq.com/127.0.0.1#5335
19 | server=/a10.video.qq.com/127.0.0.1#5335
20 | server=/xyy.video.qq.com/127.0.0.1#5335
21 | server=/vcq.video.qq.com/127.0.0.1#5335
22 | server=/vsh.video.qq.com/127.0.0.1#5335
23 | server=/vbj.video.qq.com/127.0.0.1#5335
24 | server=/bobo.video.qq.com/127.0.0.1#5335
25 | server=/flvs.video.qq.com/127.0.0.1#5335
26 | server=/bkvv.video.qq.com/127.0.0.1#5335
27 | server=/info.zb.qq.com/127.0.0.1#5335
28 | server=/geo.js.kankan.xunlei.com/127.0.0.1#5335
29 | server=/web-play.pptv.com/127.0.0.1#5335
30 | server=/web-play.pplive.cn/127.0.0.1#5335
31 | server=/dyn.ugc.pps.tv/127.0.0.1#5335
32 | server=/v.pps.tv/127.0.0.1#5335
33 | server=/inner.kandian.com/127.0.0.1#5335
34 | server=/ipservice.163.com/127.0.0.1#5335
35 | server=/so.open.163.com/127.0.0.1#5335
36 | server=/zb.s.qq.com/127.0.0.1#5335
37 | server=/ip.kankan.xunlei.com/127.0.0.1#5335
38 | server=/vxml.56.com/127.0.0.1#5335
39 | server=/music.sina.com.cn/127.0.0.1#5335
40 | server=/play.baidu.com/127.0.0.1#5335
41 | server=/v.iask.com/127.0.0.1#5335
42 | server=/tv.weibo.com/127.0.0.1#5335
43 | server=/wtv.v.iask.com/127.0.0.1#5335
44 | server=/video.sina.com.cn/127.0.0.1#5335
45 | server=/www.yinyuetai.com/127.0.0.1#5335
46 | server=/api.letv.com/127.0.0.1#5335
47 | server=/live.gslb.letv.com/127.0.0.1#5335
48 | server=/static.itv.letv.com/127.0.0.1#5335
49 | server=/ip.apps.cntv.cn/127.0.0.1#5335
50 | server=/vdn.apps.cntv.cn/127.0.0.1#5335
51 | server=/vdn.live.cntv.cn/127.0.0.1#5335
52 | server=/vip.sports.cntv.cn/127.0.0.1#5335
53 | server=/a.play.api.3g.youku.com/127.0.0.1#5335
54 | server=/i.play.api.3g.youku.com/127.0.0.1#5335
55 | server=/api.3g.youku.com/127.0.0.1#5335
56 | server=/tv.api.3g.youku.com/127.0.0.1#5335
57 | server=/play.api.3g.youku.com/127.0.0.1#5335
58 | server=/play.api.3g.tudou.com/127.0.0.1#5335
59 | server=/tv.api.3g.tudou.com/127.0.0.1#5335
60 | server=/api.3g.tudou.com/127.0.0.1#5335
61 | server=/api.tv.sohu.com/127.0.0.1#5335
62 | server=/access.tv.sohu.com/127.0.0.1#5335
63 | server=/iface.iqiyi.com/127.0.0.1#5335
64 | server=/iface2.iqiyi.com/127.0.0.1#5335
65 | server=/cache.m.iqiyi.com/127.0.0.1#5335
66 | server=/dynamic.app.m.letv.com/127.0.0.1#5335
67 | server=/dynamic.meizi.app.m.letv.com/127.0.0.1#5335
68 | server=/dynamic.search.app.m.letv.com/127.0.0.1#5335
69 | server=/dynamic.live.app.m.letv.com/127.0.0.1#5335
70 | server=/listso.m.areainfo.ppstream.com/127.0.0.1#5335
71 | server=/epg.api.pptv.com/127.0.0.1#5335
72 | server=/play.api.pptv.com/127.0.0.1#5335
73 | server=/m.letv.com/127.0.0.1#5335
74 | server=/interface.bilibili.com/127.0.0.1#5335
75 | server=/3g.music.qq.com/127.0.0.1#5335
76 | server=/mqqplayer.3g.qq.com/127.0.0.1#5335
77 | server=/proxy.music.qq.com/127.0.0.1#5335
78 | server=/proxymc.qq.com/127.0.0.1#5335
79 | server=/ip2.kugou.com/127.0.0.1#5335
80 | server=/ip.kugou.com/127.0.0.1#5335
81 | server=/client.api.ttpod.com/127.0.0.1#5335
82 | server=/mobi.kuwo.cn/127.0.0.1#5335
83 | server=/mobilefeedback.kugou.com/127.0.0.1#5335
84 | server=/tingapi.ting.baidu.com/127.0.0.1#5335
85 | server=/music.baidu.com/127.0.0.1#5335
86 | server=/serviceinfo.sdk.duomi.com/127.0.0.1#5335
87 | server=/music.163.com/127.0.0.1#5335
88 | server=/www.xiami.com/127.0.0.1#5335
89 | server=/spark.api.xiami.com/127.0.0.1#5335
90 | server=/iplocation.geo.qiyi.com/127.0.0.1#5335
91 | server=/sns.video.qq.com/127.0.0.1#5335
92 | server=/v5.pc.duomi.com/127.0.0.1#5335
93 | server=/tms.is.ysten.com/127.0.0.1#5335
94 | server=/internal.check.duokanbox.com/127.0.0.1#5335
95 | server=/openapi.youku.com/127.0.0.1#5335
96 | server=/y.qq.com/127.0.0.1#5335
97 | ipset=/v.youku.com/oversea
98 | ipset=/api.youku.com/oversea
99 | ipset=/v2.tudou.com/oversea
100 | ipset=/www.tudou.com/oversea
101 | ipset=/s.plcloud.music.qq.com/oversea
102 | ipset=/i.y.qq.com/oversea
103 | ipset=/hot.vrs.sohu.com/oversea
104 | ipset=/live.tv.sohu.com/oversea
105 | ipset=/pad.tv.sohu.com/oversea
106 | ipset=/my.tv.sohu.com/oversea
107 | ipset=/hot.vrs.letv.com/oversea
108 | ipset=/data.video.qiyi.com/oversea
109 | ipset=/cache.video.qiyi.com/oversea
110 | ipset=/cache.vip.qiyi.com/oversea
111 | ipset=/vv.video.qq.com/oversea
112 | ipset=/tt.video.qq.com/oversea
113 | ipset=/ice.video.qq.com/oversea
114 | ipset=/tjsa.video.qq.com/oversea
115 | ipset=/a10.video.qq.com/oversea
116 | ipset=/xyy.video.qq.com/oversea
117 | ipset=/vcq.video.qq.com/oversea
118 | ipset=/vsh.video.qq.com/oversea
119 | ipset=/vbj.video.qq.com/oversea
120 | ipset=/bobo.video.qq.com/oversea
121 | ipset=/flvs.video.qq.com/oversea
122 | ipset=/bkvv.video.qq.com/oversea
123 | ipset=/info.zb.qq.com/oversea
124 | ipset=/geo.js.kankan.xunlei.com/oversea
125 | ipset=/web-play.pptv.com/oversea
126 | ipset=/web-play.pplive.cn/oversea
127 | ipset=/dyn.ugc.pps.tv/oversea
128 | ipset=/v.pps.tv/oversea
129 | ipset=/inner.kandian.com/oversea
130 | ipset=/ipservice.163.com/oversea
131 | ipset=/so.open.163.com/oversea
132 | ipset=/zb.s.qq.com/oversea
133 | ipset=/ip.kankan.xunlei.com/oversea
134 | ipset=/vxml.56.com/oversea
135 | ipset=/music.sina.com.cn/oversea
136 | ipset=/play.baidu.com/oversea
137 | ipset=/v.iask.com/oversea
138 | ipset=/tv.weibo.com/oversea
139 | ipset=/wtv.v.iask.com/oversea
140 | ipset=/video.sina.com.cn/oversea
141 | ipset=/www.yinyuetai.com/oversea
142 | ipset=/api.letv.com/oversea
143 | ipset=/live.gslb.letv.com/oversea
144 | ipset=/static.itv.letv.com/oversea
145 | ipset=/ip.apps.cntv.cn/oversea
146 | ipset=/vdn.apps.cntv.cn/oversea
147 | ipset=/vdn.live.cntv.cn/oversea
148 | ipset=/vip.sports.cntv.cn/oversea
149 | ipset=/a.play.api.3g.youku.com/oversea
150 | ipset=/i.play.api.3g.youku.com/oversea
151 | ipset=/api.3g.youku.com/oversea
152 | ipset=/tv.api.3g.youku.com/oversea
153 | ipset=/play.api.3g.youku.com/oversea
154 | ipset=/play.api.3g.tudou.com/oversea
155 | ipset=/tv.api.3g.tudou.com/oversea
156 | ipset=/api.3g.tudou.com/oversea
157 | ipset=/api.tv.sohu.com/oversea
158 | ipset=/access.tv.sohu.com/oversea
159 | ipset=/iface.iqiyi.com/oversea
160 | ipset=/iface2.iqiyi.com/oversea
161 | ipset=/cache.m.iqiyi.com/oversea
162 | ipset=/dynamic.app.m.letv.com/oversea
163 | ipset=/dynamic.meizi.app.m.letv.com/oversea
164 | ipset=/dynamic.search.app.m.letv.com/oversea
165 | ipset=/dynamic.live.app.m.letv.com/oversea
166 | ipset=/listso.m.areainfo.ppstream.com/oversea
167 | ipset=/epg.api.pptv.com/oversea
168 | ipset=/play.api.pptv.com/oversea
169 | ipset=/m.letv.com/oversea
170 | ipset=/interface.bilibili.com/oversea
171 | ipset=/3g.music.qq.com/oversea
172 | ipset=/mqqplayer.3g.qq.com/oversea
173 | ipset=/proxy.music.qq.com/oversea
174 | ipset=/proxymc.qq.com/oversea
175 | ipset=/ip2.kugou.com/oversea
176 | ipset=/ip.kugou.com/oversea
177 | ipset=/client.api.ttpod.com/oversea
178 | ipset=/mobi.kuwo.cn/oversea
179 | ipset=/mobilefeedback.kugou.com/oversea
180 | ipset=/tingapi.ting.baidu.com/oversea
181 | ipset=/music.baidu.com/oversea
182 | ipset=/serviceinfo.sdk.duomi.com/oversea
183 | ipset=/music.163.com/oversea
184 | ipset=/www.xiami.com/oversea
185 | ipset=/spark.api.xiami.com/oversea
186 | ipset=/iplocation.geo.qiyi.com/oversea
187 | ipset=/sns.video.qq.com/oversea
188 | ipset=/v5.pc.duomi.com/oversea
189 | ipset=/tms.is.ysten.com/oversea
190 | ipset=/internal.check.duokanbox.com/oversea
191 | ipset=/openapi.youku.com/oversea
192 | ipset=/y.qq.com/oversea
193 |
--------------------------------------------------------------------------------
/po/zh-cn/ssr-plus.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr "Content-Type: text/plain; charset=UTF-8\n"
3 |
4 | msgid "ShadowSocksR Client"
5 | msgstr "ShadowSocksR 客户端"
6 |
7 | msgid "Enable"
8 | msgstr "启用"
9 |
10 | msgid "Disable"
11 | msgstr "停用"
12 |
13 | msgid "Log"
14 | msgstr "日志"
15 |
16 | msgid "ShadowSocksR is running"
17 | msgstr "ShadowSocksR 客户端运行中"
18 |
19 | msgid "ShadowSocksR is not running"
20 | msgstr "ShadowSocksR 客户端未运行"
21 |
22 | msgid "Global Setting"
23 | msgstr "全局设置"
24 |
25 | msgid "Global Server"
26 | msgstr "全局服务器"
27 |
28 | msgid "ShadowSocksR SOCK5 Proxy is running"
29 | msgstr "ShadowSocksR SOCK5代理运行中"
30 |
31 | msgid "UDP Relay Server"
32 | msgstr "UDP中继服务器"
33 |
34 | msgid "Same as Global Server"
35 | msgstr "与全局服务器相同"
36 |
37 | msgid "Servers Setting"
38 | msgstr "服务器配置"
39 |
40 | msgid "Alias(optional)"
41 | msgstr "别名(可选)"
42 |
43 | msgid "Onetime Authentication"
44 | msgstr "一次验证"
45 |
46 | msgid "Server Address"
47 | msgstr "服务器地址"
48 |
49 | msgid "Server Port"
50 | msgstr "服务器端口"
51 |
52 | msgid "Local Port"
53 | msgstr "本地端口"
54 |
55 | msgid "Connection Timeout"
56 | msgstr "连接超时"
57 |
58 | msgid "Password"
59 | msgstr "密码"
60 |
61 | msgid "Encrypt Method"
62 | msgstr "加密方式"
63 |
64 | msgid "Protocol"
65 | msgstr "传输协议"
66 |
67 | msgid "Protocol param(optional)"
68 | msgstr "传输协议参数(可选)"
69 |
70 | msgid "Obfs"
71 | msgstr "混淆插件"
72 |
73 | msgid "Obfs param(optional)"
74 | msgstr "混淆参数(可选)"
75 |
76 | msgid "Enable Tunnel(DNS)"
77 | msgstr "启用隧道(DNS)转发"
78 |
79 | msgid "Tunnel Port"
80 | msgstr "隧道(DNS)本地端口"
81 |
82 | msgid "Forwarding Tunnel"
83 | msgstr "隧道(DNS)转发地址"
84 |
85 | msgid "Access Control"
86 | msgstr "访问控制"
87 |
88 | msgid "Interfaces - WAN"
89 | msgstr "接口 - WAN"
90 |
91 | msgid "Bypassed IP List"
92 | msgstr "被忽略IP列表"
93 |
94 | msgid "NULL - As Global Proxy"
95 | msgstr "留空 - 作为全局代理"
96 |
97 | msgid "Bypassed IP"
98 | msgstr "额外被忽略IP"
99 |
100 | msgid "Forwarded IP"
101 | msgstr "强制走代理IP"
102 |
103 | msgid "Interfaces - LAN"
104 | msgstr "接口 - LAN"
105 |
106 | msgid "LAN Access Control"
107 | msgstr "内网访问控制"
108 |
109 | msgid "Allow listed only"
110 | msgstr "仅允许列表内"
111 |
112 | msgid "Allow all except listed"
113 | msgstr "仅允许列表外"
114 |
115 | msgid "LAN Host List"
116 | msgstr "内网主机列表"
117 |
118 | msgid "SSR Client"
119 | msgstr "客户端"
120 |
121 | msgid "SSR Server"
122 | msgstr "服务端"
123 |
124 | msgid "ShadowSocksR Server"
125 | msgstr "ShadowSocksR 服务端"
126 |
127 | msgid "ShadowSocksR Server is running"
128 | msgstr "ShadowSocksR 服务端运行中"
129 |
130 | msgid "ShadowSocksR Server is not running"
131 | msgstr "ShadowSocksR 服务端未运行"
132 |
133 | msgid "Enable Server"
134 | msgstr "启动服务端"
135 |
136 | msgid "Server Setting"
137 | msgstr "服务端配置"
138 |
139 | msgid "KcpTun Enable"
140 | msgstr "KcpTun 启用"
141 |
142 | msgid "bin:/usr/bin/kcptun-client"
143 | msgstr "二进制文件:/usr/bin/kcptun-client"
144 |
145 | msgid "KcpTun Port"
146 | msgstr "KcpTun 端口"
147 |
148 | msgid "KcpTun Param"
149 | msgstr "KcpTun 参数"
150 |
151 | msgid "KcpTun Password"
152 | msgstr "KcpTun 密码"
153 |
154 | msgid "Haven't a Kcptun executable file"
155 | msgstr "不存在Kcptun可执行文件,请下载Kcptun可执行文件并改名放入/usr/bin/kcptun-client"
156 |
157 | msgid "Not a Kcptun executable file"
158 | msgstr "Kcptun可执行文件格式不正确,请确认是否正确下载了路由器对应的可执行文件"
159 |
160 | msgid "Enable Process Monitor"
161 | msgstr "启用进程监控"
162 |
163 | msgid "Edit ShadowSocksR Server"
164 | msgstr "编辑服务器配置"
165 |
166 | msgid "Alias"
167 | msgstr "别名"
168 |
169 | msgid "SOCKS5 Proxy"
170 | msgstr "SOCKS5代理"
171 |
172 | msgid "Server"
173 | msgstr "服务器"
174 |
175 | msgid "TCP Fast Open"
176 | msgstr "TCP快速打开"
177 |
178 | msgid "Status"
179 | msgstr "状态"
180 |
181 | msgid "Unknown"
182 | msgstr "未知"
183 |
184 | msgid "Running Status"
185 | msgstr "运行状态"
186 |
187 | msgid "Global Client"
188 | msgstr "TCP透明代理"
189 |
190 | msgid "Global SSR Server"
191 | msgstr "SSR服务端"
192 |
193 | msgid "DNS Tunnel"
194 | msgstr "DNS 隧道"
195 |
196 | msgid "IPK Version"
197 | msgstr "IPK 版本号"
198 |
199 | msgid "KcpTun Version"
200 | msgstr "KcpTun 版本号"
201 |
202 | msgid "Not exist"
203 | msgstr "未安装可执行文件"
204 |
205 | msgid "IPK Installation Time"
206 | msgstr "IPK 安装时间"
207 |
208 | msgid "Project"
209 | msgstr "项目地址"
210 |
211 | msgid "Not Running"
212 | msgstr "未运行"
213 |
214 | msgid "Running"
215 | msgstr "运行中"
216 |
217 | msgid "Enable GFW mode"
218 | msgstr "启用 GFW 模式"
219 |
220 | msgid "Running Mode"
221 | msgstr "运行模式"
222 |
223 | msgid "IP Route Mode"
224 | msgstr "绕过中国大陆IP模式"
225 |
226 | msgid "GFW List Mode"
227 | msgstr "GFW列表模式"
228 |
229 | msgid "Global Mode"
230 | msgstr "全局模式"
231 |
232 | msgid "Oversea Mode"
233 | msgstr "海外用户回国模式"
234 |
235 | msgid "Router Proxy"
236 | msgstr "路由器访问控制"
237 |
238 | msgid "Normal Proxy"
239 | msgstr "正常代理"
240 |
241 | msgid "Bypassed Proxy"
242 | msgstr "不走代理"
243 |
244 | msgid "Forwarded Proxy"
245 | msgstr "强制走代理"
246 |
247 | msgid "UDP Relay"
248 | msgstr "UDP中继"
249 |
250 | msgid "Google Connectivity"
251 | msgstr "【谷歌】连通性检查"
252 |
253 | msgid "Baidu Connectivity"
254 | msgstr "【百度】连通性检查"
255 |
256 | msgid "No Check"
257 | msgstr "未检查"
258 |
259 | msgid "Check"
260 | msgstr "检查"
261 |
262 | msgid "Connect OK"
263 | msgstr "连接正常"
264 |
265 | msgid "Connect Error"
266 | msgstr "连接错误"
267 |
268 | msgid "Check..."
269 | msgstr "正在检查.."
270 |
271 | msgid "Proxy Check"
272 | msgstr "代理检查"
273 |
274 |
275 | msgid "GFW List Data"
276 | msgstr "【GFW列表】数据库"
277 |
278 | msgid "China IP Data"
279 | msgstr "【国内IP段】数据库"
280 |
281 | msgid "Records"
282 | msgstr "条记录"
283 |
284 | msgid "Refresh Data"
285 | msgstr "更新数据库"
286 |
287 | msgid "Refresh..."
288 | msgstr "正在更新,请稍候.."
289 |
290 | msgid "Refresh OK!"
291 | msgstr "更新成功!"
292 |
293 | msgid "Refresh Error!"
294 | msgstr "更新失败!"
295 |
296 | msgid "No new data!"
297 | msgstr "你已经是最新数据,无需更新!"
298 |
299 | msgid "Total Records:"
300 | msgstr "新的总纪录数:"
301 |
302 | msgid "Check Server Port"
303 | msgstr "【服务器端口】检查"
304 |
305 | msgid "Check Connect"
306 | msgstr "检查连通性"
307 |
308 | msgid "Check Server"
309 | msgstr "检查服务器"
310 |
311 | msgid "Auto Switch"
312 | msgstr "自动切换"
313 |
314 | msgid "Enable Auto Switch"
315 | msgstr "启用自动切换"
316 |
317 | msgid "Switch check cycly(second)"
318 | msgstr "自动切换检查周期(秒)"
319 |
320 | msgid "Check timout(second)"
321 | msgstr "切换检查超时时间(秒)"
322 |
323 | msgid "Enable Process Deamon"
324 | msgstr "启用进程自动守护"
325 |
326 | msgid "Advertising Data"
327 | msgstr "【广告屏蔽】数据库"
328 |
329 | msgid "DNS Server IP and Port"
330 | msgstr "DNS服务器地址和端口"
331 |
332 | msgid "Resolve Dns Mode"
333 | msgstr "DNS解析方式"
334 |
335 | msgid "Use SSR DNS Tunnel"
336 | msgstr "使用SSR-DNS隧道"
337 |
338 | msgid "Use Pdnsd"
339 | msgstr "使用Pdnsd"
340 |
341 | msgid "Use Other DNS Tunnel(Need to install)"
342 | msgstr "使用其他DNS转发(需要自己安装)"
343 |
344 | msgid "Import SSR"
345 | msgstr "导入ssr配置信息"
346 |
347 | msgid "Export SSR"
348 | msgstr "导出ssr配置信息"
349 |
350 | msgid "Import SSR successfully."
351 | msgstr "成功导入SSR。"
352 |
353 | msgid "Invalid SSR format."
354 | msgstr "无效的SSR格式。"
355 |
356 | msgid "User cancelled."
357 | msgstr "用户已取消。"
358 |
359 | msgid "Paste ssr url here"
360 | msgstr "在此处粘贴ssr://网址"
361 |
362 | msgid "Unable to copy SSR to clipboard."
363 | msgstr "无法复制SSR网址到剪贴板。"
364 |
365 | msgid "Copy SSR to clipboard successfully."
366 | msgstr "成功复制SSR网址到剪贴板。"
367 |
368 | msgid "Servers Manage"
369 | msgstr "服务器管理"
370 |
371 | msgid "Auto Update"
372 | msgstr "自动更新"
373 |
374 | msgid "Through proxy update"
375 | msgstr "通过代理更新"
376 |
377 | msgid "GFW List"
378 | msgstr "GFW列表"
379 |
380 | msgid "ShadowSocksR Plus+ Settings"
381 | msgstr "ShadowSocksR Plus+ 设置(支持SS/SSR/V2RAY)"
382 |
383 | msgid "Main Server"
384 | msgstr "主服务器"
385 |
386 | msgid "Anti-pollution DNS Server"
387 | msgstr "访问国外域名DNS服务器"
388 |
389 | msgid "Use Pdnsd tcp query and cache"
390 | msgstr "使用PDNSD TCP查询并缓存"
391 |
392 | msgid "DNS Server IP:Port"
393 | msgstr "DNS服务器 IP:Port"
394 |
395 | msgid "Update time (every day)"
396 | msgstr "更新时间 (每天)"
397 |
398 | msgid "Auto Update Server subscription, GFW list and CHN route"
399 | msgstr "自动更新服务器订阅、GFW列表和 CHN路由表"
400 |
401 | msgid "Subscribe URL"
402 | msgstr "SSR/V2RAY订阅URL地址"
403 |
404 | msgid "Update"
405 | msgstr "更新"
406 |
407 | msgid "Server Count"
408 | msgstr "服务器节点数量"
409 |
410 | msgid "IP black-and-white list"
411 | msgstr "IP黑白名单"
412 |
413 | msgid "WAN IP AC"
414 | msgstr "WAN IP访问控制"
415 |
416 | msgid "WAN White List IP"
417 | msgstr "不走代理的WAN IP"
418 |
419 | msgid "WAN Force Proxy IP"
420 | msgstr "强制走代理的WAN IP"
421 |
422 | msgid "LAN Bypassed Host List"
423 | msgstr "不走代理的局域网LAN IP"
424 |
425 | msgid "LAN Force Proxy Host List"
426 | msgstr "全局代理的LAN IP"
427 |
428 | msgid "Router Self AC"
429 | msgstr "路由器自身代理设置"
430 |
431 | msgid "Router Self Proxy"
432 | msgstr "路由器自身代理方式"
433 |
434 | msgid "Normal Proxy"
435 | msgstr "跟随全局设置"
436 |
437 | msgid "Bypassed Proxy"
438 | msgstr "不走代理"
439 |
440 | msgid "Forwarded Proxy"
441 | msgstr "全局代理"
442 |
443 | msgid "GFW Custom List"
444 | msgstr "GFW 用户自定义列表"
445 |
446 | msgid "Please refer to the following writing"
447 | msgstr "每行一个域名,无需写前面的 HTTP(S):// ,提交后即时生效"
448 |
449 | msgid "Servers subscription and manage"
450 | msgstr "服务器节点订阅与管理(支持订阅和手动导入SSR链接)"
451 |
452 | msgid "Through proxy update list, Not Recommended"
453 | msgstr "通过路由器自身代理更新订阅(不推荐)"
454 |
455 | msgid "LAN IP AC"
456 | msgstr "LAN IP访问控制"
457 |
458 | msgid "Game Mode UDP Server"
459 | msgstr "游戏模式UDP中继服务器"
460 |
461 | msgid "Game Mode UDP Relay"
462 | msgstr "游戏模式UDP中继"
463 |
464 | msgid "Server failsafe auto swith settings"
465 | msgstr "服务器节点故障自动切换设置"
466 |
467 | msgid "Delete all severs"
468 | msgstr "删除所有服务器"
469 |
470 | msgid "Severs Nodes"
471 | msgstr "服务器节点"
472 |
473 | msgid "Use Local DNS Service listen port 5335"
474 | msgstr "使用本机端口为5335的DNS服务"
475 |
476 | msgid "Server Node Type"
477 | msgstr "服务器节点类型"
478 |
479 | msgid "Using incorrect encryption mothod may causes service fail to start"
480 | msgstr "输入不正确的参数组合可能会导致服务无法启动"
481 |
482 | msgid "Game Mode Host List"
483 | msgstr "增强游戏模式客户端LAN IP"
484 |
485 | msgid "Multi Threads Option"
486 | msgstr "多线程并发转发"
487 |
488 | msgid "Auto Threads"
489 | msgstr "自动(CPU线程数)"
490 |
491 | msgid "1 Thread"
492 | msgstr "单线程"
493 |
494 | msgid "2 Threads"
495 | msgstr "2 线程"
496 |
497 | msgid "4 Threads"
498 | msgstr "4 线程"
499 |
500 | msgid "8 Threads"
501 | msgstr "8 线程"
502 |
--------------------------------------------------------------------------------
/root/usr/bin/ssr-rules:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright (C) 2017 openwrt-ssr
4 | # Copyright (C) 2017 yushi studio
5 | #
6 | # This is free software, licensed under the GNU General Public License v3.
7 | # See /LICENSE for more information.
8 | #
9 |
10 | TAG="_SS_SPEC_RULE_" # comment tag
11 | IPT="iptables -t nat" # alias of iptables
12 | FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file
13 |
14 | usage() {
15 | cat <<-EOF
16 | Usage: ssr-rules [options]
17 |
18 | Valid options are:
19 |
20 | -s ip address of shadowsocksr remote server
21 | -l port number of shadowsocksr local server
22 | -S ip address of shadowsocksr remote UDP server
23 | -L port number of shadowsocksr local UDP server
24 | -i a file content is bypassed ip list
25 | -a lan ip of access control, need a prefix to
26 | define access control mode
27 | -b wan ip of will be bypassed
28 | -w wan ip of will be forwarded
29 | -p lan ip of will be global proxy
30 | -G lan ip of will be game mode proxy
31 | -e extra options for iptables
32 | -o apply the rules to the OUTPUT chain
33 | -O apply the global rules to the OUTPUT chain
34 | -u enable udprelay mode, TPROXY is required
35 | -U enable udprelay mode, using different IP
36 | and ports for TCP and UDP
37 | -f flush the rules
38 | -g gfw list mode
39 | -r return china mode
40 | -h show this help message and exit
41 | EOF
42 | exit $1
43 | }
44 |
45 | loger() {
46 | # 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug
47 | logger -st ssr-rules[$$] -p$1 $2
48 | }
49 |
50 | flush_r() {
51 | flush_iptables() {
52 | local ipt="iptables -t $1"
53 | local DAT=$(iptables-save -t $1)
54 | eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/')
55 | for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do
56 | $ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1}
57 | done
58 | }
59 | flush_iptables nat
60 | flush_iptables mangle
61 | ip rule del fwmark 0x01/0x01 table 100 2>/dev/null
62 | ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
63 | ipset -X ss_spec_lan_ac 2>/dev/null
64 | ipset -X ss_spec_wan_ac 2>/dev/null
65 | ipset -X ssr_gen_router 2>/dev/null
66 | ipset -X fplan 2>/dev/null
67 | ipset -X gmlan 2>/dev/null
68 | ipset -X oversea 2>/dev/null
69 | [ -n "$FWI" ] && echo '#!/bin/sh' >$FWI
70 | return 0
71 | }
72 |
73 | ipset_r() {
74 | if [ "$RUNMODE" = "router" ] ;then
75 | ipset -! -R <<-EOF || return 1
76 | create ss_spec_wan_ac hash:net
77 | $(gen_iplist | sed -e "s/^/add ss_spec_wan_ac /")
78 | $(for ip in $WAN_FW_IP; do echo "add ss_spec_wan_ac $ip nomatch"; done)
79 | EOF
80 | ipset -N gfwlist hash:net 2>/dev/null
81 | $IPT -N SS_SPEC_WAN_AC
82 | $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
83 | $IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN
84 | $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
85 |
86 | elif [ "$RUNMODE" = "gfw" ] ;then
87 | ipset -N gfwlist hash:net 2>/dev/null
88 | for ip in $WAN_FW_IP; do ipset -! add gfwlist $ip ; done
89 | $IPT -N SS_SPEC_WAN_AC
90 | $IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW
91 | ipset -N gmlan hash:net 2>/dev/null
92 | for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done
93 | $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
94 | $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
95 |
96 | elif [ "$RUNMODE" = "oversea" ] ;then
97 | ipset -N oversea hash:net 2>/dev/null
98 | $IPT -N SS_SPEC_WAN_AC
99 | ipset -N gmlan hash:net 2>/dev/null
100 | for ip in $LAN_GM_IP; do ipset -! add gmlan $ip ; done
101 | $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW
102 | $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
103 |
104 | elif [ "$RUNMODE" = "all" ] ;then
105 | $IPT -N SS_SPEC_WAN_AC
106 | $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
107 | $IPT -I SS_SPEC_WAN_AC -d $server -j RETURN
108 |
109 | fi
110 |
111 | ipset -N fplan hash:net 2>/dev/null
112 | for ip in $LAN_FP_IP; do ipset -! add fplan $ip ; done
113 | $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW
114 |
115 | return $?
116 | }
117 |
118 | fw_rule() {
119 | $IPT -N SS_SPEC_WAN_FW
120 | $IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN
121 | $IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN
122 | $IPT -A SS_SPEC_WAN_FW -d 127.0.0.0/8 -j RETURN
123 | $IPT -A SS_SPEC_WAN_FW -d 169.254.0.0/16 -j RETURN
124 | $IPT -A SS_SPEC_WAN_FW -d 172.16.0.0/12 -j RETURN
125 | $IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN
126 | $IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN
127 | $IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN
128 | $IPT -A SS_SPEC_WAN_FW -p tcp \
129 | -j REDIRECT --to-ports $local_port 2>/dev/null || {
130 | loger 3 "Can't redirect, please check the iptables."
131 | exit 1
132 | }
133 | return $?
134 | }
135 |
136 | ac_rule() {
137 | if [ -n "$LAN_AC_IP" ]; then
138 | case "${LAN_AC_IP:0:1}" in
139 | w|W)
140 | MATCH_SET="-m set --match-set ss_spec_lan_ac src"
141 | ;;
142 | b|B)
143 | MATCH_SET="-m set ! --match-set ss_spec_lan_ac src"
144 | ;;
145 | *)
146 | loger 3 "Bad argument \`-a $LAN_AC_IP\`."
147 | return 2
148 | ;;
149 | esac
150 | fi
151 | IFNAME=$(uci get -P/var/state network.lan.ifname 2>/dev/null)
152 | ipset -! -R <<-EOF || return 1
153 | create ss_spec_lan_ac hash:net
154 | $(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done)
155 | EOF
156 | $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET \
157 | -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
158 | if [ "$OUTPUT" = 1 ]; then
159 | $IPT -I OUTPUT 1 -p tcp $EXT_ARGS \
160 | -m comment --comment "$TAG" -j SS_SPEC_WAN_AC
161 | elif [ "$OUTPUT" = 2 ]; then
162 | ipset -! -R <<-EOF || return 1
163 | create ssr_gen_router hash:net
164 | $(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
165 | EOF
166 | $IPT -N SS_SPEC_ROUTER && \
167 | $IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
168 | $IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
169 | $IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
170 | fi
171 | return $?
172 | }
173 |
174 | tp_rule() {
175 | [ -n "$TPROXY" ] || return 0
176 | ip rule add fwmark 0x01/0x01 table 100
177 | ip route add local 0.0.0.0/0 dev lo table 100
178 | local ipt="iptables -t mangle"
179 | $ipt -N SS_SPEC_TPROXY
180 | $ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN
181 | $ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN
182 | $ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN
183 | $ipt -A SS_SPEC_TPROXY -p udp -d 127.0.0.0/8 -j RETURN
184 | $ipt -A SS_SPEC_TPROXY -p udp -d 169.254.0.0/16 -j RETURN
185 | $ipt -A SS_SPEC_TPROXY -p udp -d 172.16.0.0/12 -j RETURN
186 | $ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN
187 | $ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN
188 | $ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN
189 | $ipt -A SS_SPEC_TPROXY -p udp -d $SERVER -j RETURN
190 |
191 | $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set fplan src \
192 | -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
193 |
194 | if [ "$RUNMODE" = "router" ] ;then
195 | $ipt -A SS_SPEC_TPROXY -p udp -m set ! --match-set ss_spec_wan_ac dst \
196 | -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
197 |
198 | elif [ "$RUNMODE" = "gfw" ] ;then
199 | $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst \
200 | -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
201 | $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gfwlist dst \
202 | -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
203 |
204 | elif [ "$RUNMODE" = "oversea" ] ;then
205 | $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst \
206 | -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
207 |
208 | elif [ "$RUNMODE" = "all" ] ;then
209 | $ipt -A SS_SPEC_TPROXY -p udp -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01
210 | fi
211 |
212 | $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET \
213 | -m comment --comment "$TAG" -j SS_SPEC_TPROXY
214 |
215 | return $?
216 | }
217 |
218 | get_wan_ip() {
219 | cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}"
220 | $server
221 | $SERVER
222 | $WAN_BP_IP
223 | EOF
224 | }
225 |
226 | gen_iplist() {
227 | cat <<-EOF
228 | 0.0.0.0/8
229 | 10.0.0.0/8
230 | 100.64.0.0/10
231 | 127.0.0.0/8
232 | 169.254.0.0/16
233 | 172.16.0.0/12
234 | 192.0.0.0/24
235 | 192.0.2.0/24
236 | 192.88.99.0/24
237 | 192.168.0.0/16
238 | 198.18.0.0/15
239 | 198.51.100.0/24
240 | 203.0.113.0/24
241 | 224.0.0.0/4
242 | 240.0.0.0/4
243 | 255.255.255.255
244 | $(get_wan_ip)
245 | $(cat ${IGNORE_LIST:=/dev/null} 2>/dev/null)
246 | EOF
247 | }
248 |
249 | gen_spec_iplist() {
250 | cat <<-EOF
251 | 0.0.0.0/8
252 | 10.0.0.0/8
253 | 100.64.0.0/10
254 | 127.0.0.0/8
255 | 169.254.0.0/16
256 | 172.16.0.0/12
257 | 192.0.0.0/24
258 | 192.0.2.0/24
259 | 192.88.99.0/24
260 | 192.168.0.0/16
261 | 198.18.0.0/15
262 | 198.51.100.0/24
263 | 203.0.113.0/24
264 | 224.0.0.0/4
265 | 240.0.0.0/4
266 | 255.255.255.255
267 | $(get_wan_ip)
268 | EOF
269 | }
270 |
271 | gen_include() {
272 | [ -n "$FWI" ] || return 0
273 | extract_rules() {
274 | echo "*$1"
275 | iptables-save -t $1 | grep SS_SPEC_ |\
276 | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/"
277 | echo 'COMMIT'
278 | }
279 | cat <<-EOF >>$FWI
280 | iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c
281 | iptables-restore -n <<-EOT
282 | $(extract_rules nat)
283 | $(extract_rules mangle)
284 | EOT
285 | EOF
286 | return 0
287 | }
288 |
289 | while getopts ":s:l:S:L:i:e:a:b:w:p:G:oOuUfgrczh" arg; do
290 | case "$arg" in
291 | s)
292 | server=$OPTARG
293 | ;;
294 | l)
295 | local_port=$OPTARG
296 | ;;
297 | S)
298 | SERVER=$OPTARG
299 | ;;
300 | L)
301 | LOCAL_PORT=$OPTARG
302 | ;;
303 | i)
304 | IGNORE_LIST=$OPTARG
305 | ;;
306 | e)
307 | EXT_ARGS=$OPTARG
308 | ;;
309 | a)
310 | LAN_AC_IP=$OPTARG
311 | ;;
312 | b)
313 | WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done)
314 | ;;
315 | w)
316 | WAN_FW_IP=$OPTARG
317 | ;;
318 | p)
319 | LAN_FP_IP=$OPTARG
320 | ;;
321 | G)
322 | LAN_GM_IP=$OPTARG
323 | ;;
324 | o)
325 | OUTPUT=1
326 | ;;
327 | O)
328 | OUTPUT=2
329 | ;;
330 | u)
331 | TPROXY=1
332 | ;;
333 | U)
334 | TPROXY=2
335 | ;;
336 | g)
337 | RUNMODE=gfw
338 | ;;
339 | r)
340 | RUNMODE=router
341 | ;;
342 | c)
343 | RUNMODE=oversea
344 | ;;
345 | z)
346 | RUNMODE=all
347 | ;;
348 | f)
349 | flush_r
350 | exit 0
351 | ;;
352 | h)
353 | usage 0
354 | ;;
355 | esac
356 | done
357 |
358 | if [ -z "$server" -o -z "$local_port" ]; then
359 | usage 2
360 | fi
361 |
362 | if [ "$TPROXY" = 1 ]; then
363 | SERVER=$server
364 | LOCAL_PORT=$local_port
365 | elif [ "$TPROXY" = 2 ]; then
366 | : ${SERVER:?"You must assign an ip for the udp relay server."}
367 | : ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
368 | fi
369 |
370 | flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include
371 | [ "$?" = 0 ] || loger 3 "Start failed!"
372 | exit $?
373 |
--------------------------------------------------------------------------------
/luasrc/model/cbi/shadowsocksr/client-config.lua:
--------------------------------------------------------------------------------
1 | -- Copyright (C) 2017 yushi studio github.com/ywb94
2 | -- Licensed to the public under the GNU General Public License v3.
3 |
4 | local m, s, o,kcp_enable
5 | local shadowsocksr = "shadowsocksr"
6 | local uci = luci.model.uci.cursor()
7 | local ipkg = require("luci.model.ipkg")
8 | local fs = require "nixio.fs"
9 | local sys = require "luci.sys"
10 | local sid = arg[1]
11 | local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
12 |
13 | local function isKcptun(file)
14 | if not fs.access(file, "rwx", "rx", "rx") then
15 | fs.chmod(file, 755)
16 | end
17 |
18 | local str = sys.exec(file .. " -v | awk '{printf $1}'")
19 | return (str:lower() == "kcptun")
20 | end
21 |
22 |
23 | local server_table = {}
24 | local encrypt_methods = {
25 | "none",
26 | "table",
27 | "rc4",
28 | "rc4-md5-6",
29 | "rc4-md5",
30 | "aes-128-cfb",
31 | "aes-192-cfb",
32 | "aes-256-cfb",
33 | "aes-128-ctr",
34 | "aes-192-ctr",
35 | "aes-256-ctr",
36 | "bf-cfb",
37 | "camellia-128-cfb",
38 | "camellia-192-cfb",
39 | "camellia-256-cfb",
40 | "cast5-cfb",
41 | "des-cfb",
42 | "idea-cfb",
43 | "rc2-cfb",
44 | "seed-cfb",
45 | "salsa20",
46 | "chacha20",
47 | "chacha20-ietf",
48 | }
49 |
50 | local encrypt_methods_ss = {
51 | -- aead
52 | "aes-128-gcm",
53 | "aes-192-gcm",
54 | "aes-256-gcm",
55 | "chacha20-ietf-poly1305",
56 | "xchacha20-ietf-poly1305",
57 | -- stream
58 | "table",
59 | "rc4",
60 | "rc4-md5",
61 | "aes-128-cfb",
62 | "aes-192-cfb",
63 | "aes-256-cfb",
64 | "aes-128-ctr",
65 | "aes-192-ctr",
66 | "aes-256-ctr",
67 | "bf-cfb",
68 | "camellia-128-cfb",
69 | "camellia-192-cfb",
70 | "camellia-256-cfb",
71 | "salsa20",
72 | "chacha20",
73 | "chacha20-ietf",
74 | }
75 |
76 | local protocol = {
77 | "origin",
78 | "verify_deflate",
79 | "auth_sha1_v4",
80 | "auth_aes128_sha1",
81 | "auth_aes128_md5",
82 | "auth_chain_a",
83 | "auth_chain_b",
84 | "auth_chain_c",
85 | "auth_chain_d",
86 | "auth_chain_e",
87 | "auth_chain_f",
88 | }
89 |
90 | obfs = {
91 | "plain",
92 | "http_simple",
93 | "http_post",
94 | "random_head",
95 | "tls1.2_ticket_auth",
96 | }
97 |
98 | local securitys = {
99 | "auto",
100 | "none",
101 | "aes-128-gcm",
102 | "chacha20-poly1305"
103 | }
104 |
105 |
106 | m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
107 | m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
108 | if m.uci:get(shadowsocksr, sid) ~= "servers" then
109 | luci.http.redirect(m.redirect)
110 | return
111 | end
112 |
113 | -- [[ Servers Setting ]]--
114 | s = m:section(NamedSection, sid, "servers")
115 | s.anonymous = true
116 | s.addremove = false
117 |
118 | o = s:option(DummyValue,"ssr_url","SSR URL")
119 | o.rawhtml = true
120 | o.template = "shadowsocksr/ssrurl"
121 | o.value =sid
122 | o:depends("type", "ssr")
123 |
124 | o = s:option(ListValue, "type", translate("Server Node Type"))
125 | o:value("ssr", translate("ShadowsocksR"))
126 | if nixio.fs.access("/usr/bin/ss-redir") then
127 | o:value("ss", translate("Shadowsocks New Version"))
128 | end
129 | if nixio.fs.access("/usr/bin/v2ray/v2ray") then
130 | o:value("v2ray", translate("V2Ray"))
131 | end
132 | o.description = translate("Using incorrect encryption mothod may causes service fail to start")
133 |
134 | o = s:option(Value, "alias", translate("Alias(optional)"))
135 |
136 | o = s:option(Value, "server", translate("Server Address"))
137 | o.datatype = "host"
138 | o.rmempty = false
139 |
140 | o = s:option(Value, "server_port", translate("Server Port"))
141 | o.datatype = "port"
142 | o.rmempty = false
143 |
144 | -- o = s:option(Value, "timeout", translate("Connection Timeout"))
145 | -- o.datatype = "uinteger"
146 | -- o.default = 60
147 | -- o.rmempty = false
148 |
149 | o = s:option(Value, "password", translate("Password"))
150 | o.password = true
151 | o.rmempty = true
152 | o:depends("type", "ssr")
153 | o:depends("type", "ss")
154 |
155 | o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
156 | for _, v in ipairs(encrypt_methods) do o:value(v) end
157 | o.rmempty = true
158 | o:depends("type", "ssr")
159 |
160 | o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
161 | for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
162 | o.rmempty = true
163 | o:depends("type", "ss")
164 |
165 | o = s:option(ListValue, "protocol", translate("Protocol"))
166 | for _, v in ipairs(protocol) do o:value(v) end
167 | o.rmempty = true
168 | o:depends("type", "ssr")
169 |
170 | o = s:option(Value, "protocol_param", translate("Protocol param(optional)"))
171 | o:depends("type", "ssr")
172 |
173 | o = s:option(ListValue, "obfs", translate("Obfs"))
174 | for _, v in ipairs(obfs) do o:value(v) end
175 | o.rmempty = true
176 | o:depends("type", "ssr")
177 |
178 | o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
179 | o:depends("type", "ssr")
180 |
181 | -- AlterId
182 | o = s:option(Value, "alter_id", translate("AlterId"))
183 | o.datatype = "port"
184 | o.default = 16
185 | o.rmempty = true
186 | o:depends("type", "v2ray")
187 |
188 | -- VmessId
189 | o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
190 | o.rmempty = true
191 | o.default = uuid
192 | o:depends("type", "v2ray")
193 |
194 | -- 加密方式
195 | o = s:option(ListValue, "security", translate("Encrypt Method"))
196 | for _, v in ipairs(securitys) do o:value(v, v:upper()) end
197 | o.rmempty = true
198 | o:depends("type", "v2ray")
199 |
200 | -- 传输协议
201 | o = s:option(ListValue, "transport", translate("Transport"))
202 | o:value("tcp", "TCP")
203 | o:value("kcp", "mKCP")
204 | o:value("ws", "WebSocket")
205 | o:value("h2", "HTTP/2")
206 | o:value("quic", "QUIC")
207 | o.rmempty = true
208 | o:depends("type", "v2ray")
209 |
210 | -- [[ TCP部分 ]]--
211 |
212 | -- TCP伪装
213 | o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
214 | o:depends("transport", "tcp")
215 | o:value("none", translate("None"))
216 | o:value("http", "HTTP")
217 | o.rmempty = true
218 |
219 | -- HTTP域名
220 | o = s:option(DynamicList, "http_host", translate("HTTP Host"))
221 | o:depends("tcp_guise", "http")
222 | o.rmempty = true
223 |
224 | -- HTTP路径
225 | o = s:option(DynamicList, "http_path", translate("HTTP Path"))
226 | o:depends("tcp_guise", "http")
227 | o.rmempty = true
228 |
229 | -- [[ WS部分 ]]--
230 |
231 | -- WS域名
232 | o = s:option(Value, "ws_host", translate("WebSocket Host"))
233 | o:depends("transport", "ws")
234 | o.rmempty = true
235 |
236 | -- WS路径
237 | o = s:option(Value, "ws_path", translate("WebSocket Path"))
238 | o:depends("transport", "ws")
239 | o.rmempty = true
240 |
241 | -- [[ H2部分 ]]--
242 |
243 | -- H2域名
244 | o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
245 | o:depends("transport", "h2")
246 | o.rmempty = true
247 |
248 | -- H2路径
249 | o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
250 | o:depends("transport", "h2")
251 | o.rmempty = true
252 |
253 | -- [[ QUIC部分 ]]--
254 |
255 | o = s:option(ListValue, "quic_security", translate("QUIC Security"))
256 | o:depends("transport", "quic")
257 | o.rmempty = true
258 | o:value("none", translate("None"))
259 | o:value("aes-128-gcm", translate("aes-128-gcm"))
260 | o:value("chacha20-poly1305", translate("chacha20-poly1305"))
261 |
262 | o = s:option(Value, "quic_key", translate("QUIC Key"))
263 | o:depends("transport", "quic")
264 | o.rmempty = true
265 |
266 | o = s:option(ListValue, "quic_guise", translate("Header"))
267 | o:depends("transport", "quic")
268 | o.rmempty = true
269 | o:value("none", translate("None"))
270 | o:value("srtp", translate("VideoCall (SRTP)"))
271 | o:value("utp", translate("BitTorrent (uTP)"))
272 | o:value("wechat-video", translate("WechatVideo"))
273 | o:value("dtls", "DTLS 1.2")
274 | o:value("wireguard", "WireGuard")
275 |
276 | -- [[ mKCP部分 ]]--
277 |
278 | o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
279 | o:depends("transport", "kcp")
280 | o:value("none", translate("None"))
281 | o:value("srtp", translate("VideoCall (SRTP)"))
282 | o:value("utp", translate("BitTorrent (uTP)"))
283 | o:value("wechat-video", translate("WechatVideo"))
284 | o:value("dtls", "DTLS 1.2")
285 | o:value("wireguard", "WireGuard")
286 | o.rmempty = true
287 |
288 | o = s:option(Value, "mtu", translate("MTU"))
289 | o.datatype = "uinteger"
290 | o:depends("transport", "kcp")
291 | o.default = 1350
292 | o.rmempty = true
293 |
294 | o = s:option(Value, "tti", translate("TTI"))
295 | o.datatype = "uinteger"
296 | o:depends("transport", "kcp")
297 | o.default = 50
298 | o.rmempty = true
299 |
300 | o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
301 | o.datatype = "uinteger"
302 | o:depends("transport", "kcp")
303 | o.default = 5
304 | o.rmempty = true
305 |
306 | o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
307 | o.datatype = "uinteger"
308 | o:depends("transport", "kcp")
309 | o.default = 20
310 | o.rmempty = true
311 |
312 | o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
313 | o.datatype = "uinteger"
314 | o:depends("transport", "kcp")
315 | o.default = 2
316 | o.rmempty = true
317 |
318 | o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
319 | o.datatype = "uinteger"
320 | o:depends("transport", "kcp")
321 | o.default = 2
322 | o.rmempty = true
323 |
324 | o = s:option(Flag, "congestion", translate("Congestion"))
325 | o:depends("transport", "kcp")
326 | o.rmempty = true
327 |
328 | -- [[ allowInsecure ]]--
329 | o = s:option(Flag, "insecure", translate("allowInsecure"))
330 | o.rmempty = true
331 | o:depends("type", "v2ray")
332 |
333 | -- [[ TLS ]]--
334 | o = s:option(Flag, "tls", translate("TLS"))
335 | o.rmempty = true
336 | o.default = "0"
337 | o:depends("type", "v2ray")
338 |
339 | -- [[ Mux ]]--
340 | o = s:option(Flag, "mux", translate("Mux"))
341 | o.rmempty = true
342 | o.default = "0"
343 | o:depends("type", "v2ray")
344 |
345 | o = s:option(Value, "concurrency", translate("Concurrency"))
346 | o.datatype = "uinteger"
347 | o.rmempty = true
348 | o.default = "8"
349 | o:depends("mux", "1")
350 |
351 | o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
352 | o.rmempty = true
353 | o.default = "0"
354 | o:depends("type", "ssr")
355 | o:depends("type", "ss")
356 |
357 | o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
358 | o.rmempty = false
359 | o.default = "1"
360 |
361 | o = s:option(Value, "local_port", translate("Local Port"))
362 | o.datatype = "port"
363 | o.default = 1234
364 | o.rmempty = false
365 |
366 | if nixio.fs.access("/usr/bin/kcptun-client") then
367 |
368 | kcp_enable = s:option(Flag, "kcp_enable", translate("KcpTun Enable"), translate("bin:/usr/bin/kcptun-client"))
369 | kcp_enable.rmempty = true
370 | kcp_enable.default = "0"
371 | kcp_enable:depends("type", "ssr")
372 | kcp_enable:depends("type", "ss")
373 |
374 | o = s:option(Value, "kcp_port", translate("KcpTun Port"))
375 | o.datatype = "port"
376 | o.default = 4000
377 | function o.validate(self, value, section)
378 | local kcp_file="/usr/bin/kcptun-client"
379 | local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
380 | if enable == kcp_enable.enabled then
381 | if not fs.access(kcp_file) then
382 | return nil, translate("Haven't a Kcptun executable file")
383 | elseif not isKcptun(kcp_file) then
384 | return nil, translate("Not a Kcptun executable file")
385 | end
386 | end
387 |
388 | return value
389 | end
390 | o:depends("type", "ssr")
391 | o:depends("type", "ss")
392 |
393 | o = s:option(Value, "kcp_password", translate("KcpTun Password"))
394 | o.password = true
395 | o:depends("type", "ssr")
396 | o:depends("type", "ss")
397 |
398 | o = s:option(Value, "kcp_param", translate("KcpTun Param"))
399 | o.default = "--nocomp"
400 | o:depends("type", "ssr")
401 | o:depends("type", "ss")
402 |
403 | end
404 |
405 | return m
406 |
--------------------------------------------------------------------------------
/root/etc/init.d/shadowsocksr:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 | #
3 | # Copyright (C) 2017 openwrt-ssr
4 | # Copyright (C) 2017 yushi studio
5 | # Copyright (C) 2018 lean
6 | #
7 | # This is free software, licensed under the GNU General Public License v3.
8 | # See /LICENSE for more information.
9 | #
10 |
11 | START=90
12 | STOP=15
13 |
14 | SERVICE_DAEMONIZE=1
15 | NAME=shadowsocksr
16 | EXTRA_COMMANDS=rules
17 | CONFIG_FILE=/var/etc/${NAME}.json
18 | CONFIG_UDP_FILE=/var/etc/${NAME}_u.json
19 | CONFIG_SOCK5_FILE=/var/etc/${NAME}_s.json
20 | server_count=0
21 | redir_tcp=0
22 | redir_udp=0
23 | tunnel_enable=0
24 | local_enable=0
25 | kcp_enable_flag=0
26 | kcp_flag=0
27 | pdnsd_enable_flag=0
28 | switch_enable=0
29 | switch_server=$1
30 | MAXFD=32768
31 | CRON_FILE=/etc/crontabs/root
32 | threads=1
33 |
34 | uci_get_by_name() {
35 | local ret=$(uci get $NAME.$1.$2 2>/dev/null)
36 | echo ${ret:=$3}
37 | }
38 |
39 | uci_get_by_type() {
40 | local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
41 | echo ${ret:=$3}
42 | }
43 |
44 | add_cron()
45 | {
46 | sed -i '/ssrplus.log/d' $CRON_FILE
47 | echo '0 1 * * 0 echo "" > /tmp/ssrplus.log' >> $CRON_FILE
48 | [ -n "$(grep -w "/usr/share/shadowsocksr/subscribe.sh" $CRON_FILE)" ] && sed -i '/\/usr\/share\/shadowsocksr\/subscribe.sh/d' $CRON_FILE
49 | [ $(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
50 | [ -z "$(grep -w "/usr/share/shadowsocksr/update.sh" $CRON_FILE)" ] && echo "0 5 * * 0 /usr/share/shadowsocksr/update.sh" >> $CRON_FILE
51 | crontab $CRON_FILE
52 | }
53 |
54 | del_cron()
55 | {
56 | sed -i '/shadowsocksr/d' $CRON_FILE
57 | sed -i '/ssrplus.log/d' $CRON_FILE
58 | /etc/init.d/cron restart
59 | }
60 |
61 | run_mode=$(uci_get_by_type global run_mode)
62 |
63 | gen_config_file() {
64 | local host=$(uci_get_by_name $1 server)
65 | if echo $host|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
66 | hostip=${host}
67 | elif [ "$host" != "${host#*:[0-9a-fA-F]}" ] ;then
68 | hostip=${host}
69 | else
70 | hostip=`ping ${host} -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1`
71 | if echo $hostip|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
72 | hostip=${hostip}
73 | else
74 | hostip=`cat /etc/ssr_ip`
75 | fi
76 | fi
77 | [ $2 = "0" -a $kcp_flag = "1" ] && hostip="127.0.0.1"
78 |
79 | if [ $2 = "0" ] ;then
80 | config_file=$CONFIG_FILE
81 | elif [ $2 = "1" ]; then
82 | config_file=$CONFIG_UDP_FILE
83 | else
84 | config_file=$CONFIG_SOCK5_FILE
85 | fi
86 | if [ $(uci_get_by_name $1 fast_open 0) = "1" ] ;then
87 | fastopen="true";
88 | else
89 | fastopen="false";
90 | fi
91 | local stype=$(uci_get_by_name $1 type)
92 | if [ "$stype" == "ss" ] ;then
93 | cat <<-EOF >$config_file
94 | {
95 | "server": "$hostip",
96 | "server_port": $(uci_get_by_name $1 server_port),
97 | "local_address": "0.0.0.0",
98 | "local_port": $(uci_get_by_name $1 local_port),
99 | "password": "$(uci_get_by_name $1 password)",
100 | "timeout": $(uci_get_by_name $1 timeout 60),
101 | "method": "$(uci_get_by_name $1 encrypt_method_ss)",
102 | "reuse_port": true,
103 | "fast_open": $fastopen
104 | }
105 | EOF
106 | elif [ "$stype" == "ssr" ] ;then
107 | cat <<-EOF >$config_file
108 | {
109 |
110 | "server": "$hostip",
111 | "server_port": $(uci_get_by_name $1 server_port),
112 | "local_address": "0.0.0.0",
113 | "local_port": $(uci_get_by_name $1 local_port),
114 | "password": "$(uci_get_by_name $1 password)",
115 | "timeout": $(uci_get_by_name $1 timeout 60),
116 | "method": "$(uci_get_by_name $1 encrypt_method)",
117 | "protocol": "$(uci_get_by_name $1 protocol)",
118 | "protocol_param": "$(uci_get_by_name $1 protocol_param)",
119 | "obfs": "$(uci_get_by_name $1 obfs)",
120 | "obfs_param": "$(uci_get_by_name $1 obfs_param)",
121 | "reuse_port": true,
122 | "fast_open": $fastopen
123 | }
124 | EOF
125 | elif [ "$stype" == "v2ray" ] ;then
126 | lua /usr/share/shadowsocksr/genv2config.lua $GLOBAL_SERVER tcp $(uci_get_by_name $1 local_port) > /var/etc/v2-ssr-retcp.json
127 | sed -i 's/\\//g' /var/etc/v2-ssr-retcp.json
128 | fi
129 | }
130 |
131 | get_arg_out() {
132 | case "$(uci_get_by_type access_control router_proxy 1)" in
133 | 1) echo "-o";;
134 | 2) echo "-O";;
135 | esac
136 | }
137 |
138 | start_rules() {
139 | local server=$(uci_get_by_name $GLOBAL_SERVER server)
140 | #resolve name
141 | if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
142 | server=${server}
143 | elif [ "$server" != "${server#*:[0-9a-fA-F]}" ] ;then
144 | server=${server}
145 | else
146 | server=`ping ${server} -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1`
147 | if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
148 | echo $server >/etc/ssr_ip
149 | else
150 | server=`cat /etc/ssr_ip`
151 | fi
152 | fi
153 |
154 | kcp_server=$server
155 |
156 | local kcp_enable=$(uci_get_by_name $GLOBAL_SERVER kcp_enable 0)
157 | if [ $kcp_enable = "1" ] ;then
158 | kcp_flag=1
159 | fi
160 |
161 | local local_port=$(uci_get_by_name $GLOBAL_SERVER local_port)
162 | local lan_ac_ips=$(uci_get_by_type access_control lan_ac_ips)
163 | local lan_ac_mode="b"
164 | local router_proxy=$(uci_get_by_type access_control router_proxy)
165 | if [ "$GLOBAL_SERVER" = "$UDP_RELAY_SERVER" -a $kcp_flag = 0 ]; then
166 | ARG_UDP="-u"
167 | elif [ -n "$UDP_RELAY_SERVER" ]; then
168 | ARG_UDP="-U"
169 | local udp_server=$(uci_get_by_name $UDP_RELAY_SERVER server)
170 | local udp_local_port=$(uci_get_by_name $UDP_RELAY_SERVER local_port)
171 | fi
172 |
173 | if [ -n "$lan_ac_ips" ]; then
174 | case "$lan_ac_mode" in
175 | w|W|b|B) local ac_ips="$lan_ac_mode$lan_ac_ips";;
176 | esac
177 | fi
178 |
179 | #deal gfw firewall rule
180 | local gfwmode=""
181 | if [ "$run_mode" = "gfw" ]; then
182 | gfwmode="-g"
183 | elif [ "$run_mode" = "router" ]; then
184 | gfwmode="-r"
185 | elif [ "$run_mode" = "oversea" ]; then
186 | gfwmode="-c"
187 | elif [ "$run_mode" = "all" ]; then
188 | gfwmode="-z"
189 | fi
190 |
191 |
192 | /usr/bin/ssr-rules \
193 | -s "$server" \
194 | -l "$local_port" \
195 | -S "$udp_server" \
196 | -L "$udp_local_port" \
197 | -a "$ac_ips" \
198 | -i "$(uci_get_by_type access_control wan_bp_list)" \
199 | -b "$(uci_get_by_type access_control wan_bp_ips)" \
200 | -w "$(uci_get_by_type access_control wan_fw_ips)" \
201 | -p "$(uci_get_by_type access_control lan_fp_ips)" \
202 | -G "$(uci_get_by_type access_control lan_gm_ips)" \
203 | $(get_arg_out) $gfwmode $ARG_UDP
204 |
205 | return $?
206 | }
207 |
208 | start_pdnsd() {
209 | local usr_dns="$1"
210 | local usr_port="$2"
211 |
212 | local tcp_dns_list="208.67.222.222, 208.67.220.220"
213 | [ -z "$usr_dns" ] && usr_dns="8.8.8.8"
214 | [ -z "$usr_port" ] && usr_port="53"
215 |
216 | [ -d /var/etc ] || mkdir -p /var/etc
217 |
218 | if [ ! -d /var/pdnsd ];then
219 | mkdir -p /var/pdnsd
220 | echo -ne "pd13\000\000\000\000" >/var/pdnsd/pdnsd.cache
221 | chown -R nobody:nogroup /var/pdnsd
222 | fi
223 |
224 | cat > /var/etc/pdnsd.conf </dev/null 2>&1
321 | done
322 | echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR $threads Threads Started!" >> /tmp/ssrplus.log
323 | elif [ "$stype" == "v2ray" ] ;then
324 | $sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 &
325 | echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) Started!" >> /tmp/ssrplus.log
326 | fi
327 |
328 | if [ -n "$UDP_RELAY_SERVER" ] ;then
329 | redir_udp=1
330 | if [ "$utype" == "ss" -o "$utype" == "ssr" ] ;then
331 | case "$(uci_get_by_name $UDP_RELAY_SERVER auth_enable)" in
332 | 1|on|true|yes|enabled) ARG_OTA="-A";;
333 | *) ARG_OTA="";;
334 | esac
335 | gen_config_file $UDP_RELAY_SERVER 1
336 | last_config_file=$CONFIG_UDP_FILE
337 | pid_file="/var/run/ssr-reudp.pid"
338 | $ucmd -c $last_config_file $ARG_OTA -U -f /var/run/ssr-reudp.pid >/dev/null 2>&1
339 | elif [ "$utype" == "v2ray" ] ; then
340 | 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
341 | sed -i 's/\\//g' /var/etc/v2-ssr-reudp.json
342 | $ucmd -config /var/etc/v2-ssr-reudp.json >/dev/null 2>&1 &
343 | fi
344 | fi
345 |
346 |
347 |
348 | #deal with dns
349 |
350 | if [ "$(uci_get_by_type global pdnsd_enable)" = "1" ] ;then
351 | local dnsstr="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
352 | local dnsserver=`echo "$dnsstr"|awk -F ':' '{print $1}'`
353 | local dnsport=`echo "$dnsstr"|awk -F ':' '{print $2}'`
354 | if [ "$run_mode" = "gfw" ]; then
355 | ipset add gfwlist $dnsserver 2>/dev/null
356 | elif [ "$run_mode" = "oversea" ]; then
357 | ipset add oversea $dnsserver 2>/dev/null
358 | else
359 | ipset add ss_spec_wan_ac $dnsserver nomatch 2>/dev/null
360 | fi
361 | start_pdnsd $dnsserver $dnsport
362 | pdnsd_enable_flag=1
363 | fi
364 |
365 | if [ "$(uci_get_by_type global enable_switch)" = "1" ] ;then
366 | if [ "$(uci_get_by_name $GLOBAL_SERVER switch_enable)" = "1" ] ;then
367 | if [ -z "$switch_server" ] ;then
368 | local switch_time=$(uci_get_by_type global switch_time)
369 | local switch_timeout=$(uci_get_by_type global switch_timeout)
370 | service_start /usr/bin/ssr-switch start $switch_time $switch_timeout
371 | switch_enable=1
372 | fi
373 | fi
374 | fi
375 | add_cron
376 |
377 | return $?
378 | }
379 |
380 | gen_service_file() {
381 | if [ $(uci_get_by_name $1 fast_open) = "1" ] ;then
382 | fastopen="true";
383 | else
384 | fastopen="false";
385 | fi
386 | cat <<-EOF >$2
387 | {
388 | "server": "0.0.0.0",
389 | "server_port": $(uci_get_by_name $1 server_port),
390 | "password": "$(uci_get_by_name $1 password)",
391 | "timeout": $(uci_get_by_name $1 timeout 60),
392 | "method": "$(uci_get_by_name $1 encrypt_method)",
393 | "protocol": "$(uci_get_by_name $1 protocol)",
394 | "protocol_param": "$(uci_get_by_name $1 protocol_param)",
395 | "obfs": "$(uci_get_by_name $1 obfs)",
396 | "obfs_param": "$(uci_get_by_name $1 obfs_param)",
397 | "fast_open": $fastopen
398 | }
399 | EOF
400 | }
401 |
402 | start_service() {
403 | [ $(uci_get_by_name $1 enable) = "0" ] && return 1
404 | let server_count=server_count+1
405 | if [ $server_count = 1 ] ;then
406 | iptables -N SSR-SERVER-RULE && \
407 | iptables -t filter -I INPUT -j SSR-SERVER-RULE
408 | fi
409 |
410 | gen_service_file $1 /var/etc/${NAME}_${server_count}.json
411 | /usr/bin/ssr-server -c /var/etc/${NAME}_${server_count}.json -u -f /var/run/ssr-server${server_count}.pid >/dev/null 2>&1
412 | iptables -t filter -A SSR-SERVER-RULE -p tcp --dport $(uci_get_by_name $1 server_port) -j ACCEPT
413 | iptables -t filter -A SSR-SERVER-RULE -p udp --dport $(uci_get_by_name $1 server_port) -j ACCEPT
414 | return 0
415 | }
416 | gen_serv_include() {
417 | FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null)
418 | [ -n "$FWI" ] || return 0
419 | if [ ! -f $FWI ] ;then
420 | echo '#!/bin/sh' >$FWI
421 | fi
422 | extract_rules() {
423 | echo "*filter"
424 | iptables-save -t filter | grep SSR-SERVER-RULE|sed -e "s/^-A INPUT/-I INPUT/"
425 | echo 'COMMIT'
426 | }
427 | cat <<-EOF >>$FWI
428 | iptables-save -c | grep -v "SSR-SERVER" | iptables-restore -c
429 | iptables-restore -n <<-EOT
430 | $(extract_rules)
431 | EOT
432 | EOF
433 |
434 | }
435 | start_server() {
436 | SERVER_ENABLE=$(uci_get_by_type server_global enable_server)
437 | [ "$SERVER_ENABLE" = 0 ] && return 0
438 | mkdir -p /var/run /var/etc
439 |
440 | config_load $NAME
441 | config_foreach start_service server_config
442 | gen_serv_include
443 | return 0
444 | }
445 |
446 | start_local() {
447 | local local_server=$(uci_get_by_type socks5_proxy server)
448 | [ "$local_server" = "nil" ] && return 1
449 | mkdir -p /var/run /var/etc
450 | gen_config_file $local_server 2
451 | /usr/bin/ssr-local -c $CONFIG_SOCK5_FILE -u \
452 | -l $(uci_get_by_type socks5_proxy local_port 1080) \
453 | -b $(uci_get_by_type socks5_proxy local_address 0.0.0.0) \
454 | -f /var/run/ssr-local.pid >/dev/null 2>&1
455 | local_enable=1
456 | }
457 |
458 | rules() {
459 | [ "$GLOBAL_SERVER" = "nil" ] && return 1
460 | mkdir -p /var/run /var/etc
461 | UDP_RELAY_SERVER=$(uci_get_by_type global udp_relay_server)
462 | [ "$UDP_RELAY_SERVER" = "same" ] && UDP_RELAY_SERVER=$GLOBAL_SERVER
463 | if start_rules ;then
464 | return 0
465 | else
466 | return 1
467 | fi
468 | }
469 |
470 | start() {
471 | if [ -z "$switch_server" ] ;then
472 | GLOBAL_SERVER=$(uci_get_by_type global global_server)
473 | else
474 | GLOBAL_SERVER=$switch_server
475 | switch_enable=1
476 | fi
477 | if rules ;then
478 | start_redir
479 |
480 | mkdir -p /tmp/dnsmasq.d
481 | if ! [ "$run_mode" = "oversea" ] ;then
482 | cat > /tmp/dnsmasq.d/dnsmasq-ssr.conf < /tmp/dnsmasq.d/dnsmasq-ssr.conf </dev/null 2>&1
491 |
492 | fi
493 | start_server
494 | start_local
495 |
496 | if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then
497 | let total_count=server_count+redir_tcp+redir_udp+tunnel_enable+kcp_enable_flag+local_enable+pdnsd_enable_flag+switch_enable
498 | if [ $total_count -gt 0 ]
499 | then
500 | #param:server(count) redir_tcp(0:no,1:yes) redir_udp tunnel kcp local gfw
501 | service_start /usr/bin/ssr-monitor $server_count $redir_tcp $redir_udp $tunnel_enable $kcp_enable_flag $local_enable $pdnsd_enable_flag $switch_enable
502 | fi
503 | fi
504 |
505 | ENABLE_SERVER=$(uci_get_by_type global global_server)
506 | [ "$ENABLE_SERVER" = "nil" ] && return 1
507 | }
508 |
509 | boot() {
510 | (/usr/share/shadowsocksr/chinaipset.sh && sleep 5 && start >/dev/null 2>&1) &
511 | }
512 |
513 | stop() {
514 | /usr/bin/ssr-rules -f
515 | srulecount=`iptables -L|grep SSR-SERVER-RULE|wc -l`
516 | if [ $srulecount -gt 0 ] ;then
517 | iptables -F SSR-SERVER-RULE
518 | iptables -t filter -D INPUT -j SSR-SERVER-RULE
519 | iptables -X SSR-SERVER-RULE 2>/dev/null
520 | fi
521 | if [ -z "$switch_server" ] ;then
522 | kill -9 $(ps | grep ssr-switch | grep -v grep | awk '{print $1}') >/dev/null 2>&1
523 | fi
524 | if [ $(uci_get_by_type global monitor_enable) = 1 ] ;then
525 | kill -9 $(ps | grep ssr-monitor | grep -v grep | awk '{print $1}') >/dev/null 2>&1
526 | fi
527 | killall -q -9 ssr-monitor
528 | killall -q -9 ss-redir
529 | killall -q -9 ssr-redir
530 | killall -q -9 v2ray
531 | killall -q -9 ssr-server
532 | killall -q -9 kcptun-client
533 | killall -q -9 ssr-local
534 | if [ -f /var/run/pdnsd.pid ] ;then
535 | kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
536 | else
537 | kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
538 | fi
539 |
540 | if [ -f "/tmp/dnsmasq.d/dnsmasq-ssr.conf" ]; then
541 | rm -f /tmp/dnsmasq.d/dnsmasq-ssr.conf
542 | /etc/init.d/dnsmasq restart >/dev/null 2>&1
543 | fi
544 | del_cron
545 | }
546 |
--------------------------------------------------------------------------------