Merge Mainline
This commit is contained in:
commit
e6b52447eb
@ -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.
|
||||
|
||||
22
Makefile
22
Makefile
@ -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
|
||||
|
||||
@ -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 $@; \
|
||||
}
|
||||
|
||||
@ -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
|
||||
//
|
||||
########################################################==
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -454,6 +454,9 @@ msgstr "亚洲流媒体流量"
|
||||
msgid "Proxy"
|
||||
msgstr "必须代理的流量"
|
||||
|
||||
msgid "Youtube"
|
||||
msgstr "Youtube流量"
|
||||
|
||||
msgid "Apple"
|
||||
msgstr "苹果服务流量"
|
||||
|
||||
|
||||
@ -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))
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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%> <%- 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>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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%>
|
||||
@ -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%>
|
||||
@ -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%>
|
||||
@ -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>
|
||||
@ -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 ++ -->
|
||||
@ -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 登录设备:</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 国内:</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 国内:</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 海外:</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 海外:</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>
|
||||
|
||||
@ -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>
|
||||
@ -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%>
|
||||
@ -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>
|
||||
@ -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%>
|
||||
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
|
||||
@ -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%>
|
||||
@ -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 "文件查看器"
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -1 +0,0 @@
|
||||
0xDEADBEEF
|
||||
@ -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'
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
apple.com
|
||||
microsoft.com
|
||||
@ -1,3 +0,0 @@
|
||||
server=/.3g.music.qq.com/127.0.0.1#5335
|
||||
ipset=/3g.music.qq.com/oversea
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 $?
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
@ -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))
|
||||
@ -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))
|
||||
@ -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))
|
||||
@ -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))
|
||||
@ -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
|
||||
@ -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
|
||||
-- 未指定peer(sni)默认使用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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
@ -1 +1,2 @@
|
||||
|
||||
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" class="incon<%=subcount%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
|
||||
|
||||
@ -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%>
|
||||
@ -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%>
|
||||
@ -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>
|
||||
21
package/ctcgfw/luci-app-vssr/luasrc/view/vssr/licence.htm
Normal file
21
package/ctcgfw/luci-app-vssr/luasrc/view/vssr/licence.htm
Normal 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%>
|
||||
@ -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 ++ -->
|
||||
@ -1,3 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="pingtime" hint="<%=self:cfgvalue(section)%>">-- ms</span>
|
||||
<%+cbi/valuefooter%>
|
||||
@ -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%>
|
||||
@ -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
Loading…
Reference in New Issue
Block a user