Rename package and rebuild opkg-feed

- Added luci-app-GO-wireguard

(Luci app for Wireguard pulled from GoldenOrb)
This commit is contained in:
Cameron Thompson
2025-01-30 20:50:26 -05:00
parent e820fe3623
commit 59be0e546f
30 changed files with 22 additions and 6 deletions

View File

@@ -0,0 +1,111 @@
-- Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
-- Licensed to the public under the Apache License 2.0.
module("luci.controller.wireguard", package.seeall)
I18N = require "luci.i18n"
translate = I18N.translate
function index()
local multilock = luci.model.uci.cursor():get("custom", "multiuser", "multi") or "0"
local rootlock = luci.model.uci.cursor():get("custom", "multiuser", "root") or "0"
if (multilock == "0") or (multilock == "1" and rootlock == "1") then
entry({"admin", "vpn", "wireguard"}, cbi("wireguard"), _("Wireguard"), 63)
entry( {"admin", "vpn", "wireguard", "client"}, cbi("wireguard-client"), nil ).leaf = true
entry( {"admin", "vpn", "wireguard", "server"}, cbi("wireguard-server"), nil ).leaf = true
end
entry( {"admin", "vpn", "wireguard", "wupload"}, call("conf_upload"))
entry( {"admin", "vpn", "generateconf"}, call("conf_gen"))
entry( {"admin", "vpn", "textconf"}, call("text_gen"))
entry( {"admin", "vpn", "wirestatus"}, call("wirestatus"))
end
function conf_upload()
local fs = require("nixio.fs")
local http = require("luci.http")
local util = require("luci.util")
local uci = require("luci.model.uci").cursor()
local upload = http.formvalue("ovpn_file")
local name = http.formvalue("instance_name2")
local file = "/etc/openvpn/" ..name.. ".conf"
if name and upload then
local fp
http.setfilehandler(
function(meta, chunk, eof)
local data = util.trim(chunk:gsub("\r\n", "\n")) .. "\n"
data = util.trim(data:gsub("[\128-\255]", ""))
if not fp and meta and meta.name == "ovpn_file" then
fp = io.open(file, "w")
end
if fp and data then
fp:write(data)
end
if fp and eof then
fp:close()
end
end
)
if fs.access(file) then
os.execute("/usr/lib/wireguard/conf.sh " .. name .. " " .. file)
end
end
http.redirect(luci.dispatcher.build_url('admin/vpn/wireguard'))
end
function conf_gen()
os.execute("/usr/lib/wireguard/create.sh")
end
function text_gen()
local set = luci.http.formvalue("set")
os.execute("/usr/lib/wireguard/text.sh " .. "\"" .. set .. "\"")
end
function wirestatus()
local data = { }
local last_device = ""
local wg_dump = io.popen("wg show all dump")
if wg_dump then
local line
for line in wg_dump:lines() do
local line = string.split(line, "\t")
if not (last_device == line[1]) then
last_device = line[1]
data[line[1]] = {
name = line[1],
public_key = line[3],
listen_port = line[4],
fwmark = line[5],
peers = { }
}
else
local peer = {
public_key = line[2],
endpoint = line[4],
allowed_ips = { },
latest_handshake = line[6],
transfer_rx = line[7],
transfer_tx = line[8],
persistent_keepalive = line[9]
}
if not (line[4] == '(none)') then
for ipkey, ipvalue in pairs(string.split(line[5], ",")) do
if #ipvalue > 0 then
table.insert(peer['allowed_ips'], ipvalue)
end
end
end
table.insert(data[line[1]].peers, peer)
end
end
end
luci.http.prepare_content("application/json")
luci.http.write_json(data)
end

View File

@@ -0,0 +1,104 @@
require("luci.ip")
require("luci.model.uci")
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
local m = Map("wireguard", translate("Wireguard Client"), translate("Set up a Wireguard Client"))
e = m:section(NamedSection, "settings", "")
m.on_init = function(self)
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
end
btn = e:option(Button, "_btn", translate(" "))
btn.inputtitle = translate("Back to Main Page")
btn.inputstyle = "apply"
btn.redirect = luci.dispatcher.build_url(
"admin", "vpn", "wireguard"
)
function btn.write(self, section, value)
luci.http.redirect( self.redirect )
end
local s = m:section( NamedSection, arg[1], "wireguard", translate("Client") )
ip = s:option(Value, "addresses", translate("IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept from this client"));
ip.rmempty = true;
ip.optional=false;
ip.default="10.14.0.2/24";
port = s:option(Value, "port", translate("Listen Port :"), translate("Client Listen Port"));
port.rmempty = true;
port.optional=false;
port.default="51820";
ul = s:option(ListValue, "udptunnel", translate("Enable UDP over TCP :"));
ul:value("0", translate("No"))
ul:value("1", translate("Yes"))
ul.default=0
dns = s:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers."));
dns.rmempty = true;
dns.optional=false;
mtu = s:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU"));
mtu.rmempty = true;
mtu.optional=false;
mtu.datatype = 'range(1280,1420)';
mtu.default="1280";
pka = s:option(Value, "persistent_keepalive", translate("Persistent Keep Alive :"), translate("Seconds between keep alive messages"));
pka.rmempty = true;
pka.optional=false;
pka.datatype = 'range(1,100)';
pka.default="25";
pkey = s:option(Value, "privatekey", translate("Private Key :"), translate("Private Key supplied by the Server"));
pkey.rmempty = true;
pkey.optional=false;
il = s:option(ListValue, "wginter", translate("Interface to Use :"));
il:value("0", translate("WG0"))
il:value("1", translate("WG1"))
il.default="0"
bl = s:option(ListValue, "auto", translate("Start on Boot :"));
bl:value("0", translate("No"))
bl:value("1", translate("Yes"))
bl.default="0"
xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :"));
xbl:value("0", translate("No"))
xbl:value("1", translate("Yes"))
xbl.default="1"
s = m:section( NamedSection, arg[1], "wireguard", translate("Server") )
name = s:option( Value, "name", translate("Server Name :"), translate("Optional Server name"))
pukey = s:option(Value, "publickey", translate("Public Key :"), translate("Public Key of the Server"));
pukey.rmempty = true;
pukey.optional=false;
prkey = s:option(Value, "presharedkey", translate("Presharedkey :"), translate("PreShared Key from the Server"));
prkey.rmempty = true;
prkey.optional=false;
host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server"));
host.rmempty = true;
host.optional=false;
host.default="";
sport = s:option(Value, "sport", translate("Listen Port :"), translate("Server Listen Port"));
sport.rmempty = true;
sport.optional=false;
sport.default="51820";
sip = s:option(Value, "ips", translate("Allowed IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept"));
sip.rmempty = true;
sip.optional=false;
sip.default="10.14.0.0/24";
return m

View File

@@ -0,0 +1,130 @@
require("luci.ip")
require("luci.model.uci")
--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
local m = Map("wireguard", translate("Wireguard Server"), translate("Set up a Wireguard Server"))
e = m:section(NamedSection, "settings", "")
m.on_init = function(self)
luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1])
end
m.on_after_save = function(self)
luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1] .. "&")
end
btn = e:option(Button, "_btn", translate(" "))
btn.inputtitle = translate("Back to Main Page")
btn.inputstyle = "apply"
btn.redirect = luci.dispatcher.build_url(
"admin", "vpn", "wireguard"
)
function btn.write(self, section, value)
luci.http.redirect( self.redirect )
end
local s = m:section( NamedSection, arg[1], "wireguard", translate("Server") )
ip = s:option(Value, "addresses", translate("Internal IP Address :"));
ip.rmempty = true;
ip.optional=false;
ip.default="10.14.0.1/32";
ip.datatype = "ipaddr"
host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server"));
host.rmempty = true;
host.optional=false;
host.default="example.wireguard.org";
port = s:option(Value, "port", translate("Port :"), translate("Server Listen Port. Default is 51280"));
port.rmempty = true;
port.optional=false;
port.default="51280";
ul = s:option(ListValue, "udptunnel", "Enable UDP over TCP :");
ul:value("0", translate("No"))
ul:value("1", translate("Yes"))
ul.default=0
uport = s:option(Value, "udpport", translate("UDP over TCP Port :"), translate("Server Local TCP Port. Default is 54321"));
uport.rmempty = true;
uport.optional=false;
uport.default="54321";
uport:depends("udptunnel", "1")
pkey = s:option(DummyValue, "privatekey", translate("Private Key :"));
pkey.optional=false;
pukey = s:option(DummyValue, "publickey", translate("Public Key :"), translate("Server Public key sent to Clients"));
pukey.optional=false;
pl = s:option(ListValue, "usepre", "Use PreSharedKey :");
pl:value("0", translate("No"))
pl:value("1", translate("Yes"))
pl.default=0
prkey = s:option(DummyValue, "presharedkey", translate("PreShared Key :"), translate("PreShared Key sent to Client"));
prkey.optional=false;
prkey:depends("usepre", "1")
bl = s:option(ListValue, "auto", translate("Start on Boot :"));
bl:value("0", translate("No"))
bl:value("1", translate("Yes"))
bl.default="0"
xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :"));
xbl:value("0", translate("No"))
xbl:value("1", translate("Yes"))
xbl.default="1"
b3 = s:option(DummyValue, "blank", " ");
sx = s:option(Value, "_dmy1", translate(" "))
sx.template = "wireguard/conf"
ss = m:section(TypedSection, "custom" .. arg[1], translate("Clients"), translate("Clients of this server"))
ss.anonymous = true
ss.addremove = true
name = ss:option(Value, "name", translate("Client Name"))
name.optional=false;
cport = ss:option(Value, "endpoint_port", translate("Listen Port :"), translate("Port sent to Client. Default is 51280"));
cport.rmempty = true;
cport.optional=false;
cport.default="";
aip = ss:option(Value, "address", translate("Assigned IP Address :"), translate("IP Address assigned to Client"));
aip.rmempty = true;
aip.optional=false;
aip.default="10.14.0.2/32";
dns = ss:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers sent to Client"));
dns.rmempty = true;
dns.optional=false;
dns.default="";
mtu = ss:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU"));
mtu.rmempty = true;
mtu.optional=false;
mtu.datatype = 'range(1280,1420)';
mtu.default="1280";
aip = ss:option(Value, "allowed_ips", translate("Allowed IP Address :"), translate("Comma separated list of IP Addresses allowed from Client"));
aip.rmempty = true;
aip.optional=false;
aip.default="0.0.0.0/0,::/0";
pukey = ss:option(DummyValue, "publickey", translate("Public Key :"), translate("Client Public Key"));
pukey.optional=false;
pikey = ss:option(DummyValue, "privatekey", translate("Private Key :"), translate("Private Key sent to Client"));
pikey.optional=false;
b3 = ss:option(DummyValue, "blank", " ");
return m

View File

@@ -0,0 +1,182 @@
local fs = require "nixio.fs"
local sys = require "luci.sys"
local uci = require "luci.model.uci".cursor()
local testfullps = sys.exec("ps --help 2>&1 | grep BusyBox") --check which ps do we have
local psstring = (string.len(testfullps)>0) and "ps w" or "ps axfw" --set command we use to get pid
local m = Map("wireguard", translate("Wireguard"), translate("Set up a Wireguard VPN Tunnel on your Router"))
local s = m:section( TypedSection, "wireguard", translate("Instances"), translate("Below is a list of configured Wireguard Instances and their current state") )
s.template = "cbi/tblsection"
s.template_addremove = "wireguard/cbi-select-input-add"
s.addremove = true
s.add_select_options = { }
local cfg = s:option(DummyValue, "config")
function cfg.cfgvalue(self, section)
local file_cfg = self.map:get(section, "client")
if file_cfg == "1" then
s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "client", "%s")
else
s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "server", "%s")
end
end
uci:load("wireguard_recipes")
uci:foreach( "wireguard_recipes", "wireguard_recipe",
function(section)
s.add_select_options[section['.name']] =
section['_description'] or section['.name']
end
)
function s.parse(self, section)
local recipe = luci.http.formvalue(
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
self.sectiontype .. ".select"
)
if recipe and not s.add_select_options[recipe] then
self.invalid_cts = true
else
TypedSection.parse( self, section )
end
end
function s.create(self, name)
local recipe = luci.http.formvalue(
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
self.sectiontype .. ".select"
)
local name = luci.http.formvalue(
luci.cbi.CREATE_PREFIX .. self.config .. "." ..
self.sectiontype .. ".text"
)
if #name > 3 and not name:match("[^a-zA-Z0-9_]") then
local s = uci:section("wireguard", "wireguard", name)
if s then
local options = uci:get_all("wireguard_recipes", recipe)
for k, v in pairs(options) do
if k ~= "_role" and k ~= "_description" then
if type(v) == "boolean" then
v = v and "1" or "0"
end
uci:set("wireguard", name, k, v)
end
end
uci:save("wireguard")
uci:commit("wireguard")
if extedit then
luci.http.redirect( self.extedit:format(name) )
end
end
elseif #name > 0 then
self.invalid_cts = true
end
return 0
end
function s.remove(self, name)
local cfg_file = "/etc/openvpn/" ..name.. ".conf"
local auth_file = "/etc/openvpn/" ..name.. ".auth"
if fs.access(cfg_file) then
fs.unlink(cfg_file)
end
if fs.access(auth_file) then
fs.unlink(auth_file)
end
uci:delete("wireguard", name)
uci:save("wireguard")
uci:commit("wireguard")
end
local port = s:option( DummyValue, "client", translate("Type") )
function port.cfgvalue(self, section)
local val = AbstractValue.cfgvalue(self, section)
if val == nil then
val = 0
end
if val == "1" then
return "Client"
else
return "Server"
end
end
local addr = s:option( DummyValue, "addresses", translate("IP Addresses") )
function addr.cfgvalue(self, section)
local val = AbstractValue.cfgvalue(self, section)
return val or "----"
end
local auto = s:option( DummyValue, "udptunnel", translate("UDP over TCP") )
function auto.cfgvalue(self, section)
local val = AbstractValue.cfgvalue(self, section)
if val == nil then
val = 0
end
if val == "1" then
return "Yes"
else
return "No"
end
end
local auto = s:option( DummyValue, "auto", translate("Start on Boot") )
function auto.cfgvalue(self, section)
local val = AbstractValue.cfgvalue(self, section)
if val == nil then
val = 0
end
if val == "1" then
return "Yes"
else
return "No"
end
end
local active = s:option( DummyValue, "active", translate("Started") )
function active.cfgvalue(self, section)
local val = AbstractValue.cfgvalue(self, section)
if val == nil then
val = 0
end
if val == "1" then
return "Yes"
else
return "No"
end
end
local updown = s:option( Button, "_updown", translate("Start/Stop") )
updown._state = false
updown.redirect = luci.dispatcher.build_url(
"admin", "vpn", "wireguard"
)
function updown.cbid(self, section)
local file_cfg = self.map:get(section, "active")
if file_cfg == "1" then
pid = 1
else
pid = nil
end
self._state = pid ~= nil
self.option = self._state and "stop" or "start"
return AbstractValue.cbid(self, section)
end
function updown.cfgvalue(self, section)
self.title = self._state and "stop" or "start"
self.inputstyle = self._state and "reset" or "reload"
end
function updown.write(self, section, value)
if self.option == "stop" then
sys.call("/usr/lib/wireguard/stopvpn.sh %s" % section)
else
sys.call("/usr/lib/wireguard/startvpn.sh %s" % section)
end
luci.http.redirect( self.redirect )
end
m:section(SimpleSection).template = "wireguard/wireguard"
return m

View File

@@ -0,0 +1,111 @@
<script type="text/javascript">
//<![CDATA[
function vpn_add()
{
var vpn_name = div_add.querySelector("#instance_name1").value.replace(/[^\x00-\x7F]|[\s\.!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
var vpn_template = div_add.querySelector("#instance_template").value;
var form = document.getElementsByName('cbi')[0];
if (!vpn_name || !vpn_name.length)
{
return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
}
document.getElementById("instance_name1").value = vpn_name;
if (document.getElementById("cbi-wireguard-" + vpn_name) != null)
{
return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
}
if (!vpn_template || !vpn_template.length)
{
return info_message(vpn_output, "<%=pcdata(translate("Please select a valid VPN template!"))%>", 2000);
}
if (form)
{
form.submit();
}
}
function vpn_upload()
{
var vpn_name = div_upload.querySelector("#instance_name2").value.replace(/[^\x00-\x7F]|[\s\.!@#$%^&*()\-+=\[\]{};':"\\|,<>\/?]/g,'');
var vpn_file = document.getElementById("ovpn_file").value;
var form = document.getElementsByName('cbi')[0];
if (!vpn_name || !vpn_name.length)
{
return info_message(vpn_output, "<%=pcdata(translate("The 'Name' field must not be empty!"))%>", 2000);
}
document.getElementById("instance_name2").value = vpn_name;
if (document.getElementById("cbi-wireguard-" + vpn_name) != null)
{
return info_message(vpn_output, "<%=pcdata(translate("Instance with that name already exists!"))%>", 2000);
}
if (!vpn_file || !vpn_file.length)
{
return info_message(vpn_output, "<%=pcdata(translate("Please select a valid CONF config file to upload!"))%>", 2000);
}
if (form)
{
form.enctype = 'multipart/form-data';
form.action = '<%=url('admin/vpn/wireguard/wupload')%>';
form.submit();
}
}
function info_message(output, msg, timeout)
{
timeout = timeout || 0;
output.innerHTML = '<em>' + msg + '</em>';
if (timeout > 0)
{
setTimeout(function(){ output.innerHTML=""}, timeout);
}
}
//]]>
</script>
<%+wireguard/ovpn_css%>
<div class="cbi-section-node">
<div class="table cbi-section-table">
<h4><%:Template based configuration%></h4>
<div class="tr cbi-section-table-row" id="div_add">
<div class="td left">
<input type="text" maxlength="20" placeholder="Instance name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.text" id="instance_name1" />
</div>
<div class="td left">
<select id="instance_template" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.select">
<option value="" selected="selected" disabled="disabled"><%:Select template ...%></option>
<%- for k, v in luci.util.kspairs(self.add_select_options) do %>
<option value="<%=k%>"><%=luci.xml.pcdata(v)%></option>
<% end -%>
</select>
</div>
<div class="td left">
<input class="cbi-button cbi-button-add" type="submit" onclick="vpn_add(); return false;" value="<%:Add%>" title="<%:Add template based configuration%>" /><br />
</div>
</div>
<h4><%:Conf configuration file upload%></h4>
<div class="tr cbi-section-table-row" id="div_upload">
<div class="td left">
<input type="text" maxlength="20" placeholder="Instance name" name="instance_name2" id="instance_name2" />
</div>
<div class="td left">
<input type="file" name="ovpn_file" id="ovpn_file" accept="application/x-wireguard-profile,.conf" />
</div>
<div class="td left">
<input class="cbi-button cbi-button-add" type="submit" onclick="vpn_upload(); return false;" value="<%:Upload%>" title="<%:Upload conf file%>" />
</div>
</div>
</div>
<div class="vpn-output">
<span id="vpn_output"></span>
</div>
</div>

View File

@@ -0,0 +1,27 @@
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
function generateconf()
{
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "generateconf")%>',
null,
function(x, rv)
{
window.open('http://'+window.location.hostname+'/package/wgconf.tar.gz', '_self')
}
);
}
//]]></script>
<fieldset class="cbi-section" id="cbi-family">
<table width="550" border="0">
<tr>
<td width="20%">&nbsp;</td>
<td width="17%"><input type="button" type="submit" id="generate" class="cbi-button cbi-button-apply" value="<%:Generate Conf Files%>" onclick="return generateconf()" /></td>
<td width="17%">&nbsp;</td>
<td width="46%">&nbsp;</td>
</tr>
</table>
</fieldset>

View File

@@ -0,0 +1,38 @@
<style type="text/css">
h4
{
white-space: nowrap;
border-bottom: 0px;
margin: 10px 5px 5px 5px;
}
.tr
{
border: 0px;
text-align: left;
}
.vpn-output
{
box-shadow: none;
margin: 10px 5px 5px 5px;
color: #a22;
}
textarea
{
border: 1px solid #cccccc;
padding: 5px;
font-size: 12px;
font-family: monospace;
resize: none;
white-space: pre;
overflow-wrap: normal;
overflow-x: scroll;
}
a
{
line-height: 1.5;
}
hr
{
margin: 0.5em 0;
}
</style>

View File

@@ -0,0 +1,30 @@
<%#
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
Licensed to the public under the Apache License 2.0.
-%>
<%+openvpn/ovpn_css%>
<div class="cbi-section">
<h3>
<a href="<%=url('admin/vpn/wireguard')%>"><%:Overview%></a> &#187;
<%=luci.i18n.translatef("Instance \"%s\"", self.instance)%>
</h3>
<% if self.mode == "basic" then %>
<a href="<%=url('admin/vpn/wireguard/advanced', self.instance, "Service")%>"><%:Switch to advanced configuration%> &#187;</a><p/>
<hr />
<% elseif self.mode == "advanced" then %>
<a href="<%=url('admin/vpn/wireguard/basic', self.instance)%>"><%:Switch to basic configuration%> &#187;</a><p/>
<hr />
<%:Configuration category%>:
<% for i, c in ipairs(self.categories) do %>
<% if c == self.category then %>
<strong><%=translate(c)%></strong>
<% else %>
<a href="<%=luci.dispatcher.build_url("admin", "vpn", "wireguard", "advanced", self.instance, c)%>"><%=translate(c)%></a>
<% end %>
<% if next(self.categories, i) then %>|<% end %>
<% end %>
<% end %>
</div>

View File

@@ -0,0 +1,61 @@
<%
%>
<script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<script type="text/javascript">//<![CDATA[
function uploadc(btn)
{
var conf = document.getElementById("conf").value;
if ( conf == "" )
{
alert("<%:You must enter a Conf file!!%>");
return false;
}
var iname = document.getElementById("iname").value;
if ( iname == "" )
{
alert("<%:You must enter an Instance name!!%>");
return false;
}
var boot = document.getElementById('boot').checked;
bootn = "0";
if ( boot == true )
{
bootn= "1";
}
confile = bootn + "?" + iname + "?" + conf +"\n?";
XHR.get('<%=luci.dispatcher.build_url("admin", "vpn", "textconf")%>',
{ set: confile },
function(x, rv)
{
window.location.reload(false);
}
);
}
//]]></script>
<fieldset class="cbi-section" id="cbi-family">
<legend><%:Paste Configuration File Here%></legend>
<table id="ctxt" width="700" border="0" style="display:table;">
<tr>
<td width="50%">
<textarea name="conf" id="conf" rows="10" style="width: 600px;" maxlength="1000"></textarea>
</td>
</tr>
</table>
<table id="btxt" width="700" border="0" style="display:table;">
<tr>
<td width="10%"><input type="button" id="apply1" class="cbi-button cbi-button-apply" value="<%:Upload Conf File%>" onclick="return uploadc(this)" /></td>
<td width="10%"><div align="right"><strong><%:Instance Name : %></strong></div></td>
<td width="12%"><input type="text" name="iname" id="iname" class="cbi-input-text" style="width: 150px;" maxlength="100" value="SardisTel"></input></td>
<td width="10%"><div align="right"><strong><%:Start on Boot : %></strong></div></td>
<td width="8%">
<input type="checkbox" id="boot" checked />
</td>
<td width="50%">&nbsp;</td>
</tr>
</table>
</fieldset>

View File

@@ -0,0 +1,228 @@
<%#
Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
Licensed to the public under the Apache License 2.0.
-%>
<%
-%>
<script type="text/javascript">//<![CDATA[
function bytes_to_str(bytes) {
bytes = parseFloat(bytes);
if (bytes < 1) { return "0 B"; }
var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};
function timestamp_to_str(timestamp) {
if (timestamp < 1) {
return '<%:Never%>';
}
var now = new Date();
var seconds = (now.getTime() / 1000) - timestamp;
var ago = "";
if (seconds < 60) {
ago = parseInt(seconds) + '<%:s ago%>';
} else if (seconds < 3600) {
ago = parseInt(seconds / 60) + '<%:m ago%>';
} else if (seconds < 86401) {
ago = parseInt(seconds / 3600) + '<%:h ago%>';
} else {
ago = '<%:over a day ago%>';
}
var t = new Date(timestamp * 1000);
return t.toUTCString() + ' (' + ago + ')';
}
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "vpn", "wirestatus")%>', null,
function(x, data) {
both = {};
bothbp={};
iii = 1;
for (var key in data) {
if (!data.hasOwnProperty(key)) { continue; }
var ifname = key;
var iface = data[key];
var s = "";
if (iface.public_key == '(none)') {
s += '<em><%:Interface does not have a public key!%></em>';
} else {
s += String.format(
'<strong><%:Public Key%>: </strong>%s',
iface.public_key
);
}
if (iface.listen_port > 0) {
s += String.format(
'<br /><strong><%:Listen Port%>: </strong>%s',
iface.listen_port
);
}
if (iface.fwmark != 'off') {
s += String.format(
'<br /><strong><%:Firewall Mark%>: </strong>%s',
iface.fwmark
);
}
if ( iii == 1 )
{
document.getElementById("iinfo").innerHTML = s;
document.getElementById("leg").innerHTML = ifname;
}
else
{
document.getElementById("iinfo1").innerHTML = s;
document.getElementById("leg1").innerHTML = ifname;
}
for (var i = 0, ilen = iface.peers.length; i < ilen; i++) {
var peer = iface.peers[i];
var s = String.format(
'<strong><%:Public Key%>: </strong>%s',
peer.public_key
);
if (peer.endpoint != '(none)') {
s += String.format(
'<br /><strong><%:Endpoint%>: </strong>%s',
peer.endpoint
);
}
if (peer.allowed_ips.length > 0) {
s += '<br /><strong><%:Allowed IPs%>:</strong>';
for (var k = 0, klen = peer.allowed_ips.length; k < klen; k++) {
s += '<br />&nbsp;&nbsp;&bull;&nbsp;' + peer.allowed_ips[k];
}
}
if (peer.persistent_keepalive != 'off') {
s += String.format(
'<br /><strong><%:Persistent Keepalive%>: </strong>%ss',
peer.persistent_keepalive
);
}
var icon = '<img src="<%=resource%>/icons/wireguard_disabled.png" />';
var now = new Date();
if (((now.getTime() / 1000) - peer.latest_handshake) < 140) {
icon = '<img src="<%=resource%>/icons/wireguard.png" />';
}
s += String.format(
'<br /><strong><%:Latest Handshake%>: </strong>%s',
timestamp_to_str(peer.latest_handshake)
);
s += String.format(
'<br /><strong><%:Data Received%>: </strong>%s' +
'<br /><strong><%:Data Transmitted%>: </strong>%s',
bytes_to_str(peer.transfer_rx),
bytes_to_str(peer.transfer_tx)
);
if ( iii == 1 )
{
document.getElementById("config").innerHTML = icon;
document.getElementById("info").innerHTML = s;
}
else
{
document.getElementById("config1").innerHTML = icon;
document.getElementById("info1").innerHTML = s;
}
}
iii = iii + 1;
}
});
//]]></script>
<h2><%:WireGuard Status%></h2>
<fieldset class="cbi-section">
<div>
<table width="900" border="0">
<tr>
<td width="50px" style="vertical-align:center;font-size : 25px">
<div><%:Interface %></div>
</td>
<td width="100px" id="leg" style="width:100px; text-align:left; padding:3px;font-size : 25px">&nbsp;</td>
<td width="650px">&nbsp;</td>
</tr>
</table>
<table width="900" border="0">
<tr>
<td width="20px">&nbsp;</td>
<td width="150px" style="vertical-align:center;font-size : 20px">
<div><%:Configuration%></div>
</td>
<td width="100px" id="config" style="width:16px; text-align:center; padding:3px">&nbsp;</td>
<td width="50px">&nbsp;</td>
<td width="580px">
<div id="info" style="vertical-align:middle; padding: 3px">
<em><%:Collecting data...%></em>
</div>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td style="vertical-align:center;font-size : 20px">
<div><%:Peer%></div>
</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>
<div id="iinfo" style="vertical-align:middle; padding: 3px">
<em><%:Collecting data...%></em>
</div>
</td>
</tr>
</table>
<table width="900" border="0" id="second1">
<tr>
<td width="50px" style="vertical-align:center;font-size : 25px">
<div><%:Interface %></div>
</td>
<td width="100px" id="leg1" style="width:100px; text-align:left; padding:3px;font-size : 25px">&nbsp;</td>
<td width="650px">&nbsp;</td>
</tr>
</table>
<table width="900" border="0" id="second">
<tr>
<td width="20px">&nbsp;</td>
<td width="150px" style="vertical-align:center;font-size : 20px">
<div><%:Configuration%></div>
</td>
<td width="100px" id="config1" style="width:16px; text-align:center; padding:3px">&nbsp;</td>
<td width="50px">&nbsp;</td>
<td width="580px">
<div id="info1" style="vertical-align:middle; padding: 3px">
<em><%:Collecting data...%></em>
</div>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td style="vertical-align:center;font-size : 20px">
<div><%:Peer%></div>
</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>
<div id="iinfo1" style="vertical-align:middle; padding: 3px">
<em><%:Collecting data...%></em>
</div>
</td>
</tr>
</table>
<!--
<table id="cmdtxt" width="700" border="0" style="display:table;">
<tr>
<td width="100%">
<textarea readonly="readonly" name="attxt" id="attxt" rows="6" style="width: 600px;" maxlength="160"></textarea>
</td>
</tr>
</table> -->
</div>
</fieldset>