Merge Mainline

This commit is contained in:
CN_SZTL 2020-07-31 21:46:49 +08:00
commit e6b52447eb
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
207 changed files with 3197 additions and 83917 deletions

View File

@ -19,7 +19,6 @@ Package zxlhhyccc: [zxlhhyccc/MY-lede](https://github.com/zxlhhyccc/MY-lede).<br
luci-theme-argonv3 source: [jerrykuku/luci-theme-argon](https://github.com/jerrykuku/luci-theme-argon).<br/>
luci-theme-darkmatter source: [apollo-ng/luci-theme-darkmatter](https://github.com/apollo-ng/luci-theme-darkmatter).<br/>
openwrt-chinadns-ng source: [pexcn/openwrt-chinadns-ng](https://github.com/pexcn/openwrt-chinadns-ng).<br/>
luci-app-ssr-plus-Jo source: [Leo-Jo-My/luci-app-ssr-plus-Jo](https://github.com/Leo-Jo-My/luci-app-ssr-plus-Jo).<br/>
openwrt-udpspeeder source: [zhfreal/openwrt-UDPspeeder](https://github.com/zhfreal/openwrt-UDPspeeder).<br/>
luci-app-onliner source: [rufengsuixing/luci-app-onliner](https://github.com/rufengsuixing/luci-app-onliner).<br/>
luci-app-dockerman source: [KFERMercer/luci-app-dockerman](https://github.com/KFERMercer/luci-app-dockerman).<br/>
@ -29,7 +28,6 @@ luci-app-autoipsetadder source: [rufengsuixing/luci-app-autoipsetadder](https://
luci-app-adguardhome source: [rufengsuixing/luci-app-adguardhome](https://github.com/rufengsuixing/luci-app-adguardhome).<br/>
Rclone-OpenWrt source: [ElonH/Rclone-OpenWrt](https://github.com/ElonH/Rclone-OpenWrt).<br/>
luci-app-usb3disable source: [rufengsuixing/luci-app-usb3disable](https://github.com/rufengsuixing/luci-app-usb3disable).<br/>
luci-app-vssr source: [Leo-Jo-My/luci-app-vssr](https://github.com/Leo-Jo-My/luci-app-vssr).<br/>
luci-app-diskman source: [lisaac/luci-app-diskman](https://github.com/lisaac/luci-app-diskman).<br/>
NanoPi R1s(h5) support: [jerrykuku/openwrt-nanopi-r1s-h5](https://github.com/jerrykuku/openwrt-nanopi-r1s-h5).<br/>
NanoPi support: [speedyworldclub/nlede](https://github.com/speedyworldclub/nlede).<br/>
@ -56,7 +54,8 @@ node-request source: [jerrykuku/node-request](https://github.com/jerrykuku/node-
luci-app-jd-dailybonus source: [jerrykuku/luci-app-jd-dailybonus](https://github.com/jerrykuku/luci-app-jd-dailybonus).<br/>
luci-app-oled source: [NateLol/luci-app-oled](https://github.com/NateLol/luci-app-oled).<br/>
luci-theme-edge source: [garypang13/luci-theme-edge](https://github.com//garypang13/luci-theme-edge).<br/>
luci-app-beardropper source: [NateLol/natelol](https://github.com/NateLol/natelol).
luci-app-beardropper source: [NateLol/natelol](https://github.com/NateLol/natelol).<br/>
luci-app-vssr source: [jerrykuku/luci-app-vssr](https://github.com/jerrykuku/luci-app-vssr).
## License
### Depend on their own License.

View File

@ -88,18 +88,36 @@ prereq: $(target/stamp-prereq) tmp/.prereq_packages
exit 1; \
fi
$(BIN_DIR)/profiles.json: FORCE
$(if $(CONFIG_JSON_OVERVIEW_IMAGE_INFO), \
WORK_DIR=$(BUILD_DIR)/json_info_files \
$(SCRIPT_DIR)/json_overview_image_info.py $@ \
)
json_overview_image_info: $(BIN_DIR)/profiles.json
checksum: FORCE
$(call sha256sums,$(BIN_DIR),$(CONFIG_BUILDBOT))
buildversion: FORCE
$(SCRIPT_DIR)/getver.sh > $(BIN_DIR)/version.buildinfo
feedsversion: FORCE
$(SCRIPT_DIR)/feeds list -fs > $(BIN_DIR)/feeds.buildinfo
diffconfig: FORCE
mkdir -p $(BIN_DIR)
$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.seed
$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.buildinfo
buildinfo: FORCE
$(_SINGLE)$(SUBMAKE) -r diffconfig buildversion feedsversion
prepare: .config $(tools/stamp-compile) $(toolchain/stamp-compile)
$(_SINGLE)$(SUBMAKE) -r diffconfig
$(_SINGLE)$(SUBMAKE) -r buildinfo
world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
$(_SINGLE)$(SUBMAKE) -r package/index
$(_SINGLE)$(SUBMAKE) -r json_overview_image_info
$(_SINGLE)$(SUBMAKE) -r checksum
.PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean

View File

@ -269,7 +269,7 @@ define Build/xor-image
endef
define Build/check-size
@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $@)" ] || { \
@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(if $(1),$(1),$(IMAGE_SIZE)))))) -ge "$$(stat -c%s $@)" ] || { \
echo "WARNING: Image file $@ is too big" >&2; \
rm -f $@; \
}

View File

@ -1,132 +0,0 @@
########################################################
#
# RELEASE NOTES
#
########################################################
########################################################
//
// 0.8.1 2020-07-16
//
//
########################################################
Updates
- UPDATE: 修正部分cookie无法更新到脚本的问题。
########################################################
//
// 0.8 2020-07-15
//
//
########################################################
Updates
- NEW: 增加了使用Server酱推送签到结果到微信的功能。
- NEW: 增加了仅当cookie失效时进行微信推送的功能。
- NEW: 增加了一个自定义延迟签到的选项,能够避免并发签到带来的负面影响。
- UPDATE: 修正了在不勾选自动签到或者自动更新选项时点击保存Cookie并签到无法执行的问题。
- UPDATE: 代码精简与优化。
########################################################
//
// 0.7.8 2020-07-13
//
//
########################################################
Updates
- UPDATE: 修改了签到时间策略将原来的固定时间修改为设定时间后的180秒间随机执行感谢kid424 提供方案)。
########################################################
//
// 0.7.7 2020-07-10
// 大幅修改,建议卸载后重新安装
//
########################################################
Updates
- UPDATE: 对整个插件进行了重构cookie更新机制做了修改。
- UPDATE: 增加新的栏目可以自行编辑脚本的cookie。
- UPDATE: 增加每天定时开关,可从脚本作者源更新脚本。
- UPDATE: 将当前的打开插件自动检测版本,修改为手动检查,检查到新版本可点击更新。
########################################################
//
// 0.7.5 2020-06-25
// 小幅修正
//
########################################################
Updates
- BUGFIX: 使用wget取代curl 现在不需要curl依赖了
- UPDATE: 增加 当前版本显示
########################################################
//
// 0.7.4 2020-06-07
// 小幅修正
//
########################################################
Updates
- BUGFIX: 修正编译依赖
- BUGFIX: 修正弹窗log无法自动关闭的bug
########################################################
//
// 0.7 2020-05-27
// 小幅修正
//
########################################################
Updates
- BUGFIX: 修正部分文字翻译错误
- UPD: 改善log输出方式
- UPD: 不再对脚本检测进行锁定,可以强制更新。
########################################################
//
// 0.6 2020-05-09
// 增加脚本在线版本检测和更新功能
//
########################################################
Updates
- UPD: 增加脚本在线版本检测和更新功能
########################################################
//
// 0.5 2020-05-06
// bug修复
//
########################################################
Updates
- UPD: 增加了一个cookie工具zip包如果crx安装不上可以解压zip包内容加载已解压的扩展包。
- UPD: 增加了第二个账号的cookie可以实现双签到
- UPD: 修复部分文字解释
########################################################==
//
// END RELEASE NOTES
//
########################################################==

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-openclash
PKG_VERSION:=0.39.5
PKG_VERSION:=0.39.6
PKG_RELEASE:=beta
PKG_MAINTAINER:=vernesong <https://github.com/vernesong/OpenClash>

View File

@ -5211,7 +5211,6 @@ rules:
- DOMAIN-SUFFIX,m.xxkio.com,AdBlock
- DOMAIN-SUFFIX,m.yalayi.com,AdBlock
- DOMAIN-SUFFIX,m.yangjingbang.net,AdBlock
- DOMAIN-SUFFIX,m.yap.yahoo.com,AdBlock
- DOMAIN-SUFFIX,m.yicang8.com,AdBlock
- DOMAIN-SUFFIX,m.yingchengtou.com,AdBlock
- DOMAIN-SUFFIX,m.ynnke.com,AdBlock
@ -8489,6 +8488,7 @@ rules:
- DOMAIN-SUFFIX,bilivideo.com,AsianTV
- DOMAIN-SUFFIX,hdslb.com,AsianTV
- DOMAIN-SUFFIX,im9.com,AsianTV
- DOMAIN-SUFFIX,smtcdns.net,AsianTV
# > IQIYI
- DOMAIN-KEYWORD,qiyi,AsianTV
@ -8533,11 +8533,12 @@ rules:
- DOMAIN-SUFFIX,amazonaws.com,GlobalTV
- DOMAIN-SUFFIX,amazonvideo.com,GlobalTV
- DOMAIN-SUFFIX,llnwd.net,GlobalTV
- DOMAIN-SUFFIX,primevideo.com,GlobalTV
# > Apple News and Apple Map TOMTOM Version
# - USER-AGENT,AppleNews*,GlobalTV
# - USER-AGENT,com.apple.news*,GlobalTV
- DOMAIN,gspe1-ssl.ls.apple.com,GlobalTV
# - DOMAIN,gspe1-ssl.ls.apple.com,GlobalTV
# - USER-AGENT,News*,GlobalTV
# - DOMAIN,apple.comscoreresearch.com,GlobalTV
# - DOMAIN,gateway.icloud.com,GlobalTV
@ -8701,20 +8702,6 @@ rules:
- DOMAIN-SUFFIX,viu.tv,GlobalTV
- DOMAIN-SUFFIX,viu.now.com,GlobalTV
# > Youtube Music
# - USER-AGENT,*YouTubeMusic*,GlobalTV
# - USER-AGENT,*com.google.ios.youtubemusic*,GlobalTV
# > Youtube
# - USER-AGENT,*youtube*,GlobalTV
# - USER-AGENT,YouTube*,GlobalTV
- DOMAIN-KEYWORD,youtube,GlobalTV
- DOMAIN,yt3.ggpht.com,GlobalTV
- DOMAIN-SUFFIX,googlevideo.com,GlobalTV
- DOMAIN-SUFFIX,gvt2.com,GlobalTV
- DOMAIN-SUFFIX,youtu.be,GlobalTV
- DOMAIN-SUFFIX,ytimg.com,GlobalTV
# > Netflix
@ -8789,22 +8776,13 @@ rules:
- IP-CIDR,170.249.179.114/32,Netflix
- IP-CIDR,170.52.52.130/32,Netflix
- IP-CIDR,172.56.128.126/32,Netflix
- IP-CIDR,172.56.128.126/32,Netflix
- IP-CIDR,172.56.132.126/32,Netflix
- IP-CIDR,172.56.132.126/32,Netflix
- IP-CIDR,172.56.133.126/32,Netflix
- IP-CIDR,172.56.133.126/32,Netflix
- IP-CIDR,172.56.138.126/32,Netflix
- IP-CIDR,172.56.138.126/32,Netflix
- IP-CIDR,172.56.139.126/32,Netflix
- IP-CIDR,172.56.139.126/32,Netflix
- IP-CIDR,172.56.140.126/32,Netflix
- IP-CIDR,172.56.140.126/32,Netflix
- IP-CIDR,172.56.141.126/32,Netflix
- IP-CIDR,172.56.141.126/32,Netflix
- IP-CIDR,172.56.143.126/32,Netflix
- IP-CIDR,172.56.143.126/32,Netflix
- IP-CIDR,172.56.145.66/32,Netflix
- IP-CIDR,172.56.145.66/32,Netflix
- IP-CIDR,173.219.132.226/32,Netflix
- IP-CIDR,173.219.132.229/32,Netflix
@ -8971,12 +8949,10 @@ rules:
- IP-CIDR,184.150.15.99/32,Netflix
- IP-CIDR,184.175.190.38/32,Netflix
- IP-CIDR,185.43.181.232/32,Netflix
- IP-CIDR,185.43.181.232/32,Netflix
- IP-CIDR,185.43.181.234/32,Netflix
- IP-CIDR,185.43.181.236/32,Netflix
- IP-CIDR,185.43.181.238/32,Netflix
- IP-CIDR,185.43.181.240/32,Netflix
- IP-CIDR,185.43.181.240/32,Netflix
- IP-CIDR,185.43.181.246/32,Netflix
- IP-CIDR,185.97.110.36/32,Netflix
- IP-CIDR,186.15.229.194/32,Netflix
@ -8996,7 +8972,6 @@ rules:
- IP-CIDR,188.47.196.252/32,Netflix
- IP-CIDR,188.47.196.253/32,Netflix
- IP-CIDR,188.47.208.242/32,Netflix
- IP-CIDR,188.47.208.242/32,Netflix
- IP-CIDR,189.194.232.193/32,Netflix
- IP-CIDR,189.194.232.194/32,Netflix
- IP-CIDR,189.194.232.195/32,Netflix
@ -9013,10 +8988,7 @@ rules:
- IP-CIDR,190.98.134.144/32,Netflix
- IP-CIDR,190.98.134.146/32,Netflix
- IP-CIDR,190.98.156.141/32,Netflix
- IP-CIDR,190.98.156.141/32,Netflix
- IP-CIDR,190.98.156.149/32,Netflix
- IP-CIDR,190.98.156.149/32,Netflix
- IP-CIDR,190.98.156.183/32,Netflix
- IP-CIDR,190.98.156.183/32,Netflix
- IP-CIDR,192.148.237.10/32,Netflix
- IP-CIDR,192.148.237.130/32,Netflix
@ -9037,14 +9009,10 @@ rules:
- IP-CIDR,193.212.179.82/32,Netflix
- IP-CIDR,193.212.179.98/32,Netflix
- IP-CIDR,193.247.193.100/32,Netflix
- IP-CIDR,193.247.193.100/32,Netflix
- IP-CIDR,193.247.193.38/32,Netflix
- IP-CIDR,193.247.193.72/32,Netflix
- IP-CIDR,193.247.193.74/32,Netflix
- IP-CIDR,193.247.193.74/32,Netflix
- IP-CIDR,193.247.193.99/32,Netflix
- IP-CIDR,193.247.193.99/32,Netflix
- IP-CIDR,194.228.248.66/32,Netflix
- IP-CIDR,194.228.248.66/32,Netflix
- IP-CIDR,195.121.126.132/32,Netflix
- IP-CIDR,195.121.126.139/32,Netflix
@ -9110,26 +9078,19 @@ rules:
- IP-CIDR,203.116.200.130/32,Netflix
- IP-CIDR,203.116.200.131/32,Netflix
- IP-CIDR,203.116.200.134/32,Netflix
- IP-CIDR,203.116.200.134/32,Netflix
- IP-CIDR,203.116.200.135/32,Netflix
- IP-CIDR,203.116.200.136/32,Netflix
- IP-CIDR,203.116.200.136/32,Netflix
- IP-CIDR,203.116.200.137/32,Netflix
- IP-CIDR,203.116.210.132/32,Netflix
- IP-CIDR,203.116.210.133/32,Netflix
- IP-CIDR,203.116.210.133/32,Netflix
- IP-CIDR,203.116.210.134/32,Netflix
- IP-CIDR,203.116.210.135/32,Netflix
- IP-CIDR,203.116.210.136/32,Netflix
- IP-CIDR,203.116.210.137/32,Netflix
- IP-CIDR,203.116.210.196/32,Netflix
- IP-CIDR,203.116.210.196/32,Netflix
- IP-CIDR,203.116.210.197/32,Netflix
- IP-CIDR,203.116.210.198/32,Netflix
- IP-CIDR,203.116.210.198/32,Netflix
- IP-CIDR,203.116.210.199/32,Netflix
- IP-CIDR,203.116.210.199/32,Netflix
- IP-CIDR,203.116.210.200/32,Netflix
- IP-CIDR,203.116.210.200/32,Netflix
- IP-CIDR,203.116.210.201/32,Netflix
- IP-CIDR,203.177.54.2/32,Netflix
@ -9178,17 +9139,11 @@ rules:
- IP-CIDR,208.180.59.229/32,Netflix
- IP-CIDR,208.54.16.65/32,Netflix
- IP-CIDR,208.54.2.3/32,Netflix
- IP-CIDR,208.54.2.3/32,Netflix
- IP-CIDR,208.54.37.30/32,Netflix
- IP-CIDR,208.54.37.30/32,Netflix
- IP-CIDR,208.54.66.30/32,Netflix
- IP-CIDR,208.54.67.30/32,Netflix
- IP-CIDR,208.54.67.30/32,Netflix
- IP-CIDR,208.54.70.30/32,Netflix
- IP-CIDR,208.54.70.30/32,Netflix
- IP-CIDR,208.54.80.30/32,Netflix
- IP-CIDR,208.54.80.30/32,Netflix
- IP-CIDR,208.54.85.30/32,Netflix
- IP-CIDR,208.54.85.30/32,Netflix
- IP-CIDR,208.76.186.5/32,Netflix
- IP-CIDR,208.76.186.50/32,Netflix
@ -9274,13 +9229,10 @@ rules:
- IP-CIDR,40.133.138.47/32,Netflix
- IP-CIDR,40.133.138.57/32,Netflix
- IP-CIDR,43.245.105.1/32,Netflix
- IP-CIDR,43.245.105.1/32,Netflix
- IP-CIDR,43.245.105.11/32,Netflix
- IP-CIDR,43.245.105.11/32,Netflix
- IP-CIDR,43.245.105.129/32,Netflix
- IP-CIDR,43.245.105.13/32,Netflix
- IP-CIDR,43.245.105.9/32,Netflix
- IP-CIDR,43.245.105.9/32,Netflix
- IP-CIDR,45.121.219.34/32,Netflix
- IP-CIDR,45.57.56.130/32,Netflix
- IP-CIDR,49.231.114.6/32,Netflix
@ -9295,7 +9247,6 @@ rules:
- IP-CIDR,51.148.80.22/32,Netflix
- IP-CIDR,51.148.80.6/32,Netflix
- IP-CIDR,58.27.11.201/32,Netflix
- IP-CIDR,58.27.11.201/32,Netflix
- IP-CIDR,58.27.38.199/32,Netflix
- IP-CIDR,62.127.102.10/32,Netflix
- IP-CIDR,62.127.102.14/32,Netflix
@ -9637,9 +9588,26 @@ rules:
# > Spotify
# - USER-AGENT,*Spotify*,Spotify
- DOMAIN-KEYWORD,spotify,Spotify
- DOMAIN-SUFFIX,pscdn.co,Spotify
- DOMAIN-SUFFIX,scdn.co,Spotify
- DOMAIN-SUFFIX,spoti.fi,Spotify
- DOMAIN-SUFFIX,spotify.com,Spotify
- DOMAIN-SUFFIX,spotifycdn.net,Spotify
# > Youtube Music
# - USER-AGENT,*YouTubeMusic*,Youtube
# - USER-AGENT,*com.google.ios.youtubemusic*,Youtube
# > Youtube
# - USER-AGENT,*youtube*,Youtube
# - USER-AGENT,YouTube*,Youtube
- DOMAIN-KEYWORD,youtube,Youtube
- DOMAIN,yt3.ggpht.com,Youtube
- DOMAIN-SUFFIX,googlevideo.com,Youtube
- DOMAIN-SUFFIX,gvt2.com,Youtube
- DOMAIN-SUFFIX,youtu.be,Youtube
- DOMAIN-SUFFIX,ytimg.com,Youtube
# > Telegram
@ -9970,7 +9938,7 @@ rules:
- DOMAIN-SUFFIX,gvt0.com,Proxy
- DOMAIN-SUFFIX,gvt1.com,Proxy
- DOMAIN-SUFFIX,helpshift.com,Proxy
- DOMAIN-SUFFIX,hinet.net,Proxy
- DOMAIN-SUFFIX,hitun.io,Proxy
- DOMAIN-SUFFIX,hockeyapp.net,Proxy
- DOMAIN-SUFFIX,homedepot.com,Proxy
- DOMAIN-SUFFIX,hootsuite.com,Proxy
@ -10031,6 +9999,7 @@ rules:
- DOMAIN-SUFFIX,macid.co,Proxy
- DOMAIN-SUFFIX,macromedia.com,Proxy
- DOMAIN-SUFFIX,macrumors.com,Proxy
- DOMAIN-SUFFIX,mangaup.jp,Proxy
- DOMAIN-SUFFIX,manhuaren.com,Proxy
- DOMAIN-SUFFIX,marketwatch.com,Proxy
- DOMAIN-SUFFIX,mashable.com,Proxy
@ -10056,7 +10025,9 @@ rules:
- DOMAIN-SUFFIX,netdna-cdn.com,Proxy
- DOMAIN-SUFFIX,newipnow.com,Proxy
- DOMAIN-SUFFIX,nextmedia.com,Proxy
- DOMAIN-SUFFIX,nicovideo.jp,Proxy
- DOMAIN-SUFFIX,nih.gov,Proxy
- DOMAIN-SUFFIX,nimg.jp,Proxy
- DOMAIN-SUFFIX,nintendo.com,Proxy
- DOMAIN-SUFFIX,nintendo.net,Proxy
- DOMAIN-SUFFIX,notion.so,Proxy
@ -10383,7 +10354,6 @@ rules:
- DOMAIN-SUFFIX,gcr.io,Proxy
- DOMAIN-SUFFIX,gmail.com,Proxy
- DOMAIN-SUFFIX,gosetsuden.jp,Proxy
- DOMAIN-SUFFIX,gvt1.com,Proxy
- DOMAIN-SUFFIX,gwtproject.org,Proxy
- DOMAIN-SUFFIX,heroku.com,Proxy
- DOMAIN-SUFFIX,html5rocks.com,Proxy
@ -10548,7 +10518,6 @@ rules:
- DOMAIN-SUFFIX,bababian.com,Domestic
- DOMAIN-SUFFIX,baidu.com,Domestic
- DOMAIN-SUFFIX,baidupcs.com,Domestic
- DOMAIN-SUFFIX,battle.net,Domestic
- DOMAIN-SUFFIX,bdimg.com,Domestic
- DOMAIN-SUFFIX,bdstatic.com,Domestic
- DOMAIN-SUFFIX,beatsbydre.com,Domestic
@ -10639,6 +10608,8 @@ rules:
- DOMAIN-SUFFIX,lxdns.com,Domestic
- DOMAIN-SUFFIX,mai.tn,Domestic
- DOMAIN-SUFFIX,meizu.com,Domestic
- DOMAIN-SUFFIX,metatrader4.com,Domestic
- DOMAIN-SUFFIX,metatrader5.com,Domestic
- DOMAIN-SUFFIX,mi.com,Domestic
- DOMAIN-SUFFIX,miaopai.com,Domestic
- DOMAIN-SUFFIX,miui.com,Domestic

File diff suppressed because one or more lines are too long

View File

@ -308,6 +308,12 @@ o:depends("rule_source", "ConnersHua_return")
o:value(l)
end
file:seek("set")
o = s:taboption("rules", ListValue, "Youtube", translate("Youtube"))
o:depends("rule_source", "lhie1")
for l in file:lines() do
o:value(l)
end
file:seek("set")
o = s:taboption("rules", ListValue, "Apple", translate("Apple"))
o:depends("rule_source", "lhie1")
for l in file:lines() do

View File

@ -704,6 +704,20 @@ EOF
fi
cat /tmp/Proxy_Provider >> $SERVER_FILE 2>/dev/null
cat >> "$SERVER_FILE" <<-EOF
- name: Youtube
type: select
proxies:
- GlobalTV
- DIRECT
EOF
cat /tmp/Proxy_Server >> $SERVER_FILE 2>/dev/null
if [ -f "/tmp/Proxy_Provider" ]; then
cat >> "$SERVER_FILE" <<-EOF
use:
EOF
fi
cat /tmp/Proxy_Provider >> $SERVER_FILE 2>/dev/null
cat >> "$SERVER_FILE" <<-EOF
- name: Spotify
type: select
proxies:
@ -825,6 +839,7 @@ ${UCI_SET}rule_source="lhie1"
${UCI_SET}GlobalTV="GlobalTV"
${UCI_SET}AsianTV="AsianTV"
${UCI_SET}Proxy="Proxy"
${UCI_SET}Youtube="Youtube"
${UCI_SET}Apple="Apple"
${UCI_SET}Microsoft="Microsoft"
${UCI_SET}Netflix="Netflix"
@ -841,6 +856,7 @@ ${UCI_SET}Others="Others"
${UCI_SET}servers_update="1"
${UCI_DEL_LIST}="Auto - UrlTest" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Auto - UrlTest" >/dev/null 2>&1
${UCI_DEL_LIST}="Proxy" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Proxy" >/dev/null 2>&1
${UCI_DEL_LIST}="Youtube" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Youtube" >/dev/null 2>&1
${UCI_DEL_LIST}="AsianTV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="AsianTV" >/dev/null 2>&1
${UCI_DEL_LIST}="GlobalTV" >/dev/null 2>&1 && ${UCI_ADD_LIST}="GlobalTV" >/dev/null 2>&1
${UCI_DEL_LIST}="Netflix" >/dev/null 2>&1 && ${UCI_ADD_LIST}="Netflix" >/dev/null 2>&1

View File

@ -84,6 +84,7 @@ if [ "$2" != 0 ]; then
GlobalTV=$(uci get openclash.config.GlobalTV 2>/dev/null)
AsianTV=$(uci get openclash.config.AsianTV 2>/dev/null)
Proxy=$(uci get openclash.config.Proxy 2>/dev/null)
Youtube=$(uci get openclash.config.Youtube 2>/dev/null)
Apple=$(uci get openclash.config.Apple 2>/dev/null)
Netflix=$(uci get openclash.config.Netflix 2>/dev/null)
Spotify=$(uci get openclash.config.Spotify 2>/dev/null)
@ -117,6 +118,7 @@ if [ "$2" != 0 ]; then
if [ -z "$(grep "$GlobalTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$AsianTV" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Proxy" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Youtube" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Apple" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Netflix" /tmp/Proxy_Group)" ]\
|| [ -z "$(grep "$Spotify" /tmp/Proxy_Group)" ]\
@ -156,6 +158,7 @@ if [ "$2" != 0 ]; then
GlobalTV_YAML=$(grep '##GlobalTV:' "$4" |awk -F ':' '{print $2}')
AsianTV_YAML=$(grep '##AsianTV:' "$4" |awk -F ':' '{print $2}')
Proxy_YAML=$(grep '##Proxy:' "$4" |awk -F ':' '{print $2}')
Youtube_YAML=$(grep '##Youtube:' "$4" |awk -F ':' '{print $2}')
Apple_YAML=$(grep '##Apple:' "$4" |awk -F ':' '{print $2}')
Netflix_YAML=$(grep '##Netflix:' "$4" |awk -F ':' '{print $2}')
Spotify_YAML=$(grep '##Spotify:' "$4" |awk -F ':' '{print $2}')
@ -186,6 +189,7 @@ if [ "$2" != 0 ]; then
if [ "$GlobalTV" != "$GlobalTV_YAML" ]\
|| [ "$AsianTV" != "$AsianTV_YAML" ]\
|| [ "$Proxy" != "$Proxy_YAML" ]\
|| [ "$Youtube" != "$Youtube_YAML" ]\
|| [ "$Apple" != "$Apple_YAML" ]\
|| [ "$Netflix" != "$Netflix_YAML" ]\
|| [ "$Spotify" != "$Spotify_YAML" ]\
@ -217,6 +221,9 @@ if [ "$2" != 0 ]; then
sed -i "s/,Proxy$/,${Proxy}#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "s/,Proxy,no-resolve$/,${Proxy},no-resolve#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "/rules:/a\##Proxy:${Proxy}" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "s/,Youtube$/,${Youtube}#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "s/,Youtube,no-resolve$/,${Youtube},no-resolve#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "/rules:/a\##Youtube:${Youtube}" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "s/,Apple$/,${Apple}#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "s/,Apple,no-resolve$/,${Apple},no-resolve#d/g" "/tmp/other_rule.yaml" 2>/dev/null
sed -i "/rules:/a\##Apple:${Apple}" "/tmp/other_rule.yaml" 2>/dev/null

View File

@ -454,6 +454,9 @@ msgstr "亚洲流媒体流量"
msgid "Proxy"
msgstr "必须代理的流量"
msgid "Youtube"
msgstr "Youtube流量"
msgid "Apple"
msgstr "苹果服务流量"

View File

@ -1,181 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-ssr-plus-Jo
PKG_VERSION:=152
PKG_RELEASE:=20200307-5
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_haproxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_privoxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)/config
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
bool "Include Shadowsocks New Version"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
bool "Include Trojan"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
bool "Include ShadowsocksR Server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server
bool "Include Shadowsocks Server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
bool "Include ShadowsocksR Socks and Tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks
bool "Include Shadowsocks Socks and Tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks
bool "Include ipt2socks"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy
bool "Include dnscrypt-proxy-full"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder
bool "Include dnsforwarder"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS
bool "Include chinadns"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_haproxy
bool "Include haproxy"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_privoxy
bool "Include privoxy http local"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs
bool "Include simple-obfsl"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server
bool "Include simple-obfs-server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder
bool "Include udpspeeder"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel
bool "Include udp2raw-tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client
bool "Include GoQuiet-client"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server
bool "Include GoQuiet-server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
bool "Include v2ray-plugin"
default y
endef
define Package/luci-app-ssr-plus-Jo
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:=SS/SSR/V2Ray LuCI interface
PKGARCH:=all
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +luasocket +jshn +curl +wget +unzip \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server:shadowsocks-libev-ss-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy:dnscrypt-proxy-full \
+PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder:dnsforwarder \
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS:openwrt_chinadns \
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_privoxy:privoxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder:speederv2-tunnel \
+PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel:udp2raw-tunnel \
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs:simple-obfs \
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server:simple-obfs-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client:gq-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server:gq-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin:v2ray-plugin
endef
define Build/Prepare
endef
define Build/Compile
endef
define Package/luci-app-ssr-plus-Jo/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
$(INSTALL_DIR) $(1)/
cp -pR ./root/* $(1)/
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
po2lmo ./po/zh-cn/ssr-plus.po $(1)/usr/lib/lua/luci/i18n/ssr-plus.zh-cn.lmo
endef
define Package/luci-app-ssr-plus-Jo/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
( . /etc/uci-defaults/luci-ssr-plus ) && rm -f /etc/uci-defaults/luci-ssr-plus
rm -f /tmp/luci-indexcache
chmod 755 /etc/init.d/shadowsocksr >/dev/null 2>&1
/etc/init.d/shadowsocksr enable >/dev/null 2>&1
fi
exit 0
endef
define Package/luci-app-ssr-plus-Jo/prerm
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
/etc/init.d/shadowsocksr disable
/etc/init.d/shadowsocksr stop
fi
exit 0
endef
$(eval $(call BuildPackage,luci-app-ssr-plus-Jo))

View File

@ -1,387 +0,0 @@
-- Copyright (C) 2018 jerrykuku <jerrykuku@qq.com>
-- Licensed to the public under the GNU General Public License v3.
module("luci.controller.shadowsocksr", package.seeall)
function index()
if not nixio.fs.access("/etc/config/shadowsocksr") then
return
end
if nixio.fs.access("/usr/bin/ssr-redir") then
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
entry({"admin", "vpn", "shadowsocksr"},alias("admin", "vpn", "shadowsocksr", "client"), _("ShadowSocksR Plus+"),10).dependent = true
entry({"admin", "vpn", "shadowsocksr", "client"},cbi("shadowsocksr/client"),_("SSR Client"),10).leaf = true
entry({"admin", "vpn", "shadowsocksr", "servers"}, cbi("shadowsocksr/servers"), _("Node List"), 11).leaf = true
entry({"admin", "vpn", "shadowsocksr", "servers"},arcombine(cbi("shadowsocksr/servers"), cbi("shadowsocksr/client-config")),_("Node List"), 11).leaf = true
entry({"admin", "vpn", "shadowsocksr", "subscription"},cbi("shadowsocksr/subscription"), _("Subscription"),12).leaf = true
entry({"admin", "vpn", "shadowsocksr", "control"},cbi("shadowsocksr/control"),_("Access Control"),13).leaf = true
entry({"admin", "vpn", "shadowsocksr", "servers-list"}, cbi("shadowsocksr/servers-list"), _("Severs Nodes"), 14).leaf = true
entry({"admin", "vpn", "shadowsocksr", "appointlist"},form("shadowsocksr/appointlist"),_("Appointlist List"), 17).leaf = true
entry({"admin", "vpn", "shadowsocksr", "udp2raw"},cbi("shadowsocksr/udp2raw"),_("udp2raw tunnel"),16).leaf = true
entry({"admin", "vpn", "shadowsocksr", "advanced"},cbi("shadowsocksr/advanced"), _("Advanced Settings"),21).leaf = true
elseif nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "vpn", "shadowsocksr"},alias("admin", "vpn", "shadowsocksr", "server"), _("ShadowSocksR"),10).dependent = true
else
return
end
if nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "vpn", "shadowsocksr", "server"},arcombine(cbi("shadowsocksr/server"), cbi("shadowsocksr/server-config")),_("SSR Server"),22).leaf = true
end
entry({"admin", "vpn", "shadowsocksr", "status"},form("shadowsocksr/status"),_("Status"), 23).leaf = true
entry({"admin", "vpn", "shadowsocksr", "logview"}, cbi("shadowsocksr/logview", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("Log") ,30).leaf=true
entry({"admin", "vpn", "shadowsocksr", "fileread"}, call("act_read"), nil).leaf=true
entry({"admin", "vpn", "shadowsocksr", "refresh"}, call("refresh_data"))
entry({"admin", "vpn", "shadowsocksr", "checkport"}, call("check_port"))
entry({"admin", "vpn", "shadowsocksr", "checkports"}, call("check_ports"))
entry({"admin", "vpn", "shadowsocksr", "run"}, call("act_status"))
entry({"admin", "vpn", "shadowsocksr", "change"}, call("change_node"))
entry({"admin", "vpn", "shadowsocksr", "allserver"}, call("get_servers"))
entry({"admin", "vpn", "shadowsocksr", "subscribe"}, call("get_subscribe"))
entry({"admin", "vpn", "shadowsocksr", "ping"}, call("act_ping")).leaf=true
end
function get_subscribe()
local cjson = require "cjson"
local e = {}
local uci = luci.model.uci.cursor()
local auto_update = luci.http.formvalue("auto_update")
local auto_update_time = luci.http.formvalue("auto_update_time")
local proxy = luci.http.formvalue("proxy")
local subscribe_url = luci.http.formvalue("subscribe_url")
if subscribe_url ~= "[]" then
local cmd1 = 'uci set shadowsocksr.@server_subscribe[0].auto_update="' ..
auto_update .. '"'
local cmd2 = 'uci set shadowsocksr.@server_subscribe[0].auto_update_time="' ..
auto_update_time .. '"'
local cmd3 = 'uci set shadowsocksr.@server_subscribe[0].proxy="' .. proxy .. '"'
luci.sys.call('uci delete shadowsocksr.@server_subscribe[0].subscribe_url ')
luci.sys.call(cmd1)
luci.sys.call(cmd2)
luci.sys.call(cmd3)
for k, v in ipairs(cjson.decode(subscribe_url)) do
luci.sys.call(
'uci add_list shadowsocksr.@server_subscribe[0].subscribe_url="' .. v ..
'"')
end
luci.sys.call('uci commit shadowsocksr')
luci.sys.call(
"nohup /usr/bin/lua /usr/share/shadowsocksr/subscribe.lua >/www/check_update.htm 2>/dev/null &")
e.error = 0
else
e.error = 1
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-- 获取所有节点
function get_servers()
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach("shadowsocksr", "servers", function(s)
s["name"] = s[".name"]
table.insert(server_table,s)
end)
luci.http.prepare_content("application/json")
luci.http.write_json(server_table)
end
-- 切换节点
function change_node()
local e={}
local uci = luci.model.uci.cursor()
local sid = luci.http.formvalue("set")
local name = ""
uci:foreach("shadowsocksr", "global", function(s)
name = s[".name"]
end)
e.status = false
e.sid = sid
if sid ~= "" then
uci:set("shadowsocksr", name, "global_server" , sid)
luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr restart")
e.status = true
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-- 检测全局服务器状态
function act_status()
local e={}
--全局服务器
e.global=luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0
--检测chinadns状态
if tonumber(luci.sys.exec("ps -w | grep chinadns |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnsparsing |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnscrypt-proxy |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep pdnsd |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnsforwarder |grep -v grep| wc -l"))>0 then
e.chinadns= true
end
--检测SOCKS5状态
if tonumber(luci.sys.exec("ps -w | grep ssr-local |grep -v grep| wc -l"))>0 then
e.SOCKS5= true
elseif tonumber(luci.sys.exec("ps -w | grep ss-local |grep -v grep| wc -l"))>0 then
e.SOCKS5= true
elseif tonumber(luci.sys.exec("ps -w | grep v2-ssr-local |grep -v grep| wc -l"))>0 then
e.SOCKS5= true
end
--检测UDP2RAW状态
if tonumber(luci.sys.exec("ps -w | grep udp2raw |grep -v grep| wc -l"))>0 then
e.udp2raw= true
end
--检测UDPspeeder状态
if tonumber(luci.sys.exec("ps -w | grep udpspeeder |grep -v grep| wc -l"))>0 then
e.udpspeeder= true
end
--检测服务端状态
if tonumber(luci.sys.exec("ps -w | grep ssr-server |grep -v grep| wc -l"))>0 then
e.server= true
end
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
e.ssr_server= true
end
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
e.ss_server= true
end
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
e.v2_server= true
end
-- 检测游戏模式状态
e.game = false
if tonumber(luci.sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l"))>0 then
e.game= true
else
if tonumber(luci.sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l"))>0 then
e.game= true
end
end
-- 检测国内通道
e.baidu = false
sret = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
if sret == 0 then
e.baidu = true
end
-- 检测国外通道
e.google = false
sret = luci.sys.call("/usr/bin/ssr-check www.google.com 80 3 1")
if sret == 0 then
e.google = true
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function act_ping()
local e={}
e.index=luci.http.formvalue("index")
e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function check_status()
local set ="/usr/bin/ssr-check www." .. luci.http.formvalue("set") .. ".com 80 3 1"
sret=luci.sys.call(set)
if sret== 0 then
retstring ="0"
else
retstring ="1"
end
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring })
end
function refresh_data()
local set = luci.http.formvalue("set")
local icount = 0
if set == "gfw_data" then
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd =
"wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfw.b64"
else
refresh_cmd = "wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64"
end
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
luci.sys.call("/usr/bin/ssr-gfw")
icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
if tonumber(icount) > 1000 then
oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf")
retstring = tostring(math.ceil(tonumber(icount) / 2))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
else
retstring = "-1"
end
elseif set == "ip_data" then
refresh_cmd =
'wget -O- \'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest\' 2>/dev/null| awk -F\\| \'/CN\\|ipv4/ { printf("%s/%d\\n", $4, 32-log($5)/log(2)) }\' > /tmp/china_ssr.txt'
sret = luci.sys.call(refresh_cmd)
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if sret == 0 and tonumber(icount) > 1000 then
oldcount = luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
retstring = tostring(tonumber(icount))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
else
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd =
"wget --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt | grep ^\\|\\|[^\\*]*\\^$ | sed -e 's:||:address\\=\\/:' -e 's:\\^:/127\\.0\\.0\\.1:' > /tmp/ad.conf"
else
refresh_cmd = "wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf"
end
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount) > 1000 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
oldcount = luci.sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount = 0
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
retstring = tostring(math.ceil(tonumber(icount)))
if oldcount == 0 then
luci.sys.call("/etc/init.d/dnsmasq restart")
end
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/ad.conf ")
else
retstring = "-1"
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring, retcount = icount})
end
function act_ping()
local e={}
e.index=luci.http.formvalue("index")
e.ping=luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'"%luci.http.formvalue("domain"))
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function check_ports()
local set = ""
local retstring = "<br /><br />"
local s
local server_name = ""
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local iret = 1
uci:foreach(
shadowsocksr,
"servers",
function(s)
if s.alias then
server_name = s.alias
elseif s.server and s.server_port then
server_name = "%s:%s" % {s.server, s.server_port}
end
iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
ret = socket:connect(s.server, s.server_port)
if tostring(ret) == "true" then
socket:close()
retstring = retstring .. "<font color='green'>[" .. server_name .. "] OK.</font><br />"
else
retstring = retstring .. "<font color='red'>[" .. server_name .. "] Error.</font><br />"
end
if iret == 0 then
luci.sys.call(" ipset del ss_spec_wan_ac " .. s.server)
end
end
)
luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring})
end
-- 检测单个节点状态并返回连接速度
function check_port()
local sockets = require "socket"
local set = luci.http.formvalue("host")
local port = luci.http.formvalue("port")
local retstring = ""
local iret = 1
iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. set .. " 2>/dev/null")
socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
local t0 = sockets.gettime()
ret = socket:connect(set, port)
if tostring(ret) == "true" then
socket:close()
retstring = "1"
else
retstring = "0"
end
if iret == 0 then
luci.sys.call(" ipset del ss_spec_wan_ac " .. set)
end
local t1 = sockets.gettime()
local tt =t1 -t0
luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring , used = math.floor(tt*1000 + 0.5)})
end
function act_read(lfile)
local NXFS = require "nixio.fs"
local HTTP = require "luci.http"
local lfile = HTTP.formvalue("lfile")
local ldata={}
ldata[#ldata+1] = NXFS.readfile(lfile) or "_nofile_"
if ldata[1] == "" then
ldata[1] = "_nodata_"
end
HTTP.prepare_content("application/json")
HTTP.write_json(ldata)
end

View File

@ -1,114 +0,0 @@
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
m = Map(shadowsocksr)
-- [[ global ]]--
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
s.anonymous = true
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
o.rmempty = false
o.default = "1"
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
o.rmempty = false
o.default = "1"
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 667
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 5
o = s:option(Value, "switch_try_count", translate("Check Try Count"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 3
-- [[ SOCKS5 Proxy ]]--
if nixio.fs.access("/usr/bin/ssr-local") then
s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
s.anonymous = true
o = s:option(ListValue, "server", translate("Server"))
o:value("nil", translate("Disable"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.default = 1080
o.rmempty = false
-- [[ HTTP Proxy ]]--
if nixio.fs.access("/usr/sbin/privoxy") then
o = s:option(Flag, "http_enable", translate("Enable HTTP Proxy"))
o.rmempty = false
o = s:option(Value, "http_port", translate("HTTP Port"))
o.datatype = "port"
o.default = 1081
o.rmempty = false
end
end
-- [[ adblock ]]--
s = m:section(TypedSection, "global", translate("adblock settings"))
s.anonymous = true
o = s:option(Flag, "adblock", translate("Enable adblock"))
o.rmempty = false
o = s:option(Value, "adblock_url", translate("adblock_url"))
o.default = "https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt"
-- [[ haProxy ]]--
s = m:section(TypedSection, "global_haproxy", translate("haProxy settings"))
s.anonymous = true
o = s:option(Flag, "admin_enable", translate("Enabling the Management Console"))
o.rmempty = false
o.default = 1
o = s:option(Value, "admin_port", translate("Service Port"))
o.datatype = "uinteger"
o.default = 1111
o = s:option(Value, "admin_user", translate("User name"))
o.default = "admin"
o = s:option(Value, "admin_password", translate("Password"))
o.default = "root"
return m

View File

@ -1,23 +0,0 @@
local fs = require "nixio.fs"
local conffile = "/etc/dnsmasq.ssr/appoint_list.conf"
f = SimpleForm("custom", translate("Appoint dns List"))
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 13
function t.cfgvalue()
return fs.readfile(conffile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.conf then
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
luci.sys.call("/etc/init.d/dnsmasq restart")
end
end
return true
end
return f

View File

@ -1,49 +0,0 @@
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
m = Map(shadowsocksr)
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
s.anonymous = true
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
o.rmempty = false
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
o.rmempty = false
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 3600
o = s:option(Value, "switch_timeout", translate("Check timout(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 5
o = s:option(Value, "switch_try_count", translate("Check Try Count"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 3
return m

View File

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

View File

@ -1,237 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
-- Licensed to the public under the GNU General Public License v3.
local m, s, sec, o, kcp_enable
local shadowsocksr = "shadowsocksr"
local gfw_count=0
local ad_count=0
local ip_count=0
local gfwmode=0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfwmode=1
end
local uci = luci.model.uci.cursor()
local sys = require "luci.sys"
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
m = Map(shadowsocksr)
m:section(SimpleSection).template = "shadowsocksr/status"
local server_table = {}
local v2ray_table = {}
uci:foreach(shadowsocksr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
if s.type == "v2ray" then
if s.alias then
v2ray_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
v2ray_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
local key_table_v2 = {}
for key,_ in pairs(v2ray_table) do
table.insert(key_table_v2,key)
end
table.sort(key_table_v2)
-- [[ Global Setting ]]--
s = m:section(TypedSection, "global", translate("ShadowSocksR Plus+ Settings"))
s.anonymous = true
o = s:option(ListValue, "global_server", translate("Main Server"))
o:value("nil", translate("Disable"))
if nixio.fs.access("/usr/sbin/haproxy")then
o:value("__haproxy__", translate("Load Balancing"))
end
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o.rmempty = false
o = s:option(ListValue, "udp_relay_server", translate("Game Mode UDP Server"))
o:value("", translate("Disable"))
o:value("same", translate("Same as Global Server"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o = s:option(Flag, "v2ray_flow", translate("Open v2ray split-flow"))
o.rmempty = false
o.description = translate("When open v2ray split-flow,your main server must be a v2ray server")
o = s:option(ListValue, "youtube_server", translate("Youtube Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "tw_video_server", translate("TaiWan Video Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "netflix_server", translate("Netflix Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "disney_server", translate("Diseny+ Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "prime_server", translate("Prime Video Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "threads", translate("Multi Threads Option"))
o:value("0", translate("Auto Threads"))
o:value("1", translate("1 Thread"))
o:value("2", translate("2 Threads"))
o:value("4", translate("4 Threads"))
o:value("8", translate("8 Threads"))
o:value("16", translate("16 Threads"))
o:value("32", translate("32 Threads"))
o:value("64", translate("64 Threads"))
o:value("128", translate("128 Threads"))
o:value("256", translate("256 Threads"))
o:value("512", translate("512 Threads"))
o.default = "0"
o.rmempty = false
o = s:option(ListValue, "run_mode", translate("Running Mode"))
o:value("gfw", translate("GFW List Mode"))
o:value("router", translate("IP Route Mode"))
o:value("routers", translate("Oversea IP Route Mode"))
o:value("all", translate("Global Mode"))
o.default = gfw
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
o:value("0", translate("Use Local DNS Service listen port 5335"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
o:value("2", translate("Use Pdnsd udp query and cache"))
if nixio.fs.access("/usr/bin/dnsforwarder") then
o:value("3", translate("Use dnsforwarder tcp query and cache"))
o:value("4", translate("Use dnsforwarder udp query and cache"))
end
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
o:value("5", translate("Use dnscrypt-proxy query and cache"))
end
if nixio.fs.access("/usr/bin/chinadns") then
o:value("6", translate("Use chinadns query and cache"))
end
o.default = 1
o = s:option(ListValue, "chinadns_enable", translate("Chiadns Resolve Dns Mode"))
o:value("0", translate("Use Local DNS Service"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
o:value("2", translate("Use Pdnsd udp query and cache"))
if nixio.fs.access("/usr/bin/dnsforwarder") then
o:value("3", translate("Use dnsforwarder tcp query and cache"))
o:value("4", translate("Use dnsforwarder udp query and cache"))
end
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
o:value("5", translate("Use dnscrypt-proxy query and cache"))
end
if nixio.fs.access("/usr/sbin/smartdns") then
o:value("6", translate("Use smartdns query and cache"))
end
if nixio.fs.access("/usr/sbin/https_dns_proxy") then
o:value("7", translate("Use https_dns_proxy query and cache"))
end
o.default = 1
o:depends("pdnsd_enable", "6")
o = s:option(Value, "tunnel_forward", translate("Anti-pollution DNS Server"))
o:value("0.0.0.0:53", translate("Using System Default DNS"))
o:value("0.0.0.0:5333", translate("Using acceleration center DNS"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
o:value("208.67.220.220:53", translate("OpenDNS (208.67.220.220)"))
o:value("209.244.0.3:53", translate("Level 3 Public DNS (209.244.0.3)"))
o:value("209.244.0.4:53", translate("Level 3 Public DNS (209.244.0.4)"))
o:value("4.2.2.1:53", translate("Level 3 Public DNS (4.2.2.1)"))
o:value("4.2.2.2:53", translate("Level 3 Public DNS (4.2.2.2)"))
o:value("4.2.2.3:53", translate("Level 3 Public DNS (4.2.2.3)"))
o:value("4.2.2.4:53", translate("Level 3 Public DNS (4.2.2.4)"))
o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)"))
o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)"))
o:depends("pdnsd_enable", "1")
o:depends("pdnsd_enable", "2")
o:depends("pdnsd_enable", "3")
o:depends("pdnsd_enable", "4")
o:depends("pdnsd_enable", "6")
o.default = "8.8.4.4:53"
o = s:option(Flag, "bt", translate("Kill BT"))
o.default = 0
o.rmempty = false
o.description = translate("Prohibit downloading tool ports through proxy")
o = s:option(Value, "bt_port", translate("BT Port"))
o.default = "1236:65535"
o.rmempty = true
o:depends("bt", "1")
o = s:option(Button,"gfw_data",translate("GFW List Data"))
o.rawhtml = true
o.template = "shadowsocksr/refresh"
o.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
o = s:option(Button,"ad_data",translate("Advertising Data"))
o .rawhtml = true
o .template = "shadowsocksr/refresh"
o .value =tostring(math.ceil(ad_count)) .. " " .. translate("Records")
o = s:option(Button,"ip_data",translate("China IP Data"))
o.rawhtml = true
o.template = "shadowsocksr/refresh"
o.value =ip_count .. " " .. translate("Records")
o = s:option(Button,"check_port",translate("Check Server Port"))
o.template = "shadowsocksr/checkport"
o.value =translate("No Check")
return m

View File

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

View File

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

View File

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

View File

@ -1,48 +0,0 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher"
local HTTP = require "luci.http"
local UCI = luci.model.uci.cursor()
m = Map("shadowsocksr")
-- log directory
log_dir = UCI:get_first(m.config, "global", "log_dir") or "/tmp"
run_dir = UCI:get_first(m.config, "global", "run_dir") or "/var/etc"
local logfile_list = {}
for path in (NXFS.glob("%s/ssr*" % log_dir) or function() end) do
logfile_list[#logfile_list+1] = path
end
for path in (NXFS.glob("%s/*.*" % run_dir) or function() end) do
logfile_list[#logfile_list+1] = path
end
ns = m:section(TypedSection, "_dummy", translate("File Viewer"))
ns.addremove = false
ns.anonymous = true
function ns.cfgsections()
return{"_exrules"}
end
lv = ns:option(DynamicList, "logfiles")
lv.template = "shadowsocksr/logsview"
lv.inputtitle = translate("Read / Reread log file")
lv.rows = 25
lv.default = ""
for _, lfile in ipairs(logfile_list) do lv:value(lfile, lfile) end
function lv.cfgvalue(self, section)
if logfile_list[1] then
local lfile=logfile_list[1]
if NXFS.access(lfile) then
return lfile .. "\n" .. translate("Please press [Read] button")
end
return lfile .. "\n" .. translate("File not found or empty")
else
return log_dir .. "\/\n" .. translate("No files found")
end
end
return m

View File

@ -1,23 +0,0 @@
local fs = require "nixio.fs"
local conffile = "/etc/dnsmasq.oversea/base_list.conf"
f = SimpleForm("custom", translate("Oversea Custom List"))
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 13
function t.cfgvalue()
return fs.readfile(conffile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.conf then
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
luci.sys.call("/etc/init.d/dnsmasq restart")
end
end
return true
end
return f

View File

@ -1,380 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
local http = luci.http
local ucursor = require "luci.model.uci".cursor()
local server_table = {}
local encrypt_methods = {
"none",
"table",
"rc4",
"rc4-md5-6",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local encrypt_methods_ss = {
-- aead
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
-- stream
"table",
"rc4",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
"auth_chain_b",
"auth_chain_c",
"auth_chain_d",
"auth_chain_e",
"auth_chain_f",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
}
local obfs_opts = {
"none",
"http",
"tls",
}
local securitys = {
"auto",
"none",
"aes-128-gcm",
"chacha20-poly1305"
}
m = Map(shadowsocksr, translate("Edit ShadowSocksR Server"))
m.redirect = luci.dispatcher.build_url("admin/vpn/shadowsocksr/server")
if m.uci:get(shadowsocksr, sid) ~= "server_config" then
luci.http.redirect(m.redirect)
return
end
-- [[ Server Setting ]]--
s = m:section(NamedSection, sid, "server_config")
s.anonymous = true
s.addremove = false
o = s:option(Flag, "enable", translate("Enable"))
o.default = 1
o.rmempty = false
o = s:option(ListValue, "type", translate("Server Node Type"))
if nixio.fs.access("/usr/bin/ssr-server") then
o:value("ssr", translate("ShadowsocksR"))
end
if nixio.fs.access("/usr/bin/ss-server") then
o:value("ss", translate("Shadowsocks New Version"))
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
o:value("v2ray", translate("V2Ray"))
end
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
o = s:option(Flag, "ipv4_ipv6", translate("Enabling IPv6 server"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.default = 8388
o.rmempty = false
o = s:option(Value, "timeout", translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 60
o.rmempty = false
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(ListValue, "plugin", translate("plugin"))
o:value("none", "None")
if nixio.fs.access("/usr/bin/v2ray-plugin") then
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
end
if nixio.fs.access("/usr/bin/obfs-server") then
o:value("/usr/bin/obfs-server", "obfs-server")
end
if nixio.fs.access("/usr/bin/gq-server") then
o:value("/usr/bin/gq-server", "GoQuiet")
end
o.rmempty = false
o.default = "none"
o:depends("type", "ss")
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
o.rmempty = true
o:depends("plugin", "/usr/bin/v2ray-plugin")
o:depends("plugin", "/usr/bin/obfs-server")
o:depends("plugin", "/usr/bin/gq-server")
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(ListValue, "obfs", translate("Obfs"))
for _, v in ipairs(obfs) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
o:depends("type", "ssr")
-- AlterId
o = s:option(Value, "alter_id", translate("AlterId"))
o.default = 100
o.rmempty = true
o:depends("type", "v2ray")
o=s:option(Value,"VMess_level",translate("User Level"))
o.default=1
o:depends("type", "v2ray")
-- VmessId
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
o.rmempty = true
o.default = uuid
o:depends("type", "v2ray")
-- 加密方式
o = s:option(ListValue, "security", translate("Encrypt Method"))
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
o.rmempty = true
o:depends("type", "v2ray")
-- 传输协议
o = s:option(ListValue, "transport", translate("Transport"))
o:value("tcp", "TCP")
o:value("kcp", "mKCP")
o:value("ws", "WebSocket")
o:value("h2", "HTTP/2")
o:value("quic", "QUIC")
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TCP部分 ]]--
-- TCP伪装
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
o:depends("transport", "tcp")
o:value("none", translate("None"))
o:value("http", "HTTP")
o.rmempty = true
-- HTTP域名
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- HTTP路径
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- [[ WS部分 ]]--
-- WS域名
o = s:option(Value, "ws_host", translate("WebSocket Host"))
o:depends("transport", "ws")
o.rmempty = true
-- WS路径
o = s:option(Value, "ws_path", translate("WebSocket Path"))
o:depends("transport", "ws")
o.rmempty = true
-- [[ H2部分 ]]--
-- H2域名
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
o:depends("transport", "h2")
o.rmempty = true
-- H2路径
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
o:depends("transport", "h2")
o.rmempty = true
-- [[ QUIC部分 ]]--
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("aes-128-gcm", translate("aes-128-gcm"))
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
o = s:option(Value, "quic_key", translate("QUIC Key"))
o:depends("transport", "quic")
o.rmempty = true
o = s:option(ListValue, "quic_guise", translate("Header"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
-- [[ mKCP部分 ]]--
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
o:depends("transport", "kcp")
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
o.rmempty = true
o = s:option(Value, "mtu", translate("MTU"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 1350
o.rmempty = true
o = s:option(Value, "tti", translate("TTI"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 50
o.rmempty = true
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 50
o.rmempty = true
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 20
o.rmempty = true
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Flag, "congestion", translate("Congestion"))
o:depends("transport", "kcp")
o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, "insecure", translate("allowInsecure"))
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TLS ]]--
o = s:option(Flag, "tls", translate("TLS"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
-- [[ Mux ]]--
o = s:option(Flag, "mux", translate("Mux"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
o = s:option(Value, "concurrency", translate("Concurrency"))
o.datatype = "uinteger"
o.rmempty = true
o.default = "8"
o:depends("mux", "1")
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
o.rmempty = true
o:depends("type", "ssr")
return m

View File

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

View File

@ -1,80 +0,0 @@
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_count = 0
uci:foreach("shadowsocksr", "servers", function(s)
server_count = server_count + 1
end)
local fs = require "nixio.fs"
local sys = require "luci.sys"
m = Map(shadowsocksr)
m:section(SimpleSection).template = "shadowsocksr/status"
-- [[ Servers Manage ]]--
s = m:section(TypedSection, "servers")
s.anonymous = true
s.addremove = true
s.description = string.format(translate("Server Count") .. ": %d", server_count)
s.sortable = true
s.template = "cbi/tblsection"
s.extedit = luci.dispatcher.build_url("admin/vpn/shadowsocksr/servers/%s")
function s.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(s.extedit % sid)
return
end
end
o = s:option(DummyValue, "type", translate("Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("")
end
o = s:option(DummyValue, "alias", translate("Alias"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or translate("None")
end
o = s:option(DummyValue, "server", translate("Server Address"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = s:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = s:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
o.width="10%"
o = s:option(DummyValue, "protocol", translate("Protocol"))
o.width="10%"
o = s:option(DummyValue, "obfs", translate("Obfs"))
o.width="10%"
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
if nixio.fs.access("/usr/bin/kcptun-client") then
o = s:option(Flag, "kcp_enable", translate("KcpTun"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
end
o = s:option(DummyValue,"server",translate("Ping Latency"))
o.template="shadowsocksr/ping"
o.width="10%"
m:append(Template("shadowsocksr/server_list"))
return m

View File

@ -1,62 +0,0 @@
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local shadowsocksr = "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_count = 0
local server_table = {}
uci:foreach("shadowsocksr", "servers", function(s)
server_count = server_count + 1
s["name"] = s[".name"]
table.insert(server_table, s)
end)
local name = ""
uci:foreach("shadowsocksr", "global", function(s) name = s[".name"] end)
m = Map(shadowsocksr)
m:section(SimpleSection).template = "shadowsocksr/status"
-- [[ Servers List ]]--
s = m:section(TypedSection, "servers")
s.anonymous = true
s.addremove = true
s.sortable = false
s.des = server_count
s.current = uci:get("shadowsocksr", name, "global_server")
s.template = "cbi/add"
s.extedit = luci.dispatcher.build_url("admin/vpn/shadowsocksr/servers/%s")
function s.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(s.extedit % sid)
return
end
end
o = s:option(DummyValue, "type", translate("Type"))
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("") end
o = s:option(DummyValue, "alias", translate("Alias"))
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("None") end
o = s:option(DummyValue, "server", translate("Server Address"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
o = s:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
if nixio.fs.access("/usr/bin/kcptun-client") then
o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
end
return m

View File

@ -1,452 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local IPK_Version="20200304.151"
local m, s, o
local redir_run=0
local reudp_run=0
local sock5_run=0
local ssock5_run=0
local v2sock5_run=0
local server_run=0
local sserver_run=0
local v2server_run=0
local kcptun_run=0
local tunnel_run=0
local udp2raw_run=0
local udpspeeder_run=0
local gfw_count=0
local ad_count=0
local ip_count=0
local gfwmode=0
local pdnsd_run=0
local dnsforwarder_run=0
local dnscrypt_proxy_run=0
local chinadns_run=0
local haproxy_run=0
local privoxy_run=0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfwmode=1
end
local shadowsocksr = "shadowsocksr"
-- html constants
font_blue = [[<font color="green">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
local fs = require "nixio.fs"
local sys = require "luci.sys"
local kcptun_version=translate("Unknown")
local kcp_file="/usr/bin/kcptun-client"
if not fs.access(kcp_file) then
kcptun_version=translate("Not exist")
else
if not fs.access(kcp_file, "rwx", "rx", "rx") then
fs.chmod(kcp_file, 755)
end
kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
if not kcptun_version or kcptun_version == "" then
kcptun_version = translate("Unknown")
end
end
local udp2raw_version=translate("Unknown")
local udp2raw_file="/usr/bin/udp2raw"
if not fs.access(udp2raw_file) then
udp2raw_version=translate("Not exist")
else
if not fs.access(udp2raw_file, "rwx", "rx", "rx") then
fs.chmod(udp2raw_file, 755)
end
udp2raw_version=sys.exec(udp2raw_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
if not udp2raw_version or udp2raw_version == "" then
udp2raw_version = translate("Unknown")
end
end
local udpspeeder_version=translate("Unknown")
local udpspeeder_file="/usr/bin/udpspeeder"
if not fs.access(udpspeeder_file) then
udpspeeder_version=translate("Not exist")
else
if not fs.access(udpspeeder_file, "rwx", "rx", "rx") then
fs.chmod(udpspeeder_file, 755)
end
udpspeeder_version=sys.exec(udpspeeder_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
if not udpspeeder_version or udpspeeder_version == "" then
udpspeeder_version = translate("Unknown")
end
end
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
function processlist()
local data = {}
local netf = {}
local k
local ps = luci.util.execi("/bin/busybox top -bn1 | egrep -v dnsmasq")
local nets = luci.util.execi("netstat -netupl | egrep -v dnsmasq | awk '{print $1,$4,_,$6,$7}'")
if not ps or not nets then
return
end
for line in nets do
-- tcp 0 0 127.0.0.1:1234 0.0.0.0:* LISTEN 5103/v2ray
-- udp 0 0 127.0.0.1:1234 0.0.0.0:* 5147/v2ray
-- local proto, ip, port, nid = line:match("([^%s]+) +.* +([^ ]*):(%d+) +.* +(%d+)\/.*")
local proto, ip, port, nid = line:match("([^%s]+) (.*):(%d+)[^%d]+(%d+)\/.*")
local idx = tonumber(nid)
if idx and ip then
local newstr = "://" .. ip .. ":" .. port
local isnew = (netf[idx] and netf[idx]['listen']) and netf[idx]['listen']:match(proto .. newstr) or false
netf[idx] = {
['listen'] = ((netf[idx] and netf[idx]['listen']) and (not isnew) and (netf[idx]['listen'] .. "\n" .. proto) or proto) .. newstr,
}
end
end
-- 5103 1 root S 661m 543% 0% /usr/bin/v2ray/v2ray -config /var/etc/shadowsocksr.json
for line in ps do
local pid, ppid, user, stat, vsz, mem, cpu, cmd = line:match(
"^ *(%d+) +(%d+) +(%S.-%S) +([RSDZTW][W ][<N ]) +(%d+.?) +(%d+%%) +(%d+%%) +(.+)"
)
if cmd then
local idx = tonumber(pid)
local bin, param, cfg = cmd:match("^.*\/([^ ]*) *([^ ]*) *\/var\/etc\/([^ ]*).*")
if idx and cfg then
local listen = "NONE"
if netf[idx] and netf[idx]['listen'] then
listen = netf[idx]['listen']
end
data[idx] = {
['PID'] = pid,
['COMMAND'] = bin,
['LISTEN'] = listen,
['CONFIG'] = cfg,
['%MEM'] = mem,
['%CPU'] = cpu,
}
end
end
end
return data
end
function printstat(status, form, name)
local tabs = {
["Global Client"] = "shadowsocksr.json",
["Game Mode UDP Relay"] = "shadowsocksr_u.json",
["PDNSD"] = "pdnsd.conf",
["DNS Forward"] = "shadowsocksr_d.json",
["SOCKS5 Proxy"] = "shadowsocksr_s.json",
["Global SSR Server"] = "shadowsocksr_0.json",
}
local stat = translate("Unknown")
local sname = stat
if tabs[name] and status then
stat = translate("Not Running")
for idx, cfg in pairs(status) do
if status[idx]['CONFIG'] and status[idx]['CONFIG'] == tabs[name] then
stat = font_blue .. bold_on .. translate("Running") .. bold_off .. " > " .. status[idx]['COMMAND'] .. " -c " .. status[idx]['CONFIG'] .. font_off
sname = translate(status[idx]['COMMAND'])
break
end
end
end
local section = form:field(DummyValue,name,translate(name) .. ": " .. sname)
section.rawhtml = true
section.value = stat
return section
end
procs=processlist()
local icount=sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
else
icount=sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
end
end
if luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
redir_run=1
end
if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
sock5_run=1
end
if luci.sys.call("pidof ss-local >/dev/null") == 0 then
ssock5_run=1
end
if luci.sys.call("ps -w | grep v2-ssr-local | grep -v grep >/dev/null") == 0 then
v2sock5_run=1
end
if luci.sys.call("pidof privoxy >/dev/null") == 0 then
privoxy_run=1
end
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
kcptun_run=1
end
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
server_run=1
end
if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
tunnel_run=1
end
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
sserver_run=1
end
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
v2server_run=1
end
if luci.sys.call("ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
tunnel_run=1
end
if luci.sys.call("pidof udp2raw >/dev/null") == 0 then
udp2raw_run=1
end
if luci.sys.call("pidof udpspeeder >/dev/null") == 0 then
udpspeeder_run=1
end
if luci.sys.call("pidof chinadns >/dev/null") == 0 then
chinadns_run=1
end
if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
pdnsd_run=1
end
if luci.sys.call("pidof dnsparsing >/dev/null") == 0 then
dnsforwarder_run=1
end
if luci.sys.call("pidof dnscrypt-proxy >/dev/null") == 0 then
dnscrypt_proxy_run=1
end
if luci.sys.call("pidof haproxy >/dev/null") == 0 then
haproxy_run=1
end
m = SimpleForm("Version")
m.reset = false
m.submit = false
t = m:section(Table, procs, translate("Running Details: ") .. "(/var/etc)")
t:option(DummyValue, "PID", translate("PID"))
t:option(DummyValue, "COMMAND", translate("CMD"))
t:option(DummyValue, "LISTEN", translate("LISTEN"))
t:option(DummyValue, "%CPU", translate("CPU"))
t:option(DummyValue, "%MEM", translate("MEM"))
s=m:field(DummyValue,"redir_run",translate("Global Client"))
s.rawhtml = true
if redir_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
s.rawhtml = true
if reudp_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"haproxy_run",translate("Load Balancing"))
s.rawhtml = true
if haproxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/chinadns") then
s=m:field(DummyValue,"chinadns_run",translate("ChinaDNS"))
s.rawhtml = true
if chinadns_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
s.rawhtml = true
if pdnsd_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"dnsforwarder_run",translate("dnsforwarder"))
s.rawhtml = true
if dnsforwarder_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"dnscrypt_proxy_run",translate("dnscrypt_proxy"))
s.rawhtml = true
if dnscrypt_proxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/ss-local") then
s=m:field(DummyValue,"ssock5_run",translate("SSOCKS5 Proxy"))
s.rawhtml = true
if ssock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ssr-local") then
s=m:field(DummyValue,"sock5_run",translate("SSR SOCKS5 Proxy"))
s.rawhtml = true
if sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
s=m:field(DummyValue,"ssock5_run",translate("V2SOCKS5 Proxy"))
s.rawhtml = true
if v2sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/sbin/privoxy") then
s=m:field(DummyValue,"privoxy_run",translate("HTTP Proxy"))
s.rawhtml = true
if privoxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ssr-server") then
s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
s.rawhtml = true
if server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ss-server") then
s=m:field(DummyValue,"sserver_run",translate("Global SS Server"))
s.rawhtml = true
if sserver_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/v2ray") then
s=m:field(DummyValue,"v2server_run",translate("Global V2RAY Server"))
s.rawhtml = true
if v2server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/kcptun-client") then
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
s.rawhtml = true
s.value =kcptun_version
s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
s.rawhtml = true
if kcptun_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"version",translate("IPK Version"))
s.rawhtml = true
s.value =IPK_Version
s=m:field(DummyValue,"udp2raw_version",translate("udp2raw Version"))
s.rawhtml = true
s.value =udp2raw_version
s=m:field(DummyValue,"udp2raw_run",translate("udp2raw"))
s.rawhtml = true
if udp2raw_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"udpspeeder_version",translate("UDPspeeder Version"))
s.rawhtml = true
s.value =udpspeeder_version
s=m:field(DummyValue,"udpspeeder_run",translate("UDPspeeder"))
s.rawhtml = true
if udpspeeder_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"feedback",translate("Feedback"))
s.template = "shadowsocksr/feedback"
s.value =translate("No feedback")
return m

View File

@ -1,83 +0,0 @@
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local shadowsocksr= "shadowsocksr"
local uci = luci.model.uci.cursor()
local server_table = {}
local gfwmode=0
local gfw_count=0
local ip_count=0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfwmode=1
end
local uci = luci.model.uci.cursor()
local server_count = 0
uci:foreach("shadowsocksr", "servers", function(s)
server_count = server_count + 1
end)
local fs = require "nixio.fs"
local sys = require "luci.sys"
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l"))/2
end
m = Map(shadowsocksr)
m:section(SimpleSection).template = "shadowsocksr/status3"
-- [[ 节点订阅 ]]--
s = m:section(TypedSection, "server_subscribe", translate("Subscription"))
s.anonymous = true
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false
o.description = translate("Auto Update Server subscription, GFW list and CHN route")
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0,23 do
o:value(t, t..":00")
end
o.default=2
o.rmempty = false
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true
o = s:option(Flag, "proxy", translate("Through proxy update"))
o.rmempty = false
o.description = translate("Through proxy update list, Not Recommended ")
o = s:option(DummyValue, "", "")
o.rawhtml = true
o.template = "shadowsocksr/update_subscribe"
o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
o.inputstyle = "reset"
o.description = string.format(translate("Server Count") .. ": %d", server_count)
o.write = function()
uci:delete_all("shadowsocksr", "servers", function(s)
if s["hashkey"] then
return true
else
return false
end
end)
uci:save("shadowsocksr")
luci.sys.call("uci commit shadowsocksr && /etc/init.d/shadowsocksr stop")
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "shadowsocksr", "servers"))
return
end
return m

View File

@ -1,197 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
-- Licensed to the public under the GNU General Public License v3.
local m, s, sec, o, kcp_enable
local shadowsocksr = "shadowsocksr"
m = Map(shadowsocksr)
local server_table = {}
local encrypt_methods = {
"none",
"table",
"rc4",
"rc4-md5-6",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
"auth_chain_b",
"auth_chain_c",
"auth_chain_d",
"auth_chain_e",
"auth_chain_f",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
}
local raw_mode = {
"faketcp",
"udp",
"icmp",
}
local seq_mode = {
"0",
"1",
"2",
"3",
"4",
}
local cipher_mode = {
"none",
"xor",
"aes128cbc",
}
local auth_mode = {
"none",
"simple",
"md5",
"crc32",
}
local speeder_mode = {
"0",
"1",
}
-- [[ udp2raw ]]--
if nixio.fs.access("/usr/bin/udp2raw") then
s = m:section(TypedSection, "udp2raw", translate(" UDP2raw "))
s.anonymous = true
o = s:option(Flag, "udp2raw_enable", translate("Enable udp2raw"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "key", translate("Password"))
o.password = true
o.rmempty = false
o = s:option(ListValue, "raw_mode", translate("Raw Mode"))
for _, v in ipairs(raw_mode) do o:value(v) end
o.default = "faketcp"
o.rmempty = false
o = s:option(ListValue, "seq_mode", translate("Seq Mode"))
for _, v in ipairs(seq_mode) do o:value(v) end
o.default = "3"
o.rmempty = false
o = s:option(ListValue, "cipher_mode", translate("Cipher Mode"))
for _, v in ipairs(cipher_mode) do o:value(v) end
o.default = "xor"
o.rmempty = false
o = s:option(ListValue, "auth_mode", translate("Auth Mode"))
for _, v in ipairs(auth_mode) do o:value(v) end
o.default = "simple"
o.rmempty = false
end
-- [[ udpspeeder ]]--
if nixio.fs.access("/usr/bin/udpspeeder") then
s = m:section(TypedSection, "udpspeeder", translate("UDPspeeder"))
s.anonymous = true
o = s:option(Flag, "udpspeeder_enable", translate("Enable UDPspeeder"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "key", translate("Password"))
o.password = true
o.rmempty = false
o = s:option(ListValue, "speeder_mode", translate("Speeder Mode"))
for _, v in ipairs(speeder_mode) do o:value(v) end
o.default = "0"
o.rmempty = false
o = s:option(Value, "fec", translate("Fec"))
o.default = "20:10"
o.rmempty = false
o = s:option(Value, "mtu", translate("Mtu"))
o.datatype = "uinteger"
o.default = 1250
o.rmempty = false
o = s:option(Value, "queue_len", translate("Queue Len"))
o.datatype = "uinteger"
o.default = 200
o.rmempty = false
o = s:option(Value, "timeout", translate("Fec Timeout"))
o.datatype = "uinteger"
o.default = 8
o.rmempty = false
end
return m

View File

@ -1,409 +0,0 @@
<style>
.cbi-section-table-row {
position: relative;
background: #172b4d;
margin: 10px;
padding: 8px 15px 10px 65px;
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
border-radius: .5rem;
border: 0;
color: #ffffff;
text-align: left;
line-height: 1.7em;
white-space: nowrap;
     text-overflow: ellipsis;
overflow: hidden;
transition: all 0.3s;
}
.incon.fast ,.cbi-section-table-row.fast{
background: #009966!important;
}
.incon.nopass ,.cbi-section-table-row.nopass{
background: #dc3545 !important;
}
.incon.middle ,.cbi-section-table-row.middle{
background: #fbc658 !important;
}
.incon.slow ,.cbi-section-table-row.slow{
background: #fb6340 !important;
}
.host_con.fast{
color: #00ff18;
}
.host_con.nopass{
color: #f5365c;
}
.host_con.middle{
color: #ffff00;
}
.host_con.slow{
color: #ffa200;
}
.loadings {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255,255,255,0.7);
border-radius: .5rem;
left: 0;
top: 0;
z-index: 10;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
transition: all 0.3s;
}
.loadings.hide{
opacity:0;
visibility:hidden;
pointer-events:none;
}
.loadings span {
animation: anim-rotate 2s infinite linear;
height: 30px;
}
.incon {
display: inline-block;
margin: 0.2em 0;
}
.incon:nth-child(2) {
position: absolute;
display:flex;
align-items:center;
justify-content: center;
left: 0;
top: -3px;
width: 55px;
height: 105%;
border: 0;
background: #00CED1;
text-transform: uppercase;
}
.incon:nth-child(3) {
padding-left: 0px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.incon:nth-child(5) ,.incon:nth-child(6){
display: none;
}
.cbi-section-table-cell {
text-align: right;
}
.ssr-button {
background: none;
color: #fff;
padding: 0 0 0 0.8rem;
}
.ssr-button:hover,
.ssr-button:focus,
.ssr-button:active {
color: #fff;
outline: 0;
text-decoration: none;
box-shadow: none;
}
.cbi-section h3{
margin-left:10px;
margin-top:1rem;
}
.cbi-button-check {
color: #fff !important;
background-color: #008080 !important;
border-color: #2e6da4 !important;
font-size:14px;
padding:0.5rem 0.8rem;
float:right;
margin-right:10px;
margin-top:-0.5rem;
}
.cbi-section-table-cell{
position:relative;
}
.host_con{
position:absolute;
left:0;
width:50px;
text-align: left;
height:22px;
font-weight: bold;
}
.host_ok{
color:#fff;
background:#2dce89;
padding: 0.1rem 0.5rem;
border-radius: 0.2rem;
}
.host_error{
color:#fff;
background:#f5365c;
padding: 0.1rem 0.5rem;
border-radius: 0.2rem;
}
.cbi-button-add{
position:fixed;
padding: 0.3rem 0.5rem;
z-index:1000;
width:80px !important;
height:80px;
bottom:50px;
right:60px;
font-size:20px;
border-radius:50%;
display:block;
background-color: #008080!important;
border-color: #008080 !important;
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
}
.statused{
position: absolute;
z-index: 20;
right: 0;
top: 0;
background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjAwIDIwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzZGOUEzNzt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLjIsMGwxOTkuNiwyMDBMMjAwLDAuMkwwLjIsMHoiLz4NCjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xNjQuNSw1MS4zTDEyMyw5My44Yy0wLjksMS0yLjEsMS40LTMuNCwxLjRjLTEuMywwLTIuNS0wLjQtMy40LTEuNEw5OSw3NS42Yy0xLjgtMS45LTEuNi00LjksMC40LTYuOA0KCWMyLTEuOSw1LTEuOSw2LjgsMGwxMy41LDE0LjJsMzcuNy0zOC42YzEuOC0xLjksNC44LTEuOSw2LjgsMEMxNjYuMSw0Ni40LDE2Ni4zLDQ5LjQsMTY0LjUsNTEuM0wxNjQuNSw1MS4zeiIvPg0KPC9zdmc+DQo=');
background-size: contain;
width: 50px;
height: 50px;
transition: all 0.2s;
pointer-events: none;
}
.statused.hide{
visibility: hidden;
opacity: 0;
}
@media screen and (max-width: 1900px) {
.pure-u-1-5{
width:25%;
}
}
@media screen and (max-width: 1600px) {
.pure-u-1-5{
width:33.33333333%;
}
}
@media screen and (max-width: 1200px) {
.pure-u-1-5{
width:50%;
}
.status .pure-u-1-5{
width:33.333%;
}
}
@media screen and (max-width: 700px) {
.pure-u-1-5{
width:100%;
font-size: 14px;
}
.status .pure-u-1-5{
width: 50%;
}
}
</style>
<fieldset class="cbi-section" id="cbi-apply-shadowsocksr1" style="display: none;">
<span class="panel-title">正在应用更改</span>
<img src="/luci-static/resources/icons/loading.gif" alt="载入中" style="vertical-align:middle">
</fieldset>
<!-- tblsection -->
<fieldset class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>">
<button class="cbi-button cbi-button-check "><%:Ping All Servers%></button><span class="panel-title"><%:Node list%> <%:total%> &nbsp; <%- print(self.des)-%><%:Nodes%></span>
<div class="cbi-section-node">
<%- local count = 0 -%>
<div class="cbi-section-table pure-g">
<%- local isempty = true
for i, k in ipairs(self:cfgsections()) do
section = k
isempty = false
scope = { valueheader = "cbi/cell_valueheader", valuefooter = "cbi/cell_valuefooter" }
-%>
<div class="pure-u-1-5">
<div class="cbi-section-table-row " id="cbi-<%=self.config%>-<%=section%>">
<div class="loadings hide"><span class="icon-loading"></span></div>
<div class="incon type" ></div>
<div class="incon alias"></div>
<div class="incon switch_enable"></div>
<div class="statused hide"></div>
<%- if self.extedit or self.addremove then -%>
<div class="cbi-section-table-cell">
<div class="host_con">
</div>
<a class="cbi-button ssr-button " type="button" value="" onclick="apply_node('<%=section%>')" alt="应用" title="<%:Apply%>"><span class="icon-edit"></span> <%:Apply%></a>
<%- if self.extedit then -%>
<a class="cbi-button ssr-button " type="button" value=""
<%- if type(self.extedit) == "string" then
%> onclick="location.href='<%=self.extedit:format(section)%>'"
<%- elseif type(self.extedit) == "function" then
%> onclick="location.href='<%=self:extedit(section)%>'"
<%- end
%> alt="<%:Edit%>" title="<%:Edit%>" ><span class="icon-edit"></span> <%:Edit%></a>
<%- end; if self.addremove then %>
<button class="cbi-button ssr-button" type="submit" value="" onclick="this.form.cbi_state = 'del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" /><span class="icon-delete"></span> <%:Delete%></button>
<%- end -%>
</div>
<%- end -%>
</div>
</div>
<%- end -%>
<%- if isempty then -%>
<div class="cbi-section-table-row">
<div colspan="<%=count%>"><em><br /><%:This section contains no values yet%></em></div>
</div>
<%- end -%>
</div>
<% if self.error then %>
<div class="cbi-section-error">
<ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%>
<li><%=pcdata(e):gsub("\n","<br />")%></li>
<%- end end %></ul>
</div>
<% end %>
<%- if self.addremove then -%>
<% if self.template_addremove then include(self.template_addremove) else -%>
<div class="cbi-section-create cbi-tblsection-create">
<% if self.anonymous then %>
<input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" />
<% else %>
<% if self.invalid_cts then -%><div class="cbi-section-error"><% end %>
<input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" />
<input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state = 'add-section'; return true" value="<%:Add%>" title="<%:Add%>" />
<% if self.invalid_cts then -%>
<br /><%:Invalid%></div>
<%- end %>
<% end %>
</div>
<%- end %>
<%- end -%>
</div>
</fieldset>
<!-- /tblsection -->
<script type="text/javascript">
function apply_node(node){
$("#cbi-apply-shadowsocksr1").show();
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","change")%>',
{
set:node
},
function (data, status) {
$("#cbi-apply-shadowsocksr1").hide();
if (data.status ) {
var id = '#cbi-<%=self.config%>-'+node;
$(".statused").addClass("hide");
$(id).find(".statused").removeClass("hide");
}
});
}
$(document).ready(function () {
setTimeout(function() { check(); }, 500);
function check() {
$(".host_con").html("");
$(".pure-u-1-5").each(function () {
host = $(this).find(".cbi-section-table-row ").attr("server");
port = $(this).find(".cbi-section-table-row ").attr("server_port");
$(".host_con").text("--ms");
check_port(host, port, this);
});
}
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","allserver")%>',
function (data) {
$.each(data, function (i, val) {
var id = '#cbi-<%=self.config%>-'+val.name;
if(val.name == "<%=self.current%>"){
$(id).find(".statused").removeClass("hide");
}
$(id).find(".type").text(val.type);
$(id).find(".alias").text(val.alias);
var switch_text = (val.switch_enable == 1)?'<span class="icon-switch" title="自动切换"></span>':'';
$(id).find(".switch_enable").html(switch_text);
$(id).attr("server",val.server);
$(id).attr("server_port",val.server_port) ;
});
}, "json");
function check_port(hosts, ports, target) {
$.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr","checkport")%>',
{
host: hosts,
port: ports
},
function (data, status) {
$(target).find(".loadings").addClass("hide");
$(target).find(".incon").removeClass("fast");
$(target).find(".incon").removeClass("middle");
$(target).find(".incon").removeClass("slow");
$(target).find(".incon").removeClass("nopass");
$(target).find(".host_con").removeClass("fast");
$(target).find(".host_con").removeClass("middle");
$(target).find(".host_con").removeClass("slow");
$(target).find(".host_con").removeClass("nopass");
if (data.ret == 1) {
if (data.used <= 80) {
$(target).find(".incon").eq(0).addClass("fast");
$(target).find(".host_con").addClass("fast");
} else if (data.used > 80 && data.used <= 200) {
$(target).find(".incon").eq(0).addClass("middle");
$(target).find(".host_con").addClass("middle");
} else if (data.used > 200) {
$(target).find(".incon").eq(0).addClass("slow");
$(target).find(".host_con").addClass("slow");
}
$(target).find(".host_con").text(data.used + "ms");
} else {
$(target).find(".incon").eq(0).addClass("nopass");
$(target).find(".host_con").addClass("nopass");
$(target).find(".host_con").text("Error");
}
});
}
$(".cbi-button-check").click(function () {
check();
return false;
});
//check();
});
</script>

View File

@ -1,6 +0,0 @@
<%+cbi/valueheader%>
<label class="cbi-value-title" style="display:inline-block; width: 180px" for="ulfile"><%:Choose local file:%></label>
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
<%+cbi/valuefooter%>

View File

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

View File

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

View File

@ -1,22 +0,0 @@
</style>
<div class="cbi-value">
<label class="cbi-value-title">udp2raw 项目</label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/udp2raw-tunnel','target');" />
</div>
</div>
<div class="cbi-value">
<label class="cbi-value-title">UDPspeeder 项目</label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/UDPspeeder','target');" />
</div>
</div>
</fieldset>
</fieldset>

View File

@ -1,109 +0,0 @@
<!-- ++ BEGIN ++ Auto Repeater ++ logsview.htm ++ -->
<%-
local values = self:formvalue(section)
if not values then
values = self:cfgvalue(section) or {self.default}
end
local function serialize_json(x, cb)
local rv, push = nil, cb
if not push then
rv = { }
push = function(tok) rv[#rv+1] = tok end
end
if x == nil then
push("null")
elseif type(x) == "table" then
push("[")
for k = 1, #x do
if k > 1 then
push(",")
end
serialize_json(x[k], push)
end
push("]")
else
push('"%s"' % tostring(x):gsub('["%z\1-\31\\]',
function(c) return '\\u%04x' % c:byte(1) end))
end
if not cb then
return table.concat(rv, "")
end
end
-%>
<%+cbi/valueheader%>
<select class="cbi-input-select" onchange="onclick_logview(this, false)"
<%=
attr("name", cbid) .. attr("id", cbid) .. attr("value", self.default) .. ifattr(self.size, "size")
%>
></select>
<script type="text/javascript">//<![CDATA[
(function() {
//var values = <%=serialize_json(values)%>;
var keylist = <%=serialize_json(self.keylist)%>;
var vallist = <%=serialize_json(self.vallist)%>;
var parent = document.getElementById("<%=cbid%>");
for (var j = 0; j < keylist.length; j++) {
var opt = document.createElement("option");
opt.value = keylist[j];
if (j == 0) {
opt.selected = "selected";
}
opt.appendChild(document.createTextNode(vallist[j]));
parent.appendChild(opt);
}
}());
//]]></script>
<script type="text/javascript">//<![CDATA[
function onclick_logview(id, bottom) {
// get elements
var txt = document.getElementById("<%=cbid%>.txt"); // TextArea
if ( !txt ) { return; } // security check
txt.value= "Reading: " + document.getElementById("<%=cbid%>").value
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr", "fileread")%>', {lfile: document.getElementById("<%=cbid%>").value} ,
function(x, ifc) {
if (! ifc) {txt.value = "XHR.get(<%=luci.dispatcher.build_url("admin", "vpn", "shadowsocksr", "fileread")%>) Failed!"; return;}
txt.value = ifc[0];
if (bottom)
txt.scrollTop = txt.scrollHeight;
else
txt.scrollTop = 0;
txt.scrollLeft = 0;
}
);
}
//]]></script>
<%
-- one button on top, one at the buttom
%>
<br /><br />
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, false)'
<%=
attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
%> />
<br /><br />
<%
-- set a readable style taken from openwrt theme for textarea#syslog
-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
%>
<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 200px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
<%=
attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
%> >
<%-=pcdata(self:cfgvalue(section))-%>
</textarea>
<br /><br />
<%
-- one button on top, one at the buttom
%>
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, true)'
<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
<br /><br />
<%+cbi/valuefooter%>
<!-- ++ END ++ Auto Repeater ++ logsview.htm ++ -->

View File

@ -1,350 +0,0 @@
<head>
<meta charset="utf-8">
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//cdn.jsdelivr.net">
<link rel="dns-prefetch" href="//whois.pconline.com.cn">
<link rel="dns-prefetch" href="//ipv4.ip.sb">
<link rel="dns-prefetch" href="//myip.ipip.net">
<link rel="dns-prefetch" href="//api.ipify.org">
<link rel="dns-prefetch" href="//api.ttt.sh">
<link rel="dns-prefetch" href="//api.skk.moe">
<link rel="dns-prefetch" href="//d.skk.moe">
<link rel="preconnect" href="https://whois.pconline.com.cn">
<link rel="preconnect" href="https://ip.sb">
<link rel="preconnect" href="https://myip.ipip.net">
<link rel="preconnect" href="https://api.ipify.org">
<link rel="preconnect" href="https://api.ttt.sh">
<link rel="preconnect" href="https://api.skk.moe">
<link rel="preconnect" href="https://d.skk.moe">
<link rel="shortcut icon" type="image/ico" href="https://cdn.jsdelivr.net/npm/skx@0.0.1">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,minimal-ui">
<style>
.ip-title {
font-weight: bold;
color: #444;
font-size:15px;
display: inline-block;
width: 25%;
vertical-align:bottom;
}
.ip-state_title {
font-weight: bold;
color: #444;
font-size:15px;
display: inline-block;
width: 52%;
vertical-align:bottom;
transform:translateY(10%);
}
.ip-result {
color: #444;
font-size:16px;
white-space: nowrap; /*强制span不换行*/
display: inline-block; /*将span当做块级元素对待*/
width: 29%; /*限制宽度*/
overflow: hidden; /*超出宽度部分隐藏*/
text-overflow: ellipsis; /*超出部分以点号代替*/
vertical-align:bottom;
transform:translateY(8%);
}
.ip-geo {
color: #444;
font-size:15px;
white-space: nowrap; /*强制span不换行*/
display: inline-block; /*将span当做块级元素对待*/
width: 40%; /*限制宽度*/
overflow: hidden; /*超出宽度部分隐藏*/
text-overflow: ellipsis; /*超出部分以点号代替*/
vertical-align:bottom;
transform:translateY(2%);
}
.ip-checking {
color: #444;
font-size:15px;
display: inline-block;
vertical-align:bottom;
width: 29%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transform:translateY(10%);
}
.sk-text-success {
color: #32b643;
font-size:15px;
display: inline-block;
vertical-align:bottom;
width: 48%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
transform:translateY(10%);
}
.sk-text-error {
color: #e85600;
font-size:15px;
display: inline-block;
vertical-align:bottom;
width: 48%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
transform:translateY(10%);
}
h3 {
margin: 5px 0 6px;
}
p {
margin: 10px 0;
}
a {
text-decoration: none;
color: #666;
}
</style>
</head>
<fieldset class="cbi-section">
<table>
<tr><td width="100%">
<body>
<div style="display: flex;">
<div style="width: 51%">
<h3><font color="#2E8B57"><B>IP 地址查询</B></font></h3>
<p>
<span class="ip-title">IP&nbsp;&nbsp;&nbsp;登录设备:</span><span class="ip-result" id="ip-webrtc"></span> <span class="ip-geo" id="ip-webrtc-cz88"></span>
</p>
<p>
<span class="ip-title">IPIP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;国内:</span><span class="ip-result" id="ip-ipipnet"></span> <span class="ip-geo" id="ip-ipipnet-geo"></span>
</p>
<p>
<span class="ip-title">IP.PC&nbsp;&nbsp;&nbsp;&nbsp;国内:</span><span class="ip-result" id="ip-pcol"></span> <span class="ip-geo" id="ip-pcol-ipip"></span>
</p>
<p>
<span class="ip-title">IP.SB&nbsp;&nbsp;&nbsp;&nbsp;海外:</span><span class="ip-result" id="ip-ipsb"></span> <span class="ip-geo" id="ip-ipsb-geo"></span>
</p>
<p>
<span class="ip-title">IPIFY&nbsp;&nbsp;&nbsp;&nbsp;海外:</span><span class="ip-result" id="ip-ipify"></span> <span class="ip-geo" id="ip-ipify-ipip"></span>
</p>
</div>
<div style="width: 49%">
<h3><font color="#2E8B57"><B>网站访问检查</B></font></h3>
<p>
<span class="ip-state_title">百度搜索:</span><span id="http-baidu"></span>
</p>
<p>
<span class="ip-state_title">网易云音乐:</span><span id="http-163"></span>
</p>
<p>
<span class="ip-state_title">GitHub:</span><span id="http-github"></span>
</p>
<p>
<span class="ip-state_title">Facebook:</span><span id="http-facebook"></span>
</p>
<p>
<span class="ip-state_title">YouTube:</span><span id="http-youtube"></span>
</p>
</div>
</div>
<div>
<p style="float: right; margin-top: 4px; font-size:15px; padding-right: 10px"><a onclick="return ip_skk()" href="javascript:void(0);">ip.skk.moe 提供支持</a></p>
</div>
</td></tr>
</table>
</fieldset>
<script>
function ip_skk()
{
url2='https://ip.skk.moe';
window.open(url2);
}
const $$ = document;
$$.getElementById('ip-webrtc').innerHTML = '查询中...';
$$.getElementById('ip-pcol').innerHTML = '查询中...';
$$.getElementById('ip-ipify').innerHTML = '查询中...';
$$.getElementById('ip-ipipnet').innerHTML = '查询中...';
$$.getElementById('ip-ipsb').innerHTML = '查询中...';
let random = parseInt(Math.random() * 100000000);
let IP = {
get: (url, type) =>
fetch(url, { method: 'GET' }).then((resp) => {
if (type === 'text')
return Promise.all([resp.ok, resp.status, resp.text(), resp.headers]);
else {
return Promise.all([resp.ok, resp.status, resp.json(), resp.headers]);
}
}).then(([ok, status, data, headers]) => {
if (ok) {
let json = {
ok,
status,
data,
headers
}
return json;
} else {
throw new Error(JSON.stringify(json.error));
}
}).catch(error => {
throw error;
}),
parseIPIpip: (ip, elID) => {
IP.get(`https://api.skk.moe/network/parseIp/ipip/v3/${ip}`, 'json')
.then(resp => {
let x = '';
for (let i of resp.data) {
x += (i !== '') ? `${i} ` : '';
}
$$.getElementById(elID).innerHTML = x;
//$$.getElementById(elID).innerHTML = `${resp.data.country} ${resp.data.regionName} ${resp.data.city} ${resp.data.isp}`;
})
},
getWebrtcIP: () => {
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
let pc = new RTCPeerConnection({ iceServers: [] }),
noop = () => { };
pc.createDataChannel('');
pc.createOffer(pc.setLocalDescription.bind(pc), noop);
pc.onicecandidate = (ice) => {
if (!ice || !ice.candidate || !ice.candidate.candidate) {
$$.getElementById('ip-webrtc').innerHTML = '没有查询到 IP';
return;
}
let ip = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
$$.getElementById('ip-webrtc').innerHTML = ip;
IP.parseIPIpip(ip, 'ip-webrtc-cz88');
pc.onicecandidate = noop;
};
},
getIpipnetIP: () => {
IP.get(`https://myip.ipip.net/?z=${random}`, 'text')
.then((resp) => {
let data = resp.data.replace('当前 IP', '').split(' 来自于:');
$$.getElementById('ip-ipipnet').innerHTML = `${data[0]}`;
$$.getElementById('ip-ipipnet-geo').innerHTML = `${data[1]}`;
});
},
getIPApiIP: () => {
IP.get(`https://ipapi.co/json?z=${random}`, 'json')
.then(resp => {
$$.getElementById('ip-ipapi').innerHTML = resp.data.ip;
IP.parseIPIpip(resp.data.ip, 'ip-ipapi-geo');
})
},
getIpifyIP: () => {
IP.get(`https://api.ipify.org/?format=json&z=${random}`, 'json')
.then(resp => {
$$.getElementById('ip-ipify').innerHTML = resp.data.ip;
return resp.data.ip;
})
.then(ip => {
IP.parseIPIpip(ip, 'ip-ipify-ipip');
})
}
};
$$.getElementById('http-baidu').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-163').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-github').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-facebook').innerHTML = '<span class="ip-checking">检测中...</span>';
$$.getElementById('http-youtube').innerHTML = '<span class="ip-checking">检测中...</span>';
let HTTP = {
checker: (domain, cbElID) => {
let img = new Image;
let timeout = setTimeout(() => {
img.onerror = img.onload = null;
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">连接超时</span>'
}, 5000);
img.onerror = () => {
clearTimeout(timeout);
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-error">无法访问</span>'
}
img.onload = () => {
clearTimeout(timeout);
$$.getElementById(cbElID).innerHTML = '<span class="sk-text-success">连接正常</span>'
}
img.src = `https://${domain}/favicon.ico?${+(new Date)}`
},
runcheck: () => {
HTTP.checker('www.baidu.com', 'http-baidu');
HTTP.checker('s1.music.126.net/style', 'http-163');
HTTP.checker('github.com', 'http-github');
HTTP.checker('www.facebook.com', 'http-facebook');
HTTP.checker('www.youtube.com', 'http-youtube');
}
};
HTTP.runcheck();
IP.getIpipnetIP();
IP.getIpifyIP();
IP.getWebrtcIP();
function getPcolIP(data){
let pcisp = data.addr.split(' ');
$$.getElementById('ip-pcol').innerHTML = data.ip;
$$.getElementById('ip-pcol-ipip').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`;
};
function getIpsbIP(data){
$$.getElementById('ip-ipsb').innerHTML = data.address;
$$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.province} ${data.city} ${data.isp.name}`
};
window.onload=myip_Load();
function myip_Load()
{
var pcip = document.getElementsByTagName('HEAD').item(0);
var pcipScript= document.createElement("script");
pcipScript.defer = "defer";
pcipScript.src='https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP';
pcip.appendChild(pcipScript);
var sbip = document.getElementsByTagName('HEAD').item(0);
var sbipScript= document.createElement("script");
sbipScript.defer = "defer";
sbipScript.src='https://ip.sb/addrinfo?callback=getIpsbIP';
sbip.appendChild(sbipScript);
const $$ = document;
random = parseInt(Math.random() * 100000000);
HTTP.runcheck();
IP.getIpipnetIP();
IP.getIpifyIP();
IP.getWebrtcIP();
function getPcolIP(data){
let pcisp = data.addr.split(' ');
$$.getElementById('ip-pcol').innerHTML = data.ip;
$$.getElementById('ip-pcol-ipip').innerHTML = `${data.pro} ${data.city} ${data.region} ${pcisp[1]}`;
};
function getIpsbIP(data){
$$.getElementById('ip-ipsb').innerHTML = data.address;
$$.getElementById('ip-ipsb-geo').innerHTML = `${data.country} ${data.province} ${data.city} ${data.isp.name}`
};
setTimeout("myip_Load()",1000*10);
}
</script>
<script defer="defer" src="https://whois.pconline.com.cn/ipJson.jsp?callback=getPcolIP"></script>
<script defer="defer" src="https://ip.sb/addrinfo?callback=getIpsbIP"></script>
</body>
</html>

View File

@ -1,28 +0,0 @@
<%+cbi/valueheader%>
<span class="pingtime" hint="<%=self:cfgvalue(section)%>">-- ms</span>
<%+cbi/valuefooter%>
</fieldset>
<!-- /tblsection --><script type="text/javascript">
//<![CDATA[
var pings = document.getElementsByClassName('pingtime');
for(var i = 0; i < pings.length; i++) {
XHR.get('/cgi-bin/luci/admin/vpn/shadowsocksr/ping', {
index: i,
domain: pings[i].getAttribute("hint")
},
function(x, result) {
pings[result.index].innerHTML = (result.ping ? "<b><font color=green>"+result.ping+"</font></b> ms" : "<b><font color=red> 检测失败 </font></b>");
}
);
XHR.poll(10,'/cgi-bin/luci/admin/vpn/shadowsocksr/ping',{
index: i,
domain: pings[i].getAttribute("hint")
},
function(x, result) {
pings[result.index].innerHTML = (result.ping ? "<b><font color=green>"+result.ping+"</font></b> ms" : "<b><font color=red> 检测失败 </font></b>");
}
);
}
//]]>
</script>

View File

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

View File

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

View File

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

View File

@ -1,210 +0,0 @@
<style>
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
.status{
margin: 1.5rem -0.5rem 0 -0.5rem;
}
.block{
margin: 0.5rem 0.5rem;
padding: 0;
font-weight: normal;
font-style: normal;
line-height: 1;
font-family: inherit;
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid rgba(0,0,0,.05);
border-radius: .375rem;
background-color: #fff ;
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
}
.img-con{
margin: 1rem;
}
.green{
color: #2dce89;
}
.red{
color: #f5365c;
}
.block img{
max-width: 100%;
height: auto;
}
.pure-u-5-8{
display:flex;
align-items:center;
}
.block h4{
font-size: 1.3rem;
font-weight: bold;
margin: 0.75rem 0;
line-height: 1.8em;
}
@media screen and (max-width: 1920px) {
.block h4{
font-size: 1.2rem;
}
}
@media screen and (max-width: 1690px) {
.block h4{
font-size: 1rem;
}
}
@media screen and (max-width: 1290px) {
.block h4{
font-size: 0.8rem;
}
.pure-u-1-6{
width:33.333%;
}
}
@media screen and (max-width: 700px) {
.pure-u-1-6{
width:50%;
}
.img-con{
margin: 0.5rem;
}
.block h4{
font-size: 0.81rem;
}
}
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<div class="pure-g status">
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/wzbtvXp.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="shadowsocksr_status"><%:Client%><br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/3mE04AZ.png">
</div>
</div>
<div class="pure-u-5-8">
<h4 id="google_status"><%:foreign websites%><br><span class="red"><%:Problem detected%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==" />
</div>
</div>
<div class="pure-u-5-8">
<h4 id="baidu_status"><%:domestic website%><br><span class="red"><%:Problem detected%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6I0ZCQjE0MDt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNODYuOCw0Ny42QzgzLjYsMzMsNzQuOCwyMi41LDY2LjUsMjNoLTAuM2MtMy4zLDAtNi41LDEuMi04LjksMy4zYy0xLjgsMi00LjQsMy4yLTcuMSwzLjINCgljLTIuNiwwLTUuMS0xLjEtNi45LTNjLTIuNS0yLjMtNS44LTMuNS05LjEtMy41aC0wLjRjLTguMi0wLjUtMTcuMSwxMC0yMC4zLDI0LjZjLTMuNSwxNS41LDAuOCwyOS44LDkuNSwzMS45DQoJYzYuMywxLjYsMTMuMy0zLjksMTcuOS0xM2gxOC43YzQuNyw5LjEsMTEuNiwxNC42LDE3LjksMTNDODYsNzcuNCw5MC4yLDYzLjEsODYuOCw0Ny42TDg2LjgsNDcuNnogTTQyLjksNDguNUgzNnY3LjJoLTUuNnYtNy4yDQoJaC02Ljl2LTUuOGg2Ljl2LTcuMkgzNnY3LjJoNi45TDQyLjksNDguNXogTTYyLjcsNDkuMmMtMiwwLjEtMy43LTEuNC0zLjgtMy40Yy0wLjEtMiwxLjQtMy43LDMuNC0zLjhjMi0wLjEsMy43LDEuNCwzLjgsMy40DQoJYzAsMC4xLDAsMC4xLDAsMC4yQzY2LjIsNDcuNSw2NC43LDQ5LjEsNjIuNyw0OS4yQzYyLjcsNDkuMiw2Mi43LDQ5LjIsNjIuNyw0OS4yeiBNNzMuNyw0OS4yYy0yLDAuMS0zLjctMS40LTMuOC0zLjQNCgljLTAuMS0yLDEuNC0zLjcsMy40LTMuOGMyLTAuMSwzLjcsMS40LDMuOCwzLjRjMCwwLjEsMCwwLjEsMCwwLjJjMC4xLDEuOS0xLjQsMy41LTMuMywzLjZINzMuN3oiLz4NCjwvc3ZnPg0K" />
</div>
</div>
<div class="pure-u-5-8">
<h4 id="game_status"><%:Game Mode%><br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/3hkGjsK.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="chinadns_status">𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/bYz9YoR.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="SOCKS5_status">𝙎𝙊𝘾𝙆𝙎⑤<br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
</div>
</style>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
function (x, data) {
var tb = document.getElementById('shadowsocksr_status');
var tb1 = document.getElementById('google_status');
var tb2 = document.getElementById('baidu_status');
var tb3 = document.getElementById('game_status');
var tb4 = document.getElementById('chinadns_status');
var tb5 = document.getElementById('SOCKS5_status');
if (data && tb) {
if (data.global) {
tb.innerHTML = '<%:Client%><br><span class="green"><%:Running%></span>';
} else {
tb.innerHTML = '<%:Client%><br><span class="red"><%:Not Running%></span>';
}
if (data.google) {
tb1.innerHTML = '<%:foreign websites%><br><span class="green"><%:Connect OK%></span>';
} else {
tb1.innerHTML = '<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
}
if (data.baidu) {
tb2.innerHTML = '<%:domestic website%><br><span class="green"><%:Connect OK%></span>';
} else {
tb2.innerHTML = '<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
}
if (data.game) {
tb3.innerHTML = '<%:Game Mode%><br><span class="green"><%:Running%></span>';
} else {
tb3.innerHTML = '<%:Game Mode%><br><span class="red"><%:Not Running%></span>';
}
if (data.chinadns) {
tb4.innerHTML = '𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="green"><%:Running%></span>';
} else {
tb4.innerHTML = '𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br><span class="red"><%:Not Running%></span>';
}
if (data.SOCKS5 ) {
tb5.innerHTML = '𝙎𝙊𝘾𝙆𝙎5<br><span class="green"><%:Running%></span>';
} else {
tb5.innerHTML = '𝙎𝙊𝘾𝙆𝙎5<br><span class="red"><%:Not Running%></span>';
}
}
}
);
//]]>
</script>

View File

@ -1,202 +0,0 @@
<fieldset id="_shadowsocksr_status_fieldset" class="cbi-section">
<legend>
<%:Running Status%>
</legend>
<style>
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
.status{
margin: 1.5rem -0.5rem 0 -0.5rem;
}
.block{
margin: 0.5rem 0.5rem;
padding: 0;
font-weight: normal;
font-style: normal;
line-height: 1;
font-family: inherit;
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid rgba(0,0,0,.05);
border-radius: .375rem;
background-color: #fff ;
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
}
.img-con{
margin: 1rem;
}
.green{
color: #2dce89;
}
.red{
color: #f5365c;
}
.block img{
max-width: 100%;
height: auto;
}
.pure-u-5-8{
display:flex;
align-items:center;
}
.block h4{
font-size: 1.3rem;
font-weight: bold;
margin: 0.75rem 0;
line-height: 1.8em;
}
@media screen and (max-width: 1920px) {
.block h4{
font-size: 1.2rem;
}
}
@media screen and (max-width: 1690px) {
.block h4{
font-size: 1rem;
}
}
@media screen and (max-width: 1290px) {
.block h4{
font-size: 0.8rem;
}
.pure-u-1-6{
width:33.333%;
}
}
@media screen and (max-width: 700px) {
.pure-u-1-6{
width:50%;
}
.img-con{
margin: 0.5rem;
}
.block h4{
font-size: 0.81rem;
}
}
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<div class="pure-g status">
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/wzbtvXp.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="shadowsocksr_status"><%:Client%><br /><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/3mE04AZ.png">
</div>
</div>
<div class="pure-u-5-8">
<h4 id="google_status"><%:foreign websites%><br /><span class="red"><%:Problem detected%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==">
</div>
</div>
<div class="pure-u-5-8">
<h4 id="baidu_status"><%:domestic website%><br /><span class="red"><%:Problem detected%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/0EJktYn.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="ss_server_status"><%:SS Servers%><br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/8Fj5nX2.png">
</div>
</div>
<div class="pure-u-5-8">
<h4 id="ssr_server_status"><%:SSR Servers%><br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g" >
<div class="pure-u-3-8">
<div class="img-con">
<img src="https://i.imgur.com/cWo9mwE.png" >
</div>
</div>
<div class="pure-u-5-8">
<h4 id="v2_server_status"><%:V2 Servers%><br><span class="red"><%:Not Running%></span></h4>
</div>
</div>
</div>
</div>
</style>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
function (x, data) {
var tb = document.getElementById('shadowsocksr_status');
var tb1 = document.getElementById('google_status');
var tb2 = document.getElementById('baidu_status');
var tb3 = document.getElementById('ss_server_status');
var tb4 = document.getElementById('ssr_server_status');
var tb5 = document.getElementById('v2_server_status');
if (data && tb) {
if (data.global) {
tb.innerHTML = '<%:Client%><br><span class="green"><%:Running%></span>';
} else {
tb.innerHTML = '<%:Client%><br><span class="red"><%:Not Running%></span>';
}
if (data.google) {
tb1.innerHTML = '<%:foreign websites%><br><span class="green"><%:Connect OK%></span>';
} else {
tb1.innerHTML = '<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
}
if (data.baidu) {
tb2.innerHTML = '<%:domestic website%><br><span class="green"><%:Connect OK%></span>';
} else {
tb2.innerHTML = '<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
}
if (data.ss_server) {
tb3.innerHTML = '<%:SS Servers%><br><span class="green"><%:Running%></span>';
} else {
tb3.innerHTML = '<%:SS Servers%><br><span class="red"><%:Not Running%></span>';
}
if (data.ssr_server) {
tb4.innerHTML = '<%:SSR Servers%><br><span class="green"><%:Running%></span>';
} else {
tb4.innerHTML = '<%:SSR Servers%><br><span class="red"><%:Not Running%></span>';
}
if (data.v2_server ) {
tb5.innerHTML = '<%:V2 Servers%><br><span class="green"><%:Running%></span>';
} else {
tb5.innerHTML = '<%:V2 Servers%><br><span class="red"><%:Not Running%></span>';
}
}
}
);
//]]>
</script>
</fieldset>

View File

@ -1,177 +0,0 @@
<style>
.pure-g{letter-spacing:-.31em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){table .pure-g{display:block}}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u,.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class*=pure-u]{font-family:sans-serif}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-6-6{width:100%}
.status{
margin: 0rem -0.5rem -0.7rem -0.5rem;
}
.block{
margin: 0.5rem 0.5rem;
padding: 0;
font-weight: normal;
font-style: normal;
line-height: 1;
font-family: inherit;
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid rgba(0,0,0,.05);
border-radius: .375rem;
background-color: #fff;
box-shadow: 0 0 2rem 0 rgba(136,152,170,.15);
}
.img-con{
margin: 1rem;
}
.green{
font-size:1.25rem;
color: #2dce89;
}
.red{
font-size:1.25rem;
color: #fb6340;
}
.sk-text-success{
color: #2dce89;
}
.sk-text-error{
color: #fb6340;
}
.gap{
margin-right:0.5rem;
}
.block img{
width: 48px;
height: auto;
float:right;
}
.pure-u-5-8{
display:flex;
align-items:center;
}
.block h4{
font-size: .8125rem;
font-weight: 600;
margin: 1rem;
color:#8898aa!important;
line-height: 1.8em;
}
@media screen and (max-width: 720px) {
.pure-u-1-6{
width:50%;
}
.pure-u-1-2{
width:100%;
}
}
</style>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
</head>
<body>
<div class="pure-g status">
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="shadowsocksr_status"><%:Client%><br /><span class="red"><%:Not Running%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="https://i.imgur.com/wzbtvXp.png" >
</div>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="baidu_status"><%:domestic website%><br><span class="red"><%:Problem detected%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6IzMzODhGRjt9DQoJLnN0MXtmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8ZyBpZD0i5pCc57SiX+eGiuaOjF82Nmljb24iPg0KCTxnIGlkPSJsb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjEuMjEyMTIxLCA5MC45MDkwOTEpIj4NCgkJPHBhdGggaWQ9IkZpbGwtMSIgY2xhc3M9InN0MSIgZD0iTS03OS43LTU1LjRjNC41LDAsOC41LTUuNCw4LjUtMTEuOWMwLTYuNS0zLjctMTEuOS04LjUtMTEuOWMtNC41LDAtOC41LDUuNC04LjUsMTEuOQ0KCQkJQy04Ny45LTYwLjctODQuMi01NS40LTc5LjctNTUuNCIvPg0KCQk8cGF0aCBpZD0iRmlsbC0zIiBjbGFzcz0ic3QxIiBkPSJNLTU5LjktNTQuNWM2LjIsMC44LDEwLjItNS43LDExLTEwLjhjMC44LTQuOC0zLjEtMTAuOC03LjYtMTEuNmMtNC4yLTEuMS05LjksNS45LTEwLjIsMTAuNQ0KCQkJQy02Ny4yLTYxLTY2LjEtNTUuNC01OS45LTU0LjUiLz4NCgkJPHBhdGggaWQ9IkZpbGwtNSIgY2xhc3M9InN0MSIgZD0iTS05NS4zLTM4LjZjOC41LTEuNyw3LjEtMTEuNiw3LjEtMTMuOWMtMC4zLTMuNC00LjItOS4zLTkuOS04LjhjLTYuOCwwLjYtNy42LDEwLjItNy42LDEwLjINCgkJCUMtMTA2LjktNDYuNi0xMDMuOC0zNi45LTk1LjMtMzguNiIvPg0KCQk8cGF0aCBpZD0iRmlsbC03IiBjbGFzcz0ic3QxIiBkPSJNLTM1LjItNDYuM2MwLTIuNS0yLTkuNi05LjMtOS42Yy03LjQsMC04LjUsNi44LTguNSwxMS42YzAsNC41LDAuMywxMSw5LjYsMTAuOA0KCQkJQy0zNC40LTMzLjgtMzUuMi00NC0zNS4yLTQ2LjMiLz4NCgkJPHBhdGggaWQ9IkZpbGwtOSIgY2xhc3M9InN0MSIgZD0iTS04Ni41LTIxLjRjLTAuMywwLjYtMC44LDIuNS0wLjMsNGMwLjgsMy40LDQsMy43LDQsMy43aDQuMnYtMTAuOGgtNC44DQoJCQlDLTg1LjEtMjMuNi04Ni4yLTIxLjktODYuNS0yMS40Ii8+DQoJCTxwYXRoIGlkPSJGaWxsLTExIiBjbGFzcz0ic3QxIiBkPSJNLTUzLjEtOS41aC0xMi43Yy00LjgtMS4xLTUuMS00LjgtNS4xLTQuOHYtMTMuOWg1LjF2MTIuNWMwLjMsMS40LDIsMS43LDIsMS43aDUuNHYtMTMuOWg1LjQNCgkJCVYtOS41eiBNLTczLjItOS4ySC04NGMtNC44LTAuOC02LjgtNC4yLTYuOC00LjhjLTAuMy0wLjYtMS43LTMuMS0wLjgtNy42YzItNi41LDcuOS03LjEsNy45LTcuMWg1Ljd2LTcuMWg0LjgNCgkJCUMtNzMuMi0zNS44LTczLjItOS4yLTczLjItOS4yeiBNLTQ0LjYtMjUuM2MwLDAtOS42LTcuNC0xNS4zLTE1LjNjLTcuNi0xMS42LTE4LjQtNy4xLTIxLjgtMS4xYy0zLjQsNS45LTkuMSw5LjktOS45LDEwLjgNCgkJCWMtMC44LDAuOC0xMS42LDYuOC05LjEsMTcuM0MtOTguMS0zLjItODkuOS0zLjUtODkuOS0zLjVzNi4yLDAuNiwxMy4zLTEuMWM3LjEtMS43LDEzLjMsMC4zLDEzLjMsMC4zUy00Ni42LDEuMy00Mi05LjcNCgkJCUMtMzcuNS0xOS43LTQ0LjYtMjUuMy00NC42LTI1LjNMLTQ0LjYtMjUuM3oiLz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==" />
</div>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="google_status"><%:foreign websites%><br><span class="red"><%:Problem detected%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="https://i.imgur.com/3mE04AZ.png">
</div>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="game_status"><%:Game Mode%><br /><span class="red"><%:Not Running%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i5Zu+5bGCXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6I0ZCQjE0MDt9DQoJLnN0MXtmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIi8+DQo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNODYuOCw0Ny42QzgzLjYsMzMsNzQuOCwyMi41LDY2LjUsMjNoLTAuM2MtMy4zLDAtNi41LDEuMi04LjksMy4zYy0xLjgsMi00LjQsMy4yLTcuMSwzLjINCgljLTIuNiwwLTUuMS0xLjEtNi45LTNjLTIuNS0yLjMtNS44LTMuNS05LjEtMy41aC0wLjRjLTguMi0wLjUtMTcuMSwxMC0yMC4zLDI0LjZjLTMuNSwxNS41LDAuOCwyOS44LDkuNSwzMS45DQoJYzYuMywxLjYsMTMuMy0zLjksMTcuOS0xM2gxOC43YzQuNyw5LjEsMTEuNiwxNC42LDE3LjksMTNDODYsNzcuNCw5MC4yLDYzLjEsODYuOCw0Ny42TDg2LjgsNDcuNnogTTQyLjksNDguNUgzNnY3LjJoLTUuNnYtNy4yDQoJaC02Ljl2LTUuOGg2Ljl2LTcuMkgzNnY3LjJoNi45TDQyLjksNDguNXogTTYyLjcsNDkuMmMtMiwwLjEtMy43LTEuNC0zLjgtMy40Yy0wLjEtMiwxLjQtMy43LDMuNC0zLjhjMi0wLjEsMy43LDEuNCwzLjgsMy40DQoJYzAsMC4xLDAsMC4xLDAsMC4yQzY2LjIsNDcuNSw2NC43LDQ5LjEsNjIuNyw0OS4yQzYyLjcsNDkuMiw2Mi43LDQ5LjIsNjIuNyw0OS4yeiBNNzMuNyw0OS4yYy0yLDAuMS0zLjctMS40LTMuOC0zLjQNCgljLTAuMS0yLDEuNC0zLjcsMy40LTMuOGMyLTAuMSwzLjcsMS40LDMuOCwzLjRjMCwwLjEsMCwwLjEsMCwwLjJjMC4xLDEuOS0xLjQsMy41LTMuMywzLjZINzMuN3oiLz4NCjwvc3ZnPg0K" />
</div>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="chinadns_status">𝐂𝐡𝐢𝐧𝐚𝐃𝐍𝐒<br /><span class="red"><%:Not Running%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="https://i.imgur.com/3hkGjsK.png" >
</div>
</div>
</div>
</div>
<div class="pure-u-1-6">
<div class="block pure-g">
<div class="pure-u-3-5">
<h4 id="SOCKS5_status">𝙎𝙊𝘾𝙆𝙎5<br /><span class="red"><%:Not Running%></span></h4>
</div>
<div class="pure-u-2-5">
<div class="img-con">
<img src="https://i.imgur.com/bYz9YoR.png" >
</div>
</div>
</div>
</div>
</div>
<script>
//<![CDATA[
XHR.poll(5, '<%=url([[admin]], [[vpn]], [[shadowsocksr]], [[run]])%>', null,
function (x, data) {
if (data) {
document.getElementById('shadowsocksr_status').innerHTML = data.global?'<%:Client%><br><span class="green"><%:Running%></span>':'<%:Client%><br><span class="red"><%:Not Running%></span>';
document.getElementById('baidu_status').innerHTML = data.baidu?'<%:domestic website%><br><span class="green"><%:Connect OK%></span>':'<%:domestic website%><br><span class="red"><%:Problem detected%></span>';
document.getElementById('google_status').innerHTML = data.google?'<%:foreign websites%><br><span class="green"><%:Connect OK%></span>':'<%:foreign websites%><br><span class="red"><%:Problem detected%></span>';
document.getElementById('game_status').innerHTML = data.game?'<%:Game Mode%><br><span class="green"><%:Running%></span>':'<%:Game Mode%><br><span class="red"><%:Not Running%></span>';
document.getElementById('chinadns_status').innerHTML = data.chinadns?'ChinaDNS<br><span class="green"><%:Running%></span>':'ChinaDNS<br><span class="red"><%:Not Running%></span>';
document.getElementById('SOCKS5_status').innerHTML = data.SOCKS5?'𝙎𝙊𝘾𝙆𝙎5<br><span class="green"><%:Running%></span>':'𝙎𝙊𝘾𝙆𝙎5<br><span class="red"><%:Not Running%></span>';
}
}
);
//]]>
</script>

View File

@ -1,123 +0,0 @@
<%+cbi/valueheader%>
<link rel="stylesheet" href="/luci-static/shadowsocksr/css/shadowsocksr.css?v=72883">
<label class="cbi-value-title"><%= translate("Update") %></label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-reload" id="update_subscribe" type="button"
size="0" value="<%= translate("Save And Start Subscribe") %>">
</div>
<script type="text/javascript">
//<![CDATA[
var _responseLen;
var noChange = 0;
var x = 5;
var modal = '<div class="modals-bg">' +
'<div class="modals">' +
'<h2><%:Subscription%></h2>'+
'<h3 style="margin-left:0;"><%:Subscribing,Please do not refresh!%></h3>'+
'<textarea cols="63" rows="28" wrap="on" readonly="readonly" id="log_content3" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"></textarea>'+
'</div>'+
'</div>';
function update_subscribe() {
$("body").append(modal);
$(".modals-bg").show();
setTimeout("get_realtime_log();", 500);
}
function submit_url(){
prefix_array = $("#cbi-shadowsocksr-server_subscribe .cbi-section-node").attr("id").split("-");
prefix_array[0] = "cbid";
prefix = prefix_array.join(".");
if($("[name='"+prefix+".auto_update']").is(":checked")){
var auto_update = "1";
}else{
var auto_update = "0";
}
var auto_update_time = $("[name='"+prefix+".auto_update_time']").val();
var subscribe_url = [];
$("[name='"+prefix+".subscribe_url']").each(function(){
if($(this).val() != ""){
subscribe_url.push($(this).val());
}
});
if($("[name='"+prefix+".proxy']").is(":checked")){
var proxy = "1";
}else{
var proxy = "0";
}
var data = {
auto_update:auto_update,
auto_update_time : auto_update_time,
subscribe_url: JSON.stringify(subscribe_url),
proxy: proxy
}
//console.log(data);
$.ajax({
type: "post",
url: "<%=luci.dispatcher.build_url('admin', 'vpn', 'shadowsocksr','subscribe')%>",
dataType : "json",
data: data,
success: function (d) {
if(d.error == 0){
//console.log("开始订阅");
update_subscribe();
}else{
alert("请至少填写一个订阅链接");
}
}
});
}
$("#update_subscribe").click(function(){
//console.log("提交数据");
submit_url();
return false;
});
function refresh_page(){
location.reload();
return false;
}
function get_realtime_log() {
$.ajax({
url: '/check_update.htm?v='+parseInt(Math.random() * 100000000),
dataType: 'html',
error: function (xhr) {
setTimeout("get_realtime_log();", 1000);
},
success: function (response) {
var retArea = document.getElementById("log_content3");
if (response.search("END SUBSCRIBE") != -1) {
noChange++;
}
console.log(noChange);
if (noChange > 10) {
window.location.href="<%=luci.dispatcher.build_url('admin', 'vpn', 'shadowsocksr','servers')%>"
return false;
} else {
setTimeout("get_realtime_log();", 250);
}
retArea.value = response;
retArea.scrollTop = retArea.scrollHeight;
_responseLen = response.length;
},
error: function () {
setTimeout("get_realtime_log();", 500);
}
});
}
//]]>
</script>
<%+cbi/valuefooter%>

View File

@ -1,868 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8\n"
msgid "Enable"
msgstr "启用"
msgid "Disable"
msgstr "停用"
msgid "Enable Servers"
msgstr "开启服务"
msgid "Enable Authentication"
msgstr "启用 用户名/密码 认证"
msgid "Open v2ray split-flow"
msgstr "开启V2ray分流"
msgid "When open v2ray split-flow,your main server must be a v2ray server"
msgstr "当使用v2ray分流功能时 主服务器必须为V2ray"
msgid "Youtube Proxy"
msgstr "Youtube 代理"
msgid "TaiWan Video Proxy"
msgstr "台湾视频服务代理"
msgid "Netflix Proxy"
msgstr "Netflix 代理"
msgid "Diseny+ Proxy"
msgstr "Diseny+ 代理"
msgid "Prime Video Proxy"
msgstr "Prime Video 代理"
msgid "adblock settings"
msgstr "广告屏蔽设置"
msgid "Enable adblock"
msgstr "开启广告屏蔽"
msgid "adblock_url"
msgstr "广告屏蔽订阅"
msgid "Socks user"
msgstr "用户名"
msgid "Socks pass"
msgstr "密码"
msgid "Ping All Servers"
msgstr "PING 所有节点"
msgid "Ping Latency"
msgstr "Ping 延迟"
msgid "SSR SOCKS5 Proxy"
msgstr "SSR SOCKS5代理"
msgid "Subscription"
msgstr "订阅管理"
msgid "Subscribing,Please do not refresh!"
msgstr "订阅,请不要刷新!"
msgid "Check Try Count"
msgstr "切换检查重试次数"
msgid "Log"
msgstr "日志"
msgid "Bypass Domain List"
msgstr "不走代理的域名"
msgid "Black Domain List"
msgstr "强制走代理的域名"
msgid "Node List"
msgstr "节点列表"
msgid "END SUBSCRIBE"
msgstr "结束订阅"
msgid "Update Setting"
msgstr "更新设置"
msgid "AlterId"
msgstr "额外ID"
msgid "Save And Start Subscribe"
msgstr "保存并开始订阅"
msgid "VmessId (UUID)"
msgstr "用户ID(UUID)"
msgid "Transport"
msgstr "传输方式"
msgid "Configuration Url"
msgstr "配置链接"
msgid "Import Configuration"
msgstr "导入配置信息"
msgid "Apply"
msgstr "应用"
msgid "total"
msgstr "总计"
msgid "Node list"
msgstr "节点列表"
msgid "Nodes"
msgstr "个节点"
msgid "Client"
msgstr "客户端"
msgid "Visit foreign websites"
msgstr "国外网站"
msgid "Visit domestic website"
msgstr "国内网站"
msgid "Problem detected"
msgstr "无法访问"
msgid "Working..."
msgstr "连接正常"
msgid "Game Mode"
msgstr "游戏模式"
msgid "V2ray SOCKS5 Proxy"
msgstr "V2ray SOCKS5代理"
msgid "Edit ShadowSocksR Server"
msgstr "编辑服务器配置"
msgid "ShadowSocksR is running"
msgstr "ShadowSocksR 客户端运行中"
msgid "ShadowSocksR is not running"
msgstr "ShadowSocksR 客户端未运行"
msgid "Global Setting"
msgstr "全局设置"
msgid "Global Server"
msgstr "全局服务器"
msgid "ShadowSocksR SOCK5 Proxy is running"
msgstr "ShadowSocksR SOCK5代理运行中"
msgid "UDP Relay Server"
msgstr "UDP中继服务器"
msgid "Same as Global Server"
msgstr "与全局服务器相同"
msgid "Servers Setting"
msgstr "服务器配置"
msgid "Alias(optional)"
msgstr "别名(可选)"
msgid "Onetime Authentication"
msgstr "一次验证"
msgid "Server Address"
msgstr "服务器地址"
msgid "Server Port"
msgstr "服务器端口"
msgid "Local Port"
msgstr "本地端口"
msgid "Connection Timeout"
msgstr "连接超时"
msgid "Password"
msgstr "密码"
msgid "Encrypt Method"
msgstr "加密方式"
msgid "Protocol"
msgstr "传输协议"
msgid "Protocol param(optional)"
msgstr "传输协议参数(可选)"
msgid "Obfs"
msgstr "混淆插件"
msgid "Obfs param(optional)"
msgstr "混淆参数(可选)"
msgid "Enable Tunnel(DNS)"
msgstr "启用隧道DNS转发"
msgid "Tunnel Port"
msgstr "隧道DNS本地端口"
msgid "Forwarding Tunnel"
msgstr "隧道DNS转发地址"
msgid "Access Control"
msgstr "访问控制"
msgid "Interfaces - WAN"
msgstr "接口 - WAN"
msgid "Bypassed IP List"
msgstr "被忽略IP列表"
msgid "NULL - As Global Proxy"
msgstr "留空 - 作为全局代理"
msgid "Bypassed IP"
msgstr "额外被忽略IP"
msgid "Forwarded IP"
msgstr "强制走代理IP"
msgid "Interfaces - LAN"
msgstr "接口 - LAN"
msgid "LAN Access Control"
msgstr "内网客户端分流代理控制"
msgid "Allow listed only"
msgstr "仅允许列表内主机"
msgid "Allow all except listed"
msgstr "除列表外主机皆允许"
msgid "LAN Host List"
msgstr "内网主机列表"
msgid "SSR Client"
msgstr "客户端"
msgid "ShadowSocksR Server"
msgstr "ShadowSocksR 服务端"
msgid "ShadowSocksR Server is running"
msgstr "ShadowSocksR 服务端运行中"
msgid "ShadowSocksR Server is not running"
msgstr "ShadowSocksR 服务端未运行"
msgid "Enable Server"
msgstr "启动服务端"
msgid "Server Setting"
msgstr "服务端配置"
msgid "KcpTun Enable"
msgstr "KcpTun 启用"
msgid "bin:/usr/bin/kcptun-client"
msgstr "二进制文件:/usr/bin/kcptun-client"
msgid "KcpTun Port"
msgstr "KcpTun 端口"
msgid "KcpTun Param"
msgstr "KcpTun 参数"
msgid "KcpTun Password"
msgstr "KcpTun 密码"
msgid "Haven't a Kcptun executable file"
msgstr "不存在Kcptun可执行文件请下载Kcptun可执行文件并改名放入/usr/bin/kcptun-client"
msgid "Not a Kcptun executable file"
msgstr "Kcptun可执行文件格式不正确请确认是否正确下载了路由器对应的可执行文件"
msgid "Enable Process Monitor"
msgstr "启用进程监控"
msgid "Edit ShadowSocksR Server"
msgstr "编辑服务器配置"
msgid "Alias"
msgstr "别名"
msgid "SOCKS5 Proxy"
msgstr "SOCKS5代理"
msgid "Server"
msgstr "服务器"
msgid "TCP Fast Open"
msgstr "TCP快速打开"
msgid "Status"
msgstr "状态"
msgid "Unknown"
msgstr "未知"
msgid "Running Status"
msgstr "运行状态"
msgid "ShadowSocksR Plus+"
msgstr "ShadowSocksR Plus+ 魔改版"
msgid "Global Client"
msgstr "TCP透明代理"
msgid "Global SSR Server"
msgstr "SSR服务端"
msgid "DNS Tunnel"
msgstr "DNS 隧道"
msgid "IPK Version"
msgstr "IPK 版本号"
msgid "KcpTun Version"
msgstr "KcpTun 版本号"
msgid "Not exist"
msgstr "未安装可执行文件"
msgid "IPK Installation Time"
msgstr "IPK 安装时间"
msgid "Project"
msgstr "项目地址"
msgid "Not Running"
msgstr "未运行"
msgid "Running"
msgstr "运行中"
msgid "Enable GFW mode"
msgstr "启用 GFW 模式"
msgid "Running Mode"
msgstr "运行模式"
msgid "IP Route Mode"
msgstr "绕过中国大陆IP模式"
msgid "GFW List Mode"
msgstr "GFW列表模式"
msgid "Global Mode"
msgstr "全局模式"
msgid "Oversea Mode"
msgstr "海外用户回国模式"
msgid "Router Proxy"
msgstr "路由器访问控制"
msgid "Normal Proxy"
msgstr "正常代理"
msgid "Bypassed Proxy"
msgstr "不走代理"
msgid "Forwarded Proxy"
msgstr "强制走代理"
msgid "UDP Relay"
msgstr "UDP中继"
msgid "Google Connectivity"
msgstr "【谷歌】连通性检查"
msgid "Baidu Connectivity"
msgstr "【百度】连通性检查"
msgid "No Check"
msgstr "未检查"
msgid "Check"
msgstr "检查"
msgid "Connect OK"
msgstr "连接正常"
msgid "Connect Error"
msgstr "连接错误"
msgid "Check..."
msgstr "正在检查.."
msgid "Proxy Check"
msgstr "代理检查"
msgid "GFW List Data"
msgstr "【GFW列表】数据库"
msgid "China IP Data"
msgstr "【国内IP段】数据库"
msgid "Records"
msgstr "条记录"
msgid "Refresh Data"
msgstr "更新数据库"
msgid "Refresh..."
msgstr "正在更新,请稍候.."
msgid "Refresh OK!"
msgstr "更新成功!"
msgid "Refresh Error!"
msgstr "更新失败!"
msgid "No new data!"
msgstr "你已经是最新数据,无需更新!"
msgid "Total Records:"
msgstr "新的总纪录数:"
msgid "Check Server Port"
msgstr "【服务器端口】检查"
msgid "Check Connect"
msgstr "检查连通性"
msgid "Basic Settings"
msgstr "服务器设置"
msgid "Check Server"
msgstr "检查服务器"
msgid "Auto Switch"
msgstr "自动切换"
msgid "Enable Auto Switch"
msgstr "启用自动切换"
msgid "Switch check cycly(second)"
msgstr "自动切换检查周期(秒)"
msgid "Check timout(second)"
msgstr "切换检查超时时间(秒)"
msgid "Enable Process Deamon"
msgstr "启用进程自动守护"
msgid "Advertising Data"
msgstr "【广告屏蔽】数据库"
msgid "DNS Server IP and Port"
msgstr "DNS服务器地址和端口"
msgid "Resolve Dns Mode"
msgstr "DNS解析方式"
msgid "Use SSR DNS Tunnel"
msgstr "使用SSR-DNS隧道"
msgid "Use Pdnsd"
msgstr "使用Pdnsd"
msgid "Use Other DNS Tunnel(Need to install)"
msgstr "使用其他DNS转发(需要自己安装)"
msgid "Import SSR"
msgstr "导入ssr配置信息"
msgid "Export SSR"
msgstr "导出ssr配置信息"
msgid "Import SSR successfully."
msgstr "成功导入SSR。"
msgid "Invalid SSR format."
msgstr "无效的SSR格式。"
msgid "User cancelled."
msgstr "用户已取消。"
msgid "Paste ssr url here"
msgstr "在此处粘贴ssr://网址"
msgid "Unable to copy SSR to clipboard."
msgstr "无法复制SSR网址到剪贴板。"
msgid "Copy SSR to clipboard successfully."
msgstr "成功复制SSR网址到剪贴板。"
msgid "Servers Manage"
msgstr "服务器管理"
msgid "Auto Update"
msgstr "自动更新"
msgid "Through proxy update"
msgstr "通过代理更新"
msgid "GFW List"
msgstr "GFW列表"
msgid "ShadowSocksR Plus+ Settings"
msgstr "ShadowSocksR Plus+ 设置支持SS/SSR/V2RAY/Trojan"
msgid "Main Server"
msgstr "主服务器"
msgid "Anti-pollution DNS Server"
msgstr "访问国外域名DNS服务器"
msgid "Use Pdnsd tcp query and cache"
msgstr "使用PDNSD TCP查询并缓存"
msgid "DNS Server IP:Port"
msgstr "DNS服务器 IP:Port"
msgid "Update time (every day)"
msgstr "更新时间 (每天)"
msgid "Auto Update Server subscription, GFW list and CHN route"
msgstr "自动更新服务器订阅、GFW列表和 CHN路由表"
msgid "Subscribe URL"
msgstr "SS/SSR/V2RAY订阅URL地址"
msgid "Update"
msgstr "更新"
msgid "Server Count"
msgstr "服务器节点数量"
msgid "IP black-and-white list"
msgstr "IP黑白名单"
msgid "WAN IP AC"
msgstr "WAN IP访问控制"
msgid "WAN White List IP"
msgstr "不走代理的WAN IP"
msgid "WAN Force Proxy IP"
msgstr "强制走代理的WAN IP"
msgid "LAN Bypassed Host List"
msgstr "不走代理的局域网LAN IP"
msgid "LAN Force Proxy Host List"
msgstr "全局代理的LAN IP"
msgid "Router Self AC"
msgstr "路由器自身代理设置"
msgid "Router Self Proxy"
msgstr "路由器自身代理方式"
msgid "Normal Proxy"
msgstr "跟随全局设置"
msgid "Bypassed Proxy"
msgstr "不走代理"
msgid "Forwarded Proxy"
msgstr "全局代理"
msgid "GFW Custom List"
msgstr "GFW 用户自定义列表"
msgid "Please refer to the following writing"
msgstr "每行一个域名,无需写前面的 HTTP(S):// ,提交后即时生效"
msgid "Servers subscription and manage"
msgstr "节点订阅"
msgid "Through proxy update list, Not Recommended"
msgstr "通过路由器自身代理更新订阅(不推荐)"
msgid "LAN IP AC"
msgstr "LAN IP访问控制"
msgid "Game Mode UDP Server"
msgstr "游戏模式UDP中继服务器"
msgid "Game Mode UDP Relay"
msgstr "游戏模式UDP中继"
msgid "Server failsafe auto swith settings"
msgstr "服务器节点故障自动切换设置"
msgid "Delete all severs"
msgstr "删除所有服务器"
msgid "Severs Nodes"
msgstr "服务器节点"
msgid "Use Local DNS Service listen port 5335"
msgstr "使用本机端口为5335的DNS服务"
msgid "Server Node Type"
msgstr "服务器节点类型"
msgid "Using incorrect encryption mothod may causes service fail to start"
msgstr "输入不正确的参数组合可能会导致服务无法启动"
msgid "Game Mode Host List"
msgstr "增强游戏模式客户端LAN IP"
msgid "Multi Threads Option"
msgstr "多线程并发转发"
msgid "Auto Threads"
msgstr "自动CPU线程数"
msgid "1 Thread"
msgstr "单线程"
msgid "2 Threads"
msgstr "2 线程"
msgid "4 Threads"
msgstr "4 线程"
msgid "8 Threads"
msgstr "8 线程"
msgid "16 Threads"
msgstr "16 线程"
msgid "32 Threads"
msgstr "32 线程"
msgid "64 Threads"
msgstr "64 线程"
msgid "128 Threads"
msgstr "128 线程"
msgid "256 Threads"
msgstr "256 线程"
msgid "512 Threads"
msgstr "512 线程"
msgid "Proxy Ports"
msgstr "需要代理的端口"
msgid "All Ports"
msgstr "所有端口(默认)"
msgid "Only Common Ports"
msgstr "仅常用端口不走P2P流量到代理"
msgid "Use dnscrypt-proxy query and cache"
msgstr "使用dnscrypt-proxy TCP查询并缓存"
msgid "Use dnsforwarder tcp query and cache"
msgstr "使用dnsforwarder TCP查询并缓存"
msgid "Use Pdnsd udp query and cache"
msgstr "使用Pdnsd UDP查询并缓存"
msgid "Use dnsforwarder udp query and cache"
msgstr "使用dnsforwarder UDP查询并缓存"
msgid "Use chinadns query and cache"
msgstr "使用ChinaDNS查询并缓存"
msgid "Chiadns Resolve Dns Mode"
msgstr "ChinaDNS的上游服务器"
msgid "Use Local DNS Service"
msgstr "使用设定DNS解析"
msgid "Oversea GFW List Mode"
msgstr "海外用户回国域名列表模式"
msgid "Oversea IP Route Mode"
msgstr "海外用户回国IP路由模式"
msgid "Use Local DNS Service"
msgstr "使用设定DNS解析"
msgid "Using System Default DNS"
msgstr "使用系统默认DNS"
msgid "Using acceleration center DNS"
msgstr "使用加速中心DNS"
msgid "Appoint dns List"
msgstr "指定DNS解析列表"
msgid "Use https_dns_proxy query and cache"
msgstr "使用https_dns_proxy TCP查询并缓存"
msgid "Use smartdns query and cache"
msgstr "使用SmartDNS TCP查询并缓存"
msgid "Use Pcap_DNSProxy query and cache"
msgstr "使用Pcap DNSProxy TCP查询并缓存"
msgid "Kill BT"
msgstr "禁止 BT"
msgid "BT Port"
msgstr "BT 端口"
msgid "Enabling IPv6 server"
msgstr "启用ipv6服务"
msgid "Prohibit downloading tool ports through proxy"
msgstr "禁止BT端口走代理"
msgid "udp2raw Version"
msgstr "udp2raw 版本"
msgid "udp2raw tunnel Project"
msgstr "udp2raw 项目"
msgid "UDPspeeder Version"
msgstr "UDPspeeder 版本"
msgid "UDPspeeder Project"
msgstr "UDPspeeder 项目"
msgid "Appointlist List"
msgstr "DNS列表"
msgid "udp2raw tunnel"
msgstr "UDP隧道"
msgid "Enable udp2raw"
msgstr "启用 udp2raw"
msgid "Enable UDPspeeder"
msgstr "启用 UDPspeeder"
msgid "SOCKS5 Proxy"
msgstr "SOCKS5代理"
msgid "SSOCKS5 Proxy"
msgstr "SS SOCKS5代理"
msgid "Global SS Server"
msgstr "SS服务端"
msgid "V2SOCKS5 Proxy"
msgstr "V2ray SOCKS5代理"
msgid "Global V2RAY Server"
msgstr "V2RAY服务端"
msgid "haProxy settings"
msgstr "HaProxy 设置"
msgid "Enabling the Management Console"
msgstr "启用管理控制台"
msgid "Service Port"
msgstr "端口"
msgid "Socket Connected"
msgstr "连接测试"
msgid "Enable HTTP Proxy"
msgstr "启用HTTP代理"
msgid "HTTP Port"
msgstr "HTTP代理端口"
msgid "plugin"
msgstr "插件"
msgid "Plugin Opts"
msgstr "插件参数"
msgid "Before subscribing please click below to delete all servers in the subscription"
msgstr "订阅前请点击下面的删除所有服务器在订阅"
msgid "Chnroute Setting"
msgstr "国内IP段数据库更新设置"
msgid "Enable custom chnroute"
msgstr "启用自定义更新地址"
msgid "Update url"
msgstr "更新链接"
msgid "HTTP Proxy"
msgstr "HTTP代理"
msgid "Raw Mode"
msgstr "模式"
msgid "Seq Mode"
msgstr "Seq模式"
msgid "Cipher Mode"
msgstr "加密模式"
msgid "Auth Mode"
msgstr "校验模式"
msgid "Speeder Mode"
msgstr "Speeder模式"
msgid "Fec"
msgstr "fec参数"
msgid "Mtu"
msgstr "mtu参数"
msgid "SS Servers"
msgstr "SS服务器"
msgid "SSR Servers"
msgstr "SSR服务器"
msgid "SSR Server"
msgstr "服务端"
msgid "V2 Servers"
msgstr "V2服务器"
msgid "SS/SSR/V2RAY Server"
msgstr "SS/SSR/V2RAY 服务端"
msgid "Delete All Subscribe Severs"
msgstr "删除所有订阅服务器节点"
msgid "Update All Subscribe Severs"
msgstr "更新所有订阅服务器节点"
msgid "No special needs, please click here to subscribe to update"
msgstr "没有特殊需要,请点击这里订阅更新"
msgid "Running Details:"
msgstr "进程详情:"
msgid "File Viewer"
msgstr "文件查看器"

View File

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

View File

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

View File

@ -1,120 +0,0 @@
config server_config
option type 'ss'
option ipv4_ipv6 '0'
option server_port '8387'
option timeout '60'
option password 'admin'
option encrypt_method 'aes-256-ctr'
option enable '0'
config server_config
option type 'ssr'
option ipv4_ipv6 '0'
option server_port '8388'
option timeout '60'
option password '222'
option protocol 'origin'
option obfs 'plain'
option encrypt_method 'aes-192-cfb'
option enable '0'
config server_config
option type 'v2ray'
option ipv4_ipv6 '0'
option server_port '8389'
option timeout '60'
option alter_id '100'
option VMess_level '1'
option vmess_id '576f451f-0d21-44ed-aeaf-9b27a24d7bc9'
option security 'auto'
option transport 'tcp'
option tcp_guise 'none'
option tls '1'
option enable '0'
config global
option tunnel_address '0.0.0.0'
option monitor_enable '1'
option enable_switch '1'
option switch_timeout '5'
option switch_time '667'
option threads '0'
option bt '0'
option global_server 'nil'
option run_mode 'router'
option pdnsd_enable '1'
option tunnel_forward '8.8.4.4:53'
config socks5_proxy
option local_port '1080'
option local_address '0.0.0.0'
option http_port '1081'
option bt '0'
option server 'nil'
option http_enable '0'
config global_haproxy
option admin_enable '1'
option admin_port '1111'
option admin_user 'admin'
option admin_password 'root'
option balancing_enable '0'
config access_control
option wan_bp_list '/etc/china_ssr.txt'
option lan_ac_mode 'b'
option router_proxy '1'
list wan_fw_ips '149.154.160.0/20'
list wan_fw_ips '67.198.55.0/24'
list wan_fw_ips '91.108.4.0/22'
list wan_fw_ips '91.108.56.0/22'
list wan_fw_ips '109.239.140.0/24'
list wan_fw_ips '1.1.1.1/32'
list wan_fw_ips '1.0.0.1/32'
list wan_fw_ips '8.8.8.8/32'
list wan_fw_ips '8.8.4.4/32'
list wan_fw_ips '9.9.9.9/32'
list wan_fw_ips '146.112.41.2/32'
config server_global
option enable_server '0'
config server_subscribe
option proxy '0'
option auto_update_time '2'
option auto_update '0'
option v2ray_update '0'
option edition '4.20.0'
config domain_white_list
option domain_names 'youdao.com'
config domain_white_list
option domain_names 'gov.cn'
config udp2raw
option server '127.0.0.1'
option local_port '400'
option key 'passwd'
option seq_mode '3'
option auth_mode 'simple'
option bt '0'
option udp2raw_enable '1'
option raw_mode 'udp'
option cipher_mode 'aes128cbc'
option server_port '600'
config udpspeeder
option server '127.0.0.1'
option server_port '400'
option local_port '500'
option key 'passwd'
option speeder_mode '0'
option fec '2:4'
option mtu '1250'
option queue_len '1'
option timeout '8'
option udpspeeder_enable '1'

View File

@ -1,2 +0,0 @@
apple.com
microsoft.com

View File

@ -1,3 +0,0 @@
server=/.3g.music.qq.com/127.0.0.1#5335
ipset=/3g.music.qq.com/oversea

View File

@ -1,143 +0,0 @@
server=/.1test.cn/119.29.29.29#53
server=/.360wzb.cn/119.29.29.29#53
server=/.51cdn.com/119.29.29.29#53
server=/.5test.cn/119.29.29.29#53
server=/.aicdn.com/119.29.29.29#53
server=/.alikunlun.com/119.29.29.29#53
server=/.alikunlun.net/119.29.29.29#53
server=/.b2r.com.cn/119.29.29.29#53
server=/.baiduyundns.cn/119.29.29.29#53
server=/.baiduyundns.com/119.29.29.29#53
server=/.baiduyundns.net/119.29.29.29#53
server=/.bcedns.cn/119.29.29.29#53
server=/.bcedns.com/119.29.29.29#53
server=/.bcedns.net/119.29.29.29#53
server=/.bdydns.cn/119.29.29.29#53
server=/.bdydns.com/119.29.29.29#53
server=/.bdydns.net/119.29.29.29#53
server=/.blueit.com/119.29.29.29#53
server=/.blueit.org.cn/119.29.29.29#53
server=/.cachecn.com/119.29.29.29#53
server=/.cachecn.net/119.29.29.29#53
server=/.cc-1.com/119.29.29.29#53
server=/.cc-cps.cn/119.29.29.29#53
server=/.cc-cps.com.cn/119.29.29.29#53
server=/.cc-cps.com/119.29.29.29#53
server=/.cc-cps.mobi/119.29.29.29#53
server=/.cc-cps.net/119.29.29.29#53
server=/.ccbench.com/119.29.29.29#53
server=/.ccgslb.cn/119.29.29.29#53
server=/.ccgslb.com.cn/119.29.29.29#53
server=/.ccgslb.com/119.29.29.29#53
server=/.ccgslb.net.cn/119.29.29.29#53
server=/.ccgslb.net/119.29.29.29#53
server=/.ccindex.cn/119.29.29.29#53
server=/.ccindex.com.cn/119.29.29.29#53
server=/.ccmplus.cn/119.29.29.29#53
server=/.ccmplus.com.cn/119.29.29.29#53
server=/.ccmplus.net/119.29.29.29#53
server=/.cdn2cdn.net/119.29.29.29#53
server=/.cdnetworks.net/119.29.29.29#53
server=/.cdngc.net/119.29.29.29#53
server=/.cdnsvc.cn/119.29.29.29#53
server=/.cdnsvc.com.cn/119.29.29.29#53
server=/.cdnsvc.com/119.29.29.29#53
server=/.cdnsvc.net.cn/119.29.29.29#53
server=/.cdnsvc.net/119.29.29.29#53
server=/.cdntip.com/119.29.29.29#53
server=/.cdnudns.com/119.29.29.29#53
server=/.chinacache.com.cn/119.29.29.29#53
server=/.chinacache.com/119.29.29.29#53
server=/.chinacache.net/119.29.29.29#53
server=/.chinacache.org/119.29.29.29#53
server=/.chinanetcenter.com/119.29.29.29#53
server=/.cloudcdn.cn/119.29.29.29#53
server=/.cloudcdn.net/119.29.29.29#53
server=/.clouddn.com/119.29.29.29#53
server=/.cloudglb.com/119.29.29.29#53
server=/.cloudglb.net/119.29.29.29#53
server=/.cloudtcp.net/119.29.29.29#53
server=/.cloudxns.com/119.29.29.29#53
server=/.cloudxns.net/119.29.29.29#53
server=/.dnspao.com/119.29.29.29#53
server=/.fastcdn.com /119.29.29.29#53
server=/.fastweb.com.cn/119.29.29.29#53
server=/.fastwebcdn.com/119.29.29.29#53
server=/.ffdns.net/119.29.29.29#53
server=/.fsspace.cn/119.29.29.29#53
server=/.fsspace.com.cn/119.29.29.29#53
server=/.fsspace.com/119.29.29.29#53
server=/.fwcdn.com/119.29.29.29#53
server=/.fwcdn.net/119.29.29.29#53
server=/.fwdns.net/119.29.29.29#53
server=/.fwmob.com/119.29.29.29#53
server=/.gccdn.net/119.29.29.29#53
server=/.gslbsvc.cn/119.29.29.29#53
server=/.gslbsvc.com.cn/119.29.29.29#53
server=/.gslbsvc.com/119.29.29.29#53
server=/.gslbsvc.net.cn/119.29.29.29#53
server=/.gslbsvc.net/119.29.29.29#53
server=/.hacdn.com/119.29.29.29#53
server=/.hacdn.net/119.29.29.29#53
server=/.hadns.net/119.29.29.29#53
server=/.hdslb.com/119.29.29.29#53
server=/.hdslb.net/119.29.29.29#53
server=/.hd-cdn.com/119.29.29.29#53
server=/.igslb.net/119.29.29.29#53
server=/.kunlunaq.com/119.29.29.29#53
server=/.kunlunar.com/119.29.29.29#53
server=/.kunlunca.com/119.29.29.29#53
server=/.kunluncan.com/119.29.29.29#53
server=/.kunlunea.com/119.29.29.29#53
server=/.kunlungem.com/119.29.29.29#53
server=/.kunlungr.com/119.29.29.29#53
server=/.kunlunhuf.com/119.29.29.29#53
server=/.kunlunle.com/119.29.29.29#53
server=/.kunlunli.com/119.29.29.29#53
server=/.kunlunno.com/119.29.29.29#53
server=/.kunlunpi.com/119.29.29.29#53
server=/.kunlunra.com/119.29.29.29#53
server=/.kunlunsa.com/119.29.29.29#53
server=/.kunlunsc.com/119.29.29.29#53
server=/.kunlunsl.com/119.29.29.29#53
server=/.kunlunso.com/119.29.29.29#53
server=/.kunlunta.com/119.29.29.29#53
server=/.kunlunvi.com/119.29.29.29#53
server=/.kunlunwe.com/119.29.29.29#53
server=/.lxdns.com/119.29.29.29#53
server=/.lxdns.net/119.29.29.29#53
server=/.lxsvc.cn /119.29.29.29#53
server=/.lxsvc.cn/119.29.29.29#53
server=/.lxsvc.net/119.29.29.29#53
server=/.myqcloud.com/119.29.29.29#53
server=/.myxns.cn/119.29.29.29#53
server=/.myxns.com.cn/119.29.29.29#53
server=/.myxns.net.cn/119.29.29.29#53
server=/.myxns.org/119.29.29.29#53
server=/.netcenter.com.cn/119.29.29.29#53
server=/.newdefend.cn/119.29.29.29#53
server=/.newdefend.com.cn/119.29.29.29#53
server=/.newdefend.com/119.29.29.29#53
server=/.newdefend.net.cn/119.29.29.29#53
server=/.newdefend.net/119.29.29.29#53
server=/.newdefend.org.cn/119.29.29.29#53
server=/.newdefend.org/119.29.29.29#53
server=/.ourglb0.com/119.29.29.29#53
server=/.ourwebat.com/119.29.29.29#53
server=/.ourwebcdn.com/119.29.29.29#53
server=/.qbox.me/119.29.29.29#53
server=/.qcloud.com/119.29.29.29#53
server=/.qingcdn.com/119.29.29.29#53
server=/.qiniudn.com/119.29.29.29#53
server=/.qiniudns.com/119.29.29.29#53
server=/.speedupchina.com/119.29.29.29#53
server=/.speedupchina.net/119.29.29.29#53
server=/.sz-dns.net/119.29.29.29#53
server=/.tcdn.qq.com/119.29.29.29#53
server=/.tlgslb.com /119.29.29.29#53
server=/.wangsu.com/119.29.29.29#53
server=/.webluker.com/119.29.29.29#53
server=/.wscdns.com/119.29.29.29#53
server=/.wsngb.com/119.29.29.29#53
server=/.xgslb.net/119.29.29.29#53
server=/.yunjiasu-cdn.net/119.29.29.29#53

View File

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

View File

@ -1,21 +0,0 @@
#!/bin/sh
# Copyright (C) 2007 OpenWrt.org
/etc/init.d/shadowsocksr enabled && {
[ "$ACTION" = "ifup" ] && {
local_server=`uci get shadowsocksr.@global[0].global_server 2>/dev/null`
if [ "$local_server" = "nil" ] ;then
echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR/v2ray not running!" >> /tmp/ssrplus.log
else
icount=`ps -w | grep ssr-retcp |grep -v grep| wc -l`
if [ $icount = 0 ] ;then
echo "$(date "+%Y-%m-%d %H:%M:%S") Shadowsocks/ShadowsocksR/v2ray error.restart!" >> /tmp/ssrplus.log
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
}
}

View File

@ -1,23 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@shadowsocksr[-1]
add ucitrack shadowsocksr
set ucitrack.@shadowsocksr[-1].init=shadowsocksr
commit ucitrack
delete firewall.shadowsocksr
set firewall.shadowsocksr=include
set firewall.shadowsocksr.type=script
set firewall.shadowsocksr.path=/var/etc/shadowsocksr.include
set firewall.shadowsocksr.reload=1
commit firewall
EOF
/etc/init.d/dnscrypt-proxy stop
/etc/init.d/dnscrypt-proxy disable
/etc/init.d/privoxy stop
/etc/init.d/privoxy disable
killall -q -9 v2ray-plugin
/usr/share/shadowsocksr/gfw2ipset.sh
rm -f /tmp/luci-indexcache
exit 0

View File

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

View File

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

View File

@ -1,277 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2017 openwrt-ssr
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
NAME=shadowsocksr
logfile="/tmp/ssrplus.log"
uci_get_by_name() {
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo ${ret:=$3}
}
server_process_count=$1
redir_tcp_process=$2
redir_udp_process=$3
tunnel_process=$4
kcp_process=$5
local_process=$6
pdnsd_process=$7
dnsforwarder_process=$8
ssserver_process=$10
ssrserver_process=$11
v2rayserver_process=$12
haproxy_process=$13
privoxy_process=$14
chinadns_process=$15
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}
sock5_port=$(uci_get_by_type socks5_proxy local_port 1080)
if [ "$(uci_get_by_type global chinadns_enable)" = "0" ] ;then
dnsstrs="$(uci_get_by_type global tunnel_forward 8.8.4.4:53)"
else
dnsstrs="0.0.0.0:5337"
fi
if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
server=${server}
else
server=`cat /etc/ssr_ip`
fi
while [ "1" = "1" ] #死循环
do
sleep 30
#redir tcp
if [ $redir_tcp_process -gt 0 ] ;then
icount=`ps -w | grep ssr-retcp |grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr redir tcp error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") redir tcp error.restart!" >> ${logfile}
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#redir udp
if [ $redir_udp_process -gt 0 ] ;then
icount=`ps -w | grep ssr-reudp|grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr redir udp error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") redir udp error.restart!" >> ${logfile}
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#tunnel
if [ $tunnel_process -gt 0 ] ;then
icount=`ps -w | grep ssr-tunnel |grep -v grep| wc -l`
if [ $icount = 0 ] ;then
logger -t "$NAME" "ssr tunnel error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") tunnel error.restart!" >> ${logfile}
/etc/init.d/shadowsocksr restart
exit 0
fi
fi
#server
#ssr_server
if [ $server_process_count -gt 0 ] ;then
if [ $ssrserver_process -gt 0 ] ;then
icount=`ps -w | grep ssr-server |grep -v grep| wc -l`
if [ $icount -lt $ssrserver_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr server error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr server error.restart!" >> ${logfile}
killall -q -9 ssr-server
for i in `seq $ssrserver_process`
do
/usr/bin/ssr-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ssr-server$i.pid
done
fi
fi
#ss_server
if [ $ssserver_process -gt 0 ] ;then
icount=`ps -w | grep ss-server |grep -v grep| wc -l`
if [ $icount -lt $ssserver_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ss server error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") ss server error.restart!" >> ${logfile}
killall -q -9 ss-server
for i in `seq $ssserver_process`
do
/usr/bin/ss-server -c /var/etc/shadowsocksr_$i.json -u -f /var/run/ss-server$i.pid
done
fi
fi
#v2ray_server
if [ v2rayserver_process -gt 0 ] ;then
icount=`ps -w | grep ss-server |grep -v grep| wc -l`
if [ $icount -lt $v2rayserver_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "v2ray server error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray server error.restart!" >> ${logfile}
kill -9 $(ps | grep v2ray-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
for i in `seq $v2rayserver_process`
do
( /usr/bin/v2ray/v2ray -config /var/etc/v2ray-server-$i.json >/dev/null 2>&1 &)
done
fi
fi
fi
#kcptun
if [ $kcp_process -gt 0 ] ;then
icount=`ps -w | grep kcptun-client |grep -v grep| wc -l`
if [ $icount -lt $kcp_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr kcptun error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr kcptun error.restart!" >> ${logfile}
killall -q -9 kcptun-client
( /usr/bin/kcptun-client -r $server:$kcp_port -l :$server_port $password $kcp_param &)
fi
fi
#local
if [ $local_process -eq 1 ] ;then
icount=`ps -w | grep ssr-local |grep -v grep| wc -l`
if [ $icount -lt $local_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ssr local error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") ssr local error.restart!" >> ${logfile}
killall -q -9 ssr-local
( /usr/bin/ssr-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ssr-local.pid &)
fi
fi
#local
if [ $local_process -eq 2 ] ;then
local_processs=1
icount=`ps -w | grep ss-local |grep -v grep| wc -l`
if [ $icount -lt $local_processs ] #如果进程挂掉就重启它
then
logger -t "$NAME" "ss local error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") ss local error.restart!" >> ${logfile}
killall -q -9 ss-local
( /usr/bin/ss-local -c /var/etc/shadowsocksr_s.json -u -l $sock5_port -f /var/run/ss-local.pid &)
fi
fi
#local
if [ $local_process -eq 3 ] ;then
local_processs=1
icount=`ps -w | grep v2-ssr-local |grep -v grep| wc -l`
if [ $icount -lt $local_processs ] #如果进程挂掉就重启它
then
logger -t "$NAME" "v2ray local error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray local error.restart!" >> ${logfile}
kill -9 $(ps | grep v2-ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
( /usr/bin/v2ray/v2ray -config /var/etc/v2-ssr-local.json >/dev/null 2>&1 &)
fi
fi
#privoxy
if [ $privoxy_process -gt 0 ] ;then
icount=`ps -w | grep privoxy |grep -v grep| wc -l`
if [ $icount -lt $privoxy_process ]; then
logger -t "$NAME" "privoxy http local error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") privoxy http loca error.restart!" >> ${logfile}
kill -9 $(ps | grep privoxy | grep -v grep | awk '{print $1}') >/dev/null 2>&1
/etc/init.d/privoxy restart
fi
fi
#dnsforwarder
if [ $dnsforwarder_process -gt 0 ] ;then
icount=`ps -w | grep dnsparsing |grep -v grep| wc -l`
if [ $icount -lt $dnsforwarder_process ]; then
logger -t "$NAME" "dnsforwarder tunnel error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") dnsforwarder tunnel error.restart!" >> ${logfile}
kill -9 $(ps | grep dnsparsing | grep -v grep | awk '{print $1}') >/dev/null 2>&1
( dnsparsing -f /var/run/dnsparsing/dnsparsing.conf -d &)
fi
fi
#pdnsd
if [ $pdnsd_process -gt 0 ] ;then
icount=`ps -w | grep pdnsd |grep -v grep| wc -l`
if [ $icount -lt $pdnsd_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "pdnsd tunnel error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") pdnsd tunnel error.restart!" >> ${logfile}
if [ -f /var/run/pdnsd.pid ] ;then
kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
else
kill -9 $(ps | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1
fi
( /usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d &)
fi
fi
#chiandns
if [ $chinadns_process -gt 0 ] ;then
icount=`ps -w | grep chinadns |grep -v grep| wc -l`
if [ $icount -lt $chinadns_process ]; then
logger -t "$NAME" "chinadns tunnel error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") chinadns tunnel error.restart!" >> ${logfile}
kill -9 $(ps | grep chinadns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
(nohup /usr/bin/chinadns -p 5335 -c /etc/china_ssr.txt -m -d -s $dnsstrs >/dev/null 2>&1 &)
fi
fi
#haproxy
if [ $haproxy_process -gt 0 ] ;then
icount=`ps -w | grep haproxy |grep -v grep| wc -l`
if [ $icount -lt $haproxy_process ] #如果进程挂掉就重启它
then
logger -t "$NAME" "haproxy error.restart!"
echo "$(date "+%Y-%m-%d %H:%M:%S") haproxy error.restart!" >> ${logfile}
/etc/init.d/shadowsocksr restart
fi
fi
#udp2raw
if [ $(uci_get_by_type udp2raw udp2raw_enable) = 1 ] ;then
ucount=`ps -w | grep udp2raw |grep -v grep| wc -l`
if [ $ucount = 0 ] ;then
/usr/bin/udp2raw --clear >/dev/null
/usr/bin/udp2raw --conf-file /var/etc/udp2raw.conf >/dev/null 2>&1 &
fi
fi
#udpspeeder
if [ $(uci_get_by_type udpspeeder udpspeeder_enable) = 1 ] ;then
scount=`ps -w | grep udpspeeder |grep -v grep| wc -l`
if [ $scount = 0 ] ;then
/usr/bin/udpspeeder -c -l0.0.0.0:$(uci_get_by_type udpspeeder local_port) \
-r$(uci_get_by_type udpspeeder server):$(uci_get_by_type udpspeeder server_port) \
-k $(uci_get_by_type udpspeeder key) \
--mode $(uci_get_by_type udpspeeder speeder_mode) \
--mtu $(uci_get_by_type udpspeeder mtu) \
-f$(uci_get_by_type udpspeeder fec) \
-q$(uci_get_by_type udpspeeder queue_len) \
--timeout $(uci_get_by_type udpspeeder timeout) \
>/dev/null 2>&1 &
fi
fi
done

View File

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

View File

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

View File

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

View File

@ -1,38 +0,0 @@
local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"
local server_section = arg[1]
local proto = arg[2]
local local_port = arg[3]
local server = ucursor:get_all("shadowsocksr", server_section)
local trojan = {
run_type = "nat",
local_addr = "0.0.0.0",
local_port = tonumber(local_port),
remote_addr = server.server,
remote_port = tonumber(server.server_port),
-- 传入连接
password = {server.password},
-- 传出连接
ssl = {
verify = true,
verify_hostname = true,
cert = (server.certificate == "1") and server.certpath or "",
cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RSA-AES128-GCM-SHA256:RSA-AES256-GCM-SHA384:RSA-AES128-SHA:RSA-AES256-SHA:RSA-3DES-EDE-SHA",
sni = server.tls_host,
alpn = {"h2", "http/1.1"},
curve = "",
reuse_session = true,
session_ticket = true,
},
tcp = {
no_delay = true,
keep_alive = true,
reuse_port = true,
fast_open = (server.fast_open == "1") and true or false,
fast_open_qlen = 20
}
}
print(json.stringify(trojan, 1))

View File

@ -1,95 +0,0 @@
local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"
local server_section = arg[1]
local proto = arg[2]
local local_port = arg[3]
local server = ucursor:get_all("shadowsocksr", server_section)
local v2ray = {
log = {
-- error = "/var/ssrplus.log",
loglevel = "warning"
},
-- 传入连接
inbound = {
port = local_port,
protocol = "dokodemo-door",
settings = {
network = proto,
followRedirect = true
},
sniffing = {
enabled = true,
destOverride = { "http", "tls" }
}
},
-- 传出连接
outbound = {
protocol = "vmess",
settings = {
vnext = {
{
address = "0.0.0.0",
port = '4433',
users = {
{
id = server.vmess_id,
alterId = tonumber(server.alter_id),
security = server.security
}
}
}
}
},
-- 底层传输配置
streamSettings = {
network = server.transport,
security = (server.tls == '1') and "tls" or "none",
tlsSettings = {allowInsecure = (server.insecure == "1") and true or false,},
kcpSettings = (server.transport == "kcp") and {
mtu = tonumber(server.mtu),
tti = tonumber(server.tti),
uplinkCapacity = tonumber(server.uplink_capacity),
downlinkCapacity = tonumber(server.downlink_capacity),
congestion = (server.congestion == "1") and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size),
header = {
type = server.kcp_guise
}
} or nil,
wsSettings = (server.transport == "ws") and {
path = server.ws_path,
headers = (server.ws_host ~= nil) and {
Host = server.ws_host
} or nil,
} or nil,
httpSettings = (server.transport == "h2") and {
path = server.h2_path,
host = server.h2_host,
} or nil,
quicSettings = (server.transport == "quic") and {
security = server.quic_security,
key = server.quic_key,
header = {
type = server.quic_guise
}
} or nil
},
mux = {
enabled = (server.mux == "1") and true or false,
concurrency = tonumber(server.concurrency)
}
},
-- 额外传出连接
outboundDetour = {
{
protocol = "freedom",
tag = "direct",
settings = { keep = "" }
}
}
}
print(json.stringify(v2ray, 1))

View File

@ -1,107 +0,0 @@
local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"
local server_section = arg[1]
local proto = arg[2]
local local_port = arg[3]+1
local socks_port = arg[4]
local server = ucursor:get_all("shadowsocksr", server_section)
local v2ray = {
log = {
-- error = "/var/ssrplus.log",
loglevel = "warning"
},
-- 传入连接
inbound = {
port = local_port,
protocol = "dokodemo-door",
settings = {
network = proto,
followRedirect = true
},
sniffing = {
enabled = true,
destOverride = { "http", "tls" }
}
},
-- 开启 socks 和 http 代理
inboundDetour = (proto == "tcp") and {
{
protocol = "socks",
port = socks_port,
settings = {
auth = "noauth",
udp = true
}
}
} or nil,
-- 传出连接
outbound = {
protocol = "vmess",
settings = {
vnext = {
{
address = server.server,
port = tonumber(server.server_port),
users = {
{
id = server.vmess_id,
alterId = tonumber(server.alter_id),
security = server.security
}
}
}
}
},
-- 底层传输配置
streamSettings = {
network = server.transport,
security = (server.tls == '1') and "tls" or "none",
tlsSettings = {allowInsecure = (server.insecure == "1") and true or false,},
kcpSettings = (server.transport == "kcp") and {
mtu = tonumber(server.mtu),
tti = tonumber(server.tti),
uplinkCapacity = tonumber(server.uplink_capacity),
downlinkCapacity = tonumber(server.downlink_capacity),
congestion = (server.congestion == "1") and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size),
header = {
type = server.kcp_guise
}
} or nil,
wsSettings = (server.transport == "ws") and {
path = server.ws_path,
headers = (server.ws_host ~= nil) and {
Host = server.ws_host
} or nil,
} or nil,
httpSettings = (server.transport == "h2") and {
path = server.h2_path,
host = server.h2_host,
} or nil,
quicSettings = (server.transport == "quic") and {
security = server.quic_security,
key = server.quic_key,
header = {
type = server.quic_guise
}
} or nil
},
mux = {
enabled = (server.mux == "1") and true or false,
concurrency = tonumber(server.concurrency)
}
},
-- 额外传出连接
outboundDetour = {
{
protocol = "freedom",
tag = "direct",
settings = { keep = "" }
}
}
}
print(json.stringify(v2ray, 1))

View File

@ -1,65 +0,0 @@
local ucursor = require "luci.model.uci".cursor()
local json = require "luci.jsonc"
local server_section = arg[1]
local server = ucursor:get_all("shadowsocksr", server_section)
local v2ray = {
log = {
--error = "/var/log/v2ray.log",
loglevel = "warning"
},
-- 传入连接
inbound = {
port = tonumber(server.server_port),
protocol = "vmess",
settings = {
clients = {
{
id = server.vmess_id,
alterId = tonumber(server.alter_id),
level = tonumber(server.VMess_level)
}
}
},
-- 底层传输配置
streamSettings = {
network = server.transport,
security = (server.tls == '1') and "tls" or "none",
kcpSettings = (server.transport == "kcp") and {
mtu = tonumber(server.mtu),
tti = tonumber(server.tti),
uplinkCapacity = tonumber(server.uplink_capacity),
downlinkCapacity = tonumber(server.downlink_capacity),
congestion = (server.congestion == "1") and true or false,
readBufferSize = tonumber(server.read_buffer_size),
writeBufferSize = tonumber(server.write_buffer_size),
header = {
type = server.kcp_guise
}
} or nil,
httpSettings = (server.transport == "h2") and {
path = server.h2_path,
host = server.h2_host,
} or nil,
quicSettings = (server.transport == "quic") and {
security = server.quic_security,
key = server.quic_key,
header = {
type = server.quic_guise
}
} or nil
}
},
-- 传出连接
outbound = {
protocol = "freedom"
},
-- 额外传出连接
outboundDetour = {
{
protocol = "blackhole",
tag = "blocked"
}
}
}
print(json.stringify(v2ray,1))

View File

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

View File

@ -1,440 +0,0 @@
#!/usr/bin/lua
------------------------------------------------
-- This file is part of the luci-app-ssr-plus subscribe.lua
-- @author William Chan <root@williamchan.me>
------------------------------------------------
require 'nixio'
require 'luci.util'
require 'luci.jsonc'
require 'luci.sys'
-- these global functions are accessed all the time by the event handler
-- so caching them is worth the effort
local luci = luci
local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
local b64decode = nixio.bin.b64decode
local cache = {}
local nodeResult = setmetatable({}, { __index = cache }) -- update result
local name = 'shadowsocksr'
local uciType = 'servers'
local ucic = luci.model.uci.cursor()
local proxy = ucic:get_first(name, 'server_subscribe', 'proxy', '0')
local switch = ucic:get_first(name, 'server_subscribe', 'switch', '1')
local subscribe_url = ucic:get_first(name, 'server_subscribe', 'subscribe_url', {})
local log = function(...)
print(os.date("%Y-%m-%d %H:%M:%S ") .. table.concat({ ... }, " "))
end
-- 分割字符串
local function split(full, sep)
full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0
local off, result = 1, {}
while true do
local nStart, nEnd = full:find(sep, off)
if not nEnd then
local res = ssub(full, off, slen(full))
if #res > 0 then -- 过滤掉 \0
tinsert(result, res)
end
break
else
tinsert(result, ssub(full, off, nStart - 1))
off = nEnd + 1
end
end
return result
end
-- urlencode
local function get_urlencode(c)
return sformat("%%%02X", sbyte(c))
end
local function urlEncode(szText)
local str = szText:gsub("([^0-9a-zA-Z ])", get_urlencode)
str = str:gsub(" ", "+")
return str
end
local function get_urldecode(h)
return schar(tonumber(h, 16))
end
local function UrlDecode(szText)
return szText:gsub("+", " "):gsub("%%(%x%x)", get_urldecode)
end
-- trim
local function trim(text)
if not text or text == "" then
return ""
end
return (sgsub(text, "^%s*(.-)%s*$", "%1"))
end
-- md5
local function md5(content)
local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
-- assert(nixio.errno() == 0)
return trim(stdout)
end
-- base64
local function base64Decode(text)
local raw = text
if not text then return '' end
text = text:gsub("%z", "")
text = text:gsub("_", "/")
text = text:gsub("-", "+")
local mod4 = #text % 4
text = text .. string.sub('====', mod4 + 1)
local result = b64decode(text)
if result then
return result:gsub("%z", "")
else
return raw
end
end
-- 处理数据
local function processData(szType, content)
local result = {
type = szType,
local_port = 1234,
kcp_param = '--nocomp'
}
if szType == 'ssr' then
local dat = split(content, "/%?")
local hostInfo = split(dat[1], ':')
result.server = hostInfo[1]
result.server_port = hostInfo[2]
result.protocol = hostInfo[3]
result.encrypt_method = hostInfo[4]
result.obfs = hostInfo[5]
result.password = base64Decode(hostInfo[6])
local params = {}
for _, v in pairs(split(dat[2], '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
end
result.obfs_param = base64Decode(params.obfsparam)
result.protocol_param = base64Decode(params.protoparam)
local group = base64Decode(params.group)
if group then
result.alias = "[" .. group .. "] "
end
result.alias = result.alias .. base64Decode(params.remarks)
elseif szType == 'vmess' then
local info = jsonParse(content)
result.type = 'v2ray'
result.server = info.add
result.server_port = info.port
result.transport = info.net
result.alter_id = info.aid
result.vmess_id = info.id
result.alias = info.ps
result.insecure = 1
-- result.mux = 1
-- result.concurrency = 8
if info.net == 'ws' then
result.ws_host = info.host
result.ws_path = info.path
end
if info.net == 'h2' then
result.h2_host = info.host
result.h2_path = info.path
end
if info.net == 'tcp' then
result.tcp_guise = info.type
result.http_host = info.host
result.http_path = info.path
end
if info.net == 'kcp' then
result.kcp_guise = info.type
result.mtu = 1350
result.tti = 50
result.uplink_capacity = 5
result.downlink_capacity = 20
result.read_buffer_size = 2
result.write_buffer_size = 2
end
if info.net == 'quic' then
result.quic_guise = info.type
result.quic_key = info.key
result.quic_security = info.securty
end
if info.security then
result.security = info.security
end
if info.tls == "tls" or info.tls == "1" then
result.tls = "1"
result.tls_host = info.host
else
result.tls = "0"
end
elseif szType == "ss" then
local idx_sp = 0
local alias = ""
if content:find("#") then
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
end
local info = content:sub(1, idx_sp - 1)
local hostInfo = split(base64Decode(info), "@")
local host = split(hostInfo[2], ":")
local userinfo = base64Decode(hostInfo[1])
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.alias = UrlDecode(alias)
result.type = "ss"
result.server = host[1]
if host[2]:find("/%?") then
local query = split(host[2], "/%?")
result.server_port = query[1]
local params = {}
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
end
if params.plugin then
local plugin_info = UrlDecode(params.plugin)
local idx_pn = plugin_info:find(";")
if idx_pn then
result.plugin = plugin_info:sub(1, idx_pn - 1)
result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
else
result.plugin = plugin_info
end
end
else
result.server_port = host[2]
end
result.encrypt_method_ss = method
result.password = password
elseif szType == "ssd" then
result.type = "ss"
result.server = content.server
result.server_port = content.port
result.password = content.password
result.encrypt_method_ss = content.encryption
result.plugin = content.plugin
result.plugin_opts = content.plugin_options
result.alias = "[" .. content.airport .. "] " .. content.remarks
elseif szType == "trojan" then
local idx_sp = 0
local alias = ""
if content:find("#") then
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
end
local info = content:sub(1, idx_sp - 1)
local hostInfo = split(info, "@")
local host = split(hostInfo[2], ":")
local userinfo = hostInfo[1]
local password = userinfo
result.alias = UrlDecode(alias)
result.type = "trojan"
result.server = host[1]
-- 按照官方的建议 默认验证ssl证书
result.insecure = "0"
result.tls = "1"
if host[2]:find("?") then
local query = split(host[2], "?")
result.server_port = query[1]
local params = {}
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
end
if params.peer then
-- 未指定peersni默认使用remote addr
result.tls_host = params.peer
end
if params.allowInsecure == "1" then
result.insecure = "1"
else
result.insecure = "0"
end
else
result.server_port = host[2]
end
result.password = password
end
if not result.alias then
result.alias = result.server .. ':' .. result.server_port
end
-- alias 不参与 hashkey 计算
local alias = result.alias
result.alias = nil
local switch_enable = result.switch_enable
result.switch_enable = nil
result.hashkey = md5(jsonStringify(result))
result.alias = alias
result.switch_enable = switch_enable
return result
end
-- wget
local function wget(url)
local stdout = luci.sys.exec('wget-ssl --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"')
return trim(stdout)
end
local execute = function()
-- exec
do
if proxy == '0' then -- 不使用代理更新的话先暂停
log('服务正在暂停')
luci.sys.init.stop(name)
end
for k, url in ipairs(subscribe_url) do
local raw = wget(url)
if #raw > 0 then
local nodes, szType
local groupHash = md5(url)
cache[groupHash] = {}
tinsert(nodeResult, {})
local index = #nodeResult
-- SSD 似乎是这种格式 ssd:// 开头的
if raw:find('ssd://') then
szType = 'ssd'
local nEnd = select(2, raw:find('ssd://'))
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
nodes = jsonParse(nodes)
local extra = {
airport = nodes.airport,
port = nodes.port,
encryption = nodes.encryption,
password = nodes.password
}
local servers = {}
-- SS里面包着 干脆直接这样
for _, server in ipairs(nodes.servers) do
tinsert(servers, setmetatable(server, { __index = extra }))
end
nodes = servers
else
-- ssd 外的格式
nodes = split(base64Decode(raw):gsub(" ", "\n"), "\n")
end
for _, v in ipairs(nodes) do
if v then
local result
if szType == 'ssd' then
result = processData(szType, v)
elseif not szType then
local node = trim(v)
local dat = split(node, "://")
if dat and dat[1] and dat[2] then
if dat[1] == 'ss' or dat[1] == 'trojan' then
result = processData(dat[1], dat[2])
else
result = processData(dat[1], base64Decode(dat[2]))
end
end
else
log('跳过未知类型: ' .. szType)
end
-- log(result)
if result then
if result.alias:find("过期时间") or
result.alias:find("剩余流量") or
result.alias:find("QQ群") or
result.alias:find("官网") or
result.alias:find("防失联地址") or
not result.server or
result.server:match("[^0-9a-zA-Z%-%.%s]") -- 中文做地址的 也没有人拿中文域名搞就算中文域也有Puny Code SB 机场
then
log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.alias)
else
log('成功解析: ' .. result.type ..' 节点, ' .. result.alias)
result.grouphashkey = groupHash
tinsert(nodeResult[index], result)
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
end
end
end
end
log('成功解析节点数量: ' ..#nodes)
else
log(url .. ': 获取内容为空')
end
end
end
-- diff
do
if next(nodeResult) == nil then
log("更新失败,没有可用的节点信息")
return
end
local add, del = 0, 0
ucic:foreach(name, uciType, function(old)
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
ucic:delete(name, old['.name'])
del = del + 1
else
local dat = nodeResult[old.grouphashkey][old.hashkey]
ucic:tset(name, old['.name'], dat)
-- 标记一下
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
end
else
if not old.alias then
old.alias = old.server .. ':' .. old.server_port
end
log('忽略手动添加的节点: ' .. old.alias)
end
end)
for k, v in ipairs(nodeResult) do
for kk, vv in ipairs(v) do
if not vv._ignore then
local section = ucic:add(name, uciType)
ucic:tset(name, section, vv)
ucic:set(name, section, "switch_enable", switch)
add = add + 1
end
end
end
ucic:commit(name)
-- 如果原有服务器节点已经不见了就尝试换为第一个节点
local globalServer = ucic:get_first(name, 'global', 'global_server', '')
local firstServer = ucic:get_first(name, uciType)
if firstServer then
if not ucic:get(name, globalServer) then
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
ucic:commit(name)
ucic:set(name, ucic:get_first(name, 'global'), 'global_server', ucic:get_first(name, uciType))
ucic:commit(name)
log('当前主服务器节点已被删除,正在自动更换为第一个节点。')
luci.sys.call("/etc/init.d/" .. name .. " start > /dev/null 2>&1 &")
else
log('维持当前主服务器节点。')
luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &")
end
else
log('没有服务器节点了,停止服务')
luci.sys.call("/etc/init.d/" .. name .. " stop > /dev/null 2>&1 &")
end
log('新增节点数量: ' ..add, '删除节点数量: ' .. del)
log("END SUBSCRIBE")
log('订阅更新成功')
end
end
if subscribe_url and #subscribe_url > 0 then
xpcall(execute, function(e)
log(e)
log(debug.traceback())
log("END SUBSCRIBE")
log('发生错误, 正在恢复服务')
local firstServer = ucic:get_first(name, uciType)
if firstServer then
luci.sys.call("/etc/init.d/" .. name .." restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
log('重启服务成功')
else
luci.sys.call("/etc/init.d/" .. name .." stop > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
log('停止服务成功')
end
end)
end

View File

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

View File

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

View File

@ -1,106 +0,0 @@
#!/bin/sh
logfile="/tmp/ssrplus.log"
dir="/usr/share/v2ray/"
v2ray_new_version=$(wget -qO- "https://github.com/v2ray/v2ray-core/tags"| grep "/v2ray/v2ray-core/releases/tag/"| head -n 1| awk -F "/tag/v" '{print $2}'| sed 's/\">//')
echo "$v2ray_new_version" > ${dir}v2ray_new_version
if [ $? -eq 0 ];then
edition=$(uci get shadowsocksr.@server_subscribe[0].edition 2>/dev/null)
if [ "$edition" = "auto_detected" ];then
v2ray_new_version=$(cat ${dir}v2ray_new_version|sed -n '1p')
else
v2ray_new_version=$edition
fi
echo "$(date "+%Y-%m-%d %H:%M:%S") v2ray自动更新启动验证版本..." >> ${logfile}
mem_mode=$(uci get shadowsocksr.@server_subscribe[0].mem_mode 2>/dev/null)
echo "$(date "+%Y-%m-%d %H:%M:%S") 检测到v2ray版本为$v2ray_new_version..." >> ${logfile}
UpdateApp() {
for a in $(opkg print-architecture | awk '{print $2}'); do
case "$a" in
all|noarch)
;;
aarch64_armv8-a|arm_arm1176jzf-s_vfp|arm_arm926ej-s|arm_cortex-a15_neon-vfpv4|arm_cortex-a5|arm_cortex-a53_neon-vfpv4|arm_cortex-a7_neon-vfpv4|arm_cortex-a8_vfpv3|arm_cortex-a9|arm_cortex-a9_neon|arm_cortex-a9_vfpv3|arm_fa526|arm_mpcore|arm_mpcore_vfp|arm_xscale|armeb_xscale)
ARCH="arm"
;;
i386_pentium|i386_pentium4)
ARCH="32"
;;
ar71xx|mips_24kc|mips_mips32|mips64_octeon)
ARCH="mips"
;;
mipsel_24kc|mipsel_24kec_dsp|mipsel_74kc|mipsel_mips32|mipsel_1004kc_dsp)
ARCH="mipsle"
;;
x86_64)
ARCH="64"
;;
*)
exit 0
;;
esac
done
}
download_binary(){
echo "$(date "+%Y-%m-%d %H:%M:%S") 开始下载v2ray二进制文件..." >> ${logfile}
rm -rf $bin_dir/v2ray*.zip
bin_dir="/tmp"
UpdateApp
cd $bin_dir
down_url=https://github.com/v2ray/v2ray-core/releases/download/v"$v2ray_new_version"/v2ray-linux-"$ARCH".zip
local a=0
while [ ! -f $bin_dir/v2ray-linux-"$ARCH"*.zip ]; do
[ $a = 6 ] && exit
/usr/bin/wget -T10 $down_url
sleep 2
let "a = a + 1"
done
if [ -f $bin_dir/v2ray-linux-"$ARCH"*.zip ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") 成功下载v2ray二进制文件" >> ${logfile}
killall -q -9 v2ray
if [ ! -d "/usr/bin/v2ray/" ]; then
mkdir -p /usr/bin/v2ray
fi
unzip -o v2ray-linux-"$ARCH"*.zip -d $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/
mem_mode=$(uci get shadowsocksr.@server_subscribe[0].mem_mode 2>/dev/null)
if [ $mem_mode -eq 1 ]; then
if [ -f /usr/bin/v2ray/v2ray ]; then
rm -rf /usr/bin/v2ray/*
rm -rf $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"
fi
chmod +x $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2*
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ray /usr/bin/v2ray/
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ctl /usr/bin/v2ray/
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geoip.dat /usr/bin/v2ray/
ln -s $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geosite.dat /usr/bin/v2ray/
else
if [ -f /usr/bin/v2ray/v2ray ]; then
rm -rf /usr/bin/v2ray/*
fi
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ray /usr/bin/v2ray/
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/v2ctl /usr/bin/v2ray/
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geoip.dat /usr/bin/v2ray/
mv $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"/geosite.dat /usr/bin/v2ray/
rm -rf $bin_dir/v2ray-v"$v2ray_new_version"-linux-"$ARCH"
fi
rm -rf $bin_dir/v2ray*.zip
if [ -f "/usr/bin/v2ray/v2ray" ]; then
chmod +x /usr/bin/v2ray/v2*
/etc/init.d/shadowsocksr restart
fi
else
echo "$(date "+%Y-%m-%d %H:%M:%S") 下载v2ray二进制文件失败请重试" >> ${logfile}
fi
}
download_binary
echo "" > ${dir}v2ray_version
echo "$v2ray_new_version" > ${dir}v2ray_version
rm -rf ${dir}v2ray_new_version
fi

View File

@ -1,704 +0,0 @@
@import url("flag-icon.min.css");
/*!
Pure v1.0.1
Copyright 2013 Yahoo!
Licensed under the BSD License.
https://github.com/pure-css/pure/blob/master/LICENSE.md
*/
.pure-g {
letter-spacing: -.31em;
text-rendering: optimizespeed;
font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-align-content: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start
}
@media all and (-ms-high-contrast:none),
(-ms-high-contrast:active) {
table .pure-g {
display: block
}
}
.opera-only :-o-prefocus,
.pure-g {
word-spacing: -.43em
}
.pure-u {
display: inline-block;
zoom: 1;
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
text-rendering: auto
}
.pure-g [class*=pure-u] {
font-family: sans-serif
}
.pure-u-1,
.pure-u-1-1,
.pure-u-1-12,
.pure-u-1-2,
.pure-u-1-24,
.pure-u-1-3,
.pure-u-1-4,
.pure-u-1-5,
.pure-u-1-6,
.pure-u-1-8,
.pure-u-10-24,
.pure-u-11-12,
.pure-u-11-24,
.pure-u-12-24,
.pure-u-13-24,
.pure-u-14-24,
.pure-u-15-24,
.pure-u-16-24,
.pure-u-17-24,
.pure-u-18-24,
.pure-u-19-24,
.pure-u-2-24,
.pure-u-2-3,
.pure-u-2-5,
.pure-u-20-24,
.pure-u-21-24,
.pure-u-22-24,
.pure-u-23-24,
.pure-u-24-24,
.pure-u-3-24,
.pure-u-3-4,
.pure-u-3-5,
.pure-u-3-8,
.pure-u-4-24,
.pure-u-4-5,
.pure-u-5-12,
.pure-u-5-24,
.pure-u-5-5,
.pure-u-5-6,
.pure-u-5-8,
.pure-u-6-24,
.pure-u-7-12,
.pure-u-7-24,
.pure-u-7-8,
.pure-u-8-24,
.pure-u-9-24 {
display: inline-block;
zoom: 1;
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
text-rendering: auto
}
.pure-u-1-24 {
width: 4.1667%
}
.pure-u-1-12,
.pure-u-2-24 {
width: 8.3333%
}
.pure-u-1-8,
.pure-u-3-24 {
width: 12.5%
}
.pure-u-1-6,
.pure-u-4-24 {
width: 16.6667%
}
.pure-u-1-5 {
width: 20%
}
.pure-u-5-24 {
width: 20.8333%
}
.pure-u-1-4,
.pure-u-6-24 {
width: 25%
}
.pure-u-7-24 {
width: 29.1667%
}
.pure-u-1-3,
.pure-u-8-24 {
width: 33.3333%
}
.pure-u-3-8,
.pure-u-9-24 {
width: 37.5%
}
.pure-u-2-5 {
width: 40%
}
.pure-u-10-24,
.pure-u-5-12 {
width: 41.6667%
}
.pure-u-11-24 {
width: 45.8333%
}
.pure-u-1-2,
.pure-u-12-24 {
width: 50%
}
.pure-u-13-24 {
width: 54.1667%
}
.pure-u-14-24,
.pure-u-7-12 {
width: 58.3333%
}
.pure-u-3-5 {
width: 60%
}
.pure-u-15-24,
.pure-u-5-8 {
width: 62.5%
}
.pure-u-16-24,
.pure-u-2-3 {
width: 66.6667%
}
.pure-u-17-24 {
width: 70.8333%
}
.pure-u-18-24,
.pure-u-3-4 {
width: 75%
}
.pure-u-19-24 {
width: 79.1667%
}
.pure-u-4-5 {
width: 80%
}
.pure-u-20-24,
.pure-u-5-6 {
width: 83.3333%
}
.pure-u-21-24,
.pure-u-7-8 {
width: 87.5%
}
.pure-u-11-12,
.pure-u-22-24 {
width: 91.6667%
}
.pure-u-23-24 {
width: 95.8333%
}
.pure-u-1,
.pure-u-1-1,
.pure-u-24-24,
.pure-u-5-5 {
width: 100%
}
.status {
margin: 1rem -0.5rem 1rem -0.5rem;
}
.block {
margin: 0.5rem 0.5rem;
padding: 0;
font-weight: normal;
font-style: normal;
line-height: 1;
font-family: inherit;
min-width: inherit;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid rgba(0, 0, 0, .05);
border-radius: .500rem;
background-color: #f4;
box-shadow: 0 0 2rem 0 rgba(136, 152, 170, .15);
}
.img-con {
margin: 1rem;
}
.pure-img{
max-height: 100%;
width: auto;
}
.green {
font-size: 1.25rem;
color: #2dce89;
}
.red {
font-size: 1.25rem;
color: #fb6340;
}
.sk-text-success {
color: #2dce89;
}
.sk-text-error {
color: #fb6340;
}
.gap {
margin-right: 0.5rem;
}
.block img {
width: 48px;
height: auto;
float: right;
}
.pure-u-5-8 {
display: flex;
align-items: center;
}
.block h4 {
font-size: .8125rem;
font-weight: 600;
margin: 1rem;
color: #8898aa !important;
line-height: 1.8em;
}
.p-in5{
padding: 8px;
}
.cbi-section-table-row {
position: relative;
background: #f4;
margin: 10px;
padding: 8px 15px 10px 70px;
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
border-radius: .5rem;
border: 0;
color: #fff;
text-align: left;
line-height: 1.7em;
white-space: nowrap;
     text-overflow: ellipsis;
overflow: hidden;
transition: all 0.3s;
}
.cbi-section-table-row:hover{
background: #fff;
}
.cbi-section-table-row.fast{
background: #5e72e4;
color: #fff;
}
.cbi-section-table-row.fast .ssr-button{
color: #fff;
}
.cbi-section-table-row.fast .ssr-button:hover,
.cbi-section-table-row.fast .ssr-button:focus,
.cbi-section-table-row.fast .ssr-button:active {
color: #fff;
outline: 0;
text-decoration: none;
box-shadow: none;
}
.host_con.fast {
color: #6f9a37;
}
.host_con.nopass {
color: #dc3545;
}
.host_con.middle {
color: #fbc658;
}
.host_con.slow {
color: #fb6340;
}
.loadings {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.7);
border-radius: .5rem;
left: 0;
top: 0;
z-index: 10;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
transition: all 0.3s;
}
.loadings.hide {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.loadings span {
animation: anim-rotate 2s infinite linear;
height: 30px;
}
.alias{
margin-bottom:1px;
}
.incon:nth-child(2) {
position: absolute;
left: 0;
top: 0;
width: 61px;
height: 100%;
border: 0;
border-right: #d1dfed 1px solid;
background-position: top;
}
.incon:nth-child(2) .tp{
position: absolute;
left: 0;
bottom: 0;
height: 25%;
width: 100%;
text-align: center;
font-size: 12px;
line-height: 15px;
color: #fff;
background: #525f7f;
}
.incon:nth-child(3) {
padding-left: 0px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.incon:nth-child(5),
.incon:nth-child(6) {
display: none;
}
.cbi-section-table-cell {
text-align: right;
}
.ssr-button {
background: none;
color: #525f7f;
padding: 0 0 0 6px;
height: auto;
line-height: 1.5em;
}
.ssr-button:hover,
.ssr-button:focus,
.ssr-button:active {
color: #525f7f;
outline: 0;
text-decoration: none;
box-shadow: none;
}
.cbi-section h3 {
margin-left: 10px;
margin-top: 1rem;
}
.cbi-button-check {
color: #fff !important;
background-color: #336633 !important;
border-color: #2e6da4 !important;
font-size:12px;
padding:0.5rem 0.8rem;
float:right;
margin-right:10px;
margin-top:0rem;
}
.cbi-section-table-cell {
position: relative;
}
.host_con {
position: absolute;
left: 0;
width: 50px;
text-align: left;
height: 22px;
font-weight: bold;
}
.host_ok {
color: #fff;
background: #2dce89;
padding: 0.1rem 0.5rem;
border-radius: 0.2rem;
}
.host_error {
color: #fff;
background: #f5365c;
padding: 0.1rem 0.5rem;
border-radius: 0.2rem;
}
footer.mobile-hide{
display: block;
}
.cbi-button-add{
position:fixed;
padding: 0.3rem 0.5rem;
z-index:1000;
width:70px !important;
height:70px;
bottom:90px;
right:55px;
font-size:20px;
border-radius:50%;
display:block;
background-color: #336633!important;
border-color: #CC6699 !important;
box-shadow: 0 0 1rem 0 rgba(136,152,170,.75);
}
.mar-10 {margin-left: 50px; margin-right: 10px;}
.status-bar{
position: fixed;
bottom: 0;
right: 0;
box-shadow: 0 0 2rem 0 rgba(136,152,170,.3);
color: #525f7f;
background: #fff;
z-index: 5;
box-sizing: border-box;
}
.status-bar .inner{
margin: 1em;
}
.status-bar .inner .flag{
height: 3em;
display: block;
float: left;
margin-right: 1em;
}
.status-bar .icon-con{
height: 3em;
text-align: right;
}
@media screen and (max-width: 1900px) {
.pure-u-1-5 {
width: 25%;
}
}
@media screen and (max-width: 1600px) {
.pure-u-1-5 {
width: 33.33333333%;
}
}
@media screen and (max-width: 1200px) {
.pure-u-1-5 {
width: 50%;
}
.status .pure-u-1-5 {
width: 33.333%;
}
}
@media screen and (max-width: 700px) {
.pure-u-1-4 {
width: 50%;
}
.pure-u-1-2 {
width: 100%;
}
.pure-u-1-5 {
width: 100%;
font-size: 14px;
}
.status .pure-u-1-5 {
width: 50%;
}
.cbi-button-add {
position: fixed;
padding: 0.3rem 0.5rem;
z-index: 1000;
width: 50px !important;
height: 50px;
bottom: 90px;
right: 5px;
font-size: 16px;
border-radius: 50%;
display: block;
background-color: #fb6340!important;
border-color: #fb6340 !important;
box-shadow: 0 0 1rem 0 rgba(136, 152, 170, .75);
}
}
.modals-bg {
position: fixed;
z-index: 999;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(255, 255, 255, 0.8);
display: none;
}
.modals {
position: fixed;
z-index: 100;
width: 60%;
height: 500px;
background: #172b4d;
left: 20%;
top: 15%;
color: #fff;
border-radius: 10px;
padding: 20px;
box-sizing: border-box;
-moz-box-sizing: border-box;
/* Firefox */
-webkit-box-sizing: border-box;
/* Safari */
}
.modals h2 {
padding: 0 !important;
}
.modals h3 {
font-size: 14px;
color: #f5365c !important;
background: transparent;
margin: 0;
padding: 0;
}
#log_content3 {
border: 0;
width: 99%;
height: calc(100% - 4rem);
font-family: 'Lucida Console';
font-size: 11px;
background: transparent;
color: #FFFFFF;
outline: none;
padding-left: 3px;
padding-right: 22px;
overflow: hidden
}
@media screen and (max-width: 1024px) {
.modals {
position: fixed;
z-index: 100;
width: 80%;
height: 500px;
background: #172b4d;
left: 10%;
top: 15%;
color: #fff;
border-radius: 10px;
padding: 20px;
}
}
@media screen and (max-width: 700px) {
.modals-bg {
position: fixed;
z-index: 100000;
}
.modals {
width: 100%;
height: 100%;
left: 0;
top: 0;
}
.status-bar .pure-u-1-2{
width: 50%;
}
.status-bar .inner .flag{
height: 3em;
display: block;
float: left;
margin-right: 1em;
}
.status-bar .icon-con{
height: 2.5em;
text-align: right;
}
}

View File

@ -1,39 +1,16 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-vssr
PKG_VERSION:=1.32
PKG_RELEASE:=4-20200331
PKG_VERSION:=1.11
PKG_RELEASE:=20200719
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun \
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_microsocks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_haproxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_privoxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server\
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)/config
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks
bool "Include Shadowsocks New Version"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
bool "Include V2ray"
@ -42,86 +19,14 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan
bool "Include Trojan"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun
bool "Include Kcptun"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server
bool "Include ShadowsocksR Server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server
bool "Include Shadowsocks Server"
default y
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks
bool "Include ShadowsocksR Socks and Tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks
bool "Include Shadowsocks Socks and Tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks
bool "Include ipt2socks"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_microsocks
bool "Include microsocks"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks
bool "Include dns2socks"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy
bool "Include dnscrypt-proxy-full"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder
bool "Include dnsforwarder"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS
bool "Include chinadns"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_haproxy
bool "Include haproxy"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_privoxy
bool "Include privoxy http local"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs
bool "Include simple-obfsl"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server
bool "Include simple-obfs-server"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder
bool "Include udpspeeder"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel
bool "Include udp2raw-tunnel"
default y
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client
bool "Include GoQuiet-client"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server
bool "Include GoQuiet-server"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin
bool "Include v2ray-plugin"
default y
endef
define Package/luci-app-vssr
@ -130,30 +35,12 @@ define Package/luci-app-vssr
SUBMENU:=3. Applications
TITLE:=A New SS/SSR/V2Ray/Trojan LuCI interface
PKGARCH:=all
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget +tcpping +lua-maxminddb +lua +luasocket +jshn +lua-cjson +coreutils-nohup +curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget +luasocket +jshn +lua-cjson +coreutils-nohup +lua-maxminddb \
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:kcptun-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Server:shadowsocks-libev-ss-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Socks:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ipt2socks:ipt2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_microsocks:microsocks \
+PACKAGE_$(PKG_NAME)_INCLUDE_dns2socks:dns2socks \
+PACKAGE_$(PKG_NAME)_INCLUDE_dnscrypt_proxy:dnscrypt-proxy-full \
+PACKAGE_$(PKG_NAME)_INCLUDE_dnsforwarder:dnsforwarder \
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS:openwrt_chinadns \
+PACKAGE_$(PKG_NAME)_INCLUDE_haproxy:haproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_privoxy:privoxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_udpspeeder:speederv2-tunnel \
+PACKAGE_$(PKG_NAME)_INCLUDE_udp2raw-tunnel:udp2raw-tunnel \
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs:simple-obfs \
+PACKAGE_$(PKG_NAME)_INCLUDE_simple-obfs-server:simple-obfs-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-client:gq-client \
+PACKAGE_$(PKG_NAME)_INCLUDE_GoQuiet-server:gq-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_v2ray-plugin:v2ray-plugin
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local
endef
define Build/Prepare
@ -163,8 +50,12 @@ define Build/Compile
endef
define Package/luci-app-vssr/conffiles
/etc/ssr_ip
/etc/dnsmasq.vssr/gfw_list.conf
/etc/ssr_ip
/etc/dnsmasq.ssr/gfw_list.conf
/etc/china_ssr.txt
/etc/dnsmasq.ssr/gfw_list.conf
/etc/dnsmasq.ssr/gfw_base.conf
/etc/dnsmasq.oversea/oversea_list.conf
endef
define Package/luci-app-vssr/install
@ -180,7 +71,8 @@ define Package/luci-app-vssr/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
( . /etc/uci-defaults/luci-vssr ) && rm -f /etc/uci-defaults/luci-vssr
rm -f /tmp/luci-indexcache
rm -rf /tmp/luci-indexcache
rm -rf /tmp/luci-modulecache/*
chmod 755 /etc/init.d/vssr >/dev/null 2>&1
/etc/init.d/vssr enable >/dev/null 2>&1
fi
@ -197,5 +89,3 @@ exit 0
endef
$(eval $(call BuildPackage,luci-app-vssr))

View File

@ -3,375 +3,292 @@
module("luci.controller.vssr", package.seeall)
function index()
if not nixio.fs.access("/etc/config/vssr") then
return
end
if not nixio.fs.access("/etc/config/vssr") then return end
if nixio.fs.access("/usr/bin/ssr-redir") then
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
entry({"admin", "vpn", "vssr"},alias("admin", "vpn", "vssr", "client"), _("Hello World"), 10).dependent=true
entry({"admin", "vpn", "vssr", "client"}, cbi("vssr/client"), _("SSR Client"), 10).leaf=true
entry({"admin", "vpn", "vssr", "servers"}, cbi("vssr/servers"), _("Node List"), 20).leaf=true
entry({"admin", "vpn", "vssr", "servers"}, arcombine(cbi("vssr/servers"), cbi("vssr/client-config")), _("Node List"), 20).leaf =true
entry({"admin", "vpn", "vssr", "subscription"},cbi("vssr/subscription"),_("Subscription"),30).leaf=true
entry({"admin", "vpn", "vssr", "control"}, cbi("vssr/control"), _("Access Control"), 40).leaf=true
entry({"admin", "vpn", "vssr", "servers-list"}, arcombine(cbi("vssr/servers-list"), cbi("vssr/client-config")), _("Severs Nodes"), 50).leaf =true
entry({"admin", "vpn", "vssr", "appointlist"},form("vssr/appointlist"),_("Appointlist List"),60).leaf =true
entry({"admin", "vpn", "vssr", "udp2raw"},cbi("vssr/udp2raw"),_("udp2raw tunnel"),70).leaf = true
entry({"admin", "vpn", "vssr", "advanced"}, cbi("vssr/advanced"),_("Advanced Settings"), 80).leaf =true
elseif nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "vpn", "vssr"}, alias("admin", "vpn", "vssr", "server"), _("vssr"), 10).dependent =true
else
return
end
if nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "vpn", "vssr", "server"},arcombine(cbi("vssr/server"), cbi("vssr/server-config")), _("SSR Server"), 85).leaf = true
end
entry({"admin", "vpn", "vssr", "status"},form("vssr/status"),_("Status"), 90).leaf = true
entry({"admin", "vpn", "vssr", "logview"}, cbi("vssr/logview", {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), _("Log") ,100).leaf=true
entry({"admin", "vpn", "vssr", "refresh"}, call("refresh_data"))
entry({"admin", "vpn", "vssr", "checkport"}, call("check_port"))
entry({"admin", "vpn", "vssr", "checkports"}, call("check_ports"))
entry({"admin", "vpn", "vssr", "ping"}, call("act_ping")).leaf=true
entry({"admin", "vpn", "vssr", "fileread"}, call("act_read"), nil).leaf=true
entry({"admin", "vpn", "vssr", "switch"}, call("switch"))
entry({"admin", "vpn", "vssr", "run"}, call("act_status"))
entry({"admin", "vpn", "vssr", "change"}, call("change_node"))
entry({"admin", "vpn", "vssr", "allserver"}, call("get_servers"))
entry({"admin", "vpn", "vssr", "subscribe"}, call("get_subscribe"))
entry({"admin", "vpn", "vssr", "flag"}, call("get_flag"))
entry({"admin", "vpn", "vssr", "ip"}, call("check_ip"))
entry({"admin", "services", "vssr"},
alias("admin", "services", "vssr", "client"), _("Hello World"), 10).dependent =
true -- 首页
entry({"admin", "services", "vssr", "client"}, cbi("vssr/client"),
_("SSR Client"), 10).leaf = true -- 基本设置
entry({"admin", "services", "vssr", "servers"}, cbi("vssr/servers"),
_("Severs Nodes"), 11).leaf = true -- 服务器节点
entry({"admin", "services", "vssr", "servers"},
arcombine(cbi("vssr/servers"), cbi("vssr/client-config")),
_("Severs Nodes"), 11).leaf = true -- 编辑节点
entry({"admin", "services", "vssr", "control"}, cbi("vssr/control"),
_("Access Control"), 12).leaf = true -- 访问控制
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
entry({"admin", "services", "vssr", "socks5"}, cbi("vssr/socks5"),
_("Socks5"), 13).leaf = true -- Socks5代理
end
entry({"admin", "services", "vssr", "advanced"}, cbi("vssr/advanced"),
_("Advanced Settings"), 14).leaf = true -- 高级设置
elseif nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "services", "vssr"},
alias("admin", "services", "vssr", "server"), _("vssr"), 10).dependent =
true
else
return
end
if nixio.fs.access("/usr/bin/ssr-server") then
entry({"admin", "services", "vssr", "server"},
arcombine(cbi("vssr/server"), cbi("vssr/server-config")),
_("SSR Server"), 20).leaf = true
end
entry({"admin", "services", "vssr", "log"}, cbi("vssr/log"), _("Log"), 30).leaf =
true
entry({"admin", "services", "vssr", "licence"}, template("vssr/licence"),
_("Licence"), 40).leaf = true
entry({"admin", "services", "vssr", "refresh"}, call("refresh_data")) -- 更新白名单和GFWLIST
entry({"admin", "services", "vssr", "checkport"}, call("check_port")) -- 检测单个端口并返回Ping
entry({"admin", "services", "vssr", "run"}, call("act_status")) -- 检测全局服务器状态
entry({"admin", "services", "vssr", "change"}, call("change_node")) -- 切换节点
entry({"admin", "services", "vssr", "allserver"}, call("get_servers")) -- 获取所有节点Json
entry({"admin", "services", "vssr", "subscribe"}, call("get_subscribe")) -- 执行订阅
entry({"admin", "services", "vssr", "flag"}, call("get_flag")) -- 获取节点国旗 iso code
entry({"admin", "services", "vssr", "ip"}, call("check_ip")) -- 获取ip情况
entry({"admin", "services", "vssr", "switch"}, call("switch")) -- 设置节点为自动切换
end
-- 执行订阅
function get_subscribe()
local cjson = require "cjson"
local e = {}
local uci = luci.model.uci.cursor()
local auto_update = luci.http.formvalue("auto_update")
local auto_update_time = luci.http.formvalue("auto_update_time")
local proxy = luci.http.formvalue("proxy")
local subscribe_url = luci.http.formvalue("subscribe_url")
if subscribe_url ~= "[]" then
local cmd1 = 'uci set vssr.@server_subscribe[0].auto_update="' ..
local cjson = require "cjson"
local e = {}
local uci = luci.model.uci.cursor()
local auto_update = luci.http.formvalue("auto_update")
local auto_update_time = luci.http.formvalue("auto_update_time")
local proxy = luci.http.formvalue("proxy")
local subscribe_url = luci.http.formvalue("subscribe_url")
if subscribe_url ~= "[]" then
local cmd1 = 'uci set vssr.@server_subscribe[0].auto_update="' ..
auto_update .. '"'
local cmd2 = 'uci set vssr.@server_subscribe[0].auto_update_time="' ..
local cmd2 = 'uci set vssr.@server_subscribe[0].auto_update_time="' ..
auto_update_time .. '"'
local cmd3 = 'uci set vssr.@server_subscribe[0].proxy="' .. proxy .. '"'
luci.sys.call('uci delete vssr.@server_subscribe[0].subscribe_url ')
luci.sys.call(cmd1)
luci.sys.call(cmd2)
luci.sys.call(cmd3)
for k, v in ipairs(cjson.decode(subscribe_url)) do
luci.sys.call(
'uci add_list vssr.@server_subscribe[0].subscribe_url="' .. v .. '"')
end
luci.sys.call('uci commit vssr')
luci.sys.call(
local cmd3 = 'uci set vssr.@server_subscribe[0].proxy="' .. proxy .. '"'
luci.sys.call('uci delete vssr.@server_subscribe[0].subscribe_url ')
luci.sys.call(cmd1)
luci.sys.call(cmd2)
luci.sys.call(cmd3)
for k, v in ipairs(cjson.decode(subscribe_url)) do
luci.sys.call(
'uci add_list vssr.@server_subscribe[0].subscribe_url="' .. v ..
'"')
end
luci.sys.call('uci commit vssr')
luci.sys.call(
"nohup /usr/bin/lua /usr/share/vssr/subscribe.lua >/www/check_update.htm 2>/dev/null &")
e.error = 0
else
e.error = 1
e.error = 0
else
e.error = 1
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
end
-- 获取所有节点
function get_servers()
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach("vssr", "servers", function(s)
local e = {}
e["name"] = s[".name"]
local t1 = luci.sys.exec(
local uci = luci.model.uci.cursor()
local server_table = {}
uci:foreach("vssr", "servers", function(s)
local e = {}
e["name"] = s[".name"]
local t1 = luci.sys.exec(
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" %
s["server"])
e["t1"] = t1
table.insert(server_table, e)
e["t1"] = t1
table.insert(server_table, e)
end)
luci.http.prepare_content("application/json")
luci.http.write_json(server_table)
luci.http.prepare_content("application/json")
luci.http.write_json(server_table)
end
-- 切换节点
function change_node()
local e = {}
local uci = luci.model.uci.cursor()
local sid = luci.http.formvalue("set")
local name = ""
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
e.status = false
e.sid = sid
if sid ~= "" then
uci:set("vssr", name, "global_server", sid)
uci:commit("vssr")
luci.sys.call("/etc/init.d/vssr restart")
e.status = true
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function switch()
local e = {}
local uci = luci.model.uci.cursor()
local sid = luci.http.formvalue("node")
local isSwitch = uci:get("vssr", sid, "switch_enable")
if isSwitch == "1" then
uci:set("vssr", sid, "switch_enable","0")
e.switch = false
else
uci:set("vssr", sid, "switch_enable","1")
e.switch = true
end
uci:commit("vssr")
e.status = true
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-- 检测全局服务器状态
function act_status()
math.randomseed(os.time())
local e = {}
-- 全局服务器
e.global=luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0
-- 检测Socks5
if tonumber(luci.sys.exec("ps -w | grep ssr-local |grep -v grep| wc -l"))>0 then
e.socks5 = true
elseif tonumber(luci.sys.exec("ps -w | grep ss-local |grep -v grep| wc -l"))>0 then
e.socks5 = true
elseif tonumber(luci.sys.exec("ps -w | grep v2-ssr-local |grep -v grep| wc -l"))>0 then
end
--检测chinadns状态
if tonumber(luci.sys.exec("ps -w | grep chinadns |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnsparsing |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnscrypt-proxy |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep pdnsd |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dns2socks |grep -v grep| wc -l"))>0 then
e.chinadns= true
elseif tonumber(luci.sys.exec("ps -w | grep dnsforwarder |grep -v grep| wc -l"))>0 then
e.chinadns= true
end
--检测服务端状态
if tonumber(luci.sys.exec("ps -w | grep ssr-server |grep -v grep| wc -l"))>0 then
e.server= true
end
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
e.ssr_server= true
end
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
e.ss_server= true
end
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
e.v2_server= true
end
-- 检测国内通道
e.baidu = false
sret = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
if sret == 0 then
e.baidu = true
end
-- 检测国外通道
e.google = false
sret = luci.sys.call("/usr/bin/ssr-check www.google.com 80 3 1")
if sret == 0 then
e.google = true
end
-- 检测游戏模式状态
e.game = false
if tonumber(luci.sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l"))>0 then
e.game= true
else
if tonumber(luci.sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l"))>0 then
e.game= true
end
local e = {}
local uci = luci.model.uci.cursor()
local sid = luci.http.formvalue("set")
local name = ""
uci:foreach("vssr", "global", function(s) name = s[".name"] end)
e.status = false
e.sid = sid
if sid ~= "" then
uci:set("vssr", name, "global_server", sid)
uci:commit("vssr")
luci.sys.call("/etc/init.d/vssr restart")
e.status = true
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function act_ping()
local e = {}
local domain = luci.http.formvalue("domain")
local port = luci.http.formvalue("port")
e.index = luci.http.formvalue("index")
local iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
local socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
e.socket = socket:connect(domain, port)
socket:close()
e.ping = luci.sys.exec("ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" % domain)
if (e.ping == "") then
e.ping = luci.sys.exec(string.format("echo -n $(tcpping -c 1 -i 1 -p %s %s 2>&1 | grep -o 'ttl=[0-9]* time=[0-9]*.[0-9]' | awk -F '=' '{print$3}') 2>/dev/null",port, domain))
end
if (iret == 0) then
luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
end
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function check_status()
local set ="/usr/bin/ssr-check www." .. luci.http.formvalue("set") .. ".com 80 3 1"
sret=luci.sys.call(set)
if sret== 0 then
retstring ="0"
else
retstring ="1"
end
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring })
--设置节点为自动切换
function switch()
local e = {}
local uci = luci.model.uci.cursor()
local sid = luci.http.formvalue("node")
local isSwitch = uci:get("vssr", sid, "switch_enable")
if isSwitch == "1" then
uci:set("vssr", sid, "switch_enable","0")
e.switch = false
else
uci:set("vssr", sid, "switch_enable","1")
e.switch = true
end
uci:commit("vssr")
e.status = true
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-- 检测全局服务器状态
function act_status()
math.randomseed(os.time())
local e = {}
-- 全局服务器
e.global = luci.sys.call(
"busybox ps -w | grep vssr_t | grep -v grep >/dev/null") == 0
-- 检测PDNSD状态
e.pdnsd = luci.sys.call("pidof pdnsd >/dev/null") == 0
-- 检测游戏模式状态
e.game = luci.sys.call(
"busybox ps -w | grep vssr_u | grep -v grep >/dev/null") == 0
-- 检测Socks5
e.socks5 = luci.sys.call(
"busybox ps -w | grep vssr_s | grep -v grep >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
-- 刷新检测文件
function refresh_data()
local set =luci.http.formvalue("set")
local icount =0
local set = luci.http.formvalue("set")
local icount = 0
if set == "gfw_data" then
refresh_cmd="wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64"
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret== 0 then
luci.sys.call("/usr/bin/vssr-gfw")
icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
if tonumber(icount)>1000 then
oldcount=luci.sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/gfwnew.txt /etc/dnsmasq.vssr/gfw_list.conf")
luci.sys.exec("cp -f /tmp/gfwnew.txt /tmp/dnsmasq.vssr/gfw_list.conf")
luci.sys.call("/etc/init.d/dnsmasq restart")
retstring=tostring(math.ceil(tonumber(icount)/2))
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
else
retstring ="-1"
end
elseif set == "ip_data" then
if (luci.model.uci.cursor():get_first('vssr', 'global', 'chnroute', '0') == '1') then
refresh_cmd="wget-ssl --no-check-certificate -O - " .. luci.model.uci.cursor():get_first('vssr', 'global', 'chnroute_url', 'https://ispip.clang.cn/all_cn.txt') .. ' > /tmp/china_ssr.txt 2>/dev/null'
else
refresh_cmd="wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' 2>/dev/null| awk -F\\| '/CN\\|ipv4/ { printf(\"%s/%d\\n\", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt"
end
sret=luci.sys.call(refresh_cmd)
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if sret== 0 and tonumber(icount)>1000 then
oldcount=luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
retstring=tostring(tonumber(icount))
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
else
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd="wget-ssl --no-check-certificate -O - ".. luci.model.uci.cursor():get_first('vssr', 'global', 'adblock_url','https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt') .." > /tmp/adnew.conf"
end
sret=luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret== 0 then
luci.sys.call("/usr/bin/vssr-ad")
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount)>1000 then
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
oldcount=luci.sys.exec("cat /etc/dnsmasq.vssr/ad.conf | wc -l")
else
oldcount=0
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.vssr/ad.conf")
luci.sys.exec("cp -f /tmp/ad.conf /tmp/dnsmasq.vssr/ad.conf")
luci.sys.call("/etc/init.d/dnsmasq restart")
retstring=tostring(math.ceil(tonumber(icount)))
else
retstring ="0"
end
else
retstring ="-1"
end
luci.sys.exec("rm -f /tmp/ad.conf")
else
retstring ="-1"
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({ ret=retstring ,retcount=icount})
end
-- 检测所有服务器
function check_ports()
local set = ""
local retstring = "<br /><br />"
local s
local server_name = ""
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local iret = 1
uci:foreach(
vssr,
"servers",
function(s)
if s.alias then
server_name = s.alias
elseif s.server and s.server_port then
server_name = "%s:%s" % {s.server, s.server_port}
end
iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 3)
socket:setopt("socket", "sndtimeo", 3)
ret = socket:connect(s.server, s.server_port)
if tostring(ret) == "true" then
socket:close()
retstring = retstring .. "<font color='green'>[" .. server_name .. "] OK.</font><br />"
else
retstring = retstring .. "<font color='red'>[" .. server_name .. "] Error.</font><br />"
end
if iret == 0 then
luci.sys.call(" ipset del ss_spec_wan_ac " .. s.server)
end
if set == "gfw_data" then
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd =
"wget-ssl --no-check-certificate https://cdn.jsdelivr.net/gh/gfwlist/gfwlist/gfwlist.txt -O /tmp/gfw.b64"
else
refresh_cmd = "wget -O /tmp/gfw.b64 http://iytc.net/tools/list.b64"
end
)
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
luci.sys.call("/usr/bin/vssr-gfw")
icount = luci.sys.exec("cat /tmp/gfwnew.txt | wc -l")
if tonumber(icount) > 1000 then
oldcount = luci.sys.exec(
"cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec(
"cp -f /tmp/gfwnew.txt /etc/dnsmasq.ssr/gfw_list.conf")
retstring = tostring(math.ceil(tonumber(icount) / 2))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/gfwnew.txt ")
else
retstring = "-1"
end
elseif set == "ip_data" then
refresh_cmd =
"wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' 2>/dev/null| awk -F\\| '/CN\\|ipv4/ { printf(\"%s/%d\\n\", $4, 32-log($5)/log(2)) }' > /tmp/china_ssr.txt"
sret = luci.sys.call(refresh_cmd)
icount = luci.sys.exec("cat /tmp/china_ssr.txt | wc -l")
if sret == 0 and tonumber(icount) > 1000 then
oldcount = luci.sys.exec("cat /etc/china_ssr.txt | wc -l")
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/china_ssr.txt /etc/china_ssr.txt")
retstring = tostring(tonumber(icount))
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/china_ssr.txt ")
else
local need_process = 0
if nixio.fs.access("/usr/bin/wget-ssl") then
refresh_cmd =
"wget-ssl --no-check-certificate -O - https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt > /tmp/adnew.conf"
need_process = 1
else
refresh_cmd = "wget -O /tmp/ad.conf http://iytc.net/tools/ad.conf"
end
sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
if sret == 0 then
if need_process == 1 then
luci.sys.call("/usr/bin/vssr-ad")
end
icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
if tonumber(icount) > 1000 then
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
oldcount = luci.sys.exec(
"cat /etc/dnsmasq.ssr/ad.conf | wc -l")
else
oldcount = 0
end
if tonumber(icount) ~= tonumber(oldcount) then
luci.sys.exec("cp -f /tmp/ad.conf /etc/dnsmasq.ssr/ad.conf")
retstring = tostring(math.ceil(tonumber(icount)))
if oldcount == 0 then
luci.sys.call("/etc/init.d/dnsmasq restart")
end
else
retstring = "0"
end
else
retstring = "-1"
end
luci.sys.exec("rm -f /tmp/ad.conf")
else
retstring = "-1"
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({ret = retstring})
luci.http.write_json({ret = retstring, retcount = icount})
end
-- 检测单个节点状态并返回连接速度
function check_port()
local e = {}
-- e.index=luci.http.formvalue("host")
local t1 = luci.sys.exec(
"ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*.[0-9]' | awk -F '=' '{print$2}'" %
luci.http.formvalue("host"))
local sockets = require "socket"
local set = luci.http.formvalue("host")
local port = luci.http.formvalue("port")
local retstring = ""
local iret = 1
iret = luci.sys.call(" ipset add ss_spec_wan_ac " .. set .. " 2>/dev/null")
socket = nixio.socket("inet", "stream")
socket:setopt("socket", "rcvtimeo", 2)
socket:setopt("socket", "sndtimeo", 2)
local t0 = sockets.gettime()
ret = socket:connect(set, port)
socket:close()
local t1 = sockets.gettime()
if tostring(ret) == "true" then
retstring = "1"
else
retstring = "0"
end
if iret == 0 then
luci.sys.call(" ipset del ss_spec_wan_ac " .. set)
end
local tt = t1 - t0
luci.http.prepare_content("application/json")
luci.http.write_json({ret = 1, used = t1})
luci.http.write_json({ret = retstring , used = math.floor(tt*1000 + 0.5)})
end
@ -418,18 +335,19 @@ end
-- 检测 当前节点ip 和 网站访问情况
function check_ip()
-- 获取当前的ip和国家
-- 获取当前的ip和国家
local e = {}
local d = {}
local mm = require 'maxminddb'
local db = mm.open('/usr/share/vssr/GeoLite2-Country.mmdb')
local ip = string.gsub(luci.sys.exec("curl -s https://api.ip.sb/ip"), "\n", "")
local ip = string.gsub(luci.sys.exec("content=`wget --no-check-certificate -q -O - https://api.ip.sb/ip`;echo $content"), "\n", "")
local res = db:lookup(ip)
d.flag = string.lower(res:get("country", "iso_code"))
d.country = res:get("country", "names", "zh-CN")
e.outboard = ip
e.outboardip = d
-- 检测国内通道
e.baidu = false
sret1 = luci.sys.call("/usr/bin/ssr-check www.baidu.com 80 3 1")
@ -463,16 +381,3 @@ function get_flag()
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function act_read(lfile)
local NXFS = require "nixio.fs"
local HTTP = require "luci.http"
local lfile = HTTP.formvalue("lfile")
local ldata={}
ldata[#ldata+1] = NXFS.readfile(lfile) or "_nofile_"
if ldata[1] == "" then
ldata[1] = "_nodata_"
end
HTTP.prepare_content("application/json")
HTTP.write_json(ldata)
end

View File

@ -1,25 +1,52 @@
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local server_table = {}
local gfwmode = 0
local gfw_count = 0
local ip_count = 0
local ad_count = 0
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then gfwmode = 1 end
local sys = require "luci.sys"
if gfwmode == 1 then
gfw_count =
tonumber(sys.exec("cat /etc/dnsmasq.ssr/gfw_list.conf | wc -l")) / 2
if nixio.fs.access("/etc/dnsmasq.ssr/ad.conf") then
ad_count = tonumber(sys.exec("cat /etc/dnsmasq.ssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
uci:foreach(vssr, "servers", function(s)
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
if s["type"] == "v2ray" then
if s.alias then
server_table[s[".name"]] = "[%s]:%s" %
{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %
{
string.upper(s.type), s.server, s.server_port
}
end
end
end)
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
local key_table = {}
for key, _ in pairs(server_table) do table.insert(key_table, key) end
table.sort(key_table)
m = Map(vssr)
-- [[ 服务器节点故障自动切换设置 ]]--
s = m:section(TypedSection, "global", translate("Server failsafe auto swith settings"))
s = m:section(TypedSection, "global",
translate("Server failsafe auto swith settings"))
s.anonymous = true
o = s:option(Flag, "monitor_enable", translate("Enable Process Deamon"))
@ -28,16 +55,6 @@ o.rmempty = false
o = s:option(Flag, "enable_switch", translate("Enable Auto Switch"))
o.rmempty = false
-- [[ adblock ]]--
o = s:option(Flag, "adblock", translate("Enable adblock"))
o.rmempty = false
o = s:option(Value, "adblock_url", translate("adblock_url"))
o:value("https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf", translate("anti-AD"))
o.default = "https://gitee.com/privacy-protection-tools/anti-ad/raw/master/anti-ad-for-dnsmasq.conf"
o:depends("adblock", "1")
o.description = translate("Support AdGuardHome and DNSMASQ format list")
o = s:option(Value, "switch_time", translate("Switch check cycly(second)"))
o.datatype = "uinteger"
o:depends("enable_switch", "1")
@ -53,64 +70,71 @@ o.datatype = "uinteger"
o:depends("enable_switch", "1")
o.default = 3
-- [[ SOCKS5 Proxy ]]--
if nixio.fs.access("/usr/bin/ssr-local") then
s = m:section(TypedSection, "socks5_proxy", translate("SOCKS5 Proxy"))
-- [[ 节点订阅 ]]--
s = m:section(TypedSection, "server_subscribe",
translate("Servers subscription and manage"))
s.anonymous = true
o = s:option(ListValue, "server", translate("Server"))
o:value("nil", translate("Disable"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false
o.description = translate(
"Auto Update Server subscription, GFW list and CHN route")
o =
s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0, 23 do o:value(t, t .. ":00") end
o.default = 2
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.default = 1080
o.rmempty = false
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true
-- [[ HTTP Proxy ]]--
if nixio.fs.access("/usr/sbin/privoxy") then
o = s:option(Flag, "http_enable", translate("Enable HTTP Proxy"))
o = s:option(Flag, "proxy", translate("Through proxy update"))
o.rmempty = false
o.description = translate("Through proxy update list, Not Recommended ")
o = s:option(Value, "http_port", translate("HTTP Port"))
o.datatype = "port"
o.default = 1081
o.rmempty = false
o = s:option(DummyValue, "", "")
o.rawhtml = true
o.template = "vssr/update_subscribe"
o = s:option(Button, "delete", translate("Delete all severs"))
o.inputstyle = "reset"
o.write = function()
uci:delete_all("vssr", "servers", function(s) return true end)
uci:commit("vssr")
luci.sys.call("/etc/init.d/vssr stop")
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "vssr",
"advanced"))
end
-- [[ chnroute ]]
s = m:section(TypedSection, "global", translate("Chnroute Setting"))
-- [[ adblock ]]--
s = m:section(TypedSection, "global", translate("adblock settings"))
s.anonymous = true
o = s:option(Flag, "chnroute", translate("Enable custom chnroute"))
o = s:option(Flag, "adblock", translate("Enable adblock"))
o.rmempty = false
o = s:option(Value, "chnroute_url", translate("Update url"))
o.default = "https://ispip.clang.cn/all_cn.txt"
-- [[ 更新设置 ]]--
-- [[ haProxy ]]--
s = m:section(TypedSection, "global_haproxy", translate("haProxy settings"))
s = m:section(TypedSection, "socks5_proxy", translate("Update Setting"))
s.anonymous = true
o = s:option(Flag, "admin_enable", translate("Enabling the Management Console"))
o.rmempty = false
o.default = 1
o = s:option(Button, "gfw_data", translate("GFW List Data"))
o.rawhtml = true
o.template = "vssr/refresh"
o.value = tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
o = s:option(Value, "admin_port", translate("Service Port"))
o.datatype = "uinteger"
o.default = 1111
o = s:option(Value, "admin_user", translate("User name"))
o.default = "admin"
o = s:option(Value, "admin_password", translate("Password"))
o.default = "root"
o = s:option(Button, "ip_data", translate("China IP Data"))
o.rawhtml = true
o.template = "vssr/refresh"
o.value = ip_count .. " " .. translate("Records")
if uci:get_first('vssr', 'global', 'adblock', '') == '1' then
o = s:option(Button, "ad_data", translate("Advertising Data"))
o.rawhtml = true
o.template = "vssr/refresh"
o.value = ad_count .. " " .. translate("Records")
end
return m

View File

@ -1,23 +0,0 @@
local fs = require "nixio.fs"
local conffile = "/etc/dnsmasq.vssr/appoint_list.conf"
f = SimpleForm("custom", translate("Appoint dns List"))
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 13
function t.cfgvalue()
return fs.readfile(conffile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.conf then
fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
luci.sys.call("/etc/init.d/dnsmasq restart")
end
end
return true
end
return f

View File

@ -41,14 +41,14 @@ local protocol = {
"auth_chain_d", "auth_chain_e", "auth_chain_f"
}
local obfs = {
obfs = {
"plain", "http_simple", "http_post", "random_head", "tls1.2_ticket_auth"
}
local securitys = {"auto", "none", "aes-128-gcm", "chacha20-poly1305"}
m = Map(vssr, translate("Edit vssr Server"))
m.redirect = luci.dispatcher.build_url("admin/vpn/vssr/servers")
m.redirect = luci.dispatcher.build_url("admin/services/vssr/servers")
if m.uci:get(vssr, sid) ~= "servers" then
luci.http.redirect(m.redirect)
return
@ -65,29 +65,24 @@ o.template = "vssr/ssrurl"
o.value = sid
o = s:option(ListValue, "type", translate("Server Node Type"))
if nixio.fs.access("/usr/sbin/trojan") then
o:value("trojan", translate("Trojan"))
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
o:value("v2ray", translate("V2Ray"))
end
o:value("ssr", translate("ShadowsocksR"))
if nixio.fs.access("/usr/bin/ss-redir") then
o:value("ss", translate("Shadowsocks"))
if nixio.fs.access("/usr/bin/v2ray/v2ray") or nixio.fs.access("/usr/bin/v2ray") then
o:value("ss", translate("Shadowsocks New Version"))
o:value("v2ray", translate("V2Ray"))
end
if nixio.fs.access("/usr/bin/ipt2socks") then
o:value("socks5", translate("Socks5"))
if nixio.fs.access("/usr/sbin/trojan") then
o:value("trojan", translate("Trojan"))
end
o.description = translate(
"Using incorrect encryption mothod may causes service fail to start")
o = s:option(Value, "alias", translate("Alias(optional)"))
o = s:option(Value, "flag", translate("Country"))
o.description = translate(
"请自己指定。格式cn us hk 等")
o = s:option(Value, "flag", translate("Area"))
o.description = translate("请自己指定。格式cn us hk 等")
o.rmempty = true
o = s:option(Value, "server", translate("Server Address"))
@ -103,24 +98,17 @@ o.rmempty = false
-- o.default = 60
-- o.rmempty = false
o = s:option(Flag, "auth_enable", translate("Enable Authentication"))
o.rmempty = false
o.default = "0"
o:depends("type", "socks5")
o = s:option(Value, "username", translate("Username"))
o.rmempty = true
o:depends("type", "socks5")
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o:depends("type", "trojan")
o:depends("type", "socks5")
o = s:option(Value, "peer", translate("Peer"))
o.datatype = "host"
o.rmempty = true
o:depends("type", "trojan")
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods) do o:value(v) end
@ -132,29 +120,6 @@ for _, v in ipairs(encrypt_methods_ss) do o:value(v) end
o.rmempty = true
o:depends("type", "ss")
-- Shadowsocks Plugin
o = s:option(ListValue, "plugin", translate("plugin"))
o:value("none", "None")
if nixio.fs.access("/usr/bin/v2ray-plugin") then
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
end
if nixio.fs.access("/usr/bin/obfs-local") then
o:value("/usr/bin/obfs-local", "obfs-local")
end
if nixio.fs.access("/usr/bin/goquiet-client") then
o:value("/usr/bin/goquiet-client", "GoQuiet")
end
o.rmempty = false
o.default = "none"
o:depends("type", "ss")
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
o.rmempty = true
o:depends("plugin", "/usr/bin/v2ray-plugin")
o:depends("plugin", "/usr/bin/obfs-local")
o:depends("plugin", "/usr/bin/goquiet-client")
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do o:value(v) end
o.rmempty = true
@ -168,6 +133,27 @@ for _, v in ipairs(obfs) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o = s:option(Flag, "v2ray_plugin", translate("V2ray-plugin"))
o.rmempty = false
o:depends("type", "ss")
o = s:option(Value, "obfs_transport", translate("V2ray-plugin-transport"))
o.rmempty = true
o.default = "ws"
o:depends("v2ray_plugin", "1")
o = s:option(Value, "obfs_host", translate("V2ray-plugin-host"))
o.rmempty = true
o:depends("v2ray_plugin", "1")
o = s:option(Value, "obfs_path", translate("V2ray-plugin-path"))
o.rmempty = true
o:depends("v2ray_plugin", "1")
o = s:option(Flag, "obfs_opts", translate("TLS"))
o.rmempty = false
o:depends("v2ray_plugin", "1")
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
o:depends("type", "ssr")
@ -265,7 +251,6 @@ o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
-- [[ mKCP部分 ]]--
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
@ -331,12 +316,6 @@ o.default = "0"
o:depends("type", "v2ray")
o:depends("type", "trojan")
o = s:option(Value, "tls_host", translate("TLS Host"))
--o:depends("type", "trojan")
o:depends("tls", "1")
o.rmempty = true
-- [[ Mux ]]--
o = s:option(Flag, "mux", translate("Mux"))
o.rmempty = true

View File

@ -4,33 +4,17 @@
local m, s, sec, o, kcp_enable
local vssr = "vssr"
local gfw_count=0
local ad_count=0
local ip_count=0
local gfwmode=0
if nixio.fs.access("/etc/dnsmasq.vssr/gfw_list.conf") then
if nixio.fs.access("/etc/dnsmasq.ssr/gfw_list.conf") then
gfwmode=1
end
local uci = luci.model.uci.cursor()
local sys = require "luci.sys"
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.vssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
m = Map(vssr)
m:section(SimpleSection).template = "vssr/status"
m:section(SimpleSection).template = "vssr/status_top"
local server_table = {}
local v2ray_table = {}
@ -40,7 +24,8 @@ uci:foreach(vssr, "servers", function(s)
elseif s.server and s.server_port then
server_table[s[".name"]] = "[%s]:%s:%s" %{string.upper(s.type), s.server, s.server_port}
end
if s.type == "v2ray" then
if s.type == "v2ray" then
if s.alias then
v2ray_table[s[".name"]] = "[%s]:%s" %{string.upper(s.type), s.alias}
elseif s.server and s.server_port then
@ -49,12 +34,12 @@ if s.type == "v2ray" then
end
end)
local key_table = {}
local key_table = {}
for key,_ in pairs(server_table) do
table.insert(key_table,key)
end
table.sort(key_table)
table.sort(key_table)
local key_table_v2 = {}
for key,_ in pairs(v2ray_table) do
@ -64,16 +49,11 @@ end
table.sort(key_table_v2)
-- [[ Global Setting ]]--
s = m:section(TypedSection, "global", translate("Basic Settings"))
s = m:section(TypedSection, "global",translate("Basic Settings [SS(R)|V2ray|Trojan]"))
s.anonymous = true
o = s:option(ListValue, "global_server", translate("Main Server"))
o:value("nil", translate("Disable"))
if nixio.fs.access("/usr/sbin/haproxy")then
o:value("__haproxy__", translate("Load Balancing"))
end
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o.default = "nil"
o.rmempty = false
@ -83,9 +63,9 @@ o:value("", translate("Disable"))
o:value("same", translate("Same as Global Server"))
for _,key in pairs(key_table) do o:value(key,server_table[key]) end
o = s:option(Flag, "v2ray_flow", translate("Open v2ray split-flow") .."</font>")
o = s:option(Flag, "v2ray_flow", translate("Open v2ray split-flow"))
o.rmempty = false
o.description = ("<font color='red'>" ..translate("When open v2ray split-flow,your main server must be a v2ray server").."</font>")
o.description = translate("When open v2ray split-flow,your main server must be a v2ray server")
o = s:option(ListValue, "youtube_server", translate("Youtube Proxy"))
o:value("nil", translate("Same as Global Server"))
@ -93,96 +73,62 @@ for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "tw_video_server", translate("TaiWan Video Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "netflix_server", translate("Netflix Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "disney_server", translate("Diseny+ Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "prime_server", translate("Prime Video Proxy"))
o:value("nil", translate("Same as Global Server"))
for _,key in pairs(key_table_v2) do o:value(key,v2ray_table[key]) end
o:depends("v2ray_flow", "1")
o.default = "nil"
o = s:option(ListValue, "threads", translate("Multi Threads Option"))
o:value("0", translate("Auto Threads"))
o:value("1", translate("1 Thread"))
o:value("2", translate("2 Threads"))
o:value("4", translate("4 Threads"))
o:value("8", translate("8 Threads"))
o:value("16", translate("16 Threads"))
o:value("32", translate("32 Threads"))
o:value("64", translate("64 Threads"))
o:value("128", translate("128 Threads"))
o.default = "0"
o.rmempty = false
o = s:option(ListValue, "run_mode", translate("Running Mode"))
o:value("gfw", translate("GFW List Mode"))
o:value("router", translate("IP Route Mode"))
o:value("routers", translate("Oversea IP Route Mode"))
o:value("oversea", translate("Oversea GFW List Mode"))
o:value("all", translate("Global Mode"))
o.default = gfw
o:value("oversea", translate("Oversea Mode"))
o.default = "router"
o = s:option(ListValue, "dports", translate("Proxy Ports"))
o:value("1", translate("All Ports"))
o:value("2", translate("Only Common Ports"))
o.default = 1
o.default = 1
o = s:option(ListValue, "pdnsd_enable", translate("Resolve Dns Mode"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
o:value("0", translate("Use Local DNS Service listen port 5335"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
if nixio.fs.access("/usr/bin/dnsforwarder") then
o:value("3", translate("Use dnsforwarder tcp query and cache"))
end
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
o:value("5", translate("Use dnscrypt-proxy query and cache"))
end
if nixio.fs.access("/usr/bin/chinadns") then
o:value("6", translate("Use chinadns query and cache"))
end
if nixio.fs.access("/usr/bin/dns2socks") then
o:value("7", translate("Use DNS2SOCKS query and cache"))
end
o.default = 1
o = s:option(ListValue, "chinadns_enable", translate("Chiadns Resolve Dns Mode"))
o:value("0", translate("Use Local DNS Service"))
o:value("1", translate("Use Pdnsd tcp query and cache"))
if nixio.fs.access("/usr/bin/dnsforwarder") then
o:value("3", translate("Use dnsforwarder tcp query and cache"))
end
if nixio.fs.access("/usr/bin/dnscrypt-proxy") then
o:value("5", translate("Use dnscrypt-proxy query and cache"))
end
if nixio.fs.access("/usr/sbin/smartdns") then
o:value("6", translate("Use smartdns query and cache"))
end
if nixio.fs.access("/usr/sbin/https_dns_proxy") then
o:value("7", translate("Use https_dns_proxy query and cache"))
end
o.default = 1
o:depends("pdnsd_enable", "6")
o = s:option(Value, "tunnel_forward", translate("Anti-pollution DNS Server"))
o:value("0.0.0.0:53", translate("Using System Default DNS"))
o:value("0.0.0.0:5333", translate("Using acceleration center DNS"))
o:value("8.8.4.4:53", translate("Google Public DNS (8.8.4.4)"))
o:value("8.8.8.8:53", translate("Google Public DNS (8.8.8.8)"))
o:value("208.67.222.222:53", translate("OpenDNS (208.67.222.222)"))
@ -197,33 +143,6 @@ o:value("1.1.1.1:53", translate("Cloudflare DNS (1.1.1.1)"))
o:value("114.114.114.114:53", translate("Oversea Mode DNS-1 (114.114.114.114)"))
o:value("114.114.115.115:53", translate("Oversea Mode DNS-2 (114.114.115.115)"))
o:depends("pdnsd_enable", "1")
o:depends("pdnsd_enable", "2")
o:depends("pdnsd_enable", "3")
o:depends("pdnsd_enable", "4")
o:depends("pdnsd_enable", "5")
o:depends("pdnsd_enable", "6")
o:depends("pdnsd_enable", "7")
o.default = "8.8.4.4:53"
o = s:option(Button,"gfw_data",translate("GFW List Data"))
o.rawhtml = true
o.template = "vssr/refresh"
o.value =tostring(math.ceil(gfw_count)) .. " " .. translate("Records")
o = s:option(Button,"ad_data",translate("Advertising Data"))
o .rawhtml = true
o .template = "vssr/refresh"
o .value =tostring(math.ceil(ad_count)) .. " " .. translate("Records")
o = s:option(Button,"ip_data",translate("China IP Data"))
o.rawhtml = true
o.template = "vssr/refresh"
o.value =ip_count .. " " .. translate("Records")
o = s:option(Button,"check_port",translate("Check Server Port"))
o.template = "vssr/checkport"
o.value =translate("No Check")
m:section(SimpleSection).template = "vssr/status2"
m:section(SimpleSection).template = "vssr/status_bottom"
return m

View File

@ -18,44 +18,28 @@ o.datatype = "ip4addr"
-- Part of LAN
s:tab("lan_ac", translate("LAN IP AC"))
o = s:taboption("lan_ac", ListValue, "lan_ac_mode", translate("LAN Access Control"))
o:value("0", translate("Disable"))
o:value("w", translate("Allow listed only"))
o:value("b", translate("Allow all except listed"))
o.rmempty = false
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Host List"))
o = s:taboption("lan_ac", DynamicList, "lan_ac_ips", translate("LAN Bypassed Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
end)
o:depends("lan_ac_mode", "w")
o:depends("lan_ac_mode", "b")
o = s:taboption("lan_ac", DynamicList, "lan_bp_ips", translate("LAN Bypassed Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
if entry.reachable then
o:value(entry.dest:string())
end
end)
o = s:taboption("lan_ac", DynamicList, "lan_fp_ips", translate("LAN Force Proxy Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
if entry.reachable then
o:value(entry.dest:string())
end
end)
o = s:taboption("lan_ac", DynamicList, "lan_gm_ips", translate("Game Mode Host List"))
o.datatype = "ipaddr"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
o:value(entry.dest:string())
end
if entry.reachable then
o:value(entry.dest:string())
end
end)
-- Part of Self
@ -66,9 +50,7 @@ end)
-- o:value("2", translatef("Forwarded Proxy"))
-- o.rmempty = false
s:tab("esc", translate("Bypass Domain List"), "<font color='red'>" ..
translate("Join the white list of domain names will not go agent.") ..
"</font>")
s:tab("esc", translate("Bypass Domain List"))
local escconf = "/etc/config/white.list"
o = s:taboption("esc", TextValue, "escconf")
@ -86,10 +68,7 @@ o.remove = function(self, section, value)
end
s:tab("block", translate("Black Domain List"),
"<font color='red'>" .. translate(
"These had been joined websites will use proxy.Please input the domain names of websites,every line can input only one website domain.For example,google.com.") ..
"</font>")
s:tab("block", translate("Black Domain List"))
local blockconf = "/etc/config/black.list"
o = s:taboption("block", TextValue, "blockconf")
@ -106,4 +85,4 @@ o.remove = function(self, section, value)
NXFS.writefile(blockconf, "")
end
return m
return m

View File

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

View File

@ -1,48 +0,0 @@
-- Copyright 2009 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher"
local HTTP = require "luci.http"
local UCI = luci.model.uci.cursor()
m = Map("vssr")
-- log directory
log_dir = UCI:get_first(m.config, "global", "log_dir") or "/tmp"
run_dir = UCI:get_first(m.config, "global", "run_dir") or "/var/etc"
local logfile_list = {}
for path in (NXFS.glob("%s/vssr*" % log_dir) or function() end) do
logfile_list[#logfile_list+1] = path
end
for path in (NXFS.glob("%s/*.*" % run_dir) or function() end) do
logfile_list[#logfile_list+1] = path
end
ns = m:section(TypedSection, "_dummy", translate("File Viewer"))
ns.addremove = false
ns.anonymous = true
function ns.cfgsections()
return{"_exrules"}
end
lv = ns:option(DynamicList, "logfiles")
lv.template = "vssr/logview"
lv.inputtitle = translate("Read / Reread log file")
lv.rows = 25
lv.default = ""
for _, lfile in ipairs(logfile_list) do lv:value(lfile, lfile) end
function lv.cfgvalue(self, section)
if logfile_list[1] then
local lfile=logfile_list[1]
if NXFS.access(lfile) then
return lfile .. "\n" .. translate("Please press [Read] button")
end
return lfile .. "\n" .. translate("File not found or empty")
else
return log_dir .. "\/\n" .. translate("No files found")
end
end
return m

View File

@ -3,21 +3,13 @@
local m, s, o
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local fs = require "nixio.fs"
local sys = require "luci.sys"
local sid = arg[1]
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
local http = luci.http
local ucursor = require "luci.model.uci".cursor()
local server_table = {}
local encrypt_methods = {
"none",
"table",
"rc4",
"rc4-md5-6",
"rc4-md5",
"rc4-md5-6",
"rc4",
"table",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
@ -38,72 +30,19 @@ local encrypt_methods = {
"chacha20-ietf",
}
local encrypt_methods_ss = {
-- aead
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
-- stream
"table",
"rc4",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
"auth_chain_b",
"auth_chain_c",
"auth_chain_d",
"auth_chain_e",
"auth_chain_f",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
}
local obfs_opts = {
"none",
"http",
"tls",
}
local securitys = {
"auto",
"none",
"aes-128-gcm",
"chacha20-poly1305"
}
m = Map(vssr, translate("Edit vssr Server"))
m.redirect = luci.dispatcher.build_url("admin/vpn/vssr/server")
m.redirect = luci.dispatcher.build_url("admin/services/vssr/server")
if m.uci:get(vssr, sid) ~= "server_config" then
luci.http.redirect(m.redirect)
return
@ -121,24 +60,6 @@ o = s:option(Flag, "enable", translate("Enable"))
o.default = 1
o.rmempty = false
o = s:option(ListValue, "type", translate("Server Node Type"))
if nixio.fs.access("/usr/bin/ssr-server") then
o:value("ssr", translate("ShadowsocksR"))
end
if nixio.fs.access("/usr/bin/ss-server") then
o:value("ss", translate("Shadowsocks New Version"))
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
o:value("v2ray", translate("V2Ray"))
end
o.description = translate("Using incorrect encryption mothod may causes service fail to start")
o = s:option(Flag, "ipv4_ipv6", translate("Enabling IPv6 server"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.default = 8388
@ -151,228 +72,24 @@ o.rmempty = false
o = s:option(Value, "password", translate("Password"))
o.password = true
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o.rmempty = false
o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
for _, v in ipairs(encrypt_methods) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o:depends("type", "ss")
o = s:option(ListValue, "plugin", translate("plugin"))
o:value("none", "None")
if nixio.fs.access("/usr/bin/v2ray-plugin") then
o:value("/usr/bin/v2ray-plugin", "v2ray-plugin")
end
if nixio.fs.access("/usr/bin/obfs-server") then
o:value("/usr/bin/obfs-server", "obfs-server")
end
if nixio.fs.access("/usr/bin/gq-server") then
o:value("/usr/bin/gq-server", "GoQuiet")
end
o.rmempty = false
o.default = "none"
o:depends("type", "ss")
o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
o.rmempty = true
o:depends("plugin", "/usr/bin/v2ray-plugin")
o:depends("plugin", "/usr/bin/obfs-server")
o:depends("plugin", "/usr/bin/gq-server")
o = s:option(ListValue, "protocol", translate("Protocol"))
for _, v in ipairs(protocol) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o.rmempty = false
o = s:option(ListValue, "obfs", translate("Obfs"))
for _, v in ipairs(obfs) do o:value(v) end
o.rmempty = true
o:depends("type", "ssr")
o.rmempty = false
o = s:option(Value, "obfs_param", translate("Obfs param(optional)"))
o:depends("type", "ssr")
-- AlterId
o = s:option(Value, "alter_id", translate("AlterId"))
o.default = 100
o.rmempty = true
o:depends("type", "v2ray")
o=s:option(Value,"VMess_level",translate("User Level"))
o.default=1
o:depends("type", "v2ray")
-- VmessId
o = s:option(Value, "vmess_id", translate("VmessId (UUID)"))
o.rmempty = true
o.default = uuid
o:depends("type", "v2ray")
-- 加密方式
o = s:option(ListValue, "security", translate("Encrypt Method"))
for _, v in ipairs(securitys) do o:value(v, v:upper()) end
o.rmempty = true
o:depends("type", "v2ray")
-- 传输协议
o = s:option(ListValue, "transport", translate("Transport"))
o:value("tcp", "TCP")
o:value("kcp", "mKCP")
o:value("ws", "WebSocket")
o:value("h2", "HTTP/2")
o:value("quic", "QUIC")
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TCP部分 ]]--
-- TCP伪装
o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
o:depends("transport", "tcp")
o:value("none", translate("None"))
o:value("http", "HTTP")
o.rmempty = true
-- HTTP域名
o = s:option(DynamicList, "http_host", translate("HTTP Host"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- HTTP路径
o = s:option(DynamicList, "http_path", translate("HTTP Path"))
o:depends("tcp_guise", "http")
o.rmempty = true
-- [[ WS部分 ]]--
-- WS域名
o = s:option(Value, "ws_host", translate("WebSocket Host"))
o:depends("transport", "ws")
o.rmempty = true
-- WS路径
o = s:option(Value, "ws_path", translate("WebSocket Path"))
o:depends("transport", "ws")
o.rmempty = true
-- [[ H2部分 ]]--
-- H2域名
o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host"))
o:depends("transport", "h2")
o.rmempty = true
-- H2路径
o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
o:depends("transport", "h2")
o.rmempty = true
-- [[ QUIC部分 ]]--
o = s:option(ListValue, "quic_security", translate("QUIC Security"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("aes-128-gcm", translate("aes-128-gcm"))
o:value("chacha20-poly1305", translate("chacha20-poly1305"))
o = s:option(Value, "quic_key", translate("QUIC Key"))
o:depends("transport", "quic")
o.rmempty = true
o = s:option(ListValue, "quic_guise", translate("Header"))
o:depends("transport", "quic")
o.rmempty = true
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
-- [[ mKCP部分 ]]--
o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
o:depends("transport", "kcp")
o:value("none", translate("None"))
o:value("srtp", translate("VideoCall (SRTP)"))
o:value("utp", translate("BitTorrent (uTP)"))
o:value("wechat-video", translate("WechatVideo"))
o:value("dtls", "DTLS 1.2")
o:value("wireguard", "WireGuard")
o.rmempty = true
o = s:option(Value, "mtu", translate("MTU"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 1350
o.rmempty = true
o = s:option(Value, "tti", translate("TTI"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 50
o.rmempty = true
o = s:option(Value, "uplink_capacity", translate("Uplink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 50
o.rmempty = true
o = s:option(Value, "downlink_capacity", translate("Downlink Capacity"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 20
o.rmempty = true
o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
o.datatype = "uinteger"
o:depends("transport", "kcp")
o.default = 2
o.rmempty = true
o = s:option(Flag, "congestion", translate("Congestion"))
o:depends("transport", "kcp")
o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, "insecure", translate("allowInsecure"))
o.rmempty = true
o:depends("type", "v2ray")
-- [[ TLS ]]--
o = s:option(Flag, "tls", translate("TLS"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
-- [[ Mux ]]--
o = s:option(Flag, "mux", translate("Mux"))
o.rmempty = true
o.default = "0"
o:depends("type", "v2ray")
o = s:option(Value, "concurrency", translate("Concurrency"))
o.datatype = "uinteger"
o.rmempty = true
o.default = "8"
o:depends("mux", "1")
o = s:option(Flag, "fast_open", translate("TCP Fast Open"))
o.rmempty = true
o:depends("type", "ssr")
o.rmempty = false
return m

View File

@ -6,13 +6,8 @@ local vssr = "vssr"
local uci = luci.model.uci.cursor()
local ipkg = require("luci.model.ipkg")
m = Map(vssr, translate("SS/SSR/V2RAY Server"))
m:section(SimpleSection).template = "vssr/status3"
local type = {
"ssr",
"ss",
"v2ray",
}
m = Map(vssr, translate("vssr Server"))
local encrypt_methods = {
"table",
@ -24,10 +19,7 @@ local encrypt_methods = {
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"aes-128-gcm",
"aes-192-gcm",
"aes-256-gcm",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
@ -40,8 +32,6 @@ local encrypt_methods = {
"salsa20",
"chacha20",
"chacha20-ietf",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
}
local protocol = {
@ -53,7 +43,7 @@ local protocol = {
"auth_chain_a",
}
local obfs = {
obfs = {
"plain",
"http_simple",
"http_post",
@ -64,10 +54,14 @@ local obfs = {
-- [[ Global Setting ]]--
sec = m:section(TypedSection, "server_global", translate("Global Setting"))
sec.anonymous = true
o = sec:option(Flag, "enable_server", translate("Enable Server"))
o.rmempty = false
@ -75,9 +69,8 @@ o.rmempty = false
sec = m:section(TypedSection, "server_config", translate("Server Setting"))
sec.anonymous = true
sec.addremove = true
sec.sortable = true
sec.template = "cbi/tblsection"
sec.extedit = luci.dispatcher.build_url("admin/vpn/vssr/server/%s")
sec.extedit = luci.dispatcher.build_url("admin/services/vssr/server/%s")
function sec.create(...)
local sid = TypedSection.create(...)
if sid then
@ -92,28 +85,30 @@ function o.cfgvalue(...)
end
o.rmempty = false
o = sec:option(DummyValue, "type", translate("Server Node Type"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = sec:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = sec:option(DummyValue,"vmess_id",translate("ID"))
o.width="10%"
o = sec:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
o.width="10%"
function o.cfgvalue(...)
local v = Value.cfgvalue(...)
return v and v:upper() or "?"
end
o = sec:option(DummyValue, "protocol", translate("Protocol"))
o.width="10%"
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
o = sec:option(DummyValue, "obfs", translate("Obfs"))
o.width="10%"
m:append(Template("vssr/server_list"))
function o.cfgvalue(...)
return Value.cfgvalue(...) or "?"
end
return m

View File

@ -1,76 +0,0 @@
-- Licensed to the public under the GNU General Public License v3.
local d = require "luci.dispatcher"
local fs = require "nixio.fs"
local sys = require "luci.sys"
local uci = require "luci.model.uci".cursor()
local m, s, o
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local server_count = 0
uci:foreach("vssr", "servers", function(s)
server_count = server_count + 1
end)
m = Map(vssr, translate("Node List"))
m:section(SimpleSection).template = "vssr/status1"
-- [[ Servers Manage ]]--
s = m:section(TypedSection, "servers")
s.anonymous = true
s.addremove = true
s.description = string.format(translate("Server Count") .. ": %d", server_count)
s.sortable = true
s.template = "cbi/tblsection"
s.extedit = luci.dispatcher.build_url("admin/vpn/vssr/servers/%s")
function s.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(s.extedit % sid)
return
end
end
o = s:option(DummyValue, "alias", translate("Alias"))
o.width="10%"
o = s:option(DummyValue, "type", translate("Type"))
o.width="15%"
o = s:option(DummyValue, "server", translate("Server Address"))
o.width="10%"
o = s:option(DummyValue, "server_port", translate("Server Port"))
o.width="10%"
o = s:option(DummyValue, "encrypt_method", translate("Encrypt Method"))
o.width="10%"
o = s:option(DummyValue, "protocol", translate("Protocol"))
o.width="10%"
o = s:option(DummyValue, "obfs", translate("Obfs"))
o.width="10%"
o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
o.width="10%"
if nixio.fs.access("/usr/bin/kcptun-client") then
o = s:option(Flag, "kcp_enable", translate("KcpTun"))
o.width="10%"
end
o = s:option(DummyValue, "server_port", translate("Socket Connected"))
o.template="vssr/socket"
o.width="10%"
o = s:option(DummyValue,"server",translate("Ping Latency"))
o.template="vssr/ping"
o.width="10%"
m:append(Template("vssr/server_list"))
return m

View File

@ -17,7 +17,7 @@ uci:foreach("vssr", "global", function(s) name = s[".name"] end)
m = Map(vssr)
m:section(SimpleSection).template = "vssr/status"
m:section(SimpleSection).template = "vssr/status_top"
-- [[ Servers List ]]--
s = m:section(TypedSection, "servers")
@ -29,34 +29,15 @@ s.des = server_count
s.current = uci:get("vssr", name, "global_server")
s.servers = cjson.encode(server_table)
s.template = "vssr/tblsection"
s.extedit = luci.dispatcher.build_url("admin/vpn/vssr/servers/%s")
s.extedit = luci.dispatcher.build_url("admin/services/vssr/servers/%s")
function s.create(...)
local sid = TypedSection.create(...)
local sid = TypedSection.create(...)
if sid then
luci.http.redirect(s.extedit % sid)
return
end
end
o = s:option(DummyValue, "type", translate("Type"))
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("") end
o = s:option(DummyValue, "alias", translate("Alias"))
function o.cfgvalue(...) return Value.cfgvalue(...) or translate("None") end
o = s:option(DummyValue, "server", translate("Server Address"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
o = s:option(DummyValue, "server_port", translate("Server Port"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
if nixio.fs.access("/usr/bin/kcptun-client") then
o = s:option(DummyValue, "kcp_enable", translate("KcpTun"))
function o.cfgvalue(...) return Value.cfgvalue(...) or "?" end
end
m:section(SimpleSection).template = "vssr/status2"
m:section(SimpleSection).template = "vssr/status_bottom"
return m

View File

@ -0,0 +1,41 @@
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local server_table = {}
local sys = require "luci.sys"
m = Map(vssr)
-- [[ SOCKS5 Proxy ]]--
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
s = m:section(TypedSection, "socks5_proxy", translate("V2ray SOCKS5 Proxy"))
s.anonymous = true
o = s:option(Flag, "enable_server", translate("Enable Servers"))
o.rmempty = false
o = s:option(Flag, "enable_auth", translate("Enable Auth"))
o.rmempty = false
o = s:option(Value, "Socks_user", translate("Socks user"))
o.default="user"
o.rmempty = true
o:depends("enable_auth", "1")
o = s:option(Value, "Socks_pass", translate("Socks pass"))
o.default="password"
o.password = true
o.rmempty = true
o:depends("enable_auth", "1")
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.default = 1080
o.rmempty = false
end
return m

View File

@ -1,466 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com>
-- Licensed to the public under the GNU General Public License v3.
local IPK_Version="20200328.1.31"
local m, s, o
local redir_run=0
local reudp_run=0
local sock5_run=0
local ssock5_run=0
local v2sock5_run=0
local server_run=0
local sserver_run=0
local v2server_run=0
local kcptun_run=0
local tunnel_run=0
local udp2raw_run=0
local udpspeeder_run=0
local gfw_count=0
local ad_count=0
local ip_count=0
local gfwmode=0
local pdnsd_run=0
local dnsforwarder_run=0
local dnscrypt_proxy_run=0
local chinadns_run=0
local dns2socks_run=0
local haproxy_run=0
local privoxy_run=0
if nixio.fs.access("/etc/dnsmasq.vssr/gfw_list.conf") then
gfwmode=1
end
local vssr= "vssr"
-- html constants
font_blue = [[<font color="green">]]
font_off = [[</font>]]
bold_on = [[<strong>]]
bold_off = [[</strong>]]
local fs = require "nixio.fs"
local sys = require "luci.sys"
local kcptun_version=translate("Unknown")
local kcp_file="/usr/bin/kcptun-client"
if not fs.access(kcp_file) then
kcptun_version=translate("Not exist")
else
if not fs.access(kcp_file, "rwx", "rx", "rx") then
fs.chmod(kcp_file, 755)
end
kcptun_version=sys.exec(kcp_file .. " -v | awk '{printf $3}'")
if not kcptun_version or kcptun_version == "" then
kcptun_version = translate("Unknown")
end
end
local udp2raw_version=translate("Unknown")
local udp2raw_file="/usr/bin/udp2raw"
if not fs.access(udp2raw_file) then
udp2raw_version=translate("Not exist")
else
if not fs.access(udp2raw_file, "rwx", "rx", "rx") then
fs.chmod(udp2raw_file, 755)
end
udp2raw_version=sys.exec(udp2raw_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
if not udp2raw_version or udp2raw_version == "" then
udp2raw_version = translate("Unknown")
end
end
local udpspeeder_version=translate("Unknown")
local udpspeeder_file="/usr/bin/udpspeeder"
if not fs.access(udpspeeder_file) then
udpspeeder_version=translate("Not exist")
else
if not fs.access(udpspeeder_file, "rwx", "rx", "rx") then
fs.chmod(udpspeeder_file, 755)
end
udpspeeder_version=sys.exec(udpspeeder_file .. " -h |grep 'git version' |awk -F ':' '{print $2}'|awk '{print $1}'")
if not udpspeeder_version or udpspeeder_version == "" then
udpspeeder_version = translate("Unknown")
end
end
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
if nixio.fs.access("/etc/dnsmasq.vssr/ad.conf") then
ad_count=tonumber(sys.exec("cat /etc/dnsmasq.vssr/ad.conf | wc -l"))
end
end
if nixio.fs.access("/etc/china_ssr.txt") then
ip_count = sys.exec("cat /etc/china_ssr.txt | wc -l")
end
function processlist()
local data = {}
local netf = {}
local k
local ps = luci.util.execi("/bin/busybox top -bn1 | egrep -v dnsmasq")
local nets = luci.util.execi("netstat -netupl | egrep -v dnsmasq | awk '{print $1,$4,_,$6,$7}'")
if not ps or not nets then
return
end
for line in nets do
-- tcp 0 0 127.0.0.1:1234 0.0.0.0:* LISTEN 5103/v2ray
-- udp 0 0 127.0.0.1:1234 0.0.0.0:* 5147/v2ray
-- local proto, ip, port, nid = line:match("([^%s]+) +.* +([^ ]*):(%d+) +.* +(%d+)\/.*")
local proto, ip, port, nid = line:match("([^%s]+) (.*):(%d+)[^%d]+(%d+)\/.*")
local idx = tonumber(nid)
if idx and ip then
local newstr = "://" .. ip .. ":" .. port
local isnew = (netf[idx] and netf[idx]['listen']) and netf[idx]['listen']:match(proto .. newstr) or false
netf[idx] = {
['listen'] = ((netf[idx] and netf[idx]['listen']) and (not isnew) and (netf[idx]['listen'] .. "\n" .. proto) or proto) .. newstr,
}
end
end
-- 5103 1 root S 661m 543% 0% /usr/bin/v2ray/v2ray -config /var/etc/shadowsocksr.json
for line in ps do
local pid, ppid, user, stat, vsz, mem, cpu, cmd = line:match(
"^ *(%d+) +(%d+) +(%S.-%S) +([RSDZTW][W ][<N ]) +(%d+.?) +(%d+%%) +(%d+%%) +(.+)"
)
if cmd then
local idx = tonumber(pid)
local bin, param, cfg = cmd:match("^.*\/([^ ]*) *([^ ]*) *\/var\/etc\/([^ ]*).*")
if idx and cfg then
local listen = "NONE"
if netf[idx] and netf[idx]['listen'] then
listen = netf[idx]['listen']
end
data[idx] = {
['PID'] = pid,
['COMMAND'] = bin,
['LISTEN'] = listen,
['CONFIG'] = cfg,
['%MEM'] = mem,
['%CPU'] = cpu,
}
end
end
end
return data
end
function printstat(status, form, name)
local tabs = {
["Global Client"] = "shadowsocksr.json",
["Game Mode UDP Relay"] = "shadowsocksr_u.json",
["PDNSD"] = "pdnsd.conf",
["DNS Forward"] = "shadowsocksr_d.json",
["SOCKS5 Proxy"] = "shadowsocksr_s.json",
["Global SSR Server"] = "shadowsocksr_0.json",
}
local stat = translate("Unknown")
local sname = stat
if tabs[name] and status then
stat = translate("Not Running")
for idx, cfg in pairs(status) do
if status[idx]['CONFIG'] and status[idx]['CONFIG'] == tabs[name] then
stat = font_blue .. bold_on .. translate("Running") .. bold_off .. " > " .. status[idx]['COMMAND'] .. " -c " .. status[idx]['CONFIG'] .. font_off
sname = translate(status[idx]['COMMAND'])
break
end
end
end
local section = form:field(DummyValue,name,translate(name) .. ": " .. sname)
section.rawhtml = true
section.value = stat
return section
end
procs=processlist()
local icount=sys.exec("ps -w | grep ssr-reudp |grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
else
icount=sys.exec("ps -w | grep ssr-retcp |grep \"\\-u\"|grep -v grep| wc -l")
if tonumber(icount)>0 then
reudp_run=1
end
end
if luci.sys.call("ps -w | grep ssr-retcp | grep -v grep >/dev/null") == 0 then
redir_run=1
end
if luci.sys.call("pidof ssr-local >/dev/null") == 0 then
sock5_run=1
end
if luci.sys.call("pidof ss-local >/dev/null") == 0 then
ssock5_run=1
end
if luci.sys.call("ps -w | grep v2-ssr-local | grep -v grep >/dev/null") == 0 then
v2sock5_run=1
end
if luci.sys.call("pidof privoxy >/dev/null") == 0 then
privoxy_run=1
end
if luci.sys.call("pidof kcptun-client >/dev/null") == 0 then
kcptun_run=1
end
if luci.sys.call("pidof ssr-server >/dev/null") == 0 then
server_run=1
end
if luci.sys.call("busybox ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
tunnel_run=1
end
if luci.sys.call("pidof ss-server >/dev/null") == 0 then
sserver_run=1
end
if luci.sys.call("ps -w | grep v2ray-server | grep -v grep >/dev/null") == 0 then
v2server_run=1
end
if luci.sys.call("ps -w | grep ssr-tunnel |grep -v grep >/dev/null") == 0 then
tunnel_run=1
end
if luci.sys.call("pidof udp2raw >/dev/null") == 0 then
udp2raw_run=1
end
if luci.sys.call("pidof udpspeeder >/dev/null") == 0 then
udpspeeder_run=1
end
if luci.sys.call("pidof chinadns >/dev/null") == 0 then
chinadns_run=1
end
if luci.sys.call("pidof pdnsd >/dev/null") == 0 then
pdnsd_run=1
end
if luci.sys.call("pidof dnsparsing >/dev/null") == 0 then
dnsforwarder_run=1
end
if luci.sys.call("pidof dnscrypt-proxy >/dev/null") == 0 then
dnscrypt_proxy_run=1
end
if luci.sys.call("pidof dns2socks >/dev/null") == 0 then
dns2socks_run=1
end
if luci.sys.call("pidof haproxy >/dev/null") == 0 then
haproxy_run=1
end
m = SimpleForm("Version")
m.reset = false
m.submit = false
t = m:section(Table, procs, translate("Running Details: ") .. "(/var/etc)")
t:option(DummyValue, "PID", translate("PID"))
t:option(DummyValue, "COMMAND", translate("CMD"))
t:option(DummyValue, "LISTEN", translate("LISTEN"))
t:option(DummyValue, "%CPU", translate("CPU usage (%)"))
t:option(DummyValue, "%MEM", translate("Memory usage (%)"))
s=m:field(DummyValue,"redir_run",translate("Global Client"))
s.rawhtml = true
if redir_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"reudp_run",translate("Game Mode UDP Relay"))
s.rawhtml = true
if reudp_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"haproxy_run",translate("Load Balancing"))
s.rawhtml = true
if haproxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/chinadns") then
s=m:field(DummyValue,"chinadns_run",translate("ChinaDNS"))
s.rawhtml = true
if chinadns_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"pdnsd_run",translate("PDNSD"))
s.rawhtml = true
if pdnsd_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/dns2socks") then
s=m:field(DummyValue,"dns2socks_run",translate("DNS2SOCKS"))
s.rawhtml = true
if dns2socks_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"dnsforwarder_run",translate("dnsforwarder"))
s.rawhtml = true
if dnsforwarder_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"dnscrypt_proxy_run",translate("dnscrypt_proxy"))
s.rawhtml = true
if dnscrypt_proxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
if nixio.fs.access("/usr/bin/ss-local") then
s=m:field(DummyValue,"ssock5_run",translate("SSOCKS5 Proxy"))
s.rawhtml = true
if ssock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ssr-local") then
s=m:field(DummyValue,"sock5_run",translate("SSR SOCKS5 Proxy"))
s.rawhtml = true
if sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/v2ray/v2ray") then
s=m:field(DummyValue,"ssock5_run",translate("V2SOCKS5 Proxy"))
s.rawhtml = true
if v2sock5_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/sbin/privoxy") then
s=m:field(DummyValue,"privoxy_run",translate("HTTP Proxy"))
s.rawhtml = true
if privoxy_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ssr-server") then
s=m:field(DummyValue,"server_run",translate("Global SSR Server"))
s.rawhtml = true
if server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/ss-server") then
s=m:field(DummyValue,"sserver_run",translate("Global SS Server"))
s.rawhtml = true
if sserver_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/v2ray") then
s=m:field(DummyValue,"v2server_run",translate("Global V2RAY Server"))
s.rawhtml = true
if v2server_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
if nixio.fs.access("/usr/bin/kcptun-client") then
s=m:field(DummyValue,"kcp_version",translate("KcpTun Version"))
s.rawhtml = true
s.value =kcptun_version
s=m:field(DummyValue,"kcptun_run",translate("KcpTun"))
s.rawhtml = true
if kcptun_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
end
s=m:field(DummyValue,"version",translate("IPK Version"))
s.rawhtml = true
s.value =IPK_Version
s=m:field(DummyValue,"udp2raw_version",translate("udp2raw Version"))
s.rawhtml = true
s.value =udp2raw_version
s=m:field(DummyValue,"udp2raw_run",translate("udp2raw"))
s.rawhtml = true
if udp2raw_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"udpspeeder_version",translate("UDPspeeder Version"))
s.rawhtml = true
s.value =udpspeeder_version
s=m:field(DummyValue,"udpspeeder_run",translate("UDPspeeder"))
s.rawhtml = true
if udpspeeder_run == 1 then
s.value =font_blue .. bold_on .. translate("Running") .. bold_off .. font_off
else
s.value = translate("Not Running")
end
s=m:field(DummyValue,"feedback",translate("Feedback"))
s.template = "vssr/feedback"
s.value =translate("No feedback")
return m

View File

@ -1,91 +0,0 @@
-- Licensed to the public under the GNU General Public License v3.
local m, s, o
local vssr = "vssr"
local uci = luci.model.uci.cursor()
local server_table = {}
local gfwmode=0
local gfw_count=0
local ip_count=0
if nixio.fs.access("/etc/dnsmasq.vssr/gfw_list.conf") then
gfwmode=1
end
local uci = luci.model.uci.cursor()
local server_count = 0
uci:foreach("vssr", "servers", function(s)
server_count = server_count + 1
end)
local fs = require "nixio.fs"
local sys = require "luci.sys"
if gfwmode==1 then
gfw_count = tonumber(sys.exec("cat /etc/dnsmasq.vssr/gfw_list.conf | wc -l"))/2
end
m = Map(vssr)
m:section(SimpleSection).template = "vssr/status"
-- [[ 节点订阅 ]]--
s = m:section(TypedSection, "server_subscribe", translate("Subscription"))
s.anonymous = true
o = s:option(Flag, "auto_update", translate("Auto Update"))
o.rmempty = false
o.description = translate("Auto Update Server subscription, GFW list and CHN route")
o = s:option(ListValue, "auto_update_time", translate("Update time (every day)"))
for t = 0,23 do
o:value(t, t..":00")
end
o.default=2
o.rmempty = false
o = s:option(DynamicList, "subscribe_url", translate("Subscribe URL"))
o.rmempty = true
o = s:option(Flag, "proxy", translate("Through proxy update"))
o.rmempty = false
o.description = translate("Through proxy update list, Not Recommended ")
o = s:option(Flag, "switch", translate("Subscribe Default Auto-Switch"))
o.rmempty = false
o.description = translate("Subscribe new add server default Auto-Switch on")
o.default="0"
o = s:option(DummyValue, "", "")
o.rawhtml = true
o.template = "vssr/update_subscribe"
o = s:option(Button,"delete",translate("Delete All Subscribe Severs"))
o.inputstyle = "reset"
o.description = string.format(translate("Server Count") .. ": %d", server_count)
o.write = function()
uci:delete_all("vssr", "servers", function(s)
if s["hashkey"] then
return true
else
return false
end
end)
uci:save("vssr")
luci.sys.call("uci commit vssr && /etc/init.d/vssr stop")
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "vssr", "servers"))
return
end
m:section(SimpleSection).template = "vssr/status2"
return m

View File

@ -1,197 +0,0 @@
-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Copyright (C) 2018 lean <coolsnowwolf@gmail.com> github.com/coolsnowwolf
-- Licensed to the public under the GNU General Public License v3.
local m, s, sec, o, kcp_enable
local vssr = "vssr"
m = Map(vssr)
local server_table = {}
local encrypt_methods = {
"none",
"table",
"rc4",
"rc4-md5-6",
"rc4-md5",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"bf-cfb",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"cast5-cfb",
"des-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
"salsa20",
"chacha20",
"chacha20-ietf",
}
local protocol = {
"origin",
"verify_deflate",
"auth_sha1_v4",
"auth_aes128_sha1",
"auth_aes128_md5",
"auth_chain_a",
"auth_chain_b",
"auth_chain_c",
"auth_chain_d",
"auth_chain_e",
"auth_chain_f",
}
obfs = {
"plain",
"http_simple",
"http_post",
"random_head",
"tls1.2_ticket_auth",
}
local raw_mode = {
"faketcp",
"udp",
"icmp",
}
local seq_mode = {
"0",
"1",
"2",
"3",
"4",
}
local cipher_mode = {
"none",
"xor",
"aes128cbc",
}
local auth_mode = {
"none",
"simple",
"md5",
"crc32",
}
local speeder_mode = {
"0",
"1",
}
-- [[ udp2raw ]]--
if nixio.fs.access("/usr/bin/udp2raw") then
s = m:section(TypedSection, "udp2raw", translate(" UDP2raw "))
s.anonymous = true
o = s:option(Flag, "udp2raw_enable", translate("Enable udp2raw"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "key", translate("Password"))
o.password = true
o.rmempty = false
o = s:option(ListValue, "raw_mode", translate("Raw Mode"))
for _, v in ipairs(raw_mode) do o:value(v) end
o.default = "faketcp"
o.rmempty = false
o = s:option(ListValue, "seq_mode", translate("Seq Mode"))
for _, v in ipairs(seq_mode) do o:value(v) end
o.default = "3"
o.rmempty = false
o = s:option(ListValue, "cipher_mode", translate("Cipher Mode"))
for _, v in ipairs(cipher_mode) do o:value(v) end
o.default = "xor"
o.rmempty = false
o = s:option(ListValue, "auth_mode", translate("Auth Mode"))
for _, v in ipairs(auth_mode) do o:value(v) end
o.default = "simple"
o.rmempty = false
end
-- [[ udpspeeder ]]--
if nixio.fs.access("/usr/bin/udpspeeder") then
s = m:section(TypedSection, "udpspeeder", translate("UDPspeeder"))
s.anonymous = true
o = s:option(Flag, "udpspeeder_enable", translate("Enable UDPspeeder"))
o.default = 0
o.rmempty = false
o = s:option(Value, "server", translate("Server Address"))
o.datatype = "host"
o.rmempty = false
o = s:option(Value, "server_port", translate("Server Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "local_port", translate("Local Port"))
o.datatype = "port"
o.rmempty = false
o = s:option(Value, "key", translate("Password"))
o.password = true
o.rmempty = false
o = s:option(ListValue, "speeder_mode", translate("Speeder Mode"))
for _, v in ipairs(speeder_mode) do o:value(v) end
o.default = "0"
o.rmempty = false
o = s:option(Value, "fec", translate("Fec"))
o.default = "20:10"
o.rmempty = false
o = s:option(Value, "mtu", translate("Mtu"))
o.datatype = "uinteger"
o.default = 1250
o.rmempty = false
o = s:option(Value, "queue_len", translate("Queue Len"))
o.datatype = "uinteger"
o.default = 200
o.rmempty = false
o = s:option(Value, "timeout", translate("Fec Timeout"))
o.datatype = "uinteger"
o.default = 8
o.rmempty = false
end
return m

View File

@ -1 +1,2 @@
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" class="incon<%=subcount%>" data-depends="<%=pcdata(self:deplist2json(section))%>">

View File

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

View File

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

View File

@ -1,21 +0,0 @@
</style>
<div class="cbi-value">
<label class="cbi-value-title">udp2raw 项目</label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/udp2raw-tunnel','target');" />
</div>
</div>
<div class="cbi-value">
<label class="cbi-value-title">UDPspeeder 项目</label>
<div class="cbi-value-field">
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://github.com/wangyu-/UDPspeeder','target');" />
</div>
</div>
</fieldset>
</fieldset>

View File

@ -0,0 +1,21 @@
<%+header%>
<link rel="stylesheet" href="/luci-static/vssr/css/vssr.css?v=<%=math.random(1,100000)%>">
<div class="pure-g status">
<div class="pure-u-1">
<div class="block pure-g">
<div class="pure-u-1">
<h4 id="vssr_status"><span class="green" style="color: #404040;">GeoLite2</span></h4>
<p style="margin: 1rem; line-height: 1.8em;">This product includes GeoLite2 data created by MaxMind,
available from
<a href="https://www.maxmind.com">https://www.maxmind.com</a>.</p>
<h4 id="vssr_status"><span class="green" style="color: #404040;">Flag-icon-css</span></h4>
<p style="margin: 1rem; line-height: 1.8em;">A collection of all country flags in SVG — plus the CSS for easier integration <a href="https://flagicons.lipis.dev">https://flagicons.lipis.dev</a></p>
</div>
</div>
</div>
</div>
<%+footer%>

View File

@ -1,109 +0,0 @@
<!-- ++ BEGIN ++ Auto Repeater ++ logsview.htm ++ -->
<%-
local values = self:formvalue(section)
if not values then
values = self:cfgvalue(section) or {self.default}
end
local function serialize_json(x, cb)
local rv, push = nil, cb
if not push then
rv = { }
push = function(tok) rv[#rv+1] = tok end
end
if x == nil then
push("null")
elseif type(x) == "table" then
push("[")
for k = 1, #x do
if k > 1 then
push(",")
end
serialize_json(x[k], push)
end
push("]")
else
push('"%s"' % tostring(x):gsub('["%z\1-\31\\]',
function(c) return '\\u%04x' % c:byte(1) end))
end
if not cb then
return table.concat(rv, "")
end
end
-%>
<%+cbi/valueheader%>
<select class="cbi-input-select" onchange="onclick_logview(this, false)"
<%=
attr("name", cbid) .. attr("id", cbid) .. attr("value", self.default) .. ifattr(self.size, "size")
%>
></select>
<script type="text/javascript">//<![CDATA[
(function() {
//var values = <%=serialize_json(values)%>;
var keylist = <%=serialize_json(self.keylist)%>;
var vallist = <%=serialize_json(self.vallist)%>;
var parent = document.getElementById("<%=cbid%>");
for (var j = 0; j < keylist.length; j++) {
var opt = document.createElement("option");
opt.value = keylist[j];
if (j == 0) {
opt.selected = "selected";
}
opt.appendChild(document.createTextNode(vallist[j]));
parent.appendChild(opt);
}
}());
//]]></script>
<script type="text/javascript">//<![CDATA[
function onclick_logview(id, bottom) {
// get elements
var txt = document.getElementById("<%=cbid%>.txt"); // TextArea
if ( !txt ) { return; } // security check
txt.value= "Reading: " + document.getElementById("<%=cbid%>").value
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vssr", "fileread")%>', {lfile: document.getElementById("<%=cbid%>").value} ,
function(x, ifc) {
if (! ifc) {txt.value = "XHR.get(<%=luci.dispatcher.build_url("admin", "vpn", "vssr", "fileread")%>) Failed!"; return;}
txt.value = ifc[0];
if (bottom)
txt.scrollTop = txt.scrollHeight;
else
txt.scrollTop = 0;
txt.scrollLeft = 0;
}
);
}
//]]></script>
<%
-- one button on top, one at the buttom
%>
<br /><br />
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, false)'
<%=
attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
%> />
<br /><br />
<%
-- set a readable style taken from openwrt theme for textarea#syslog
-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
%>
<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 200px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
<%=
attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
%> >
<%-=pcdata(self:cfgvalue(section))-%>
</textarea>
<br /><br />
<%
-- one button on top, one at the buttom
%>
<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick='onclick_logview(this, true)'
<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
<br /><br />
<%+cbi/valuefooter%>
<!-- ++ END ++ Auto Repeater ++ logsview.htm ++ -->

View File

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

View File

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

View File

@ -1,53 +0,0 @@
<%#
Copyright 2018-2019 Lienol <lawlienol@gmail.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">
//<![CDATA[
const doms = document.getElementsByClassName('pingtime');
const ports = document.getElementsByClassName("socket-connected")
const xhr = (index) => {
return new Promise((res) => {
const dom = doms[index];
const port = ports[index];
if (!dom) res()
port.innerHTML = '<font color="#0072c3">connecting...</font>';
XHR.get('<%=dsp.build_url("admin/vpn/vssr/ping")%>', {
index,
domain: dom.getAttribute("hint"),
port: port.getAttribute("hint")
},
(x, result) => {
let col = '#ff0000';
if (result.ping) {
if (result.ping < 300) col = '#ff3300';
if (result.ping < 200) col = '#ff7700';
if (result.ping < 100) col = '#249400';
}
dom.innerHTML = `<font color="${col}">${(result.ping ? result.ping : "--") + " ms"}</font>`
if (result.socket) {
port.innerHTML = '<font color="#249400">ok</font>';
} else {
port.innerHTML = '<font color="#ff0000">fail</font>';
}
res();
});
})
}
let task = -1;
const thread = () => {
task = task + 1
if (doms[task]) {
xhr(task).then(thread);
}
}
for (let i = 0; i < 10; i++) {
thread()
}
</script>

Some files were not shown because too many files have changed in this diff Show More