From 26cae0a0c46d2c188dfa4bcd8de89ec16e9f0954 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Feb 2023 00:47:38 +0800 Subject: [PATCH] update 2023-02-08 00:47:38 --- .../root/etc/mosdns/rule/geoip_cn.txt | 1 - .../root/etc/mosdns/rule/geosite_cn.txt | 62 +-- .../root/usr/share/passwall/subscribe.lua | 2 +- luci-app-passwall2/Makefile | 2 +- .../luasrc/model/cbi/passwall2/api/api.lua | 53 ++- .../luasrc/model/cbi/passwall2/api/brook.lua | 2 +- .../model/cbi/passwall2/api/gen_hysteria.lua | 1 + .../model/cbi/passwall2/api/gen_v2ray.lua | 17 +- .../model/cbi/passwall2/api/hysteria.lua | 2 +- .../luasrc/model/cbi/passwall2/api/v2ray.lua | 2 +- .../luasrc/model/cbi/passwall2/api/xray.lua | 2 +- .../model/cbi/passwall2/client/global.lua | 31 +- .../cbi/passwall2/client/node_config.lua | 12 +- .../cbi/passwall2/client/node_subscribe.lua | 5 - .../model/cbi/passwall2/server/api/v2ray.lua | 35 +- .../model/cbi/passwall2/server/user.lua | 19 +- luci-app-passwall2/po/zh-cn/passwall2.po | 10 +- .../root/usr/share/passwall2/0_default_config | 2 +- .../root/usr/share/passwall2/app.sh | 22 +- .../root/usr/share/passwall2/iptables.sh | 10 + .../root/usr/share/passwall2/rule_update.lua | 13 +- .../root/usr/share/passwall2/subscribe.lua | 41 +- luci-app-ssr-plus/root/usr/bin/ssr-monitor | 124 +++++ luci-app-ssr-plus/root/usr/bin/ssr-rules | 426 ++++++++++++++++++ luci-app-ssr-plus/root/usr/bin/ssr-switch | 155 +++++++ 25 files changed, 923 insertions(+), 128 deletions(-) create mode 100755 luci-app-ssr-plus/root/usr/bin/ssr-monitor create mode 100755 luci-app-ssr-plus/root/usr/bin/ssr-rules create mode 100755 luci-app-ssr-plus/root/usr/bin/ssr-switch diff --git a/luci-app-mosdns/root/etc/mosdns/rule/geoip_cn.txt b/luci-app-mosdns/root/etc/mosdns/rule/geoip_cn.txt index 971431654..c69a4feed 100644 --- a/luci-app-mosdns/root/etc/mosdns/rule/geoip_cn.txt +++ b/luci-app-mosdns/root/etc/mosdns/rule/geoip_cn.txt @@ -6152,7 +6152,6 @@ 2400:3fc0::/32 2400:4440::/32 2400:44c0::/32 -2400:44e0::/32 2400:4540::/32 2400:4600::/32 2400:4640::/32 diff --git a/luci-app-mosdns/root/etc/mosdns/rule/geosite_cn.txt b/luci-app-mosdns/root/etc/mosdns/rule/geosite_cn.txt index 7f76d03b7..2fbb52733 100644 --- a/luci-app-mosdns/root/etc/mosdns/rule/geosite_cn.txt +++ b/luci-app-mosdns/root/etc/mosdns/rule/geosite_cn.txt @@ -1140,6 +1140,7 @@ 135309.com 135320.com 135650.com +13567.com 1356789.com 1356net.com 135958.com @@ -1282,6 +1283,7 @@ 163663.com 163686.com 1637.com +163888.net 163cdn.com 163cn.tv 163cp.com @@ -1937,6 +1939,7 @@ 210997.com 210z.com 2113.net +2114.com 2115.com 211600.com 211ic.com @@ -2568,7 +2571,6 @@ 3259.com 326pay.com 32800.com -328888.xyz 328f.com 328vip.com 3290.com @@ -3891,7 +3893,6 @@ 51job.com 51jobcdn.com 51jobdns.com -51joyfish.com 51js.com 51jt.com 51jucaimi.com @@ -4507,6 +4508,7 @@ 5433.com 545c.com 5460.net +54674479.com 5490146.cc 5490196.cc 5499.com @@ -4525,6 +4527,7 @@ 54md.com 54op.com 54pictu.com +54qs.com 54tf.com 54traveler.com 54tusi.com @@ -4801,6 +4804,7 @@ 593yx.com 5947.net 59490.com +5951835ccc.com 595818.com 595led.com 595tuchuang.com @@ -5157,6 +5161,7 @@ 6543210.com 654321wan.com 654h.com +65522v.com 655a.com 655u.com 655yx.com @@ -5457,6 +5462,7 @@ 711pr.com 7120.com 712100.com +71268924.com 71360.com 7139.com 714.com @@ -6036,6 +6042,7 @@ 861817.com 86215.com 8624x.com +86255845.com 86262.com 8633.com 863347.com @@ -6224,6 +6231,7 @@ 89dj.com 89ds.com 89hl.com +89qw.com 89uu.com 8a.hk 8ao8ao.com @@ -7096,7 +7104,6 @@ 9txs.org 9u.net 9upk.com -9v.com 9vf.com 9w9.com 9wee.com @@ -7967,6 +7974,7 @@ aituan.com aitupian.com aituwo.com aityp.com +aiufida.com aiurl.com aiuw.com aiuxdesign.com @@ -8821,7 +8829,6 @@ apgblogs.com apgoview.com aphidic.com api.anythinktech.com -api.bz apiadmin.org apiairasia.com apicase.io @@ -11251,6 +11258,7 @@ bjythd.com bjyunyu.com bjywt.com bjzaxy.com +bjzbb.com bjzbkj.com bjzcha.com bjzcth.com @@ -12105,6 +12113,7 @@ bytesmanager.com bytestacks.com bytetcc.com bytetos.com +bytewars.cc bytexns.com bytexservice.com byts.com @@ -12774,7 +12783,6 @@ ccpitqd.org ccpitsd.com ccpittex.com ccpittj.org -ccpitwh.org ccpitxiamen.org ccpitxian.org ccpitxj.org @@ -13267,6 +13275,7 @@ cf-ns.tech cf.com cf69.com cf865.com +cf9q4i.xyz cfachina.org cfbond.com cfc365.com @@ -15677,7 +15686,6 @@ cnhacker.com cnhaio.com cnhalo.net cnhan.com -cnhandan.com cnhanxing.com cnhaoshengyi.com cnhaskell.com @@ -17681,7 +17689,6 @@ dashoucloud.com dashuihua.com dashuju123.com dashuye.com -dasougu.com dasoujia.com dassm.com dasung.com @@ -17966,7 +17973,6 @@ ddwhm.com ddwzh.com ddxinwen.com ddxq.mobi -ddxs.cc ddxstxt8.com ddyqh.com ddyun.com @@ -19393,7 +19399,6 @@ drip.im dripcar.com driverdevelop.com drivergenius.com -driversdown.com driverzeng.com drivethelife.com drli.group @@ -20043,7 +20048,6 @@ eastcompeace.com eastcoms.com eastday.com eastdesign.net -eastdigit.com eastdrama.com eastdushi.com easteat.com @@ -21926,6 +21930,7 @@ fenglinjiu.com fengmanginfo.com fengmaniu.com fengmeng.net +fengmi-baike.com fengmk2.com fengniao.com fengniaohuanjing.com @@ -22555,7 +22560,6 @@ fqnovelpic.com fqnovelstatic.com fqnovelvod.com fqpai.com -fqsszx.com fqxs.org fr-odc.samsungapps.com fr-trading.com @@ -26106,7 +26110,6 @@ hbsia.org hbskw.com hbslndx.com hbsmservice.com -hbsmw.com hbsocar.com hbsoft.net hbsogdjt.com @@ -26515,7 +26518,6 @@ hengxiangtaji.com hengxinjinshu.com hengxueedu.com hengyan.com -hengyer.com hengyidai.com hengyigl.com hengyoux.com @@ -27003,7 +27005,6 @@ hkwb.net hkxbjt.com hkxen.com hkyykq.com -hkzcdn.com hkzlcm.com hl-brushes.com hl95.com @@ -27410,6 +27411,7 @@ hookbase.com hookdll.com hoolai.com hoolaigames.com +hoolee8.com hoolinks.com hoolo.tv hoop-archi.com @@ -27846,7 +27848,6 @@ huaguoshan.com huahanart.com huahua777.com huahuacaocao.com -huahuakon.com huahuo.com huaibaobei.com huaibei.com @@ -28629,6 +28630,7 @@ hxsd.tv hxsec.com hxshx.com hxsme.org +hxstrive.com hxtk.com hxwglm.com hxxkw.org @@ -29218,6 +29220,7 @@ icloudgslb.com icloudnative.io icloudnews.net iclouds.work +icloudv6.com icloudwaf.com icmade.com icme14.org @@ -29522,6 +29525,7 @@ ifjing.com iflyhealth.com iflying.com iflyink.com +iflynote.com iflyos.vip iflyread.com iflyrec.com @@ -29942,7 +29946,6 @@ imgii.com imgkr.com imglefeng.com imglink.win -imgloc.com imgo.tv imgscdn.com imgse.com @@ -30639,6 +30642,7 @@ itaoyun.com itavcn.com itbegin.com itbeihe.com +itbiancheng.com itbiaoju.com itbilu.com itbkz.com @@ -30825,6 +30829,7 @@ iuctrip.com iudodo.com iufida.com iuinns.com +iun2s8.xyz iuni.com iuoooo.com iuplus.com @@ -32636,7 +32641,6 @@ jocat.com joe92.com joenchen.com johhan.com -johnwatsondev.com johogames.com joiest.com joinchitchat.com @@ -34159,7 +34163,6 @@ kintiger.com kinval.com kinzoncap.com kirgen.com -kirikira.com kirimasharo.com kirin-tech.com kirincloud.net @@ -34913,7 +34916,6 @@ kx516.com kx7p.com kxapp.com kxapps.com -kxbaidu.com kxbox.com kxcblog.com kxceping.com @@ -34943,6 +34945,7 @@ kxxsc.com kxxxl.com kxzmw.com ky-express.com +ky0001.vip ky0048.cc ky010.vip ky107.co @@ -35167,6 +35170,7 @@ langren8.com langrencard.com langrenclub.com langrensha.net +langtao.cc langtaojin.com langtze.com languangdy.com @@ -36678,6 +36682,7 @@ lm284.com lm335.com lm553.com lm685.com +lm7979.com lm9999.com lmacc.com lmanmo.com @@ -38244,6 +38249,7 @@ mdvoo.com mdy-edu.com mdybk.com mdydt.net +mdzgjx.com me-city.com me361.com me4399.com @@ -40241,6 +40247,7 @@ n127.com n12m.cc n18081.com n21.cc +n28082.com n3293.com n3762.com n3875.com @@ -40459,7 +40466,6 @@ ncacg.org ncartfoundation.org ncdxbbs.com ncfcsa.org -ncfcw.net ncfgroup.com ncfwx.com ncfxwhjjh.com @@ -41599,7 +41605,6 @@ okii.com okinfo.org okjike.com okjk.co -okjoys.com okjx.cc okki.com okkkk.com @@ -44045,7 +44050,6 @@ qiansw.com qiantucdn.com qianvisa.com qianwa.com -qianwee.com qianxiangbank.com qianxibj.net qianxin.com @@ -45420,6 +45424,7 @@ rdcy.org rddoc.com rdfybk.com rdgz.org +rdhyw.com rdidc.com rdnsdb.com rdplat.com @@ -50044,6 +50049,7 @@ suobuy.com suofeiya.com suofeiyashop.com suoge.net +suokao.com suosihulian.com suoxin5.com suoyiren.com @@ -50537,6 +50543,7 @@ szider.com szisland.com szjcyyy.com szjhxjt.com +szjinhuanyu.com szjlwul.com szjunfei.com szjuquan.com @@ -51144,6 +51151,7 @@ tciplay.com tcl.com tclbusiness.com tclclouds.com +tcljd.com tclking.com tclkqn.com tcloudbase.com @@ -51888,6 +51896,7 @@ tingke8.com tingliku.com tingmall.com tingmimi.net +tingniukeji.com tingroom.com tingshuge.com tingsonglaw.com @@ -52149,6 +52158,7 @@ toec.com toecsec.com toecsoft.com toecxy.com +tofengmi.com togj.com togocareer.com togogo.net @@ -53302,6 +53312,7 @@ u6u.com u77.com u78.com u7u9.com +u8376.com u8sy.com u8yx.com u9game.net @@ -53310,7 +53321,6 @@ u9time.com u9u8.com u9u9.com u9wan.com -ua168.com uahh.site uami-global.org uao-online.com @@ -56412,7 +56422,6 @@ wj001.com wj166.com wjajw.com wjasset.com -wjbb.com wjbk.site wjceo.com wjdaily.com @@ -56576,6 +56585,7 @@ wnzhuishu.com wnzy.net wo-smart.com wo-xa.com +wo.cc wo113.net wo116114.com wo123.com @@ -61517,7 +61527,6 @@ yoolin.cc yoooooooooo.com yoopu.me yootou.com -yoouxi.com yooxun.com yooxuu.com yooyoo360.com @@ -62027,7 +62036,6 @@ ytcos.com ytcutv.com ytdaily.com ytdcloud.com -ytdfcw.com yte1.com yteng.net ytesting.com @@ -62973,7 +62981,6 @@ zampdmp.com zampdsp.com zamplink.net zamplus.com -zan-shang.com zanba.com zanbai.com zangaifamily.com @@ -64410,6 +64417,7 @@ zichenit.com zidan.chat zidanduanxin.com zidanduanxin.net +zidg.com zidian8.com zidianwang.com zidoo.tv diff --git a/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/luci-app-passwall/root/usr/share/passwall/subscribe.lua index d9c14b218..763afbb07 100755 --- a/luci-app-passwall/root/usr/share/passwall/subscribe.lua +++ b/luci-app-passwall/root/usr/share/passwall/subscribe.lua @@ -775,7 +775,7 @@ local function processData(szType, content, add_mode, add_from) result.tls = "1" result.tlsflow = params.flow or nil result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host - result.fingerprint = (params.fp and params.fp ~= "") and params.fp or nil + result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome" end result.port = port diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 238e58b04..4c4b73a96 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=1.6 +PKG_VERSION:=1.7 PKG_RELEASE:=1 PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/api.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/api.lua index a68641786..2c5885017 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/api.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/api.lua @@ -8,7 +8,6 @@ jsonc = require "luci.jsonc" i18n = require "luci.i18n" appname = "passwall2" -curl = "/usr/bin/curl" curl_args = {"-skfL", "--connect-timeout 3", "--retry 3", "-m 60"} command_timeout = 300 LEDE_BOARD = nil @@ -31,6 +30,39 @@ function base64Decode(text) end end +function curl_base(url, file, args) + if not args then args = {} end + if file then + args[#args + 1] = "-o " .. file + end + local cmd = string.format('curl %s "%s"', table_join(args), url) + if file then + return luci.sys.call(cmd .. " > /dev/null") + else + return trim(luci.sys.exec(cmd)) + end +end + +function curl_proxy(url, file, args) + --使用代理 + local socks_server = luci.sys.exec("[ -f /tmp/etc/passwall2/global_SOCKS_server ] && echo -n $(cat /tmp/etc/passwall2/global_SOCKS_server) || echo -n ''") + if socks_server ~= "" then + if not args then args = {} end + local tmp_args = clone(args) + tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server + return curl_base(url, file, tmp_args) + end + return nil +end + +function curl_logic(url, file, args) + local result = curl_proxy(url, file, args) + if not result then + result = curl_base(url, file, args) + end + return result +end + function url(...) local url = string.format("admin/services/%s", appname) local args = { ... } @@ -92,7 +124,7 @@ function strToTable(str) end function is_normal_node(e) - if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt") then + if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then return false end return true @@ -202,7 +234,7 @@ function get_valid_nodes() uci:foreach(appname, "nodes", function(e) e.id = e[".name"] if e.type and e.remarks then - if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt") then + if e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface") then e["remark"] = "%s:[%s] " % {i18n.translatef(e.type .. e.protocol), e.remarks} e["node_type"] = "special" nodes[#nodes + 1] = e @@ -239,7 +271,7 @@ end function get_full_node_remarks(n) local remarks = "" if n then - if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt") then + if n.protocol and (n.protocol == "_balancing" or n.protocol == "_shunt" or n.protocol == "_iface") then remarks = "%s:[%s] " % {i18n.translatef(n.type .. n.protocol), n.remarks} else local type2 = n.type @@ -427,6 +459,17 @@ function _unpack(t, i) if t[i] ~= nil then return t[i], _unpack(t, i + 1) end end +function table_join(t, s) + if not s then + s = " " + end + local str = "" + for index, value in ipairs(t) do + str = str .. t[index] .. (index == #t and "" or s) + end + return str +end + function exec(cmd, args, writer, timeout) local os = require "os" local nixio = require "nixio" @@ -557,7 +600,7 @@ end function get_api_json(url) local jsonc = require "luci.jsonc" - local json_content = luci.sys.exec(curl .. " " .. _unpack(curl_args) .. " " .. url) + local json_content = curl_logic(url, nil, curl_args) if json_content == "" then return {} end return jsonc.parse(json_content) or {} end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/brook.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/brook.lua index 9f6b4d80f..76f8a17d4 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/brook.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/brook.lua @@ -63,7 +63,7 @@ function to_download(url, size) end end - result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0 + result = api.curl_logic(url, tmp_file, api.curl_args) == 0 if not result then api.exec("/bin/rm", {"-f", tmp_file}) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_hysteria.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_hysteria.lua index 025d3d791..b12ecec1f 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_hysteria.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_hysteria.lua @@ -41,6 +41,7 @@ local config = { recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil, recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil, disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false, + fast_open = (node.fast_open == "1") and true or false, socks5 = (local_socks_address and local_socks_port) and { listen = local_socks_address .. ":" .. local_socks_port, timeout = 300, diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_v2ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_v2ray.lua index 4d06f8471..16c4d57ac 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_v2ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/gen_v2ray.lua @@ -562,7 +562,22 @@ if true then } end else - local outbound = gen_outbound(node) + local outbound = nil + if node.protocol == "_iface" then + if node.iface then + outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + interface = node.iface + } + } + } + end + else + outbound = gen_outbound(node) + end if outbound then table.insert(outbounds, outbound) end routing = { domainStrategy = "AsIs", diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/hysteria.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/hysteria.lua index 567dbc6be..dec76b917 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/hysteria.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/hysteria.lua @@ -63,7 +63,7 @@ function to_download(url, size) end end - result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0 + result = api.curl_logic(url, tmp_file, api.curl_args) == 0 if not result then api.exec("/bin/rm", {"-f", tmp_file}) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/v2ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/v2ray.lua index 9edc8408e..ad14dd246 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/v2ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/v2ray.lua @@ -69,7 +69,7 @@ function to_download(url, size) end end - result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0 + result = api.curl_logic(url, tmp_file, api.curl_args) == 0 if not result then api.exec("/bin/rm", {"-f", tmp_file}) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/xray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/xray.lua index 6f5a74f13..826d9b9a8 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/api/xray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/api/xray.lua @@ -69,7 +69,7 @@ function to_download(url, size) end end - result = api.exec(api.curl, {api._unpack(api.curl_args), "-o", tmp_file, url}, nil, api.command_timeout) == 0 + result = api.curl_logic(url, tmp_file, api.curl_args) == 0 if not result then api.exec("/bin/rm", {"-f", tmp_file}) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua index 2cd53af41..764daf6c4 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua @@ -12,23 +12,6 @@ for k, e in ipairs(api.get_valid_nodes()) do nodes_table[#nodes_table + 1] = e end -local socks_table = {} -uci:foreach(appname, "socks", function(s) - if s.enabled == "1" and s.node then - local id, remarks - for k, n in pairs(nodes_table) do - if (s.node == n.id) then - remarks = n["remark"]; break - end - end - id = "127.0.0.1" .. ":" .. s.port - socks_table[#socks_table + 1] = { - id = id, - remarks = id .. " - " .. (remarks or translate("Misconfigured")) - } - end -end) - local doh_validate = function(self, value, t) if value ~= "" then local flag = 0 @@ -148,6 +131,18 @@ o = s:taboption("Main", Flag, "localhost_proxy", translate("Localhost Proxy"), t o.default = "1" o.rmempty = false +node_socks_port = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks " .. translate("Listen Port")) +node_socks_port.default = 1070 +node_socks_port.datatype = "port" + +--[[ +if has_v2ray or has_xray then + node_http_port = s:taboption("Main", Value, "node_http_port", translate("Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) + node_http_port.default = 0 + node_http_port.datatype = "port" +end +]]-- + s:tab("DNS", translate("DNS")) o = s:taboption("DNS", ListValue, "direct_dns_protocol", translate("Direct DNS Protocol")) @@ -273,7 +268,7 @@ o.rmempty = false socks_node = s:option(ListValue, "node", translate("Socks Node")) -local n = 0 +local n = 1 uci:foreach(appname, "socks", function(s) if s[".name"] == section then return false diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua index 4cca0f948..7c11d5e21 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_config.lua @@ -109,9 +109,15 @@ protocol:value("trojan", translate("Trojan")) protocol:value("wireguard", translate("WireGuard")) protocol:value("_balancing", translate("Balancing")) protocol:value("_shunt", translate("Shunt")) +protocol:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") protocol:depends("type", "V2ray") protocol:depends("type", "Xray") + +iface = s:option(Value, "iface", translate("Interface")) +iface.default = "eth1" +iface:depends("protocol", "_iface") + local nodes_table = {} for k, e in ipairs(api.get_valid_nodes()) do if e.node_type == "normal" then @@ -437,13 +443,17 @@ timeout:depends("type", "SS") timeout:depends("type", "SS-Rust") timeout:depends("type", "SSR") -tcp_fast_open = s:option(ListValue, "tcp_fast_open", translate("TCP Fast Open"), translate("Need node support required")) +tcp_fast_open = s:option(ListValue, "tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required")) tcp_fast_open:value("false") tcp_fast_open:value("true") tcp_fast_open:depends("type", "SS") tcp_fast_open:depends("type", "SS-Rust") tcp_fast_open:depends("type", "SSR") +fast_open = s:option(Flag, "fast_open", translate("Fast Open")) +fast_open.default = "0" +fast_open:depends("type", "Hysteria") + ss_plugin = s:option(ListValue, "ss_plugin", translate("plugin")) ss_plugin:value("none", translate("none")) if api.is_finded("xray-plugin") then ss_plugin:value("xray-plugin") end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua index adc1f9657..2b59e66d3 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe.lua @@ -24,11 +24,6 @@ m = Map(appname) s = m:section(TypedSection, "global_subscribe", "") s.anonymous = true ----- Subscribe via proxy -o = s:option(Flag, "subscribe_proxy", translate("Subscribe via proxy")) -o.default = 0 -o.rmempty = false - o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode")) o:value("0", translate("Close")) o:value("1", translate("Discard List")) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/api/v2ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/api/v2ray.lua index 38892f274..ebba17947 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/api/v2ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/api/v2ray.lua @@ -117,19 +117,32 @@ function gen_config(user) } if user.outbound_node and user.outbound_node ~= "nil" then - local outbound_node_t = uci:get_all("passwall2", user.outbound_node) - if user.outbound_node == "_socks" or user.outbound_node == "_http" then - outbound_node_t = { - type = user.type, - protocol = user.outbound_node:gsub("_", ""), - transport = "tcp", - address = user.outbound_node_address, - port = user.outbound_node_port, - username = (user.outbound_node_username and user.outbound_node_username ~= "") and user.outbound_node_username or nil, - password = (user.outbound_node_password and user.outbound_node_password ~= "") and user.outbound_node_password or nil, + local outbound = nil + if user.outbound_node == "_iface" and user.outbound_node_iface then + outbound = { + protocol = "freedom", + tag = "outbound", + streamSettings = { + sockopt = { + interface = user.outbound_node_iface + } + } } + else + local outbound_node_t = uci:get_all("passwall2", user.outbound_node) + if user.outbound_node == "_socks" or user.outbound_node == "_http" then + outbound_node_t = { + type = user.type, + protocol = user.outbound_node:gsub("_", ""), + transport = "tcp", + address = user.outbound_node_address, + port = user.outbound_node_port, + username = (user.outbound_node_username and user.outbound_node_username ~= "") and user.outbound_node_username or nil, + password = (user.outbound_node_password and user.outbound_node_password ~= "") and user.outbound_node_password or nil, + } + end + outbound = require("luci.model.cbi.passwall2.api.gen_v2ray").gen_outbound(outbound_node_t, "outbound") end - local outbound = require("luci.model.cbi.passwall2.api.gen_v2ray").gen_outbound(outbound_node_t, "outbound") if outbound then table.insert(outbounds, 1, outbound) end diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua index 762171825..2fae07f79 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua @@ -571,18 +571,8 @@ bind_local:depends("type", "Xray") accept_lan = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) accept_lan.default = "0" -accept_lan:depends({ type = "V2ray", protocol = "vmess" }) -accept_lan:depends({ type = "V2ray", protocol = "vless" }) -accept_lan:depends({ type = "V2ray", protocol = "http" }) -accept_lan:depends({ type = "V2ray", protocol = "socks" }) -accept_lan:depends({ type = "V2ray", protocol = "shadowsocks" }) -accept_lan:depends({ type = "V2ray", protocol = "trojan" }) -accept_lan:depends({ type = "Xray", protocol = "vmess" }) -accept_lan:depends({ type = "Xray", protocol = "vless" }) -accept_lan:depends({ type = "Xray", protocol = "http" }) -accept_lan:depends({ type = "Xray", protocol = "socks" }) -accept_lan:depends({ type = "Xray", protocol = "shadowsocks" }) -accept_lan:depends({ type = "Xray", protocol = "trojan" }) +accept_lan:depends("type", "V2ray") +accept_lan:depends("type", "Xray") local nodes_table = {} for k, e in ipairs(api.get_valid_nodes()) do @@ -598,6 +588,7 @@ outbound_node = s:option(ListValue, "outbound_node", translate("outbound node")) outbound_node:value("nil", translate("Close")) outbound_node:value("_socks", translate("Custom Socks")) outbound_node:value("_http", translate("Custom HTTP")) +outbound_node:value("_iface", translate("Custom Interface") .. " (Only Support Xray)") for k, v in pairs(nodes_table) do outbound_node:value(v.id, v.remarks) end outbound_node.default = "nil" outbound_node:depends("type", "V2ray") @@ -621,6 +612,10 @@ outbound_node_password.password = true outbound_node_password:depends("outbound_node", "_socks") outbound_node_password:depends("outbound_node", "_http") +outbound_node_iface = s:option(Value, "outbound_node_iface", translate("Interface")) +outbound_node_iface.default = "eth1" +outbound_node_iface:depends("outbound_node", "_iface") + log = s:option(Flag, "log", translate("Log")) log.default = "1" log.rmempty = false diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po index 8a2552925..1bd20e3cb 100644 --- a/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -865,8 +865,8 @@ msgstr "连接超时时间" msgid "Local Port" msgstr "本地端口" -msgid "TCP Fast Open" -msgstr "TCP快速打开" +msgid "Fast Open" +msgstr "快速打开" msgid "Need node support required" msgstr "需要节点支持" @@ -1027,6 +1027,12 @@ msgstr "自定义 Socks" msgid "Custom HTTP" msgstr "自定义 HTTP" +msgid "Custom Interface" +msgstr "自定义接口" + +msgid "Interface" +msgstr "接口" + msgid "Bind Local" msgstr "本机监听" diff --git a/luci-app-passwall2/root/usr/share/passwall2/0_default_config b/luci-app-passwall2/root/usr/share/passwall2/0_default_config index 7afe0ede5..a647ccd7c 100644 --- a/luci-app-passwall2/root/usr/share/passwall2/0_default_config +++ b/luci-app-passwall2/root/usr/share/passwall2/0_default_config @@ -1,6 +1,7 @@ config global option enabled '0' + option node_socks_port '1070' option localhost_proxy '1' option socks_enabled '0' option node 'myshunt' @@ -45,7 +46,6 @@ config global_app option hysteria_file '/usr/bin/hysteria' config global_subscribe - option subscribe_proxy '0' option filter_keyword_mode '1' list filter_discard_list '过期时间' list filter_discard_list '剩余流量' diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh index 2344343da..011fb3764 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -21,6 +21,7 @@ RULES_PATH=/usr/share/${CONFIG}/rules TUN_DNS_PORT=15353 TUN_DNS="127.0.0.1#${TUN_DNS_PORT}" DEFAULT_DNS= +IFACES= NO_PROXY=0 PROXY_IPV6=0 PROXY_IPV6_UDP=0 @@ -365,6 +366,11 @@ run_v2ray() { esac lua $API_GEN_V2RAY -node $node -redir_port $redir_port -tcp_proxy_way $tcp_proxy_way -loglevel $loglevel ${_extra_param} > $config_file ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file" + + local protocol=$(config_n_get $node protocol) + [ "$protocol" == "_iface" ] && { + IFACES="$IFACES $(config_n_get $node iface)" + } } run_socks() { @@ -398,9 +404,12 @@ run_socks() { else error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!" fi - - if ([ "$type" == "v2ray" ] || [ "$type" == "xray" ]) && ([ -n "$(config_n_get $node balancing_node)" ] || [ "$(config_n_get $node default_node)" != "_direct" -a "$(config_n_get $node default_node)" != "_blackhole" ]); then - unset error_msg + + if [ "$type" == "v2ray" ] || [ "$type" == "xray" ]; then + local protocol=$(config_n_get $node protocol) + if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then + unset error_msg + fi fi [ -n "${error_msg}" ] && { @@ -602,6 +611,13 @@ run_global() { [ "$(config_t_get global close_log 1)" = "1" ] && V2RAY_LOG="/dev/null" V2RAY_ARGS="${V2RAY_ARGS} log_file=${V2RAY_LOG} config_file=${V2RAY_CONFIG}" + node_socks_port=$(config_t_get global node_socks_port 1070) + V2RAY_ARGS="${V2RAY_ARGS} socks_port=${node_socks_port}" + echo "127.0.0.1:$node_socks_port" > $TMP_PATH/global_SOCKS_server + + node_http_port=$(config_t_get global node_http_port 0) + [ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}" + run_v2ray $V2RAY_ARGS echo "run_v2ray $V2RAY_ARGS" > $TMP_SCRIPT_FUNC_PATH/_global } diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh index c3fa57a07..8b8a7caeb 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -766,6 +766,11 @@ add_firewall_rule() { $ip6t_m -A PSW2 $(comment "本机") -p tcp -i lo -j RETURN $ip6t_m -A OUTPUT -p tcp -j PSW2_OUTPUT fi + + for iface in $IFACES; do + $ipt_n -I PSW2_OUTPUT -o $iface -p tcp -j RETURN + $ipt_m -I PSW2_OUTPUT -o $iface -p tcp -j RETURN + done fi # 过滤Socks节点 @@ -816,6 +821,11 @@ add_firewall_rule() { $ip6t_m -A PSW2 $(comment "本机") -p udp -i lo -j RETURN $ip6t_m -A OUTPUT -p udp -j PSW2_OUTPUT fi + + for iface in $IFACES; do + $ipt_n -I PSW2_OUTPUT -o $iface -p udp -j RETURN + $ipt_m -I PSW2_OUTPUT -o $iface -p udp -j RETURN + done fi $ipt_m -A PSW2 -p udp --dport 53 -j RETURN diff --git a/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua b/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua index d36599e18..34e80d580 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/rule_update.lua @@ -6,6 +6,7 @@ local luci = luci local ucic = luci.model.uci.cursor() local jsonc = require "luci.jsonc" local name = 'passwall2' +local api = require "luci.model.cbi.passwall2.api.api" local arg1 = arg[1] local reboot = 0 @@ -41,16 +42,18 @@ end -- curl local function curl(url, file) - local cmd = "curl -skL -w %{http_code} --retry 3 --connect-timeout 3 '" .. url .. "'" + local args = { + "-sKL", "-w %{http_code}", "--retry 3", "--connect-timeout 3" + } if file then - cmd = cmd .. " -o " .. file + args[#args + 1] = "-o " .. file end - local stdout = luci.sys.exec(cmd) + local result = api.curl_logic(url, nil, args) if file then - return tonumber(trim(stdout)) + return tonumber(trim(result)) else - return trim(stdout) + return trim(result) end end diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index 28fdd787e..6c22b616b 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -647,7 +647,7 @@ local function processData(szType, content, add_mode, add_from) result.tls = "1" result.tlsflow = params.flow or nil result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host - result.fingerprint = (params.fp and params.fp ~= "") and params.fp or nil + result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome" end result.port = port @@ -699,30 +699,15 @@ local function processData(szType, content, add_mode, add_from) return result end --- curl local function curl(url, file, ua) if not ua or ua == "" then ua = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" end - local stdout = "" - local cmd = string.format('curl -skL --user-agent "%s" --retry 3 --connect-timeout 3 "%s"', ua, url) - if file then - cmd = cmd .. " -o " .. file - stdout = luci.sys.call(cmd .. " > /dev/null") - return stdout - else - stdout = luci.sys.exec(cmd) - return trim(stdout) - end - - if not stdout or #stdout <= 0 then - if uci:get(appname, "@global_subscribe[0]", "subscribe_proxy") or "0" == "1" and uci:get(appname, "@global[0]", "enabled") or "0" == "1" then - log('通过代理订阅失败,尝试关闭代理订阅。') - luci.sys.call("/etc/init.d/" .. appname .. " stop > /dev/null") - stdout = luci.sys.exec(string.format('curl -skL --user-agent "%s" -k --retry 3 --connect-timeout 3 "%s"', ua, url)) - end - end - return trim(stdout) + local args = { + "-skL", "--retry 3", "--connect-timeout 3", '--user-agent "' .. ua .. '"' + } + local result = api.curl_logic(url, file, args) + return result end local function truncate_nodes(add_from) @@ -1015,7 +1000,7 @@ end local execute = function() do local subscribe_list = {} - local retry = {} + local fail_list = {} if arg[2] then string.gsub(arg[2], '[^' .. "," .. ']+', function(w) subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {} @@ -1066,7 +1051,7 @@ local execute = function() os.remove("/tmp/" .. cfgid) parse_link(raw, "2", remark) else - retry[#retry + 1] = value + fail_list[#fail_list + 1] = value end allowInsecure_default = true filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0" @@ -1075,13 +1060,9 @@ local execute = function() ss_aead_type_default = uci:get(appname, "@global_subscribe[0]", "ss_aead_type") or "shadowsocks-libev" end - if #retry > 0 then - for index, value in ipairs(retry) do - if (uci:get(appname, "@global_subscribe[0]", "subscribe_proxy") or "0") == "1" and (uci:get(appname, "@global[0]", "enabled") or "0") == "1" then - log(value.remark .. '订阅失败,请尝试关闭代理后再订阅。') - else - log(value.remark .. '订阅失败,可能是订阅地址失效,或是网络问题,请诊断!') - end + if #fail_list > 0 then + for index, value in ipairs(fail_list) do + log(value.remark .. '订阅失败,可能是订阅地址失效,或是网络问题,请诊断!') end end update_node(0) diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-monitor b/luci-app-ssr-plus/root/usr/bin/ssr-monitor new file mode 100755 index 000000000..fb9ed57e7 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-monitor @@ -0,0 +1,124 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# +. $IPKG_INSTROOT/etc/init.d/shadowsocksr +LOCK_FILE="/var/lock/ssr-monitor.lock" +[ -f "$LOCK_FILE" ] && exit 2 +touch "$LOCK_FILE" +server_process_count=$1 +redir_tcp_process=$2 +redir_udp_process=$3 +kcp_process=$4 +local_process=$5 +pdnsd_process=$6 +if [ -z "$pdnsd_process" ]; then + pdnsd_process=0 +fi +i=0 +GLOBAL_SERVER=$(uci_get_by_type global global_server) +server=$(uci_get_by_name $GLOBAL_SERVER server) +kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port) +server_port=$(uci_get_by_name $GLOBAL_SERVER server_port) +password=$(uci_get_by_name $GLOBAL_SERVER kcp_password) +kcp_param=$(uci_get_by_name $GLOBAL_SERVER kcp_param) +[ "$password" != "" ] && password="--key "${password} + +while [ "1" == "1" ]; do #死循环 + sleep 000030s + #redir tcp + if [ "$redir_tcp_process" -gt 0 ]; then + icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l) + if [ "$icount" == 0 ]; then + logger -t "$NAME" "ssrplus redir tcp error.restart!" + echolog "ssrplus redir tcp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #redir udp + if [ "$redir_udp_process" -gt 0 ]; then + icount=$(busybox ps -w | grep ssr-reudp | grep -v grep | wc -l) + if [ "$icount" == 0 ]; then + logger -t "$NAME" "ssrplus redir udp error.restart!" + echolog "ssrplus redir udp error.restart!" + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #server + if [ "$server_process_count" -gt 0 ]; then + icount=$(busybox ps -w | grep ssr-server | grep -v grep | wc -l) + if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "ssrplus server error.restart!" + echolog "ssrplus server error.restart!" + kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #kcptun + if [ "$kcp_process" -gt 0 ]; then + icount=$(busybox ps -w | grep kcptun-client | grep -v grep | wc -l) + if [ "$icount" -lt "$kcp_process" ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "ssrplus kcptun error.restart!" + echolog "ssrplus kcptun error.restart!" + killall -q -9 kcptun-client + (/usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &) + fi + fi + #localsocks + if [ "$local_process" -gt 0 ]; then + icount=$(busybox ps -w | grep ssr-local | grep -v grep | wc -l) + if [ "$icount" -lt "$local_process" ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "global socks server error.restart!" + echolog "global socks server error.restart!" + kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + /etc/init.d/shadowsocksr restart + exit 0 + fi + fi + #dns2tcp + if [ "$pdnsd_process" -eq 1 ]; then + icount=$(busybox ps -w | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "dns2tcp tunnel error.restart!" + echolog "dns2tcp tunnel error.restart!" + dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) + kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + ln_start_bin $(first_type dns2tcp) dns2tcp -L "127.0.0.1#$dns_port" -R "${dnsserver/:/#}" + fi + #dns2socks + elif [ "$pdnsd_process" -eq 2 ]; then + icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l) + if [ "$icount" -lt 2 ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "dns2socks $dnsserver tunnel error.restart!" + echolog "dns2socks $dnsserver tunnel error.restart!" + dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53) + kill -9 $(busybox ps -w | grep ssrplus-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + kill -9 $(busybox ps -w | grep "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns + ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q + fi + fi + #chinadns-ng + if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then + icount=$(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l) + if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它 + logger -t "$NAME" "chinadns-ng tunnel error.restart!" + echolog "chinadns-ng tunnel error.restart!" + chinadns=$(uci_get_by_type global chinadns_forward) + wandns="$(ifstatus wan | jsonfilter -e '@["dns-server"][0]' || echo "119.29.29.29")" + case "$chinadns" in + "wan") chinadns="$wandns" ;; + ""|"wan_114") chinadns="$wandns,114.114.114.114" ;; + esac + kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + ln_start_bin $(first_type chinadns-ng) chinadns-ng -l $china_dns_port -4 china -p 3 -c ${chinadns/:/#} -t 127.0.0.1#$dns_port -N -f -r + fi + fi +done diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-rules b/luci-app-ssr-plus/root/usr/bin/ssr-rules new file mode 100755 index 000000000..4a85173fa --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-rules @@ -0,0 +1,426 @@ +#!/bin/sh +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# +TAG="_SS_SPEC_RULE_" # comment tag +IPT="iptables -t nat" # alias of iptables +FWI=$(uci get firewall.shadowsocksr.path 2>/dev/null) # firewall include file +usage() { + cat <<-EOF + Usage: ssr-rules [options] + + Valid options are: + + -s ip address of shadowsocksr remote server + -l port number of shadowsocksr local server + -S ip address of shadowsocksr remote UDP server + -L port number of shadowsocksr local UDP server + -i a file content is bypassed ip list + -a lan ip of access control, need a prefix to + define access control mode + -b wan ip of will be bypassed + -w wan ip of will be forwarded + -B lan ip of will be bypassed proxy + -p lan ip of will be global proxy + -G lan ip of will be game mode proxy + -D proxy ports + -F shunt mode + -N shunt server IP + -M shunt proxy mode + -m Interface name + -I a file content is bypassed shunt ip list + -e extra options for iptables + -o apply the rules to the OUTPUT chain + -O apply the global rules to the OUTPUT chain + -u enable udprelay mode, TPROXY is required + -U enable udprelay mode, using different IP + and ports for TCP and UDP + -f flush the rules + -g gfwlist mode + -r router mode + -c oversea mode + -z all mode + -h show this help message and exit + EOF + exit $1 +} + +loger() { + # 1.alert 2.crit 3.err 4.warn 5.notice 6.info 7.debug + logger -st ssr-rules[$$] -p$1 $2 +} + +flush_r() { + flush_iptables() { + local ipt="iptables -t $1" + local DAT=$(iptables-save -t $1) + eval $(echo "$DAT" | grep "$TAG" | sed -e 's/^-A/$ipt -D/' -e 's/$/;/') + for chain in $(echo "$DAT" | awk '/^:SS_SPEC/{print $1}'); do + $ipt -F ${chain:1} 2>/dev/null && $ipt -X ${chain:1} + done + } + flush_iptables nat + flush_iptables mangle + ip rule del fwmark 0x01/0x01 table 100 2>/dev/null + ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null + ipset -X ss_spec_lan_ac 2>/dev/null + ipset -X ss_spec_wan_ac 2>/dev/null + ipset -X ssr_gen_router 2>/dev/null + ipset -X fplan 2>/dev/null + ipset -X bplan 2>/dev/null + ipset -X gmlan 2>/dev/null + ipset -X oversea 2>/dev/null + ipset -X whitelist 2>/dev/null + ipset -X blacklist 2>/dev/null + ipset -X netflix 2>/dev/null + [ -n "$FWI" ] && echo '#!/bin/sh' >$FWI + return 0 +} + +ipset_r() { + [ -f "$IGNORE_LIST" ] && /usr/share/shadowsocksr/chinaipset.sh $IGNORE_LIST + $IPT -N SS_SPEC_WAN_AC + $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d $server -j RETURN + ipset -N gmlan hash:net 2>/dev/null + for ip in $LAN_GM_IP; do ipset -! add gmlan $ip; done + case "$RUNMODE" in + router) + ipset -! -R <<-EOF || return 1 + create ss_spec_wan_ac hash:net + $(gen_spec_iplist | sed -e "s/^/add ss_spec_wan_ac /") + EOF + $IPT -A SS_SPEC_WAN_AC -m set --match-set ss_spec_wan_ac dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + ;; + gfw) + ipset -N gfwlist hash:net 2>/dev/null + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j RETURN + $IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW + ;; + oversea) + ipset -N oversea hash:net 2>/dev/null + $IPT -I SS_SPEC_WAN_AC -m set --match-set oversea dst -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -j SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW + ;; + all) + $IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW + ;; + esac + ipset -N fplan hash:net 2>/dev/null + for ip in $LAN_FP_IP; do ipset -! add fplan $ip; done + $IPT -I SS_SPEC_WAN_AC -m set --match-set fplan src -j SS_SPEC_WAN_FW + ipset -N bplan hash:net 2>/dev/null + for ip in $LAN_BP_IP; do ipset -! add bplan $ip; done + $IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN + ipset -N whitelist hash:net 2>/dev/null + ipset -N blacklist hash:net 2>/dev/null + $IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW + $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN + if [ $(ipset list music -name -quiet | grep music) ]; then + $IPT -I SS_SPEC_WAN_AC -m set --match-set music dst -j RETURN 2>/dev/null + fi + for ip in $WAN_BP_IP; do ipset -! add whitelist $ip; done + for ip in $WAN_FW_IP; do ipset -! add blacklist $ip; done + if [ "$SHUNT_PORT" != "0" ]; then + ipset -N netflix hash:net 2>/dev/null + for ip in $(cat ${SHUNT_LIST:=/dev/null} 2>/dev/null); do ipset -! add netflix $ip; done + case "$SHUNT_PORT" in + 0) ;; + 1) + $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $local_port + ;; + *) + $IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports $SHUNT_PORT + if [ "$SHUNT_PROXY" == "1" ]; then + $IPT -I SS_SPEC_WAN_AC -p tcp -d $SHUNT_IP -j REDIRECT --to-ports $local_port + else + ipset -! add whitelist $SHUNT_IP + fi + ;; + esac + fi + return $? +} + +fw_rule() { + $IPT -N SS_SPEC_WAN_FW + $IPT -A SS_SPEC_WAN_FW -d 0.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 10.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 127.0.0.0/8 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 169.254.0.0/16 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 172.16.0.0/12 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 192.168.0.0/16 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 224.0.0.0/4 -j RETURN + $IPT -A SS_SPEC_WAN_FW -d 240.0.0.0/4 -j RETURN + $IPT -A SS_SPEC_WAN_FW -p tcp $PROXY_PORTS -j REDIRECT --to-ports $local_port 2>/dev/null || { + loger 3 "Can't redirect, please check the iptables." + exit 1 + } + return $? +} + +ac_rule() { + if [ -n "$LAN_AC_IP" ]; then + case "${LAN_AC_IP:0:1}" in + w | W) + MATCH_SET="-m set --match-set ss_spec_lan_ac src" + ;; + b | B) + MATCH_SET="-m set ! --match-set ss_spec_lan_ac src" + ;; + *) + loger 3 "Bad argument \`-a $LAN_AC_IP\`." + return 2 + ;; + esac + fi + ipset -! -R <<-EOF || return 1 + create ss_spec_lan_ac hash:net + $(for ip in ${LAN_AC_IP:1}; do echo "add ss_spec_lan_ac $ip"; done) + EOF + if [ -z "$Interface" ]; then + $IPT -I PREROUTING 1 -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network.$name.device 2>/dev/null) + [ -n "$IFNAME" ] && $IPT -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p tcp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + done + fi + + case "$OUTPUT" in + 1) + $IPT -I OUTPUT 1 -p tcp $EXT_ARGS -m comment --comment "$TAG" -j SS_SPEC_WAN_AC + ;; + 2) + ipset -! -R <<-EOF || return 1 + create ssr_gen_router hash:net + $(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /") + EOF + $IPT -N SS_SPEC_ROUTER && \ + $IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \ + $IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW + $IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER + ;; + esac + return $? +} + +tp_rule() { + [ -n "$TPROXY" ] || return 0 + ip rule add fwmark 0x01/0x01 table 100 + ip route add local 0.0.0.0/0 dev lo table 100 + local ipt="iptables -t mangle" + $ipt -N SS_SPEC_TPROXY + $ipt -A SS_SPEC_TPROXY -p udp --dport 53 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 0.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 10.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 127.0.0.0/8 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 169.254.0.0/16 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 172.16.0.0/12 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 192.168.0.0/16 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 224.0.0.0/4 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d $SERVER -j RETURN + [ "$server" != "$SERVER" ] && ipset -! add whitelist $SERVER + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + case "$RUNMODE" in + router) + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set ss_spec_wan_ac dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set ! --match-set ss_spec_wan_ac dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + ;; + gfw) + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set china dst -j RETURN + $ipt -A SS_SPEC_TPROXY -p udp --dport 443 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp --dport 80 -j DROP + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set gfwlist dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + ;; + oversea) + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set oversea src -m dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + ;; + all) + $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 + ;; + esac + if [ -z "$Interface" ]; then + $ipt -I PREROUTING 1 -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY + else + for name in $Interface; do + local IFNAME=$(uci -P /var/state get network.$name.ifname 2>/dev/null) + [ -z "$IFNAME" ] && IFNAME=$(uci -P /var/state get network.$name.device 2>/dev/null) + [ -n "$IFNAME" ] && $ipt -I PREROUTING 1 ${IFNAME:+-i $IFNAME} -p udp $EXT_ARGS $MATCH_SET -m comment --comment "$TAG" -j SS_SPEC_TPROXY + done + fi + return $? +} + +get_wan_ip() { + cat <<-EOF | grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" + $server + $SERVER + $WAN_BP_IP + EOF +} + +gen_spec_iplist() { + cat <<-EOF + 0.0.0.0/8 + 10.0.0.0/8 + 100.64.0.0/10 + 127.0.0.0/8 + 169.254.0.0/16 + 172.16.0.0/12 + 192.0.0.0/24 + 192.0.2.0/24 + 192.88.99.0/24 + 192.168.0.0/16 + 198.18.0.0/15 + 198.51.100.0/24 + 203.0.113.0/24 + 224.0.0.0/4 + 240.0.0.0/4 + 255.255.255.255 + $(get_wan_ip) + EOF +} + +gen_include() { + [ -n "$FWI" ] || return 0 + extract_rules() { + echo "*$1" + iptables-save -t $1 | grep SS_SPEC_ | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + echo 'COMMIT' + } + cat <<-EOF >>$FWI + iptables-save -c | grep -v "SS_SPEC" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules nat) + $(extract_rules mangle) + EOT + EOF + return 0 +} + +while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczh" arg; do + case "$arg" in + m) + Interface=$OPTARG + ;; + s) + server=$OPTARG + ;; + l) + local_port=$OPTARG + ;; + S) + SERVER=$OPTARG + ;; + L) + LOCAL_PORT=$OPTARG + ;; + i) + IGNORE_LIST=$OPTARG + ;; + e) + EXT_ARGS=$OPTARG + ;; + a) + LAN_AC_IP=$OPTARG + ;; + B) + LAN_BP_IP=$OPTARG + ;; + b) + WAN_BP_IP=$(for ip in $OPTARG; do echo $ip; done) + ;; + w) + WAN_FW_IP=$OPTARG + ;; + p) + LAN_FP_IP=$OPTARG + ;; + G) + LAN_GM_IP=$OPTARG + ;; + D) + PROXY_PORTS=$OPTARG + ;; + F) + SHUNT_PORT=$OPTARG + ;; + N) + SHUNT_IP=$OPTARG + ;; + M) + SHUNT_PROXY=$OPTARG + ;; + I) + SHUNT_LIST=$OPTARG + ;; + o) + OUTPUT=1 + ;; + O) + OUTPUT=2 + ;; + u) + TPROXY=1 + ;; + U) + TPROXY=2 + ;; + g) + RUNMODE=gfw + ;; + r) + RUNMODE=router + ;; + c) + RUNMODE=oversea + ;; + z) + RUNMODE=all + ;; + f) + flush_r + exit 0 + ;; + h) usage 0 ;; + esac +done + +if [ -z "$server" -o -z "$local_port" ]; then + usage 2 +fi + +case "$TPROXY" in +1) + SERVER=$server + LOCAL_PORT=$local_port + ;; +2) + : ${SERVER:?"You must assign an ip for the udp relay server."} + : ${LOCAL_PORT:?"You must assign a port for the udp relay server."} + ;; +esac + +flush_r && fw_rule && ipset_r && ac_rule && tp_rule && gen_include +RET=$? +[ "$RET" = 0 ] || loger 3 "Start failed!" +exit $RET diff --git a/luci-app-ssr-plus/root/usr/bin/ssr-switch b/luci-app-ssr-plus/root/usr/bin/ssr-switch new file mode 100755 index 000000000..5a2a37090 --- /dev/null +++ b/luci-app-ssr-plus/root/usr/bin/ssr-switch @@ -0,0 +1,155 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2017 openwrt-ssr +# Copyright (C) 2017 yushi studio +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +. $IPKG_INSTROOT/etc/init.d/shadowsocksr +LOCK_FILE="/var/lock/ssr-switch.lock" +[ -f "$LOCK_FILE" ] && exit 2 +touch "$LOCK_FILE" +LOG_FILE=/var/log/ssrplus.log + +cycle_time=60 +switch_time=3 +normal_flag=0 +server_locate=0 +server_count=0 +ENABLE_SERVER=nil +[ -n "$1" ] && cycle_time=$1 +[ -n "$2" ] && switch_time=$2 +DEFAULT_SERVER=$(uci_get_by_type global global_server) +CURRENT_SERVER=$DEFAULT_SERVER + +#判断代理是否正常 +check_proxy() { + local result=0 + local try_count=$(uci_get_by_type global switch_try_count 3) + for i in $(seq 1 $try_count); do + /usr/bin/ssr-check www.google.com 80 $switch_time 1 + if [ "$?" == "0" ]; then + # echolog "Check Google Proxy Success, count=$i" + result=0 + break + else + # echolog "Check Google Proxy Fail, count=$i" + /usr/bin/ssr-check www.baidu.com 80 $switch_time 1 + if [ "$?" == "0" ]; then + result=1 + else + result=2 + fi + fi + sleep 1 + done + return $result +} + +test_proxy() { + local servername=$(uci_get_by_name $1 server) + local serverport=$(uci_get_by_name $1 server_port) + ipset add whitelist $servername 2>/dev/null + tcping -q -c 3 -i 1 -t 2 -p $serverport $servername + if [ "$?" -gt "0" ]; then + ipset del whitelist $servername 2>/dev/null + return 1 + fi + /usr/bin/ssr-check $servername $serverport $switch_time + local ret=$? + ipset del whitelist $servername 2>/dev/null + if [ "$ret" == "0" ]; then + return 0 + else + return 1 + fi +} + +search_proxy() { + let server_count=server_count+1 + [ "$normal_flag" == "1" -a "$server_count" -le "$server_locate" ] && return 0 + [ "$(uci_get_by_name $1 switch_enable 0)" != "1" ] && return 1 + [ $ENABLE_SERVER != nil ] && return 0 + [ "$1" == "$CURRENT_SERVER" ] && return 0 + local servername=$(uci_get_by_name $1 server) + local serverport=$(uci_get_by_name $1 server_port) + ipset add whitelist $servername 2>/dev/null + /usr/bin/ssr-check $servername $serverport $switch_time + local ret=$? + ipset del whitelist $servername 2>/dev/null + if [ "$ret" == "0" ]; then + server_locate=$server_count + ENABLE_SERVER=$1 + return 0 + else + return 1 + fi +} + +#选择可用的代理 +select_proxy() { + config_load $NAME + ENABLE_SERVER=nil + mkdir -p /var/run /var/etc + server_count=0 + config_foreach search_proxy servers +} + +#切换代理 +switch_proxy() { + /etc/init.d/shadowsocksr restart $1 + return 0 +} + +start() { + #不支持kcptun启用时的切换 + [ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1 + while [ "1" == "1" ]; do #死循环 + sleep 0000$cycle_time + LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") + #判断当前代理是否为缺省服务器 + if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ]; then + #echo "not default proxy" + echolog "Current server is not default Main server, try to switch back." + #检查缺省服务器是否正常 + if test_proxy $DEFAULT_SERVER; then + #echo "switch to default proxy" + echolog "Main server is avilable." + #缺省服务器正常,切换回来 + CURRENT_SERVER=$DEFAULT_SERVER + switch_proxy $CURRENT_SERVER + echolog "switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" + else + echolog "Main server is NOT avilable.Continue using current server." + fi + fi + #判断当前代理是否正常 + #echolog "Start checking if the current server is available." + check_proxy + current_ret=$? + if [ "$current_ret" == "1" ]; then + #当前代理错误,判断有无可用的服务器 + #echo "current error" + echolog "Current server error, try to switch another server." + select_proxy + if [ "$ENABLE_SERVER" != nil ]; then + #有其他服务器可用,进行切换 + #echo $(uci_get_by_name $new_proxy server) + echolog "Another server is avilable, now switching server." + CURRENT_SERVER=$ENABLE_SERVER + switch_proxy $CURRENT_SERVER + normal_flag=1 + echolog "Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!" + else + switch_proxy $CURRENT_SERVER + normal_flag=1 + echolog "Try restart current server." + fi + else + normal_flag=0 + # echolog "ShadowsocksR No Problem." + fi + done +}