Files
kaskad_web_vpn/templates/index.html
Андрей Бобырев 7af4f701e1 feat: Kaskad Web UI v2 dashboard
System/services/NAT CRUD, iptables chain KASKAD_WEB, host-network Docker install, docker CLI in image for status row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 20:35:34 +03:00

122 lines
5.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ ui_title }}</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 shell-wide">
<div class="top-bar">
<h1 class="product-title">{{ ui_title }}</h1>
<button type="button" class="btn btn-ghost" id="btn-refresh" title="Обновить данные">Обновить</button>
</div>
<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&nbsp;СБП</a>
<span class="sep">·</span>
<a href="https://t.me/lot_andrey" target="_blank" rel="noopener noreferrer">Telegram @lot_andrey</a>
</div>
{% if panel_url %}
<p class="support-blurb">Панель Amnezia / доп.: <a href="{{ panel_url }}">{{ panel_url }}</a></p>
{% else %}
<p class="support-blurb">Открытый исходный код, без сторонней рекламы на странице.</p>
{% endif %}
</header>
<section class="card" id="sec-system">
<h2 class="card-title">Система</h2>
<div class="sys-grid" id="system-grid"></div>
</section>
<section class="card" id="sec-services">
<h2 class="card-title">Сервисы</h2>
<div class="table-wrap">
<table class="data-table" id="tbl-services">
<thead>
<tr><th>UNIT</th><th>ACTIVE</th><th>ENABLED</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
</section>
<section class="card" id="sec-clients">
<div class="card-head">
<h2 class="card-title">Клиенты (правила NAT)</h2>
<button type="button" class="btn" id="btn-add-client">+ Добавить клиента</button>
</div>
<div class="table-wrap table-scroll">
<table class="data-table" id="tbl-clients">
<thead>
<tr>
<th>USER</th><th>PROTO</th><th>IN</th><th></th><th>TARGET</th><th>OUT</th>
<th>ЗАМЕТКА</th><th>ГДЕ</th><th></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</section>
<details class="panel-fold card-inner" id="fold-iptables">
<summary class="fold-sum">
<span class="fold-arrow" aria-hidden="true"></span>
<span class="fold-h">Сырые iptables правила (kaskad)</span>
</summary>
<div class="fold-body">
<button type="button" class="btn btn-sm" id="btn-load-iptables">Показать</button>
<pre class="mono-block" id="iptables-out"></pre>
</div>
</details>
<section class="card">
<h2 class="card-title">Мониторы</h2>
<p class="muted pad-v">— нет ни одного —</p>
</section>
<footer class="site-footer">
Kaskad Web UI · <a href="https://github.com/andrey271192/kaskad_web_vpn">kaskad_web_vpn</a> · HTTP Basic Auth · DNAT в цепочке <span class="mono">KASKAD_WEB</span> (nat).
</footer>
</div>
<div class="modal-overlay" id="modal-overlay" hidden>
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<h3 id="modal-title">Клиент</h3>
<form id="form-client" class="form-grid">
<input type="hidden" name="id" id="f-id">
<label>USER <input name="user" id="f-user" required maxlength="64" autocomplete="off"></label>
<label>PROTO
<select name="proto" id="f-proto">
<option value="udp">udp</option>
<option value="tcp">tcp</option>
</select>
</label>
<label>IN (порт) <input name="in_port" id="f-in" type="number" required min="1" max="65535"></label>
<label>TARGET (IPv4) <input name="target" id="f-target" required autocomplete="off" placeholder="10.0.0.5"></label>
<label>OUT (порт) <input name="out_port" id="f-out" type="number" required min="1" max="65535"></label>
<label class="span-2">ЗАМЕТКА <input name="note" id="f-note" maxlength="256" autocomplete="off"></label>
<label class="span-2">ГДЕ <input name="where" id="f-where" maxlength="256" autocomplete="off" placeholder="Netherlands · узел …"></label>
<div class="modal-actions span-2">
<button type="submit" class="btn">Сохранить</button>
<button type="button" class="btn btn-ghost" id="modal-cancel">Отмена</button>
</div>
</form>
</div>
</div>
<script src="{{ url_for('static', filename='dashboard.js') }}" defer></script>
</body>
</html>