feat: tunnel host and port in the panel settings, ufw kept in sync
The direct tunnel port (8446 by default) and the host agents dial for it can be set in Settings. The server moves its listeners at once and agents pick the address up from the panel: on connect and with every poll, unless TUNNEL_ADDR / TUNNEL_PORT pin it locally. ufw: run with a C locale (the output is translated), do not adopt rules that existed before the panel, skip loopback-only listeners, re-open what saved forwards need on start and when the integration is turned on, move the shared tunnel rule with the port and drop it when no direct forward is left. The last ufw error is shown in Settings. The forwards page shows the real tunnel and panel ports.
This commit is contained in:
1 parent
08fc2d79a8
commit
bcfe909aaa
15 files changed
+540
-97
No files matched your search
@@ -70,8 +70,8 @@
|
||||
<label>Тип</label>
|
||||
<select name="proto" id="proto">
|
||||
<option value="http">http (long-poll, работает везде)</option>
|
||||
<option value="tcp">tcp (прямой, низкая задержка, порт 8446)</option>
|
||||
<option value="udp">udp (прямой, порт 8446)</option>
|
||||
<option value="tcp">tcp (прямой, низкая задержка, порт {{.TunnelPort}})</option>
|
||||
<option value="udp">udp (прямой, порт {{.TunnelPort}})</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="fld">
|
||||
@@ -95,18 +95,18 @@
|
||||
<div class="card">
|
||||
<h2>Режимы</h2>
|
||||
<ul class="muted" style="font-size:14px; line-height:1.7">
|
||||
<li><b>http</b> — туннель поверх HTTP long-poll (через nginx :8445). Работает везде, где доступна панель, но задержка выше.</li>
|
||||
<li><b>tcp</b> — прямой TCP-мультиплексор через порт <b>8446</b> хоста. Минимальная задержка, keep-alive, TCP_NODELAY. Нужно открыть 8446/tcp на хосте.</li>
|
||||
<li><b>udp</b> — прямой UDP через порт <b>8446</b> хоста. Нужно открыть 8446/udp.</li>
|
||||
<li><b>http</b> — туннель поверх HTTP long-poll (через адрес панели, порт {{.PanelPort}}). Работает везде, где доступна панель, но задержка выше.</li>
|
||||
<li><b>tcp</b> — прямой TCP-мультиплексор через порт <b>{{.TunnelPort}}</b> хоста. Минимальная задержка, keep-alive, TCP_NODELAY. Нужно открыть {{.TunnelPort}}/tcp на хосте.</li>
|
||||
<li><b>udp</b> — прямой UDP через порт <b>{{.TunnelPort}}</b> хоста. Нужно открыть {{.TunnelPort}}/udp.</li>
|
||||
</ul>
|
||||
<p class="muted" style="font-size:13px">Для tcp/udp агент держит исходящее соединение к <code>host:8446</code>; несколько клиентов и портов мультиплексируются на нём.</p>
|
||||
<p class="muted" style="font-size:13px">Для tcp/udp агент держит исходящее соединение к <code>host:{{.TunnelPort}}</code>; несколько клиентов и портов мультиплексируются на нём.</p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var notes = {
|
||||
http: 'Трафик идёт через :8445 (long-poll). Порт 8446 не требуется.',
|
||||
tcp: 'Требуется открытый порт 8446/tcp на хосте. Самая низкая задержка.',
|
||||
udp: 'Требуется открытый порт 8446/udp на хосте.'
|
||||
http: 'Трафик идёт через порт панели {{.PanelPort}} (long-poll). Порт {{.TunnelPort}} не требуется.',
|
||||
tcp: 'Требуется открытый порт {{.TunnelPort}}/tcp на хосте. Самая низкая задержка.',
|
||||
udp: 'Требуется открытый порт {{.TunnelPort}}/udp на хосте.'
|
||||
};
|
||||
var sel = document.getElementById('proto'), note = document.getElementById('note');
|
||||
function upd(){ note.textContent = notes[sel.value] || ''; }
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
</header>
|
||||
<div class="wrap">
|
||||
<h1>Настройки</h1>
|
||||
{{if .Error}}<div class="err">{{.Error}}</div>{{end}}
|
||||
|
||||
<div class="card">
|
||||
<h2>Установка на новую машину</h2>
|
||||
@@ -49,6 +50,26 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Прямой туннель (tcp/udp проброс)</h2>
|
||||
{{if not .TunnelDefault}}
|
||||
<p class="muted">Прямой туннель отключён при запуске сервера (пустой <code>-tunnel</code> / <code>LPRA_TUNNEL_ADDR</code>).</p>
|
||||
{{else}}
|
||||
<p class="muted">Адрес, к которому агенты подключаются для проброса в режимах tcp/udp. Агенты забирают его
|
||||
с панели сами — при подключении и при каждом опросе, так что смена применяется без переустановки.
|
||||
Хост можно оставить пустым (тогда берётся хост из адреса панели) или указать IP/другое имя.</p>
|
||||
<form method="post" action="/settings/tunnel" class="row">
|
||||
<input type="hidden" name="csrf" value="{{.CSRF}}">
|
||||
<input type="text" name="tunnel_host" value="{{.TunnelHost}}" placeholder="хост (как у панели)" style="max-width:260px">
|
||||
<input type="number" name="tunnel_port" min="1" max="65535" value="{{if .TunnelCustom}}{{.TunnelPort}}{{end}}" placeholder="{{.TunnelDefault}}" style="max-width:120px">
|
||||
<button type="submit">Сохранить</button>
|
||||
</form>
|
||||
<p class="muted" style="font-size:13px">Сейчас сервер слушает порт <b>{{.TunnelPort}}</b> (tcp и udp). При смене порта сервер
|
||||
сразу начинает слушать новый, агенты переподключаются в течение ~30 секунд, правило ufw переносится.
|
||||
Агенты старше 0.0.3 и агенты с заданными <code>TUNNEL_ADDR</code>/<code>TUNNEL_PORT</code> адрес с панели не берут.</p>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Enroll-секрет</h2>
|
||||
<p class="muted">Общий секрет для регистрации новых агентов.</p>
|
||||
@@ -103,7 +124,8 @@
|
||||
Статус ufw: {{if .UfwActive}}<span style="color:var(--ok)">активен</span>{{else}}<span style="color:var(--danger)">выключен</span>{{end}}
|
||||
· Интеграция: {{if .UfwEnabled}}<span style="color:var(--ok)">включена</span>{{else}}<span class="muted">выключена</span>{{end}}
|
||||
</p>
|
||||
<p class="muted" style="font-size:13px">При создании правила проброса порт открывается в ufw автоматически (для tcp/udp — также порт 8446).</p>
|
||||
<p class="muted" style="font-size:13px">При создании правила проброса порт открывается в ufw автоматически (для tcp/udp — также порт туннеля{{if .TunnelPort}} {{.TunnelPort}}{{end}}); для http-проброса открывается tcp-порт хоста. Порты правил, слушающих только 127.0.0.1, не открываются.</p>
|
||||
{{if .UfwError}}<div class="err">Последняя команда ufw завершилась ошибкой: <code>{{.UfwError}}</code></div>{{end}}
|
||||
<form method="post" action="/settings/ufw/toggle" style="display:inline">
|
||||
<input type="hidden" name="csrf" value="{{.CSRF}}">
|
||||
<input type="hidden" name="enabled" value="{{if .UfwEnabled}}0{{else}}1{{end}}">
|
||||
|
||||
Reference in new issue
Block a user