mirror of
https://github.com/andrey271192/kaskad_web_vpn.git
synced 2026-09-20 11:55:35 +00:00
Flask + Docker, header support links, install/uninstall curl scripts, password file or ADMIN_PASSWORD. Co-authored-by: Cursor <cursoragent@cursor.com>
145 lines
7.5 KiB
HTML
145 lines
7.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Каскад AmneziaWG — памятка</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;600;700&family=JetBrains+Mono:wght@400&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
||
</head>
|
||
<body>
|
||
<div class="shell">
|
||
<header class="site-header">
|
||
<div class="support-line">
|
||
<span class="support-title">Поддержка автора</span>
|
||
<span class="sep" aria-hidden="true">·</span>
|
||
<a href="https://github.com/andrey271192/kaskad_web_vpn" target="_blank" rel="noopener noreferrer">GitHub</a>
|
||
<span class="sep">·</span>
|
||
<a href="https://boosty.to/andrey27/donate" target="_blank" rel="noopener noreferrer">Boosty</a>
|
||
<span class="sep">·</span>
|
||
<a href="https://finance.ozon.ru/apps/sbp/ozonbankpay/019dc200-2a5d-7931-a619-782d285f6798" target="_blank" rel="noopener noreferrer">Ozon СБП</a>
|
||
<span class="sep">·</span>
|
||
<a href="https://t.me/lot_andrey" target="_blank" rel="noopener noreferrer">Telegram @lot_andrey</a>
|
||
</div>
|
||
<p class="support-blurb">Звезда репозиторию и донат помогают развивать утилиты. На этой странице нет сторонней рекламы.</p>
|
||
</header>
|
||
|
||
<p class="eyebrow">VPN · каскад</p>
|
||
<h1>Каскад для AmneziaWG</h1>
|
||
<p class="lead">
|
||
Краткая памятка: клиент подключается сначала к вашему <strong>промежуточному узлу</strong> (Endpoint),
|
||
а ключ и peer создаются на основном сервере AmneziaWG. Эта страница только объясняет шаги и может собрать текст-памятку;
|
||
генерация <span class="inline-code">.conf</span> выполняется в вашей <strong>админ-панели</strong> или вручную.
|
||
</p>
|
||
|
||
{% if panel_url %}
|
||
<p class="muted">Ваша панель: <a href="{{ panel_url }}">{{ panel_url }}</a></p>
|
||
{% endif %}
|
||
|
||
<details class="panel-fold" open>
|
||
<summary>
|
||
<span class="fold-arrow" aria-hidden="true"></span>
|
||
<span class="fold-h">Что такое каскад</span>
|
||
</summary>
|
||
<div class="fold-body">
|
||
<p class="muted">
|
||
В конфиге клиента поле <span class="inline-code">Endpoint</span> указывает на IP или DNS узла «перед» VPS
|
||
(домашний роутер с пробросом UDP, другой VPS и т.д.). На этом узле нужен проброс порта на ваш основной сервер WireGuard/AWG.
|
||
Сервер AmneziaWG добавляет peer и выдаёт готовый <span class="inline-code">.conf</span>.
|
||
</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="panel-fold" open>
|
||
<summary>
|
||
<span class="fold-arrow" aria-hidden="true"></span>
|
||
<span class="fold-h">Через панель Amnezia Admin</span>
|
||
</summary>
|
||
<div class="fold-body">
|
||
<p class="muted">
|
||
Если установлена <strong>Amnezia Admin WebUI</strong>, откройте блок <strong>«Новый клиент под каскад»</strong>:
|
||
укажите Endpoint (ваш публичный IP/DNS узла и при необходимости порт), затем скачайте <span class="inline-code">.conf</span>.
|
||
</p>
|
||
<p class="muted">
|
||
Репозиторий панели:
|
||
<a href="https://github.com/andrey271192/Amnezia_web" target="_blank" rel="noopener noreferrer">github.com/andrey271192/Amnezia_web</a>
|
||
</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="panel-fold">
|
||
<summary>
|
||
<span class="fold-arrow" aria-hidden="true"></span>
|
||
<span class="fold-h">Собрать памятку (локально в браузере)</span>
|
||
</summary>
|
||
<div class="fold-body">
|
||
<p class="muted">Данные не отправляются на сервер — только текст для копирования.</p>
|
||
<div class="grid-form">
|
||
<label for="ep-host">Endpoint (хост для клиента)</label>
|
||
<input id="ep-host" type="text" placeholder="203.0.113.50 или ddns.example.com" autocomplete="off">
|
||
|
||
<label for="ep-port">Порт Endpoint (если пусто — как у сервера)</label>
|
||
<input id="ep-port" type="number" min="1" max="65535" placeholder="51820" autocomplete="off">
|
||
|
||
<label for="memo-name">Имя клиента (произвольно)</label>
|
||
<input id="memo-name" type="text" placeholder="Телефон через узел X" autocomplete="off">
|
||
|
||
<div class="btn-row">
|
||
<button type="button" class="btn" id="btn-build">Собрать текст</button>
|
||
<button type="button" class="btn" id="btn-copy">Копировать</button>
|
||
</div>
|
||
</div>
|
||
<pre class="out-box" id="out-memo" aria-live="polite"></pre>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="panel-fold">
|
||
<summary>
|
||
<span class="fold-arrow" aria-hidden="true"></span>
|
||
<span class="fold-h">Проброс UDP</span>
|
||
</summary>
|
||
<div class="fold-body">
|
||
<p class="muted">
|
||
На промежуточном узле пробросьте UDP с выбранного порта на IP VPS и порт, где слушает ваш инстанс AmneziaWG.
|
||
Убедитесь, что фаервол не режет входящий UDP.
|
||
</p>
|
||
</div>
|
||
</details>
|
||
|
||
<footer class="site-footer">
|
||
Сервис: HTTP Basic Auth (realm «kaskad»). Установка одной ссылкой — см. README репозитория kaskad_web_vpn.
|
||
</footer>
|
||
</div>
|
||
<script>
|
||
(function () {
|
||
function buildText() {
|
||
var host = (document.getElementById("ep-host").value || "").trim();
|
||
var port = (document.getElementById("ep-port").value || "").trim();
|
||
var name = (document.getElementById("memo-name").value || "").trim() || "клиент";
|
||
var epLine = host ? (host + (port ? ":" + port : "")) : "(укажите Endpoint)";
|
||
return (
|
||
"Памятка по каскаду\n" +
|
||
"— Имя: " + name + "\n" +
|
||
"— Endpoint для клиента: " + epLine + "\n" +
|
||
"— На промежуточном узле: проброс UDP на VPS и порт WG/AWG.\n" +
|
||
"— На основном сервере: создать peer (панель Amnezia Admin → «Новый клиент под каскад») и выдать .conf.\n"
|
||
);
|
||
}
|
||
document.getElementById("btn-build").addEventListener("click", function () {
|
||
document.getElementById("out-memo").textContent = buildText();
|
||
});
|
||
document.getElementById("btn-copy").addEventListener("click", async function () {
|
||
var t = document.getElementById("out-memo").textContent || buildText();
|
||
try {
|
||
await navigator.clipboard.writeText(t);
|
||
} catch (e) {
|
||
alert("Не удалось скопировать — выделите текст вручную.");
|
||
}
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|