🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
PKG_VERSION:=1.2.16
PKG_RELEASE:=1
LUCI_TITLE:=LuCI support for vnt
LUCI_DEPENDS:=+kmod-tun +luci-compat
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-vnt
define Package/$(PKG_NAME)/prerm
#!/bin/sh
if [ -f /etc/config/vnt ] ; then
echo "备份vnt配置文件/etc/config/vnt到/tmp/vnt_backup"
echo "不重启设备之前再次安装luci-app-vnt 配置不丢失,不用重新配置"
mv -f /etc/config/vnt /tmp/vnt_backup
fi
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
chmod +x /etc/init.d/vnt
if [ -f /tmp/vnt_backup ] ; then
echo "发现vnt备份配置文件/tmp/vnt_backup,开始恢复到/etc/config/vnt"
mv -f /tmp/vnt_backup /etc/config/vnt
echo "请前往 VPN - VNT 界面进行重启插件"
fi
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+241
View File
@@ -0,0 +1,241 @@
module("luci.controller.vnt", package.seeall)
function index()
if not nixio.fs.access("/etc/config/vnt") then
return
end
entry({"admin", "vpn", "vnt"}, alias("admin", "vpn", "vnt", "vnt"),_("VNT"), 44).dependent = true
entry({"admin", "vpn", "vnt", "vnt"}, cbi("vnt"),_("VNT"), 45).leaf = true
entry({"admin", "vpn", "vnt", "vnt_log"}, form("vnt_log"),_("客户端日志"), 46).leaf = true
entry({"admin", "vpn", "vnt", "get_log"}, call("get_log")).leaf = true
entry({"admin", "vpn", "vnt", "clear_log"}, call("clear_log")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_log2"}, form("vnt_log2"),_("服务端日志"), 47).leaf = true
entry({"admin", "vpn", "vnt", "get_log2"}, call("get_log2")).leaf = true
entry({"admin", "vpn", "vnt", "clear_log2"}, call("clear_log2")).leaf = true
entry({"admin", "vpn", "vnt", "status"}, call("act_status")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_info"}, call("vnt_info")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_all"}, call("vnt_all")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_list"}, call("vnt_list")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_route"}, call("vnt_route")).leaf = true
entry({"admin", "vpn", "vnt", "vnt_cmd"}, call("vnt_cmd")).leaf = true
end
function act_status()
local e = {}
local sys = require "luci.sys"
local uci = require "luci.model.uci".cursor()
local port = tonumber(uci:get_first("vnt", "vnts", "web_port"))
e.port = (port or 29870)
local web = tonumber(uci:get_first("vnt", "vnts", "web"))
e.web = (web or 0)
e.crunning = luci.sys.call("pgrep vnt-cli >/dev/null") == 0
e.srunning = luci.sys.call("pgrep vnts >/dev/null") == 0
local tagfile = io.open("/tmp/vnt_time", "r")
if tagfile then
local tagcontent = tagfile:read("*all")
tagfile:close()
if tagcontent and tagcontent ~= "" then
os.execute("start_time=$(cat /tmp/vnt_time) && time=$(($(date +%s)-start_time)) && day=$((time/86400)) && [ $day -eq 0 ] && day='' || day=${day}天 && time=$(date -u -d @${time} +'%H小时%M分%S秒') && echo $day $time > /tmp/command_vnt 2>&1")
local command_output_file = io.open("/tmp/command_vnt", "r")
if command_output_file then
e.vntsta = command_output_file:read("*all")
command_output_file:close()
end
end
end
local command2 = io.popen('test ! -z "`pidof vnt-cli`" && (top -b -n1 | grep -E "$(pidof vnt-cli)" 2>/dev/null | grep -v grep | awk \'{for (i=1;i<=NF;i++) {if ($i ~ /vnt-cli/) break; else cpu=i}} END {print $cpu}\')')
e.vntcpu = command2:read("*all")
command2:close()
local command3 = io.popen("test ! -z `pidof vnt-cli` && (cat /proc/$(pidof vnt-cli | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
e.vntram = command3:read("*all")
command3:close()
local stagfile = io.open("/tmp/vnts_time", "r")
if stagfile then
local stagcontent = stagfile:read("*all")
stagfile:close()
if stagcontent and stagcontent ~= "" then
os.execute("start_time=$(cat /tmp/vnts_time) && time=$(($(date +%s)-start_time)) && day=$((time/86400)) && [ $day -eq 0 ] && day='' || day=${day}天 && time=$(date -u -d @${time} +'%H小时%M分%S秒') && echo $day $time > /tmp/command_vnts 2>&1")
local command_output_file2 = io.open("/tmp/command_vnts", "r")
if command_output_file2 then
e.vntsta2 = command_output_file2:read("*all")
command_output_file2:close()
end
end
end
local command5 = io.popen('test ! -z "`pidof vnts`" && (top -b -n1 | grep -E "$(pidof vnts)" 2>/dev/null | grep -v grep | awk \'{for (i=1;i<=NF;i++) {if ($i ~ /vnts/) break; else cpu=i}} END {print $cpu}\')')
e.vntscpu = command5:read("*all")
command5:close()
local command6 = io.popen("test ! -z `pidof vnts` && (cat /proc/$(pidof vnts | awk '{print $NF}')/status | grep -w VmRSS | awk '{printf \"%.2f MB\", $2/1024}')")
e.vntsram = command6:read("*all")
command6:close()
local command7 = io.popen("([ -s /tmp/vnt.tag ] && cat /tmp/vnt.tag ) || (echo `$(uci -q get vnt.@vnt-cli[0].clibin) -h |grep 'version:'| awk -F 'version:' '{print $2}'` > /tmp/vnt.tag && cat /tmp/vnt.tag)")
e.vnttag = command7:read("*all")
command7:close()
local command8 = io.popen("([ -s /tmp/vntnew.tag ] && cat /tmp/vntnew.tag ) || ( curl -L -k -s --connect-timeout 3 --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' https://api.github.com/repos/vnt-dev/vnt/releases/latest | grep tag_name | sed 's/[^0-9.]*//g' >/tmp/vntnew.tag && cat /tmp/vntnew.tag )")
e.vntnewtag = command8:read("*all")
command8:close()
local command9 = io.popen("([ -s /tmp/vnts.tag ] && cat /tmp/vnts.tag ) || ( echo `$(uci -q get vnt.@vnts[0].vntsbin) -V | awk -F 'version: ' '{print $2}'` > /tmp/vnts.tag && cat /tmp/vnts.tag && [ ! -s /tmp/vnts.tag ] && echo '?' >> /tmp/vnts.tag && cat /tmp/vnts.tag )")
e.vntstag = command9:read("*all")
command9:close()
local command0 = io.popen("([ -s /tmp/vntsnew.tag ] && cat /tmp/vntsnew.tag ) || ( curl -L -k -s --connect-timeout 3 --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' https://api.github.com/repos/vnt-dev/vnts/releases/latest | grep tag_name | sed 's/[^0-9.]*//g' >/tmp/vntsnew.tag ; cat /tmp/vntsnew.tag )")
e.vntsnewtag = command0:read("*all")
command0:close()
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function get_log()
local log = ""
local files = {"/tmp/vnt-cli.log"}
for i, file in ipairs(files) do
if luci.sys.call("[ -f '" .. file .. "' ]") == 0 then
log = log .. luci.sys.exec("cat " .. file)
end
end
luci.http.write(log)
end
function clear_log()
luci.sys.call("rm -rf /tmp/vnt-cli*.log")
end
function get_log2()
local log2 = ""
local files = {"/tmp/vnts.log"}
for i, file in ipairs(files) do
if luci.sys.call("[ -f '" .. file .. "' ]") == 0 then
log2 = log2 .. luci.sys.exec("cat " .. file)
end
end
luci.http.write(log2)
end
function clear_log2()
luci.sys.call("rm -rf /tmp/vnts*.log")
end
function vnt_info()
os.execute("rm -rf /tmp/vnt-cli_info")
local info = luci.sys.exec("$(uci -q get vnt.@vnt-cli[0].clibin) --info 2>&1")
info = info:gsub("Connection status", "连接状态")
info = info:gsub("Virtual ip", "虚拟IP")
info = info:gsub("Virtual gateway", "虚拟网关")
info = info:gsub("Virtual netmask", "虚拟网络掩码")
info = info:gsub("NAT type", "NAT类型")
info = info:gsub("Relay server", "服务器地址")
info = info:gsub("Public ips", "外网IP")
info = info:gsub("Local addr", "WAN口IP")
luci.http.prepare_content("application/json")
luci.http.write_json({ info = info })
end
function vnt_all()
os.execute("rm -rf /tmp/vnt-cli_all")
local all = luci.sys.exec("$(uci -q get vnt.@vnt-cli[0].clibin) --all 2>&1")
all = all:gsub("Virtual Ip", "虚拟IP")
all = all:gsub("NAT Type", "NAT类型")
all = all:gsub("Public Ips", "外网IP")
all = all:gsub("Local Ip", "WAN口IP")
local rows = {}
for line in all:gmatch("[^\r\n]+") do
local cols = {}
for col in line:gmatch("%S+") do
table.insert(cols, col)
end
table.insert(rows, cols)
end
local html_table = "<table>"
for i, row in ipairs(rows) do
html_table = html_table .. "<tr>"
for j, col in ipairs(row) do
local colors = {"#FFA500", "#800000", "#0000FF", "#3CB371", "#00BFFF", "#DAA520", "#48D1CC", "#6600CC", "#2F4F4F"}
local color = colors[(j % 9) + 1]
html_table = html_table .. "<td><font color='" .. color .. "'>" .. col .. "</font></td>"
end
html_table = html_table .. "</tr>"
end
html_all = html_table .. "</table>"
luci.http.prepare_content("application/json")
luci.http.write_json({ all = html_all })
end
function vnt_route()
os.execute("rm -rf /tmp/vnt-cli_route")
local route = luci.sys.exec("$(uci -q get vnt.@vnt-cli[0].clibin) --route 2>&1")
route = route:gsub("Next Hop", "下一跳地址")
route = route:gsub("Interface", "连接地址")
local rows = {}
for line in route:gmatch("[^\r\n]+") do
local cols = {}
for col in line:gmatch("%S+") do
table.insert(cols, col)
end
table.insert(rows, cols)
end
local html_table = "<table>"
for i, row in ipairs(rows) do
html_table = html_table .. "<tr>"
for j, col in ipairs(row) do
local colors = {"#FFA500", "#800000", "#0000FF", "#3CB371", "#00BFFF"}
local color = colors[(j % 5) + 1]
html_table = html_table .. "<td><font color='" .. color .. "'>" .. col .. "</font></td>"
end
html_table = html_table .. "</tr>"
end
html_route = html_table .. "</table>"
luci.http.prepare_content("application/json")
luci.http.write_json({ route = html_route })
end
function vnt_list()
os.execute("rm -rf /tmp/vnt-cli_list")
local list = luci.sys.exec("$(uci -q get vnt.@vnt-cli[0].clibin) --list 2>&1")
list = list:gsub("Virtual Ip", "虚拟IP")
local rows = {}
for line in list:gmatch("[^\r\n]+") do
local cols = {}
for col in line:gmatch("%S+") do
table.insert(cols, col)
end
table.insert(rows, cols)
end
local html_table = "<table>"
for i, row in ipairs(rows) do
html_table = html_table .. "<tr>"
for j, col in ipairs(row) do
local colors = {"#FFA500", "#800000", "#0000FF", "#3CB371", "#00BFFF"}
local color = colors[(j % 5) + 1]
html_table = html_table .. "<td><font color='" .. color .. "'>" .. col .. "</font></td>"
end
html_table = html_table .. "</tr>"
end
html_table = html_table .. "</table>"
luci.http.prepare_content("application/json")
luci.http.write_json({ list = html_table })
end
function vnt_cmd()
os.execute("rm -rf /tmp/vnt*_cmd")
local html_cmd= luci.sys.exec("echo $(cat /proc/$(pidof vnt-cli)/cmdline | awk '{print $1}') 2>&1")
html_cmd = html_cmd:gsub("--no", "-不")
html_cmd = html_cmd:gsub("--dns", "dns服务")
html_cmd = html_cmd:gsub("--ip", "--地址")
html_cmd = html_cmd:gsub("--nic", "网卡名")
html_cmd = html_cmd:gsub("--use", "直连")
html_cmd = html_cmd:gsub("-channel", "方式")
luci.http.prepare_content("application/json")
luci.http.write_json({ cmd = html_cmd })
end
+600
View File
@@ -0,0 +1,600 @@
local http = luci.http
local nixio = require "nixio"
m = Map("vnt")
m.description = translate('vnt是一个简便高效的异地组网、内网穿透工具。<br>官网:<a href="http://rustvnt.com/">rustvnt.com</a>&nbsp;&nbsp;项目地址:<a href="https://github.com/vnt-dev/vnt">github.com/vnt-dev/vnt</a>&nbsp;&nbsp;安卓端、GUI:<a href="https://github.com/nt-dev/VntApp">VntApp</a>&nbsp;&nbsp;<a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=o3Rr9xUWwAAnV9TkU_Nyj3yHNLs9k5F5&authKey=l1FKvqk7%2F256SK%2FHrw0PUhs%2Bar%2BtKYx0pLb7aiwBN9%2BKBCY8sOzWWEqtl4pdXAT7&noverify=0&group_code=1034868233">QQ群</a>')
-- vnt-cli
m:section(SimpleSection).template = "vnt/vnt_status"
s = m:section(TypedSection, "vnt-cli", translate("vnt-cli 客户端设置"))
s.anonymous = true
s:tab("general", translate("基本设置"))
s:tab("privacy", translate("高级设置"))
s:tab("infos", translate("连接信息"))
s:tab("upload", translate("上传程序"))
switch = s:taboption("general",Flag, "enabled", translate("Enable"))
switch.rmempty = false
btncq = s:taboption("general", Button, "btncq", translate("重启"))
btncq.inputtitle = translate("重启")
btncq.description = translate("在没有修改参数的情况下快速重新启动一次")
btncq.inputstyle = "apply"
btncq:depends("enabled", "1")
btncq.write = function()
os.execute("/etc/init.d/vnt restart ")
end
token = s:taboption("general", Value, "token", translate("Token"),
translate("这是必填项!一个虚拟局域网的标识,连接同一服务器时,使用相同token的客户端设备才会组成一个局域网(这是 -k 参数)"))
token.optional = false
token.password = true
token.placeholder = "test"
token.datatype = "string"
token.maxlength = 63
token.minlength = 1
token.validate = function(self, value, section)
if value and #value >= 1 and #value <= 63 then
return value
else
return nil, translate("Token为必填项,可填1至63位字符")
end
end
switch.write = function(self, section, value)
if value == "1" then
token.rmempty = false
else
token.rmempty = true
end
return Flag.write(self, section, value)
end
mode = s:taboption("general",ListValue, "mode", translate("接口模式"),
translate("动态分配将由服务器随机分配一个未使用的ip地址,重启程序可能导致ip变化,建议手动指定ip并指定设备ID"))
mode:value("dhcp",translate("动态分配"))
mode:value("static",translate("手动指定"))
ipaddr = s:taboption("general",Value, "ipaddr", translate("接口IP地址"),
translate("每个vnt-cli客户端的接口IP不能相同"))
ipaddr.optional = false
ipaddr.datatype = "ip4addr"
ipaddr.placeholder = "10.26.0.5"
ipaddr:depends("mode", "static")
desvice_id = s:taboption("general",Value, "desvice_id", translate("设备ID"),
translate("每台设备的唯一标识,注意不要重复,每个vnt-cli客户端的设备ID不能相同"))
desvice_id.placeholder = "5"
localadd = s:taboption("general",DynamicList, "localadd", translate("本地网段"),
translate("每个vnt-cli客户端的内网lan网段不能相同,例如本机lanIP为192.168.1.1则填 192.168.1.0/24 "))
localadd.placeholder = "192.168.1.0/24"
peeradd = s:taboption("general",DynamicList, "peeradd", translate("对端网段"),
translate("格式为对端的lanIP网段加英文,对端的接口IP,例如对端lanIP为192.168.2.1接口IP10.26.0.3则填192.168.2.0/24,10.26.0.3"))
peeradd.placeholder = "192.168.2.0/24,10.26.0.3"
forward = s:taboption("general",Flag, "forward", translate("启用IP转发"),
translate("内置的IP代理较为简单,而且一般来说直接使用网卡NAT转发性能会更高,所以默认开启IP转发关闭内置的ip代理"))
forward.rmempty = false
allow_wg = s:taboption("general",Flag, "allow_wg", translate("允许WireGuard接入"),
translate("由于WireGuard是来自vnts转发的,如果vnts不受信任,这将会有安全隐患,所以默认不允许WireGuard流量访问本机"))
allow_wg.rmempty = false
log = s:taboption("general",Flag, "log", translate("启用日志"),
translate("运行日志在/tmp/vnt.log,可在上方客户端日志查看"))
log.rmempty = false
clibin = s:taboption("privacy", Value, "clibin", translate("vnt-cli程序路径"),
translate("自定义vnt-cli的存放路径,确保填写完整的路径及名称,若指定的路径可用空间不足将会自动移至/tmp/vnt-cli"))
clibin.placeholder = "/usr/bin/vnt-cli"
vntshost = s:taboption("privacy", Value, "vntshost", translate("vnts服务器地址"),
translate("相同的服务器,相同token的设备才会组成一个局域网<br>协议支持使用tcp://和ws://和wss://,默认为udp://"))
vntshost.placeholder = "tcp://域名:端口"
vntdns = s:taboption("privacy",DynamicList, "vntdns", translate("DNS服务器"),
translate("指定DNS服务器地址,可使用多个dns,不指定时使用系统解析"))
vntdns.placeholder = "8.8.8.8:53"
stunhost = s:taboption("privacy",DynamicList, "stunhost", translate("stun服务器地址"),
translate("使用stun服务探测客户端NAT类型,不同类型有不同的打洞策略,最多三个,超过将被忽略<br>已内置谷歌 QQ 可不填,一些<a href='https://github.com/heiher/natmap/issues/18#issue-1580804352' target='_blank'>免费stun服务器</a>"))
stunhost.placeholder = "stun.qq.com:3478"
local model = nixio.fs.readfile("/proc/device-tree/model") or ""
local hostname = nixio.fs.readfile("/proc/sys/kernel/hostname") or ""
model = model:gsub("\n", "")
hostname = hostname:gsub("\n", "")
local device_name = (model ~= "" and model) or (hostname ~= "" and hostname) or "OpenWrt"
device_name = device_name:gsub(" ", "_")
desvice_name = s:taboption("privacy", Value, "desvice_name", translate("设备名称"),
translate("本机设备名称,方便区分不同设备"))
desvice_name.placeholder = device_name
desvice_name.default = device_name
tunname = s:taboption("privacy",Value, "tunname", translate("虚拟网卡名称"),
translate("自定义虚拟网卡的名称,在多开时虚拟网卡名称不能相同,默认为 vnt-tun"))
tunname.placeholder = "vnt-tun"
relay = s:taboption("privacy",ListValue, "relay", translate("传输模式"),
translate("自动:根据当前网络环境,自动选择由服务器或客户端转发还是客户端之间直连<br>转发:仅中继转发,会禁止打洞/p2p直连,只使用服务器或客户端转发<br>p2p:仅直连模式,会禁止网络数据从服务器/客户端转发,只会使用服务器转发控制包<br>在网络环境很差时,不使用p2p只使用服务器中继转发效果可能更好(可以配合服务器的tcp协议一起使用)<br>tcp直连需要指定监听port,且防火墙需要放行第一个端口,才有几率tcp-p2p"))
relay:value("自动")
relay:value("转发")
relay:value("P2P")
client_port = s:taboption("privacy", Value, "client_port", translate("本地监听端口"),
translate("取值0~65535,指定本地监听的端口组,多个端口使用英文逗号分隔,多个端口可以分摊流量,增加并发,tcp会监听端口组的第一个端口,用于tcp直连<br>例1:12345,12346,12347 表示udp监听12345、12346、12347这三个端口,tcp监听12345端口<br>例2:0,0 表示udp监听两个未使用的端口,tcp监听一个未使用的端口"))
client_port.placeholder = "0,0"
mapping = s:taboption("privacy",DynamicList, "mapping", translate("端口映射"),
translate("端口映射,可以设置多个映射地址,例如 udp:0.0.0.0:80->10.26.0.10:80 和 tcp:0.0.0.0:80->10.26.0.11:81 <br>表示将本地udp 80端口的数据转发到10.26.0.10:80,将本地tcp 80端口的数据转发到10.26.0.11:81,转发的目的地址可以使用域名+端口"))
mapping.placeholder = "tcp:0.0.0.0:80->10.26.0.10:80"
mtu = s:taboption("privacy",Value, "mtu", translate("MTU"),
translate("设置虚拟网卡的mtu值,大多数情况下(留空)使用默认值效率会更高,也可根据实际情况进行微调,默认值:不加密1450,加密1410"))
mtu.datatype = "range(1,1500)"
mtu.placeholder = "1300"
punch = s:taboption("privacy",ListValue, "punch", translate("打洞模式"),
translate("选择只使用ipv4打洞或者只使用ipv6打洞,all都会使用,ipv6相对于ipv4速率可能会有所降低,ipv6更容易打通直连"))
punch:value("all",translate("都使用"))
punch:value("ipv4",translate("仅ipv4-tcp/udp"))
punch:value("ipv6",translate("仅ipv6-tcp/udp"))
punch:value("ipv4-tcp",translate("仅ipv4-tcp"))
punch:value("ipv6-tcp",translate("仅ipv6-tcp"))
punch:value("ipv4-udp",translate("仅ipv4-udp"))
punch:value("ipv6-udp",translate("仅ipv6-udp"))
comp = s:taboption("privacy",ListValue, "comp", translate("启用压缩"),
translate("启用压缩,默认仅支持lz4压缩,开启压缩后,如果数据包长度大于等于128,则会使用压缩,否则还是会按原数据发送<br>也支持zstd压缩,但是需要确认程序编译时是否添加支持zstd否则无法启动!编译参数--features zstd<br>如果宽度速度比较慢,可以考虑使用高级别的压缩"))
comp:value("OFF",translate("关闭"))
comp:value("lz4")
comp:value("zstd")
passmode = s:taboption("privacy",ListValue, "passmode", translate("加密模式"),
translate("默认off不加密,通常情况aes_gcm安全性高、aes_ecb性能更好,在低性能设备上aes_ecb、chacha20、chacha20_poly1305、xor速度最快<br>注意:xor为数据混淆,并不是一种强大的加密算法,易被破解,因此不适合用于真正的加密需求"))
passmode:value("off",translate("不加密"))
passmode:value("aes_ecb")
passmode:value("sm4_cbc")
passmode:value("aes_cbc")
passmode:value("aes_gcm")
passmode:value("chacha20")
passmode:value("chacha20_poly1305")
passmode:value("xor")
key = s:taboption("privacy",Value, "key", translate("加密密钥"),
translate("先开启上方的加密模式再填写密钥才能生效,使用相同密钥的客户端才能通信,服务端无法解密(包括中继转发数据)"))
key.placeholder = "wodemima"
key.password = true
key:depends("passmode", "aes_ecb")
key:depends("passmode", "sm4_cbc")
key:depends("passmode", "sm4_cbc")
key:depends("passmode", "aes_gcm")
key:depends("passmode", "chacha20")
key:depends("passmode", "chacha20_poly1305")
key:depends("passmode", "xor")
local sys = require("luci.sys")
local_dev = s:taboption("privacy", ListValue, "local_dev", translate("绑定出口网卡"),
translate("指定作为流量出口的网卡"))
local_dev.optional = false
-- 添加空白值作为默认选项
local_dev:value("", translate("不绑定"))
-- 获取通过 ifconfig 列出的网卡接口
local ifaces = sys.exec("ifconfig | grep -E '^[a-zA-Z0-9]+' | awk -F':' '{print $1}' | awk '{print $1}'")
for iface in string.gmatch(ifaces, "%S+") do
-- 使用 ip 命令获取网卡的 IP 地址
local ip_addr = sys.exec("ifconfig " .. iface .. " | grep 'inet ' | awk '{print $2}'")
ip_addr = ip_addr:gsub("%s+", "") -- 去除回车和空白字符
-- 如果没有找到 IP 地址,则继续下一个网卡
if ip_addr ~= "" then
-- 将网卡名作为值,IP地址作为显示名称
local_dev:value(iface, iface .. " (" .. ip_addr .. ")")
end
end
serverw = s:taboption("privacy",Flag, "serverw", translate("启用服务端客户端加密"),
translate("用服务端通信的数据加密,采用rsa+aes256gcm加密客户端和服务端之间通信的数据,可以避免token泄漏、中间人攻击,<br>上面的加密模式是客户端与客户端之间加密,这是服务器和客户端之间的加密,不是一个性质,无需选择加密模式"))
serverw.rmempty = false
finger = s:taboption("privacy",Flag, "finger", translate("启用数据指纹校验"),
translate("开启数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启,开启会损耗一部分性能。<br>注意:默认情况下服务端不会对中转的数据做校验,如果要对中转的数据做校验,则需要客户端、服务端都开启此参数"))
finger.rmempty = false
first_latency = s:taboption("privacy",Flag, "first_latency", translate("启用优化传输"),
translate("启用后优先使用低延迟通道,默认情况下优先使用p2p通道,某些情况下可能p2p比客户端中继延迟更高,可启用此参数进行优化传输"))
first_latency.rmempty = false
disable_stats = s:taboption("privacy",Flag, "disable_stats", translate("启用流量统计"),
translate("记录vnt使用的流量统计信息"))
disable_stats.rmempty = false
vnt_forward = s:taboption("privacy",MultiValue, "vnt_forward", translate("访问控制"),
translate("设置不同网络区域之间的流量允许规则"))
vnt_forward:value("vntfwlan", translate("允许从虚拟网络 VNT 到局域网 lan 的流量"))
vnt_forward:value("vntfwwan", translate("允许从虚拟网络 VNT 到广域网 wan 的流量"))
vnt_forward:value("lanfwvnt", translate("允许从局域网 lan 到虚拟网络 VNT 的流量"))
vnt_forward:value("wanfwvnt", translate("允许从广域网 wan 到虚拟网络 VNT 的流量"))
vnt_forward.default = "vntfwlan vntfwwan lanfwvnt"
vnt_forward.rmempty = true
check = s:taboption("privacy",Flag, "check", translate("通断检测"),
translate("开启通断检测后,可以指定对端的设备IP,当所有指定的IP都ping不通时将会重启vnt程序"))
checkip=s:taboption("privacy",DynamicList,"checkip",translate("检测IP"),
translate("确保这里的对端设备IP地址填写正确且可访问,若填写错误将会导致无法ping通,程序反复重启"))
checkip.rmempty = true
checkip.datatype = "ip4addr"
checkip:depends("check", "1")
checktime = s:taboption("privacy",ListValue, "checktime", translate("间隔时间 (分钟)"),
translate("检测间隔的时间,每隔多久检测指定的IP通断一次"))
for s=1,60 do
checktime:value(s)
end
checktime:depends("check", "1")
cmdmode = s:taboption("infos",ListValue, "cmdmode", translate(""))
cmdmode:value("原版")
cmdmode:value("表格式")
local process_status = luci.sys.exec("ps | grep vnt-cli | grep -v grep")
vnt_info = s:taboption("infos", Button, "vnt_info" )
vnt_info.rawhtml = true
vnt_info:depends("cmdmode", "表格式")
vnt_info.template = "vnt/vnt_info"
btn1 = s:taboption("infos", Button, "btn1")
btn1.inputtitle = translate("本机设备信息")
btn1.description = translate("点击按钮刷新,查看当前设备信息")
btn1.inputstyle = "apply"
btn1:depends("cmdmode", "原版")
btn1.write = function()
if process_status ~= "" then
luci.sys.call("$(uci -q get vnt.@vnt-cli[0].clibin) --info >/tmp/vnt-cli_info")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_info")
end
end
btn1info = s:taboption("infos", DummyValue, "btn1info")
btn1info.rawhtml = true
btn1info:depends("cmdmode", "原版")
btn1info.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_info") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
vnt_all = s:taboption("infos", Button, "vnt_all" )
vnt_all.rawhtml = true
vnt_all:depends("cmdmode", "表格式")
vnt_all.template = "vnt/vnt_all"
btn2 = s:taboption("infos", Button, "btn2")
btn2.inputtitle = translate("所有设备信息")
btn2.description = translate("点击按钮刷新,查看所有设备详细信息")
btn2.inputstyle = "apply"
btn2:depends("cmdmode", "原版")
btn2.write = function()
if process_status ~= "" then
luci.sys.call("$(uci -q get vnt.@vnt-cli[0].clibin) --all >/tmp/vnt-cli_all")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_all")
end
end
btn2all = s:taboption("infos", DummyValue, "btn2all")
btn2all.rawhtml = true
btn2all:depends("cmdmode", "原版")
btn2all.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_all") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
vnt_list = s:taboption("infos", Button, "vnt_list" )
vnt_list.rawhtml = true
vnt_list:depends("cmdmode", "表格式")
vnt_list.template = "vnt/vnt_list"
btn3 = s:taboption("infos", Button, "btn3")
btn3.inputtitle = translate("所有设备列表")
btn3.description = translate("点击按钮刷新,查看所有设备列表")
btn3.inputstyle = "apply"
btn3:depends("cmdmode", "原版")
btn3.write = function()
if process_status ~= "" then
luci.sys.call("$(uci -q get vnt.@vnt-cli[0].clibin) --list >/tmp/vnt-cli_list")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_list")
end
end
btn3list = s:taboption("infos", DummyValue, "btn3list")
btn3list.rawhtml = true
btn3list:depends("cmdmode", "原版")
btn3list.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_list") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
vnt_route = s:taboption("infos", Button, "vnt_route" )
vnt_route.rawhtml = true
vnt_route:depends("cmdmode", "表格式")
vnt_route.template = "vnt/vnt_route"
btn4 = s:taboption("infos", Button, "btn4")
btn4.inputtitle = translate("路由转发信息")
btn4.description = translate("点击按钮刷新,查看本机路由转发路径")
btn4.inputstyle = "apply"
btn4:depends("cmdmode", "原版")
btn4.write = function()
if process_status ~= "" then
luci.sys.call("$(uci -q get vnt.@vnt-cli[0].clibin) --route >/tmp/vnt-cli_route")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_route")
end
end
btn4route = s:taboption("infos", DummyValue, "btn4route")
btn4route.rawhtml = true
btn4route:depends("cmdmode", "原版")
btn4route.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_route") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
btnchart = s:taboption("infos", Button, "btnchart")
btnchart.inputtitle = translate("设备流量统计")
btnchart.description = translate("点击按钮刷新,查看所有设备流量统计")
btnchart.inputstyle = "apply"
btnchart:depends({ cmdmode = "原版", disable_stats = "1" })
btnchart.write = function()
if process_status ~= "" then
luci.sys.call("$(uci -q get vnt.@vnt-cli[0].clibin) --chart_a >/tmp/vnt-cli_chart")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_chart")
end
end
btn4chart = s:taboption("infos", DummyValue, "btn4chart")
btn4chart.rawhtml = true
btn4chart:depends("cmdmode", "原版")
btn4chart.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_chart") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
vnt_cmd = s:taboption("infos", Button, "vnt_cmd" )
vnt_cmd.rawhtml = true
vnt_cmd:depends("cmdmode", "表格式")
vnt_cmd.template = "vnt/vnt_cmd"
btn5 = s:taboption("infos", Button, "btn5")
btn5.inputtitle = translate("本机启动参数")
btn5.description = translate("点击按钮刷新,查看本机完整启动参数")
btn5.inputstyle = "apply"
btn5:depends("cmdmode", "原版")
btn5.write = function()
if process_status ~= "" then
luci.sys.call("echo $(cat /proc/$(pidof vnt-cli)/cmdline | awk '{print $1}') >/tmp/vnt-cli_cmd")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnt-cli_cmd")
end
end
btn5cmd = s:taboption("infos", DummyValue, "btn5cmd")
btn5cmd.rawhtml = true
btn5cmd:depends("cmdmode", "原版")
btn5cmd.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt-cli_cmd") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
local upload = s:taboption("upload", FileUpload, "upload_file")
upload.optional = true
upload.default = ""
upload.template = "vnt/other_upload"
upload.description = translate("可直接上传二进制程序vnt-cli和vnts或者以.tar.gz结尾的压缩包,上传新版本会自动覆盖旧版本,下载地址:<a href='https://github.com/vnt-dev/vnt/releases' target='_blank'>vnt-cli</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='https://github.com/vnt-dev/vnts/releases' target='_blank'>vnts</a><br>上传的文件将会保存在/tmp文件夹里,如果在高级设置里自定义了程序路径那么启动程序时将会自动移至自定义的路径<br>")
local um = s:taboption("upload",DummyValue, "", nil)
um.template = "vnt/other_dvalue"
local dir, fd, chunk
dir = "/tmp/"
nixio.fs.mkdir(dir)
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
if not fd then
um.value = translate("错误:上传失败!")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
um.value = translate("文件已上传至") .. ' "/tmp/' .. meta.file .. '"'
if string.sub(meta.file, -7) == ".tar.gz" then
local file_path = dir .. meta.file
os.execute("tar -xzf " .. file_path .. " -C " .. dir)
if nixio.fs.access("/tmp/vnt-cli") then
um.value = um.value .. "\n" .. translate("-程序/tmp/vnt-cli上传成功,重启一次客户端才生效")
end
if nixio.fs.access("/tmp/vnts") then
um.value = um.value .. "\n" .. translate("-程序/tmp/vnts上传成功,重启一次服务端才生效")
end
end
os.execute("chmod 777 /tmp/vnts")
os.execute("chmod 777 /tmp/vnt-cli")
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
end
local vnt_input = s:taboption("upload", ListValue, "vnt_input")
vnt_input:value("vnt",translate("客户端"))
vnt_input:value("vnts",translate("服务端"))
vnt_input:value("luci",translate("luci-app-vnt"))
vnt_input.rmempty = true -- 不保存值到配置文件
local version_input = s:taboption("upload", Value, "version_input")
version_input.placeholder = "指定版本号,留空为最新稳定版本"
version_input.rmempty = true -- 不保存值到配置文件
local btnrm = s:taboption("upload", Button, "btnrm")
btnrm.inputtitle = translate("更新")
btnrm.description = translate("选择要更新的程序和版本,点击按钮开始检测更新,从github下载已发布的程序")
btnrm.inputstyle = "apply"
btnrm.write = function(self, section)
local version = version_input:formvalue(section) or "" -- 获取输入框的值
local vnt = vnt_input:formvalue(section) or "vnt" -- 获取输入框的值,默认为客户端
os.execute(string.format("wget -q -O - http://s1.ct8.pl:1095/vntop.sh | sh -s -- %s %s", vnt, version))
-- 清空输入框的值
version_input.map:set(section, "version_input", "")
vnt_input.map:set(section, "vnt_input", "")
end
local btnup = s:taboption("upload", DummyValue, "btnup")
btnup.rawhtml = true
btnup.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnt_update") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
-- vnts
s = m:section(TypedSection, "vnts", translate("vnts服务器设置"))
s.anonymous = true
s:tab("gen", translate("基本设置"))
s:tab("pri", translate("高级设置"))
switch = s:taboption("gen", Flag, "enabled", translate("Enable"))
switch.rmempty = false
btnscq = s:taboption("gen", Button, "btncqs", translate("重启"))
btnscq.inputtitle = translate("重启")
btnscq.description = translate("在没有修改参数的情况下快速重新启动一次")
btnscq.inputstyle = "apply"
btnscq:depends("enabled", "1")
btnscq.write = function()
os.execute("/etc/init.d/vnt restart ")
end
server_port = s:taboption("gen",Value, "server_port", translate("本地监听端口"))
server_port.datatype = "port"
server_port.optional = false
server_port.placeholder = "29872"
white_Token = s:taboption("gen",DynamicList, "white_Token", translate("Token白名单"),
translate("填写后将只能指定的token才能连接此服务器,留空则没有限制,所有token都可以连接此服务端"))
subnet = s:taboption("gen",Value, "subnet", translate("指定DHCP网关"),
translate("分配给vnt-cli客户端的接口IP网段"))
subnet.datatype = "ip4addr"
subnet.placeholder = "10.10.0.1"
servern_netmask = s:taboption("gen",Value, "servern_netmask", translate("指定子网掩码"))
servern_netmask.placeholder = "255.255.255.0"
web = s:taboption("gen",Flag, "web", translate("启用WEB管理"),
translate("WEB管理界面,图形化显示所有客户端详情"))
web.rmempty = false
web_port = s:taboption("gen",Value, "web_port", translate("WEB端口"))
web_port.datatype = "port"
web_port:depends("web", "1")
web_port.placeholder = "29870"
webuser = s:taboption("gen", Value, "webuser", translate("帐号"),
translate("WEB管理界面的登录用户名"))
webuser.placeholder = "admin"
webuser:depends("web", "1")
webuser.password = true
webpass = s:taboption("gen", Value, "webpass", translate("密码"),
translate("WEB管理界面的登录密码"))
webpass.placeholder = "admin"
webpass:depends("web", "1")
webpass.password = true
web_wan = s:taboption("gen",Flag, "web_wan", translate("允许外网访问WEB管理"),
translate("启用后外网可访问WEB管理界面,开启后账号和密码务必设置复杂一些,定期更换,防止泄露"))
web_wan.rmempty = false
web_wan:depends("web", "1")
logs = s:taboption("gen",Flag, "logs", translate("启用日志"),
translate("运行日志在/tmp/vnts.log,可在上方服务端日志查看"))
logs.rmempty = false
vntsbin = s:taboption("pri",Value, "vntsbin", translate("vnts程序路径"),
translate("自定义vnts的存放路径,确保填写完整的路径及名称,若指定的路径可用空间不足将会自动移至/tmp/vnts,可使用上方客户端里上传程序进行上传"))
vntsbin.placeholder = "/usr/bin/vnts"
sfinger = s:taboption("pri",Flag, "sfinger", translate("启用数据指纹校验"),
translate("开启后只会转发指纹正确的客户端数据包,增强安全性,这会损失一部分性能,如果服务端开启指纹校验,则客户端也必须开启。<br>注意:默认情况下服务端不会对中转的数据做校验,如果要对中转的数据做校验,则需要客户端、服务端都开启此参数"))
sfinger.rmempty = false
public_key = s:taboption("pri",TextValue, "public_key", translate("public公钥"),
translate("服务端密钥在程序同目录/key里,可以替换成自定义的密钥对<br>修改服务端密钥后,客户端要重启才能正常链接(修改密钥后无法自动重连)"))
public_key.rows = 3
public_key.wrap = "off"
public_key.cfgvalue = function(self, section)
return nixio.fs.readfile("/tmp/vnts_key/public_key.pem") or ""
end
public_key.write = function(self, section, value)
nixio.fs.writefile("/tmp/vnts_key/public_key.pem", value:gsub("\r\n", "\n"))
end
private_key = s:taboption("pri",TextValue, "private_key", translate("private私钥"),
translate("服务端密钥在程序同目录/key里,可以替换成自定义的密钥对<br>修改服务端密钥后,客户端要重启才能正常链接(修改密钥后无法自动重连)<br>服务端密钥用于加密客户端和服务端之间传输的数据(使用rsa+aes256gcm加密)<br>可以防止token被中间人窃取,如果客户端显示的密钥指纹和服务端的不一致,<br>则表示可能有中间人攻击"))
private_key.rows = 3
private_key.wrap = "off"
private_key.cfgvalue = function(self, section)
return nixio.fs.readfile("/tmp/vnts_key/private_key.pem") or ""
end
private_key.write = function(self, section, value)
nixio.fs.writefile("/tmp/vnts_key/private_key.pem", value:gsub("\r\n", "\n"))
end
local vnts_status = luci.sys.exec("ps | grep vnts | grep -v grep")
btn6 = s:taboption("pri", Button, "btn6")
btn6.inputtitle = translate("本机启动参数")
btn6.description = translate("点击按钮刷新,查看本机完整启动参数")
btn6.inputstyle = "apply"
btn6:depends("enabled", "1")
btn6.write = function()
if vnts_status ~= "" then
luci.sys.call("echo $(cat /proc/$(pidof vnts)/cmdline | awk '{print $1}') >/tmp/vnts_cmd")
else
luci.sys.call("echo '错误:程序未运行!请启动程序后重新点击刷新' >/tmp/vnts_cmd")
end
end
btn6cmd = s:taboption("pri", DummyValue, "btn6cmd")
btn6cmd.rawhtml = true
btn6cmd:depends("enabled", "1")
btn6cmd.cfgvalue = function(self, section)
local content = nixio.fs.readfile("/tmp/vnts_cmd") or ""
return string.format("<pre>%s</pre>", luci.util.pcdata(content))
end
return m
@@ -0,0 +1,5 @@
f = SimpleForm("vnt")
f.reset = false
f.submit = false
f:append(Template("vnt/vnt-cli_log"))
return f
@@ -0,0 +1,5 @@
f = SimpleForm("vnt")
f.reset = false
f.submit = false
f:append(Template("vnt/vnts_log"))
return f
@@ -0,0 +1,8 @@
<%+cbi/valueheader%>
<span style="color: red">
<%
local val = self:cfgvalue(section) or self.default or ""
write(pcdata(val))
%>
</span>
<%+cbi/valuefooter%>
@@ -0,0 +1,5 @@
<%+cbi/valueheader%>
<label class="cbi-value" style="display:inline-block; width: 130px" for="ulfile"><%:上传程序:%></label>
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
<input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
<%+cbi/valuefooter%>
@@ -0,0 +1,33 @@
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">
//<![CDATA[
function clearlog(btn) {
XHR.get('<%=dsp.build_url("admin/vpn/vnt/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(2, '<%=dsp.build_url("admin/vpn/vnt/get_log")%>', null,
function(x, data) {
if(x && x.status == 200 && document.getElementById("checkbox1").checked == true) {
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">
<input type="checkbox" id="checkbox1" style="vertical-align:middle;height: auto;"checked><%:自动刷新%></input>
<input class="cbi-button cbi-input-remove" type="button" onclick="clearlog()" value="<%:清除日志%>" />
<textarea id="log_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="30" wrap="off" readonly="readonly"></textarea>
</fieldset>
+40
View File
@@ -0,0 +1,40 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function vnt_all(btn)
{
btn.disabled = true;
btn.value = '<%:Collecting data...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vnt", "vnt_all")%>',
null,
function(x,rv)
{
var tb = document.getElementById('<%=self.option%>-status');
if (tb) {
rv.all = rv.all.replace(/Name/g, "<em><b>设备名称</em></b>")
.replace(/虚拟IP/g, "<em><b>虚拟IP</em></b>")
.replace(/Status/g, "<em><b>状态</em></b>")
.replace(/P2P\/Relay/g, "<em><b>直连/转发</em></b>")
.replace(/Rt/g, "<em><b>延迟(ms)</em></b>")
.replace(/Online/g, "<font color='#00FF00'>在线</font>")
.replace(/NAT类型/g, "<em><b>NAT类型</em></b>")
.replace(/Cone/g, "<font color='#1E90FF'>全锥型NAT</font>")
.replace(/Symmetric/g, "<font color='#CC0000'>对称型NAT</font>")
.replace(/外网IP/g, "<em><b>外网IP</em></b>")
.replace(/WAN口IP/g, "<em><b>WAN口IP</em></b>")
.replace(/IPv6/g, "<em><b>IPv6地址</em></b>")
.replace(/server-relay/g, "<font color='#FF3300'>服务器转发</font>")
.replace(/client-relay/g, "<font color='#CC3300'>客户端转发</font>")
.replace(/Offline/g, "<font color='#CC0000'>离线</font>")
.replace(/p2p/g, "<font color='#1E90FF'>直连</font>");
tb.innerHTML = "<br><font color='#F260CE'>&nbsp;&nbsp;&nbsp;<b><%:vnt-cli --all %></b></font><br>" + rv.all ;
}
btn.disabled = false;
btn.value = '<%:所有设备信息%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:所有设备信息%>" onclick="return vnt_all(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>
+50
View File
@@ -0,0 +1,50 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function vnt_cmd(btn)
{
btn.disabled = true;
btn.value = '<%:Collecting data...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vnt", "vnt_cmd")%>',
null,
function(x,rv)
{
var tb = document.getElementById('<%=self.option%>-status');
if (tb) {
rv.cmd = rv.cmd.replace(/-k/g, "<font color='#0000FF'><em><b>-k&nbsp;</em></b></font>")
.replace(/-d/g, "<font color='#0000FF'><em><b>-d&nbsp;</em></b></font>")
.replace(/dns服务/g, "<font color='#0000FF'><em><b>--dns&nbsp;</em></b></font>")
.replace(/-n/g, "<font color='#0000FF'><em><b>-n</em></b></font>")
.replace(/-s/g, "<font color='#0000FF'><em><b>-s</em></b></font>")
.replace(/-不/g, "<font color='#0000FF'><em><b>--no</b></em></font>")
.replace(/-o/g, "<font color='#0000FF'><em><b>-o&nbsp;</b></em></font>")
.replace(/-i/g, "<font color='#0000FF'><em><b>-i&nbsp;</b></em></font>")
.replace(/-a/g, "<font color='#0000FF'><em><b>-a&nbsp;</b></em></font>")
.replace(/-w/g, "<font color='#0000FF'><em><b>-w&nbsp;</b></em></font>")
.replace(/-W/g, "<font color='#0000FF'><em><b>-W&nbsp;</b></em></font>")
.replace(/--tcp/g, "<font color='#0000FF'><em><b>--tcp&nbsp;</b></em></font>")
.replace(/--finger/g, "<font color='#0000FF'><em><b>--finger&nbsp;</b></em></font>")
.replace(/--punch/g, "<font color='#0000FF'><em><b>--punch&nbsp;</b></em></font>")
.replace(/--ports/g, "<font color='#0000FF'><em><b>--ports&nbsp;</b></em></font>")
.replace(/--model/g, "<font color='#0000FF'><em><b>--model&nbsp;</b></em></font>")
.replace(/-u/g, "<font color='#0000FF'><em><b>-u&nbsp;</b></em></font>")
.replace(/-m/g, "<font color='#0000FF'><em><b>-m&nbsp;</b></em></font>")
.replace(/--par/g, "<font color='#0000FF'><em><b>--par&nbsp;</b></em></font>")
.replace(/-e/g, "<font color='#0000FF'><em><b>-e&nbsp;</b></em></font>")
.replace(/--first-latency/g, "<font color='#0000FF'><em><b>--first-latency&nbsp;</b></em></font>")
.replace(/--relay/g, "<font color='#0000FF'><em><b>--relay&nbsp;</b></em></font>")
.replace(/--地址/g, "<font color='#0000FF'><em><b>--ip</em></b></font>")
.replace(/网卡名/g, "<font color='#0000FF'><em><b>--nic&nbsp;</em></b></font>")
.replace(/直连方式/g, "<font color='#0000FF'><em><b>--use-channel&nbsp;</em></b></font>")
.replace(/-proxy/g, "<font color='#0000FF'><em><b>-proxy</em></b></font>");
tb.innerHTML = "<br><font color='#FF00FF'>&nbsp;&nbsp;&nbsp;<b><%:当前启动参数: %></b></font><br>" + "<font color='#000066'>" + rv.cmd + "</font>";
}
btn.disabled = false;
btn.value = '<%:vnt-cli启动参数%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:vnt-cli启动参数%>" onclick="return vnt_cmd(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>
+40
View File
@@ -0,0 +1,40 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function vnt_info(btn)
{
btn.disabled = true;
btn.value = '<%:Collecting data...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vnt", "vnt_info")%>',
null,
function(x,rv)
{
var tb = document.getElementById('<%=self.option%>-status');
if (tb) {
rv.info = rv.info.replace(/Name:/g, "<font color='#0000FF'><em><b>设备名称:</em></b></font>")
.replace(/虚拟IP:/g, "<font color='#0000FF'><em><b><br>虚拟IP:</em></b></font>")
.replace(/虚拟网关:/g, "<font color='#0000FF'><em><b><br>虚拟网关:</em></b></font>")
.replace(/虚拟网络掩码:/g, "<font color='#0000FF'><em><b><br>虚拟网络掩码:</em></b></font>")
.replace(/NAT类型:/g, "<font color='#0000FF'><em><b><br>NAT类型:</em></b></font>")
.replace(/服务器地址:/g, "<font color='#0000FF'><em><b><br>服务器地址:</em></b></font>")
.replace(/外网IP:/g, "<font color='#0000FF'><em><b><br>外网IP:</em></b></font>")
.replace(/连接状态:/g, "<font color='#0000FF'><em><b><br>连接状态:</em></b></font>")
.replace(/WAN口IP:/g, "<font color='#0000FF'><em><b><br>WAN口IP:</em></b></font>")
.replace(/IPv6:/g, "<font color='#0000FF'><em><b><br>IPv6地址:</em></b></font>")
.replace(/Connected/g, "<font color='#00CC00'>已连接</font>")
.replace(/Connecting/g, "<font color='#FF0000'>正在连接</font>")
.replace(/Cone/g, "<font color='#33B728'>全锥型NAT</font>")
.replace(/Up:/g, "<font color='#0000FF'><em><b><br>上传总量:</em></b></font>")
.replace(/Down:/g, "<font color='#0000FF'><em><b><br>下载总量:</em></b></font>")
.replace(/Symmetric/g, "<font color='#CC0000'>对称型NAT</font>");
tb.innerHTML = "<br><font color='#FF00FF'>&nbsp;&nbsp;&nbsp;<b><%:vnt-cli --info %></b></font><br>" + "<font color='#FF4500'>" + rv.info + "</font>";
}
btn.disabled = false;
btn.value = '<%:本机设备信息%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:本机设备信息%>" onclick="return vnt_info(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>
+34
View File
@@ -0,0 +1,34 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function vnt_list(btn)
{
btn.disabled = true;
btn.value = '<%:Collecting data...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vnt", "vnt_list")%>',
null,
function(x,rv)
{
var tb = document.getElementById('<%=self.option%>-status');
if (tb) {
rv.list = rv.list.replace(/Name/g, "<em><b>设备名称</em></b>")
.replace(/虚拟IP/g, "<em><b>虚拟IP</em></b>")
.replace(/Status/g, "<em><b>状态</em></b>")
.replace(/P2P\/Relay/g, "<em><b>直连/转发</em></b>")
.replace(/Rt/g, "<em><b>延迟(ms)</em></b>")
.replace(/Online/g, "<font color='#008000'>在线</font>")
.replace(/p2p/g, "<font color='#008000'>直连</font>")
.replace(/server-relay/g, "<font color='#FF3300'>服务器转发</font>")
.replace(/client-relay/g, "<font color='#CC3300'>客户端转发</font>")
.replace(/Offline/g, "<font color='#CC0000'>离线</font>");
tb.innerHTML = "<br><font color='#FF00FF'>&nbsp;&nbsp;&nbsp;<b><%:vnt-cli --list %></b></font><br>" + rv.list ;
}
btn.disabled = false;
btn.value = '<%:所有设备列表%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:所有设备列表%>" onclick="return vnt_list(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>
@@ -0,0 +1,29 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function vnt_route(btn)
{
btn.disabled = true;
btn.value = '<%:Collecting data...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "vnt", "vnt_route")%>',
null,
function(x,rv)
{
var tb = document.getElementById('<%=self.option%>-status');
if (tb) {
rv.route = rv.route.replace(/Destination/g, "<em><b>对端地址</em></b>")
.replace(/下一跳地址/g, "<em><b>下一跳地址</em></b>")
.replace(/Metric/g, "<em><b>跳数</em></b>")
.replace(/Rt/g, "<em><b>延迟(ms)</em></b>")
.replace(/连接地址/g, "<em><b>连接地址</em></b>")
tb.innerHTML = "<br><font color='#FF00FF'>&nbsp;&nbsp;&nbsp;<b><%:vnt-cli --route %></b></font><br>" + rv.route ;
}
btn.disabled = false;
btn.value = '<%:路由转发信息%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:路由转发信息%>" onclick="return vnt_route(this)" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>
@@ -0,0 +1,36 @@
<%
local uci = require 'luci.model.uci'.cursor()
protocol="http://"
%>
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[vpn]], [[vnt]], [[status]])%>', null,
function(x, data) {
var st = document.getElementById('vnt_status');
if (data && st) {
var clientStatus = data.crunning ? "<span style='color:green;'> 运行中</span><img src='https://www.right.com.cn/forum/data/attachment/album/202401/30/081238k459q2d5klacs8rk.gif' width='30px' alt=''>" : "<span style='color:red;'> 未运行</span>";
var serverStatus = data.srunning ? "<span style='color:green;'> 运行中</span><img src='https://www.right.com.cn/forum/data/attachment/album/202401/30/081238k459q2d5klacs8rk.gif' width='30px' alt=''>" : "<span style='color:red;'> 未运行</span>";
var vntstaContent = data.crunning ? "已运行:" + "<span style='color:#DA70D6;'>" + data.vntsta + "</span>" : "";
var vntcpuContent = data.crunning ? "<br>" + "CPU占用:" + "<span style='color:#6A5ACD;'>" + data.vntcpu + "</span>" : "";
var vntramContent = data.crunning ? "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + "&nbsp;&nbsp;&nbsp;&nbsp;内存占用:" + "<span style='color:#0000CD;'>" + data.vntram + "</span>" : "";
var vntsta2Content = data.srunning ? "&nbsp;&nbsp;&nbsp;&nbsp;" + "&nbsp;&nbsp;已&nbsp;运&nbsp;行&nbsp;:" + "<span style='color:#DA70D6;'>" + data.vntsta2 + "</span>" : "";
var vntscpuContent = data.srunning ? "<br>" + "CPU占用:" + "<span style='color:#6A5ACD;'>" + data.vntscpu + "</span>" : "";
var vntsramContent = data.srunning ? "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + "&nbsp;&nbsp;&nbsp;内存占用:" + "<span style='color:#0000CD;'>" + data.vntsram + "</span>" : "";
var vnttagContent = data.crunning ? "<br>" + "当前版本:" + "<span style='color:#CD853F;'>" + data.vnttag + "</span>" : "";
var vntnewtagContent = data.crunning ? "&nbsp;&nbsp;&nbsp;&nbsp;" + "&nbsp;&nbsp;&nbsp;最新版本:" + "<span style='color:#FFA500;'>" + data.vntnewtag + "</span>" : "";
var vntstagContent = data.srunning ? "<br>" + "当前版本:" + "<span style='color:#CD853F;'>" + data.vntstag + "</span>" : "";
var vntsnewtagContent = data.srunning ? "&nbsp;&nbsp;&nbsp;" + "最新版本:" + "<span style='color:#FFA500;'>" + data.vntsnewtag + "</span>" : "";
var vntswebContent = "";
if (data.web !== 0 && data.srunning) {
vntswebContent = "&nbsp;&nbsp;&nbsp;" + "<input class=\"cbi-button cbi-button-reload mar-10\" type=\"button\" value=\" <%:Web 界面%> \" onclick=\"window.open('<%=protocol%>" + window.location.hostname + ":" + data.port + "/')\"/>";
}
st.innerHTML = "<em><b>vnt-cli " + clientStatus + vntstaContent + vntcpuContent + vntramContent + vnttagContent + vntnewtagContent + "</b></em><br><br><em><b>vnts " + serverStatus + vntsta2Content + vntscpuContent + vntsramContent + vntstagContent + vntsnewtagContent + vntswebContent + "</b></em>";
}
}
);
//]]>
</script>
<fieldset class="cbi-section">
<p id="vnt_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
+33
View File
@@ -0,0 +1,33 @@
<%
local dsp = require "luci.dispatcher"
-%>
<script type="text/javascript">
//<![CDATA[
function clearlog(btn) {
XHR.get('<%=dsp.build_url("admin/vpn/vnt/clear_log2")%>', null,
function(x, data) {
if(x && x.status == 200) {
var log2_textarea = document.getElementById('log2_textarea');
log2_textarea.innerHTML = "";
log2_textarea.scrollTop = log2_textarea.scrollHeight;
}
}
);
}
XHR.poll(2, '<%=dsp.build_url("admin/vpn/vnt/get_log2")%>', null,
function(x, data) {
if(x && x.status == 200 && document.getElementById("checkbox2").checked == true) {
var log2_textarea = document.getElementById('log2_textarea');
log2_textarea.innerHTML = x.responseText;
log2_textarea.scrollTop = log2_textarea.scrollHeight;
}
}
);
//]]>
</script>
<fieldset class="cbi-section" id="_log_fieldset">
<input type="checkbox" id="checkbox2" style="vertical-align:middle;height: auto;"checked><%:自动刷新%></input>
<input class="cbi-button cbi-input-remove" type="button" onclick="clearlog()" value="<%:清除日志%>" />
<textarea id="log2_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="30" wrap="off" readonly="readonly"></textarea>
</fieldset>
+24
View File
@@ -0,0 +1,24 @@
config vnt-cli
option enabled '0'
option mode 'static'
option ipaddr '10.26.0.6'
option desvice_id '10.26.0.6'
option punch 'ipv4/ipv6'
option forward '1'
option serverw '0'
option finger '0'
option relay '0'
option first_latency '0'
option multicast '0'
option tunmode 'tun'
option passmode 'off'
option clibin '/usr/bin/vnt-cli'
option vnt_input 'vnt'
config vnts
option enabled '0'
option server_port '29872'
option subnet '10.26.0.1'
option vntsbin '/usr/bin/vnts'
option logs '1'
option web '0'
option sfinger '0'
+660
View File
@@ -0,0 +1,660 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2008-2020 OpenWrt.org
START=99
USE_PROCD=1
size="$(df -k | awk '/\/overlay$/ {sub(/K$/, "", $4); print $4}')"
[ -z "$size" ] && size="$(df -k /usr/bin | awk 'NR==2 {print $(NF-2) }')"
curltest=`which curl`
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
get_tz() {
SET_TZ=""
[ -e "/etc/localtime" ] && return
for tzfile in /etc/TZ /var/etc/TZ
do
[ -e "$tzfile" ] || continue
tz="$(cat $tzfile 2>/dev/null)"
done
[ -z "$tz" ] && return
SET_TZ=$tz
}
start_vntcli() {
local cfg="$1"
local enabled
config_get_bool enabled "$cfg" 'enabled' '0'
[ "$enabled" = "1" ] || return 1
config_get clibin "$cfg" 'clibin'
if [ -z "$clibin" ] ;then
clibin=/tmp/vnt-cli
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : vnt-cli_${cpucore}开始启动" >>/tmp/vnt-cli.log
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 若启动失败,请打开 状态 - 系统日志 找到vnt相关的字眼查看启动失败错误的原因" >>/tmp/vnt-cli.log
[ -z "`opkg list-installed | grep kmod-tun`" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 未安装kmod-tun模块, 请确定安装好kmod-tun " >>/tmp/vnt-cli.log
path=$(dirname "$clibin")
if [ -f /tmp/vnt-cli ] && [ "${path:0:4}" != "/tmp" ] ;then
mkdir -p $path
chmod +x /tmp/vnt-cli
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 找到上传的程序/tmp/vnt-cli,替换为$clibin " >>/tmp/vnt-cli.log
upsize="$(du -k /tmp/vnt-cli | cut -f1)"
result=$(expr $size - $upsize)
if [ "$(($(/tmp/vnt-cli -h 2>&1 | wc -l)))" -gt 3 ] && [ "$result" -gt 500 ] ; then
mv -f /tmp/vnt-cli "$clibin"
else
[ -z "$size" ] && [ "$(($(/tmp/vnt-cli -h 2>&1 | wc -l)))" -gt 3 ] && mv -f /tmp/vnt-cli "$clibin"
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 无法替换,上传的程序不完整或自定义路径的可用空间不足,当前空间剩余${size}kb" >>/tmp/vnt-cli.log
fi
fi
if [ ! -f "$clibin" ] && [ "$size" -lt 4000 ] && [ ! -z "$size" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 自定义程序路径的可用空间不足,当前可用空间剩余${size}kb,自动切换为内存/tmp/vnt-cli" >>/tmp/vnt-cli.log
sed -i "/clibin/c option clibin '/tmp/vnt-cli' " /etc/config/vnt
clibin=/tmp/vnt-cli
fi
if [ "$($clibin -h 2>&1 | wc -l)" -lt 3 ] || [ ! -f "$clibin" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 未找到程序 $clibin 开始在线下载,下载较慢耐心等候" >>/tmp/vnt-cli.log
mkdir -p "$path"
if [ -z "$curltest" ] || [ ! -s "`which curl`" ] ; then
tag="$( wget -T 5 -t 3 --user-agent "$user_agent" --max-redirect=0 --output-document=- https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- https://dl.cnqq.cloudns.ch/https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
else
tag="$( curl --connect-timeout 3 --user-agent "$user_agent" https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( curl -k --connect-timeout 3 --user-agent "$user_agent" -s https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( curl -Lk --connect-timeout 5 --user-agent "$user_agent" -s https://dl.cnqq.cloudns.ch/https://api.github.com/repos/vnt-dev/vnt/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
fi
[ -z "$tag" ] && tag="v1.2.16"
case "${cpucore}" in
"mipsle") url="mipsel-unknown-linux-musl"
;;
"mips") url="mips-unknown-linux-musl"
;;
"x86_64") url="x86_64-unknown-linux-musl"
;;
"i386") url="i686-unknown-linux-musl"
;;
"aarch64") url="aarch64-unknown-linux-musl"
;;
"armv7") url="armv7-unknown-linux-musleabi"
;;
"arm") url="arm-unknown-linux-musleabi"
;;
esac
for proxy in $proxys ; do
curl -Lko /tmp/vnt-cli.tar.gz "${proxy}https://github.com/vnt-dev/vnt/releases/download/${tag}/vnt-${url}-${tag}.tar.gz" || wget --no-check-certificate -O /tmp/vnt-cli.tar.gz "${proxy}https://github.com/vnt-dev/vnt/releases/download/${tag}/vnt-${url}-${tag}.tar.gz"
if [ "$?" = 0 ] ; then
tar -zxf /tmp/vnt-cli.tar.gz -C $path
rm -f /tmp/vnt-cli.tar.gz ${path}/vn-link-cli ${path}/README.md >/dev/null 2>&1
chmod +x "$clibin"
if [ "$($clibin -h 2>&1 | wc -l)" -gt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : ${clibin} 下载成功" >>/tmp/vnt-cli.log
break
else
uci -q set vnt.@vnt-cli[0].enabled=0
uci commit vnt
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : $clibin 下载失败,请手动下载上传程序,程序退出" >>/tmp/vnt-cli.log
return 1
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : $clibin 下载失败,请手动下载上传程序,程序退出" >>/tmp/vnt-cli.log
fi
done
fi
chmod +x "$clibin"
ver="$($clibin -h | grep version | awk -F ':' {'print $2'})"
[ ! -z "$ver" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : ${clibin}当前版本号-${ver} " >>/tmp/vnt-cli.log
pgrep -f vnt_check | xargs kill -9 >/dev/null 2>&1
ps | grep 'vnt-cli' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'vnt-cli' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
local token mode ipaddr mtu desvice_id localadd log comp local_dev
local peeradd desvice_name vntshost stunhost checkip mapping disable_stats
local punch client_port key forward serverw vntdns allow_wg
local finger relay first_latency tunname passmode
config_get token "$cfg" 'token'
config_get vntdns "$cfg" 'vntdns'
config_get desvice_id "$cfg" 'desvice_id'
config_get desvice_name "$cfg" 'desvice_name'
config_get vntshost "$cfg" 'vntshost'
config_get local_dev "$cfg" 'local_dev'
config_get stunhost "$cfg" 'stunhost'
config_get client_port "$cfg" 'client_port'
config_get punch "$cfg" 'punch' 'all'
config_get passmode "$cfg" 'passmode'
config_get peeradd "$cfg" 'peeradd'
config_get localadd "$cfg" 'localadd'
config_get mode "$cfg" 'mode'
config_get ipaddr "$cfg" 'ipaddr'
config_get mtu "$cfg" 'mtu'
config_get tunname "$cfg" 'tunname'
config_get key "$cfg" 'key'
config_get relay "$cfg" 'relay'
config_get_bool serverw "$cfg" 'serverw' '0'
config_get_bool forward "$cfg" 'forward' '0'
config_get_bool finger "$cfg" 'finger' '0'
config_get_bool first_latency "$cfg" 'first_latency' '0'
config_get_bool log "$cfg" 'log' '0'
config_get_bool disable_stats "$cfg" 'disable_stats' '0'
config_get_bool allow_wg "$cfg" 'allow_wg' '0'
config_get checkip "$cfg" 'checkip'
config_get comp "$cfg" 'comp'
config_get mapping "$cfg" 'mapping'
if [ "$log" = "1" ] ;then
if [ ! -f /tmp/log4rs.yaml ] ; then
cat > /tmp/log4rs.yaml<<EOF
refresh_rate: 30 seconds
appenders:
rolling_file:
kind: rolling_file
path: /tmp/vnt-cli.log
append: true
encoder:
pattern: "{d(%Y-%m-%d %H:%M:%S vnt-cli:)} [{f}:{L}] {h({l})} {M}:{m}{n}"
policy:
kind: compound
trigger:
kind: size
limit: 1 mb
roller:
kind: fixed_window
pattern: /tmp/vnt-cli.{}.log
base: 1
count: 2
root:
level: info
appenders:
- rolling_file
EOF
fi
[ ! -L /log4rs.yaml ] && rm -rf /log4rs.yaml && ln -sf /tmp/log4rs.yaml /log4rs.yaml
[ ! -L /tmp/vnt-cli.0.log ] && ln -sf /tmp/vnt-cli.log /tmp/vnt-cli.0.log
[ ! -L /tmp/vnt-cli.1.log ] && ln -sf /tmp/vnt-cli.log /tmp/vnt-cli.1.log
[ ! -L /tmp/vnt-cli.2.log ] && ln -sf /tmp/vnt-cli.log /tmp/vnt-cli.2.log
else
rm -rf /tmp/log4rs.yaml
fi
procd_open_instance "vnt-cli"
get_tz
[ -z "$SET_TZ" ] || procd_set_param env TZ="$SET_TZ"
procd_set_param command "$clibin"
procd_append_param command -k "$token"
[ -z "$ipaddr" ] || procd_append_param command --ip "$ipaddr"
[ -z "$mtu" ] || procd_append_param command -u "$mtu"
[ -z "$desvice_id" ] || procd_append_param command -d "$desvice_id"
[ -z "$desvice_name" ] || procd_append_param command -n "$desvice_name"
[ -z "$vntshost" ] || procd_append_param command -s "$vntshost"
[ -z "$client_port" ] || procd_append_param command --ports "$client_port"
if [ ! -z "$peeradd" ] ; then
if [[ "$(grep "list peeradd" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command -i "$peeradd"
else
for peeraddr in $(cat /etc/config/vnt | grep 'list peeradd' | awk -F 'list peeradd' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command -i "$peeraddr"
done
fi
fi
if [ ! -z "$localadd" ] ; then
if [[ "$(grep "list localadd" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command -o "$localadd"
else
for localaddr in $(cat /etc/config/vnt | grep 'list localadd' | awk -F 'list localadd' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command -o "$localaddr"
done
fi
fi
if [ ! -z "$vntdns" ] ; then
if [[ "$(grep "list vntdns" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command --dns "$vntdns"
else
for vntdnss in $(cat /etc/config/vnt | grep 'list vntdns' | awk -F 'list vntdns' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command --dns "$vntdnss"
done
fi
fi
if [ ! -z "$stunhost" ] ; then
if [[ "$(grep "list stunhost" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command -e "$stunhost"
else
for stunhosts in $(cat /etc/config/vnt | grep 'list stunhost' | awk -F 'list stunhost' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command -e "$stunhosts"
done
fi
fi
if [ ! -z "$mapping" ] ; then
if [[ "$(grep "list mapping" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command --mapping "$mapping"
else
for mappings in $(cat /etc/config/vnt | grep 'list mapping' | awk -F 'list mapping' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command --mapping "$mappings"
done
fi
fi
[ -z "$tunname" ] || procd_append_param command --nic "$tunname"
[ -z "$local_dev" ] || procd_append_param command --local-dev "$local_dev"
[ "$punch" = "all" ] || procd_append_param command --punch "$punch"
[ "$passmode" != "off" ] && [ -n "$key" ] && procd_append_param command --model "$passmode"
[ "$passmode" != "off" ] && [ -n "$key" ] && procd_append_param command -w "$key"
[ "$allow_wg" = "0" ] || procd_append_param command --allow-wg
[ "$forward" = "0" ] || procd_append_param command --no-proxy
[ "$finger" = "0" ] || procd_append_param command --finger
[ "$serverw" = "0" ] || procd_append_param command -W
[ "$disable_stats" = "1" ] || procd_append_param command --disable-stats
[ "$first_latency" = "0" ] || procd_append_param command --first-latency
[ "$relay" = "转发" ] && procd_append_param command --use-channel relay
[ "$relay" = "P2P" ] && procd_append_param command --use-channel p2p
[ "$comp" != "OFF" ] && procd_append_param command --compressor "$comp"
procd_set_param limits core="unlimited"
procd_set_param limits nofile="1000000 1000000"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
if [ -z "$tunname" ] ; then
vnt_tun="vnt-tun"
else
vnt_tun="$tunname"
fi
if [ ! -z "$client_port" ] ; then
if [ ! -z "$(echo $client_port | grep ',' )" ] ; then
vnt_tcp_port="${client_port%%,*}"
else
vnt_tcp_port="$client_port"
fi
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 添加端口放行规则,放行TCP端口 $vnt_tcp_port" >>/tmp/vnt-cli.log
uci -q delete firewall.vntcli
uci set firewall.vntcli=rule
uci set firewall.vntcli.name="vntcli"
uci set firewall.vntcli.target="ACCEPT"
uci set firewall.vntcli.src="wan"
uci set firewall.vntcli.proto="tcp"
uci set firewall.vntcli.dest_port="$vnt_tcp_port"
uci set firewall.vntcli.enabled="1"
fi
#vnt_ip="$($clibin --info | awk -F 'Virtual ip:' {'print $2'} | tr -d ' \n')"
if [ -z "$(uci -q get network.VNT)" ]; then
uci set network.VNT='interface'
if [ -z "$ipaddr" ]; then
uci set network.VNT.proto='none'
else
uci set network.VNT.proto='static'
uci set network.VNT.ipaddr=$ipaddr
uci set network.VNT.netmask='255.255.255.0'
fi
uci set network.VNT.device=$vnt_tun
uci set network.VNT.device=$vnt_tun
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 添加网络接口 VNT ,绑定虚拟网卡$vnt_tun " >>/tmp/vnt-cli.log
fi
if [ -z "$(uci -q get firewall.vntzone)" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 添加防火墙规则,开启IP动态伪装 MSS钳制" >>/tmp/vnt-cli.log
uci set firewall.vntzone='zone'
uci set firewall.vntzone.input='ACCEPT'
uci set firewall.vntzone.output='ACCEPT'
uci set firewall.vntzone.forward='ACCEPT'
uci set firewall.vntzone.masq='1'
uci set firewall.vntzone.mtu_fix='1'
uci set firewall.vntzone.name='VNT'
uci set firewall.vntzone.network='VNT'
fi
vnt_forward="$(uci -q get vnt.@vnt-cli[0].vnt_forward)"
if [ "${vnt_forward//vntfwlan/}" != "$vnt_forward" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 允许从虚拟网络 VNT 到局域网 lan 的流量" >>/tmp/vnt-cli.log
uci set firewall.vntfwlan=forwarding
uci set firewall.vntfwlan.dest='lan'
uci set firewall.vntfwlan.src='VNT'
else
uci -q delete firewall.vntfwlan
fi
if [ "${vnt_forward//vntfwwan/}" != "$vnt_forward" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 允许从虚拟网络 VNT 到广域网 wan 的流量" >>/tmp/vnt-cli.log
uci set firewall.vntfwwan=forwarding
uci set firewall.vntfwwan.dest='wan'
uci set firewall.vntfwwan.src='VNT'
else
uci -q delete firewall.vntfwwan
fi
if [ "${vnt_forward//lanfwvnt/}" != "$vnt_forward" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 允许从局域网 lan 到虚拟网络 VNT 的流量" >>/tmp/vnt-cli.log
uci set firewall.lanfwvnt=forwarding
uci set firewall.lanfwvnt.dest='VNT'
uci set firewall.lanfwvnt.src='lan'
else
uci -q delete firewall.lanfwvnt
fi
if [ "${vnt_forward//wanfwvnt/}" != "$vnt_forward" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 允许从广域网 wan 到虚拟网络 VNT 的流量" >>/tmp/vnt-cli.log
uci set firewall.wanfwvnt=forwarding
uci set firewall.wanfwvnt.dest='VNT'
uci set firewall.wanfwvnt.src='wan'
else
uci -q delete firewall.wanfwvnt
fi
[ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1
[ "$forward" = "0" ] || sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1
[ ! -z "$checkip" ] && check
echo `date +%s` > /tmp/vnt_time
}
check () {
if [ ! -z "$checkip" ] ; then
echo ' ' >/tmp/vnt_check
cat > /tmp/vnt_check<<'EOF'
#!/bin/sh
time="$(($(uci -q get vnt.@vnt-cli[0].checktime) * 60))"
if [ -z "$time" ] ;then
time=120
uci -q set vnt.@vnt-cli[0].checktime=2
uci commit vnt
fi
while true; do
if [ "$(uci -q get vnt.@vnt-cli[0].enabled)" = "1" ] ; then
/bin/ping -c 3 223.5.5.5 -w 5 >/dev/null 2>&1
if [ "$?" == "0" ]; then
if [ ! -z "$(uci -q get vnt.@vnt-cli[0].checkip)" ] ; then
online=""
for ip in $(uci -q get vnt.@vnt-cli[0].checkip); do
ms=`echo $(/bin/ping -4 $ip -c 2 -w 4 -q) | awk -F '/' '{print $4}'`
[ ! -z "$ms" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 通断检测:${ip} 延迟:${ms}ms " >>/tmp/vnt-cli.log && online=1
[ -z "$ms" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 通断检测:${ip} 网络中断 " >>/tmp/vnt-cli.log
done
[ "$online" != "1" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 通断检测:$(uci -q get vnt.@vnt-cli[0].checkip) 所有指定IP皆无法ping通,重新启动程序! " >>/tmp/vnt-cli.log && /etc/init.d/vnt restart
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 通断检测:检测到互联网未能成功访问,跳过检测 " >>/tmp/vnt-cli.log
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 通断检测:程序已关闭,退出检测 " >>/tmp/vnt-cli.log
/etc/init.d/vnt restart
break
fi
sleep $((time))
[ "$(du -k /log/vnt-cli.log | cut -f1)" = "1000" ] && echo " " >/tmp/vnt-cli.log
done
EOF
chmod +x /tmp/vnt_check
procd_open_instance
procd_set_param respawn
procd_set_param command /tmp/vnt_check
procd_close_instance
fi
}
start_vnts() {
local cfg="$1"
local enabled
config_get_bool enabled "$cfg" 'enabled' '0'
[ "$enabled" = "1" ] || return 1
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : vnts_${cpucore}开始启动" >>/tmp/vnts.log
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 若启动失败,请打开 状态 - 系统日志 找到vnt相关的字眼查看启动失败错误的原因" >>/tmp/vnts.log
config_get vntsbin "$cfg" 'vntsbin'
if [ -z "$vntsbin" ] ;then
vntsbin=/tmp/vnts
fi
if [ -f /tmp/vnts ] && [ "${path:0:4}" != "/tmp" ] ;then
chmod +x /tmp/vnts
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 找到上传的程序/tmp/vnts,替换为$vntsbin " >>/tmp/vnts.log
upsize="$(du -k /tmp/vnts | cut -f1)"
result=$(expr $size - $upsize)
if [ "$(($(/tmp/vnts -h 2>&1 | wc -l)))" -gt 3 ] && [ "$result" -gt 500 ] ; then
mv -f /tmp/vnts "$vntsbin"
else
[ -z "$size" ] && [ "$(($(/tmp/vnts -h 2>&1 | wc -l)))" -gt 3 ] && mv -f /tmp/vnts "$vntsbin"
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 无法替换,上传的程序不完整或自定义路径的可用空间不足,当前空间剩余${size}kb" >>/tmp/vnts.log
fi
fi
if [ ! -f "$vntsbin" ] && [ "$size" -lt 10240 ] && [ ! -z "$size" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 自定义程序路径的可用空间不足,当前可用空间剩余${size}kb,自动切换为内存/tmp/vnts" >>/tmp/vnts.log
uci -q set vnt.@vnts[0].vntsbin=/tmp/vnts
uci commit
vntsbin=/tmp/vnts
fi
path=$(dirname "$vntsbin")
key_path="${path}/key"
log_path="${path}/log"
if [ "$($vntsbin -h 2>&1 | wc -l)" -lt 3 ] || [ ! -f "$vntsbin" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : ${vntsbin} 不存在,开始在线下载,下载较慢耐心等候..." >>/tmp/vnts.log
mkdir -p "$path"
if [ -z "$curltest" ] || [ ! -s "`which curl`" ] ; then
tag="$( wget -T 5 -t 3 --user-agent "$user_agent" --max-redirect=0 --output-document=- https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( wget --no-check-certificate -T 5 -t 3 --user-agent "$user_agent" --quiet --output-document=- https://dl.cnqq.cloudns.ch/https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
else
tag="$( curl --connect-timeout 3 --user-agent "$user_agent" https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( curl -k --connect-timeout 3 --user-agent "$user_agent" -s https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
[ -z "$tag" ] && tag="$( curl -Lk --connect-timeout 5 --user-agent "$user_agent" -s https://dl.cnqq.cloudns.ch/https://api.github.com/repos/vnt-dev/vnts/releases/latest 2>&1 | grep 'tag_name' | cut -d\" -f4 )"
fi
[ -z "$tag" ] && tag=v1.2.12
case "${cpucore}" in
"mipsle") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-mipsel-unknown-linux-musl-${tag}.tar.gz"
;;
"mips") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-mips-unknown-linux-musl-${tag}.tar.gz"
;;
"x86_64") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-x86_64-unknown-linux-musl-${tag}.tar.gz"
;;
"i386") echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 不支持的架构,程序退出" >>/tmp/vnts.log
return 1
;;
"arm") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-arm-unknown-linux-musleabi-${tag}.tar.gz"
;;
"armv7") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-armv7-unknown-linux-musleabi-${tag}.tar.gz"
;;
"aarch64") vntsurl="https://github.com/vnt-dev/vnts/releases/download/${tag}/vnts-aarch64-unknown-linux-musl-${tag}.tar.gz"
;;
esac
for proxy in $proxys ; do
curl -Lko /tmp/vnts.tar.gz "${proxy}${vntsurl}" || wget --no-check-certificate -O /tmp/vnts.tar.gz "${proxy}${vntsurl}"
if [ "$?" = 0 ] ; then
tar zxf /tmp/vnts.tar.gz -C /tmp/
chmod +x /tmp/vnts
rm -rf /tmp/vnts.tar.gz
if [ "$(($(/tmp/vnts -h 2>&1 | wc -l)))" -gt 3 ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : /tmp/vnts 下载成功" >>/tmp/vnts.log
mv -f /tmp/vnts "$vntsbin"
break
else
uci -q set vnt.@vnts[0].enabled=0
uci commit vnt
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : $vntsbin 下载失败,请手动下载上传程序,程序退出" >>/tmp/vnts.log
return 1
fi
else
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : $vntsbin 下载失败,请手动下载上传程序,程序退出" >>/tmp/vnts.log
fi
done
fi
chmod +x "$vntsbin"
ps | grep 'vnts' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'vnts' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
local server_port white_Token subnet servern_netmask logs sfinger web_port webuser webpass web web_wan
config_get server_port "$cfg" 'server_port'
config_get white_Token "$cfg" 'white_Token'
config_get subnet "$cfg" 'subnet'
config_get servern_netmask "$cfg" 'servern_netmask'
config_get web_port "$cfg" 'web_port'
config_get webuser "$cfg" 'webuser'
config_get webpass "$cfg" 'webpass'
config_get_bool web "$cfg" 'web' '0'
config_get_bool web_wan "$web_wan" 'web_wan' '0'
config_get_bool logs "$cfg" 'logs' '0'
config_get_bool sfinger "$cfg" 'sfinger' '0'
procd_open_instance "vnts"
get_tz
[ -z "$SET_TZ" ] || procd_set_param env TZ="$SET_TZ"
procd_set_param command "$vntsbin"
procd_append_param command --port "$server_port"
if [ ! -z "$white_Token" ] ; then
if [[ "$(grep "list white_Token" /etc/config/vnt | awk '{print $3}' | wc -l ) " -eq 1 ]]; then
procd_append_param command --white-token "$white_Token"
else
for white_Tokens in $(cat /etc/config/vnt | grep 'list white_Token' | awk -F 'list white_Token' '{print $2}' | sed "s/'/\n/g" | tr -d " ' "); do
procd_append_param command --white-token "$white_Tokens"
done
fi
fi
[ -z "$subnet" ] || procd_append_param command --gateway "$subnet"
[ -z "$servern_netmask" ] || procd_append_param command --netmask "$servern_netmask"
[ "$sfinger" = "0" ] || procd_append_param command --finger
[ "$logs" = "1" ] || procd_append_param command --log-path /dev/null
if [ ! -f "${log_path}/log4rs.yaml" ] ; then
mkdir -p ${log_path}
cat > "${log_path}/log4rs.yaml"<<EOF
refresh_rate: 30 seconds
appenders:
rolling_file:
kind: rolling_file
path: /tmp/vnts.log
append: true
encoder:
pattern: "{d(%Y-%m-%d %H:%M:%S vnts:)} [{f}:{L}] {h({l})} {M}:{m}{n}"
policy:
kind: compound
trigger:
kind: size
limit: 1 mb
roller:
kind: fixed_window
pattern: /tmp/vnts.{}.log
base: 1
count: 2
root:
level: info
appenders:
- rolling_file
EOF
fi
if [ "$web" = "1" ] && [ "$cpucore" != "mips" ] ; then
[ -z "$web_port" ] || procd_append_param command --web-port "$web_port"
[ -z "$webuser" ] || procd_append_param command --username "$webuser"
[ -z "$webpass" ] || procd_append_param command --password "$webpass"
[ -z "$web_port" ] && web_port=29870
else
[ "$cpucore" = "mips" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : mips架构不支持web界面" >>/tmp/vnt-cli.log
[ "$cpucore" != "mips" ] && procd_append_param command --web-port 0
fi
procd_set_param limits core="unlimited"
procd_set_param limits nofile="1000000 1000000"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 防火墙放行服务器服务端口$server_port" >>/tmp/vnt-cli.log
uci -q delete firewall.vnts
uci set firewall.vnts=rule
uci set firewall.vnts.name="vnts"
uci set firewall.vnts.target="ACCEPT"
uci set firewall.vnts.src="wan"
uci set firewall.vnts.proto="tcp udp icmp igmp"
uci set firewall.vnts.dest_port="$server_port"
uci set firewall.vnts.enabled="1"
if [ "$web" = "1" ] && [ "$web_wan" = "1" ] ; then
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 防火墙放行服务器WEB端口$web_port" >>/tmp/vnt-cli.log
uci -q delete firewall.vntsweb
uci set firewall.vntsweb=rule
uci set firewall.vntsweb.name="vnts_web"
uci set firewall.vntsweb.target="ACCEPT"
uci set firewall.vntsweb.src="wan"
uci set firewall.vntsweb.proto="tcp"
uci set firewall.vntsweb.dest_port="$web_port"
uci set firewall.vntsweb.enabled="1"
fi
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1
[ "$(uci -q get vnt.@vnts[0].logs)" = "0" ] && rm -rf /tmp/vnts*.log
if [ "$logs" = "1" ] ;then
sed -i 's|limit: 10 mb|limit: 1 mb|g' ${log_path}/log4rs.yaml
sed -i 's|count: 5|count: 2|g' ${log_path}/log4rs.yaml
logyaml=$(cat ${log_path}/log4rs.yaml |grep path: | awk -F'path: ' '{print $2}')
logyaml2=$(cat ${log_path}/log4rs.yaml | grep pattern: | awk -F'pattern: ' '{print $2}')
if [ "$logyaml" != "/tmp/vnts.log" ] ; then
sed -i "s|${logyaml}|/tmp/vnts.log|g" ${log_path}/log4rs.yaml
sed -i "s|${logyaml2}|/tmp/vnts.{}.log|g" ${log_path}/log4rs.yaml
fi
[ ! -L /tmp/vnts.0.log ] && ln -sf /tmp/vnts.log /tmp/vnts.0.log
[ ! -L /tmp/vnts.1.log ] && ln -sf /tmp/vnts.log /tmp/vnts.1.log
[ ! -L /tmp/vnts.2.log ] && ln -sf /tmp/vnts.log /tmp/vnts.2.log
fi
mkdir -p /tmp/vnts_key
[ ! -L /tmp/vnts_key/public_key.pem ] && ln -sf ${key_path}/public_key.pem /tmp/vnts_key/public_key.pem
[ ! -L /tmp/vnts_key/private_key.pem ] && ln -sf ${key_path}/private_key.pem /tmp/vnts_key/private_key.pem
echo `date +%s` > /tmp/vnts_time
}
stop_cli() {
local cfg="$1"
pgrep -f vnt_check | xargs kill -9 >/dev/null 2>&1
ps | grep 'vnt-cli' | grep -v grep | awk '{print $1}' | xargs kill >/dev/null 2>&1
ps | grep 'vnt-cli' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
uci -q delete network.VNT
uci -q delete firewall.vntzone
uci -q delete firewall.vntfwlan
uci -q delete firewall.vntfwwan
uci -q delete firewall.lanfwvnt
uci -q delete firewall.wanfwvnt
uci -q delete firewall.vntcli
[ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload >/dev/null 2>&1
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1
rm -rf /tmp/vnt-cli_info /tmp/vnt-cli_all /tmp/vnt-cli_list /tmp/vnt-cli_route
rm -rf /tmp/vnt-cli.log /tmp/vnt-cli*.log
rm -rf /tmp/vntnew.tag /tmp/vnt.tag
echo "$(date '+%Y-%m-%d %H:%M:%S') vnt-cli : 停止运行" >>/tmp/vnt-cli.log
}
stop_vnts() {
local cfg="$1"
ps | grep 'vnts' | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
uci -q delete firewall.vnts
uci -q delete firewall.vntsweb
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload >/dev/null 2>&1
rm -rf /tmp/vnts.log /tmp/vnts*.log
rm -rf /tmp/vntsnew.tag /tmp/vnts.tag
echo "$(date '+%Y-%m-%d %H:%M:%S') vnts : 停止运行" >>/tmp/vnts.log
}
start_service() {
config_load 'vnt'
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="arm"
[ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="aarch64"
[ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="i386"
[ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="x86_64"
if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] ; then
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}')
[ "$mipstype" = "0" ] && cpucore="mips" || cpucore="mipsle"
fi
proxys="https://github.moeyy.xyz/
https://gh.llkk.cc/
https://mirror.ghproxy.com/
https://ghproxy.net/
"
#[ -z "`opkg list-installed | grep curl`" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt : 未安装curl,请确定安装好curl " >>/tmp/vnt-cli.log
#[ -z "`opkg list-installed | grep luci-lib-fs`" ] && echo "$(date '+%Y-%m-%d %H:%M:%S') vnt : 未安装luci-lib-fs,请确定安装好luci-lib-fs " >>/tmp/vnt-cli.log
config_foreach start_vntcli 'vnt-cli'
config_foreach start_vnts 'vnts'
}
stop_service() {
[ "$(uci -q get vnt.@vnts[0].enabled)" = "0" ] && stop_vnts 'vnts'
[ "$(uci -q get vnt.@vnt-cli[0].enabled)" = "0" ] && stop_cli 'vnt-cli'
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger "vnt"
procd_add_interface_trigger "interface.*.up" wan /etc/init.d/vnt reload
}
@@ -0,0 +1,19 @@
#!/bin/sh
[ ! -f "/usr/share/ucitrack/luci-app-vnt.json" ] && {
cat > /usr/share/ucitrack/luci-app-vnt.json << EEOF
{
"config": "vnt",
"init": "vnt"
}
EEOF
}
uci -q batch <<-EOF >/dev/null
delete ucitrack.@vnt[-1]
add ucitrack vnt
set ucitrack.@vnt[-1].init=vnt
commit ucitrack
EOF
chmod +x /etc/init.d/vnt
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
exit 0
@@ -0,0 +1,11 @@
{
"luci-app-vnt": {
"description": "Grant UCI access for luci-app-vnt",
"read": {
"uci": [ "vnt" ]
},
"write": {
"uci": [ "vnt" ]
}
}
}