feat(servers): полная поддержка генератора конфигураций AmneziaWG, QR-кода, скачивания .conf и расширенных настроек сервера

This commit is contained in:
Dushnilin
2026-08-16 19:37:14 +03:00
parent 1062982070
commit 9b5707982c
7 changed files with 450 additions and 54 deletions
+9 -9
View File
@@ -1178,8 +1178,8 @@
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660",
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10239",
"src/partials/modal/renderModal.ts:263",
"src/tachyon/tabs/diagnostic/initController.ts:1545",
"src/tachyon/tabs/dashboard/initController.ts:1256",
"src/tachyon/tabs/diagnostic/initController.ts:1545",
"src/tachyon/tabs/monitoring/initController.ts:884",
"src/tachyon/tabs/monitoring/initController.ts:934",
"src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212",
@@ -1307,8 +1307,8 @@
"key": "Conflict",
"places": [
"src/tachyon/methods/custom/getDashboardSections.ts:1639",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141",
"src/tachyon/tabs/dashboard/partials/renderSections.ts:618"
"src/tachyon/tabs/dashboard/partials/renderSections.ts:618",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141"
]
},
{
@@ -4819,9 +4819,9 @@
"key": "Not configured",
"places": [
"src/tachyon/methods/custom/getDashboardSections.ts:1642",
"src/tachyon/tabs/dashboard/partials/renderSections.ts:621",
"src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152",
"src/tachyon/tabs/dashboard/partials/renderSections.ts:621"
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152"
]
},
{
@@ -6168,8 +6168,8 @@
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1953",
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1954",
"src/tachyon/methods/custom/getDashboardSections.ts:1637",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135",
"src/tachyon/tabs/dashboard/partials/renderSections.ts:616"
"src/tachyon/tabs/dashboard/partials/renderSections.ts:616",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135"
]
},
{
@@ -7083,8 +7083,8 @@
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307",
"../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1959",
"src/tachyon/methods/custom/getDashboardSections.ts:1641",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147",
"src/tachyon/tabs/dashboard/partials/renderSections.ts:620"
"src/tachyon/tabs/dashboard/partials/renderSections.ts:620",
"src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147"
]
},
{
+7 -7
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-16 14:48+0300\n"
"PO-Revision-Date: 2026-08-16 14:48+0300\n"
"POT-Creation-Date: 2026-08-16 16:34+0300\n"
"PO-Revision-Date: 2026-08-16 16:34+0300\n"
"Last-Translator: Dushnilin <dushnilin@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -720,8 +720,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10239
#: src/partials/modal/renderModal.ts:263
#: src/tachyon/tabs/diagnostic/initController.ts:1545
#: src/tachyon/tabs/dashboard/initController.ts:1256
#: src/tachyon/tabs/diagnostic/initController.ts:1545
#: src/tachyon/tabs/monitoring/initController.ts:884
#: src/tachyon/tabs/monitoring/initController.ts:934
#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212
@@ -798,8 +798,8 @@ msgid "Configure User-Agent in the item settings"
msgstr ""
#: src/tachyon/methods/custom/getDashboardSections.ts:1639
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:618
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141
msgid "Conflict"
msgstr ""
@@ -2858,9 +2858,9 @@ msgid "None"
msgstr ""
#: src/tachyon/methods/custom/getDashboardSections.ts:1642
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:621
#: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:621
msgid "Not configured"
msgstr ""
@@ -3652,8 +3652,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1953
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1954
#: src/tachyon/methods/custom/getDashboardSections.ts:1637
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:616
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135
msgid "Running"
msgstr ""
@@ -4189,8 +4189,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1959
#: src/tachyon/methods/custom/getDashboardSections.ts:1641
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:620
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147
msgid "Stopped"
msgstr ""
+2 -2
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-16 17:48+0300\n"
"PO-Revision-Date: 2026-08-16 17:48+0300\n"
"POT-Creation-Date: 2026-08-16 19:34+0300\n"
"PO-Revision-Date: 2026-08-16 19:34+0300\n"
"Last-Translator: Dushnilin\n"
"Language-Team: none\n"
"Language: ru\n"
@@ -1416,6 +1416,59 @@ function buildMtprotoLink(sectionId, identity) {
return `https://t.me/proxy?${query}`;
}
function buildAwgClientConfig(sectionId) {
const host = getPublicHost(sectionId);
const port = uci.get(UCI_PACKAGE, sectionId, "listen_port") || "51820";
const clientPrivateKey = uci.get(UCI_PACKAGE, sectionId, "awg_client_private_key") || "";
const serverPublicKey =
uci.get(UCI_PACKAGE, sectionId, "awg_server_public_key") ||
uci.get(UCI_PACKAGE, sectionId, "awg_peer_public_key") ||
"";
const presharedKey = uci.get(UCI_PACKAGE, sectionId, "awg_preshared_key") || "";
const clientAddress = uci.get(UCI_PACKAGE, sectionId, "awg_client_address") || "10.0.0.2/32";
const mtu = uci.get(UCI_PACKAGE, sectionId, "awg_mtu") || "1280";
const keepalive = uci.get(UCI_PACKAGE, sectionId, "awg_keepalive") || "25";
const dns = uci.get(UCI_PACKAGE, sectionId, "awg_dns") || "10.0.0.1";
const jc = uci.get(UCI_PACKAGE, sectionId, "awg_jc") || "4";
const jmin = uci.get(UCI_PACKAGE, sectionId, "awg_jmin") || "40";
const jmax = uci.get(UCI_PACKAGE, sectionId, "awg_jmax") || "70";
const s1 = uci.get(UCI_PACKAGE, sectionId, "awg_s1") || "0";
const s2 = uci.get(UCI_PACKAGE, sectionId, "awg_s2") || "0";
const s3 = uci.get(UCI_PACKAGE, sectionId, "awg_s3") || "0";
const s4 = uci.get(UCI_PACKAGE, sectionId, "awg_s4") || "0";
const h1 = uci.get(UCI_PACKAGE, sectionId, "awg_h1") || "1";
const h2 = uci.get(UCI_PACKAGE, sectionId, "awg_h2") || "2";
const h3 = uci.get(UCI_PACKAGE, sectionId, "awg_h3") || "3";
const h4 = uci.get(UCI_PACKAGE, sectionId, "awg_h4") || "4";
const i1 = uci.get(UCI_PACKAGE, sectionId, "awg_i1") || "";
const i2 = uci.get(UCI_PACKAGE, sectionId, "awg_i2") || "";
const i3 = uci.get(UCI_PACKAGE, sectionId, "awg_i3") || "";
const i4 = uci.get(UCI_PACKAGE, sectionId, "awg_i4") || "";
const i5 = uci.get(UCI_PACKAGE, sectionId, "awg_i5") || "";
const j1 = uci.get(UCI_PACKAGE, sectionId, "awg_j1") || "";
const j2 = uci.get(UCI_PACKAGE, sectionId, "awg_j2") || "";
const j3 = uci.get(UCI_PACKAGE, sectionId, "awg_j3") || "";
const itime = uci.get(UCI_PACKAGE, sectionId, "awg_itime") || "";
let conf = `[Interface]\nAddress = ${clientAddress}\nPrivateKey = ${clientPrivateKey}\nDNS = ${dns}\nMTU = ${mtu}\n`;
conf += `Jc = ${jc}\nJmin = ${jmin}\nJmax = ${jmax}\nS1 = ${s1}\nS2 = ${s2}\nS3 = ${s3}\nS4 = ${s4}\nH1 = ${h1}\nH2 = ${h2}\nH3 = ${h3}\nH4 = ${h4}\n`;
if (i1) conf += `I1 = ${i1}\n`;
if (i2) conf += `I2 = ${i2}\n`;
if (i3) conf += `I3 = ${i3}\n`;
if (i4) conf += `I4 = ${i4}\n`;
if (i5) conf += `I5 = ${i5}\n`;
if (j1) conf += `J1 = ${j1}\n`;
if (j2) conf += `J2 = ${j2}\n`;
if (j3) conf += `J3 = ${j3}\n`;
if (itime) conf += `Itime = ${itime}\n`;
conf += `\n[Peer]\nPublicKey = ${serverPublicKey}\nEndpoint = ${host}:${port}\nAllowedIPs = 0.0.0.0/0, ::/0\nPersistentKeepalive = ${keepalive}\n`;
if (presharedKey) conf += `PresharedKey = ${presharedKey}\n`;
return conf;
}
function buildClientLink(sectionId, options = {}) {
const protocol = getProtocol(sectionId);
const identity = getServerIdentity(sectionId);
@@ -1424,6 +1477,10 @@ function buildClientLink(sectionId, options = {}) {
return "";
}
if (protocol === "awg") {
return buildAwgClientConfig(sectionId);
}
if (
((protocol === "vless" || protocol === "vmess") && !identity.uuid) ||
(PASSWORD_PROTOCOLS.includes(protocol) && !identity.password) ||
@@ -1454,6 +1511,8 @@ function buildClientLink(sectionId, options = {}) {
return buildHysteria2Link(sectionId, identity, options);
case "mtproto":
return buildMtprotoLink(sectionId, identity);
case "awg":
return buildAwgClientConfig(sectionId);
case "vless":
default:
return buildVlessTrojanLink(sectionId, identity);
@@ -1679,19 +1738,46 @@ function renderInfoClientLink(sectionId, linkContext = {}) {
},
link,
),
E(
"button",
{
class:
"btn cbi-button cbi-button-neutral fkp-server-info-modal__copy-btn",
type: "button",
click: (ev) => {
ev.preventDefault();
copyText(link);
E("div", { style: "display:flex;gap:6px;" }, [
E(
"button",
{
class:
"btn cbi-button cbi-button-neutral fkp-server-info-modal__copy-btn",
type: "button",
click: (ev) => {
ev.preventDefault();
copyText(link);
},
},
},
[iconSvg("copy"), " ", E("span", {}, _("Copy"))],
),
[iconSvg("copy"), " ", E("span", {}, _("Copy"))],
),
protocol === "awg"
? E(
"button",
{
class:
"btn cbi-button cbi-button-action fkp-server-info-modal__copy-btn",
type: "button",
click: (ev) => {
ev.preventDefault();
const blob = new Blob([link], {
type: "text/plain;charset=utf-8",
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `${name || "amneziawg"}.conf`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
},
},
[E("span", {}, _("Download .conf"))],
)
: "",
]),
]),
]),
]);
@@ -2296,10 +2382,57 @@ function shouldGenerateRealityKeypair(sectionId) {
);
}
function generateAwgKeypair(sectionId) {
return fs
.exec("/usr/bin/tachyon", ["generate_wg_keypair"])
.then((response) => {
const text = response?.stdout || "";
const matchPriv = text.match(/PrivateKey:\s*([^\s]+)/);
const matchPub = text.match(/PublicKey:\s*([^\s]+)/);
if (matchPriv && matchPub) {
return {
private_key: matchPriv[1],
public_key: matchPub[1],
};
}
return null;
})
.catch(() => null);
}
function generateAwgKeypairsIfMissing(sectionId) {
const currentServerPriv = uci.get(UCI_PACKAGE, sectionId, "awg_private_key");
const currentPeerPub = uci.get(UCI_PACKAGE, sectionId, "awg_peer_public_key");
if (currentServerPriv && currentPeerPub) {
return Promise.resolve();
}
return Promise.all([generateAwgKeypair(sectionId), generateAwgKeypair(sectionId)]).then(
([srvPair, cliPair]) => {
if (srvPair) {
uci.set(UCI_PACKAGE, sectionId, "awg_private_key", srvPair.private_key);
uci.set(UCI_PACKAGE, sectionId, "awg_server_public_key", srvPair.public_key);
setWidgetValue(sectionId, "awg_private_key", srvPair.private_key);
setWidgetValue(sectionId, "awg_server_public_key", srvPair.public_key);
}
if (cliPair) {
uci.set(UCI_PACKAGE, sectionId, "awg_client_private_key", cliPair.private_key);
uci.set(UCI_PACKAGE, sectionId, "awg_peer_public_key", cliPair.public_key);
setWidgetValue(sectionId, "awg_client_private_key", cliPair.private_key);
setWidgetValue(sectionId, "awg_peer_public_key", cliPair.public_key);
}
},
);
}
function prepareServerModal(sectionId) {
return shouldGenerateRealityKeypair(sectionId)
? generateRealityKeypairIfMissing(sectionId)
: Promise.resolve();
if (shouldGenerateRealityKeypair(sectionId)) {
return generateRealityKeypairIfMissing(sectionId);
}
if (getProtocol(sectionId) === "awg") {
return generateAwgKeypairsIfMissing(sectionId);
}
return Promise.resolve();
}
function addStreamDepends(option) {
@@ -2529,6 +2662,9 @@ function createServerContent(section, options = {}) {
if (value === "vless" && getEffectiveSecurity(sectionId) === "reality") {
generateRealityKeypairIfMissing(sectionId);
}
if (value === "awg") {
generateAwgKeypairsIfMissing(sectionId);
}
};
o = section.option(form.Value, "listen", _("Listen address"));
@@ -3134,6 +3270,239 @@ function createServerContent(section, options = {}) {
o.modalonly = true;
o.rmempty = true;
addTailscaleDepends(o, singBoxTailscale);
// AWG Server Options
o = section.option(
form.Value,
"awg_local_address",
_("Server Address"),
_("Server VPN IP address and subnet (e.g. 10.0.0.1/24)"),
);
o.default = "10.0.0.1/24";
o.modalonly = true;
o.rmempty = false;
o.validate = validateRequired;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_client_address",
_("Client Address"),
_("Client VPN IP address (e.g. 10.0.0.2/32)"),
);
o.default = "10.0.0.2/32";
o.modalonly = true;
o.rmempty = false;
o.validate = validateRequired;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_dns",
_("Client DNS"),
_("DNS server pushed to the client configuration"),
);
o.default = "10.0.0.1";
o.modalonly = true;
o.rmempty = false;
o.depends("protocol", "awg");
o = section.option(form.Value, "awg_mtu", _("MTU"));
o.default = "1280";
o.modalonly = true;
o.rmempty = false;
o.validate = validatePositiveInteger;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_keepalive",
_("Persistent Keepalive"),
);
o.default = "25";
o.modalonly = true;
o.rmempty = false;
o.validate = validatePositiveInteger;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_private_key",
_("Server Private Key"),
);
o.modalonly = true;
o.rmempty = false;
o.validate = validateRequired;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_server_public_key",
_("Server Public Key"),
);
o.modalonly = true;
o.rmempty = true;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_client_private_key",
_("Client Private Key"),
);
o.modalonly = true;
o.rmempty = false;
o.validate = validateRequired;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_peer_public_key",
_("Client Public Key"),
);
o.modalonly = true;
o.rmempty = false;
o.validate = validateRequired;
o.depends("protocol", "awg");
o = section.option(
form.Value,
"awg_preshared_key",
_("Pre-shared Key (PSK)"),
);
o.modalonly = true;
o.rmempty = true;
o.depends("protocol", "awg");
const awgParams = [
{
name: "awg_jc",
title: _("Junk packet count (Jc)"),
desc: _("Number of junk packets before handshake (1-10)"),
default: "4",
},
{
name: "awg_jmin",
title: _("Junk packet min size (Jmin)"),
desc: _("Minimum size of junk packets"),
default: "40",
},
{
name: "awg_jmax",
title: _("Junk packet max size (Jmax)"),
desc: _("Maximum size of junk packets"),
default: "70",
},
{
name: "awg_s1",
title: _("Init packet junk size (S1)"),
desc: _("Junk size for initiation packet"),
default: "0",
},
{
name: "awg_s2",
title: _("Response packet junk size (S2)"),
desc: _("Junk size for response packet"),
default: "0",
},
{
name: "awg_s3",
title: _("Cookie packet junk size (S3)"),
desc: _("Junk size for cookie packet"),
default: "0",
},
{
name: "awg_s4",
title: _("Transport packet junk size (S4)"),
desc: _("Junk size for transport packet"),
default: "0",
},
{
name: "awg_h1",
title: _("Init packet header (H1)"),
desc: _("Custom header for handshake initiation"),
default: "1",
},
{
name: "awg_h2",
title: _("Response packet header (H2)"),
desc: _("Custom header for handshake response"),
default: "2",
},
{
name: "awg_h3",
title: _("Underload packet header (H3)"),
desc: _("Custom header for cookie packet"),
default: "3",
},
{
name: "awg_h4",
title: _("Transport packet header (H4)"),
desc: _("Custom header for data packet"),
default: "4",
},
{
name: "awg_i1",
title: _("Init payload (I1)"),
desc: _("Hex or binary payload for init"),
default: "",
},
{
name: "awg_i2",
title: _("Response payload (I2)"),
desc: _("Hex or binary payload for response"),
default: "",
},
{
name: "awg_i3",
title: _("Payload (I3)"),
desc: _("Hex or binary payload"),
default: "",
},
{
name: "awg_i4",
title: _("Payload (I4)"),
desc: _("Hex or binary payload"),
default: "",
},
{
name: "awg_i5",
title: _("Payload (I5)"),
desc: _("Hex or binary payload"),
default: "",
},
{
name: "awg_j1",
title: _("Junk payload (J1)"),
desc: _("Hex or binary junk payload"),
default: "",
},
{
name: "awg_j2",
title: _("Junk payload (J2)"),
desc: _("Hex or binary junk payload"),
default: "",
},
{
name: "awg_j3",
title: _("Junk payload (J3)"),
desc: _("Hex or binary junk payload"),
default: "",
},
{
name: "awg_itime",
title: _("Init timeout (Itime)"),
desc: _("Init handshake timeout"),
default: "",
},
];
awgParams.forEach((param) => {
let opt = section.option(form.Value, param.name, param.title, param.desc);
opt.modalonly = true;
opt.rmempty = true;
if (param.default !== "") opt.default = param.default;
opt.depends("protocol", "awg");
});
}
return baseclass.extend({
+2 -2
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-16 17:48+0300\n"
"PO-Revision-Date: 2026-08-16 17:48+0300\n"
"POT-Creation-Date: 2026-08-16 19:34+0300\n"
"PO-Revision-Date: 2026-08-16 19:34+0300\n"
"Last-Translator: Dushnilin\n"
"Language-Team: none\n"
"Language: ru\n"
+7 -7
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-16 14:48+0300\n"
"PO-Revision-Date: 2026-08-16 14:48+0300\n"
"POT-Creation-Date: 2026-08-16 16:34+0300\n"
"PO-Revision-Date: 2026-08-16 16:34+0300\n"
"Last-Translator: Dushnilin <dushnilin@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -720,8 +720,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10239
#: src/partials/modal/renderModal.ts:263
#: src/tachyon/tabs/diagnostic/initController.ts:1545
#: src/tachyon/tabs/dashboard/initController.ts:1256
#: src/tachyon/tabs/diagnostic/initController.ts:1545
#: src/tachyon/tabs/monitoring/initController.ts:884
#: src/tachyon/tabs/monitoring/initController.ts:934
#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:212
@@ -798,8 +798,8 @@ msgid "Configure User-Agent in the item settings"
msgstr ""
#: src/tachyon/methods/custom/getDashboardSections.ts:1639
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:618
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141
msgid "Conflict"
msgstr ""
@@ -2858,9 +2858,9 @@ msgid "None"
msgstr ""
#: src/tachyon/methods/custom/getDashboardSections.ts:1642
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:621
#: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:621
msgid "Not configured"
msgstr ""
@@ -3652,8 +3652,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1953
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1954
#: src/tachyon/methods/custom/getDashboardSections.ts:1637
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:616
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135
msgid "Running"
msgstr ""
@@ -4189,8 +4189,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:1959
#: src/tachyon/methods/custom/getDashboardSections.ts:1641
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:620
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147
msgid "Stopped"
msgstr ""
+39 -12
View File
@@ -674,6 +674,30 @@ function generate_reality_keypair_values() {
};
}
function generate_wg_keypair_values() {
let data = output("sing-box generate wg-keypair 2>/dev/null");
let private_key = first_key_value_line_value(data, "PrivateKey");
let public_key = first_key_value_line_value(data, "PublicKey");
if (private_key == null || public_key == null || private_key == "" || public_key == "")
return null;
return {
private_key: private_key,
public_key: public_key
};
}
function generate_wg_keypair_cli() {
let pair = generate_wg_keypair_values();
if (pair == null) {
error_response("Failed to generate WireGuard key pair");
exit(1);
}
print(sprintf("PrivateKey: %s\nPublicKey: %s\n", pair.private_key, pair.public_key));
}
function generate_reality_keypair_cli() {
let pair = generate_reality_keypair_values();
if (pair == null) {
@@ -969,6 +993,7 @@ function prepare_server_defaults(section) {
server_default_set_option(section, "listen_port", "51820");
server_default_set_option(section, "awg_mtu", "1280");
server_default_set_option(section, "awg_local_address", "10.0.0.1/24");
server_default_set_option(section, "awg_client_address", "10.0.0.2/32");
server_default_set_option(section, "awg_jc", "4");
server_default_set_option(section, "awg_jmin", "40");
server_default_set_option(section, "awg_jmax", "70");
@@ -981,19 +1006,19 @@ function prepare_server_defaults(section) {
server_default_set_option(section, "awg_h3", "3");
server_default_set_option(section, "awg_h4", "4");
server_default_set_option(section, "awg_keepalive", "25");
if (uci_get(config_path(section, "awg_private_key")) == "") {
let data = output("sing-box generate wg-keypair 2>/dev/null");
let priv = "";
let pub = "";
for (let line in split(data, "\n")) {
let m_priv = match(line, /^PrivateKey:\s*(.+)$/);
if (m_priv) priv = trim(m_priv[1]);
let m_pub = match(line, /^PublicKey:\s*(.+)$/);
if (m_pub) pub = trim(m_pub[1]);
let server_private_key = uci_get(config_path(section, "awg_private_key"));
let peer_public_key = uci_get(config_path(section, "awg_peer_public_key"));
if (server_private_key == "" || peer_public_key == "") {
let srv_pair = generate_wg_keypair_values();
let cli_pair = generate_wg_keypair_values();
if (srv_pair != null) {
server_set_option(section, "awg_private_key", srv_pair.private_key);
server_set_option(section, "awg_server_public_key", srv_pair.public_key);
}
if (priv != "" && pub != "") {
server_set_option(section, "awg_private_key", priv);
server_set_option(section, "awg_peer_public_key", pub);
if (cli_pair != null) {
server_set_option(section, "awg_client_private_key", cli_pair.private_key);
server_set_option(section, "awg_peer_public_key", cli_pair.public_key);
}
}
}
@@ -1127,6 +1152,8 @@ else if (mode == "prepare-all-defaults")
prepare_all_server_defaults();
else if (mode == "generate-reality-keypair")
generate_reality_keypair_cli();
else if (mode == "generate-wg-keypair")
generate_wg_keypair_cli();
else if (mode == "tls-certificate-sha256")
get_tls_certificate_sha256_cli(ARGV[1]);
else if (mode == "reality-keypair-response")