mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-10 19:12:33 +08:00
Merge Lean's source
This commit is contained in:
parent
e229035c61
commit
9882b97bf3
@ -0,0 +1,5 @@
|
||||
/usr/share/adbyby/adhost.conf
|
||||
/usr/share/adbyby/adblack.conf
|
||||
/usr/share/adbyby/blockip.conf
|
||||
/usr/share/adbyby/adesc.conf
|
||||
/usr/share/adbyby/rules.txt
|
@ -1,21 +0,0 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for PPTP VPN Server
|
||||
LUCI_DEPENDS:=+pptpd +kmod-mppe +ppp
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_NAME:=luci-app-pptp-server
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=13
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
|
||||
module("luci.controller.pptp-server", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/pptpd") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin", "vpn", "pptp-server"}, cbi("pptp-server/pptp-server"), _("PPTP VPN Server"), 80).dependent=false
|
||||
entry({"admin", "vpn", "pptp-server","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep pptpd >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
@ -1,37 +0,0 @@
|
||||
|
||||
mp = Map("pptpd", translate("PPTP VPN Server"))
|
||||
mp.description = translate("PPTP VPN Server connectivity using the native built-in VPN Client on Windows/Linux or Andriod")
|
||||
|
||||
mp:section(SimpleSection).template = "pptp/pptp_status"
|
||||
|
||||
s = mp:section(NamedSection, "pptpd", "service")
|
||||
s.anonymouse = true
|
||||
|
||||
enabled = s:option(Flag, "enabled", translate("Enable"))
|
||||
enabled.default = 0
|
||||
enabled.rmempty = false
|
||||
|
||||
localip = s:option(Value, "localip", translate("Local IP"))
|
||||
localip.datatype = "ip4addr"
|
||||
|
||||
clientip = s:option(Value, "remoteip", translate("Client IP"))
|
||||
clientip.datatype = "string"
|
||||
clientip.description = translate("LAN DHCP reserved start-to-end IP addresses with the same subnet mask")
|
||||
|
||||
remotedns = s:option(Value, "remotedns", translate("Remote Client DNS"))
|
||||
remotedns.datatype = "ip4addr"
|
||||
|
||||
logging = s:option(Flag, "logwtmp", translate("Debug Logging"))
|
||||
logging.default = 0
|
||||
logging.rmempty = false
|
||||
|
||||
logins = mp:section(NamedSection, "login", "login", translate("PPTP Logins"))
|
||||
logins.anonymouse = true
|
||||
|
||||
username = logins:option(Value, "username", translate("User name"))
|
||||
username.datatype = "string"
|
||||
|
||||
password = logins:option(Value, "password", translate("Password"))
|
||||
password.password = true
|
||||
|
||||
return mp
|
@ -1,22 +0,0 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[vpn]], [[pptp-server]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('pptp_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>PPTP VPN Server <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>PPTP VPN Server <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="pptp_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
@ -1,88 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh-Hans\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:17
|
||||
msgid "Client IP"
|
||||
msgstr "客户端分配的IP范围"
|
||||
|
||||
#: luasrc/view/pptp/pptp_status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:24
|
||||
msgid "Debug Logging"
|
||||
msgstr "记录日志"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:10
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:19
|
||||
msgid "LAN DHCP reserved start-to-end IP addresses with the same subnet mask"
|
||||
msgstr ""
|
||||
"使用和 LAN 同一网段。请使用 DHCP分配地址以外的空余IP地址范围,例如 "
|
||||
"192.168.0.20-30"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:14
|
||||
msgid "Local IP"
|
||||
msgstr "PPTP 服务器IP"
|
||||
|
||||
#: luasrc/view/pptp/pptp_status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:28
|
||||
msgid "PPTP Logins"
|
||||
msgstr "PPTP 登录设置"
|
||||
|
||||
#: luasrc/controller/pptp-server.lua:10
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:2
|
||||
msgid "PPTP VPN Server"
|
||||
msgstr "PPTP VPN 服务器"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:3
|
||||
msgid ""
|
||||
"PPTP VPN Server connectivity using the native built-in VPN Client on Windows/"
|
||||
"Linux or Andriod"
|
||||
msgstr "使用Windows/Linux 或者 Andriod 内置的 PPTP VPN 客户端进行连接 "
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:34
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: luasrc/view/pptp/pptp_status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:21
|
||||
msgid "Remote Client DNS"
|
||||
msgstr "客户端分配IP的DNS服务器"
|
||||
|
||||
#: luasrc/model/cbi/pptp-server/pptp-server.lua:31
|
||||
msgid "User name"
|
||||
msgstr "用户名"
|
||||
|
||||
#~ msgid "Disable from startup"
|
||||
#~ msgstr "禁止开机启动"
|
||||
|
||||
#~ msgid "Enable on startup"
|
||||
#~ msgstr "允许开机启动"
|
||||
|
||||
#~ msgid "PPTP Service"
|
||||
#~ msgstr "PPTP 服务设置"
|
||||
|
||||
#~ msgid "PPTPD status"
|
||||
#~ msgstr "PPTPD 服务状态"
|
||||
|
||||
#~ msgid "Start"
|
||||
#~ msgstr "启动"
|
||||
|
||||
#~ msgid "Stop"
|
||||
#~ msgstr "关闭"
|
@ -1,56 +0,0 @@
|
||||
msgid "Disable from startup"
|
||||
msgstr "禁止开机启动"
|
||||
|
||||
msgid "Enable on startup"
|
||||
msgstr "允许开机启动"
|
||||
|
||||
msgid "PPTP VPN Server"
|
||||
msgstr "PPTP VPN 服务器"
|
||||
|
||||
msgid "PPTP Service"
|
||||
msgstr "PPTP 服务设置"
|
||||
|
||||
msgid "Local IP"
|
||||
msgstr "PPTP 服务器IP"
|
||||
|
||||
msgid "Client IP"
|
||||
msgstr "客户端分配的IP范围"
|
||||
|
||||
msgid "LAN DHCP reserved start-to-end IP addresses with the same subnet mask"
|
||||
msgstr "使用和 LAN 同一网段。请使用 DHCP分配地址以外的空余IP地址范围,例如 192.168.0.20-30"
|
||||
|
||||
msgid "Remote Client DNS"
|
||||
msgstr "客户端分配IP的DNS服务器"
|
||||
|
||||
msgid "Debug Logging"
|
||||
msgstr "记录日志"
|
||||
|
||||
msgid "PPTP Logins"
|
||||
msgstr "PPTP 登录设置"
|
||||
|
||||
msgid "User name"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "PPTPD status"
|
||||
msgstr "PPTPD 服务状态"
|
||||
|
||||
msgid "Start"
|
||||
msgstr "启动"
|
||||
|
||||
msgid "Stop"
|
||||
msgstr "关闭"
|
||||
|
||||
msgid "PPTP VPN Server"
|
||||
msgstr "PPTP VPN 服务器"
|
||||
|
||||
msgid "PPTP VPN Server connectivity using the native built-in VPN Client on Windows/Linux or Andriod"
|
||||
msgstr "使用Windows/Linux 或者 Andriod 内置的 PPTP VPN 客户端进行连接 "
|
||||
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
|
||||
config service 'pptpd'
|
||||
option enabled '0'
|
||||
option remoteip '192.168.0.20-30'
|
||||
option remotedns '192.168.0.1'
|
||||
option logwtmp '0'
|
||||
option localip '192.168.0.1'
|
||||
|
||||
config login 'login'
|
||||
option username 'lean'
|
||||
option password 'I234567B'
|
||||
|
@ -1,6 +0,0 @@
|
||||
iptables -D forwarding_rule -i ppp+ -j ACCEPT 2>/dev/null
|
||||
iptables -D forwarding_rule -o ppp+ -j ACCEPT 2>/dev/null
|
||||
|
||||
iptables -A forwarding_rule -i ppp+ -j ACCEPT
|
||||
iptables -A forwarding_rule -o ppp+ -j ACCEPT
|
||||
echo 1 > /proc/sys/net/ipv4/conf/br-lan/proxy_arp
|
@ -1,37 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete firewall.pptpd
|
||||
set firewall.pptpd=include
|
||||
set firewall.pptpd.type=script
|
||||
set firewall.pptpd.path=/etc/pptpd.include
|
||||
set firewall.pptpd.reload=1
|
||||
delete firewall.pptp
|
||||
add firewall rule
|
||||
rename firewall.@rule[-1]="pptp"
|
||||
set firewall.@rule[-1].name="pptp"
|
||||
set firewall.@rule[-1].target="ACCEPT"
|
||||
set firewall.@rule[-1].src="wan"
|
||||
set firewall.@rule[-1].proto="tcp"
|
||||
set firewall.@rule[-1].dest_port="1723"
|
||||
delete firewall.gre
|
||||
add firewall rule
|
||||
rename firewall.@rule[-1]="gre"
|
||||
set firewall.@rule[-1].name="gre"
|
||||
set firewall.@rule[-1].target="ACCEPT"
|
||||
set firewall.@rule[-1].src="wan"
|
||||
set firewall.@rule[-1].proto="47"
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@pptpd[-1]
|
||||
add ucitrack pptpd
|
||||
set ucitrack.@pptpd[-1].init=pptpd
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
/etc/init.d/pptpd enable && /etc/init.d/pptpd restart
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
674
package/lean/luci-app-v2ray-server/LICENSE
Normal file
674
package/lean/luci-app-v2ray-server/LICENSE
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
@ -1,15 +1,15 @@
|
||||
# Copyright (C) 2018-2019 Lienol
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for V2ray Server
|
||||
LUCI_DEPENDS:=+v2ray
|
||||
LUCI_DEPENDS:=+v2ray
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=1.1
|
||||
PKG_RELEASE:=3
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
@ -1,47 +1,41 @@
|
||||
module("luci.controller.v2ray_server",package.seeall)
|
||||
module("luci.controller.v2ray_server", package.seeall)
|
||||
local http = require "luci.http"
|
||||
local v2ray = require "luci.model.cbi.v2ray_server.api.v2ray"
|
||||
local v2ray = require "luci.model.cbi.v2ray_server.api.v2ray"
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/v2ray_server")then
|
||||
return
|
||||
end
|
||||
entry({"admin","vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin","vpn","v2ray_server"},cbi("v2ray_server/index"),_("V2ray Server"),3).dependent=true
|
||||
entry({"admin","vpn","v2ray_server","config"},cbi("v2ray_server/config")).leaf=true
|
||||
|
||||
entry({"admin","vpn","v2ray_server","users_status"},call("v2ray_users_status")).leaf=true
|
||||
entry({"admin", "vpn", "v2ray_server", "check"}, call("v2ray_check")).leaf = true
|
||||
entry({"admin", "vpn", "v2ray_server", "update"}, call("v2ray_update")).leaf = true
|
||||
if not nixio.fs.access("/etc/config/v2ray_server") then return end
|
||||
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin", "vpn", "v2ray_server"}, cbi("v2ray_server/index"),
|
||||
_("V2ray Server"), 3).dependent = true
|
||||
entry({"admin", "vpn", "v2ray_server", "config"}, cbi("v2ray_server/config")).leaf =
|
||||
true
|
||||
|
||||
entry({"admin", "vpn", "v2ray_server", "users_status"},
|
||||
call("v2ray_users_status")).leaf = true
|
||||
entry({"admin", "vpn", "v2ray_server", "get_log"}, call("get_log")).leaf =
|
||||
true
|
||||
entry({"admin", "vpn", "v2ray_server", "clear_log"}, call("clear_log")).leaf =
|
||||
true
|
||||
end
|
||||
|
||||
local function http_write_json(content)
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(content or { code = 1 })
|
||||
http.prepare_content("application/json")
|
||||
http.write_json(content or {code = 1})
|
||||
end
|
||||
|
||||
function v2ray_users_status()
|
||||
local e={}
|
||||
e.index=luci.http.formvalue("index")
|
||||
e.status=luci.sys.call("ps -w| grep -v grep | grep '/var/etc/v2ray_server/" .. luci.http.formvalue("id") .. "' >/dev/null")==0
|
||||
http_write_json(e)
|
||||
local e = {}
|
||||
e.index = luci.http.formvalue("index")
|
||||
e.status = luci.sys.call(
|
||||
"ps -w| grep -v grep | grep '/var/etc/v2ray_server/" ..
|
||||
luci.http.formvalue("id") .. "' >/dev/null") == 0
|
||||
http_write_json(e)
|
||||
end
|
||||
|
||||
function v2ray_check()
|
||||
local json = v2ray.to_check("")
|
||||
http_write_json(json)
|
||||
function get_log()
|
||||
luci.http.write(luci.sys.exec(
|
||||
"[ -f '/var/log/v2ray_server/app.log' ] && cat /var/log/v2ray_server/app.log"))
|
||||
end
|
||||
|
||||
function v2ray_update()
|
||||
local json = nil
|
||||
local task = http.formvalue("task")
|
||||
if task == "extract" then
|
||||
json = v2ray.to_extract(http.formvalue("file"), http.formvalue("subfix"))
|
||||
elseif task == "move" then
|
||||
json = v2ray.to_move(http.formvalue("file"))
|
||||
else
|
||||
json = v2ray.to_download(http.formvalue("url"))
|
||||
end
|
||||
function clear_log() luci.sys.call("echo '' > /var/log/v2ray_server/app.log") end
|
||||
|
||||
http_write_json(json)
|
||||
end
|
@ -1,92 +1,124 @@
|
||||
local ucursor = require "luci.model.uci".cursor()
|
||||
local ucursor = require"luci.model.uci".cursor()
|
||||
local json = require "luci.jsonc"
|
||||
local server_section = arg[1]
|
||||
local server = ucursor:get_all("v2ray_server", server_section)
|
||||
|
||||
local proset
|
||||
local settings = nil
|
||||
local routing = nil
|
||||
|
||||
if server.protocol == "vmess" then
|
||||
proset = {
|
||||
clients = {
|
||||
{
|
||||
id = server.VMess_id,
|
||||
alterId = tonumber(server.VMess_alterId),
|
||||
level = tonumber(server.VMess_level)
|
||||
}
|
||||
}
|
||||
}
|
||||
if server.VMess_id then
|
||||
local clients = {}
|
||||
for i = 1, #server.VMess_id do
|
||||
clients[i] = {
|
||||
id = server.VMess_id[i],
|
||||
level = tonumber(server.VMess_level),
|
||||
alterId = tonumber(server.VMess_alterId)
|
||||
}
|
||||
end
|
||||
settings = {clients = clients}
|
||||
end
|
||||
elseif server.protocol == "socks" then
|
||||
settings = {
|
||||
auth = (server.socks_username == nil and server.socks_password == nil) and
|
||||
"password" or "noauth",
|
||||
accounts = {
|
||||
{
|
||||
user = (server.socks_username == nil) and "" or
|
||||
server.socks_username,
|
||||
pass = (server.socks_password == nil) and "" or
|
||||
server.socks_password
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif server.protocol == "http" then
|
||||
proset = {
|
||||
allowTransparent = false,
|
||||
accounts = {
|
||||
{
|
||||
user = (server.Http_user == nil) and "" or server.Http_user,
|
||||
pass = (server.Http_pass == nil) and "" or server.Http_pass
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
proset = {
|
||||
auth = (server.Socks_user == nil) and "noauth" or "password",
|
||||
accounts = {
|
||||
{
|
||||
user = (server.Socks_user == nil) and "" or server.Socks_user,
|
||||
pass = (server.Socks_pass == nil) and "" or server.Socks_pass
|
||||
}
|
||||
}
|
||||
}
|
||||
settings = {
|
||||
allowTransparent = false,
|
||||
accounts = {
|
||||
{
|
||||
user = (server.socks_username == nil) and "" or
|
||||
server.socks_username,
|
||||
pass = (server.socks_password == nil) and "" or
|
||||
server.socks_password
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif server.protocol == "shadowsocks" then
|
||||
settings = {
|
||||
method = server.ss_method,
|
||||
password = server.ss_password,
|
||||
level = tonumber(server.ss_level),
|
||||
network = server.ss_network,
|
||||
ota = (server.ss_ota == '1') and true or false
|
||||
}
|
||||
end
|
||||
|
||||
if server.accept_lan == nil or server.accept_lan == "0" then
|
||||
routing = {
|
||||
domainStrategy = "IPOnDemand",
|
||||
rules = {
|
||||
{
|
||||
type = "field",
|
||||
ip = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
|
||||
outboundTag = "blocked"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
local v2ray = {
|
||||
log = {
|
||||
--error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = {
|
||||
port = tonumber(server.port),
|
||||
protocol = server.protocol,
|
||||
settings = proset,
|
||||
-- 底层传输配置
|
||||
streamSettings = {
|
||||
network = server.transport,
|
||||
security = (server.tls == '1') and "tls" or "none",
|
||||
kcpSettings = (server.transport == "mkcp") and {
|
||||
mtu = tonumber(server.mkcp_mtu),
|
||||
tti = tonumber(server.mkcp_tti),
|
||||
uplinkCapacity = tonumber(server.mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(server.mkcp_downlinkCapacity),
|
||||
congestion = (server.mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(server.mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(server.mkcp_writeBufferSize),
|
||||
header = {
|
||||
type = server.mkcp_guise
|
||||
}
|
||||
} or nil,
|
||||
httpSettings = (server.transport == "h2") and {
|
||||
path = server.h2_path,
|
||||
host = server.h2_host,
|
||||
} or nil,
|
||||
quicSettings = (server.transport == "quic") and {
|
||||
security = server.quic_security,
|
||||
key = server.quic_key,
|
||||
header = {
|
||||
type = server.quic_guise
|
||||
}
|
||||
} or nil
|
||||
}
|
||||
},
|
||||
-- 传出连接
|
||||
outbound = {
|
||||
protocol = "freedom"
|
||||
},
|
||||
-- 额外传出连接
|
||||
outboundDetour = {
|
||||
{
|
||||
protocol = "blackhole",
|
||||
tag = "blocked"
|
||||
}
|
||||
}
|
||||
log = {
|
||||
-- error = "/var/log/v2ray.log",
|
||||
loglevel = "warning"
|
||||
},
|
||||
-- 传入连接
|
||||
inbound = {
|
||||
listen = (server.bind_local == "1") and "127.0.0.1" or nil,
|
||||
port = tonumber(server.port),
|
||||
protocol = server.protocol,
|
||||
-- 底层传输配置
|
||||
settings = settings,
|
||||
streamSettings = (server.protocol == "vmess") and {
|
||||
network = server.transport,
|
||||
security = (server.tls_enable == '1') and "tls" or "none",
|
||||
tlsSettings = (server.tls_enable == '1') and {
|
||||
-- serverName = (server.tls_serverName),
|
||||
allowInsecure = false,
|
||||
disableSystemRoot = false,
|
||||
certificates = {
|
||||
{
|
||||
certificateFile = server.tls_certificateFile,
|
||||
keyFile = server.tls_keyFile
|
||||
}
|
||||
}
|
||||
} or nil,
|
||||
kcpSettings = (server.transport == "mkcp") and {
|
||||
mtu = tonumber(server.mkcp_mtu),
|
||||
tti = tonumber(server.mkcp_tti),
|
||||
uplinkCapacity = tonumber(server.mkcp_uplinkCapacity),
|
||||
downlinkCapacity = tonumber(server.mkcp_downlinkCapacity),
|
||||
congestion = (server.mkcp_congestion == "1") and true or false,
|
||||
readBufferSize = tonumber(server.mkcp_readBufferSize),
|
||||
writeBufferSize = tonumber(server.mkcp_writeBufferSize),
|
||||
header = {type = server.mkcp_guise}
|
||||
} or nil,
|
||||
wsSettings = (server.transport == "ws") and {
|
||||
headers = (server.ws_host) and {Host = server.ws_host} or nil,
|
||||
path = server.ws_path
|
||||
} or nil,
|
||||
httpSettings = (server.transport == "h2") and
|
||||
{path = server.h2_path, host = server.h2_host} or nil,
|
||||
quicSettings = (server.transport == "quic") and {
|
||||
security = server.quic_security,
|
||||
key = server.quic_key,
|
||||
header = {type = server.quic_guise}
|
||||
} or nil
|
||||
} or nil
|
||||
},
|
||||
-- 传出连接
|
||||
outbound = {protocol = "freedom"},
|
||||
-- 额外传出连接
|
||||
outboundDetour = {{protocol = "blackhole", tag = "blocked"}},
|
||||
routing = routing
|
||||
}
|
||||
print(json.stringify(v2ray,1))
|
||||
print(json.stringify(v2ray, 1))
|
||||
|
@ -1,321 +0,0 @@
|
||||
-- Copyright 2018 Lienol <lienol@qq.com>
|
||||
-- Licensed to the public under the Apache License 2.0.
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
local util = require "luci.util"
|
||||
local i18n = require "luci.i18n"
|
||||
|
||||
module("luci.model.cbi.v2ray_server.api.v2ray", package.seeall)
|
||||
|
||||
local v2ray_api = "https://api.github.com/repos/v2ray/v2ray-core/releases/latest"
|
||||
|
||||
local wget = "/usr/bin/wget"
|
||||
local wget_args = { "--no-check-certificate", "--quiet", "--timeout=10", "--tries=2" }
|
||||
local curl = "/usr/bin/curl"
|
||||
local command_timeout = 40
|
||||
|
||||
local function _unpack(t, i)
|
||||
i = i or 1
|
||||
if t[i] ~= nil then
|
||||
return t[i], _unpack(t, i + 1)
|
||||
end
|
||||
end
|
||||
|
||||
local function exec(cmd, args, writer, timeout)
|
||||
local os = require "os"
|
||||
local nixio = require "nixio"
|
||||
|
||||
local fdi, fdo = nixio.pipe()
|
||||
local pid = nixio.fork()
|
||||
|
||||
if pid > 0 then
|
||||
fdo:close()
|
||||
|
||||
if writer or timeout then
|
||||
local starttime = os.time()
|
||||
while true do
|
||||
if timeout and os.difftime(os.time(), starttime) >= timeout then
|
||||
nixio.kill(pid, nixio.const.SIGTERM)
|
||||
return 1
|
||||
end
|
||||
|
||||
if writer then
|
||||
local buffer = fdi:read(2048)
|
||||
if buffer and #buffer > 0 then
|
||||
writer(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local wpid, stat, code = nixio.waitpid(pid, "nohang")
|
||||
|
||||
if wpid and stat == "exited" then
|
||||
return code
|
||||
end
|
||||
|
||||
if not writer and timeout then
|
||||
nixio.nanosleep(1)
|
||||
end
|
||||
end
|
||||
else
|
||||
local wpid, stat, code = nixio.waitpid(pid)
|
||||
return wpid and stat == "exited" and code
|
||||
end
|
||||
elseif pid == 0 then
|
||||
nixio.dup(fdo, nixio.stdout)
|
||||
fdi:close()
|
||||
fdo:close()
|
||||
nixio.exece(cmd, args, nil)
|
||||
nixio.stdout:close()
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
local function compare_versions(ver1, comp, ver2)
|
||||
local table = table
|
||||
|
||||
local av1 = util.split(ver1, "[%.%-]", nil, true)
|
||||
local av2 = util.split(ver2, "[%.%-]", nil, true)
|
||||
|
||||
local max = table.getn(av1)
|
||||
local n2 = table.getn(av2)
|
||||
if (max < n2) then
|
||||
max = n2
|
||||
end
|
||||
|
||||
for i = 1, max, 1 do
|
||||
local s1 = av1[i] or ""
|
||||
local s2 = av2[i] or ""
|
||||
|
||||
if comp == "~=" and (s1 ~= s2) then return true end
|
||||
if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
|
||||
if (comp == ">" or comp == ">=") and (s1 > s2) then return true end
|
||||
if (s1 ~= s2) then return false end
|
||||
end
|
||||
|
||||
return not (comp == "<" or comp == ">")
|
||||
end
|
||||
|
||||
local function auto_get_arch()
|
||||
local arch = nixio.uname().machine or ""
|
||||
|
||||
if arch == "mips" then
|
||||
if fs.access("/usr/lib/os-release") then
|
||||
arch = sys.exec("grep 'LEDE_BOARD' /usr/lib/os-release | grep -oE 'ramips|ar71xx'")
|
||||
elseif fs.access("/etc/openwrt_release") then
|
||||
arch = sys.exec("grep 'DISTRIB_TARGET' /etc/openwrt_release | grep -oE 'ramips|ar71xx'")
|
||||
end
|
||||
end
|
||||
|
||||
return util.trim(arch)
|
||||
end
|
||||
|
||||
local function get_file_info(arch)
|
||||
local file_tree = ""
|
||||
local sub_version = ""
|
||||
|
||||
if arch == "x86_64" then
|
||||
file_tree = "64"
|
||||
elseif arch == "ramips" then
|
||||
file_tree = "mipsle"
|
||||
elseif arch == "ar71xx" then
|
||||
file_tree = "mips"
|
||||
elseif arch:match("^i[%d]86$") then
|
||||
file_tree = "32"
|
||||
elseif arch:match("^armv[5-8]") then
|
||||
file_tree = "arm"
|
||||
sub_version = arch:match("[5-8]")
|
||||
end
|
||||
|
||||
return file_tree, sub_version
|
||||
end
|
||||
|
||||
local function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
|
||||
local output = { }
|
||||
--exec(wget, { "-O-", url, _unpack(wget_args) },
|
||||
-- function(chunk) output[#output + 1] = chunk end)
|
||||
--local json_content = util.trim(table.concat(output))
|
||||
|
||||
local json_content = luci.sys.exec(curl.." -sL "..url)
|
||||
|
||||
if json_content == "" then
|
||||
return { }
|
||||
end
|
||||
|
||||
return jsonc.parse(json_content) or { }
|
||||
end
|
||||
|
||||
function get_config_option(option, default)
|
||||
return uci:get("v2ray", "general", option) or default
|
||||
end
|
||||
|
||||
function get_current_log_file(type)
|
||||
local log_folder = get_config_option("log_folder", "/var/log/v2ray")
|
||||
return "%s/%s.%s.log" % { log_folder, type, "general" }
|
||||
end
|
||||
|
||||
function is_running(client)
|
||||
if client and client ~= "" then
|
||||
local file_name = client:match(".*/([^/]+)$") or ""
|
||||
if file_name ~= "" then
|
||||
return sys.call("pidof %s >/dev/null" % file_name) == 0
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function get_v2ray_version()
|
||||
return luci.sys.exec("/usr/bin/v2ray/v2ray -version | awk '{print $2}' | sed -n 1P")
|
||||
end
|
||||
|
||||
function to_check(arch)
|
||||
if not arch or arch == "" then
|
||||
arch = auto_get_arch()
|
||||
end
|
||||
|
||||
local file_tree, sub_version = get_file_info(arch)
|
||||
|
||||
if file_tree == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Can't determine ARCH, or ARCH not supported. Please select manually.")
|
||||
}
|
||||
end
|
||||
|
||||
local json = get_api_json(v2ray_api)
|
||||
|
||||
if json.tag_name == nil then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Get remote version info failed.")
|
||||
}
|
||||
end
|
||||
|
||||
local remote_version = json.tag_name:match("[^v]+")
|
||||
local needs_update = compare_versions(get_v2ray_version(), "<", remote_version)
|
||||
local html_url, download_url
|
||||
|
||||
if needs_update then
|
||||
html_url = json.html_url
|
||||
for _, v in ipairs(json.assets) do
|
||||
if v.name and v.name:match("linux%-" .. file_tree) then
|
||||
download_url = v.browser_download_url
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if needs_update and not download_url then
|
||||
return {
|
||||
code = 1,
|
||||
version = remote_version,
|
||||
html_url = html_url,
|
||||
type = file_tree .. sub_version,
|
||||
error = i18n.translate("New version found, but failed to get new version download url.")
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
update = needs_update,
|
||||
version = remote_version,
|
||||
url = {
|
||||
html = html_url,
|
||||
download = download_url
|
||||
},
|
||||
type = file_tree .. sub_version
|
||||
}
|
||||
end
|
||||
|
||||
function to_download(url)
|
||||
if not url or url == "" then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Download url is required.")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -f /tmp/v2ray_download.*")
|
||||
|
||||
local tmp_file = util.trim(util.exec("mktemp -u -t v2ray_download.XXXXXX"))
|
||||
|
||||
local result = exec(wget, {
|
||||
"-O", tmp_file, url, _unpack(wget_args) }, nil, command_timeout) == 0
|
||||
|
||||
if not result then
|
||||
exec("/bin/rm", { "-f", tmp_file })
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("File download failed or timed out: %s", url)
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
file = tmp_file
|
||||
}
|
||||
end
|
||||
|
||||
function to_extract(file, subfix)
|
||||
local isinstall_unzip=sys.call("opkg list-installed | grep unzip > /dev/null")==0
|
||||
if not isinstall_unzip then
|
||||
sys.call("opkg update && opkg install unzip > /dev/null")
|
||||
end
|
||||
|
||||
if not file or file == "" or not fs.access(file) then
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("File path required.")
|
||||
}
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t v2ray_extract.XXXXXX"))
|
||||
|
||||
local output = { }
|
||||
exec("/usr/bin/unzip", { "-o", file , "-d", tmp_dir },
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
exec("/bin/rm", { "-f", file })
|
||||
|
||||
return {
|
||||
code = 0,
|
||||
file = tmp_dir
|
||||
}
|
||||
end
|
||||
|
||||
function to_move(file)
|
||||
if not file or file == "" then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Client file is required.")
|
||||
}
|
||||
end
|
||||
|
||||
local client_file = "/usr/bin/v2ray"
|
||||
|
||||
sys.call("mkdir -p "..client_file)
|
||||
|
||||
local result = exec("/bin/mv", { "-f", file.."/v2ray", file.."/v2ctl", client_file }, nil, command_timeout) == 0
|
||||
|
||||
if not result or not fs.access(client_file) then
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translatef("Can't move new file to path: %s", client_file)
|
||||
}
|
||||
end
|
||||
|
||||
exec("/bin/chmod", { "-R", "755", client_file })
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/v2ray_extract.*")
|
||||
|
||||
return { code = 0 }
|
||||
end
|
@ -1,117 +1,238 @@
|
||||
local i="v2ray_server"
|
||||
local n=require"luci.dispatcher"
|
||||
local a,t,e
|
||||
local o={
|
||||
"none",
|
||||
"srtp",
|
||||
"utp",
|
||||
"wechat-video",
|
||||
"dtls",
|
||||
"wireguard",
|
||||
}
|
||||
a=Map(i,"V2ray "..translate("Server Config"))
|
||||
a.redirect=n.build_url("admin","vpn","v2ray_server")
|
||||
local app_name = "v2ray_server"
|
||||
local d = require "luci.dispatcher"
|
||||
|
||||
t=a:section(NamedSection,arg[1],"user","")
|
||||
t.addremove=false
|
||||
t.dynamic=false
|
||||
local header_type = {"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"}
|
||||
|
||||
e=t:option(Flag,"enable",translate("Enable"))
|
||||
e.default="1"
|
||||
e.rmempty=false
|
||||
map = Map(app_name, "V2ray " .. translate("Server Config"))
|
||||
map.redirect = d.build_url("admin", "vpn", "v2ray_server")
|
||||
|
||||
e=t:option(Value,"remarks",translate("Remarks"))
|
||||
e.default=translate("Remarks")
|
||||
t = map:section(NamedSection, arg[1], "user", "")
|
||||
t.addremove = false
|
||||
t.dynamic = false
|
||||
|
||||
e.rmempty=false
|
||||
e=t:option(Value,"port",translate("Port"))
|
||||
e.datatype="port"
|
||||
e.rmempty=false
|
||||
e.default=10086
|
||||
enable = t:option(Flag, "enable", translate("Enable"))
|
||||
enable.default = "1"
|
||||
enable.rmempty = false
|
||||
|
||||
e=t:option(ListValue,"protocol",translate("Protocol"))
|
||||
e:value("vmess",translate("Vmess"))
|
||||
e:value("socks",translate("Socks"))
|
||||
e:value("http",translate("Http"))
|
||||
remarks = t:option(Value, "remarks", translate("Remarks"))
|
||||
remarks.default = translate("Remarks")
|
||||
remarks.rmempty = false
|
||||
|
||||
e=t:option(Value,"VMess_id",translate("ID"))
|
||||
e.default=luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
e.rmempty=true
|
||||
e:depends("protocol","vmess")
|
||||
bind_local = t:option(Flag, "bind_local", translate("Bind Local"), translate(
|
||||
"When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies."))
|
||||
bind_local.default = "0"
|
||||
bind_local.rmempty = false
|
||||
|
||||
e=t:option(Value,"VMess_alterId",translate("Alter ID"))
|
||||
e.default=16
|
||||
e.rmempty=true
|
||||
e:depends("protocol","vmess")
|
||||
port = t:option(Value, "port", translate("Port"))
|
||||
port.datatype = "port"
|
||||
port.rmempty = false
|
||||
|
||||
e=t:option(Value,"Socks_user",translate("User name"))
|
||||
e.default=""
|
||||
e.rmempty=true
|
||||
e:depends("protocol","socks")
|
||||
protocol = t:option(ListValue, "protocol", translate("Protocol"))
|
||||
protocol:value("vmess", translate("Vmess"))
|
||||
protocol:value("socks", translate("Socks"))
|
||||
protocol:value("http",translate("Http"))
|
||||
protocol:value("shadowsocks", translate("Shadowsocks"))
|
||||
|
||||
e=t:option(Value,"Socks_pass",translate("Password"))
|
||||
e.default=""
|
||||
e.rmempty=true
|
||||
e.password=true
|
||||
e:depends("protocol","socks")
|
||||
socks_username = t:option(Value, "socks_username", translate("User name"))
|
||||
socks_username.rmempty = true
|
||||
socks_username:depends("protocol", "socks")
|
||||
|
||||
e=t:option(Value,"Http_user",translate("User name"))
|
||||
e.default=""
|
||||
e.rmempty=true
|
||||
e:depends("protocol","http")
|
||||
socks_password = t:option(Value, "socks_password", translate("Password"))
|
||||
socks_password.rmempty = true
|
||||
socks_password.password = true
|
||||
socks_password:depends("protocol", "socks")
|
||||
|
||||
e=t:option(Value,"Http_pass",translate("Password"))
|
||||
e.default=""
|
||||
e.rmempty=true
|
||||
e.password=true
|
||||
e:depends("protocol","http")
|
||||
http_username = t:option(Value, "http_username", translate("User name"))
|
||||
http_username.rmempty = true
|
||||
http_username:depends("protocol", "http")
|
||||
|
||||
e=t:option(Value,"VMess_level",translate("User Level"))
|
||||
e.default=1
|
||||
http_password = t:option(Value, "http_password", translate("Password"))
|
||||
http_password.rmempty = true
|
||||
http_password.password = true
|
||||
http_password:depends("protocol", "http")
|
||||
|
||||
e=t:option(ListValue,"transport",translate("Transport"))
|
||||
e.default=tcp
|
||||
e:value("tcp","TCP")
|
||||
e:value("mkcp","mKCP")
|
||||
e:value("quic","QUIC")
|
||||
e:depends("protocol","vmess")
|
||||
ss_method = t:option(ListValue, "ss_method", translate("Encrypt Method"))
|
||||
ss_method:value("aes-128-cfb")
|
||||
ss_method:value("aes-256-cfb")
|
||||
ss_method:value("aes-128-gcm")
|
||||
ss_method:value("aes-256-gcm")
|
||||
ss_method:value("chacha20")
|
||||
ss_method:value("chacha20-ietf")
|
||||
ss_method:value("chacha20-poly1305")
|
||||
ss_method:value("chacha20-ietf-poly1305")
|
||||
ss_method:depends("protocol", "shadowsocks")
|
||||
|
||||
e=t:option(ListValue,"tcp_guise",translate("Camouflage Type"))
|
||||
e:depends("transport","tcp")
|
||||
e:value("none","none")
|
||||
e:value("http","http")
|
||||
e.default=none
|
||||
ss_password = t:option(Value, "ss_password", translate("Password"))
|
||||
ss_password:depends("protocol", "shadowsocks")
|
||||
|
||||
e=t:option(DynamicList,"tcp_guise_http_host",translate("HTTP Host"))
|
||||
e:depends("tcp_guise","http")
|
||||
e=t:option(DynamicList,"tcp_guise_http_path",translate("HTTP Path"))
|
||||
e:depends("tcp_guise","http")
|
||||
e=t:option(ListValue,"mkcp_guise",translate("Camouflage Type"))
|
||||
for a,t in ipairs(o)do e:value(t)end
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_mtu",translate("KCP MTU"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_tti",translate("KCP TTI"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_uplinkCapacity",translate("KCP uplinkCapacity"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_downlinkCapacity",translate("KCP downlinkCapacity"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Flag,"mkcp_congestion",translate("KCP Congestion"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_readBufferSize",translate("KCP readBufferSize"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(Value,"mkcp_writeBufferSize",translate("KCP writeBufferSize"))
|
||||
e:depends("transport","mkcp")
|
||||
e=t:option(ListValue,"quic_security",translate("Encrypt Method"))
|
||||
e:value("none")
|
||||
e:value("aes-128-gcm")
|
||||
e:value("chacha20-poly1305")
|
||||
e:depends("transport","quic")
|
||||
e=t:option(Value,"quic_key",translate("Encrypt Method")..translate("Key"))
|
||||
e:depends("transport","quic")
|
||||
e=t:option(ListValue,"quic_guise",translate("Camouflage Type"))
|
||||
for a,t in ipairs(o)do e:value(t)end
|
||||
e:depends("transport","quic")
|
||||
ss_level = t:option(Value, "ss_level", translate("User Level"))
|
||||
ss_level.default = 1
|
||||
ss_level:depends("protocol", "shadowsocks")
|
||||
|
||||
return a
|
||||
ss_network = t:option(ListValue, "ss_network", translate("Transport"))
|
||||
ss_network.default = "tcp,udp"
|
||||
ss_network:value("tcp", "TCP")
|
||||
ss_network:value("udp", "UDP")
|
||||
ss_network:value("tcp,udp", "TCP,UDP")
|
||||
ss_network:depends("protocol", "shadowsocks")
|
||||
|
||||
ss_ota = t:option(Flag, "ss_ota", translate("OTA"), translate(
|
||||
"When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."))
|
||||
ss_ota.default = "0"
|
||||
ss_ota:depends("protocol", "shadowsocks")
|
||||
|
||||
VMess_id = t:option(DynamicList, "VMess_id", translate("ID"))
|
||||
for i = 1, 3 do
|
||||
local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
|
||||
VMess_id:value(uuid)
|
||||
end
|
||||
VMess_id:depends("protocol", "vmess")
|
||||
|
||||
VMess_alterId = t:option(Value, "VMess_alterId", translate("Alter ID"))
|
||||
VMess_alterId.default = 16
|
||||
VMess_alterId:depends("protocol", "vmess")
|
||||
|
||||
VMess_level = t:option(Value, "VMess_level", translate("User Level"))
|
||||
VMess_level.default = 1
|
||||
VMess_level:depends("protocol", "vmess")
|
||||
|
||||
transport = t:option(ListValue, "transport", translate("Transport"))
|
||||
transport:value("tcp", "TCP")
|
||||
transport:value("mkcp", "mKCP")
|
||||
transport:value("ws", "WebSocket")
|
||||
transport:value("h2", "HTTP/2")
|
||||
transport:value("quic", "QUIC")
|
||||
transport:depends("protocol", "vmess")
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
-- TCP伪装
|
||||
tcp_guise = t:option(ListValue, "tcp_guise", translate("Camouflage Type"))
|
||||
tcp_guise:depends("transport", "tcp")
|
||||
tcp_guise:value("none", "none")
|
||||
tcp_guise:value("http", "http")
|
||||
|
||||
-- HTTP域名
|
||||
tcp_guise_http_host = t:option(DynamicList, "tcp_guise_http_host",
|
||||
translate("HTTP Host"))
|
||||
tcp_guise_http_host:depends("tcp_guise", "http")
|
||||
|
||||
-- HTTP路径
|
||||
tcp_guise_http_path = t:option(DynamicList, "tcp_guise_http_path",
|
||||
translate("HTTP Path"))
|
||||
tcp_guise_http_path:depends("tcp_guise", "http")
|
||||
|
||||
-- [[ mKCP部分 ]]--
|
||||
mkcp_guise = t:option(ListValue, "mkcp_guise", translate("Camouflage Type"),
|
||||
translate(
|
||||
'<br>none: default, no masquerade, data sent is packets with no characteristics.<br>srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br>utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br>wechat-video: packets disguised as WeChat video calls.<br>dtls: disguised as DTLS 1.2 packet.<br>wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||
for a, t in ipairs(header_type) do mkcp_guise:value(t) end
|
||||
mkcp_guise:depends("transport", "mkcp")
|
||||
|
||||
mkcp_mtu = t:option(Value, "mkcp_mtu", translate("KCP MTU"))
|
||||
mkcp_mtu:depends("transport", "mkcp")
|
||||
|
||||
mkcp_tti = t:option(Value, "mkcp_tti", translate("KCP TTI"))
|
||||
mkcp_tti:depends("transport", "mkcp")
|
||||
|
||||
mkcp_uplinkCapacity = t:option(Value, "mkcp_uplinkCapacity",
|
||||
translate("KCP uplinkCapacity"))
|
||||
mkcp_uplinkCapacity:depends("transport", "mkcp")
|
||||
|
||||
mkcp_downlinkCapacity = t:option(Value, "mkcp_downlinkCapacity",
|
||||
translate("KCP downlinkCapacity"))
|
||||
mkcp_downlinkCapacity:depends("transport", "mkcp")
|
||||
|
||||
mkcp_congestion = t:option(Flag, "mkcp_congestion", translate("KCP Congestion"))
|
||||
mkcp_congestion:depends("transport", "mkcp")
|
||||
|
||||
mkcp_readBufferSize = t:option(Value, "mkcp_readBufferSize",
|
||||
translate("KCP readBufferSize"))
|
||||
mkcp_readBufferSize:depends("transport", "mkcp")
|
||||
|
||||
mkcp_writeBufferSize = t:option(Value, "mkcp_writeBufferSize",
|
||||
translate("KCP writeBufferSize"))
|
||||
mkcp_writeBufferSize:depends("transport", "mkcp")
|
||||
|
||||
-- [[ WebSocket部分 ]]--
|
||||
ws_path = t:option(Value, "ws_path", translate("WebSocket Path"))
|
||||
ws_path:depends("transport", "ws")
|
||||
|
||||
ws_host = t:option(Value, "ws_host", translate("WebSocket Host"))
|
||||
ws_host:depends("transport", "ws")
|
||||
|
||||
-- [[ HTTP/2部分 ]]--
|
||||
h2_path = t:option(Value, "h2_path", translate("HTTP/2 Path"))
|
||||
h2_path:depends("transport", "h2")
|
||||
|
||||
h2_host = t:option(DynamicList, "h2_host", translate("HTTP/2 Host"),
|
||||
translate("Camouflage Domain,you can not fill in"))
|
||||
h2_host:depends("transport", "h2")
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
quic_security =
|
||||
t:option(ListValue, "quic_security", translate("Encrypt Method"))
|
||||
quic_security:value("none")
|
||||
quic_security:value("aes-128-gcm")
|
||||
quic_security:value("chacha20-poly1305")
|
||||
quic_security:depends("transport", "quic")
|
||||
|
||||
quic_key = t:option(Value, "quic_key",
|
||||
translate("Encrypt Method") .. translate("Key"))
|
||||
quic_key:depends("transport", "quic")
|
||||
|
||||
quic_guise = t:option(ListValue, "quic_guise", translate("Camouflage Type"))
|
||||
for a, t in ipairs(header_type) do quic_guise:value(t) end
|
||||
quic_guise:depends("transport", "quic")
|
||||
|
||||
-- [[ TLS部分 ]] --
|
||||
tls_enable = t:option(Flag, "tls_enable", translate("Use HTTPS"))
|
||||
tls_enable:depends("transport", "ws")
|
||||
tls_enable:depends("transport", "h2")
|
||||
tls_enable.default = "1"
|
||||
tls_enable.rmempty = false
|
||||
|
||||
-- tls_serverName = t:option(Value, "tls_serverName", translate("Domain"))
|
||||
-- tls_serverName:depends("transport", "ws")
|
||||
-- tls_serverName:depends("transport", "h2")
|
||||
|
||||
tls_certificateFile = t:option(Value, "tls_certificateFile",
|
||||
translate("Public key absolute path"),
|
||||
translate("as:") .. "/etc/ssl/fullchain.pem")
|
||||
tls_certificateFile:depends("tls_enable", 1)
|
||||
|
||||
tls_keyFile = t:option(Value, "tls_keyFile",
|
||||
translate("Private key absolute path"),
|
||||
translate("as:") .. "/etc/ssl/private.key")
|
||||
tls_keyFile:depends("tls_enable", 1)
|
||||
|
||||
accept_lan = t:option(Flag, "accept_lan", translate("Accept LAN Access"),
|
||||
translate(
|
||||
"When selected, it can accessed lan , this will not be safe!"))
|
||||
accept_lan.default = "0"
|
||||
accept_lan.rmempty = false
|
||||
|
||||
function rmempty_restore()
|
||||
VMess_id.rmempty = true
|
||||
VMess_alterId.rmempty = true
|
||||
socks_username.rmempty = true
|
||||
socks_password.rmempty = true
|
||||
ss_password.rmempty = true
|
||||
ss_ota.rmempty = true
|
||||
end
|
||||
|
||||
protocol.validate = function(self, value)
|
||||
rmempty_restore()
|
||||
if value == "vmess" then
|
||||
VMess_id.rmempty = false
|
||||
VMess_alterId.rmempty = false
|
||||
elseif value == "socks" then
|
||||
socks_username.rmempty = true
|
||||
socks_password.rmempty = true
|
||||
elseif value == "shadowsocks" then
|
||||
ss_password.rmempty = false
|
||||
ss_ota.rmempty = false
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
return map
|
||||
|
@ -1,45 +1,105 @@
|
||||
local i=require"luci.dispatcher"
|
||||
local e=require"nixio.fs"
|
||||
local e=require"luci.sys"
|
||||
local e=luci.model.uci.cursor()
|
||||
local o="v2ray_server"
|
||||
local a,e,t
|
||||
local i = require "luci.dispatcher"
|
||||
local e = require "nixio.fs"
|
||||
local e = require "luci.sys"
|
||||
local e = luci.model.uci.cursor()
|
||||
local o = "v2ray_server"
|
||||
|
||||
a=Map(o,translate("V2ray Server"))
|
||||
e=a:section(TypedSection,"global",translate("Global Settings"))
|
||||
e.anonymous=true
|
||||
e.addremove=false
|
||||
t=e:option(Flag,"enable",translate("Enable"))
|
||||
t.rmempty=false
|
||||
m = Map(o, translate("V2ray Server"))
|
||||
|
||||
e=a:section(TypedSection,"user",translate("Server Config"))
|
||||
e.anonymous=true
|
||||
e.addremove=true
|
||||
e.template="cbi/tblsection"
|
||||
e.extedit=i.build_url("admin","vpn",o,"config","%s")
|
||||
t = m:section(TypedSection, "global", translate("Global Settings"))
|
||||
t.anonymous = true
|
||||
t.addremove = false
|
||||
e = t:option(Flag, "enable", translate("Enable"))
|
||||
e.rmempty = false
|
||||
t:append(Template("v2ray_server/v2ray"))
|
||||
|
||||
function e.create(t,e)
|
||||
local e=TypedSection.create(t,e)
|
||||
luci.http.redirect(i.build_url("admin","vpn",o,"config",e))
|
||||
t = m:section(TypedSection, "user", translate("Users Manager"))
|
||||
t.anonymous = true
|
||||
t.addremove = true
|
||||
t.template = "cbi/tblsection"
|
||||
t.extedit = i.build_url("admin", "vpn", o, "config", "%s")
|
||||
function t.create(t, e)
|
||||
local e = TypedSection.create(t, e)
|
||||
luci.http.redirect(i.build_url("admin", "vpn", o, "config", e))
|
||||
end
|
||||
function t.remove(t, a)
|
||||
t.map.proceed = true
|
||||
t.map:del(a)
|
||||
luci.http.redirect(i.build_url("admin", "vpn", o))
|
||||
end
|
||||
e = t:option(Flag, "enable", translate("Enable"))
|
||||
e.width = "5%"
|
||||
e.rmempty = false
|
||||
e = t:option(DummyValue, "status", translate("Status"))
|
||||
e.template = "v2ray_server/users_status"
|
||||
e.value = translate("Collecting data...")
|
||||
e = t:option(DummyValue, "remarks", translate("Remarks"))
|
||||
e.width = "15%"
|
||||
e = t:option(DummyValue, "port", translate("Port"))
|
||||
e.width = "10%"
|
||||
e = t:option(DummyValue, "protocol", translate("Protocol"))
|
||||
e.width = "15%"
|
||||
e.cfgvalue = function(self, section)
|
||||
local str = "未知"
|
||||
local protocol = m:get(section, "protocol") or ""
|
||||
if protocol ~= "" then str = (protocol:gsub("^%l", string.upper)) end
|
||||
return str
|
||||
end
|
||||
e = t:option(DummyValue, "transport", translate("Transport"))
|
||||
e.width = "10%"
|
||||
e.cfgvalue = function(self, section)
|
||||
local t = "未知"
|
||||
local b = ""
|
||||
local protocol = m:get(section, "protocol") or ""
|
||||
if protocol == "vmess" then
|
||||
b = "transport"
|
||||
elseif protocol == "shadowsocks" then
|
||||
b = "ss_network"
|
||||
end
|
||||
local a = m:get(section, b) or ""
|
||||
if a == "tcp" then
|
||||
t = "TCP"
|
||||
elseif a == "udp" then
|
||||
t = "UDP"
|
||||
elseif a == "tcp,udp" then
|
||||
t = "TCP,UDP"
|
||||
elseif a == "mkcp" then
|
||||
t = "mKCP"
|
||||
elseif a == "ws" then
|
||||
t = "WebSocket"
|
||||
elseif a == "h2" then
|
||||
t = "HTTP/2"
|
||||
elseif a == "quic" then
|
||||
t = "QUIC"
|
||||
else
|
||||
t = "TCP,UDP"
|
||||
end
|
||||
return t
|
||||
end
|
||||
e = t:option(DummyValue, "password", translate("Password"))
|
||||
e.width = "30%"
|
||||
e.cfgvalue = function(self, section)
|
||||
local e = ""
|
||||
local protocol = m:get(section, "protocol") or ""
|
||||
if protocol == "vmess" then
|
||||
e = "VMess_id"
|
||||
elseif protocol == "shadowsocks" then
|
||||
e = "ss_password"
|
||||
elseif protocol == "socks" then
|
||||
e = "socks_password"
|
||||
end
|
||||
local e = m:get(section, e) or ""
|
||||
local t = ""
|
||||
if type(e) == "table" then
|
||||
for a = 1, #e do t = t .. e[a] end
|
||||
else
|
||||
t = e
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function e.remove(e,a)
|
||||
e.map.proceed=true
|
||||
e.map:del(a)
|
||||
luci.http.redirect(i.build_url("admin","vpn",o))
|
||||
end
|
||||
m:append(Template("v2ray_server/log"))
|
||||
|
||||
t=e:option(Flag,"enable",translate("Enable"))
|
||||
t.width="5%"
|
||||
t.rmempty=false
|
||||
t=e:option(DummyValue,"status",translate("Status"))
|
||||
t.template="v2ray_server/users_status"
|
||||
t.value=translate("Collecting data...")
|
||||
t=e:option(DummyValue,"remarks",translate("Remarks"))
|
||||
t.width="15%"
|
||||
t=e:option(DummyValue,"port",translate("Port"))
|
||||
t=e:option(DummyValue,"protocol",translate("Protocol"))
|
||||
m:append(Template("v2ray_server/users_list_status"))
|
||||
return m
|
||||
|
||||
a:append(Template("v2ray_server/users_list_status"))
|
||||
|
||||
return a
|
||||
|
@ -0,0 +1,31 @@
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function clear_log(btn) {
|
||||
XHR.get('<%=url([[admin]], [[vpn]], [[v2ray_server]], [[clear_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = "";
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
XHR.poll(3, '<%=url([[admin]], [[vpn]], [[v2ray_server]], [[get_log]])%>', null,
|
||||
function(x, data) {
|
||||
if(x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = x.responseText;
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<fieldset class="cbi-section" id="_log_fieldset">
|
||||
<legend>
|
||||
<%:Logs%>
|
||||
</legend>
|
||||
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>">
|
||||
<textarea id="log_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="20" wrap="off" readonly="readonly"></textarea>
|
||||
</fieldset>
|
@ -1,8 +1,3 @@
|
||||
<%#
|
||||
Copyright 2018 Lienol
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
|
@ -1,188 +1,14 @@
|
||||
<%#
|
||||
Copyright 2018 <lienol@qq.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<%
|
||||
local v2ray_version=luci.sys.exec("/usr/bin/v2ray/v2ray -version | awk '{print $2}' | sed -n 1P")
|
||||
local dsp = require "luci.dispatcher"
|
||||
local v2ray_version=luci.sys.exec("[ -f '/usr/bin/v2ray/v2ray' ] && /usr/bin/v2ray/v2ray -version | awk '{print $2}' | sed -n 1P")
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var v2rayInfo;
|
||||
var tokenStr = '<%=token%>';
|
||||
var noUpdateText = '<%:已是最新版本%>';
|
||||
var updateSuccessText = '<%:更新成功.%>';
|
||||
var clickToUpdateText = '<%:点击更新%>';
|
||||
var inProgressText = '<%:正在更新...%>';
|
||||
var unexpectedErrorText = '<%:意外错误.%>';
|
||||
var updateInProgressNotice = '<%:正在更新,你确认要关闭吗?%>';
|
||||
|
||||
window.onload = function() {
|
||||
var v2rayCheckBtn = document.getElementById('_v2ray-check_btn');
|
||||
var v2rayDetailElm = document.getElementById('_v2ray-check_btn-detail');
|
||||
};
|
||||
|
||||
function addPageNotice_v2ray() {
|
||||
window.onbeforeunload = function(e) {
|
||||
e.returnValue = updateInProgressNotice;
|
||||
return updateInProgressNotice;
|
||||
};
|
||||
}
|
||||
|
||||
function removePageNotice_v2ray() {
|
||||
window.onbeforeunload = undefined;
|
||||
}
|
||||
|
||||
function onUpdateSuccess_v2ray(btn) {
|
||||
alert(updateSuccessText);
|
||||
|
||||
if(btn) {
|
||||
btn.value = updateSuccessText;
|
||||
btn.placeholder = updateSuccessText;
|
||||
btn.disabled = true;
|
||||
}
|
||||
|
||||
window.setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function onRequestError_v2ray(btn, errorMessage) {
|
||||
btn.disabled = false;
|
||||
btn.value = btn.placeholder;
|
||||
|
||||
if(errorMessage) {
|
||||
alert(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function doAjaxGet(url, data, onResult) {
|
||||
new XHR().get(url, data, function(_, json) {
|
||||
var resultJson = json || {
|
||||
'code': 1,
|
||||
'error': unexpectedErrorText
|
||||
};
|
||||
|
||||
if(typeof onResult === 'function') {
|
||||
onResult(resultJson);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onBtnClick_v2ray(btn) {
|
||||
if(v2rayInfo === undefined) {
|
||||
checkUpdate_v2ray(btn);
|
||||
} else {
|
||||
doUpdate_v2ray(btn);
|
||||
}
|
||||
}
|
||||
|
||||
function checkUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = inProgressText;
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var ckeckDetailElm = document.getElementById(btn.id + '-detail');
|
||||
|
||||
doAjaxGet('<%=dsp.build_url("admin/vpn/v2ray_server/check")%>', {
|
||||
token: tokenStr,
|
||||
arch: ''
|
||||
}, function(json) {
|
||||
removePageNotice_v2ray();
|
||||
|
||||
if(json.code) {
|
||||
v2rayInfo = undefined;
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
if(json.update) {
|
||||
v2rayInfo = json;
|
||||
btn.disabled = false;
|
||||
btn.value = clickToUpdateText;
|
||||
btn.placeholder = clickToUpdateText;
|
||||
|
||||
if(ckeckDetailElm) {
|
||||
var urlNode = '';
|
||||
if(json.version) {
|
||||
urlNode = '<em style="color:red;">最新版本号:' + json.version + '</em>';
|
||||
if(json.url && json.url.html) {
|
||||
urlNode = '<a href="' + json.url.html + '" target="_blank">' + urlNode + '</a>';
|
||||
}
|
||||
}
|
||||
ckeckDetailElm.innerHTML = urlNode;
|
||||
}
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.value = noUpdateText;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doUpdate_v2ray(btn) {
|
||||
btn.disabled = true;
|
||||
btn.value = '<%:下载中...%>';
|
||||
|
||||
addPageNotice_v2ray();
|
||||
|
||||
var v2rayUpdateUrl = '<%=dsp.build_url("admin/vpn/v2ray_server/update")%>';
|
||||
// Download file
|
||||
doAjaxGet(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
url: v2rayInfo ? v2rayInfo.url.download : ''
|
||||
}, function(json) {
|
||||
if(json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:解压中...%>';
|
||||
|
||||
// Extract file
|
||||
doAjaxGet(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'extract',
|
||||
file: json.file,
|
||||
subfix: v2rayInfo ? v2rayInfo.type : ''
|
||||
}, function(json) {
|
||||
if(json.code) {
|
||||
removePageNotice_v2ray();
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
btn.value = '<%:移动中...%>';
|
||||
|
||||
// Move file to target dir
|
||||
doAjaxGet(v2rayUpdateUrl, {
|
||||
token: tokenStr,
|
||||
task: 'move',
|
||||
file: json.file
|
||||
}, function(json) {
|
||||
removePageNotice_v2ray();
|
||||
if(json.code) {
|
||||
onRequestError_v2ray(btn, json.error);
|
||||
} else {
|
||||
onUpdateSuccess_v2ray(btn);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">V2ray
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<div class="cbi-value-description">
|
||||
<img src="/luci-static/resources/cbi/help.gif">
|
||||
<span>【 <%=v2ray_version%>】</span>
|
||||
<input class="cbi-button cbi-input-apply" type="submit" id="_v2ray-check_btn" onclick="onBtnClick_v2ray(this);" value="<%:Manually update%>">
|
||||
<span id="_v2ray-check_btn-detail"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,236 +0,0 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: zh-Hans\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:42
|
||||
msgid "Alter ID"
|
||||
msgstr "额外ID(AlterID)"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:79
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:89
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:113
|
||||
msgid "Camouflage Type"
|
||||
msgstr "伪装类型"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:185
|
||||
msgid "Can't determine ARCH, or ARCH not supported. Please select manually."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:312
|
||||
msgid "Can't move new file to path: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:298
|
||||
msgid "Client file is required."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:37
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:238
|
||||
msgid "Download url is required."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:19
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:12
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:32
|
||||
msgid "Enable"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:106
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:111
|
||||
msgid "Encrypt Method"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:253
|
||||
msgid "File download failed or timed out: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:272
|
||||
msgid "File path required."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:194
|
||||
msgid "Get remote version info failed."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:9
|
||||
msgid "Global Settings"
|
||||
msgstr "全局设置"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:85
|
||||
msgid "HTTP Host"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:87
|
||||
msgid "HTTP Path"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:35
|
||||
msgid "Http"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:37
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:100
|
||||
msgid "KCP Congestion"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:92
|
||||
msgid "KCP MTU"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:94
|
||||
msgid "KCP TTI"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:98
|
||||
msgid "KCP downlinkCapacity"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:102
|
||||
msgid "KCP readBufferSize"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:96
|
||||
msgid "KCP uplinkCapacity"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:104
|
||||
msgid "KCP writeBufferSize"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:111
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:184
|
||||
msgid "Manually update"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/api/v2ray.lua:218
|
||||
msgid "New version found, but failed to get new version download url."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:52
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:63
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:27
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:40
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:32
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:41
|
||||
msgid "Protocol"
|
||||
msgstr "协议"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:23
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:24
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:38
|
||||
msgid "Remarks"
|
||||
msgstr "备注"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:12
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:15
|
||||
msgid "Server Config"
|
||||
msgstr "服务器配置"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:34
|
||||
msgid "Socks"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:35
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:72
|
||||
msgid "Transport"
|
||||
msgstr "传输方式"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:69
|
||||
msgid "User Level"
|
||||
msgstr "用户等级(Level)"
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:47
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:58
|
||||
msgid "User name"
|
||||
msgstr "用户名"
|
||||
|
||||
#: luasrc/controller/v2ray_server.lua:10
|
||||
#: luasrc/model/cbi/v2ray_server/index.lua:8
|
||||
msgid "V2ray Server"
|
||||
msgstr "V2ray 服务器"
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:178
|
||||
msgid "Version"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/model/cbi/v2ray_server/config.lua:33
|
||||
msgid "Vmess"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:126
|
||||
msgid "下载中..."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:15
|
||||
msgid "已是最新版本"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:19
|
||||
msgid "意外错误."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:16
|
||||
msgid "更新成功."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:18
|
||||
msgid "正在更新..."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:20
|
||||
msgid "正在更新,你确认要关闭吗?"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:17
|
||||
msgid "点击更新"
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:153
|
||||
msgid "移动中..."
|
||||
msgstr ""
|
||||
|
||||
#: luasrc/view/v2ray_server/v2ray.htm:140
|
||||
msgid "解压中..."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Users Manager"
|
||||
#~ msgstr "用户管理"
|
||||
|
||||
#~ msgid "Null"
|
||||
#~ msgstr "无"
|
||||
|
||||
#~ msgid "Enabled"
|
||||
#~ msgstr "启用"
|
||||
|
||||
#~ msgid "Current Condition"
|
||||
#~ msgstr "当前状态"
|
||||
|
||||
#~ msgid "NOT RUNNING"
|
||||
#~ msgstr "未运行"
|
||||
|
||||
#~ msgid "RUNNING"
|
||||
#~ msgstr "运行中"
|
@ -13,12 +13,15 @@ msgstr "用户管理"
|
||||
msgid "Remarks"
|
||||
msgstr "备注"
|
||||
|
||||
msgid "Bind Local"
|
||||
msgstr "本机监听"
|
||||
|
||||
msgid "When selected, it can only be accessed locally,It is recommended to turn on when using reverse proxies."
|
||||
msgstr "当勾选时,只能由本机访问此端口,当开启反向代理时建议勾选此项。"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
msgid "User name"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
@ -34,12 +37,51 @@ msgstr "额外ID(AlterID)"
|
||||
msgid "User Level"
|
||||
msgstr "用户等级(Level)"
|
||||
|
||||
msgid "When OTA is enabled, V2Ray will reject connections that are not OTA enabled. This option is invalid when using AEAD encryption."
|
||||
msgstr "开启 OTA 后,V2Ray 会拒绝未启用 OTA 的连接。当使用 AEAD 加密时,该选项无效。"
|
||||
|
||||
msgid "Transport"
|
||||
msgstr "传输方式"
|
||||
|
||||
msgid "Camouflage Type"
|
||||
msgstr "伪装类型"
|
||||
|
||||
msgid "Camouflage Domain,you can not fill in"
|
||||
msgstr "伪装域名,也可以不填写"
|
||||
|
||||
msgid "can not has conflict"
|
||||
msgstr "请不要冲突"
|
||||
|
||||
msgid "Use HTTPS"
|
||||
msgstr "使用HTTPS"
|
||||
|
||||
msgid "TLS Settings"
|
||||
msgstr "TLS配置"
|
||||
|
||||
msgid "as:"
|
||||
msgstr "如:"
|
||||
|
||||
msgid "Public key absolute path"
|
||||
msgstr "公钥文件绝对路径"
|
||||
|
||||
msgid "Private key absolute path"
|
||||
msgstr "私钥文件绝对路径"
|
||||
|
||||
msgid "<br>none: default, no masquerade, data sent is packets with no characteristics.<br>srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br>utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br>wechat-video: packets disguised as WeChat video calls.<br>dtls: disguised as DTLS 1.2 packet.<br>wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)"
|
||||
msgstr "<br>none:默认值,不进行伪装,发送的数据是没有特征的数据包。<br>srtp:伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。<br>utp:伪装成 uTP 数据包,会被识别为 BT 下载数据。<br>wechat-video:伪装成微信视频通话的数据包。<br>dtls:伪装成 DTLS 1.2 数据包。<br>wireguard:伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)"
|
||||
|
||||
msgid "Accept LAN Access"
|
||||
msgstr "接受局域网访问"
|
||||
|
||||
msgid "When selected, it can accessed lan , this will not be safe!"
|
||||
msgstr "当勾选时,可以直接访问局域网,这将不安全!(非特殊情况不建议开启)"
|
||||
|
||||
msgid "Logs"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
@ -53,4 +95,4 @@ msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
msgstr "运行中"
|
@ -4,12 +4,26 @@ config global
|
||||
|
||||
config user
|
||||
option enable '1'
|
||||
option remarks '备注222'
|
||||
option remarks 'tcp'
|
||||
option bind_local '0'
|
||||
option protocol 'vmess'
|
||||
option VMess_id 'fd00927a-b0c2-4629-aef7-d9ff15a9d722'
|
||||
list VMess_id 'fd00927a-b0c2-4629-aef7-d9ff15a9d722'
|
||||
option VMess_alterId '16'
|
||||
option VMess_level '1'
|
||||
option transport 'tcp'
|
||||
option tcp_guise 'none'
|
||||
option port '12366'
|
||||
|
||||
config user
|
||||
option enable '1'
|
||||
option remarks 'ws'
|
||||
option bind_local '0'
|
||||
option protocol 'vmess'
|
||||
option VMess_alterId '16'
|
||||
option VMess_level '1'
|
||||
list VMess_id 'fd00927a-b0c2-4629-aef7-d9ff15a9d722'
|
||||
option transport 'ws'
|
||||
option ws_path '/websocket'
|
||||
option tls_enable '0'
|
||||
option port '30010'
|
||||
|
@ -1,22 +1,31 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2018-2019 Lienol <lawlienol@gmail.com>
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
|
||||
START=99
|
||||
|
||||
CONFIG=v2ray_server
|
||||
CONFIG_PATH=/var/etc/$CONFIG
|
||||
LOG_PATH=/var/log/$CONFIG
|
||||
LOG_APP_FILE=$LOG_PATH/app.log
|
||||
|
||||
echolog() {
|
||||
echo -e "$(date "+%Y-%m-%d %H:%M:%S"): $1" >> $LOG_APP_FILE
|
||||
}
|
||||
|
||||
gen_v2ray_config_file() {
|
||||
config_get enable $1 enable
|
||||
[ "$enable" = "0" ] && return 0
|
||||
config_get remarks $1 remarks
|
||||
config_get port $1 port
|
||||
config_get transport $1 transport
|
||||
lua /usr/lib/lua/luci/model/cbi/v2ray_server/api/genv2rayconfig.lua $1 > $CONFIG_PATH/$1.json
|
||||
[ -f /var/v2server ] || cp -a /usr/bin/v2ray/v2ray /var/v2server
|
||||
/var/v2server -config $CONFIG_PATH/$1.json >/dev/null 2>&1 &
|
||||
echolog "$remarks $port 生成并运行 V2ray 配置文件 - $CONFIG_PATH/$1.json"
|
||||
/usr/bin/v2ray/v2ray -config $CONFIG_PATH/$1.json >/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
start_v2ray_server() {
|
||||
mkdir -p $CONFIG_PATH $LOG_PATH
|
||||
touch $LOG_APP_FILE
|
||||
config_foreach gen_v2ray_config_file "user"
|
||||
fw3 reload > /dev/null 2>&1
|
||||
}
|
||||
@ -24,6 +33,8 @@ start_v2ray_server() {
|
||||
stop_v2ray_server() {
|
||||
fw3 reload > /dev/null 2>&1
|
||||
ps -w | grep "$CONFIG_PATH/" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
|
||||
rm -rf $CONFIG_PATH
|
||||
rm -rf $LOG_PATH
|
||||
}
|
||||
|
||||
start() {
|
||||
@ -32,18 +43,16 @@ start() {
|
||||
if [ "$enable" = "0" ];then
|
||||
stop_v2ray_server
|
||||
else
|
||||
mkdir -p $CONFIG_PATH
|
||||
start_v2ray_server
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
stop_v2ray_server
|
||||
rm -rf $CONFIG_PATH
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
sleep 1
|
||||
start
|
||||
}
|
||||
}
|
@ -7,9 +7,13 @@ gen_user_iptables() {
|
||||
config_get enable $1 enable
|
||||
[ "$enable" = "0" ] && return 0
|
||||
config_get remarks $1 remarks
|
||||
config_get bind_local $1 bind_local
|
||||
config_get port $1 port
|
||||
iptables -A V2RAY-SERVER -p tcp --dport $port -m comment --comment "$remarks" -j ACCEPT
|
||||
iptables -A V2RAY-SERVER -p udp --dport $port -m comment --comment "$remarks" -j ACCEPT
|
||||
dport=$port
|
||||
[ "$bind_local" != "1" ] && {
|
||||
iptables -A V2RAY-SERVER -p tcp --dport $dport -m comment --comment "$remarks" -j ACCEPT
|
||||
iptables -A V2RAY-SERVER -p udp --dport $dport -m comment --comment "$remarks" -j ACCEPT
|
||||
}
|
||||
}
|
||||
|
||||
iptables -F V2RAY-SERVER 2>/dev/null
|
||||
|
@ -1,18 +0,0 @@
|
||||
# Copyright (C) 2018-2020 Lienol <lawlienol@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for PPTP VPN Server
|
||||
LUCI_DEPENDS:=+pptpd +kmod-mppe +ppp
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=12-20190704
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
-- Copyright 2018-2019 Lienol <lawlienol@gmail.com>
|
||||
module("luci.controller.pptpd", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/pptpd") then return end
|
||||
|
||||
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
|
||||
entry({"admin", "vpn", "pptpd"}, alias("admin", "vpn", "pptpd", "settings"),
|
||||
_("PPTP VPN Server"), 48)
|
||||
entry({"admin", "vpn", "pptpd", "settings"}, cbi("pptpd/settings"),
|
||||
_("General Settings"), 10).leaf = true
|
||||
entry({"admin", "vpn", "pptpd", "users"}, cbi("pptpd/users"),
|
||||
_("Users Manager"), 20).leaf = true
|
||||
entry({"admin", "vpn", "pptpd", "online"}, cbi("pptpd/online"),
|
||||
_("Online Users"), 30).leaf = true
|
||||
entry({"admin", "vpn", "pptpd", "status"}, call("status")).leaf = true
|
||||
end
|
||||
|
||||
function status()
|
||||
local e = {}
|
||||
e.status = luci.sys.call("pidof %s >/dev/null" % "pptpd") == 0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
@ -1,80 +0,0 @@
|
||||
local e = {}
|
||||
local o = require "luci.dispatcher"
|
||||
local a = luci.util.execi("/bin/busybox top -bn1 | grep '/usr/sbin/pppd'")
|
||||
for t in a do
|
||||
local a, n, h, s, o, i = t:match(
|
||||
"^ *(%d+) +(%d+) +.+options%.pptpd +(%d+) +(%S.-%S)%:(%S.-%S) +.+ +(.+)")
|
||||
local t = tonumber(a)
|
||||
if t then
|
||||
e["%02i.%s" % {t, "online"}] = {
|
||||
['PID'] = a,
|
||||
['PPID'] = n,
|
||||
['SPEED'] = h,
|
||||
['GATEWAY'] = s,
|
||||
['VIP'] = o,
|
||||
['CIP'] = i,
|
||||
['BLACKLIST'] = 0
|
||||
}
|
||||
end
|
||||
end
|
||||
local a = luci.util.execi("sed = /etc/firewall.user | sed 'N;s/\\n/:/'")
|
||||
for t in a do
|
||||
local t, a = t:match("^ *(%d+)%:.+%#%# pptpd%-blacklist%-(.+)")
|
||||
local t = tonumber(t)
|
||||
if t then
|
||||
e["%02i.%s" % {t, "blacklist"}] =
|
||||
{
|
||||
['PID'] = "-1",
|
||||
['PPID'] = "-1",
|
||||
['SPEED'] = "-1",
|
||||
['GATEWAY'] = "-",
|
||||
['VIP'] = "-",
|
||||
['CIP'] = a,
|
||||
['BLACKLIST'] = 1
|
||||
}
|
||||
end
|
||||
end
|
||||
f = SimpleForm("processes", translate("PPTP VPN Server"))
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
f.description = translate(
|
||||
"Simple, quick and convenient PPTP VPN, universal across the platform")
|
||||
t = f:section(Table, e, translate("Online Users"))
|
||||
t:option(DummyValue, "GATEWAY", translate("Server IP"))
|
||||
t:option(DummyValue, "VIP", translate("Client IP"))
|
||||
t:option(DummyValue, "CIP", translate("IP address"))
|
||||
blacklist = t:option(Button, "_blacklist", translate("Blacklist"))
|
||||
function blacklist.render(e, t, a)
|
||||
if e.map:get(t, "BLACKLIST") == 0 then
|
||||
e.title = translate("Add to Blacklist")
|
||||
e.inputstyle = "remove"
|
||||
else
|
||||
e.title = translate("Remove from Blacklist")
|
||||
e.inputstyle = "apply"
|
||||
end
|
||||
Button.render(e, t, a)
|
||||
end
|
||||
function blacklist.write(t, a)
|
||||
local e = t.map:get(a, "CIP")
|
||||
if t.map:get(a, "BLACKLIST") == 0 then
|
||||
luci.util.execi(
|
||||
"echo 'iptables -A input_rule -s %s -p tcp --dport 1723 -j DROP ## pptpd-blacklist-%s' >> /etc/firewall.user" %
|
||||
{e, e})
|
||||
luci.util.execi(
|
||||
"iptables -A input_rule -s %s -p tcp --dport 1723 -j DROP" % {e})
|
||||
null, t.tag_error[a] = luci.sys.process.signal(t.map:get(a, "PID"), 9)
|
||||
else
|
||||
luci.util.execi(
|
||||
"sed -i -e '/## pptpd-blacklist-%s/d' /etc/firewall.user" % {e})
|
||||
luci.util.execi(
|
||||
"iptables -D input_rule -s %s -p tcp --dport 1723 -j DROP" % {e})
|
||||
end
|
||||
luci.http.redirect(o.build_url("admin/vpn/pptpd/online"))
|
||||
end
|
||||
kill = t:option(Button, "_kill", translate("Forced offline"))
|
||||
kill.inputstyle = "reset"
|
||||
function kill.write(e, t)
|
||||
null, e.tag_error[t] = luci.sys.process.signal(e.map:get(t, "PID"), 9)
|
||||
luci.http.redirect(o.build_url("admin/vpn/pptpd/online"))
|
||||
end
|
||||
return f
|
@ -1,61 +0,0 @@
|
||||
local s = require "luci.sys"
|
||||
local net = require"luci.model.network".init()
|
||||
local ifaces = s.net:devices()
|
||||
local m, s, o
|
||||
m = Map("pptpd", translate("PPTP VPN Server"))
|
||||
m.description = translate(
|
||||
"Simple, quick and convenient PPTP VPN, universal across the platform")
|
||||
m.template = "pptpd/index"
|
||||
|
||||
s = m:section(TypedSection, "service")
|
||||
s.anonymous = true
|
||||
|
||||
o = s:option(DummyValue, "pptpd_status", translate("Current Condition"))
|
||||
o.template = "pptpd/status"
|
||||
o.value = translate("Collecting data...")
|
||||
|
||||
o = s:option(Flag, "enabled", translate("Enable VPN Server"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, "localip", translate("Server IP"),
|
||||
translate("VPN Server IP address, it not required."))
|
||||
o.datatype = "ipaddr"
|
||||
o.placeholder = translate("192.168.1.2")
|
||||
o.rmempty = true
|
||||
o.default = "192.168.1.2"
|
||||
|
||||
o = s:option(Value, "remoteip", translate("Client IP"),
|
||||
translate("VPN Client IP address, it not required."))
|
||||
o.placeholder = translate("192.168.1.10-20")
|
||||
o.rmempty = true
|
||||
o.default = "192.168.1.10-20"
|
||||
|
||||
o = s:option(Value, "dns", translate("DNS IP address"),
|
||||
translate("This will be sent to the client, it not required."))
|
||||
o.placeholder = translate("192.168.1.1")
|
||||
o.datatype = "ipaddr"
|
||||
o.rmempty = true
|
||||
o.default = "192.168.1.1"
|
||||
|
||||
o = s:option(Flag, "mppe", translate("Enable MPPE Encryption"),
|
||||
translate("Allows 128-bit encrypted connection."))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Flag, "is_nat", translate("is_nat"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, "export_interface", translate("Interface"),
|
||||
translate("Specify interface forwarding traffic."))
|
||||
o:value("default", translate("default"))
|
||||
for _, iface in ipairs(ifaces) do
|
||||
if (iface:match("^br*") or iface:match("^eth*") or iface:match("^pppoe*") or
|
||||
iface:match("wlan*")) then
|
||||
local nets = net:get_interface(iface)
|
||||
nets = nets and nets:get_networks() or {}
|
||||
for k, v in pairs(nets) do nets[k] = nets[k].sid end
|
||||
nets = table.concat(nets, ",")
|
||||
o:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface))
|
||||
end
|
||||
end
|
||||
o:depends("is_nat", "1")
|
||||
return m
|
@ -1,24 +0,0 @@
|
||||
m = Map("pptpd", translate("PPTP VPN Server"))
|
||||
m.description = translate(
|
||||
"Simple, quick and convenient PPTP VPN, universal across the platform")
|
||||
s = m:section(TypedSection, "users", translate("Users Manager"))
|
||||
s.addremove = true
|
||||
s.anonymous = true
|
||||
s.template = "cbi/tblsection"
|
||||
o = s:option(Flag, "enabled", translate("Enabled"))
|
||||
o.rmempty = false
|
||||
o = s:option(Value, "username", translate("User name"))
|
||||
o.placeholder = translate("User name")
|
||||
o.rmempty = true
|
||||
o = s:option(Value, "password", translate("Password"))
|
||||
o.rmempty = true
|
||||
o = s:option(Value, "ipaddress", translate("IP address"))
|
||||
o.placeholder = translate("Automatically")
|
||||
o.datatype = "ipaddr"
|
||||
o.rmempty = true
|
||||
function o.cfgvalue(e, t)
|
||||
value = e.map:get(t, "ipaddress")
|
||||
return value == "*" and "" or value
|
||||
end
|
||||
function o.remove(e, t) Value.write(e, t, "*") end
|
||||
return m
|
@ -1,13 +0,0 @@
|
||||
<% include("cbi/map") %>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(2, '<%=luci.dispatcher.build_url("admin", "vpn", "pptpd", "status")%>', null,
|
||||
function(x, result)
|
||||
{
|
||||
var status = document.getElementsByClassName('pptpd_status')[0];
|
||||
status.setAttribute("style","font-weight:bold;");
|
||||
status.setAttribute("color",result.status ? "green":"red");
|
||||
status.innerHTML = result.status?'<%=translate("RUNNING")%>':'<%=translate("NOT RUNNING")%>';
|
||||
}
|
||||
)
|
||||
//]]>
|
||||
</script>
|
@ -1,3 +0,0 @@
|
||||
<%+cbi/valueheader%>
|
||||
<font class="pptpd_status"><%=pcdata(self:cfgvalue(section) or self.default or "")%></font>
|
||||
<%+cbi/valuefooter%>
|
@ -1,89 +0,0 @@
|
||||
msgid "PPTP VPN Server"
|
||||
msgstr "PPTP VPN 服务器"
|
||||
|
||||
msgid "Simple, quick and convenient PPTP VPN, universal across the platform"
|
||||
msgstr "简单快捷方便的PPTP VPN,全平台通用。"
|
||||
|
||||
msgid "PPTP VPN Server status"
|
||||
msgstr "PPTP VPN 服务器运行状态"
|
||||
|
||||
msgid "Current Condition"
|
||||
msgstr "当前状态"
|
||||
|
||||
msgid "General settings"
|
||||
msgstr "基本设置"
|
||||
|
||||
msgid "Enable VPN Server"
|
||||
msgstr "启用 VPN 服务器"
|
||||
|
||||
msgid "Server IP"
|
||||
msgstr "服务器 IP 地址"
|
||||
|
||||
msgid "VPN Server IP address, it not required."
|
||||
msgstr "VPN 服务器远程地址,留空将自动设置。"
|
||||
|
||||
msgid "Client IP"
|
||||
msgstr "客户端 IP 地址"
|
||||
|
||||
msgid "VPN Client IP address, it not required."
|
||||
msgstr "分配给客户端的 IP 地址范围,留空将自动设置。"
|
||||
|
||||
msgid "DNS IP address"
|
||||
msgstr "DNS IP 地址"
|
||||
|
||||
msgid "This will be sent to the client, it not required."
|
||||
msgstr "设置 VPN 服务器默认 DNS 服务器,该设置非必须。"
|
||||
|
||||
msgid "Enable MPPE Encryption"
|
||||
msgstr "启用MPPE 加密"
|
||||
|
||||
msgid "Allows 128-bit encrypted connection."
|
||||
msgstr "允许使用 128 位加密连接。"
|
||||
|
||||
msgid "is_nat"
|
||||
msgstr "NAT转发"
|
||||
|
||||
msgid "Interface"
|
||||
msgstr "接口"
|
||||
|
||||
msgid "Specify interface forwarding traffic."
|
||||
msgstr "指定接口转发流量。"
|
||||
|
||||
msgid "Users Manager"
|
||||
msgstr "用户管理"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "User name"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "IP address"
|
||||
msgstr "IP 地址"
|
||||
|
||||
msgid "Automatically"
|
||||
msgstr "自动分配"
|
||||
|
||||
msgid "Online Users""
|
||||
msgstr "在线用户"
|
||||
|
||||
msgid "Blacklist"
|
||||
msgstr "黑名单"
|
||||
|
||||
msgid "Add to Blacklist"
|
||||
msgstr "加入黑名单"
|
||||
|
||||
msgid "Remove from Blacklist"
|
||||
msgstr "移出黑名单"
|
||||
|
||||
msgid "Forced offline"
|
||||
msgstr "强制下线"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
@ -1,16 +0,0 @@
|
||||
|
||||
config service 'pptpd'
|
||||
option mppe '1'
|
||||
option localip '192.168.2.1'
|
||||
option remoteip '192.168.2.10-20'
|
||||
option dns '192.168.0.2'
|
||||
option is_nat '1'
|
||||
option export_interface 'default'
|
||||
option enabled '0'
|
||||
|
||||
config users
|
||||
option enabled '1'
|
||||
option ipaddress '*'
|
||||
option username 'guest'
|
||||
option password '123456'
|
||||
|
@ -1,95 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2018-2019 Lienol <lawlienol@gmail.com>
|
||||
|
||||
START=99
|
||||
CONFIG=pptpd
|
||||
CONFIG_FILE=/var/etc/$CONFIG.conf
|
||||
BIN=/usr/sbin/$CONFIG
|
||||
DEFAULT=/etc/default/$BIN
|
||||
RUN_D=/var/run
|
||||
PID_F=$RUN_D/$BIN.pid
|
||||
CHAP_SECRETS=/var/etc/chap-secrets
|
||||
SERVER_NAME="pptp-server"
|
||||
TEMP=/tmp/pptpd.tmp
|
||||
|
||||
setup_dns() {
|
||||
[ -n "$1" ] || return 0
|
||||
echo ms-dns $1>>/etc/ppp/options.pptpd
|
||||
}
|
||||
setup_login() {
|
||||
config_get enabled $1 enabled
|
||||
[ "$enabled" -eq 0 ] && return 0
|
||||
config_get ipaddress $1 ipaddress
|
||||
[ -n "$ipaddress" ] || local ipaddress = "*"
|
||||
config_get username $1 username
|
||||
config_get password $1 password
|
||||
[ -n "$username" ] || return 0
|
||||
[ -n "$password" ] || return 0
|
||||
echo "$username $SERVER_NAME $password $ipaddress" >> $CHAP_SECRETS
|
||||
}
|
||||
|
||||
setup_config() {
|
||||
config_get enabled $1 enabled
|
||||
[ "$enabled" -eq 0 ] && return 1
|
||||
|
||||
mkdir -p /var/etc
|
||||
cp /etc/pptpd.conf $CONFIG_FILE
|
||||
|
||||
config_get localip $1 localip
|
||||
config_get remoteip $1 remoteip
|
||||
config_get is_nat $1 is_nat
|
||||
|
||||
[ -z "$localip" ] && localip=$(ifconfig br-lan 2>/dev/null | grep "inet addr:" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\."|head -1)2
|
||||
[ -z "$localip" ] && remoteip=$(ifconfig br-lan 2>/dev/null | grep "inet addr:" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\."|head -1)10-20
|
||||
options="cat /etc/pptpd.conf |grep options"
|
||||
[ -n "$localip" ] && echo "localip $localip" >> $CONFIG_FILE
|
||||
[ -n "$remoteip" ] && echo "remoteip $remoteip" >> $CONFIG_FILE
|
||||
[ -n "$options" ] && echo "option /etc/ppp/options.pptpd" >> $CONFIG_FILE
|
||||
|
||||
fw3 reload
|
||||
|
||||
config_get mppe $1 mppe
|
||||
[ -n "$(cat "/etc/ppp/options.pptpd" |grep mppe)" ] && sed -i '/mppe/'d /etc/ppp/options.pptpd
|
||||
[ -z "$(cat "/etc/ppp/options.pptpd" |grep mppe)" ] && echo "mppe required,no40,no56,stateless" >> /etc/ppp/options.pptpd
|
||||
if [ "$mppe" -eq 0 ]; then
|
||||
sed -i -e 's/mppe/#mppe/g' /etc/ppp/options.pptpd
|
||||
fi
|
||||
sed -i -e '/ms-dns/d' /etc/ppp/options.pptpd
|
||||
config_get dns $1 dns
|
||||
setup_dns $dns
|
||||
echo ms-dns 223.5.5.5 >>/etc/ppp/options.pptpd
|
||||
return 0
|
||||
}
|
||||
|
||||
start_pptpd() {
|
||||
[ -f $DEFAULT ] && . $DEFAULT
|
||||
mkdir -p $RUN_D
|
||||
for m in arc4 sha1_generic slhc crc-ccitt ppp_generic ppp_async ppp_mppe; do
|
||||
insmod $m >/dev/null 2>&1
|
||||
done
|
||||
ln -sfn $CHAP_SECRETS /etc/ppp/chap-secrets
|
||||
chmod 600 /etc/ppp/*-secrets
|
||||
service_start $BIN $OPTIONS -c $CONFIG_FILE
|
||||
}
|
||||
|
||||
del_user()
|
||||
{
|
||||
cat $CHAP_SECRETS | grep -v $SERVER_NAME > $TEMP
|
||||
cat $TEMP > $CHAP_SECRETS
|
||||
rm $TEMP
|
||||
}
|
||||
|
||||
start() {
|
||||
config_load $CONFIG
|
||||
setup_config $CONFIG || return
|
||||
del_user
|
||||
config_foreach setup_login users
|
||||
start_pptpd
|
||||
}
|
||||
|
||||
stop() {
|
||||
service_stop $BIN
|
||||
ps | grep "pppd local" | grep -v "grep" | awk '{print $1}' | xargs kill -9
|
||||
fw3 reload
|
||||
del_user
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete firewall.pptpd
|
||||
set firewall.pptpd=include
|
||||
set firewall.pptpd.type=script
|
||||
set firewall.pptpd.path=/usr/share/pptpd/firewall.include
|
||||
set firewall.pptpd.reload=1
|
||||
EOF
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@pptpd[-1]
|
||||
add ucitrack pptpd
|
||||
set ucitrack.@pptpd[-1].init=pptpd
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
chmod a+x /usr/share/pptpd/* >/dev/null 2>&1
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
iptables -D INPUT -p tcp --dport 1723 -m comment --comment "Rule For PPTP VPN Server" -j ACCEPT 2> /dev/null
|
||||
pptp_nums=`iptables -t nat -L POSTROUTING 2> /dev/null|grep -c "Rule For PPTP VPN Server"`
|
||||
if [ -n "$pptp_nums" ]; then
|
||||
until [ "$pptp_nums" = 0 ]
|
||||
do
|
||||
pptp_rules=`iptables -t nat -L POSTROUTING --line-num 2> /dev/null|grep "Rule For PPTP VPN Server" |awk '{print $1}'`
|
||||
for pptp_rule in $pptp_rules
|
||||
do
|
||||
iptables -t nat -D POSTROUTING $pptp_rule 2> /dev/null
|
||||
break
|
||||
done
|
||||
pptp_nums=`expr $pptp_nums - 1`
|
||||
done
|
||||
fi
|
||||
nums=`iptables -L forwarding_rule 2> /dev/null|grep -c "Rule For PPTP VPN Server"`
|
||||
if [ -n "$nums" ]; then
|
||||
until [ "$nums" = 0 ]
|
||||
do
|
||||
rules=`iptables -L forwarding_rule --line-num 2> /dev/null|grep "Rule For PPTP VPN Server" |awk '{print $1}'`
|
||||
for rule in $rules
|
||||
do
|
||||
iptables -D forwarding_rule $rule 2> /dev/null
|
||||
break
|
||||
done
|
||||
nums=`expr $nums - 1`
|
||||
done
|
||||
fi
|
||||
|
||||
enable=$(uci get pptpd.pptpd.enabled)
|
||||
if [ $enable -eq 1 ]; then
|
||||
is_nat=$(uci get pptpd.pptpd.is_nat)
|
||||
if [ "$is_nat" -eq 1 ];then
|
||||
localip=$(uci get pptpd.pptpd.localip)
|
||||
export_interface=$(uci get pptpd.pptpd.export_interface)
|
||||
if [ "$export_interface" != "default" ];then
|
||||
iptables -t nat -I POSTROUTING -s ${localip%.*}.0/24 -o ${export_interface} -m comment --comment "Rule For PPTP VPN Server" -j MASQUERADE
|
||||
else
|
||||
iptables -t nat -I POSTROUTING -s ${localip%.*}.0/24 -m comment --comment "Rule For PPTP VPN Server" -j MASQUERADE
|
||||
fi
|
||||
iptables -I forwarding_rule -s ${localip%.*}.0/24 -m comment --comment "Rule For PPTP VPN Server" -j ACCEPT
|
||||
fi
|
||||
iptables -I INPUT -p tcp --dport 1723 -m comment --comment "Rule For PPTP VPN Server" -j ACCEPT 2>/dev/null
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user