Initial commit
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"admin/status/amneziawg": {
|
||||
"title": "AmneziaWG",
|
||||
"order": 92,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "amneziawg/status"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [ "luci-proto-amneziawg" ],
|
||||
"uci": { "network": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"luci-proto-amneziawg": {
|
||||
"description": "Grant access to LuCI AmneziaWG procedures",
|
||||
"read": {
|
||||
"file": {
|
||||
"/usr/bin/qrencode --inline --8bit --type=SVG --output=- -- *": [ "exec" ]
|
||||
},
|
||||
"ubus": {
|
||||
"luci.amneziawg": [
|
||||
"getWgInstances"
|
||||
]
|
||||
},
|
||||
"uci": [ "ddns", "system" ]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
"luci.amneziawg": [
|
||||
"generateKeyPair",
|
||||
"getPublicAndPrivateKeyFromPrivate",
|
||||
"generatePsk"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
luci-app-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg
Normal file
107
luci-app-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright 2022 Jo-Philipp Wich <jo@mein.io>
|
||||
// Licensed to the public under the Apache License 2.0.
|
||||
|
||||
'use strict';
|
||||
|
||||
import { cursor } from 'uci';
|
||||
import { popen } from 'fs';
|
||||
|
||||
|
||||
function shellquote(s) {
|
||||
return `'${replace(s ?? '', "'", "'\\''")}'`;
|
||||
}
|
||||
|
||||
function command(cmd) {
|
||||
return trim(popen(cmd)?.read?.('all'));
|
||||
}
|
||||
|
||||
|
||||
const methods = {
|
||||
generatePsk: {
|
||||
call: function() {
|
||||
return { psk: command('amneziawg genpsk 2>/dev/null') };
|
||||
}
|
||||
},
|
||||
|
||||
generateKeyPair: {
|
||||
call: function() {
|
||||
const priv = command('amneziawg genkey 2>/dev/null');
|
||||
const pub = command(`echo ${shellquote(priv)} | wg pubkey 2>/dev/null`);
|
||||
|
||||
return { keys: { priv, pub } };
|
||||
}
|
||||
},
|
||||
|
||||
getPublicAndPrivateKeyFromPrivate: {
|
||||
args: { privkey: "privkey" },
|
||||
call: function(req) {
|
||||
const priv = req.args?.privkey;
|
||||
const pub = command(`echo ${shellquote(priv)} | wg pubkey 2>/dev/null`);
|
||||
|
||||
return { keys: { priv, pub } };
|
||||
}
|
||||
},
|
||||
|
||||
getWgInstances: {
|
||||
call: function() {
|
||||
const data = {};
|
||||
let last_device;
|
||||
let qr_pubkey = {};
|
||||
|
||||
const uci = cursor();
|
||||
const wg_dump = popen("amneziawg show all dump 2>/dev/null");
|
||||
|
||||
if (wg_dump) {
|
||||
uci.load("network");
|
||||
|
||||
for (let line = wg_dump.read('line'); length(line); line = wg_dump.read('line')) {
|
||||
const record = split(rtrim(line, '\n'), '\t');
|
||||
|
||||
if (last_device != record[0]) {
|
||||
last_device = record[0];
|
||||
data[last_device] = {
|
||||
name: last_device,
|
||||
public_key: record[2],
|
||||
listen_port: record[3],
|
||||
fwmark: record[4],
|
||||
peers: []
|
||||
};
|
||||
|
||||
if (!length(record[2]) || record[2] == '(none)')
|
||||
qr_pubkey[last_device] = '';
|
||||
else
|
||||
qr_pubkey[last_device] = `PublicKey = ${record[2]}`;
|
||||
}
|
||||
else {
|
||||
let peer_name;
|
||||
|
||||
uci.foreach('network', `amneziawg_${last_device}`, (s) => {
|
||||
if (s.public_key == record[1])
|
||||
peer_name = s.description;
|
||||
});
|
||||
|
||||
const peer = {
|
||||
name: peer_name,
|
||||
public_key: record[1],
|
||||
endpoint: record[3],
|
||||
allowed_ips: [],
|
||||
latest_handshake: record[5],
|
||||
transfer_rx: record[6],
|
||||
transfer_tx: record[7],
|
||||
persistent_keepalive: record[8]
|
||||
};
|
||||
|
||||
if (record[3] != '(none)' && length(record[4]))
|
||||
push(peer.allowed_ips, ...split(record[4], ','));
|
||||
|
||||
push(data[last_device].peers, peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { 'luci.amneziawg': methods };
|
||||
Reference in New Issue
Block a user