feat: publish WARP Web UI with install scripts and docs

Sanitized panel from production: env-based auth, interactive install
prompts for SOCKS/Web UI ports, MIT license, EN/RU README.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Андрей Бобырев
2026-05-26 22:50:57 +03:00
commit 4f4e85f810
11 changed files with 1620 additions and 0 deletions

22
.env.example Normal file
View File

@@ -0,0 +1,22 @@
# Copy to /etc/default/warp-webui (install.sh creates this automatically)
WARP_WEBUI_USER=warpadmin
WARP_WEBUI_PASS=change-me-to-a-strong-password
WARP_WEBUI_HOST=0.0.0.0
WARP_WEBUI_PORT=3030
# SOCKS port for warp-cli proxy mode (install script asks for this)
WARP_PROXY_PORT=40000
# Shown in client preset JSON (your server's public IP or hostname)
WARP_PUBLIC_HOST=
# Optional paths (defaults match install.sh layout)
# WARP_INSTALL_SCRIPT=/opt/warp-webui/scripts/warp-install-cf.sh
# WARP_UNINSTALL_SCRIPT=/opt/warp-webui/scripts/warp-uninstall-cf.sh
# XUI_CONFIG=/usr/local/x-ui/bin/config.json
# AMNEZIA_XRAY_CONTAINER=amnezia-xray
# AMNEZIA_XRAY_CONFIG=/opt/amnezia/xray/server.json
# WARP_CLIENT_ALIASES=/etc/warp-webui/client-aliases.json
# WARP_SOCKS_BRIDGE_HOST=172.17.0.1
# WARP_SOCKS_BRIDGE_PORT=11025

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
__pycache__/
*.py[cod]
*.bak*
_src/
.env
*.log
.DS_Store

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Andrey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

108
README.md Normal file
View File

@@ -0,0 +1,108 @@
# WARP Web UI
Browser-based control panel for **Cloudflare WARP** on Linux: connect/disconnect, WARP+ license, SOCKS proxy port, and optional presets for **3x-ui** and **Amnezia Xray**.
## Features
- **WARP control**: Connect, disconnect, restart `warp-svc`, view status and logs
- **Account**: Registration info, apply WARP+ license key
- **Install / uninstall** `cloudflare-warp` from the UI (Debian/Ubuntu apt repo)
- **SOCKS proxy**: Set `warp-cli` proxy port (e.g. `40000` or `1024`)
- **3x-ui preset**: Add `warp-socks` outbound → `127.0.0.1:PORT` and `geosite:google` routing rule
- **Amnezia preset**: Docker bridge `172.17.0.1:11025` → host SOCKS, per-client WARP routing with friendly names
## Requirements
- Linux (Debian/Ubuntu recommended)
- `python3` (stdlib only — no pip packages)
- `systemd`
- Optional: `cloudflare-warp` package (can be installed via UI or `scripts/warp-install-cf.sh`)
- Optional: `docker`, `socat`, `x-ui` / Amnezia for integration presets
## Quick start
### One-line install
```bash
curl -fsSL https://raw.githubusercontent.com/andrey271192/WARP-Web-UI/main/install.sh | sudo bash
```
The installer **asks interactively**:
| Prompt | Default | Notes |
|--------|---------|--------|
| SOCKS proxy port | `40000` | Also `1024` is common for official `cloudflare-warp` |
| Web UI port | `3030` | Open in firewall if needed |
| Admin username | `warpadmin` | HTTP Basic Auth |
| Admin password | *(required, min 8 chars)* | Stored in `/etc/default/warp-webui` (`chmod 600`) |
### Clone and install
```bash
git clone https://github.com/andrey271192/WARP-Web-UI.git
cd WARP-Web-UI
sudo bash install.sh
```
Open `http://YOUR_SERVER:3030/` (use the port you chose). Log in with the credentials you set.
If WARP is not installed yet, click **Install WARP** in the UI (or run `scripts/warp-install-cf.sh` with `WARP_PROXY_PORT` set).
### Uninstall
```bash
curl -fsSL https://raw.githubusercontent.com/andrey271192/WARP-Web-UI/main/uninstall.sh | sudo bash
```
Or from a clone: `sudo bash uninstall.sh` — stops the service, optionally removes files, config, and the `cloudflare-warp` package.
## Repository layout
```
app.py # Web UI + API (Python http.server)
scripts/warp-install-cf.sh # Install cloudflare-warp from Cloudflare apt repo
scripts/warp-uninstall-cf.sh # Remove cloudflare-warp package
systemd/warp-webui.service # systemd unit template
install.sh / uninstall.sh # One-command setup / teardown
.env.example # Environment variable reference
```
After install, files live under `/opt/warp-webui/`, config in `/etc/default/warp-webui`.
## Configuration
See [`.env.example`](.env.example). Main variables:
- `WARP_WEBUI_USER`, `WARP_WEBUI_PASS` — Basic Auth
- `WARP_WEBUI_PORT` — HTTP port (default `3030`)
- `WARP_PROXY_PORT` — SOCKS port used at install and for `warp-install` from UI
- `WARP_PUBLIC_HOST` — Public IP/hostname for client preset hints
Client display names for Amnezia: `/etc/warp-webui/client-aliases.json`
## Security notes
- **HTTP Basic Auth only** — credentials are sent on every request. Prefer **HTTPS** (reverse proxy: nginx/Caddy + TLS) for production.
- **Firewall**: Expose only the Web UI port to trusted IPs (`ufw allow from TRUSTED to any port 3030`).
- **Root service**: The panel runs as root to manage `warp-cli`, systemd, and Docker. Do not expose it to the public internet without protection.
- **Secrets**: Never commit `/etc/default/warp-webui`. Rotate the admin password after install.
- WARP+ license keys are entered in the UI and passed to `warp-cli` — they are not stored in this repo.
## API (authenticated)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/` | HTML UI |
| GET | `/status`, `/registration`, `/proxy`, `/logs` | Status |
| POST | `/connect`, `/disconnect`, `/restart` | WARP control |
| POST | `/warp-install`, `/warp-uninstall` | Package install/remove |
| POST | `/proxy-port`, `/license` | SOCKS port, WARP+ key |
| POST | `/xui-preset`, `/amnezia-preset`, `/amnezia-routing` | Integration presets |
## License
MIT — see [LICENSE](LICENSE).
## Russian documentation
See [README.ru.md](README.ru.md).

83
README.ru.md Normal file
View File

@@ -0,0 +1,83 @@
# WARP Web UI
Веб-панель для управления **Cloudflare WARP** на Linux: подключение/отключение, ключ WARP+, порт SOCKS-прокси и пресеты для **3x-ui** и **Amnezia Xray**.
## Возможности
- **WARP**: Connect / Disconnect, перезапуск `warp-svc`, статус и логи
- **Аккаунт**: тип регистрации (Free / WARP+), применение лицензионного ключа
- **Установка и удаление** пакета `cloudflare-warp` из браузера
- **SOCKS**: смена порта `warp-cli proxy` (например `40000` или `1024`)
- **3x-ui**: outbound `warp-socks``127.0.0.1:ПОРТ`, маршрут `geosite:google`
- **Amnezia**: мост Docker `172.17.0.1:11025` → SOCKS на хосте, WARP только для выбранных клиентов, понятные имена
## Требования
- Linux (рекомендуется Debian/Ubuntu)
- `python3` (только стандартная библиотека)
- `systemd`
- По желанию: `cloudflare-warp` (ставится из UI или `scripts/warp-install-cf.sh`)
- Для пресетов: `docker`, `socat`, `x-ui` / Amnezia
## Быстрый старт
### Установка одной командой
```bash
curl -fsSL https://raw.githubusercontent.com/andrey271192/WARP-Web-UI/main/install.sh | sudo bash
```
Скрипт **спрашивает**:
| Вопрос | По умолчанию | Пояснение |
|--------|--------------|-----------|
| Порт SOCKS | `40000` | Часто также `1024` у официального пакета |
| Порт веб-UI | `3030` | Откройте в firewall при необходимости |
| Логин админа | `warpadmin` | HTTP Basic Auth |
| Пароль админа | *(обязательно, ≥ 8 символов)* | Файл `/etc/default/warp-webui` |
### Клонирование
```bash
git clone https://github.com/andrey271192/WARP-Web-UI.git
cd WARP-Web-UI
sudo bash install.sh
```
Откройте `http://ВАШ_СЕРВЕР:3030/`. Если WARP ещё не установлен — кнопка **Install WARP** в интерфейсе.
### Удаление
```bash
curl -fsSL https://raw.githubusercontent.com/andrey271192/WARP-Web-UI/main/uninstall.sh | sudo bash
```
Или `sudo bash uninstall.sh` из клонированного репозитория. Можно удалить только панель или также пакет `cloudflare-warp` (подтверждение в конце).
## Структура репозитория
- `app.py` — веб-интерфейс и API
- `scripts/warp-install-cf.sh`, `warp-uninstall-cf.sh` — установка/удаление WARP
- `systemd/warp-webui.service` — шаблон unit
- `install.sh`, `uninstall.sh` — установка и снятие «в одну кнопку»
После установки: `/opt/warp-webui/`, настройки `/etc/default/warp-webui`.
## Настройка
См. [`.env.example`](.env.example). Имена клиентов Amnezia: `/etc/warp-webui/client-aliases.json`.
## Безопасность
- Только **Basic Auth по HTTP** — для продакшена используйте **HTTPS** (nginx/Caddy).
- **Firewall**: открывайте порт панели только для доверенных IP.
- Сервис работает от **root** (нужен для `warp-cli`, systemd, Docker). Не выставляйте панель в открытый интернет без защиты.
- Не публикуйте `/etc/default/warp-webui` и смените пароль после установки.
## English documentation
See [README.md](README.md).
## Лицензия
MIT — [LICENSE](LICENSE).

1152
app.py Executable file

File diff suppressed because it is too large Load Diff

114
install.sh Executable file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/env bash
# WARP Web UI — one-command installer (run as root on Debian/Ubuntu)
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${WARP_WEBUI_INSTALL_DIR:-/opt/warp-webui}"
ENV_FILE="/etc/default/warp-webui"
SERVICE_NAME="warp-webui"
UNIT_DST="/etc/systemd/system/${SERVICE_NAME}.service"
ALIASES_DIR="/etc/warp-webui"
LOG_DIR="/var/log/warp-webui"
if [[ "${EUID:-0}" -ne 0 ]]; then
echo "Run as root: sudo bash install.sh"
exit 1
fi
echo "=== WARP Web UI installer ==="
echo
prompt() {
local var_name="$1" prompt_text="$2" default_val="$3"
local input
read -rp "${prompt_text} [${default_val}]: " input
if [[ -z "${input}" ]]; then
printf -v "${var_name}" '%s' "${default_val}"
else
printf -v "${var_name}" '%s' "${input}"
fi
}
echo "SOCKS port: local port for warp-cli proxy mode (used by x-ui / Amnezia presets)."
echo "Common choices: 40000 (warp-offline style) or 1024 (cloudflare-warp default)."
prompt WARP_PROXY_PORT "SOCKS proxy port" "40000"
if ! [[ "${WARP_PROXY_PORT}" =~ ^[0-9]+$ ]] || (( WARP_PROXY_PORT < 1 || WARP_PROXY_PORT > 65535 )); then
echo "Invalid SOCKS port: ${WARP_PROXY_PORT}"
exit 1
fi
prompt WARP_WEBUI_PORT "Web UI HTTP port" "3030"
if ! [[ "${WARP_WEBUI_PORT}" =~ ^[0-9]+$ ]] || (( WARP_WEBUI_PORT < 1 || WARP_WEBUI_PORT > 65535 )); then
echo "Invalid Web UI port: ${WARP_WEBUI_PORT}"
exit 1
fi
prompt WARP_WEBUI_USER "Web UI admin username" "warpadmin"
while true; do
read -rsp "Web UI admin password (min 8 chars): " WARP_WEBUI_PASS
echo
if [[ "${#WARP_WEBUI_PASS}" -ge 8 ]]; then
break
fi
echo "Password too short. Use at least 8 characters."
done
# Detect public host for client preset hints (optional)
WARP_PUBLIC_HOST="${WARP_PUBLIC_HOST:-}"
if [[ -z "${WARP_PUBLIC_HOST}" ]]; then
WARP_PUBLIC_HOST="$(curl -fsS --max-time 3 https://api.ipify.org 2>/dev/null || true)"
fi
if [[ -z "${WARP_PUBLIC_HOST}" ]]; then
WARP_PUBLIC_HOST="$(hostname -f 2>/dev/null || hostname)"
fi
echo
echo "Installing to ${INSTALL_DIR} ..."
mkdir -p "${INSTALL_DIR}/scripts" "${ALIASES_DIR}" "${LOG_DIR}"
install -m 0755 "${REPO_DIR}/app.py" "${INSTALL_DIR}/app.py"
install -m 0755 "${REPO_DIR}/scripts/warp-install-cf.sh" "${INSTALL_DIR}/scripts/warp-install-cf.sh"
install -m 0755 "${REPO_DIR}/scripts/warp-uninstall-cf.sh" "${INSTALL_DIR}/scripts/warp-uninstall-cf.sh"
umask 077
cat > "${ENV_FILE}" <<EOF
WARP_WEBUI_USER=${WARP_WEBUI_USER}
WARP_WEBUI_PASS=${WARP_WEBUI_PASS}
WARP_WEBUI_HOST=0.0.0.0
WARP_WEBUI_PORT=${WARP_WEBUI_PORT}
WARP_PROXY_PORT=${WARP_PROXY_PORT}
WARP_PUBLIC_HOST=${WARP_PUBLIC_HOST}
WARP_INSTALL_SCRIPT=${INSTALL_DIR}/scripts/warp-install-cf.sh
WARP_UNINSTALL_SCRIPT=${INSTALL_DIR}/scripts/warp-uninstall-cf.sh
WARP_CLIENT_ALIASES=${ALIASES_DIR}/client-aliases.json
EOF
chmod 600 "${ENV_FILE}"
if [[ ! -f "${ALIASES_DIR}/client-aliases.json" ]]; then
echo '{}' > "${ALIASES_DIR}/client-aliases.json"
chmod 600 "${ALIASES_DIR}/client-aliases.json"
fi
sed \
-e "s|@INSTALL_DIR@|${INSTALL_DIR}|g" \
-e "s|@ENV_FILE@|${ENV_FILE}|g" \
"${REPO_DIR}/systemd/warp-webui.service" > "${UNIT_DST}"
systemctl daemon-reload
systemctl enable "${SERVICE_NAME}.service"
systemctl restart "${SERVICE_NAME}.service"
# Optional: open firewall for Web UI port
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -qi active; then
ufw allow "${WARP_WEBUI_PORT}/tcp" comment 'warp-webui' || true
fi
echo
echo "=== Installed ==="
echo "Web UI: http://${WARP_PUBLIC_HOST}:${WARP_WEBUI_PORT}/"
echo "Login: ${WARP_WEBUI_USER} / (password you entered)"
echo "SOCKS: 127.0.0.1:${WARP_PROXY_PORT} (after WARP is installed and proxy mode enabled)"
echo "Env: ${ENV_FILE}"
echo
echo "Next: open the Web UI and use 'Install WARP' if cloudflare-warp is not installed yet."
echo "Set proxy port in the UI or re-run install with a different WARP_PROXY_PORT in ${ENV_FILE}."

24
scripts/warp-install-cf.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
if command -v warp-cli >/dev/null 2>&1; then
echo "cloudflare-warp already installed: $(warp-cli --version 2>/dev/null || true)"
systemctl enable --now warp-svc 2>/dev/null || true
warp-cli --accept-tos registration show 2>/dev/null || warp-cli --accept-tos registration new 2>/dev/null || true
warp-cli --accept-tos mode proxy 2>/dev/null || true
warp-cli --accept-tos proxy port "${WARP_PROXY_PORT:-1024}" 2>/dev/null || true
exit 0
fi
apt-get update -qq
apt-get install -y -qq curl gnupg lsb-release ca-certificates
mkdir -p /usr/share/keyrings
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/cloudflare-client.list
apt-get update -qq
apt-get install -y -qq cloudflare-warp
systemctl enable --now warp-svc
sleep 2
warp-cli --accept-tos registration new || true
warp-cli --accept-tos mode proxy
warp-cli --accept-tos proxy port "${WARP_PROXY_PORT:-1024}"
echo "WARP installed."

10
scripts/warp-uninstall-cf.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
warp-cli --accept-tos disconnect 2>/dev/null || true
systemctl stop warp-svc 2>/dev/null || true
systemctl disable warp-svc 2>/dev/null || true
if dpkg -l cloudflare-warp >/dev/null 2>&1; then
apt-get remove -y -qq cloudflare-warp || apt-get purge -y -qq cloudflare-warp
fi
echo "WARP package removed (config may remain under /var/lib/cloudflare-warp)."

View File

@@ -0,0 +1,20 @@
[Unit]
Description=WARP Web UI Controller
After=network-online.target warp-svc.service
Wants=network-online.target
[Service]
Type=simple
EnvironmentFile=@ENV_FILE@
ExecStart=/usr/bin/python3 @INSTALL_DIR@/app.py
Restart=always
RestartSec=2
User=root
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/run /var/log /etc/default/warp-webui /etc/warp-webui /var/backups/warp-webui
[Install]
WantedBy=multi-user.target

59
uninstall.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# WARP Web UI — one-command uninstaller
set -euo pipefail
INSTALL_DIR="${WARP_WEBUI_INSTALL_DIR:-/opt/warp-webui}"
ENV_FILE="/etc/default/warp-webui"
SERVICE_NAME="warp-webui"
UNIT="/etc/systemd/system/${SERVICE_NAME}.service"
BRIDGE_UNIT="/etc/systemd/system/warp-socks-bridge.service"
if [[ "${EUID:-0}" -ne 0 ]]; then
echo "Run as root: sudo bash uninstall.sh"
exit 1
fi
echo "=== WARP Web UI uninstaller ==="
if systemctl is-active --quiet "${SERVICE_NAME}.service" 2>/dev/null; then
systemctl stop "${SERVICE_NAME}.service"
fi
systemctl disable "${SERVICE_NAME}.service" 2>/dev/null || true
if [[ -f "${UNIT}" ]]; then
rm -f "${UNIT}"
fi
if systemctl is-active --quiet warp-socks-bridge.service 2>/dev/null; then
systemctl stop warp-socks-bridge.service 2>/dev/null || true
fi
systemctl disable warp-socks-bridge.service 2>/dev/null || true
[[ -f "${BRIDGE_UNIT}" ]] && rm -f "${BRIDGE_UNIT}"
systemctl daemon-reload
read -rp "Remove application files in ${INSTALL_DIR}? [y/N]: " REMOVE_APP
if [[ "${REMOVE_APP,,}" == "y" || "${REMOVE_APP,,}" == "yes" ]]; then
rm -rf "${INSTALL_DIR}"
fi
read -rp "Remove config ${ENV_FILE} and /etc/warp-webui/? [y/N]: " REMOVE_CFG
if [[ "${REMOVE_CFG,,}" == "y" || "${REMOVE_CFG,,}" == "yes" ]]; then
rm -f "${ENV_FILE}"
rm -rf /etc/warp-webui
fi
read -rp "Remove cloudflare-warp package (apt remove)? [y/N]: " REMOVE_WARP
if [[ "${REMOVE_WARP,,}" == "y" || "${REMOVE_WARP,,}" == "yes" ]]; then
if [[ -x "${INSTALL_DIR}/scripts/warp-uninstall-cf.sh" ]]; then
WARP_PROXY_PORT=1024 bash "${INSTALL_DIR}/scripts/warp-uninstall-cf.sh"
elif command -v warp-cli >/dev/null 2>&1; then
warp-cli --accept-tos disconnect 2>/dev/null || true
systemctl stop warp-svc 2>/dev/null || true
apt-get remove -y -qq cloudflare-warp 2>/dev/null || apt-get purge -y -qq cloudflare-warp 2>/dev/null || true
else
echo "cloudflare-warp not found; skipped."
fi
fi
echo "WARP Web UI uninstalled."