diff --git a/README.md b/README.md index 52cdeb7..4bb5540 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ - Быстро развернуть WireGuard-сервер (`wg-quick@wg0`) с автозапуском через `systemd`. - Включить IP forwarding и NAT для выхода клиентов в интернет через сервер. -- Установить встроенный GUI для управления peer'ами и QR (`wg-admin-gui`) с хранением данных в PostgreSQL. +- Установить встроенный GUI для управления peer'ами и QR (`wg-admin-gui`) с хранением данных в SQLite. - Автоматизировать добавление клиента с клиентской машины через SSH на сервер. - Поддержать 2 режима маршрутизации клиента: - полный туннель (весь трафик через VPN) @@ -36,7 +36,7 @@ - Сервер разворачивается нативно на `wg-quick` + `systemd` (стабильность после reboot). - GUI (`wg-admin-gui`) работает поверх того же `/etc/wireguard`, где лежит серверный конфиг. -- Метаданные GUI хранятся в PostgreSQL. +- Метаданные GUI хранятся в SQLite. - На сервере ставится `wg-syncconf@wg0.path`: при изменении `/etc/wireguard/wg0.conf` конфиг автоматически применяется в живой интерфейс `wg0`. - Клиентский скрипт: 1. генерирует ключи локально, @@ -60,7 +60,6 @@ - `wireguard`, `wireguard-tools` - `iproute2`, `iptables` - `curl`, `ca-certificates`, `openssl`, `qrencode` -- `docker.io` и один из пакетов: `docker-compose-plugin` или `docker-compose` (для PostgreSQL контейнера GUI) - `python3`, `python3-venv`, `python3-pip` (для `wg-admin-gui`) ### Клиент @@ -79,7 +78,7 @@ sudo bash server/install_server.sh ``` -Важно: серверный установщик теперь всегда выполняет полный reset прошлого состояния (`/etc/wireguard` + данные GUI/PostgreSQL) и поднимает всё заново. +Важно: серверный установщик теперь всегда выполняет полный reset прошлого состояния (`/etc/wireguard` + данные GUI/SQLite) и поднимает всё заново. ### Запуск сервера одной командой (без `git clone`) @@ -234,7 +233,7 @@ http://203.0.113.10:5000 1. Откройте GUI по ссылке из итоговой сводки установки. 2. Перейдите в раздел добавления peer. 3. Создайте клиента. -4. Используйте показанный QR. +4. Используйте показанный QR или скачайте готовый `.conf`. 5. На iPhone: WireGuard → `Add Tunnel` → `Create from QR code` и отсканируйте код. ## Взаимодействие клиента с сервером @@ -309,7 +308,6 @@ ls -l /usr/local/sbin/wg-peerctl 4. GUI недоступен: ```bash sudo systemctl status wg-admin-gui --no-pager -sudo docker ps | grep wg-admin-postgres sudo ss -tulpn | grep 5000 ``` diff --git a/gui/app.py b/gui/app.py index 20fd8bd..9670836 100644 --- a/gui/app.py +++ b/gui/app.py @@ -2,18 +2,17 @@ import base64 import io import os +import sqlite3 import subprocess from datetime import datetime import qrcode from flask import Flask, redirect, render_template, request, url_for, flash, Response -from psycopg import connect -from psycopg.rows import dict_row app = Flask(__name__) app.secret_key = os.environ.get("APP_SECRET", "dev-secret") -DB_DSN = os.environ.get("DB_DSN", "postgresql://wgadmin:wgadmin@127.0.0.1:5432/wgadmin") +DB_PATH = os.environ.get("DB_PATH", "/opt/wg-admin-gui/data/wgadmin.db") WG_INTERFACE = os.environ.get("WG_INTERFACE", "wg0") WG_META_FILE = os.environ.get("WG_META_FILE", "/etc/wireguard/wg-meta.env") ADMIN_USER = os.environ.get("ADMIN_USER", "admin") @@ -21,23 +20,25 @@ ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "") def db_conn(): - return connect(DB_DSN, row_factory=dict_row) + os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) + conn = sqlite3.connect(DB_PATH) + conn.row_factory = sqlite3.Row + return conn def ensure_schema(): - with db_conn() as conn, conn.cursor() as cur: - cur.execute( - """ + with db_conn() as conn: + cur = conn.cursor() + cur.execute(""" CREATE TABLE IF NOT EXISTS peers ( - id BIGSERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, public_key TEXT UNIQUE NOT NULL, client_address TEXT, advertised_routes TEXT, - created_at TIMESTAMPTZ NOT NULL DEFAULT now() + created_at TEXT NOT NULL DEFAULT (datetime('now')) ); - """ - ) + """) conn.commit() @@ -150,9 +151,10 @@ def _schema(): def index(): meta = load_meta() runtime = {p["public_key"]: p for p in wg_dump()} - with db_conn() as conn, conn.cursor() as cur: + with db_conn() as conn: + cur = conn.cursor() cur.execute("SELECT * FROM peers ORDER BY id DESC") - db_peers = cur.fetchall() + db_peers = [dict(r) for r in cur.fetchall()] items = [] seen = set() @@ -260,16 +262,14 @@ def new_peer(): client_conf = "\n".join(conf_lines) qr_b64 = to_png_b64(client_conf) - with db_conn() as conn, conn.cursor() as cur: - cur.execute( - """ + with db_conn() as conn: + cur = conn.cursor() + cur.execute(""" INSERT INTO peers(name, public_key, client_address, advertised_routes) - VALUES (%s,%s,%s,%s) + VALUES (?,?,?,?) ON CONFLICT(public_key) DO UPDATE SET name=excluded.name, client_address=excluded.client_address, advertised_routes=excluded.advertised_routes - """, - (name, client_pub, client_addr, routes), - ) + """, (name, client_pub, client_addr, routes)) conn.commit() return render_template( diff --git a/gui/requirements.txt b/gui/requirements.txt index d053fba..65efa38 100644 --- a/gui/requirements.txt +++ b/gui/requirements.txt @@ -1,4 +1,3 @@ Flask==3.0.3 -psycopg[binary]==3.2.1 qrcode==7.4.2 gunicorn==23.0.0 diff --git a/gui/templates/peer_created.html b/gui/templates/peer_created.html index df562f2..4f5576b 100644 --- a/gui/templates/peer_created.html +++ b/gui/templates/peer_created.html @@ -2,6 +2,7 @@ {% block content %}
PublicKey: {{ public_key }}
+