Initial vibeproxy implementation
Self-contained HTTP/HTTPS/TCP/UDP reverse proxy manager written in Go, with SQLite storage, a Bootstrap 5 admin UI (Go templates, no JS framework), and a REST API under /api/v1. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QTXFrNP1imCW7jtfL5SZrw
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
-- vibeproxy initial schema
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
must_change_pw INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL UNIQUE,
|
||||
prefix TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
last_used_at TEXT,
|
||||
revoked_at TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS certificates (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL, -- letsencrypt|custom
|
||||
domains TEXT NOT NULL, -- json array
|
||||
challenge_type TEXT, -- http-01|dns-01
|
||||
dns_provider TEXT,
|
||||
cert_path TEXT,
|
||||
key_path TEXT,
|
||||
not_before TEXT,
|
||||
not_after TEXT,
|
||||
last_renewed_at TEXT,
|
||||
last_error TEXT,
|
||||
auto_renew INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS access_lists (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
default_allow INTEGER NOT NULL DEFAULT 0,
|
||||
comments TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS access_rules (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
access_list_id INTEGER NOT NULL REFERENCES access_lists(id) ON DELETE CASCADE,
|
||||
action TEXT NOT NULL, -- allow|deny
|
||||
cidr TEXT NOT NULL,
|
||||
priority INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_access_rules_list ON access_rules(access_list_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS access_list_users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
access_list_id INTEGER NOT NULL REFERENCES access_lists(id) ON DELETE CASCADE,
|
||||
username TEXT NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
UNIQUE(access_list_id, username)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS proxy_hosts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL DEFAULT 'proxy', -- proxy|redirect
|
||||
listen_addr TEXT NOT NULL DEFAULT '',
|
||||
forward_scheme TEXT NOT NULL DEFAULT 'http',
|
||||
preserve_host_header INTEGER NOT NULL DEFAULT 0,
|
||||
websocket_support INTEGER NOT NULL DEFAULT 1,
|
||||
force_https INTEGER NOT NULL DEFAULT 0,
|
||||
hsts_enabled INTEGER NOT NULL DEFAULT 0,
|
||||
certificate_id INTEGER REFERENCES certificates(id) ON DELETE SET NULL,
|
||||
access_list_id INTEGER REFERENCES access_lists(id) ON DELETE SET NULL,
|
||||
connect_timeout_ms INTEGER NOT NULL DEFAULT 5000,
|
||||
read_timeout_ms INTEGER NOT NULL DEFAULT 60000,
|
||||
write_timeout_ms INTEGER NOT NULL DEFAULT 60000,
|
||||
idle_timeout_ms INTEGER NOT NULL DEFAULT 120000,
|
||||
load_balancing_method TEXT NOT NULL DEFAULT 'round_robin',
|
||||
redirect_target_url TEXT NOT NULL DEFAULT '',
|
||||
redirect_code INTEGER NOT NULL DEFAULT 301,
|
||||
redirect_preserve_path INTEGER NOT NULL DEFAULT 1,
|
||||
redirect_preserve_qs INTEGER NOT NULL DEFAULT 1,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
comments TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS proxy_host_domains (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
proxy_host_id INTEGER NOT NULL REFERENCES proxy_hosts(id) ON DELETE CASCADE,
|
||||
domain TEXT NOT NULL COLLATE NOCASE,
|
||||
UNIQUE(domain)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_phd_host ON proxy_host_domains(proxy_host_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_phd_domain ON proxy_host_domains(domain);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS backends (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
proxy_host_id INTEGER NOT NULL REFERENCES proxy_hosts(id) ON DELETE CASCADE,
|
||||
host TEXT NOT NULL,
|
||||
port INTEGER NOT NULL,
|
||||
weight INTEGER NOT NULL DEFAULT 1,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
health_check_type TEXT NOT NULL DEFAULT 'tcp', -- tcp|http|none
|
||||
health_check_path TEXT NOT NULL DEFAULT '/',
|
||||
health_check_status INTEGER NOT NULL DEFAULT 200,
|
||||
interval_seconds INTEGER NOT NULL DEFAULT 10,
|
||||
failure_threshold INTEGER NOT NULL DEFAULT 3,
|
||||
recovery_threshold INTEGER NOT NULL DEFAULT 2
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_backends_host ON backends(proxy_host_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS custom_headers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
proxy_host_id INTEGER NOT NULL REFERENCES proxy_hosts(id) ON DELETE CASCADE,
|
||||
direction TEXT NOT NULL, -- request|response
|
||||
action TEXT NOT NULL, -- set|remove
|
||||
name TEXT NOT NULL,
|
||||
value TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_headers_host ON custom_headers(proxy_host_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS streams (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
protocol TEXT NOT NULL, -- tcp|udp
|
||||
listen_ip TEXT NOT NULL DEFAULT '',
|
||||
listen_port INTEGER NOT NULL,
|
||||
destination_host TEXT NOT NULL,
|
||||
destination_port INTEGER NOT NULL,
|
||||
connect_timeout_ms INTEGER NOT NULL DEFAULT 5000,
|
||||
idle_timeout_ms INTEGER NOT NULL DEFAULT 300000,
|
||||
proxy_protocol INTEGER NOT NULL DEFAULT 0,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
comments TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
UNIQUE(protocol, listen_ip, listen_port)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS request_logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
timestamp TEXT NOT NULL,
|
||||
proxy_host_id INTEGER,
|
||||
proxy_host_name TEXT NOT NULL DEFAULT '',
|
||||
client_ip TEXT NOT NULL DEFAULT '',
|
||||
method TEXT NOT NULL DEFAULT '',
|
||||
host TEXT NOT NULL DEFAULT '',
|
||||
path TEXT NOT NULL DEFAULT '',
|
||||
status INTEGER NOT NULL DEFAULT 0,
|
||||
response_size INTEGER NOT NULL DEFAULT 0,
|
||||
backend TEXT NOT NULL DEFAULT '',
|
||||
response_time_ms INTEGER NOT NULL DEFAULT 0,
|
||||
user_agent TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_logs_ts ON request_logs(timestamp);
|
||||
CREATE INDEX IF NOT EXISTS idx_logs_host ON request_logs(proxy_host_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_logs_status ON request_logs(status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
timestamp TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
||||
actor TEXT NOT NULL DEFAULT '',
|
||||
action TEXT NOT NULL,
|
||||
target TEXT NOT NULL DEFAULT '',
|
||||
details TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_ts ON audit_logs(timestamp);
|
||||
Reference in New Issue
Block a user