Files
alpine-router/public/firewall.html
2026-04-15 11:38:26 +03:00

241 lines
9.3 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.0">
<title>Файрвол — NanoRouter</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<div class="header-left">
<svg class="logo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>
<h1>NanoRouter</h1>
</div>
<div class="header-right">
</div>
</header>
<nav class="tab-nav">
<a href="/home.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>
Главная
</a>
<a href="/ifaces.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
<path d="M2 12l10 5 10-5"/>
</svg>
Интерфейсы
</a>
<a href="/dhcp.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
DHCP сервер
</a>
<a href="/clients.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<circle cx="9" cy="7" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2"/>
<path d="M16 3.13a4 4 0 0 1 0 7.75M21 21v-2a4 4 0 0 0-3-3.87"/>
</svg>
Клиенты
</a>
<a href="/firewall.html" class="tab-link active">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
<path d="M9 12l2 2 4-4"/>
</svg>
Файрвол
</a>
<a href="/proxy.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<circle cx="12" cy="12" r="3"/>
<path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/>
</svg>
Прокси
</a>
<a href="/profile.html" class="tab-link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="15" height="15">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
<circle cx="12" cy="7" r="4"/>
</svg>
Профиль
</a>
</nav>
<main class="fw-main">
<div id="notInstalledBanner" class="alert alert-error hidden">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18">
<circle cx="12" cy="12" r="10"/><path d="M12 8v4m0 4h.01"/>
</svg>
<div>
<strong>nftables не установлен.</strong>
Для работы файрвола выполните на роутере:
<code>apk add nftables</code>
</div>
</div>
<!-- Top controls bar -->
<div class="fw-toolbar">
<div class="fw-toolbar-left">
<label class="toggle-label" id="vlanIsolationLabel" title="Запрещает трафик между VLAN-интерфейсами по умолчанию. Явные правила разрешения выше имеют приоритет.">
<input type="checkbox" id="vlanIsolation">
<span class="toggle-slider"></span>
<span>Изоляция VLAN</span>
</label>
<span class="fw-hint">— теговые VLAN не видят друг друга; NAT — только выход в интернет</span>
</div>
<div class="fw-toolbar-right">
<button class="btn btn-ghost btn-sm" id="addRuleBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><path d="M12 5v14M5 12h14"/></svg>
Добавить правило
</button>
<button class="btn btn-primary" id="applyBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><path d="M5 12l5 5L20 7"/></svg>
Сохранить и применить
</button>
</div>
</div>
<!-- Rules table -->
<div class="fw-card">
<div class="fw-table-wrap">
<table class="fw-table" id="rulesTable">
<thead>
<tr>
<th class="col-drag"></th>
<th class="col-num">#</th>
<th class="col-en">Вкл</th>
<th class="col-action">Действие</th>
<th class="col-proto">Протокол</th>
<th class="col-iface">Вх. интерфейс</th>
<th class="col-iface">Вых. интерфейс</th>
<th class="col-addr">Источник</th>
<th class="col-addr">Назначение</th>
<th class="col-comment">Комментарий</th>
<th class="col-btns"></th>
</tr>
</thead>
<tbody id="rulesTbody">
<tr id="emptyRow">
<td colspan="11" class="fw-empty">
Правил нет. Нажмите «Добавить правило» для создания.
</td>
</tr>
</tbody>
</table>
</div>
<div class="fw-policy-note">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14">
<circle cx="12" cy="12" r="10"/><path d="M12 8v4m0 4h.01"/>
</svg>
Политика по умолчанию: <strong>DROP</strong> — весь трафик запрещён, если не разрешён явно выше или через NAT.
Трафик established/related всегда разрешается.
</div>
</div>
</main>
<!-- Rule Edit Modal -->
<div id="ruleModal" class="modal hidden" role="dialog" aria-modal="true">
<div class="modal-backdrop" id="ruleModalBackdrop"></div>
<div class="modal-box modal-wide">
<div class="modal-header">
<h2 id="ruleModalTitle">Добавить правило</h2>
<button class="btn-icon" id="closeRuleModal"></button>
</div>
<form id="ruleForm" autocomplete="off">
<div class="form-row">
<label for="rComment">Комментарий</label>
<input type="text" id="rComment" placeholder="Описание правила (необязательно)">
</div>
<div class="form-row">
<label>Действие</label>
<div class="segmented" id="actionSwitch">
<button type="button" class="seg-btn active" data-val="accept">Разрешить</button>
<button type="button" class="seg-btn" data-val="drop">Запретить</button>
<button type="button" class="seg-btn" data-val="reject">Отклонить</button>
</div>
</div>
<div class="form-row">
<label>Протокол</label>
<div class="segmented" id="protoSwitch">
<button type="button" class="seg-btn active" data-val="all">Любой</button>
<button type="button" class="seg-btn" data-val="tcp">TCP</button>
<button type="button" class="seg-btn" data-val="udp">UDP</button>
<button type="button" class="seg-btn" data-val="icmp">ICMP</button>
</div>
</div>
<div class="form-grid-2">
<div class="form-row">
<label for="rInIface">Входящий интерфейс</label>
<input type="text" id="rInIface" placeholder="eth0, eth0.100 … (пусто = любой)" list="ifaceList">
</div>
<div class="form-row">
<label for="rOutIface">Исходящий интерфейс</label>
<input type="text" id="rOutIface" placeholder="eth1 … (пусто = любой)" list="ifaceList">
</div>
</div>
<div class="form-grid-2">
<div class="form-row">
<label for="rSrcAddr">Источник (адрес/подсеть)</label>
<input type="text" id="rSrcAddr" placeholder="192.168.1.0/24 или 10.0.0.5">
</div>
<div class="form-row">
<label for="rDstAddr">Назначение (адрес/подсеть)</label>
<input type="text" id="rDstAddr" placeholder="10.0.0.0/24 или 8.8.8.8">
</div>
</div>
<div class="form-grid-2" id="portFields">
<div class="form-row">
<label for="rSrcPort">Порт источника</label>
<input type="text" id="rSrcPort" placeholder="80 или 1000-2000">
</div>
<div class="form-row">
<label for="rDstPort">Порт назначения</label>
<input type="text" id="rDstPort" placeholder="443 или 8080-8090">
</div>
</div>
<div class="form-row">
<label class="checkbox-label">
<input type="checkbox" id="rEnabled" checked>
<span>Правило активно</span>
</label>
</div>
</form>
<div class="modal-footer">
<button class="btn btn-ghost" id="cancelRuleBtn">Отмена</button>
<button class="btn btn-primary" id="saveRuleBtn">Сохранить</button>
</div>
</div>
</div>
<datalist id="ifaceList"></datalist>
<div id="toast" class="toast hidden"></div>
<script src="firewall.js"></script>
</body>
</html>