Firewall added & some fixes
This commit is contained in:
234
public/firewall.html
Normal file
234
public/firewall.html
Normal file
@@ -0,0 +1,234 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Файрвол — AlpineRouter</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>AlpineRouter</h1>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button class="btn btn-ghost" id="refreshBtn" title="Обновить">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
|
||||
<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
|
||||
<path d="M3 3v5h5"/>
|
||||
</svg>
|
||||
Обновить
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="tab-nav">
|
||||
<a href="/" 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>
|
||||
</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>
|
||||
Reference in New Issue
Block a user