├── .gitignore ├── LICENSE ├── README.md ├── gmod.sublime-project ├── luci ├── luci-app-redsocks2 │ ├── Makefile │ ├── README.md │ ├── ipkg │ │ └── postinst │ ├── luasrc │ │ ├── controller │ │ │ └── redsocks2.lua │ │ └── model │ │ │ └── cbi │ │ │ └── redsocks2 │ │ │ ├── advanced.lua │ │ │ └── general.lua │ ├── po │ │ └── zh-cn │ │ │ └── redsocks2.po │ └── root │ │ ├── etc │ │ ├── config │ │ │ └── redsocks2 │ │ ├── init.d │ │ │ └── redsocks2 │ │ └── uci-defaults │ │ │ └── luci-redsocks2 │ │ └── usr │ │ └── share │ │ ├── redsocks2 │ │ └── firewall.include │ │ └── rpcd │ │ └── acl.d │ │ └── luci-app-redsocks2.json ├── luci-app-smartdns │ ├── Makefile │ └── files │ │ ├── usr │ │ ├── lib │ │ │ └── lua │ │ │ │ └── luci │ │ │ │ └── i18n │ │ │ │ └── smartdns.zh-cn.lmo │ │ └── share │ │ │ ├── luci │ │ │ └── menu.d │ │ │ │ └── luci-app-smartdns.json │ │ │ └── rpcd │ │ │ └── acl.d │ │ │ └── luci-app-smartdns.json │ │ └── www │ │ └── luci-static │ │ └── resources │ │ └── view │ │ └── smartdns │ │ └── smartdns.js ├── luci-app-v2ray-server │ ├── LICENSE │ ├── Makefile │ ├── luasrc │ │ ├── controller │ │ │ └── v2ray_server.lua │ │ ├── model │ │ │ └── cbi │ │ │ │ └── v2ray_server │ │ │ │ ├── api │ │ │ │ ├── app.lua │ │ │ │ ├── gen_config.lua │ │ │ │ └── v2ray.lua │ │ │ │ ├── index.lua │ │ │ │ └── user.lua │ │ └── view │ │ │ └── v2ray_server │ │ │ ├── log.htm │ │ │ ├── users_list_status.htm │ │ │ └── v2ray.htm │ ├── po │ │ └── zh-cn │ │ │ └── v2ray_server.po │ └── root │ │ ├── etc │ │ ├── config │ │ │ └── v2ray_server │ │ ├── init.d │ │ │ └── v2ray_server │ │ └── uci-defaults │ │ │ └── luci-v2ray-server │ │ └── usr │ │ └── share │ │ └── rpcd │ │ └── acl.d │ │ └── luci-app-v2ray-server.json ├── luci-app-v2ray │ ├── .editorconfig │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── i18n-scan.pl │ ├── i18n-update.pl │ ├── luasrc │ │ ├── controller │ │ │ └── v2ray.lua │ │ ├── model │ │ │ ├── cbi │ │ │ │ └── v2ray │ │ │ │ │ ├── about.lua │ │ │ │ │ ├── dns.lua │ │ │ │ │ ├── inbound-detail.lua │ │ │ │ │ ├── inbound-list.lua │ │ │ │ │ ├── main.lua │ │ │ │ │ ├── outbound-detail.lua │ │ │ │ │ ├── outbound-list.lua │ │ │ │ │ ├── policy-level-detail.lua │ │ │ │ │ ├── policy.lua │ │ │ │ │ ├── reverse.lua │ │ │ │ │ ├── routing-rule-detail.lua │ │ │ │ │ ├── routing.lua │ │ │ │ │ └── transparent-proxy.lua │ │ │ └── v2ray.lua │ │ └── view │ │ │ └── v2ray │ │ │ ├── import_outbound.htm │ │ │ ├── list_status.htm │ │ │ └── status_header.htm │ ├── po │ │ ├── templates │ │ │ └── v2ray.pot │ │ ├── zh-cn │ │ │ └── v2ray.po │ │ └── zh_Hans │ │ │ └── v2ray.po │ └── root │ │ └── etc │ │ ├── config │ │ └── v2ray │ │ ├── firewall.v2ray │ │ ├── init.d │ │ └── v2ray │ │ ├── uci-defaults │ │ └── 40_luci-v2ray │ │ └── v2ray │ │ ├── chnroute.txt │ │ ├── chnroute6.txt │ │ ├── directlist.txt │ │ ├── gfwlist.txt │ │ ├── proxylist.txt │ │ ├── srcdirectlist.txt │ │ ├── transport.json │ │ └── upload │ │ └── .gitkeep ├── luci-app-vlmcsd │ ├── Makefile │ ├── luasrc │ │ ├── controller │ │ │ └── vlmcsd.lua │ │ ├── model │ │ │ └── cbi │ │ │ │ └── vlmcsd.lua │ │ └── view │ │ │ └── vlmcsd │ │ │ └── vlmcsd_status.htm │ ├── po │ │ └── zh-cn │ │ │ └── vlmcsd.po │ └── root │ │ └── etc │ │ ├── config │ │ └── vlmcsd │ │ ├── init.d │ │ └── kms │ │ └── uci-defaults │ │ └── luci-vlmcsd ├── luci-app-zerotier │ ├── Makefile │ ├── luasrc │ │ ├── controller │ │ │ └── zerotier.lua │ │ ├── model │ │ │ └── cbi │ │ │ │ └── zerotier │ │ │ │ ├── info.lua │ │ │ │ └── settings.lua │ │ └── view │ │ │ └── zerotier │ │ │ └── zerotier_status.htm │ ├── po │ │ └── zh-cn │ │ │ └── zerotier.po │ └── root │ │ ├── etc │ │ ├── init.d │ │ │ └── zerotier │ │ ├── uci-defaults │ │ │ └── 40_luci-zerotier │ │ ├── zerotier.start │ │ ├── zerotier.stop │ │ └── zerotier │ │ │ └── zerotier.log │ │ └── usr │ │ └── share │ │ └── rpcd │ │ └── acl.d │ │ └── luci-app-zerotier.json ├── luci-proto-n2n │ ├── LICENSE │ ├── Makefile │ └── files │ │ ├── cbi │ │ └── proto_n2n.lua │ │ ├── n2n.sh │ │ └── network │ │ └── proto_n2n.lua ├── luci-theme-argon │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── README_ZH.md │ ├── htdocs │ │ └── luci-static │ │ │ ├── argon │ │ │ ├── background │ │ │ │ └── README.md │ │ │ ├── css │ │ │ │ ├── cascade.css │ │ │ │ ├── dark.css │ │ │ │ ├── fonts.css │ │ │ │ └── pure-min.css │ │ │ ├── favicon.ico │ │ │ ├── fonts │ │ │ │ ├── TypoGraphica.eot │ │ │ │ ├── TypoGraphica.svg │ │ │ │ ├── TypoGraphica.ttf │ │ │ │ ├── TypoGraphica.woff │ │ │ │ ├── argon.eot │ │ │ │ ├── argon.svg │ │ │ │ ├── argon.ttf │ │ │ │ └── argon.woff │ │ │ ├── icon │ │ │ │ ├── android-icon-192x192.png │ │ │ │ ├── apple-icon-144x144.png │ │ │ │ ├── apple-icon-60x60.png │ │ │ │ ├── apple-icon-72x72.png │ │ │ │ ├── arrow.svg │ │ │ │ ├── browserconfig.xml │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── favicon-96x96.png │ │ │ │ ├── manifest.json │ │ │ │ ├── ms-icon-144x144.png │ │ │ │ └── spinner.svg │ │ │ ├── img │ │ │ │ ├── argon.svg │ │ │ │ ├── bg1.jpg │ │ │ │ ├── blank.png │ │ │ │ ├── volume_high.svg │ │ │ │ └── volume_off.svg │ │ │ ├── js │ │ │ │ ├── jquery.min.js │ │ │ │ └── polyfill.min.js │ │ │ └── less │ │ │ │ ├── cascade.less │ │ │ │ └── dark.less │ │ │ └── resources │ │ │ └── menu.js │ ├── luasrc │ │ └── view │ │ │ └── themes │ │ │ └── argon │ │ │ ├── footer.htm │ │ │ ├── footer_login.htm │ │ │ ├── header.htm │ │ │ ├── header_login.htm │ │ │ ├── out_footer_login.htm │ │ │ ├── out_header_login.htm │ │ │ └── sysauth.htm │ └── root │ │ └── etc │ │ └── uci-defaults │ │ └── 30_luci-theme-argon └── tools │ └── po2lmo │ ├── Makefile │ └── src │ ├── po2lmo.c │ ├── template_lmo.c │ └── template_lmo.h ├── package ├── ipt2socks │ └── Makefile ├── n2n │ └── Makefile ├── redsocks2 │ └── Makefile ├── smartdns │ └── Makefile ├── v2ray │ ├── Config.in │ └── Makefile └── vlmcsd │ ├── Makefile │ └── files │ ├── vlmcsd.ini │ └── vlmcsd.init └── scripts ├── gettracker.sh ├── rmoldtorrent.sh ├── smartdnsGuard.sh └── tracker.list /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | /gmod.sublime-workspace 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openwrt-gmod 2 | 3 | 包含内容 4 | ------- 5 | ``` 6 | luci-app-smartdns 7 | luci-app-v2ray 8 | luci-proto-n2n 9 | n2n 10 | smartdns 11 | v2ray 12 | ``` 13 | ============== 14 | 15 | 安装 16 | ------- 17 | 18 | 把下面这行添加到你的 feeds.conf.default 文件首行 19 | 20 | src-git gmod https://github.com/ghostry/openwrt-gmod;openwrt-19.07 21 | 22 | 然后运行 23 | 24 | ./scripts/feeds update -a && ./scripts/feeds install -a 25 | 26 | ============== 27 | 28 | 文件来源 29 | ------- 30 | github.com,自己编写 31 | 32 | ============== 33 | -------------------------------------------------------------------------------- /gmod.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": "." 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # Copyright (C) 2015 GuoGuo 4 | # 5 | # 6 | # This is free software, licensed under the Apache License, Version 2.0 . 7 | # 8 | 9 | include $(TOPDIR)/rules.mk 10 | 11 | LUCI_TITLE:=LuCI Support for redsocks2 12 | LUCI_DEPENDS:=+redsocks2 13 | 14 | include $(TOPDIR)/feeds/luci/luci.mk 15 | 16 | # call BuildPackage - OpenWrt buildroot signature 17 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/README.md: -------------------------------------------------------------------------------- 1 | # Luci support for redsocks2 2 | 3 | 4 | ------- 5 | V0.1 6 | Add http and https support in luci. #http-relay and http-connect 7 | 8 | Forked from [Guoguo](https://github.com/981213) 9 | 10 | How to use 11 | 12 | Git clone https://github.com/hqvv/luci-app-redsocks2 13 | 14 | move luci-app-redsocks2 to feeds/luci/application 15 | 16 | move redsocks2 to ~/source/package 17 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/ipkg/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | [ -n "${IPKG_INSTROOT}" ] || { 3 | ( . /etc/uci-defaults/luci-redsocks2 ) && rm -f /etc/uci-defaults/luci-redsocks2 4 | chmod 755 /etc/init.d/redsocks2 >/dev/null 2>&1 5 | /etc/init.d/redsocks2 enable >/dev/null 2>&1 6 | exit 0 7 | } 8 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/luasrc/controller/redsocks2.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Redsocks2配置页面 Controller 3 | Copyright (C) 2015 GuoGuo 4 | ]]-- 5 | 6 | module("luci.controller.redsocks2", package.seeall) 7 | 8 | function index() 9 | 10 | if not nixio.fs.access("/etc/config/redsocks2") then 11 | return 12 | end 13 | 14 | entry({"admin", "services", "redsocks2"}, 15 | alias("admin", "services", "redsocks2", "general"), 16 | _("Redsocks2")) 17 | 18 | entry({"admin", "services", "redsocks2", "general"}, 19 | cbi("redsocks2/general"), 20 | _("General Settings"), 10).leaf = true 21 | 22 | entry({"admin", "services", "redsocks2", "advanced"}, 23 | cbi("redsocks2/advanced"), 24 | _("Advanced Options"), 20).leaf = true 25 | 26 | end 27 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/luasrc/model/cbi/redsocks2/advanced.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Redsocks2 高级配置页面 3 | Copyright (C) 2015 GuoGuo 4 | ]]-- 5 | 6 | m = Map("redsocks2", translate("Redsocks2 - Advanced Options")) 7 | 8 | s = m:section(TypedSection, "redsocks2_autoproxy", translate("Auto Proxy Options")) 9 | s.anonymous = true 10 | 11 | o = s:option(Value, "no_quick_check_seconds", translate("Direct Connect Timeout")) 12 | o.datatype = "uinteger" 13 | 14 | o = s:option(Value, "quick_connect_timeout", translate("Quick Check Timeout")) 15 | o.datatype = "uinteger" 16 | 17 | s = m:section(TypedSection, "redsocks2_ipcache", translate("IP Cache Options")) 18 | s.anonymous = true 19 | 20 | o = s:option(Value, "cache_size", translate("Max Cached Records(K)")) 21 | o.datatype = "uinteger" 22 | 23 | o = s:option(Value, "cache_file", translate("Cache File Path")) 24 | 25 | o = s:option(Value, "stale_time", translate("Stale Time")) 26 | o.datatype = "uinteger" 27 | 28 | o = s:option(Value, "autosave_interval", translate("Autosave Interval")) 29 | o.datatype = "uinteger" 30 | 31 | o = s:option(Flag, "port_check", translate("Enable Port-based IP Cache")) 32 | o.rmempty = false 33 | 34 | return m 35 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/luasrc/model/cbi/redsocks2/general.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Redsocks2 基础配置页面 3 | Copyright (C) 2015 GuoGuo 4 | ]]-- 5 | 6 | m = Map("redsocks2", translate("Redsocks2 - General Settings"), 7 | translatef("A modified version of redsocks.Beside the basic function of redsocks,it can redirect TCP connections which are blocked via proxy automatically without a blacklist.") 8 | ) 9 | 10 | s = m:section(TypedSection, "redsocks2_base", translate("Basic Settings")) 11 | s.anonymous = true 12 | o = s:option(Flag, "enabled", translate("Enable Redsocks2")) 13 | 14 | o = s:option(ListValue, "loglevel", translate("Log Level")) 15 | o:value("debug", translate("Verbose")) 16 | o:value("info", translate("Normal")) 17 | o:value("off", translate("Off")) 18 | 19 | s = m:section(TypedSection, "redsocks2_redirect", translate("Redirector Settings")) 20 | s.anonymous = true 21 | s.addremove = true 22 | 23 | o = s:option(Value, "local_ip", translate("Local IP")) 24 | o.datatype = "ip4addr" 25 | 26 | o = s:option(Value, "local_port", translate("Local Port")) 27 | o.datatype = "uinteger" 28 | 29 | o = s:option(Value, "ip", translate("Proxy Server IP")) 30 | o.datatype = "ip4addr" 31 | 32 | o = s:option(Value, "port", translate("Proxy Server Port")) 33 | o.datatype = "uinteger" 34 | 35 | o = s:option(ListValue, "proxy_type", translate("Proxy Server Type")) 36 | o:value("shadowsocks", translate("Shadowsocks")) 37 | o:value("socks5", translate("Socks5")) 38 | o:value("http-relay", translate("http-relay")) 39 | o:value("http-connect", translate("https")) 40 | o:value("direct", translate("Direct")) 41 | 42 | o = s:option(ListValue, "enc_type", translate("Cipher Method")) 43 | o:depends({proxy_type="shadowsocks"}) 44 | o:value("table") 45 | o:value("rc4") 46 | o:value("rc4-md5") 47 | o:value("aes-128-cfb") 48 | o:value("aes-192-cfb") 49 | o:value("aes-256-cfb") 50 | o:value("bf-cfb") 51 | o:value("cast5-cfb") 52 | o:value("des-cfb") 53 | o:value("camellia-128-cfb") 54 | o:value("camellia-192-cfb") 55 | o:value("camellia-256-cfb") 56 | o:value("idea-cfb") 57 | o:value("rc2-cfb") 58 | o:value("seed-cfb") 59 | 60 | o = s:option(Value, "username", translate("Username"), translate("Leave empty if your proxy server doesn't need authentication.")) 61 | o:depends({proxy_type="socks5"}) 62 | o:depends({proxy_type="http-relay"}) 63 | o:depends({proxy_type="http-connect"}) 64 | 65 | o = s:option(Value, "password", translate("Password")) 66 | o:depends({proxy_type="shadowsocks"}) 67 | o:depends({proxy_type="socks5"}) 68 | o:depends({proxy_type="http-relay"}) 69 | o:depends({proxy_type="http-connect"}) 70 | o.password = true 71 | 72 | o = s:option(Value, "interface", translate("Outgoing interface"), translate("Outgoing interface for redsocks2.")) 73 | o:depends({proxy_type="direct"}) 74 | 75 | o = s:option(Flag, "autoproxy", translate("Enable Auto Proxy")) 76 | o.rmempty = false 77 | 78 | o = s:option(Value, "timeout", translate("Timeout")) 79 | o:depends({autoproxy=1}) 80 | o.datatype = "uinteger" 81 | 82 | 83 | s = m:section(TypedSection, "redsocks2_udprelay", translate("UDP Relay")) 84 | s.anonymous = true 85 | s.addremove = true 86 | 87 | o = s:option(Value, "local_ip", translate("Local IP")) 88 | o.datatype = "ip4addr" 89 | 90 | o = s:option(Value, "local_port", translate("Local Port")) 91 | o.datatype = "uinteger" 92 | 93 | o = s:option(Value, "ip", translate("Proxy Server IP")) 94 | o.datatype = "ip4addr" 95 | 96 | o = s:option(Value, "port", translate("Proxy Server Port")) 97 | o.datatype = "uinteger" 98 | 99 | o = s:option(ListValue, "proxy_type", translate("Proxy Server Type")) 100 | o:value("shadowsocks", translate("Shadowsocks")) 101 | o:value("socks5", translate("Socks5")) 102 | o:value("http-relay", translate("http-relay")) 103 | o:value("http-connect", translate("https")) 104 | o:value("direct", translate("Direct")) 105 | 106 | o = s:option(ListValue, "enc_type", translate("Cipher Method")) 107 | o:depends({proxy_type="shadowsocks"}) 108 | o:value("table") 109 | o:value("rc4") 110 | o:value("rc4-md5") 111 | o:value("aes-128-cfb") 112 | o:value("aes-192-cfb") 113 | o:value("aes-256-cfb") 114 | o:value("bf-cfb") 115 | o:value("cast5-cfb") 116 | o:value("des-cfb") 117 | o:value("camellia-128-cfb") 118 | o:value("camellia-192-cfb") 119 | o:value("camellia-256-cfb") 120 | o:value("idea-cfb") 121 | o:value("rc2-cfb") 122 | o:value("seed-cfb") 123 | 124 | o = s:option(Value, "username", translate("Username"), translate("Leave empty if your proxy server doesn't need authentication.")) 125 | o:depends({proxy_type="socks5"}) 126 | o:depends({proxy_type="http-relay"}) 127 | o:depends({proxy_type="http-connect"}) 128 | 129 | o = s:option(Value, "password", translate("Password")) 130 | o:depends({proxy_type="shadowsocks"}) 131 | o:depends({proxy_type="http-relay"}) 132 | o:depends({proxy_type="http-connect"}) 133 | o:depends({proxy_type="socks5"}) 134 | o.password = true 135 | 136 | o = s:option(Value, "interface", translate("Outgoing interface"), translate("Outgoing interface for redsocks2.")) 137 | o:depends({proxy_type="direct"}) 138 | 139 | o = s:option(Value, "udp_timeout", translate("UDP Timeout")) 140 | o.datatype = "uinteger" 141 | 142 | o = s:option(Value, "dest_ip", translate("Destination IP")) 143 | o.datatype = "ip4addr" 144 | 145 | o = s:option(Value, "dest_port", translate("Destination Port")) 146 | o.datatype = "uinteger" 147 | 148 | s = m:section(TypedSection, "redsocks2_iptables", translate("Iptables Redirect Settings")) 149 | s.anonymous = true 150 | 151 | o = s:option(Flag, "blacklist_enabled", translate("Enable Blacklist"), translate("Specify local IP addresses which won't be redirect to redsocks2.")) 152 | o.rmempty = false 153 | 154 | o = s:option(Value, "ipset_blacklist", translate("Blacklist Path")) 155 | o:depends({blacklist_enabled=1}) 156 | 157 | o = s:option(Flag, "whitelist_enabled", translate("Enable Whitelist"), translate("Specify destination IP addresses which won't be redirect to redsocks2.")) 158 | o.rmempty = false 159 | 160 | o = s:option(Value, "ipset_whitelist", translate("Whitelist Path")) 161 | o:depends({whitelist_enabled=1}) 162 | 163 | o = s:option(Value, "dest_port", translate("Destination Port")) 164 | o.datatype = "uinteger" 165 | 166 | return m 167 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/po/zh-cn/redsocks2.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: \n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2015-04-21\n" 6 | "PO-Revision-Date: 2015-04-21 16:32+0800\n" 7 | "Last-Translator: 981213 \n" 8 | "Language: zh_CN\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "Plural-Forms: nplurals=1; plural=0;\n" 13 | "Language-Team: \n" 14 | "X-Generator: Poedit 1.7.5\n" 15 | 16 | msgid "Redsocks2 - General Settings" 17 | msgstr "Redsocks2 - 基础配置" 18 | 19 | msgid "A modified version of redsocks.Beside the basic function of redsocks,it can redirect TCP connections which are blocked via proxy automatically without a blacklist." 20 | msgstr "一个修改版redsocks.除了redsocks本来的功能之外,redsocks2可以在不需要黑名单的情况下自动判断被封锁的IP并且使用代理服务器建立连接." 21 | 22 | msgid "Basic Settings" 23 | msgstr "基础设置" 24 | 25 | msgid "Advanced Options" 26 | msgstr "高级选项" 27 | 28 | msgid "Enable Port-based IP Cache" 29 | msgstr "启用基于端口的IP缓存" 30 | 31 | msgid "Enable Redsocks2" 32 | msgstr "启用Redsocks2" 33 | 34 | msgid "Log Level" 35 | msgstr "日志等级" 36 | 37 | msgid "Verbose" 38 | msgstr "调试" 39 | 40 | msgid "Normal" 41 | msgstr "正常" 42 | 43 | msgid "Off" 44 | msgstr "关闭" 45 | 46 | msgid "Redirector Settings" 47 | msgstr "透明代理设置" 48 | 49 | msgid "Local IP" 50 | msgstr "本地IP" 51 | 52 | msgid "Local Port" 53 | msgstr "本地端口" 54 | 55 | msgid "Proxy Server IP" 56 | msgstr "代理服务器IP" 57 | 58 | msgid "Proxy Server Port" 59 | msgstr "代理服务器端口" 60 | 61 | msgid "Proxy Server Type" 62 | msgstr "代理服务器类型" 63 | 64 | msgid "Shadowsocks" 65 | msgstr "Shadowsocks代理" 66 | 67 | msgid "Socks5" 68 | msgstr "Socks5代理" 69 | 70 | msgid "Direct" 71 | msgstr "直接连接" 72 | 73 | msgid "Cipher Method" 74 | msgstr "加密方式" 75 | 76 | msgid "Username" 77 | msgstr "用户名" 78 | 79 | msgid "Leave empty if your proxy server doesn't need authentication." 80 | msgstr "如果代理服务器不需要验证,请将此项留空." 81 | 82 | msgid "Password" 83 | msgstr "密码" 84 | 85 | msgid "Outgoing interface" 86 | msgstr "出口" 87 | 88 | msgid "Outgoing interface for redsocks2." 89 | msgstr "Redsocks2直连使用的外部接口" 90 | 91 | msgid "Enable Auto Proxy" 92 | msgstr "启用自动代理" 93 | 94 | msgid "Timeout" 95 | msgstr "自动代理超时" 96 | 97 | msgid "UDP Relay" 98 | msgstr "UDP转发" 99 | 100 | msgid "UDP Timeout" 101 | msgstr "UDP超时" 102 | 103 | msgid "Destination IP" 104 | msgstr "目标IP" 105 | 106 | msgid "Destination Port" 107 | msgstr "目标端口" 108 | 109 | msgid "Iptables Redirect Settings" 110 | msgstr "iptables重定向设置" 111 | 112 | msgid "Enable Blacklist" 113 | msgstr "启用排除IP" 114 | 115 | msgid "Specify local IP addresses which won't be redirect to redsocks2." 116 | msgstr "指定不会经过透明代理的本地IP地址" 117 | 118 | msgid "Blacklist Path" 119 | msgstr "排除IP列表路径" 120 | 121 | msgid "Enable Whitelist" 122 | msgstr "启用白名单" 123 | 124 | msgid "Specify destination IP addresses which won't be redirect to redsocks2." 125 | msgstr "指定不会被重定向到redsocks2的目标IP." 126 | 127 | msgid "Whitelist Path" 128 | msgstr "白名单路径" 129 | 130 | msgid "Redsocks2 - Advanced Options" 131 | msgstr "Redsocks2 - 高级选项" 132 | 133 | msgid "Auto Proxy Options" 134 | msgstr "自动代理配置" 135 | 136 | msgid "Direct Connect Timeout" 137 | msgstr "直连时间" 138 | 139 | msgid "Quick Check Timeout" 140 | msgstr "快速检查模式超时" 141 | 142 | msgid "IP Cache Options" 143 | msgstr "IP缓存选项" 144 | 145 | msgid "Max Cached Records(K)" 146 | msgstr "缓存记录数量(千条)" 147 | 148 | msgid "Cache File Path" 149 | msgstr "缓存文件路径" 150 | 151 | msgid "Stale Time" 152 | msgstr "缓存有效时间" 153 | 154 | msgid "Autosave Interval" 155 | msgstr "自动保存时间间隔" 156 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/root/etc/config/redsocks2: -------------------------------------------------------------------------------- 1 | config redsocks2_base 2 | option enabled '0' 3 | option loglevel 'info' 4 | 5 | config redsocks2_redirect 6 | option local_ip 0.0.0.0 7 | option local_port 11111 8 | option ip 1.2.3.4 9 | option port 1234 10 | option proxy_type shadowsocks 11 | option autoproxy 1 12 | option timeout 3 13 | option enc_type rc4-md5 14 | option password foobar 15 | 16 | config redsocks2_autoproxy 17 | option no_quick_check_seconds 300 18 | option quick_connect_timeout 2 19 | 20 | config redsocks2_ipcache 21 | option cache_size 4 22 | option cache_file '/tmp/redsocks2_ipcache.txt' 23 | option stale_time 7200 24 | option autosave_interval 3600 25 | option port_check 0 26 | 27 | config redsocks2_udprelay 28 | option local_ip 0.0.0.0 29 | option local_port 1153 30 | option ip 1.2.3.4 31 | option port 1234 32 | option proxy_type shadowsocks 33 | option udp_timeout 3 34 | option enc_type rc4-md5 35 | option password foobar 36 | option dest_ip 8.8.8.8 37 | option dest_port 53 38 | 39 | config redsocks2_iptables 40 | option blacklist_enabled '0' 41 | option whitelist_enabled '1' 42 | option ipset_whitelist '/etc/chnroute.txt' 43 | option dest_port 11111 44 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/root/etc/init.d/redsocks2: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # Copyright (C) 2015 GuoGuo 3 | # Redsocks2 启动脚本 4 | START=90 5 | APP=redsocks2 6 | PID_FILE=/var/run/$APP.pid 7 | CFG_FILE=/var/etc/redsocks2.conf 8 | 9 | #程序是否启用 CFG_TYPE=redsocks2_base 10 | if_enabled() { 11 | local cfg="$1" 12 | config_get_bool enabled "$cfg" 'enabled' '0' 13 | [ $enabled = '0' ] && { 14 | echo "redsocks2 is not enabled.Exit now." 15 | exit 1 16 | } 17 | } 18 | 19 | #基础配置生成 CFG_TYPE=redsocks2_base 20 | gen_config_base() { 21 | local cfg="$1" 22 | 23 | echo "base {" > $CFG_FILE 24 | 25 | config_get loglevel "$cfg" 'loglevel' 26 | case "$loglevel" in 27 | debug) 28 | echo "log_debug = on;" >> $CFG_FILE 29 | echo "log_info = on;" >> $CFG_FILE 30 | ;; 31 | info) 32 | echo "log_debug = off;" >> $CFG_FILE 33 | echo "log_info = on;" >> $CFG_FILE 34 | ;; 35 | off) 36 | echo "log_debug = off;" >> $CFG_FILE 37 | echo "log_info = off;" >> $CFG_FILE 38 | esac 39 | echo "daemon = on;" >> $CFG_FILE 40 | echo "redirector = iptables;" >> $CFG_FILE 41 | echo "}" >> $CFG_FILE 42 | } 43 | 44 | #重定向配置文件生成. CFG_TYPE=redsocks2_redirect 45 | gen_config_redirect() { 46 | local cfg="$1" 47 | 48 | config_get local_ip "$cfg" 'local_ip' 49 | config_get local_port "$cfg" 'local_port' 50 | config_get ip "$cfg" 'ip' 51 | config_get port "$cfg" 'port' 52 | #代理类型,可选值 socks5 shadowsocks direct 53 | config_get proxy_type "$cfg" 'proxy_type' 54 | config_get_bool autoproxy "$cfg" 'autoproxy' 0 55 | config_get timeout "$cfg" 'timeout' 56 | config_get redsocks2_login "$cfg" 'enc_type' 57 | [ -z $redsocks2_login ] && config_get redsocks2_login "$cfg" 'username' 58 | config_get redsocks2_password "$cfg" 'password' 59 | cat >> $CFG_FILE <> $CFG_FILE 69 | case $proxy_type in 70 | socks5 | \ 71 | shadowsocks) 72 | [ ! -z $redsocks2_login ] && { 73 | echo "login = \"$redsocks2_login\";" >> $CFG_FILE 74 | echo "password = \"$redsocks2_password\";" >> $CFG_FILE 75 | } 76 | ;; 77 | direct) 78 | config_get interface "$cfg" 'interface' 79 | [ ! -z $interface ] && echo "interface = $interface;" >> $CFG_FILE 80 | ;; 81 | esac 82 | echo "}" >> $CFG_FILE 83 | } 84 | 85 | #自动代理判断高级设置 CFG_TYPE=redsocks2_autoproxy 86 | gen_config_autoproxy() { 87 | local cfg="$1" 88 | config_get no_quick_check_seconds "$cfg" 'no_quick_check_seconds' 300 89 | config_get quick_connect_timeout "$cfg" 'quick_connect_timeout' 2 90 | cat >> $CFG_FILE <> $CFG_FILE <> $CFG_FILE <> $CFG_FILE 150 | echo "password = \"$redsocks2_password\";" >> $CFG_FILE 151 | } 152 | ;; 153 | direct) 154 | config_get interface "$cfg" 'interface' 155 | [ ! -z $interface ] && echo "interface = $interface;" >> $CFG_FILE 156 | ;; 157 | esac 158 | echo "}" >> $CFG_FILE 159 | } 160 | 161 | #redsocks2 iptables流量劫持设定 CFG_TYPE=redsocks2_iptables 162 | redsocks2_iptables_start_instance() { 163 | local cfg="$1" 164 | 165 | local CHAIN_NAME="REDSOCKS2_$cfg" 166 | config_get blacklist_enabled "$cfg" 'blacklist_enabled' 167 | config_get ipset_blacklist "$cfg" 'ipset_blacklist' 168 | config_get whitelist_enabled "$cfg" 'whitelist_enabled' 169 | config_get ipset_whitelist "$cfg" 'ipset_whitelist' 170 | config_get dest_port "$cfg" 'dest_port' 171 | 172 | iptables -t nat -N $CHAIN_NAME 173 | iptables -t nat -A $CHAIN_NAME -d 0.0.0.0/8 -j RETURN 174 | iptables -t nat -A $CHAIN_NAME -d 10.0.0.0/8 -j RETURN 175 | iptables -t nat -A $CHAIN_NAME -d 127.0.0.0/8 -j RETURN 176 | iptables -t nat -A $CHAIN_NAME -d 169.254.0.0/16 -j RETURN 177 | iptables -t nat -A $CHAIN_NAME -d 172.16.0.0/12 -j RETURN 178 | iptables -t nat -A $CHAIN_NAME -d 192.168.0.0/16 -j RETURN 179 | iptables -t nat -A $CHAIN_NAME -d 224.0.0.0/4 -j RETURN 180 | iptables -t nat -A $CHAIN_NAME -d 240.0.0.0/4 -j RETURN 181 | 182 | [ "$blacklist_enabled" = '1' ] && { 183 | sed -e "s/^/-A blacklist &/g" -e "1 i\-N blacklist nethash --hashsize 64" $ipset_blacklist | ipset -R -! 184 | iptables -t nat -A $CHAIN_NAME -p tcp -m set --match-set blacklist src -j RETURN 185 | } 186 | if [ "$whitelist_enabled" = '1' ];then 187 | sed -e "s/^/-A whitelist &/g" -e "1 i\-N whitelist nethash --hashsize 4096" $ipset_whitelist | ipset -R -! 188 | iptables -t nat -A $CHAIN_NAME -p tcp -m set ! --match-set whitelist dst -j REDIRECT --to-ports "$dest_port" 189 | else 190 | iptables -t nat -A $CHAIN_NAME -p tcp -j REDIRECT --to-ports "$dest_port" 191 | fi 192 | 193 | iptables -t nat -I zone_lan_prerouting -j $CHAIN_NAME 194 | } 195 | 196 | redsocks2_iptables_stop_instance() { 197 | local cfg="$1" 198 | 199 | local CHAIN_NAME="REDSOCKS2_$cfg" 200 | 201 | iptables -t nat -D zone_lan_prerouting -j $CHAIN_NAME &> /dev/null 202 | iptables -t nat -F $CHAIN_NAME &> /dev/null 203 | sleep 1 204 | iptables -t nat -X $CHAIN_NAME &> /dev/null 205 | ipset destroy whitelist &> /dev/null 206 | ipset destroy blacklist &> /dev/null 207 | } 208 | 209 | start() { 210 | 211 | config_load 'redsocks2' 212 | config_foreach if_enabled 'redsocks2_base' 213 | 214 | config_foreach gen_config_base 'redsocks2_base' 215 | config_foreach gen_config_redirect 'redsocks2_redirect' 216 | config_foreach gen_config_autoproxy 'redsocks2_autoproxy' 217 | config_foreach gen_config_ipcache 'redsocks2_ipcache' 218 | config_foreach gen_config_udprelay 'redsocks2_udprelay' 219 | 220 | service_start /usr/sbin/redsocks2 -c $CFG_FILE -p $PID_FILE 221 | 222 | config_foreach redsocks2_iptables_start_instance 'redsocks2_iptables' 223 | } 224 | 225 | stop() { 226 | config_load 'redsocks2' 227 | service_stop /usr/sbin/redsocks2 && rm -rf $PID_FILE 228 | config_foreach redsocks2_iptables_stop_instance 'redsocks2_iptables' 229 | } 230 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/root/etc/uci-defaults/luci-redsocks2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete ucitrack.@redsocks2[-1] 5 | add ucitrack redsocks2 6 | set ucitrack.@redsocks2[-1].init=redsocks2 7 | commit ucitrack 8 | delete firewall.redsocks2 9 | set firewall.redsocks2=include 10 | set firewall.redsocks2.type=script 11 | set firewall.redsocks2.path=/usr/share/redsocks2/firewall.include 12 | set firewall.redsocks2.reload=1 13 | commit firewall 14 | EOF 15 | 16 | rm -f /tmp/luci-indexcache 17 | exit 0 18 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/root/usr/share/redsocks2/firewall.include: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /etc/init.d/redsocks2 restart 3 | -------------------------------------------------------------------------------- /luci/luci-app-redsocks2/root/usr/share/rpcd/acl.d/luci-app-redsocks2.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-redsocks2": { 3 | "description": "Grant UCI access for luci-app-redsocks2", 4 | "read": { 5 | "uci": [ "redsocks2" ] 6 | }, 7 | "write": { 8 | "uci": [ "redsocks2" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /luci/luci-app-smartdns/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Gmod 3 | # 4 | # This is free software, licensed under the GNU General Public License v3. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=luci-app-smartdns 11 | PKG_VERSION:=1.2021.08 12 | PKG_RELEASE:=1 13 | 14 | PKG_LICENSE:=GPLv3 15 | PKG_LICENSE_FILES:=LICENSE 16 | PKG_MAINTAINER:=pymumu ,ghostry 17 | 18 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) 19 | 20 | include $(INCLUDE_DIR)/package.mk 21 | 22 | define Package/luci-app-smartdns 23 | SECTION:=luci 24 | CATEGORY:=Gmod 25 | SUBMENU:=Luci 26 | TITLE:=SmartDNS LuCI interface 27 | PKGARCH:=all 28 | DEPENDS:=+smartdns 29 | endef 30 | 31 | 32 | define Package/luci-app-smartdns/description 33 | LuCI Support for cdns. 34 | endef 35 | 36 | define Build/Prepare 37 | endef 38 | 39 | define Build/Configure 40 | endef 41 | 42 | define Build/Compile 43 | endef 44 | 45 | define Package/luci-app-smartdns/install 46 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n 47 | $(INSTALL_DATA) ./files/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo $(1)/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo 48 | $(INSTALL_DIR) $(1)/usr/share/luci/menu.d 49 | $(INSTALL_DATA) ./files/usr/share/luci/menu.d/luci-app-smartdns.json $(1)/usr/share/luci/menu.d/luci-app-smartdns.json 50 | $(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d 51 | $(INSTALL_DATA) ./files/usr/share/rpcd/acl.d/luci-app-smartdns.json $(1)/usr/share/rpcd/acl.d 52 | $(INSTALL_DIR) $(1)/www/luci-static/resources/view/smartdns 53 | $(INSTALL_DATA) ./files/www/luci-static/resources/view/smartdns/smartdns.js $(1)/www/luci-static/resources/view/smartdns 54 | endef 55 | 56 | $(eval $(call BuildPackage,luci-app-smartdns)) 57 | -------------------------------------------------------------------------------- /luci/luci-app-smartdns/files/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-smartdns/files/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo -------------------------------------------------------------------------------- /luci/luci-app-smartdns/files/usr/share/luci/menu.d/luci-app-smartdns.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin/services/smartdns": { 3 | "title": "SmartDNS", 4 | "action": { 5 | "type": "view", 6 | "path": "smartdns/smartdns" 7 | }, 8 | "depends": { 9 | "acl": [ "luci-app-smartdns" ], 10 | "uci": { "smartdns": true } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /luci/luci-app-smartdns/files/usr/share/rpcd/acl.d/luci-app-smartdns.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-smartdns": { 3 | "description": "Grant access to LuCI app smartdns", 4 | "read": { 5 | "file": { 6 | "/etc/smartdns/*": [ "read" ], 7 | "/usr/sbin/iptables -t nat -nL PREROUTING": [ "exec" ], 8 | "/usr/sbin/ip6tables -t nat -nL PREROUTING": [ "exec" ], 9 | "/usr/sbin/smartdns": [ "exec" ] 10 | }, 11 | "ubus": { 12 | "service": [ "list" ] 13 | }, 14 | "uci": [ "smartdns" ] 15 | }, 16 | "write": { 17 | "file": { 18 | "/etc/smartdns/*": [ "write" ] 19 | }, 20 | "uci": [ "smartdns" ] 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2020 Lienol 2 | # 3 | # This is free software, licensed under the GNU General Public License v3. 4 | # 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | PKG_NAME:=luci-app-v2ray-server 9 | LUCI_TITLE:=LuCI support for V2ray Server 10 | LUCI_DEPENDS:=+unzip 11 | LUCI_PKGARCH:=all 12 | PKG_VERSION:=13 13 | PKG_RELEASE:=1 14 | 15 | include $(TOPDIR)/feeds/luci/luci.mk 16 | 17 | # call BuildPackage - OpenWrt buildroot signature 18 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/controller/v2ray_server.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2018-2019 Lienol 2 | module("luci.controller.v2ray_server", package.seeall) 3 | local http = require "luci.http" 4 | local v2ray = require "luci.model.cbi.v2ray_server.api.v2ray" 5 | 6 | function index() 7 | if not nixio.fs.access("/etc/config/v2ray_server") then 8 | return 9 | end 10 | 11 | entry({"admin", "services", "v2ray_server"}, cbi("v2ray_server/index"), _("V2ray Server"), 3).dependent = true 12 | entry({"admin", "services", "v2ray_server", "config"}, cbi("v2ray_server/user")).leaf = true 13 | entry({"admin", "services", "v2ray_server", "users_status"}, call("users_status")).leaf = true 14 | entry({"admin", "services", "v2ray_server", "check"}, call("v2ray_check")).leaf = true 15 | entry({"admin", "services", "v2ray_server", "update"}, call("v2ray_update")).leaf = true 16 | entry({"admin", "services", "v2ray_server", "get_log"}, call("get_log")).leaf = true 17 | entry({"admin", "services", "v2ray_server", "clear_log"}, call("clear_log")).leaf = true 18 | end 19 | 20 | local function http_write_json(content) 21 | http.prepare_content("application/json") 22 | http.write_json(content or {code = 1}) 23 | end 24 | 25 | function get_log() 26 | luci.http.write(luci.sys.exec("[ -f '/var/log/v2ray_server/app.log' ] && cat /var/log/v2ray_server/app.log")) 27 | end 28 | 29 | function clear_log() 30 | luci.sys.call("echo '' > /var/log/v2ray_server/app.log") 31 | end 32 | 33 | function users_status() 34 | local e = {} 35 | e.index = luci.http.formvalue("index") 36 | e.status = luci.sys.call("ps -w| grep -v grep | grep '/var/etc/v2ray_server/" .. luci.http.formvalue("id") .. "' >/dev/null") == 0 37 | http_write_json(e) 38 | end 39 | 40 | function v2ray_check() 41 | local json = v2ray.to_check("") 42 | http_write_json(json) 43 | end 44 | 45 | function v2ray_update() 46 | local json = nil 47 | local task = http.formvalue("task") 48 | if task == "extract" then 49 | json = 50 | v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix")) 51 | elseif task == "move" then 52 | json = v2ray.to_move(http.formvalue("file")) 53 | else 54 | json = v2ray.to_download(http.formvalue("url")) 55 | end 56 | 57 | http_write_json(json) 58 | end 59 | 60 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/api/app.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/lua 2 | 3 | local action = arg[1] 4 | local sys = require 'luci.sys' 5 | local jsonc = require "luci.jsonc" 6 | local ucic = require"luci.model.uci".cursor() 7 | 8 | local CONFIG = "v2ray_server" 9 | local CONFIG_PATH = "/var/etc/" .. CONFIG 10 | local LOG_PATH = "/var/log/" .. CONFIG 11 | local LOG_APP_FILE = LOG_PATH .. "/app.log" 12 | local BIN_PATH = "/var/bin/" 13 | local BIN_PATH_FILE = BIN_PATH .. CONFIG 14 | 15 | local function log(...) 16 | local f, err = io.open(LOG_APP_FILE, "a") 17 | if f and err == nil then 18 | local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") 19 | f:write(str .. "\n") 20 | f:close() 21 | end 22 | end 23 | 24 | local function cmd(cmd) 25 | sys.call(cmd) 26 | end 27 | 28 | local function gen_include() 29 | cmd(string.format("echo '#!/bin/sh' > /var/etc/%s.include", CONFIG)) 30 | local function extract_rules(a) 31 | local result = "*" .. a 32 | result = result .. "\n" .. sys.exec('iptables-save -t ' .. a .. ' | grep "V2RAY-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"') 33 | result = result .. "COMMIT" 34 | return result 35 | end 36 | local f, err = io.open("/var/etc/" .. CONFIG .. ".include", "a") 37 | if f and err == nil then 38 | f:write('iptables-save -c | grep -v "V2RAY-SERVER" | iptables-restore -c' .. "\n") 39 | f:write('iptables-restore -n <<-EOT' .. "\n") 40 | f:write(extract_rules("filter") .. "\n") 41 | f:write("EOT" .. "\n") 42 | f:close() 43 | end 44 | end 45 | 46 | local function start() 47 | local enabled = tonumber(ucic:get(CONFIG, "@global[0]", "enable") or 0) 48 | if enabled == nil or enabled == 0 then 49 | return 50 | end 51 | cmd(string.format("mkdir -p %s %s", CONFIG_PATH, LOG_PATH)) 52 | cmd(string.format("touch %s", LOG_APP_FILE)) 53 | cmd("iptables -N V2RAY-SERVER") 54 | cmd("iptables -I INPUT -j V2RAY-SERVER") 55 | ucic:foreach(CONFIG, "user", function(user) 56 | local id = user[".name"] 57 | local enable = user.enable 58 | if enable and tonumber(enable) == 1 then 59 | local remarks = user.remarks 60 | local port = tonumber(user.port) 61 | if nixio.fs.access("/usr/bin/xray") and not nixio.fs.access(BIN_PATH_FILE) then 62 | cmd(string.format("mkdir -p %s", BIN_PATH)) 63 | cmd(string.format("cp -a /usr/bin/xray %s", BIN_PATH_FILE)) 64 | end 65 | local bin = BIN_PATH_FILE 66 | local config = {} 67 | local config_file = CONFIG_PATH .. "/" .. id .. ".json" 68 | 69 | config = require("luci.model.cbi.v2ray_server.api.gen_config").gen_config(user) 70 | bin = bin .. " -config " .. config_file 71 | 72 | if next(config) then 73 | local f, err = io.open(config_file, "w") 74 | if f and err == nil then 75 | f:write(jsonc.stringify(config, 1)) 76 | f:close() 77 | end 78 | log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file)) 79 | end 80 | 81 | if bin then 82 | cmd(bin .. ">/dev/null 2>&1 &") 83 | end 84 | 85 | local bind_local = user.bind_local or 0 86 | if bind_local and tonumber(bind_local) ~= 1 then 87 | cmd(string.format('iptables -A V2RAY-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) 88 | cmd(string.format('iptables -A V2RAY-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) 89 | end 90 | end 91 | end) 92 | gen_include() 93 | end 94 | 95 | local function stop() 96 | cmd(string.format("ps -w | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &", CONFIG_PATH)) 97 | cmd("iptables -D INPUT -j V2RAY-SERVER 2>/dev/null") 98 | cmd("iptables -F V2RAY-SERVER 2>/dev/null") 99 | cmd("iptables -X V2RAY-SERVER 2>/dev/null") 100 | cmd(string.format("rm -rf %s %s /var/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG)) 101 | end 102 | 103 | if action then 104 | if action == "start" then 105 | start() 106 | elseif action == "stop" then 107 | stop() 108 | end 109 | end -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/index.lua: -------------------------------------------------------------------------------- 1 | local ds = require "luci.dispatcher" 2 | local o = "v2ray_server" 3 | 4 | m = Map(o, translate("V2ray Server")) 5 | 6 | t = m:section(TypedSection, "global", translate("Global Settings")) 7 | t.anonymous = true 8 | t.addremove = false 9 | e = t:option(Flag, "enable", translate("Enable")) 10 | e.rmempty = false 11 | t:append(Template("v2ray_server/v2ray")) 12 | 13 | t = m:section(TypedSection, "user", translate("Users Manager")) 14 | t.anonymous = true 15 | t.addremove = true 16 | t.template = "cbi/tblsection" 17 | t.extedit = ds.build_url("admin", "services", o, "config", "%s") 18 | function t.create(t, e) 19 | local uuid = luci.sys.exec("echo -n $(cat /proc/sys/kernel/random/uuid)") or "" 20 | uuid = string.gsub(uuid, "-", "") 21 | local e = TypedSection.create(t, uuid) 22 | luci.http.redirect(ds.build_url("admin", "services", o, "config", uuid)) 23 | end 24 | function t.remove(t, a) 25 | t.map.proceed = true 26 | t.map:del(a) 27 | luci.http.redirect(ds.build_url("admin", "services", o)) 28 | end 29 | 30 | e = t:option(Flag, "enable", translate("Enable")) 31 | e.width = "5%" 32 | e.rmempty = false 33 | 34 | e = t:option(DummyValue, "status", translate("Status")) 35 | e.rawhtml = true 36 | e.cfgvalue = function(t, n) 37 | return string.format('%s', n, translate("Collecting data...")) 38 | end 39 | 40 | e = t:option(DummyValue, "remarks", translate("Remarks")) 41 | 42 | e = t:option(DummyValue, "port", translate("Port")) 43 | e.width = "10%" 44 | 45 | e = t:option(DummyValue, "protocol", translate("Protocol")) 46 | e.cfgvalue = function(self, section) 47 | local str = "未知" 48 | local protocol = m:get(section, "protocol") or "" 49 | if protocol ~= "" then str = (protocol:gsub("^%l", string.upper)) end 50 | return str 51 | end 52 | 53 | m:append(Template("v2ray_server/log")) 54 | 55 | m:append(Template("v2ray_server/users_list_status")) 56 | return m 57 | 58 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/view/v2ray_server/log.htm: -------------------------------------------------------------------------------- 1 | 25 |
26 | 27 | <%:Logs%> 28 | 29 | 30 | 31 |
-------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/view/v2ray_server/users_list_status.htm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/luasrc/view/v2ray_server/v2ray.htm: -------------------------------------------------------------------------------- 1 | <% 2 | local v2ray_version=luci.sys.exec("/usr/bin/xray -version | awk '{print $2}' | sed -n 1P") 3 | -%> 4 | 5 | 172 | 173 |
174 | 177 |
178 |
179 | 【 <%=v2ray_version%>】 180 | 181 | 182 |
183 |
184 |
-------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/po/zh-cn/v2ray_server.po: -------------------------------------------------------------------------------- 1 | msgid "V2ray Server" 2 | msgstr "V2ray 服务器" 3 | 4 | msgid "Global Settings" 5 | msgstr "全局设置" 6 | 7 | msgid "Caddy path" 8 | msgstr "Caddy 路径" 9 | 10 | msgid "if you want to run from memory, change the path, such as /tmp/caddy, Then save the application and update it manually." 11 | msgstr "如果你希望从内存中运行,请更改路径,例如/tmp/caddy,然后保存应用后,再手动更新。" 12 | 13 | msgid "Server Config" 14 | msgstr "服务器配置" 15 | 16 | msgid "Users Manager" 17 | msgstr "用户管理" 18 | 19 | msgid "Remarks" 20 | msgstr "备注" 21 | 22 | msgid "Bind Local" 23 | msgstr "本机监听" 24 | 25 | msgid "When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies." 26 | msgstr "当勾选时,只能由本机访问此端口,当开启反向代理时建议勾选此项。" 27 | 28 | msgid "Port" 29 | msgstr "端口" 30 | 31 | msgid "User name" 32 | msgstr "用户名" 33 | 34 | msgid "Password" 35 | msgstr "密码" 36 | 37 | msgid "Protocol" 38 | msgstr "协议" 39 | 40 | msgid "Null" 41 | msgstr "无" 42 | 43 | msgid "Alter ID" 44 | msgstr "额外ID(AlterID)" 45 | 46 | msgid "User Level" 47 | msgstr "用户等级(Level)" 48 | 49 | msgid "When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption." 50 | msgstr "开启 OTA 后,V2Ray 会拒绝未启用 OTA 的连接。当使用 AEAD 加密时,该选项无效。" 51 | 52 | msgid "Transport" 53 | msgstr "传输方式" 54 | 55 | msgid "Camouflage Type" 56 | msgstr "伪装类型" 57 | 58 | msgid "Camouflage Domain,you can not fill in" 59 | msgstr "伪装域名,也可以不填写" 60 | 61 | msgid "Reverse Proxy" 62 | msgstr "反向代理" 63 | 64 | msgid "Reverse Proxy Type" 65 | msgstr "反向代理类型" 66 | 67 | msgid "can not has conflict" 68 | msgstr "请不要冲突" 69 | 70 | msgid "Use HTTPS" 71 | msgstr "使用HTTPS" 72 | 73 | msgid "TLS Settings" 74 | msgstr "TLS配置" 75 | 76 | msgid "Nginx does not support HTTP/2 reverse proxies" 77 | msgstr "Nginx 不支持HTTP/2反向代理" 78 | 79 | msgid "as:" 80 | msgstr "如:" 81 | 82 | msgid "Public key absolute path" 83 | msgstr "公钥文件绝对路径" 84 | 85 | msgid "Private key absolute path" 86 | msgstr "私钥文件绝对路径" 87 | 88 | msgid "
none: default, no masquerade, data sent is packets with no characteristics.
srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).
utp: packets disguised as uTP will be recognized as bittorrent downloaded data.
wechat-video: packets disguised as WeChat video calls.
dtls: disguised as DTLS 1.2 packet.
wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)" 89 | msgstr "
none:默认值,不进行伪装,发送的数据是没有特征的数据包。
srtp:伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
utp:伪装成 uTP 数据包,会被识别为 BT 下载数据。
wechat-video:伪装成微信视频通话的数据包。
dtls:伪装成 DTLS 1.2 数据包。
wireguard:伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)" 90 | 91 | msgid "transit node" 92 | msgstr "中转到此节点" 93 | 94 | msgid "This is the node inside passwall, which you can't use if you don't have it installed." 95 | msgstr "这里显示的是passwall里的节点,如果没有安装,将无法使用此功能。" 96 | 97 | msgid "Accept LAN Access" 98 | msgstr "接受局域网访问" 99 | 100 | msgid "When selected, it can accessed lan , this will not be safe!" 101 | msgstr "当勾选时,可以直接访问局域网,这将不安全!(非特殊情况不建议开启)" 102 | 103 | msgid "Logs" 104 | msgstr "日志" 105 | 106 | msgid "Clear logs" 107 | msgstr "清空日志" 108 | 109 | msgid "Can't determine ARCH, or ARCH not supported." 110 | msgstr "无法确认ARCH架构,或是不支持。" 111 | 112 | msgid "Get remote version info failed." 113 | msgstr "获取远程版本信息失败。" 114 | 115 | msgid "New version found, but failed to get new version download url." 116 | msgstr "发现新版本,但未能获得新版本的下载地址。" 117 | 118 | msgid "Download url is required." 119 | msgstr "请指定下载地址。" 120 | 121 | msgid "File download failed or timed out: %s" 122 | msgstr "文件下载失败或超时:%s" 123 | 124 | msgid "File path required." 125 | msgstr "请指定文件路径。" 126 | 127 | msgid "Can't find client in file: %s" 128 | msgstr "无法在文件中找到客户端:%s" 129 | 130 | msgid "Client file is required." 131 | msgstr "请指定客户端文件。" 132 | 133 | msgid "The client file is not suitable for current device." 134 | msgstr "客户端文件不适合当前设备。" 135 | 136 | msgid "Can't move new file to path: %s" 137 | msgstr "无法移动新文件到:%s" 138 | 139 | msgid "Update..." 140 | msgstr "更新中" 141 | 142 | msgid "It is the latest version" 143 | msgstr "已是最新版本" 144 | 145 | msgid "Update successful" 146 | msgstr "更新成功" 147 | 148 | msgid "Click to update" 149 | msgstr "点击更新" 150 | 151 | msgid "Updating..." 152 | msgstr "更新中" 153 | 154 | msgid "Unexpected error" 155 | msgstr "意外错误" 156 | 157 | msgid "Updating, are you sure to close?" 158 | msgstr "正在更新,你确认要关闭吗?" 159 | 160 | msgid "Downloading..." 161 | msgstr "下载中" 162 | 163 | msgid "Unpacking..." 164 | msgstr "解压中" 165 | 166 | msgid "Moving..." 167 | msgstr "移动中" 168 | 169 | msgid "Enabled" 170 | msgstr "启用" 171 | 172 | msgid "Status" 173 | msgstr "状态" 174 | 175 | msgid "Current Condition" 176 | msgstr "当前状态" 177 | 178 | msgid "NOT RUNNING" 179 | msgstr "未运行" 180 | 181 | msgid "RUNNING" 182 | msgstr "运行中" -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/root/etc/config/v2ray_server: -------------------------------------------------------------------------------- 1 | 2 | config global 3 | option enable '0' 4 | 5 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/root/etc/init.d/v2ray_server: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=99 4 | 5 | start() { 6 | /usr/lib/lua/luci/model/cbi/v2ray_server/api/app.lua start 7 | } 8 | 9 | stop() { 10 | /usr/lib/lua/luci/model/cbi/v2ray_server/api/app.lua stop 11 | } 12 | 13 | restart() { 14 | stop 15 | start 16 | } 17 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/root/etc/uci-defaults/luci-v2ray-server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete firewall.v2ray_server 5 | set firewall.v2ray_server=include 6 | set firewall.v2ray_server.type=script 7 | set firewall.v2ray_server.path=/var/etc/v2ray_server.include 8 | set firewall.v2ray_server.reload=1 9 | commit firewall 10 | EOF 11 | 12 | uci -q batch <<-EOF >/dev/null 13 | delete ucitrack.@v2ray_server[-1] 14 | add ucitrack v2ray_server 15 | set ucitrack.@v2ray_server[-1].init=v2ray_server 16 | commit ucitrack 17 | EOF 18 | 19 | rm -rf /tmp/luci-*cache 20 | exit 0 21 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray-server/root/usr/share/rpcd/acl.d/luci-app-v2ray-server.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-v2ray-server": { 3 | "description": "Grant UCI access for luci-app-v2ray-server", 4 | "read": { 5 | "uci": [ "v2ray_server" ] 6 | }, 7 | "write": { 8 | "uci": [ "v2ray_server" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | 8 | [*.{lua,html}] 9 | indent_style = tab 10 | indent_size = 2 11 | 12 | [Makefile] 13 | indent_style = tab 14 | indent_size = 2 15 | 16 | [{*.json,.travis.yml}] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [{v2ray,40_luci-v2ray,firewall.v2ray}] 21 | indent_style = tab 22 | indent_size = 2 23 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.po~ 3 | .idea 4 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/.travis.yml: -------------------------------------------------------------------------------- 1 | os: linux 2 | dist: bionic 3 | notifications: 4 | email: false 5 | language: c 6 | compiler: gcc 7 | cache: 8 | ccache: true 9 | directories: 10 | - "$HOME/dl" 11 | - "$HOME/files" 12 | - "$HOME/feeds" 13 | git: 14 | depth: 3 15 | submodules: false 16 | env: 17 | global: 18 | - PACKAGE=luci-app-v2ray 19 | - SDK_PATH=https://downloads.openwrt.org/releases/18.06.8/targets/x86/64 20 | - SDK=-sdk-18.06.8-x86-64_ 21 | - CONFIG_CCACHE=y 22 | install: 23 | - test -d "$HOME/files" || mkdir -p "$HOME/files" 24 | - cd "$HOME/files" 25 | - wget "$SDK_PATH/sha256sums" -O sha256sums 26 | - | 27 | if ! grep -- "$SDK" sha256sums > sha256sums.small 2>/dev/null ; then 28 | echo "Can not find ${SDK} file in sha256sums." 29 | exit 1 30 | fi 31 | - export SDK_FILE="$(cat sha256sums.small | cut -d' ' -f2 | sed 's/*//g')" 32 | - | 33 | if ! sha256sum -c ./sha256sums.small 2>/dev/null ; then 34 | wget "$SDK_PATH/$SDK_FILE" -O "$SDK_FILE" 35 | if ! sha256sum -c ./sha256sums.small 2>/dev/null ; then 36 | echo "SDK can not be verified!" 37 | exit 1 38 | fi 39 | fi 40 | - file "$HOME/files/$SDK_FILE" 41 | - export SDK_HOME="$(mktemp -d)" 42 | - cd "$SDK_HOME" 43 | - tar -Jxf "$HOME/files/$SDK_FILE" --strip=1 44 | - test -d "$HOME/dl" || mkdir -p "$HOME/dl" 45 | - test -d "dl" && rm -rf dl || true 46 | - test -d "feeds" && rm -rf feeds || true 47 | - ln -s "$HOME/dl/" dl 48 | - ln -s "$HOME/feeds" feeds 49 | - echo "src-git base https://github.com/openwrt/openwrt.git" >feeds.conf 50 | - echo "src-git packages https://github.com/openwrt/packages.git" >>feeds.conf 51 | - echo "src-git luci https://github.com/openwrt/luci.git" >>feeds.conf 52 | - echo "src-git routing https://git.openwrt.org/feed/routing.git" >>feeds.conf 53 | - echo "src-git telephony https://github.com/openwrt/telephony.git" >>feeds.conf 54 | - ln -s "$TRAVIS_BUILD_DIR" "package/$PACKAGE" 55 | script: 56 | - cd "$SDK_HOME" 57 | - ./scripts/feeds update -a >/dev/null 58 | - ./scripts/feeds install -a >/dev/null 59 | - make defconfig 60 | - make package/$PACKAGE/{clean,compile} -j2 61 | - find "$SDK_HOME/bin/" 62 | - find "$SDK_HOME/bin/" -name luci-*-v2ray*.ipk -exec cp {} "$TRAVIS_BUILD_DIR" \; 63 | - ls -hl "$TRAVIS_BUILD_DIR" | grep .*\.ipk 64 | after_failure: 65 | - cd "$SDK_HOME" 66 | - make package/$PACKAGE/compile V=s 67 | deploy: 68 | provider: releases 69 | file_glob: true 70 | file: "$TRAVIS_BUILD_DIR/*.ipk" 71 | cleanup: false 72 | edge: true 73 | token: $GITHUB_TOKEN 74 | on: 75 | tags: true 76 | all_branches: true 77 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Xingwang Liao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019-2020 Xingwang Liao 3 | # Licensed to the public under the MIT License. 4 | # 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | PKG_NAME:=luci-app-v2ray 9 | PKG_VERSION:=1.5.6 10 | PKG_RELEASE:=1 11 | 12 | PKG_LICENSE:=MIT 13 | PKG_MAINTAINER:=Xingwang Liao 14 | 15 | LUCI_TITLE:=LuCI support for V2Ray 16 | LUCI_DEPENDS:=+jshn +luci-lib-jsonc +ip +ipset +iptables +iptables-mod-tproxy \ 17 | +resolveip +dnsmasq-full 18 | LUCI_PKGARCH:=all 19 | 20 | define Package/$(PKG_NAME)/conffiles 21 | /etc/config/v2ray 22 | /etc/v2ray/transport.json 23 | /etc/v2ray/srcdirectlist.txt 24 | /etc/v2ray/directlist.txt 25 | /etc/v2ray/proxylist.txt 26 | endef 27 | 28 | include $(TOPDIR)/feeds/luci/luci.mk 29 | 30 | define Package/$(PKG_NAME)/postinst 31 | #!/bin/sh 32 | 33 | if [ -z "$${IPKG_INSTROOT}" ] ; then 34 | ( . /etc/uci-defaults/40_luci-v2ray ) && rm -f /etc/uci-defaults/40_luci-v2ray 35 | fi 36 | 37 | chmod 755 "$${IPKG_INSTROOT}/etc/init.d/v2ray" >/dev/null 2>&1 38 | ln -sf "../init.d/v2ray" \ 39 | "$${IPKG_INSTROOT}/etc/rc.d/S99v2ray" >/dev/null 2>&1 40 | 41 | exit 0 42 | endef 43 | 44 | define Package/$(PKG_NAME)/postrm 45 | #!/bin/sh 46 | 47 | if [ -s "$${IPKG_INSTROOT}/etc/rc.d/S99v2ray" ] ; then 48 | rm -f "$${IPKG_INSTROOT}/etc/rc.d/S99v2ray" 49 | fi 50 | 51 | if [ -z "$${IPKG_INSTROOT}" ] ; then 52 | rm -rf /tmp/luci-indexcache /tmp/luci-modulecache 53 | fi 54 | 55 | exit 0 56 | endef 57 | 58 | # call BuildPackage - OpenWrt buildroot signature 59 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/README.md: -------------------------------------------------------------------------------- 1 | # luci-app-v2ray 2 | 3 | Luci support for V2Ray 4 | 5 | [![Release Version](https://img.shields.io/github/release/kuoruan/luci-app-v2ray.svg)](https://github.com/kuoruan/luci-app-v2ray/releases/latest) [![Latest Release Download](https://img.shields.io/github/downloads/kuoruan/luci-app-v2ray/latest/total.svg)](https://github.com/kuoruan/luci-app-v2ray/releases/latest) [![Total Download](https://img.shields.io/github/downloads/kuoruan/luci-app-v2ray/total.svg)](https://github.com/kuoruan/luci-app-v2ray/releases) 6 | 7 | ## Install 8 | 9 | ### Install via OPKG (recommend) 10 | 11 | 1. Add new opkg key: 12 | 13 | ```sh 14 | wget -O kuoruan-public.key http://openwrt.kuoruan.net/packages/public.key 15 | opkg-key add kuoruan-public.key 16 | ``` 17 | 18 | 2. Add opkg repository from kuoruan: 19 | 20 | ```sh 21 | echo "src/gz kuoruan_universal http://openwrt.kuoruan.net/packages/releases/all" \ 22 | >> /etc/opkg/customfeeds.conf 23 | opkg update 24 | ``` 25 | 26 | 3. Install package: 27 | 28 | ```sh 29 | opkg install luci-app-v2ray 30 | opkg install luci-i18n-v2ray-zh-cn 31 | ``` 32 | 33 | We also support HTTPS protocol. 34 | 35 | 4. Upgrade package: 36 | 37 | ```sh 38 | opkg update 39 | opkg upgrade luci-app-v2ray 40 | opkg upgrade luci-i18n-v2ray-zh-cn 41 | ``` 42 | 43 | ### Manual install 44 | 45 | 1. Download ipk files from [release](https://github.com/kuoruan/luci-app-v2ray/releases) page 46 | 47 | 2. Upload files to your router 48 | 49 | 3. Install package with opkg: 50 | 51 | ```sh 52 | opkg install luci-app-v2ray_*.ipk 53 | ``` 54 | 55 | Depends: 56 | 57 | - jshn 58 | - luci-lib-jsonc 59 | - ip (ip-tiny or ip-full) 60 | - ipset 61 | - iptables 62 | - iptables-mod-tproxy 63 | - resolveip 64 | - dnsmasq-full (dnsmasq ipset is required) 65 | - luci-compat (for OpenWrt 19.07 and later) 66 | 67 | For translations, please install ```luci-i18n-v2ray-*```. 68 | 69 | > You may need to remove ```dnsmasq``` before installing this package. 70 | 71 | ## Configure 72 | 73 | 1. Download V2Ray file from V2Ray release [link](https://github.com/v2ray/v2ray-core/releases) or V2Ray ipk release [link](https://github.com/kuoruan/openwrt-v2ray/releases). 74 | 75 | 2. Upload V2Ray file to your router, or install the ipk file. 76 | 77 | 3. Config V2Ray file path in LuCI page. 78 | 79 | 4. Add your inbound and outbound rules. 80 | 81 | 5. Enable the service via LuCI. 82 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/i18n-scan.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use Text::Balanced qw(extract_tagged gen_delimited_pat); 6 | use POSIX; 7 | 8 | POSIX::setlocale(POSIX::LC_ALL, "C"); 9 | 10 | @ARGV >= 1 || die "Usage: $0 \n"; 11 | 12 | 13 | my %stringtable; 14 | 15 | sub dec_lua_str 16 | { 17 | my $s = shift; 18 | $s =~ s/\\n/\n/g; 19 | $s =~ s/\\t/\t/g; 20 | $s =~ s/\\(.)/$1/sg; 21 | $s =~ s/[\s\n]+/ /g; 22 | $s =~ s/^ //; 23 | $s =~ s/ $//; 24 | return $s; 25 | } 26 | 27 | sub dec_tpl_str 28 | { 29 | my $s = shift; 30 | $s =~ s/-$//; 31 | $s =~ s/[\s\n]+/ /g; 32 | $s =~ s/^ //; 33 | $s =~ s/ $//; 34 | $s =~ s/\\/\\\\/g; 35 | return $s; 36 | } 37 | 38 | if( open F, "find @ARGV -type f '(' -name '*.htm' -o -name '*.lua' -o -name '*.js' ')' | sort |" ) 39 | { 40 | while( defined( my $file = readline F ) ) 41 | { 42 | chomp $file; 43 | 44 | if( open S, "< $file" ) 45 | { 46 | local $/ = undef; 47 | my $raw = ; 48 | close S; 49 | 50 | my $text = $raw; 51 | my $line = 1; 52 | 53 | while ($text =~ s/ ^ (.*?) (?:translate|translatef|i18n|_) ([\n\s]*) \( //sgx) 54 | { 55 | my ($prefix, $suffix) = ($1, $2); 56 | my $code; 57 | my $res = ""; 58 | my $sub = ""; 59 | 60 | $line += () = $prefix =~ /\n/g; 61 | 62 | my $position = "$file:$line"; 63 | 64 | $line += () = $suffix =~ /\n/g; 65 | 66 | while (defined $sub) 67 | { 68 | undef $sub; 69 | 70 | if ($text =~ /^ ([\n\s]*(?:\.\.[\n\s]*)?) (\[=*\[) /sx) 71 | { 72 | my $ws = $1; 73 | my $stag = quotemeta $2; 74 | (my $etag = $stag) =~ y/[/]/; 75 | 76 | ($sub, $text) = extract_tagged($text, $stag, $etag, q{\s*(?:\.\.\s*)?}); 77 | 78 | $line += () = $ws =~ /\n/g; 79 | 80 | if (defined($sub) && length($sub)) { 81 | $line += () = $sub =~ /\n/g; 82 | 83 | $sub =~ s/^$stag//; 84 | $sub =~ s/$etag$//; 85 | $res .= $sub; 86 | } 87 | } 88 | elsif ($text =~ /^ ([\n\s]*(?:\.\.[\n\s]*)?) (['"]) /sx) 89 | { 90 | my $ws = $1; 91 | my $quote = $2; 92 | my $re = gen_delimited_pat($quote, '\\'); 93 | 94 | if ($text =~ m/\G\s*(?:\.\.\s*)?($re)/gcs) 95 | { 96 | $sub = $1; 97 | $text = substr $text, pos $text; 98 | } 99 | 100 | $line += () = $ws =~ /\n/g; 101 | 102 | if (defined($sub) && length($sub)) { 103 | $line += () = $sub =~ /\n/g; 104 | 105 | $sub =~ s/^$quote//; 106 | $sub =~ s/$quote$//; 107 | $res .= $sub; 108 | } 109 | } 110 | } 111 | 112 | if (defined($res)) 113 | { 114 | $res = dec_lua_str($res); 115 | 116 | if ($res) { 117 | $stringtable{$res} ||= [ ]; 118 | push @{$stringtable{$res}}, $position; 119 | } 120 | } 121 | } 122 | 123 | 124 | $text = $raw; 125 | $line = 1; 126 | 127 | while( $text =~ s/ ^ (.*?) <% -? [:_] /<%/sgx ) 128 | { 129 | $line += () = $1 =~ /\n/g; 130 | 131 | ( my $code, $text ) = extract_tagged($text, '<%', '%>'); 132 | 133 | if( defined $code ) 134 | { 135 | my $position = "$file:$line"; 136 | 137 | $line += () = $code =~ /\n/g; 138 | 139 | $code = dec_tpl_str(substr $code, 2, length($code) - 4); 140 | 141 | $stringtable{$code} ||= []; 142 | push @{$stringtable{$code}}, $position; 143 | } 144 | } 145 | } 146 | } 147 | 148 | close F; 149 | } 150 | 151 | 152 | if( open C, "| msgcat -" ) 153 | { 154 | printf C "msgid \"\"\nmsgstr \"Content-Type: text/plain; charset=UTF-8\"\n\n"; 155 | 156 | foreach my $key ( sort keys %stringtable ) 157 | { 158 | if( length $key ) 159 | { 160 | my @positions = @{$stringtable{$key}}; 161 | 162 | $key =~ s/\\/\\\\/g; 163 | $key =~ s/\n/\\n/g; 164 | $key =~ s/\t/\\t/g; 165 | $key =~ s/"/\\"/g; 166 | 167 | printf C "#: %s\nmsgid \"%s\"\nmsgstr \"\"\n\n", 168 | join(' ', @positions), $key; 169 | } 170 | } 171 | 172 | close C; 173 | } 174 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/i18n-update.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | @ARGV <= 2 || die "Usage: $0 [] []\n"; 4 | 5 | my $source = shift @ARGV; 6 | my $pattern = shift @ARGV || '*.po'; 7 | 8 | sub read_header 9 | { 10 | my $file = shift || return; 11 | local $/; 12 | 13 | open P, "< $file" || die "open(): $!"; 14 | my $data = readline P; 15 | close P; 16 | 17 | $data =~ / 18 | ^ ( 19 | msgid \s "" \n 20 | msgstr \s "" \n 21 | (?: " [^\n]+ " \n )+ 22 | \n ) 23 | /mx; 24 | 25 | return $1; 26 | } 27 | 28 | sub write_header 29 | { 30 | my $file = shift || return; 31 | my $head = shift || return; 32 | local $/; 33 | 34 | open P, "< $file" || die "open(): $!"; 35 | my $data = readline P; 36 | close P; 37 | 38 | $data =~ s/ 39 | ^ ( 40 | msgid \s "" \n 41 | msgstr \s "" \n 42 | (?: " [^\n]+ " \n )+ 43 | \n ) 44 | /$head/mx; 45 | 46 | open P, "> $file" || die "open(): $!"; 47 | print P $data; 48 | close P; 49 | } 50 | 51 | my @dirs; 52 | 53 | if( ! $source ) 54 | { 55 | @dirs = glob("./*/*/po/"); 56 | } 57 | else 58 | { 59 | @dirs = ( $source ); 60 | } 61 | 62 | foreach my $dir (@dirs) 63 | { 64 | if( open F, "find $dir -type f -name '$pattern' |" ) 65 | { 66 | while( chomp( my $file = readline F ) ) 67 | { 68 | my ( $basename ) = $file =~ m{.+/([^/]+)\.po$}; 69 | 70 | if( -f "$dir/templates/$basename.pot" ) 71 | { 72 | my $head = read_header($file); 73 | 74 | printf "Updating %-40s", $file; 75 | system("msgmerge", "-U", "-N", $file, "$dir/templates/$basename.pot"); 76 | 77 | write_header($file, $head); 78 | } 79 | } 80 | 81 | close F; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/about.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local uci = require "luci.model.uci".cursor() 5 | local util = require "luci.util" 6 | local fs = require "nixio.fs" 7 | 8 | local config_file = uci:get("v2ray", "main", "config_file") 9 | 10 | if not config_file or util.trim(config_file) == "" then 11 | config_file = "/var/etc/v2ray/v2ray.main.json" 12 | end 13 | 14 | local config_content = fs.readfile(config_file) or translate("Failed to open file.") 15 | 16 | local m 17 | 18 | m = SimpleForm("v2ray", "%s - %s" % { translate("V2Ray"), translate("About") }, 19 | "

%s

%s

%s

%s

%s

%s

%s

%s

" % { 20 | translate("LuCI support for V2Ray."), 21 | translatef("Author: %s", "Xingwang Liao"), 22 | translatef( 23 | "Source: %s", 24 | "https://github.com/kuoruan/luci-app-v2ray" 25 | ), 26 | translatef( 27 | "Latest: %s", 28 | "https://github.com/kuoruan/luci-app-v2ray/releases/latest" 29 | ), 30 | translatef( 31 | "Report Bugs: %s", 32 | "https://github.com/kuoruan/luci-app-v2ray/issues" 33 | ), 34 | translatef( 35 | "Donate: %s", 36 | "https://blog.kuoruan.com/donate" 37 | ), 38 | translatef("Current Config File: %s", config_file), 39 | "
%s
" % config_content, 40 | }) 41 | 42 | m.reset = false 43 | m.submit = false 44 | 45 | return m 46 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/dns.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local uci = require "luci.model.uci".cursor() 5 | local util = require "luci.util" 6 | 7 | local m, s1, s2, o 8 | 9 | local dns_keys, dns_table = {}, {} 10 | 11 | uci:foreach("v2ray", "dns_server", function(s) 12 | if s.alias then 13 | local key = s[".name"] 14 | util.append(dns_keys, key) 15 | dns_table[key] = s.alias 16 | end 17 | end) 18 | 19 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("DNS") }, 20 | translatef("Details: %s", "DnsObject")) 21 | 22 | s1 = m:section(NamedSection, "main_dns", "dns") 23 | s1.anonymous = true 24 | s1.addremove = false 25 | 26 | o = s1:option(Flag, "enabled", translate("Enabled")) 27 | o.rmempty = false 28 | 29 | o = s1:option(Value, "tag", translate("Tag")) 30 | 31 | o = s1:option(Value, "client_ip", translate("Client IP"), 32 | "%s" % translate("Get my public IP address")) 33 | o.datatype = "ipaddr" 34 | 35 | o = s1:option(DynamicList, "hosts", translate("Hosts"), 36 | translatef("A list of static addresses, format: domain|address. eg: %s", "google.com|127.0.0.1")) 37 | 38 | o = s1:option(MultiValue, "servers", translate("DNS Servers"), translate("Select DNS servers to use")) 39 | for _, v in ipairs(dns_keys) do 40 | o:value(v, dns_table[v]) 41 | end 42 | 43 | s2 = m:section(TypedSection, "dns_server", translate("DNS server"), translate("Add DNS servers here")) 44 | s2.anonymous = true 45 | s2.addremove = true 46 | 47 | o = s2:option(Value, "alias", translate("Alias"), translate("Any custom string")) 48 | o.rmempty = false 49 | 50 | o = s2:option(Value, "address", translate("Address")) 51 | 52 | o = s2:option(Value, "port", translate("Port")) 53 | o.datatype = "port" 54 | o.placeholder = "53" 55 | 56 | o = s2:option(DynamicList, "domains", translate("Domains")) 57 | 58 | return m 59 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/inbound-list.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | 6 | local m, s, o 7 | 8 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Inbound") }) 9 | 10 | s = m:section(TypedSection, "inbound") 11 | s.anonymous = true 12 | s.addremove = true 13 | s.sortable = true 14 | s.template = "cbi/tblsection" 15 | s.extedit = dsp.build_url("admin/services/v2ray/inbounds/%s") 16 | s.create = function (...) 17 | local sid = TypedSection.create(...) 18 | if sid then 19 | m.uci:save("v2ray") 20 | luci.http.redirect(s.extedit % sid) 21 | return 22 | end 23 | end 24 | 25 | o = s:option(DummyValue, "alias", translate("Alias")) 26 | o.cfgvalue = function (...) 27 | return Value.cfgvalue(...) or "?" 28 | end 29 | 30 | o = s:option(DummyValue, "listen", translate("Listen")) 31 | o.cfgvalue = function (...) 32 | return Value.cfgvalue(...) or "-" 33 | end 34 | 35 | o = s:option(DummyValue, "port", translate("Port")) 36 | o.cfgvalue = function (...) 37 | return Value.cfgvalue(...) or "?" 38 | end 39 | 40 | o = s:option(DummyValue, "protocol", translate("Protocol")) 41 | o.cfgvalue = function (...) 42 | return Value.cfgvalue(...) or "?" 43 | end 44 | 45 | o = s:option(DummyValue, "ss_network", translate("Stream Network")) 46 | o.cfgvalue = function (...) 47 | return Value.cfgvalue(...) or "?" 48 | end 49 | 50 | o = s:option(DummyValue, "tag", translate("Tag")) 51 | o.cfgvalue = function (...) 52 | return Value.cfgvalue(...) or "?" 53 | end 54 | 55 | return m 56 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/main.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local uci = require "luci.model.uci".cursor() 5 | local util = require "luci.util" 6 | local sys = require "luci.sys" 7 | local json = require "luci.jsonc" 8 | local v2ray = require "luci.model.v2ray" 9 | 10 | local m, s, o 11 | 12 | local inbound_keys, inbound_table, outbound_keys, outbound_table = {}, {}, {}, {} 13 | 14 | uci:foreach("v2ray", "inbound", function(s) 15 | if s.alias then 16 | local key = s[".name"] 17 | util.append(inbound_keys, key) 18 | inbound_table[key] = s.alias 19 | end 20 | end) 21 | 22 | uci:foreach("v2ray", "outbound", function(s) 23 | if s.alias then 24 | local key = s[".name"] 25 | util.append(outbound_keys, key) 26 | outbound_table[key] = s.alias 27 | end 28 | end) 29 | 30 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Global Settings") }, 31 | "

%s

%s

" % { 32 | translate("A platform for building proxies to bypass network restrictions."), 33 | translatef("For more information, please visit: %s", 34 | "https://www.v2ray.com") 35 | }) 36 | m:append(Template("v2ray/status_header")) 37 | 38 | s = m:section(NamedSection, "main", "v2ray") 39 | s.addremove = false 40 | s.anonymos = true 41 | 42 | o = s:option(Flag, "enabled", translate("Enabled")) 43 | o.rmempty = false 44 | 45 | o = s:option(Button, "_reload", translate("Reload Service"), translate("This will restart service when config file changes.")) 46 | o.inputstyle = "reload" 47 | o.write = function () 48 | sys.call("/etc/init.d/v2ray reload 2>/dev/null") 49 | end 50 | 51 | o = s:option(Value, "v2ray_file", translate("V2Ray file"), "%s" % translate("Collecting data...")) 52 | o.datatype = "file" 53 | o.placeholder = "/usr/bin/v2ray" 54 | o.rmempty = false 55 | 56 | o = s:option(Value, "asset_location", translate("V2Ray asset location"), 57 | translate("Directory where geoip.dat and geosite.dat files are, default: same directory as V2Ray file.")) 58 | o.datatype = "directory" 59 | o.placeholder = "/usr/bin" 60 | 61 | o = s:option(Value, "mem_percentage", translate("Memory percentage"), 62 | translate("The maximum percentage of memory used by V2Ray.")) 63 | o.datatype = "and(uinteger, max(100))" 64 | o.default = "0" 65 | o.placeholder = "80" 66 | 67 | o = s:option(Value, "config_file", translate("Config file"), 68 | translate("Use custom config file.")) 69 | o.datatype = "file" 70 | o:value("", translate("None")) 71 | 72 | o = s:option(Value, "access_log", translate("Access log file")) 73 | o:depends("config_file", "") 74 | o:value("/dev/null") 75 | o:value("/var/log/v2ray-access.log") 76 | 77 | o = s:option(ListValue, "loglevel", translate("Log level")) 78 | o:depends("config_file", "") 79 | o:value("debug", translate("Debug")) 80 | o:value("info", translate("Info")) 81 | o:value("warning", translate("Warning")) 82 | o:value("error", translate("Error")) 83 | o:value("none", translate("None")) 84 | o.default = "warning" 85 | 86 | o = s:option(Value, "error_log", translate("Error log file")) 87 | o:value("/dev/null") 88 | o:value("/var/log/v2ray-error.log") 89 | o:depends("loglevel", "debug") 90 | o:depends("loglevel", "info") 91 | o:depends("loglevel", "warning") 92 | o:depends("loglevel", "error") 93 | 94 | o = s:option(MultiValue, "inbounds", translate("Inbounds enabled")) 95 | o:depends("config_file", "") 96 | for _, v in ipairs(inbound_keys) do 97 | o:value(v, inbound_table[v]) 98 | end 99 | 100 | o = s:option(MultiValue, "outbounds", translate("Outbounds enabled")) 101 | o:depends("config_file", "") 102 | for _, v in ipairs(outbound_keys) do 103 | o:value(v, outbound_table[v]) 104 | end 105 | 106 | o = s:option(Flag, "stats_enabled", "%s - %s" % { translate("Stats"), translate("Enabled") }) 107 | o:depends("config_file", "") 108 | 109 | o = s:option(Flag, "transport_enabled", "%s - %s" % { translate("Transport"), translate("Enabled") }) 110 | o:depends("config_file", "") 111 | 112 | o = s:option(TextValue, "_transport", "%s - %s" % { translate("Transport"), translate("Settings") }, 113 | translate("transport field in top level configuration, JSON string")) 114 | o:depends("transport_enabled", "1") 115 | o.wrap = "off" 116 | o.rows = 5 117 | o.datatype = "string" 118 | o.filepath = "/etc/v2ray/transport.json" 119 | o.validate = function(self, value, section) 120 | if not value or value == "" then 121 | return nil, translate("Transport settings is required.") 122 | end 123 | 124 | if not json.parse(value) then 125 | return nil, translate("Invalid JSON content.") 126 | end 127 | return value, nil 128 | end 129 | o.cfgvalue = v2ray.textarea_cfgvalue 130 | o.write = v2ray.textarea_write 131 | o.remove = v2ray.textarea_remove 132 | 133 | return m 134 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/outbound-list.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | 6 | local m, s, o 7 | 8 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Outbound") }) 9 | m:append(Template("v2ray/import_outbound")) 10 | 11 | s = m:section(TypedSection, "outbound") 12 | s.anonymous = true 13 | s.addremove = true 14 | s.sortable = true 15 | s.template = "cbi/tblsection" 16 | s.extedit = dsp.build_url("admin/services/v2ray/outbounds/%s") 17 | s.create = function (...) 18 | local sid = TypedSection.create(...) 19 | if sid then 20 | m.uci:save("v2ray") 21 | luci.http.redirect(s.extedit % sid) 22 | return 23 | end 24 | end 25 | 26 | o = s:option(DummyValue, "alias", translate("Alias")) 27 | o.cfgvalue = function (...) 28 | return Value.cfgvalue(...) or "?" 29 | end 30 | 31 | o = s:option(DummyValue, "send_through", translate("Send Through")) 32 | o.cfgvalue = function (...) 33 | return Value.cfgvalue(...) or "-" 34 | end 35 | 36 | o = s:option(DummyValue, "protocol", translate("Protocol")) 37 | o.cfgvalue = function (...) 38 | return Value.cfgvalue(...) or "?" 39 | end 40 | 41 | o = s:option(DummyValue, "ss_network", translate("Stream Network")) 42 | o.cfgvalue = function (...) 43 | return Value.cfgvalue(...) or "?" 44 | end 45 | 46 | o = s:option(DummyValue, "tag", translate("Tag")) 47 | o.cfgvalue = function (...) 48 | return Value.cfgvalue(...) or "?" 49 | end 50 | 51 | 52 | return m 53 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/policy-level-detail.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | 6 | local m, s, o 7 | 8 | local sid = arg[1] 9 | 10 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Edit Policy Level") }, 11 | translatef("Details: %s", "LevelPolicyObject")) 12 | m.redirect = dsp.build_url("admin/services/v2ray/policy") 13 | 14 | if m.uci:get("v2ray", sid) ~= "policy_level" then 15 | luci.http.redirect(m.redirect) 16 | return 17 | end 18 | 19 | s = m:section(NamedSection, sid, "policy_level") 20 | s.anonymous = true 21 | s.addremove = false 22 | 23 | o = s:option(Value, "level", translate("Level")) 24 | o.rmempty = false 25 | o.datatype = "uinteger" 26 | 27 | o = s:option(Value, "handshake", translate("Handshake")) 28 | o.datatype = "uinteger" 29 | o.placeholder = "4" 30 | 31 | o = s:option(Value, "conn_idle", translate("Connection idle")) 32 | o.datatype = "uinteger" 33 | o.placeholder = "300" 34 | 35 | o = s:option(Value, "uplink_only", translate("Uplink only")) 36 | o.datatype = "uinteger" 37 | o.placeholder = "2" 38 | 39 | o = s:option(Value, "downlink_only", translate("Downlink only")) 40 | o.datatype = "uinteger" 41 | o.placeholder = "5" 42 | 43 | o = s:option(Flag, "stats_user_uplink", translate("Stats user uplink")) 44 | 45 | o = s:option(Flag, "stats_user_downlink", translate("Stats user downlink")) 46 | 47 | o = s:option(Value, "buffer_size", translate("Buffer size")) 48 | o.datatype = "uinteger" 49 | 50 | return m 51 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/policy.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | local uci = require "luci.model.uci".cursor() 6 | local util = require "luci.util" 7 | 8 | local m, s1, s2, o 9 | 10 | local level_keys, level_table = {}, {} 11 | 12 | uci:foreach("v2ray", "policy_level", function(s) 13 | if s.level then 14 | local key = s[".name"] 15 | util.append(level_keys, key) 16 | level_table[key] = s.level 17 | end 18 | end) 19 | 20 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Policy") }, 21 | translatef("Details: %s", "PolicyObject")) 22 | 23 | s1 = m:section(NamedSection, "main_policy", "policy") 24 | s1.anonymous = true 25 | s1.addremove = false 26 | 27 | o = s1:option(Flag, "enabled", translate("Enabled")) 28 | o.rmempty = false 29 | 30 | o = s1:option(MultiValue, "levels", translate("Levels"), translate("Select policy levels")) 31 | for _, v in ipairs(level_keys) do 32 | o:value(v, level_table[v]) 33 | end 34 | 35 | o = s1:option(Flag, "system_stats_inbound_uplink", "%s - %s" % { translate("System"), translate("Stats inbound uplink") }) 36 | 37 | o = s1:option(Flag, "system_stats_inbound_downlink", "%s - %s" % { translate("System"), translate("Stats inbound downlink") }) 38 | 39 | s2 = m:section(TypedSection, "policy_level", translate("Policy Level"), translate("Add policy levels here")) 40 | s2.anonymous = true 41 | s2.addremove = true 42 | s2.sortable = true 43 | s2.template = "cbi/tblsection" 44 | s2.extedit = dsp.build_url("admin/services/v2ray/policy/levels/%s") 45 | s2.create = function (...) 46 | local sid = TypedSection.create(...) 47 | if sid then 48 | m.uci:save("v2ray") 49 | luci.http.redirect(s2.extedit % sid) 50 | return 51 | end 52 | end 53 | 54 | o = s2:option(DummyValue, "level", translate("Level")) 55 | o.cfgvalue = function (...) 56 | return Value.cfgvalue(...) or "?" 57 | end 58 | 59 | o = s2:option(DummyValue, "handshake", translate("Handshake")) 60 | o.cfgvalue = function (...) 61 | return Value.cfgvalue(...) or "?" 62 | end 63 | 64 | o = s2:option(DummyValue, "conn_idle", translate("Connection Idle")) 65 | o.cfgvalue = function (...) 66 | return Value.cfgvalue(...) or "?" 67 | end 68 | 69 | o = s2:option(DummyValue, "buffer_size", translate("Buffer Size")) 70 | o.cfgvalue = function (...) 71 | return Value.cfgvalue(...) or "?" 72 | end 73 | 74 | return m 75 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/reverse.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local m, s, o 5 | 6 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Reverse") }, 7 | translatef("Details: %s", "ReverseObject")) 8 | 9 | s = m:section(NamedSection, "main_reverse", "reverse") 10 | s.anonymous = true 11 | s.addremove = false 12 | 13 | o = s:option(Flag, "enabled", translate("Enabled")) 14 | o.rmempty = false 15 | 16 | o = s:option(DynamicList, "bridges", translate("Bridges"), 17 | translatef("A list of bridges, format: tag|domain. eg: %s", "bridge|test.v2ray.com")) 18 | 19 | o = s:option(DynamicList, "portals", translate("Portals"), 20 | translatef("A list of portals, format: tag|domain. eg: %s", "portal|test.v2ray.com")) 21 | 22 | return m 23 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/routing-rule-detail.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | 6 | local m, s, o 7 | 8 | local sid = arg[1] 9 | 10 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Edit Routing Rule") }, 11 | translatef("Details: %s", "RuleObject")) 12 | m.redirect = dsp.build_url("admin/services/v2ray/routing") 13 | 14 | if m.uci:get("v2ray", sid) ~= "routing_rule" then 15 | luci.http.redirect(m.redirect) 16 | return 17 | end 18 | 19 | s = m:section(NamedSection, sid, "routing_rule") 20 | s.anonymous = true 21 | s.addremove = false 22 | 23 | o = s:option(Value, "alias", translate("Alias"), translate("Any custom string")) 24 | o.rmempty = false 25 | 26 | o = s:option(ListValue, "type", translate("Type")) 27 | o:value("field") 28 | 29 | o = s:option(DynamicList, "domain", translate("Domain")) 30 | 31 | o = s:option(DynamicList, "ip", translate("IP")) 32 | 33 | o = s:option(DynamicList, "port", translate("Port")) 34 | o.datatype = "or(port, portrange)" 35 | 36 | o = s:option(MultiValue, "network", translate("Network")) 37 | o:value("tcp") 38 | o:value("udp") 39 | 40 | o = s:option(DynamicList, "source", translate("Source")) 41 | 42 | o = s:option(DynamicList, "user", translate("User")) 43 | 44 | o = s:option(DynamicList, "inbound_tag", translate("Inbound tag")) 45 | 46 | o = s:option(MultiValue, "protocol", translate("Protocol")) 47 | o:value("http") 48 | o:value("tls") 49 | o:value("bittorrent") 50 | 51 | o = s:option(Value, "attrs", translate("Attrs")) 52 | 53 | o = s:option(Value, "outbound_tag", translate("Outbound tag")) 54 | 55 | o = s:option(Value, "balancer_tag", translate("Balancer tag")) 56 | o:depends("outbound_tag", "") 57 | 58 | return m 59 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/routing.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local dsp = require "luci.dispatcher" 5 | local uci = require "luci.model.uci".cursor() 6 | local util = require "luci.util" 7 | 8 | local m, s1, s2, s3, o 9 | 10 | local rule_keys, rule_table, balancer_keys, balancer_table = {}, {}, {}, {} 11 | 12 | uci:foreach("v2ray", "routing_rule", function(s) 13 | if s.alias then 14 | local key = s[".name"] 15 | util.append(rule_keys, key) 16 | rule_table[key] = s.alias 17 | end 18 | end) 19 | 20 | uci:foreach("v2ray", "routing_balancer", function(s) 21 | if s.tag then 22 | local key = s[".name"] 23 | util.append(balancer_keys, key) 24 | balancer_table[key] = s.tag 25 | end 26 | end) 27 | 28 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Routing") }, 29 | translatef("Details: %s", "RoutingObject")) 30 | 31 | s1 = m:section(NamedSection, "main_routing", "routing") 32 | s1.anonymous = true 33 | s1.addremove = false 34 | 35 | o = s1:option(Flag, "enabled", translate("Enabled")) 36 | 37 | o = s1:option(ListValue, "domain_strategy", translate("Domain resolution strategy")) 38 | o:value("") 39 | o:value("AsIs") 40 | o:value("IPIfNonMatch") 41 | o:value("IPOnDemand") 42 | 43 | o = s1:option(MultiValue, "rules", translate("Rules"), translate("Select routing rules to use")) 44 | for _, v in ipairs(rule_keys) do 45 | o:value(v, rule_table[v]) 46 | end 47 | 48 | o = s1:option(MultiValue, "balancers", translate("Balancers"), translate("Select routing balancers to use")) 49 | for _, v in ipairs(balancer_keys) do 50 | o:value(v, balancer_table[v]) 51 | end 52 | 53 | s2 = m:section(TypedSection, "routing_rule", translate("Routing Rule"), translate("Add routing rules here")) 54 | s2.anonymous = true 55 | s2.addremove = true 56 | s2.sortable = true 57 | s2.template = "cbi/tblsection" 58 | s2.extedit = dsp.build_url("admin/services/v2ray/routing/rules/%s") 59 | s2.create = function (...) 60 | local sid = TypedSection.create(...) 61 | if sid then 62 | m.uci:save("v2ray") 63 | luci.http.redirect(s2.extedit % sid) 64 | return 65 | end 66 | end 67 | 68 | o = s2:option(DummyValue, "alias", translate("Alias")) 69 | o.cfgvalue = function (...) 70 | return Value.cfgvalue(...) or "?" 71 | end 72 | 73 | o = s2:option(DummyValue, "type", translate("Type")) 74 | o.cfgvalue = function (...) 75 | return Value.cfgvalue(...) or "?" 76 | end 77 | 78 | o = s2:option(DummyValue, "inbound_tag", translate("Inbound Tag")) 79 | o.cfgvalue = function (self, section) 80 | local v = self.map:get(section, self.option) 81 | if type(v) == "table" then 82 | return table.concat(v, " ") 83 | end 84 | return v and v or "?" 85 | end 86 | 87 | o = s2:option(DummyValue, "outbound_tag", translate("Outbound Tag")) 88 | o.cfgvalue = function (...) 89 | return Value.cfgvalue(...) or "?" 90 | end 91 | 92 | o = s2:option(DummyValue, "network", translate("Network")) 93 | o.cfgvalue = function (...) 94 | return Value.cfgvalue(...) or "?" 95 | end 96 | 97 | s3 = m:section(TypedSection, "routing_balancer", translate("Routing Balancer"), translate("Add routing balancers here")) 98 | s3.anonymous = true 99 | s3.addremove = true 100 | 101 | o = s3:option(Value, "tag", translate("Tag")) 102 | o.rmempty = false 103 | 104 | o = s3:option(DynamicList, "selector", translate("Selector")) 105 | 106 | return m 107 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/model/cbi/v2ray/transparent-proxy.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2019-2020 Xingwang Liao 2 | -- Licensed to the public under the MIT License. 3 | 4 | local uci = require "luci.model.uci".cursor() 5 | local fs = require "nixio.fs" 6 | local sys = require "luci.sys" 7 | local nwm = require "luci.model.network".init() 8 | local v2ray = require "luci.model.v2ray" 9 | 10 | local m, s, o 11 | 12 | local dokodemo_door_list = {} 13 | 14 | uci:foreach("v2ray", "inbound", function(s) 15 | local port = s.port or "" 16 | local protocol = s.protocol or "" 17 | if protocol == "dokodemo-door" and port ~= "" then 18 | if s.alias then 19 | dokodemo_door_list[port] = string.format("%s - %s", s.alias, port) 20 | else 21 | dokodemo_door_list[port] = string.format("%s:%s", s.listen, port) 22 | end 23 | end 24 | end) 25 | 26 | local interfaces = {} 27 | for _, net in ipairs(nwm:get_networks()) do 28 | local net_name = net:name() 29 | if net_name ~= "loopback" and string.find(net_name, "wan") ~= 1 then 30 | local device = net:get_interface() 31 | if device then 32 | interfaces[net_name] = device:get_i18n() 33 | end 34 | end 35 | end 36 | 37 | local has_ssl = true, ssl_note 38 | 39 | if not fs.stat("/lib/libustream-ssl.so") then 40 | has_ssl = false 41 | ssl_note = translatef("Please install %s or %s to enable list update.", "libustream-openssl", "libustream-mbedtls") 42 | end 43 | 44 | local list_changed = false 45 | 46 | m = Map("v2ray", "%s - %s" % { translate("V2Ray"), translate("Transparent Proxy") }) 47 | m.apply_on_parse = true 48 | m.on_after_apply = function () 49 | if list_changed then 50 | sys.call("/etc/init.d/v2ray reload 2>/dev/null") 51 | list_changed = false 52 | end 53 | end 54 | 55 | s = m:section(NamedSection, "main_transparent_proxy", "transparent_proxy") 56 | 57 | o = s:option(Value, "redirect_port", translate("Redirect port"), translate("Enable transparent proxy on Dokodemo-door port.")) 58 | o:value("", translate("None")) 59 | for k, v in pairs(dokodemo_door_list) do 60 | o:value(k, v) 61 | end 62 | o.datatype = "port" 63 | 64 | o = s:option(MultiValue, "lan_ifaces", translate("LAN interfaces"), translate("Enable proxy on selected interfaces.")) 65 | o.delimiter = " " 66 | o.forcewrite = true 67 | o.cfgvalue = function(...) 68 | local v = MultiValue.cfgvalue(...) 69 | if not v then 70 | local names = {} 71 | for name, _ in pairs(interfaces) do 72 | names[#names+1] = name 73 | end 74 | return table.concat(names, " ") 75 | else 76 | return v 77 | end 78 | end 79 | for k, v in pairs(interfaces) do 80 | o:value(k, v) 81 | end 82 | 83 | o = s:option(Flag, "use_tproxy", translate("Use TProxy"), translate("Setup redirect rules with TProxy.")) 84 | 85 | o = s:option(Flag, "only_privileged_ports", translate("Only privileged ports"), 86 | translate("Only redirect traffic on ports below 1024.")) 87 | 88 | o = s:option(Flag, "redirect_udp", translate("Redirect UDP"), translate("Redirect UDP traffic to V2Ray.")) 89 | 90 | o = s:option(Flag, "redirect_dns", translate("Redirect DNS"), translate("Redirect DNS traffic to V2Ray.")) 91 | o:depends("redirect_udp", "") 92 | o:depends("redirect_udp", "0") 93 | 94 | o = s:option(ListValue, "proxy_mode", translate("Proxy mode"), 95 | translate("If enabled, iptables rules will be added to pre-filter traffic and then sent to V2Ray.")) 96 | o:value("default", translate("Default")) 97 | o:value("cn_direct", translate("CN Direct")) 98 | o:value("cn_proxy", translate("CN Proxy")) 99 | o:value("gfwlist_proxy", translate("GFWList Proxy")) 100 | 101 | o = s:option(ListValue, "apnic_delegated_mirror", translate("APNIC delegated mirror")) 102 | o:value("apnic", "APNIC") 103 | o:value("arin", "ARIN") 104 | o:value("ripe", "RIPE") 105 | o:value("iana", "IANA") 106 | 107 | o = s:option(DummyValue, "_chnroutelist", translate("CHNRoute"), ssl_note) 108 | o.template = "v2ray/list_status" 109 | o.listtype = "chnroute" 110 | o.updatebtn = has_ssl 111 | 112 | o = s:option(ListValue, "gfwlist_mirror", translate("GFWList mirror")) 113 | o:value("github", "GitHub") 114 | o:value("gitlab", "GitLab") 115 | o:value("bitbucket", "Bitbucket") 116 | o:value("pagure", "Pagure") 117 | 118 | o = s:option(DummyValue, "_gfwlist", translate("GFWList"), ssl_note) 119 | o.template = "v2ray/list_status" 120 | o.listtype = "gfwlist" 121 | o.updatebtn = has_ssl 122 | 123 | o = s:option(TextValue, "_proxy_list", translate("Extra proxy list"), 124 | translatef("One address per line. Allow types: DOMAIN, IP, CIDR. eg: %s, %s, %s", "www.google.com", "1.1.1.1", "192.168.0.0/16")) 125 | o.wrap = "off" 126 | o.rows = 5 127 | o.datatype = "string" 128 | o.filepath = "/etc/v2ray/proxylist.txt" 129 | o.cfgvalue = v2ray.textarea_cfgvalue 130 | o.write = v2ray.textarea_write 131 | o.remove = v2ray.textarea_remove 132 | o.parse = function(...) 133 | list_changed = v2ray.textarea_parse(...) 134 | end 135 | 136 | o = s:option(TextValue, "_direct_list", translate("Extra direct list"), 137 | translatef("One address per line. Allow types: DOMAIN, IP, CIDR. eg: %s, %s, %s", "www.google.com", "1.1.1.1", "192.168.0.0/16")) 138 | o.wrap = "off" 139 | o.rows = 5 140 | o.datatype = "string" 141 | o.filepath = "/etc/v2ray/directlist.txt" 142 | o.cfgvalue = v2ray.textarea_cfgvalue 143 | o.write = v2ray.textarea_write 144 | o.remove = v2ray.textarea_remove 145 | o.parse = function(...) 146 | list_changed = v2ray.textarea_parse(...) 147 | end 148 | 149 | o = s:option(Value, "proxy_list_dns", translate("Proxy list DNS"), 150 | translatef("DNS used for domains in proxy list, format: ip#port. eg: %s", "1.1.1.1#53")) 151 | 152 | o = s:option(Value, "direct_list_dns", translate("Direct list DNS"), 153 | translatef("DNS used for domains in direct list, format: ip#port. eg: %s", "114.114.114.114#53")) 154 | 155 | o = s:option(TextValue, "_src_direct_list", translate("Local devices direct outbound list"), 156 | translatef("One address per line. Allow types: IP, CIDR. eg: %s, %s", "192.168.0.19", "192.168.0.0/16")) 157 | o.wrap = "off" 158 | o.rows = 3 159 | o.datatype = "string" 160 | o.filepath = "/etc/v2ray/srcdirectlist.txt" 161 | o.cfgvalue = v2ray.textarea_cfgvalue 162 | o.write = v2ray.textarea_write 163 | o.remove = v2ray.textarea_remove 164 | o.parse = function(...) 165 | list_changed = v2ray.textarea_parse(...) 166 | end 167 | 168 | return m 169 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/view/v2ray/import_outbound.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2020 Xingwang Liao 3 | Licensed to the public under the MIT License. 4 | -%> 5 | 6 | <% 7 | local dsp = require "luci.dispatcher" 8 | -%> 9 | 38 | 39 |
40 |
41 | 42 | <%=translatef("Allowed link format: %s", "vmess://xxxxx")%> 43 |
44 |
45 | 55 | 56 | 104 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/view/v2ray/list_status.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2019-2020 Xingwang Liao 3 | Licensed to the public under the MIT License. 4 | -%> 5 | 6 | <% 7 | local dsp = require "luci.dispatcher" 8 | -%> 9 | 10 | <%+cbi/valueheader%> 11 | 12 | 53 | 54 | <%:Collecting data...%> 55 | <%- if self.updatebtn then %> 56 | 57 | <%- end %> 58 | 59 | <%+cbi/valuefooter%> 60 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/luasrc/view/v2ray/status_header.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2019-2020 Xingwang Liao 3 | Licensed to the public under the MIT License. 4 | -%> 5 | 6 | <% 7 | local dsp = require "luci.dispatcher" 8 | -%> 9 | 10 |
11 |

<%:Collecting data...%>

12 |
13 | 14 | 48 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/config/v2ray: -------------------------------------------------------------------------------- 1 | config v2ray 'main' 2 | option enabled '0' 3 | option v2ray_file '/usr/bin/v2ray/v2ray' 4 | option mem_percentage '0' 5 | option config_file '' 6 | option loglevel 'warning' 7 | option access_log '/dev/null' 8 | option error_log '/var/log/v2ray-error.log' 9 | option inbounds 'socks_proxy dokodemo_door' 10 | option outbounds 'vmess direct block dns_out' 11 | option stats_enabled '0' 12 | option transport_enabled '0' 13 | 14 | config dns 'main_dns' 15 | option enabled '1' 16 | list hosts 'example.com|127.0.0.1' 17 | option servers 'cloudflare_dns_1 google_dns_1 114_dns_1 ali_dns_1' 18 | 19 | config dns_server 'cloudflare_dns_1' 20 | option alias 'cloudflare_dns_1' 21 | option address '1.1.1.1' 22 | 23 | config dns_server 'google_dns_1' 24 | option alias 'google_dns_1' 25 | option address '8.8.8.8' 26 | 27 | config dns_server 'op_dns_1' 28 | option alias 'op_dns_1' 29 | option address '208.67.222.222' 30 | option port '5353' 31 | 32 | config dns_server '114_dns_1' 33 | option alias '114_dns_1' 34 | option address '114.114.114.114' 35 | option port '53' 36 | list domains 'geosite:cn' 37 | 38 | config dns_server 'ali_dns_1' 39 | option alias 'ali_dns_1' 40 | option address '223.5.5.5' 41 | list domains 'geosite:cn' 42 | 43 | config routing 'main_routing' 44 | option enabled '1' 45 | option domain_strategy 'IPOnDemand' 46 | option rules 'direct_cn_ip direct_cn_domain direct_bt route_dns direct_dns proxy_dns direct_ntp' 47 | 48 | config routing_rule 'direct_cn_ip' 49 | option alias 'direct_cn_ip' 50 | option type 'field' 51 | list ip 'geoip:private' 52 | list ip 'geoip:cn' 53 | option outbound_tag 'direct' 54 | 55 | config routing_rule 'direct_cn_domain' 56 | option alias 'direct_cn_domain' 57 | option type 'field' 58 | list domain 'geosite:cn' 59 | option outbound_tag 'direct' 60 | 61 | config routing_rule 'direct_speedtest' 62 | option alias 'direct_speedtest' 63 | option type 'field' 64 | list domain 'geosite:speedtest' 65 | option outbound_tag 'direct' 66 | 67 | config routing_rule 'direct_bt' 68 | option alias 'direct_bt' 69 | option type 'field' 70 | option protocol 'bittorrent' 71 | option outbound_tag 'direct' 72 | 73 | config routing_rule 'block_ad' 74 | option alias 'block_ad' 75 | option type 'field' 76 | list domain 'geosite:category-ads-all' 77 | option outbound_tag 'block' 78 | 79 | config routing_rule 'route_dns' 80 | option alias 'route_dns' 81 | option type 'field' 82 | list network 'udp' 83 | list port '53' 84 | list inbound_tag 'transparent' 85 | option outbound_tag 'dns_out' 86 | 87 | config routing_rule 'direct_dns' 88 | option alias 'direct_dns' 89 | option type 'field' 90 | list ip '114.114.114.114' 91 | list ip '223.5.5.5' 92 | option outbound_tag 'direct' 93 | 94 | config routing_rule 'proxy_dns' 95 | option alias 'proxy_dns' 96 | option type 'field' 97 | list ip '1.1.1.1' 98 | list ip '8.8.8.8' 99 | list ip '208.67.222.222' 100 | option outbound_tag 'proxy' 101 | 102 | config routing_rule 'direct_ntp' 103 | option alias 'direct_ntp' 104 | option type 'field' 105 | list network 'udp' 106 | list port '123' 107 | option outbound_tag 'direct' 108 | 109 | config routing_balancer 'routing_balancer_1' 110 | option tag 'balancer' 111 | list selector 'a' 112 | list selector 'ab' 113 | 114 | config policy 'main_policy' 115 | option enabled '0' 116 | 117 | config policy_level 'policy_level_0' 118 | option level '0' 119 | option handshake '4' 120 | option conn_idle '300' 121 | option uplink_only '2' 122 | option downlink_only '5' 123 | option buffer_size '0' 124 | 125 | config reverse 'main_reverse' 126 | option enabled '0' 127 | list bridges 'bridge|test.v2ray.com' 128 | list portals 'portal|test.v2ray.com' 129 | 130 | config inbound 'socks_proxy' 131 | option alias 'socks_proxy' 132 | option listen '0.0.0.0' 133 | option port '1080' 134 | option protocol 'socks' 135 | option s_socks_auth 'noauth' 136 | option s_socks_udp '1' 137 | option s_socks_ip '127.0.0.1' 138 | option sniffing_enabled '1' 139 | option sniffing_dest_override 'http tls' 140 | 141 | config inbound 'dokodemo_door' 142 | option alias 'dokodemo_door' 143 | option port '1081' 144 | option protocol 'dokodemo-door' 145 | option tag 'transparent' 146 | option sniffing_enabled '1' 147 | option sniffing_dest_override 'http tls' 148 | 149 | config outbound 'vmess' 150 | option alias 'vmess' 151 | option protocol 'vmess' 152 | option s_vmess_address '0.0.0.0' 153 | option s_vmess_port '10086' 154 | option s_vmess_user_id 'b831381d-6324-4d53-ad4f-8cda48b30811' 155 | option tag 'proxy' 156 | 157 | config outbound 'direct' 158 | option alias 'direct' 159 | option protocol 'freedom' 160 | option tag 'direct' 161 | 162 | config outbound 'block' 163 | option alias 'block' 164 | option protocol 'blackhole' 165 | option tag 'block' 166 | 167 | config outbound 'dns_out' 168 | option alias 'dns_out' 169 | option protocol 'dns' 170 | option tag 'dns_out' 171 | 172 | config transparent_proxy 'main_transparent_proxy' 173 | option redirect_port '' 174 | option proxy_mode 'default' 175 | option apnic_delegated_mirror 'apnic' 176 | option gfwlist_mirror 'github' 177 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/firewall.v2ray: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2019-2020 Xingwang Liao 4 | # Licensed to the public under the MIT License. 5 | # 6 | 7 | test -s "/etc/init.d/v2ray" && /etc/init.d/v2ray reload 8 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/uci-defaults/40_luci-v2ray: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2019-2020 Xingwang Liao 4 | # Licensed to the public under the MIT License. 5 | # 6 | 7 | # v2ray main 8 | v2ray=$(uci -q get v2ray.main) 9 | if [ "x$v2ray" != "xv2ray" ] ; then 10 | uci -q batch <<-EOF >/dev/null 11 | add v2ray v2ray 12 | rename v2ray.@v2ray[-1]="main" 13 | set v2ray.main.enabled="0" 14 | commit v2ray 15 | EOF 16 | fi 17 | 18 | # dns 19 | dns=$(uci -q get v2ray.main_dns) 20 | if [ "x$dns" != "xdns" ] ; then 21 | uci -q batch <<-EOF >/dev/null 22 | add v2ray dns 23 | rename v2ray.@dns[-1]="main_dns" 24 | set v2ray.main_dns.enabled="0" 25 | commit v2ray 26 | EOF 27 | fi 28 | 29 | # routing 30 | routing=$(uci -q get v2ray.main_routing) 31 | if [ "x$routing" != "xrouting" ] ; then 32 | uci -q batch <<-EOF >/dev/null 33 | add v2ray routing 34 | rename v2ray.@routing[-1]="main_routing" 35 | set v2ray.main_routing.enabled="0" 36 | commit v2ray 37 | EOF 38 | fi 39 | 40 | # policy 41 | policy=$(uci -q get v2ray.main_policy) 42 | if [ "x$policy" != "xpolicy" ] ; then 43 | uci -q batch <<-EOF >/dev/null 44 | add v2ray policy 45 | rename v2ray.@policy[-1]="main_policy" 46 | set v2ray.main_policy.enabled="0" 47 | commit v2ray 48 | EOF 49 | fi 50 | 51 | # reverse 52 | reverse=$(uci -q get v2ray.main_reverse) 53 | if [ "x$reverse" != "xreverse" ] ; then 54 | uci -q batch <<-EOF >/dev/null 55 | add v2ray reverse 56 | rename v2ray.@reverse[-1]="main_reverse" 57 | set v2ray.main_reverse.enabled="0" 58 | commit v2ray 59 | EOF 60 | fi 61 | 62 | # transparent_proxy 63 | transparent_proxy=$(uci -q get v2ray.main_transparent_proxy) 64 | if [ "x$transparent_proxy" != "xtransparent_proxy" ] ; then 65 | uci -q batch <<-EOF >/dev/null 66 | add v2ray transparent_proxy 67 | rename v2ray.@transparent_proxy[-1]="main_transparent_proxy" 68 | set v2ray.main_transparent_proxy.redirect_port="" 69 | commit v2ray 70 | EOF 71 | fi 72 | 73 | uci -q batch <<-EOF >/dev/null 74 | delete ucitrack.@v2ray[-1] 75 | add ucitrack v2ray 76 | set ucitrack.@v2ray[-1].init=v2ray 77 | commit ucitrack 78 | 79 | delete firewall.v2ray 80 | set firewall.v2ray=include 81 | set firewall.v2ray.type=script 82 | set firewall.v2ray.path=/etc/firewall.v2ray 83 | set firewall.v2ray.family=any 84 | set firewall.v2ray.reload=1 85 | commit firewall 86 | EOF 87 | 88 | rm -rf /tmp/luci-indexcache /tmp/luci-modulecache 89 | 90 | exit 0 91 | -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/v2ray/directlist.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-v2ray/root/etc/v2ray/directlist.txt -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/v2ray/proxylist.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-v2ray/root/etc/v2ray/proxylist.txt -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/v2ray/srcdirectlist.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-v2ray/root/etc/v2ray/srcdirectlist.txt -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/v2ray/transport.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-v2ray/root/etc/v2ray/transport.json -------------------------------------------------------------------------------- /luci/luci-app-v2ray/root/etc/v2ray/upload/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-v2ray/root/etc/v2ray/upload/.gitkeep -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | LUCI_TITLE:=LuCI page for KMS 10 | LUCI_DEPENDS:=+vlmcsd 11 | PKG_VERSION:=1.0 12 | PKG_RELEASE:=5 13 | 14 | include $(TOPDIR)/feeds/luci/luci.mk 15 | 16 | # call BuildPackage - OpenWrt buildroot signature 17 | 18 | 19 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/luasrc/controller/vlmcsd.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.vlmcsd", package.seeall) 2 | 3 | function index() 4 | if not nixio.fs.access("/etc/config/vlmcsd") then 5 | return 6 | end 7 | 8 | entry({"admin", "services", "vlmcsd"}, cbi("vlmcsd"), _("KMS Server"), 100).dependent = true 9 | entry({"admin", "services", "vlmcsd", "status"}, call("act_status")).leaf = true 10 | end 11 | 12 | function act_status() 13 | local e={} 14 | e.running=luci.sys.call("pgrep vlmcsd >/dev/null")==0 15 | luci.http.prepare_content("application/json") 16 | luci.http.write_json(e) 17 | end 18 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/luasrc/model/cbi/vlmcsd.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | m = Map("vlmcsd") 4 | m.title = translate("vlmcsd config") 5 | m.description = translate("A KMS Server Emulator to active your Windows or Office") 6 | 7 | m:section(SimpleSection).template = "vlmcsd/vlmcsd_status" 8 | 9 | s = m:section(TypedSection, "vlmcsd") 10 | s.addremove = false 11 | s.anonymous = true 12 | 13 | s:tab("basic", translate("Basic Setting")) 14 | enable = s:taboption("basic",Flag, "enabled", translate("Enable")) 15 | enable.rmempty = false 16 | 17 | autoactivate = s:taboption("basic", Flag, "autoactivate", translate("Auto activate")) 18 | autoactivate.rmempty = false 19 | 20 | s:tab("config", translate("Config File")) 21 | config = s:taboption("config", Value, "config", translate("configfile"), translate("This file is /etc/vlmcsd.ini."), "") 22 | config.template = "cbi/tvalue" 23 | config.rows = 13 24 | config.wrap = "off" 25 | 26 | function config.cfgvalue(self, section) 27 | return nixio.fs.readfile("/etc/vlmcsd.ini") 28 | end 29 | 30 | function config.write(self, section, value) 31 | value = value:gsub("\r\n?", "\n") 32 | nixio.fs.writefile("/etc/vlmcsd.ini", value) 33 | end 34 | 35 | return m 36 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/luasrc/view/vlmcsd/vlmcsd_status.htm: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |

20 | <%:Collecting data...%> 21 |

22 |
-------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/po/zh-cn/vlmcsd.po: -------------------------------------------------------------------------------- 1 | msgid "vlmcsd config" 2 | msgstr "KMS 服务器设置" 3 | 4 | msgid "KMS Server" 5 | msgstr "KMS 服务器" 6 | 7 | msgid "Basic Setting" 8 | msgstr "基本设置" 9 | 10 | msgid "Config File" 11 | msgstr "配置文件" 12 | 13 | msgid "A KMS Server Emulator to active your Windows or Office" 14 | msgstr "KMS服务器可用于激活Windows或Office" 15 | 16 | msgid "Vlmcsd is running." 17 | msgstr "KMS 服务器运行中" 18 | 19 | msgid "Vlmcsd is not running." 20 | msgstr "KMS 服务器未运行" 21 | 22 | msgid "Enable" 23 | msgstr "启用" 24 | 25 | msgid "Auto activate" 26 | msgstr "自动激活局域网客户端" 27 | 28 | msgid "configfile" 29 | msgstr "配置文件" 30 | 31 | msgid "This file is /etc/vlmcsd.ini." 32 | msgstr "这个文件在 /etc/vlmcsd.ini 下,可以增加新的产品主密钥。" 33 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/root/etc/config/vlmcsd: -------------------------------------------------------------------------------- 1 | 2 | config vlmcsd 'config' 3 | option autoactivate '1' 4 | option enabled '1' 5 | 6 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/root/etc/init.d/kms: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # Copyright (c) 2011-2015 OpenWrt.org 3 | 4 | START=90 5 | 6 | get_config() { 7 | config_get_bool enabled $1 enabled 0 8 | config_get autoactivate $1 autoactivate 1 9 | } 10 | 11 | add_vlmcs_entry() { 12 | local new_hostname="$1" 13 | 14 | uci -q batch <<-EOF >/dev/null 15 | add dhcp srvhost 16 | set dhcp.@srvhost[-1].srv=_vlmcs._tcp 17 | set dhcp.@srvhost[-1].target=$new_hostname 18 | set dhcp.@srvhost[-1].port=1688 19 | set dhcp.@srvhost[-1].class=0 20 | set dhcp.@srvhost[-1].weight=100 21 | commit dhcp 22 | EOF 23 | 24 | /etc/init.d/dnsmasq restart 25 | exit 0 26 | } 27 | 28 | start() { 29 | config_load vlmcsd 30 | config_foreach get_config vlmcsd 31 | [ $enabled -eq 0 ] && exit 0 32 | /usr/bin/vlmcsd -i /etc/vlmcsd.ini -L 0.0.0.0:1688 33 | echo "KMS Server has started." 34 | 35 | if [ $autoactivate -eq 1 ]; then 36 | local HOSTNAME=`uci get system.@system[0].hostname` 37 | 38 | local index=$(uci -q show dhcp |grep "].srv='_vlmcs._tcp'") \ 39 | || add_vlmcs_entry $HOSTNAME 40 | index=${index#*[} 41 | index=${index%]*} 42 | 43 | local host_name=$(uci -q get dhcp.@srvhost[$index].target) 44 | 45 | if [ "$HOSTNAME" != "$host_name" ]; then 46 | uci delete dhcp.@srvhost[$index] 47 | add_vlmcs_entry $HOSTNAME 48 | fi 49 | fi 50 | } 51 | 52 | stop() { 53 | killall -q -9 vlmcsd 54 | echo "KMS Server has stopped." 55 | } 56 | 57 | -------------------------------------------------------------------------------- /luci/luci-app-vlmcsd/root/etc/uci-defaults/luci-vlmcsd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete ucitrack.@vlmcsd[-1] 5 | add ucitrack vlmcsd 6 | set ucitrack.@vlmcsd[-1].init=kms 7 | commit ucitrack 8 | EOF 9 | 10 | uci delete firewall.kms 11 | uci add firewall rule 12 | uci rename firewall.@rule[-1]="kms" 13 | uci set firewall.@rule[-1].name="kms" 14 | uci set firewall.@rule[-1].target="ACCEPT" 15 | uci set firewall.@rule[-1].src="wan" 16 | uci set firewall.@rule[-1].proto="tcp" 17 | uci set firewall.@rule[-1].dest_port="1688" 18 | uci commit firewall 19 | 20 | rm -f /tmp/luci-indexcache 21 | exit 0 22 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | LUCI_TITLE:=LuCI for Zerotier 10 | LUCI_DEPENDS:=+zerotier 11 | LUCI_PKGARCH:=all 12 | PKG_VERSION:=1.0 13 | PKG_RELEASE:=20 14 | 15 | include $(TOPDIR)/feeds/luci/luci.mk 16 | 17 | # call BuildPackage - OpenWrt buildroot signature 18 | 19 | 20 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/luasrc/controller/zerotier.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.zerotier",package.seeall) 2 | 3 | function index() 4 | if not nixio.fs.access("/etc/config/zerotier") then 5 | return 6 | end 7 | 8 | entry({"admin","vpn"}, firstchild(), "VPN", 45).dependent = false 9 | 10 | entry({"admin", "vpn", "zerotier"},firstchild(), _("ZeroTier")).dependent = false 11 | 12 | entry({"admin", "vpn", "zerotier", "general"}, cbi("zerotier/settings"), _("Base Setting"), 1) 13 | entry({"admin", "vpn", "zerotier", "log"}, form("zerotier/info"), _("Interface Info"), 2) 14 | 15 | entry({"admin", "vpn", "zerotier", "status"}, call("act_status")) 16 | end 17 | 18 | function act_status() 19 | local e={} 20 | e.running=luci.sys.call("pgrep /usr/bin/zerotier-one >/dev/null")==0 21 | luci.http.prepare_content("application/json") 22 | luci.http.write_json(e) 23 | end 24 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua: -------------------------------------------------------------------------------- 1 | local fs = require "nixio.fs" 2 | local conffile = "/tmp/zero.info" 3 | 4 | f = SimpleForm("logview") 5 | 6 | t = f:field(TextValue, "conf") 7 | t.rmempty = true 8 | t.rows = 19 9 | function t.cfgvalue() 10 | luci.sys.exec("for i in $(ifconfig | grep 'zt' | awk '{print $1}'); do ifconfig $i; done > /tmp/zero.info") 11 | return fs.readfile(conffile) or "" 12 | end 13 | t.readonly="readonly" 14 | 15 | return f 16 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua: -------------------------------------------------------------------------------- 1 | 2 | a=Map("zerotier",translate("ZeroTier"),translate("Zerotier is an open source, cross-platform and easy to use virtual LAN")) 3 | a:section(SimpleSection).template = "zerotier/zerotier_status" 4 | 5 | t=a:section(NamedSection,"sample_config","zerotier") 6 | t.anonymous=true 7 | t.addremove=false 8 | 9 | e=t:option(Flag,"enabled",translate("Enable")) 10 | e.default=0 11 | e.rmempty=false 12 | 13 | e=t:option(DynamicList,"join",translate('ZeroTier Network ID')) 14 | e.password=true 15 | e.rmempty=false 16 | 17 | e=t:option(Flag,"nat",translate("Auto NAT Clients")) 18 | e.default=0 19 | e.rmempty=false 20 | e.description = translate("Allow zerotier clients access your LAN network") 21 | 22 | e=t:option(DummyValue,"opennewwindow" , 23 | translate("")) 24 | e.description = translate("Create or manage your zerotier network, and auth clients who could access") 25 | 26 | return a 27 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |

20 | <%:Collecting data...%> 21 |

22 |
23 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/po/zh-cn/zerotier.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "MIME-Version: 1.0\n" 4 | "Content-Type: text/plain; charset=UTF-8\n" 5 | "Content-Transfer-Encoding: 8bit\n" 6 | "X-Generator: Gtranslator 2.91.7\n" 7 | "Plural-Forms: nplurals=1; plural=0;\n" 8 | 9 | msgid "Zerotier is an open source, cross-platform and easy to use virtual LAN" 10 | msgstr "Zerotier 是一个开源,跨平台,而且适合内网穿透互联的傻瓜配置虚拟 VPN LAN" 11 | 12 | msgid "Auto NAT Clients" 13 | msgstr "自动允许客户端 NAT" 14 | 15 | msgid "Allow zerotier clients access your LAN network" 16 | msgstr "允许 Zerotier 的拨入客户端访问路由器 LAN 资源(需要在 Zerotier 管理页面设定到 LAN 网段的路由表)" 17 | 18 | msgid "Create or manage your zerotier network, and auth clients who could access" 19 | msgstr "点击跳转到 Zerotier 官网管理平台,新建或者管理网络,并允许客户端接入访问你私人网路(新接入的节点默认不允许访问)" 20 | 21 | msgid "Base Setting" 22 | msgstr "基本设置" 23 | 24 | msgid "Interface Info" 25 | msgstr "接口信息" 26 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/etc/init.d/zerotier: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=99 4 | 5 | USE_PROCD=1 6 | 7 | PROG=/usr/bin/zerotier-one 8 | CONFIG_PATH=/var/lib/zerotier-one 9 | 10 | service_triggers() { 11 | procd_add_reload_trigger "zerotier" 12 | procd_add_interface_trigger "interface.*.up" wan /etc/init.d/zerotier restart 13 | } 14 | 15 | section_enabled() { 16 | config_get_bool enabled "$1" 'enabled' 0 17 | [ $enabled -gt 0 ] 18 | } 19 | 20 | start_instance() { 21 | local cfg="$1" 22 | local port secret config_path 23 | local ARGS="" 24 | 25 | if ! section_enabled "$cfg"; then 26 | echo "disabled in config" 27 | return 1 28 | fi 29 | 30 | [ -d /etc/config/zero ] || mkdir -p /etc/config/zero 31 | config_path=/etc/config/zero 32 | 33 | config_get_bool port $cfg 'port' 34 | config_get secret $cfg 'secret' 35 | 36 | # Remove existing link or folder 37 | rm -rf $CONFIG_PATH 38 | 39 | # Create link from CONFIG_PATH to config_path 40 | if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then 41 | if [ ! -d "$config_path" ]; then 42 | echo "ZeroTier config_path does not exist: $config_path" 43 | return 44 | fi 45 | 46 | ln -s $config_path $CONFIG_PATH 47 | fi 48 | 49 | mkdir -p $CONFIG_PATH/networks.d 50 | 51 | if [ -n "$port" ]; then 52 | ARGS="$ARGS -p$port" 53 | fi 54 | 55 | if [ "$secret" = "generate" ]; then 56 | echo "Generate secret - please wait..." 57 | local sf="/tmp/zt.$cfg.secret" 58 | 59 | zerotier-idtool generate "$sf" > /dev/null 60 | [ $? -ne 0 ] && return 1 61 | 62 | secret="$(cat $sf)" 63 | rm "$sf" 64 | 65 | uci set zerotier.$cfg.secret="$secret" 66 | uci commit zerotier 67 | fi 68 | 69 | if [ -n "$secret" ]; then 70 | echo "$secret" > $CONFIG_PATH/identity.secret 71 | # make sure there is not previous identity.public 72 | rm -f $CONFIG_PATH/identity.public 73 | fi 74 | 75 | add_join() { 76 | # an (empty) config file will cause ZT to join a network 77 | touch $CONFIG_PATH/networks.d/$1.conf 78 | } 79 | 80 | config_list_foreach $cfg 'join' add_join 81 | 82 | procd_open_instance 83 | procd_set_param command $PROG $ARGS $CONFIG_PATH 84 | procd_set_param stderr 1 85 | procd_close_instance 86 | } 87 | 88 | start_service() { 89 | config_load 'zerotier' 90 | config_foreach start_instance 'zerotier' 91 | touch /tmp/zero.log && /etc/zerotier.start > /tmp/zero.log 2>&1 & 92 | } 93 | 94 | stop_instance() { 95 | rm -f /tmp/zero.log 96 | local cfg="$1" 97 | 98 | /etc/zerotier.stop > /tmp/zero.log 2>&1 & 99 | 100 | # Remove existing link or folder 101 | rm -f $CONFIG_PATH/networks.d/*.conf 102 | rm -rf $CONFIG_PATH 103 | } 104 | 105 | stop_service() { 106 | config_load 'zerotier' 107 | config_foreach stop_instance 'zerotier' 108 | } 109 | 110 | reload_service() { 111 | stop 112 | start 113 | } -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete ucitrack.@zerotier[-1] 5 | add ucitrack zerotier 6 | set ucitrack.@zerotier[-1].init=zerotier 7 | commit ucitrack 8 | delete firewall.zerotier 9 | set firewall.zerotier=include 10 | set firewall.zerotier.type=script 11 | set firewall.zerotier.path=/etc/zerotier.start 12 | set firewall.zerotier.reload=1 13 | commit firewall 14 | EOF 15 | 16 | rm -f /tmp/luci-indexcache 17 | exit 0 18 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/etc/zerotier.start: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | zero_enable="$(uci get zerotier.sample_config.enabled)" 4 | 5 | [ "${zero_enable}" -ne "1" ] && exit 0 6 | 7 | [ -f "/tmp/zero.log" ] && { 8 | while [ "$(ifconfig | grep 'zt' | awk '{print $1}')" = "" ] 9 | do 10 | sleep 1 11 | done 12 | } 13 | 14 | nat_enable="$(uci get zerotier.sample_config.nat)" 15 | zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" 16 | echo "${zt0}" > "/tmp/zt.nif" 17 | 18 | [ "${nat_enable}" -eq "1" ] && { 19 | for i in ${zt0} 20 | do 21 | ip_segment="" 22 | iptables -I FORWARD -i "$i" -j ACCEPT 23 | iptables -I FORWARD -o "$i" -j ACCEPT 24 | iptables -t nat -I POSTROUTING -o "$i" -j MASQUERADE 25 | ip_segment="$(ip route | grep "dev $i proto kernel" | awk '{print $1}')" 26 | iptables -t nat -I POSTROUTING -s "${ip_segment}" -j MASQUERADE 27 | done 28 | } 29 | -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/etc/zerotier.stop: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" 4 | [ -z "${zt0}" ] && zt0="$(cat "/tmp/zt.nif")" 5 | 6 | for i in ${zt0} 7 | do 8 | ip_segment="" 9 | iptables -D FORWARD -i "$i" -j ACCEPT 2>/dev/null 10 | iptables -D FORWARD -o "$i" -j ACCEPT 2>/dev/null 11 | iptables -t nat -D POSTROUTING -o "$i" -j MASQUERADE 2>/dev/null 12 | ip_segment="$(ip route | grep "dev $i proto" | awk '{print $1}')" 13 | iptables -t nat -D POSTROUTING -s "${ip_segment}" -j MASQUERADE 2>/dev/null 14 | echo "zt interface $i is stopped!" 15 | done -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/etc/zerotier/zerotier.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-app-zerotier/root/etc/zerotier/zerotier.log -------------------------------------------------------------------------------- /luci/luci-app-zerotier/root/usr/share/rpcd/acl.d/luci-app-zerotier.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-zerotier": { 3 | "description": "Grant UCI access for luci-app-zerotier", 4 | "read": { 5 | "uci": [ "zerotier" ] 6 | }, 7 | "write": { 8 | "uci": [ "zerotier" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /luci/luci-proto-n2n/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=luci-proto-n2n 4 | PKG_VERSION:=1.0 5 | PKG_RELEASE:=6 6 | PKG_MAINTAINER:=Jason Tse 7 | PKG_LICENSE:=GPLv3 8 | PKG_LICENSE_FILES:=LICENSE 9 | 10 | include $(INCLUDE_DIR)/package.mk 11 | 12 | define Package/luci-proto-n2n 13 | SECTION:=LuCI 14 | CATEGORY:=Gmod 15 | SUBMENU:=Luci 16 | DEPENDS:=+n2n-edge 17 | TITLE:=N2N VPN protocol support for LuCI 18 | MAINTAINER:=Jason Tse 19 | PKGARCH:=all 20 | endef 21 | 22 | define Package/luci-proto-n2n/description 23 | N2N VPN protocol support for LuCI 24 | endef 25 | 26 | define Package/luci-proto-n2n/install 27 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/admin_network 28 | $(INSTALL_DATA) ./files/cbi/proto_n2n.lua $(1)/usr/lib/lua/luci/model/cbi/admin_network 29 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/network 30 | $(INSTALL_DATA) ./files/network/proto_n2n.lua $(1)/usr/lib/lua/luci/model/network 31 | $(INSTALL_DIR) $(1)/lib/netifd/proto 32 | $(INSTALL_BIN) ./files/n2n.sh $(1)/lib/netifd/proto 33 | endef 34 | 35 | define Build/Compile 36 | endef 37 | 38 | $(eval $(call BuildPackage,luci-proto-n2n)) 39 | -------------------------------------------------------------------------------- /luci/luci-proto-n2n/files/cbi/proto_n2n.lua: -------------------------------------------------------------------------------- 1 | local map, section, net = ... 2 | local ifc = net:get_interface() 3 | 4 | local cfgcmd = "var Macaddr=document.getElementById(this.parentNode.parentNode.parentNode.id.replace('cbi', 'cbid').replace(/-/g, '.'));" .. 5 | "function randomString(len,type){len=len||32;type=type||0;" .. 6 | "var $chars='';" .. 7 | "switch(type){case 1:$chars='13579bdf';break;" .. 8 | "case 2:$chars='24680ace';break;" .. 9 | "default:$chars='0123456789abcdef';break;}" .. 10 | "var maxPos=$chars.length;var pwd='';" .. 11 | "for(i = 0; i < len; i++){pwd+=$chars.charAt(Math.floor(Math.random() * maxPos));}return pwd;};" .. 12 | "Macaddr.value=randomString(1)+randomString(1,2)+':'+randomString(2)+':'+randomString(2)+':'+randomString(2)+':'+randomString(2)+':'+randomString(2);" 13 | 14 | local cfgbtn = " 
" 15 | 16 | server = section:taboption("general", Value, "server", translate("Supernode server")) 17 | server.datatype = "host" 18 | server.rmempty = false 19 | 20 | port = section:taboption("general", Value, "port", translate("Supernode port")) 21 | port.datatype = "port" 22 | port.rmempty = false 23 | 24 | section:taboption("general", Flag, "_slave", translate("Enable slave supernode")) 25 | 26 | server2 = section:taboption("general", Value, "server2", translate("Slave supernode server")) 27 | server2:depends("_slave", 1) 28 | server2.datatype = "host" 29 | 30 | port2 = section:taboption("general", Value, "port2", translate("Slave supernode port")) 31 | port2:depends("_slave", 1) 32 | port2.datatype = "port" 33 | 34 | community = section:taboption("general", Value, "community", translate("Community")) 35 | community.rmempty = false 36 | 37 | key = section:taboption("general", Value, "key", translate("Key")) 38 | key.password = true 39 | 40 | mode = section:taboption("general", ListValue, "mode", translate("Mode")) 41 | mode:value("static", "Static") 42 | mode:value("dhcp", "DHCP") 43 | mode.default = "static" 44 | 45 | ipaddr = section:taboption("general", Value, "ipaddr", translate("IPv4 address")) 46 | ipaddr:depends("mode", "static") 47 | ipaddr.datatype = "ip4addr" 48 | 49 | netmask = section:taboption("general", Value, "netmask", translate("IPv4 netmask")) 50 | netmask:depends("mode", "static") 51 | netmask.datatype = "ip4addr" 52 | netmask.placeholder = "255.255.255.0" 53 | 54 | gateway = section:taboption("general", Value, "gateway", translate("IPv4 gateway")) 55 | gateway:depends("mode", "static") 56 | gateway.datatype = "ip4addr" 57 | 58 | if luci.model.network:has_ipv6() then 59 | ip6addr = section:taboption("general", Value, "ip6addr", translate("IPv6 address")) 60 | ip6addr.datatype = "ip6addr" 61 | 62 | ip6prefixlen = section:taboption("general", Value, "ip6prefixlen", translate("IPv6 prefix length")) 63 | ip6prefixlen.placeholder = "64" 64 | ip6prefixlen.datatype = "max(128)" 65 | 66 | ip6gw = section:taboption("general", Value, "ip6gw", translate("IPv6 gateway")) 67 | ip6gw.datatype = "ip6addr" 68 | end 69 | 70 | section:taboption("advanced", Flag, "forwarding", translate("Forwarding"), translate("Enable packet forwarding through n2n community.")) 71 | 72 | section:taboption("advanced", Flag, "dynamic", translate("Periodically resolve supernode IP"), translate("When supernodes are running on dynamic IPs.")) 73 | 74 | section:taboption("advanced", Flag, "multicast", translate("Accept multicast"), translate("Accept multicast MAC addresses.")) 75 | 76 | luci.tools.proto.opt_macaddr(section, ifc, translate("Override MAC address"), cfgbtn) 77 | 78 | mtu = section:taboption("advanced", Value, "mtu", translate("Override MTU")) 79 | mtu.placeholder = "1440" 80 | mtu.datatype = "max(9200)" 81 | 82 | metric = section:taboption("advanced", Value, "metric", translate("Metric")) 83 | metric.placeholder = "0" 84 | metric.datatype = "max(9200)" 85 | 86 | localport = section:taboption("advanced", Value, "localport", translate("Bind local port")) 87 | localport.datatype = "port" 88 | 89 | mgmtport = section:taboption("advanced", Value, "mgmtport", translate("Management port")) 90 | mgmtport.datatype = "port" 91 | 92 | section:taboption("advanced", Flag, "verbose", translate("Verbose"), translate("Make more verbose in syslog.")) 93 | -------------------------------------------------------------------------------- /luci/luci-proto-n2n/files/n2n.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | [ -n "$INCLUDE_ONLY" ] || { 4 | . /lib/functions.sh 5 | . ../netifd-proto.sh 6 | init_proto "$@" 7 | } 8 | 9 | proto_n2n_setup() { 10 | local cfg="$1" 11 | local device="n2n-$cfg" 12 | local server port server2 port2 mode ipaddr netmask gateway macaddr mtu community key forwarding ip6addr ip6prefixlen ip6gw dynamic localport mgmtport multicast verbose metric 13 | json_get_vars server port server2 port2 mode ipaddr netmask gateway macaddr mtu community key forwarding ip6addr ip6prefixlen ip6gw dynamic localport mgmtport multicast verbose metric 14 | 15 | proto_run_command "$cfg" /usr/sbin/edge -f \ 16 | -d "$device" \ 17 | -l "${server}:${port}" \ 18 | $([ -n "$server2" -a -n "$port2" ] && echo -l "${server2}:${port2}") \ 19 | -a "${mode}:${ipaddr=0.0.0.0}" \ 20 | $([ -n "$netmask" ] && echo -s $netmask) \ 21 | -c "$community" \ 22 | $([ -n "$key" ] && echo -k $key) \ 23 | $([ -n "$macaddr" ] && echo -m $macaddr) \ 24 | $([ -n "$mtu" ] && echo -M $mtu) \ 25 | $([ "$forwarding" = 1 ] && echo -r) \ 26 | $([ "$dynamic" = 1 ] && echo -b) \ 27 | $([ -n "$localport" ] && echo -p $localport) \ 28 | $([ -n "$mgmtport" ] && echo -t $mgmtport) \ 29 | $([ "$multicast" = 1 ] && echo -E) \ 30 | $([ "$verbose" = 1 ] && echo -v) 31 | 32 | proto_init_update "$device" 1 1 33 | proto_set_keep 1 34 | sleep 1 35 | 36 | proto_add_ipv4_address "$ipaddr" "$netmask" 37 | 38 | if [ -n "$ip6addr" ] && [ -n "$ip6prefixlen" ]; then 39 | ifconfig "$device" "${ip6addr}/${ip6prefixlen}" 40 | proto_add_ipv6_address "$ip6addr" "$ip6prefixlen" 41 | fi 42 | 43 | [ -n "$gateway" ] && { 44 | proto_add_ipv4_route 0.0.0.0 0 "$gateway" "" "$metric" 45 | } 46 | 47 | [ -n "$ip6gw" ] && { 48 | proto_add_ipv6_route "::" 0 "$ip6gw" "$metric" 49 | } 50 | 51 | proto_send_update "$cfg" 52 | } 53 | 54 | proto_n2n_teardown() { 55 | local cfg="$1" 56 | local device="n2n-$cfg" 57 | 58 | proto_init_update "$device" 0 59 | proto_kill_command "$1" 60 | kill -SIGKILL `ps|grep edge|grep ${device}|awk '{print $1}'` >/dev/null 2>&1 61 | proto_send_update "$cfg" 62 | } 63 | 64 | proto_n2n_init_config() { 65 | no_device=1 66 | available=1 67 | 68 | proto_config_add_string "server" 69 | proto_config_add_int "port" 70 | proto_config_add_string "server2" 71 | proto_config_add_int "port2" 72 | proto_config_add_string "mode" 73 | proto_config_add_string "ipaddr" 74 | proto_config_add_string "netmask" 75 | proto_config_add_string "gateway" 76 | proto_config_add_string "macaddr" 77 | proto_config_add_int "mtu" 78 | proto_config_add_string "community" 79 | proto_config_add_string "key" 80 | proto_config_add_boolean "forwarding" 81 | proto_config_add_string "ip6addr" 82 | proto_config_add_int "ip6prefixlen" 83 | proto_config_add_string "ip6gw" 84 | proto_config_add_boolean "dynamic" 85 | proto_config_add_int "localport" 86 | proto_config_add_int "mgmtport" 87 | proto_config_add_int "metric" 88 | proto_config_add_boolean "multicast" 89 | proto_config_add_boolean "verbose" 90 | } 91 | 92 | [ -n "$INCLUDE_ONLY" ] || { 93 | add_protocol n2n 94 | } 95 | -------------------------------------------------------------------------------- /luci/luci-proto-n2n/files/network/proto_n2n.lua: -------------------------------------------------------------------------------- 1 | local netmod = luci.model.network 2 | local interface = luci.model.network.interface 3 | local proto = netmod:register_protocol("n2n") 4 | 5 | function proto.get_i18n(self) 6 | return luci.i18n.translate("N2N VPN") 7 | end 8 | 9 | function proto.ifname(self) 10 | return "n2n-" .. self.sid 11 | end 12 | 13 | function proto.opkg_package(self) 14 | return "n2n-edge" 15 | end 16 | 17 | function proto.is_installed(self) 18 | return nixio.fs.access("/lib/netifd/proto/n2n.sh") 19 | end 20 | 21 | function proto.is_floating(self) 22 | return true 23 | end 24 | 25 | function proto.is_virtual(self) 26 | return true 27 | end 28 | 29 | function proto.get_interfaces(self) 30 | return nil 31 | end 32 | 33 | function proto.contains_interface(self, ifc) 34 | return (netmod:ifnameof(ifc) == self:ifname()) 35 | end 36 | 37 | netmod:register_pattern_virtual("^n2n-%w") 38 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/.gitignore: -------------------------------------------------------------------------------- 1 | Screenshots 2 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2019 Jerrykuku 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | LUCI_TITLE:=Argon Theme 10 | LUCI_DEPENDS:= 11 | PKG_VERSION:=2.2.7 12 | PKG_RELEASE:=20210318 13 | 14 | include $(TOPDIR)/feeds/luci/luci.mk 15 | 16 | # call BuildPackage - OpenWrt buildroot signature -------------------------------------------------------------------------------- /luci/luci-theme-argon/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

4 | A new LuCI theme for OpenWrt 5 |

6 |

7 | Argon is a clean HTML5 theme for LuCI. Users may
setup their own favorite logins, including beautiful
pics and customized mp4 videos.

8 |

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 | 37 |
38 | 39 |
English | [简体中文](README_ZH.md) 40 | 41 | ## Notice 42 | It is strongly recommended to use the Chrome browser. Some new css3 features are used in the theme, and currently only Chrome has the best compatibility. 43 | The mainline version of IE series currently has bugs to be resolved. 44 | FireFox does not enable the backdrop-filter by default, see here for the opening method: https://developer.mozilla.org/zh-CN/docs/Web/CSS/backdrop-filter 45 | 46 | v2.x.x Adapt to official mainline snapshot. 47 | You can checkout branch 18.06 for OpenWRT 18.06 or lean 19.07. 48 | 49 | ## Update Log 2020.09.13 v2.2.5 50 | 51 | - 【v2.2.5】New config app for argon theme. You can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended] [Download](https://github.com/jerrykuku/luci-app-argon-config/releases/download/v0.8-beta/luci-app-argon-config_0.8-beta_all.ipk) 52 | - 【v2.2.5】Automatically set as the default theme when compiling. 53 | - 【v2.2.5】Modify the file structure to adapt to luci-app-argon-config. The old method of turning on dark mode is no longer applicable, please use it with luci-app-argon-config. 54 | - 【v2.2.5】Adapt to Koolshare lede 2.3.6。 55 | - 【v2.2.5】Fix some Bug。 56 | - 【v2.2.4】Fix the problem that the login background cannot be displayed on some phones. 57 | - 【v2.2.4】Remove the dependency of luasocket. 58 | - 【v2.2.3】Fix Firmware flash page display error in dark mode. 59 | - 【v2.2.3】Update font icon, add a default icon of undefined menu. 60 | - 【v2.2.2】Add custom login background,put your image (allow png jpg gif) or MP4 video into /www/luci-static/argon/background, random change. 61 | - 【v2.2.2】Add force dark mode, login ssh and type "touch /etc/dark" to open dark mode. 62 | - 【v2.2.2】Add a volume mute button for video background, default is muted. 63 | - 【v2.2.2】fix login page when keyboard show the bottom text overlay the button on mobile. 64 | - 【v2.2.2】fix select color in dark mode,and add a style for scrollbar. 65 | - 【v2.2.2】jquery update to v3.5.1. 66 | - 【v2.2.2】change request bing api method form wget to luasocket (DEPENDS). 67 | - 【v2.2.1】Add blur effect for login form. 68 | - 【v2.2.1】New login theme, Request background imge from bing.com, Auto change everyday. 69 | - 【v2.2.1】New theme icon. 70 | - 【v2.2.1】Add more menu category icon. 71 | - 【v2.2.1】Fix font-size and padding margin. 72 | - 【v2.2.1】Restructure css file. 73 | - 【v2.2.1】Auto adapt to dark mode. 74 | 75 | ## How to build 76 | 77 | Enter in your openwrt/package/lean or other 78 | 79 | ### Lean lede 80 | 81 | ``` 82 | cd lede/package/lean 83 | rm -rf luci-theme-argon 84 | git clone -b 18.06 https://github.com/jerrykuku/luci-theme-argon.git 85 | make menuconfig #choose LUCI->Theme->Luci-theme-argon 86 | make -j1 V=s 87 | ``` 88 | 89 | ### Openwrt official SnapShots 90 | 91 | ``` 92 | cd openwrt/package 93 | git clone https://github.com/jerrykuku/luci-theme-argon.git 94 | make menuconfig #choose LUCI->Theme->Luci-theme-argon 95 | make -j1 V=s 96 | ``` 97 | 98 | ## How to Install 99 | 100 | ### For Lean openwrt 18.06 LuCI 101 | 102 | ``` 103 | wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v1.7.0/luci-theme-argon_1.7.0-20200909_all.ipk 104 | opkg install luci-theme-argon*.ipk 105 | ``` 106 | 107 | ### For openwrt official 19.07 Snapshots LuCI master 108 | 109 | ``` 110 | opkg install luci-compat 111 | wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.2.5/luci-theme-argon_2.2.5-20200914_all.ipk 112 | opkg install luci-theme-argon*.ipk 113 | ``` 114 | ![](/Screenshots/screenshot_pc.jpg) 115 | ![](/Screenshots/screenshot_phone.jpg) 116 | 117 | ## Thanks to 118 | 119 | luci-theme-material: https://github.com/LuttyYang/luci-theme-material/ 120 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/README_ZH.md: -------------------------------------------------------------------------------- 1 | # luci-theme-argon ([English](/README.md)) 2 | [1]: https://img.shields.io/badge/license-MIT-brightgreen.svg 3 | [2]: /LICENSE 4 | [3]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg 5 | [4]: https://github.com/jerrykuku/luci-theme-argon/pulls 6 | [5]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg 7 | [6]: https://github.com/jerrykuku/luci-theme-argon/issues/new 8 | [7]: https://img.shields.io/badge/release-v2.2.5-blue.svg? 9 | [8]: https://github.com/jerrykuku/luci-theme-argon/releases 10 | [9]: https://img.shields.io/github/downloads/jerrykuku/luci-theme-argon/total 11 | [10]: https://img.shields.io/badge/Contact-telegram-blue 12 | [11]: https://t.me/jerryk6 13 | [![license][1]][2] 14 | [![PRs Welcome][3]][4] 15 | [![Issue Welcome][5]][6] 16 | [![Release Version][7]][8] 17 | [![Release Count][9]][8] 18 | [![Contact Me][10]][11] 19 | 20 | ![](/Screenshots/screenshot_pc.jpg) 21 | ![](/Screenshots/screenshot_phone.jpg) 22 | 23 | 全新的 Openwrt 主题,基于luci-theme-material 和 开源免费的 Argon 模板进行移植。 24 | 25 | ## 注意 26 | 强烈建议使用Chrome 浏览器。主题中使用了一些新的css3特性,目前只有Chrome有最佳的兼容性。 27 | 主线版本 IE 系列目前还有Bug有待解决。 28 | FireFox 默认不开启backdrop-filter,开启方法见这里:https://developer.mozilla.org/zh-CN/docs/Web/CSS/backdrop-filter 29 | 当前master版本基于官方 OpenWrt 19.07.1 稳定版固件进行移植适配。 30 | v2.x.x 适配主线快照版本。 31 | v1.x.x 适配18.06 和 Lean Openwrt [如果你是lean代码 请选择这个版本] 32 | 33 | 34 | ## 更新日志 2020.09.13 v2.2.5 35 | 36 | - 【v2.2.5】全新的设置app.你可以设置argon 主题的登录页面的模糊和透明度,并管理背景图片与视频。[建议使用 Chrome][点击下载](https://github.com/jerrykuku/luci-app-argon-config/releases/download/v0.8-beta/luci-app-argon-config_0.8-beta_all.ipk) 37 | - 【v2.2.5】当编译固件时,将自动设置为默认主题。 38 | - 【v2.2.5】修改文件结构,以适应luci-app-argon-config,旧的开启暗色模式方法将不再适用,请搭配luci-app-argon-config使用。 39 | - 【v2.2.5】适配Koolshare lede 2.3.6。 40 | - 【v2.2.5】修复了一些Bug。 41 | - 【v2.2.4】修复了在某些手机下图片背景第一次加载不能显示的问题。 42 | - 【v2.2.4】取消 luasocket 的依赖,无需再担心依赖问题。 43 | - 【v2.2.3】修正了在暗色模式下,固件刷写弹窗内的显示错误。 44 | - 【v2.2.3】更新了图标库,为未定义的菜单增加了一个默认的图标。 45 | - 【v2.2.2】背景文件策略调整为,同时接受 jpg png gif mp4, 自行上传文件至 /www/luci-static/argon/background 图片和视频同时随机。 46 | - 【v2.2.2】增加强制暗色模式,进入ssh 输入 "touch /etc/dark" 进行开启。 47 | - 【v2.2.2】视频背景加了一个音量开关,喜欢带声音的可以自行点击开启,默认为静音模式。 48 | - 【v2.2.2】修复了手机模式下,登录页面出现键盘时,文字覆盖按钮的问题。 49 | - 【v2.2.2】修正了暗黑模式下下拉选项的背景颜色,同时修改了滚动条的样式。 50 | - 【v2.2.2】jquery 更新到 v3.5.1。 51 | - 【v2.2.2】获取Bing Api 的方法从wget 更新到luasocket 并添加依赖。 52 | - 【v2.2.1】登录背景添加毛玻璃效果。 53 | - 【v2.2.1】全新的登录界面,图片背景跟随Bing.com,每天自动切换。 54 | - 【v2.2.1】全新的主题icon。 55 | - 【v2.2.1】增加多个导航icon。 56 | - 【v2.2.1】细致的微调了 字号大小边距等等。 57 | - 【v2.2.1】重构了css文件。 58 | - 【v2.2.1】自动适应的暗黑模式。 59 | 60 | ## 如何编译 61 | 62 | 进入 openwrt/package/lean 或者其他目录 63 | 64 | ### Lean源码 65 | 66 | ``` 67 | cd lede/package/lean 68 | rm -rf luci-theme-argon 69 | git clone -b 18.06 https://github.com/jerrykuku/luci-theme-argon.git 70 | make menuconfig #choose LUCI->Theme->Luci-theme-argon 71 | make -j1 V=s 72 | ``` 73 | 74 | ### Openwrt 官方源码 75 | 76 | ``` 77 | cd openwrt/package 78 | git clone https://github.com/jerrykuku/luci-theme-argon.git 79 | make menuconfig #choose LUCI->Theme->Luci-theme-argon 80 | make -j1 V=s 81 | ``` 82 | 83 | ## 如何安装 84 | 85 | ### Lean源码 86 | 87 | ``` 88 | wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v1.7.0/luci-theme-argon_1.7.0-20200909_all.ipk 89 | opkg install luci-theme-argon*.ipk 90 | ``` 91 | 92 | ### For openwrt official 19.07 Snapshots LuCI master 93 | 94 | ``` 95 | wget --no-check-certificate https://github.com/jerrykuku/luci-theme-argon/releases/download/v2.2.5/luci-theme-argon_2.2.5-20200914_all.ipk 96 | opkg install luci-theme-argon*.ipk 97 | ``` 98 | 99 | ## 感谢 100 | 101 | luci-theme-material: https://github.com/LuttyYang/luci-theme-material/ 102 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/background/README.md: -------------------------------------------------------------------------------- 1 | Drop background here! 2 | accept jpg png gif and mp4 3 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/favicon.ico -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.eot -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.ttf -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/TypoGraphica.woff -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.eot -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.ttf -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/fonts/argon.woff -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/android-icon-192x192.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-144x144.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-60x60.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/apple-icon-72x72.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-16x16.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-32x32.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/favicon-96x96.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Openwrt", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/icon/ms-icon-144x144.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/icon/spinner.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/img/argon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 35 | 41 | 49 | 53 | 55 | 57 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/img/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/img/bg1.jpg -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/img/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostry/openwrt-gmod/937a44f4af08818875d99eb1a90578a770e870de/luci/luci-theme-argon/htdocs/luci-static/argon/img/blank.png -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/img/volume_high.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/img/volume_off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/argon/js/polyfill.min.js: -------------------------------------------------------------------------------- 1 | /* Disable minification (remove `.min` from URL path) for more info */ 2 | 3 | (function(undefined) {}).call('object' === typeof window && window || 'object' === typeof self && self || 'object' === typeof global && global || {}); -------------------------------------------------------------------------------- /luci/luci-theme-argon/htdocs/luci-static/resources/menu.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 'require baseclass'; 3 | 'require ui'; 4 | 5 | return baseclass.extend({ 6 | __init__: function () { 7 | ui.menu.load().then(L.bind(this.render, this)); 8 | }, 9 | 10 | render: function (tree) { 11 | var node = tree, 12 | url = '', 13 | children = ui.menu.getChildren(tree); 14 | 15 | for (var i = 0; i < children.length; i++) { 16 | var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0); 17 | 18 | if (isActive) 19 | this.renderMainMenu(children[i], children[i].name); 20 | } 21 | 22 | if (L.env.dispatchpath.length >= 3) { 23 | for (var i = 0; i < 3 && node; i++) { 24 | node = node.children[L.env.dispatchpath[i]]; 25 | url = url + (url ? '/' : '') + L.env.dispatchpath[i]; 26 | } 27 | 28 | if (node) 29 | this.renderTabMenu(node, url); 30 | } 31 | 32 | document.querySelector('a.showSide') 33 | .addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle')); 34 | document.querySelector('.darkMask') 35 | .addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle')); 36 | }, 37 | 38 | handleMenuExpand: function (ev) { 39 | var a = ev.target, slide = a.parentNode, slide_menu = a.nextElementSibling; 40 | 41 | document.querySelectorAll('.main .main-left .nav > li >ul.active').forEach(function (ul) { 42 | if (ul !== slide_menu) { 43 | ul.classList.remove('active'); 44 | ul.previousElementSibling.classList.remove('active'); 45 | } 46 | 47 | }); 48 | 49 | if (!slide_menu) 50 | return; 51 | 52 | slide_menu.classList.add('active'); 53 | a.classList.add('active'); 54 | a.blur(); 55 | ev.preventDefault(); 56 | ev.stopPropagation(); 57 | }, 58 | 59 | renderMainMenu: function (tree, url, level) { 60 | var l = (level || 0) + 1, 61 | ul = E('ul', { 'class': level ? 'slide-menu' : 'nav' }), 62 | children = ui.menu.getChildren(tree); 63 | 64 | if (children.length == 0 || l > 2) 65 | return E([]); 66 | 67 | for (var i = 0; i < children.length; i++) { 68 | var isActive = ((L.env.dispatchpath[l] == children[i].name) && (L.env.dispatchpath[l - 1] == tree.name)), 69 | submenu = this.renderMainMenu(children[i], url + '/' + children[i].name, l), 70 | hasChildren = submenu.children.length, 71 | slideClass = hasChildren ? 'slide' : null, 72 | menuClass = hasChildren ? 'menu' : null; 73 | if (isActive) { 74 | ul.classList.add('active'); 75 | slideClass += " active"; 76 | menuClass += " active"; 77 | } 78 | 79 | ul.appendChild(E('li', { 'class': slideClass }, [ 80 | E('a', { 81 | 'href': L.url(url, children[i].name), 82 | 'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null, 83 | 'class': menuClass, 84 | 'data-title': hasChildren ? children[i].title.replace(" ", "_") : children[i].title.replace(" ", "_"), 85 | }, [_(children[i].title)]), 86 | submenu 87 | ])); 88 | } 89 | 90 | if (l == 1) { 91 | document.querySelector('#mainmenu').appendChild(ul); 92 | document.querySelector('#mainmenu').style.display = ''; 93 | 94 | } 95 | return ul; 96 | }, 97 | 98 | renderTabMenu: function (tree, url, level) { 99 | var container = document.querySelector('#tabmenu'), 100 | l = (level || 0) + 1, 101 | ul = E('ul', { 'class': 'tabs' }), 102 | children = ui.menu.getChildren(tree), 103 | activeNode = null; 104 | 105 | if (children.length == 0) 106 | return E([]); 107 | 108 | for (var i = 0; i < children.length; i++) { 109 | var isActive = (L.env.dispatchpath[l + 2] == children[i].name), 110 | activeClass = isActive ? ' active' : '', 111 | className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass); 112 | 113 | ul.appendChild(E('li', { 'class': className }, [ 114 | E('a', { 'href': L.url(url, children[i].name) }, [_(children[i].title)]) 115 | ])); 116 | 117 | if (isActive) 118 | activeNode = children[i]; 119 | } 120 | 121 | container.appendChild(ul); 122 | container.style.display = ''; 123 | 124 | if (activeNode) 125 | container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l)); 126 | 127 | return ul; 128 | }, 129 | 130 | handleSidebarToggle: function (ev) { 131 | var showside = document.querySelector('a.showSide'), 132 | sidebar = document.querySelector('#mainmenu'), 133 | darkmask = document.querySelector('.darkMask'), 134 | scrollbar = document.querySelector('.main-right'); 135 | 136 | if (showside.classList.contains('active')) { 137 | showside.classList.remove('active'); 138 | sidebar.classList.remove('active'); 139 | scrollbar.classList.remove('active'); 140 | darkmask.classList.remove('active'); 141 | } 142 | else { 143 | showside.classList.add('active'); 144 | sidebar.classList.add('active'); 145 | scrollbar.classList.add('active'); 146 | darkmask.classList.add('active'); 147 | } 148 | } 149 | }); 150 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/footer.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template 3 | 4 | luci-theme-argon 5 | Copyright 2020 Jerrykuku 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/jerrykuku/luci-theme-argon/issues 9 | 10 | luci-theme-material: 11 | Copyright 2015 Lutty Yang 12 | 13 | Agron Theme 14 | https://demos.creative-tim.com/argon-dashboard/index.html 15 | 16 | Licensed to the public under the Apache License 2.0 17 | -%> 18 | 19 | <% local ver = require "luci.version" %> 20 | 21 | 29 | 30 | 31 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/footer_login.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template 3 | 4 | luci-theme-argon 5 | Copyright 2020 Jerrykuku 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/jerrykuku/luci-theme-argon/issues 9 | 10 | luci-theme-material: 11 | Copyright 2015 Lutty Yang 12 | 13 | Agron Theme 14 | https://demos.creative-tim.com/argon-dashboard/index.html 15 | 16 | Licensed to the public under the Apache License 2.0 17 | -%> 18 | 19 | <% local ver = require "luci.version" %> 20 | 21 | 29 | 30 | 31 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/header_login.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argon Template 3 | 4 | luci-theme-argon 5 | Copyright 2020 Jerrykuku 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/jerrykuku/luci-theme-argon/issues 9 | 10 | luci-theme-material: 11 | Copyright 2015 Lutty Yang 12 | 13 | Argon Theme 14 | https://demos.creative-tim.com/argon-dashboard/index.html 15 | 16 | Licensed to the public under the Apache License 2.0 17 | -%> 18 | 19 | <% 20 | local sys = require "luci.sys" 21 | local util = require "luci.util" 22 | local http = require "luci.http" 23 | local disp = require "luci.dispatcher" 24 | 25 | local boardinfo = util.ubus("system", "board") 26 | 27 | local node = disp.context.dispatched 28 | 29 | local fs = require "nixio.fs" 30 | local nutil = require "nixio.util" 31 | local uci = require 'luci.model.uci'.cursor() 32 | 33 | -- send as HTML5 34 | http.prepare_content("text/html") 35 | 36 | math.randomseed(tonumber(tostring(os.time()):reverse():sub(1, 9))) 37 | 38 | -- Custom settings 39 | local mode = 'normal' 40 | local dark_css = fs.readfile('/www/luci-static/argon/css/dark.css') 41 | local bar_color = '#5e72e4' 42 | local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity 43 | if fs.access('/etc/config/argon') then 44 | primary = uci:get_first('argon', 'global', 'primary') 45 | dark_primary = uci:get_first('argon', 'global', 'dark_primary') 46 | blur_radius = uci:get_first('argon', 'global', 'blur') 47 | blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark') 48 | blur_opacity = uci:get_first('argon', 'global', 'transparency') 49 | blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark') 50 | mode = uci:get_first('argon', 'global', 'mode') 51 | bar_color = mode == 'dark' and dark_primary or primary 52 | end 53 | -%> 54 | 55 | 56 | 57 | 58 | 59 | 60 | <%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> 61 | - LuCI 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | - LuCI"> 73 | - LuCI"> 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 105 | 106 | <% if node and node.css then %> 107 | 108 | <% end -%> 109 | <% if css then %> 110 | 113 | <% end -%> 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | "> 124 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/out_footer_login.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2008 Steven Barth 3 | Copyright 2008-2019 Jo-Philipp Wich 4 | Licensed to the public under the Apache License 2.0. 5 | -%> 6 | 7 | <% 8 | local is_rollback_pending, rollback_time_remaining, rollback_session, rollback_token = luci.model.uci:rollback_pending() 9 | 10 | if is_rollback_pending or trigger_apply or trigger_revert then 11 | %> 12 | 23 | <% 24 | end 25 | 26 | include("themes/" .. theme .. "/footer_login") 27 | %> 28 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/out_header_login.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2008 Steven Barth 3 | Copyright 2008-2019 Jo-Philipp Wich 4 | Licensed to the public under the Apache License 2.0. 5 | -%> 6 | 7 | <% 8 | if not luci.dispatcher.context.template_header_sent then 9 | include("themes/" .. theme .. "/header_login") 10 | luci.dispatcher.context.template_header_sent = true 11 | end 12 | 13 | local applyconf = luci.config and luci.config.apply 14 | %> 15 | 16 | 17 | 18 | 39 | -------------------------------------------------------------------------------- /luci/luci-theme-argon/luasrc/view/themes/argon/sysauth.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Argon is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI and Argon Template 3 | 4 | luci-theme-argon 5 | Copyright 2020 Jerryk 6 | 7 | Have a bug? Please create an issue here on GitHub! 8 | https://github.com/jerrykuku/luci-theme-argon/issues 9 | 10 | luci-theme-bootstrap: 11 | Copyright 2008 Steven Barth 12 | Copyright 2008-2016 Jo-Philipp Wich 13 | Copyright 2012 David Menting 14 | 15 | MUI: 16 | https://github.com/muicss/mui 17 | 18 | Argon Theme 19 | https://demos.creative-tim.com/argon-dashboard/index.html 20 | 21 | Licensed to the public under the Apache License 2.0 22 | -%> 23 | 24 | <%+themes/argon/out_header_login%> 25 | <% 26 | local util = require "luci.util" 27 | local boardinfo = util.ubus("system", "board") 28 | local fs = require "nixio.fs" 29 | local nutil = require "nixio.util" 30 | 31 | function glob(...) 32 | local iter, code, msg = fs.glob(...) 33 | if iter then 34 | return nutil.consume(iter) 35 | else 36 | return nil, code, msg 37 | end 38 | end 39 | 40 | function getExtension(str) 41 | return str:match(".+%.(%w+)$") 42 | end 43 | 44 | local bgcount = 0 45 | local currentBg = {} 46 | local bgs,attr = {} 47 | local theme_dir = media .. "/background/" 48 | for i, f in ipairs(glob("/www" .. theme_dir .. "*")) do 49 | attr = fs.stat(f) 50 | if attr then 51 | local ext = getExtension(fs.basename(f)) 52 | if ext == "jpg" or ext == "png" or ext == "gif" or ext == "mp4" then 53 | local bg = {} 54 | bg.type = ext 55 | bg.url = theme_dir .. fs.basename(f) 56 | table.insert(bgs,bg) 57 | bgcount = bgcount + 1 58 | end 59 | end 60 | end 61 | 62 | if bgcount > 0 then 63 | currentBg = bgs[math.random(1,bgcount)] 64 | end 65 | %> 66 |