81 lines
5.6 KiB
Markdown
81 lines
5.6 KiB
Markdown
# LPRA - LongPolling Remote Access
|
|
|
|
Лёгкий self-hosted сервис для доступа к Linux-машинам **без белого IP** (за NAT).
|
|
Агент на клиенте сам исходяще подключается к серверу по HTTP long-polling; админ
|
|
в веб-панели видит список машин и открывает по каждой **терминал в браузере** (по умолчанию от root, пользователя можно сменить).
|
|
|
|
```
|
|
браузер ──WS──> [nginx :8445 TLS] ──> [Go server 127.0.0.1:8091] <──long-poll── агент (root, за NAT)
|
|
│
|
|
SQLite
|
|
```
|
|
|
|
## Компоненты
|
|
- **Сервер** (`cmd/server`) - админ-панель + точка встречи для агентов. За nginx (TLS).
|
|
- **Агент** (`cmd/agent`) - Linux-бинарь, systemd-сервис от root, PTY по запросу.
|
|
- **install.sh** - интерактивный установщик, отдаётся сервером как статика.
|
|
|
|
## Сборка
|
|
```sh
|
|
./build.sh
|
|
```
|
|
Получаются `bin/lpra-server` и `dist/agent-linux-{amd64,arm64}`.
|
|
|
|
## Запуск сервера
|
|
```sh
|
|
./bin/lpra-server -addr 127.0.0.1:8091 -dist ./dist -db ./lpra.db
|
|
```
|
|
Поставьте перед ним nginx по `deploy/nginx.conf.example` (TLS, long-poll/WS).
|
|
Локально без TLS можно добавить `-insecure-cookies`.
|
|
|
|
Первый запуск: откройте `/setup` - мастер создаст администратора. Дальше `/settings`:
|
|
адрес хоста (по умолчанию `https://localhost:8445`), enroll-секрет и готовая
|
|
команда установки.
|
|
|
|
## Установка агента на клиент
|
|
Одной командой (под root):
|
|
```sh
|
|
curl -fsSL https://localhost:8445/install.sh | sudo HOST=https://localhost:8445 ENROLL_SECRET=<секрет> sh
|
|
```
|
|
Или интерактивно (спросит секрет, а если агент уже стоит - предложит удалить):
|
|
```sh
|
|
curl -fsSL https://localhost:8445/install.sh | sudo sh
|
|
```
|
|
|
|
## Проброс портов и прямой туннель
|
|
Правила проброса создаются на странице машины. Режим `http` идёт через адрес панели (long-poll),
|
|
режимы `tcp`/`udp` - через прямой туннель: агент держит исходящее соединение к порту туннеля хоста
|
|
(флаг `-tunnel` / `LPRA_TUNNEL_ADDR`).
|
|
|
|
Порт туннеля и хост, к которому для него подключаются агенты (например, IP вместо домена панели),
|
|
меняются в `/settings` → «Прямой туннель». Агенты забирают адрес с панели сами - при подключении и
|
|
при каждом опросе, переустановка не нужна. Локальные `TUNNEL_ADDR` / `TUNNEL_PORT` в окружении агента
|
|
имеют приоритет над настройкой панели (`TUNNEL_ADDR=off` отключает туннель).
|
|
|
|
Если на хосте активен ufw и сервер запущен от root, панель сама открывает порт хоста правила
|
|
(tcp для `http`/`tcp`, udp для `udp`) и порт туннеля для прямых режимов, а при удалении правила - закрывает.
|
|
При `ProtectSystem=strict` в systemd-юните ufw нужны права на запись: `ReadWritePaths=/etc/ufw /run`.
|
|
|
|
## Версия
|
|
Версия задаётся в одном месте - `VERSION.txt`; файл вшивается в сервер и агент при сборке.
|
|
|
|
## Пользователь терминала
|
|
По умолчанию терминал открывается от пользователя, под которым запущен агент (на Linux - root).
|
|
В окне «Изменить машину» можно выбрать другого пользователя машины или создать нового
|
|
(имя, пароль, опционально - добавить в sudo). Смена и создание работают, только если агент запущен от root.
|
|
Файловый менеджер по-прежнему работает от пользователя агента.
|
|
|
|
## Безопасность
|
|
- Пароли админов - bcrypt; сессии в HttpOnly/Secure/SameSite куках; CSRF на формах; rate-limit логина.
|
|
- Агенты: общий enroll-секрет → индивидуальный токен (хранится хешем, сверка constant-time).
|
|
- Открытие терминала пишется в таблицу `audit` (терминал даёт root-доступ), как и смена/создание пользователя.
|
|
|
|
## Скриншоты
|
|
<img width="1256" height="709" alt="image" src="https://github.com/user-attachments/assets/5f0b30f1-d5e3-4b62-817e-4041641df6e3" />
|
|
|
|
<img width="1254" height="532" alt="image" src="https://github.com/user-attachments/assets/0207a7f0-2b59-40ee-abd1-d8673059cc24" />
|
|
|
|
<img width="1255" height="526" alt="image" src="https://github.com/user-attachments/assets/4dcbe907-33f5-493e-a56f-01cd8bf0fea1" />
|
|
|
|
<img width="1260" height="654" alt="image" src="https://github.com/user-attachments/assets/fdf59733-8e5d-46e3-b232-235ddfe1be73" />
|