chore: 初始提交 Fonu 1.0.2
- 公网反代:Nginx 状态卡片(版本 / 运行状态 / 配置校验 / 端口监听) - 部署设置第一、二梯队(HTTPS 开关、安全头、限流、连接数、仅中国大陆 IP) - 隧道检测兼容 frps v0.68 / v0.71(V2 与旧版端点) - 恢复被清空的 internal/frp/store.go、internal/api/ddns_handler.go、web/src/views/DdnsView.vue
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INTEGER PRIMARY KEY,
|
||||
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS admins (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
admin_id INTEGER NOT NULL REFERENCES admins(id) ON DELETE CASCADE,
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS proxy_rules (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
domain TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
||||
upstream TEXT NOT NULL,
|
||||
https_enabled INTEGER NOT NULL DEFAULT 1 CHECK (https_enabled IN (0, 1)),
|
||||
http_redirect INTEGER NOT NULL DEFAULT 1 CHECK (http_redirect IN (0, 1)),
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
);
|
||||
@@ -0,0 +1,31 @@
|
||||
CREATE TABLE IF NOT EXISTS ddns_configs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
provider TEXT NOT NULL DEFAULT 'cloudflare',
|
||||
root_domain TEXT NOT NULL,
|
||||
record_name TEXT NOT NULL,
|
||||
ipv4_enabled INTEGER NOT NULL DEFAULT 1 CHECK (ipv4_enabled IN (0, 1)),
|
||||
ipv6_enabled INTEGER NOT NULL DEFAULT 0 CHECK (ipv6_enabled IN (0, 1)),
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
api_token_enc TEXT,
|
||||
last_ipv4 TEXT,
|
||||
last_ipv6 TEXT,
|
||||
last_status TEXT NOT NULL DEFAULT 'unknown',
|
||||
last_error TEXT,
|
||||
last_updated_at TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS certificates (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
domain TEXT NOT NULL UNIQUE,
|
||||
wildcard INTEGER NOT NULL DEFAULT 0 CHECK (wildcard IN (0, 1)),
|
||||
cert_path TEXT,
|
||||
key_path TEXT,
|
||||
expires_at TEXT,
|
||||
last_renew_at TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
last_error TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_ddns_configs_domain_record
|
||||
ON ddns_configs(root_domain, record_name);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE certificates ADD COLUMN acme_ca TEXT NOT NULL DEFAULT 'letsencrypt';
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE certificates ADD COLUMN domains TEXT NOT NULL DEFAULT '';
|
||||
@@ -0,0 +1,50 @@
|
||||
CREATE TEMP TABLE proxy_domain_backup AS
|
||||
SELECT id, domain FROM proxy_rules;
|
||||
|
||||
CREATE TABLE proxy_rules_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
upstream TEXT NOT NULL,
|
||||
listen_port INTEGER NOT NULL DEFAULT 80 CHECK (listen_port > 0 AND listen_port <= 65535),
|
||||
listen_ipv4 INTEGER NOT NULL DEFAULT 1 CHECK (listen_ipv4 IN (0, 1)),
|
||||
listen_ipv6 INTEGER NOT NULL DEFAULT 0 CHECK (listen_ipv6 IN (0, 1)),
|
||||
https_enabled INTEGER NOT NULL DEFAULT 1 CHECK (https_enabled IN (0, 1)),
|
||||
http_redirect INTEGER NOT NULL DEFAULT 1 CHECK (http_redirect IN (0, 1)),
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
INSERT INTO proxy_rules_new (id, upstream, listen_port, listen_ipv4, listen_ipv6, https_enabled, http_redirect, enabled, created_at, updated_at)
|
||||
SELECT
|
||||
id,
|
||||
upstream,
|
||||
CASE WHEN https_enabled = 1 THEN 443 ELSE 80 END,
|
||||
1,
|
||||
0,
|
||||
https_enabled,
|
||||
http_redirect,
|
||||
enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM proxy_rules;
|
||||
|
||||
DROP TABLE proxy_rules;
|
||||
ALTER TABLE proxy_rules_new RENAME TO proxy_rules;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS proxy_hosts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
rule_id INTEGER NOT NULL REFERENCES proxy_rules(id) ON DELETE CASCADE,
|
||||
hostname TEXT NOT NULL COLLATE NOCASE,
|
||||
listen_port INTEGER CHECK (listen_port IS NULL OR (listen_port > 0 AND listen_port <= 65535)),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(hostname)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_proxy_hosts_rule_id ON proxy_hosts(rule_id);
|
||||
|
||||
INSERT INTO proxy_hosts (rule_id, hostname, listen_port)
|
||||
SELECT id, domain, NULL
|
||||
FROM proxy_domain_backup
|
||||
WHERE domain IS NOT NULL AND TRIM(domain) != '';
|
||||
|
||||
DROP TABLE proxy_domain_backup;
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE ddns_configs ADD COLUMN record_names TEXT NOT NULL DEFAULT '[]';
|
||||
|
||||
UPDATE ddns_configs
|
||||
SET record_names = json_array(record_name)
|
||||
WHERE record_names = '[]' OR record_names IS NULL OR record_names = '';
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE ddns_configs ADD COLUMN domain_records TEXT NOT NULL DEFAULT '[]';
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS proxy_traffic (
|
||||
host TEXT PRIMARY KEY,
|
||||
upload_bytes INTEGER NOT NULL DEFAULT 0,
|
||||
download_bytes INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
@@ -0,0 +1,22 @@
|
||||
UPDATE proxy_hosts
|
||||
SET listen_port = (
|
||||
SELECT listen_port FROM proxy_rules WHERE proxy_rules.id = proxy_hosts.rule_id
|
||||
)
|
||||
WHERE listen_port IS NULL;
|
||||
|
||||
CREATE TABLE proxy_hosts_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
rule_id INTEGER NOT NULL REFERENCES proxy_rules(id) ON DELETE CASCADE,
|
||||
hostname TEXT NOT NULL COLLATE NOCASE,
|
||||
listen_port INTEGER NOT NULL CHECK (listen_port > 0 AND listen_port <= 65535),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(hostname, listen_port)
|
||||
);
|
||||
|
||||
INSERT INTO proxy_hosts_new (id, rule_id, hostname, listen_port, created_at)
|
||||
SELECT id, rule_id, hostname, listen_port, created_at FROM proxy_hosts;
|
||||
|
||||
DROP TABLE proxy_hosts;
|
||||
ALTER TABLE proxy_hosts_new RENAME TO proxy_hosts;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_proxy_hosts_rule_id ON proxy_hosts(rule_id);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE proxy_rules ADD COLUMN remark TEXT NOT NULL DEFAULT '';
|
||||
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE proxy_rules RENAME COLUMN remark TO name;
|
||||
|
||||
ALTER TABLE proxy_rules ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
UPDATE proxy_rules SET sort_order = id;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_proxy_rules_sort_order ON proxy_rules(sort_order);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE proxy_rules ADD COLUMN security_json TEXT NOT NULL DEFAULT '{}';
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE proxy_rules ADD COLUMN nginx_mode TEXT NOT NULL DEFAULT 'auto';
|
||||
@@ -0,0 +1,44 @@
|
||||
CREATE TABLE IF NOT EXISTS frp_servers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
||||
server_addr TEXT NOT NULL,
|
||||
server_port INTEGER NOT NULL CHECK (server_port > 0 AND server_port <= 65535),
|
||||
auth_token_enc TEXT,
|
||||
tls_enabled INTEGER NOT NULL DEFAULT 1 CHECK (tls_enabled IN (0, 1)),
|
||||
tls_server_name TEXT NOT NULL DEFAULT '',
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS frp_proxies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server_id INTEGER NOT NULL REFERENCES frp_servers(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL COLLATE NOCASE,
|
||||
type TEXT NOT NULL CHECK (type IN ('tcp', 'http', 'https')),
|
||||
local_ip TEXT NOT NULL DEFAULT '127.0.0.1',
|
||||
local_port INTEGER NOT NULL CHECK (local_port > 0 AND local_port <= 65535),
|
||||
remote_port INTEGER CHECK (remote_port IS NULL OR (remote_port > 0 AND remote_port <= 65535)),
|
||||
custom_domains_json TEXT NOT NULL DEFAULT '[]',
|
||||
host_header_rewrite TEXT NOT NULL DEFAULT '',
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
remark TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(server_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS frp_runtime_status (
|
||||
server_id INTEGER PRIMARY KEY REFERENCES frp_servers(id) ON DELETE CASCADE,
|
||||
status TEXT NOT NULL DEFAULT 'stopped',
|
||||
pid INTEGER,
|
||||
frpc_version TEXT NOT NULL DEFAULT '',
|
||||
last_started_at TEXT,
|
||||
last_reloaded_at TEXT,
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_frp_proxies_tcp_remote_port
|
||||
ON frp_proxies(server_id, remote_port)
|
||||
WHERE type = 'tcp' AND remote_port IS NOT NULL;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE frp_servers ADD COLUMN config_json TEXT NOT NULL DEFAULT '{}';
|
||||
ALTER TABLE frp_servers ADD COLUMN oidc_client_secret_enc TEXT NOT NULL DEFAULT '';
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE IF NOT EXISTS frp_server_diagnostics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server_id INTEGER NOT NULL REFERENCES frp_servers(id) ON DELETE CASCADE,
|
||||
checked_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
available INTEGER NOT NULL DEFAULT 0 CHECK (available IN (0, 1)),
|
||||
latency_ms INTEGER,
|
||||
error TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_frp_server_diagnostics_server_time
|
||||
ON frp_server_diagnostics(server_id, checked_at);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE frp_proxies ADD COLUMN config_json TEXT NOT NULL DEFAULT '{}';
|
||||
@@ -0,0 +1,18 @@
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN desired_state TEXT NOT NULL DEFAULT 'stopped';
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN process_state TEXT NOT NULL DEFAULT 'stopped';
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN connection_state TEXT NOT NULL DEFAULT 'unknown';
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN state_source TEXT NOT NULL DEFAULT 'legacy';
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN process_pid INTEGER;
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN exit_code INTEGER;
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN last_connected_at TEXT;
|
||||
ALTER TABLE frp_runtime_status ADD COLUMN last_disconnected_at TEXT;
|
||||
|
||||
UPDATE frp_runtime_status
|
||||
SET desired_state = CASE WHEN status IN ('running', 'starting') THEN 'running' ELSE 'stopped' END,
|
||||
process_state = CASE WHEN status IN ('running', 'starting') THEN 'unknown' ELSE 'stopped' END,
|
||||
connection_state = CASE WHEN status = 'running' THEN 'unknown' ELSE 'unknown' END,
|
||||
state_source = 'migration'
|
||||
WHERE desired_state = 'stopped' AND status IN ('running', 'starting');
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_frp_runtime_process_state
|
||||
ON frp_runtime_status(process_state, connection_state);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE frp_servers ADD COLUMN dashboard_password_enc TEXT;
|
||||
@@ -0,0 +1,42 @@
|
||||
-- FRP 规则类型与端口约束修正(文档 FRP_CROSS_MODULE_IMPLEMENTATION_PLAN.md 23.2)
|
||||
-- 原 014_frp.sql 的 type CHECK 只有 tcp/http/https,但校验器与前端已支持
|
||||
-- udp/tcpmux/stcp/sudp/xtcp:这些类型会在校验通过后因 SQLite CHECK 约束插入失败。
|
||||
-- SQLite 无法 ALTER CHECK 约束,这里重建 frp_proxies 表并统一约束。
|
||||
CREATE TABLE IF NOT EXISTS frp_proxies_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
server_id INTEGER NOT NULL REFERENCES frp_servers(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL COLLATE NOCASE,
|
||||
type TEXT NOT NULL CHECK (type IN ('tcp', 'udp', 'http', 'https', 'tcpmux', 'stcp', 'sudp', 'xtcp')),
|
||||
local_ip TEXT NOT NULL DEFAULT '127.0.0.1',
|
||||
local_port INTEGER NOT NULL CHECK (local_port > 0 AND local_port <= 65535),
|
||||
remote_port INTEGER CHECK (
|
||||
remote_port IS NULL
|
||||
OR (remote_port > 0 AND remote_port <= 65535 AND type IN ('tcp', 'udp'))
|
||||
),
|
||||
custom_domains_json TEXT NOT NULL DEFAULT '[]',
|
||||
host_header_rewrite TEXT NOT NULL DEFAULT '',
|
||||
config_json TEXT NOT NULL DEFAULT '{}',
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
remark TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(server_id, name)
|
||||
);
|
||||
|
||||
INSERT INTO frp_proxies_new
|
||||
(id, server_id, name, type, local_ip, local_port, remote_port, custom_domains_json, host_header_rewrite, config_json, enabled, remark, created_at, updated_at)
|
||||
SELECT
|
||||
id, server_id, name, type, local_ip, local_port, remote_port, custom_domains_json, host_header_rewrite, COALESCE(config_json, '{}'), enabled, remark, created_at, updated_at
|
||||
FROM frp_proxies;
|
||||
|
||||
DROP TABLE frp_proxies;
|
||||
ALTER TABLE frp_proxies_new RENAME TO frp_proxies;
|
||||
|
||||
-- tcp 与 udp 的远程端口在同一 server_id 内分别查重(原索引混用两种协议)
|
||||
DROP INDEX IF EXISTS idx_frp_proxies_tcp_remote_port;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_frp_proxies_tcp_remote_port
|
||||
ON frp_proxies(server_id, remote_port)
|
||||
WHERE type = 'tcp' AND remote_port IS NOT NULL;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_frp_proxies_udp_remote_port
|
||||
ON frp_proxies(server_id, remote_port)
|
||||
WHERE type = 'udp' AND remote_port IS NOT NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- DDNS 支持自定义 IP:填写后更新记录时直接使用该 IP(如公网服务器 IP),不填则检测本机公网 IP。
|
||||
ALTER TABLE ddns_configs ADD COLUMN custom_ipv4 TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE ddns_configs ADD COLUMN custom_ipv6 TEXT NOT NULL DEFAULT '';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- 公网 fonu-agent 远程管理配置
|
||||
ALTER TABLE frp_servers ADD COLUMN agent_url TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE frp_servers ADD COLUMN agent_token_enc TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE frp_servers ADD COLUMN ssh_host TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE frp_servers ADD COLUMN ssh_port INTEGER NOT NULL DEFAULT 22;
|
||||
ALTER TABLE frp_servers ADD COLUMN ssh_user TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE frp_servers ADD COLUMN ssh_auth TEXT NOT NULL DEFAULT 'key';
|
||||
ALTER TABLE frp_servers ADD COLUMN ssh_secret_enc TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE frp_servers ADD COLUMN mgmt_enabled INTEGER NOT NULL DEFAULT 0 CHECK (mgmt_enabled IN (0, 1));
|
||||
Reference in New Issue
Block a user