feat: add Fail2ban security detection console
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
CREATE TABLE "SecurityDetectionRule" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"sourceType" TEXT NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"threshold" INTEGER NOT NULL,
|
||||
"windowSeconds" INTEGER NOT NULL,
|
||||
"cooldownSeconds" INTEGER NOT NULL,
|
||||
"severity" TEXT NOT NULL,
|
||||
"defaultBlockSeconds" INTEGER NOT NULL,
|
||||
"maximumBlockSeconds" INTEGER NOT NULL,
|
||||
"configVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
"effectiveVersion" INTEGER NOT NULL DEFAULT 0,
|
||||
"applyStatus" TEXT NOT NULL DEFAULT 'pending',
|
||||
"lastApplyError" TEXT,
|
||||
"pendingConfig" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "SecurityDetectionRule_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE TABLE "SecurityDetectionEvent" (
|
||||
"id" TEXT NOT NULL, "eventKey" TEXT NOT NULL, "ruleId" TEXT NOT NULL,
|
||||
"sourceIp" TEXT NOT NULL, "sourcePort" INTEGER, "accountHash" TEXT,
|
||||
"path" TEXT, "protocol" TEXT, "resultCode" TEXT, "evidence" JSONB,
|
||||
"occurredAt" TIMESTAMP(3) NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "SecurityDetectionEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE TABLE "SecurityAlert" (
|
||||
"id" TEXT NOT NULL, "fingerprint" TEXT NOT NULL, "ruleId" TEXT NOT NULL,
|
||||
"sourceIp" TEXT NOT NULL, "severity" TEXT NOT NULL, "status" TEXT NOT NULL DEFAULT 'open',
|
||||
"eventCount" INTEGER NOT NULL DEFAULT 0, "windowStartedAt" TIMESTAMP(3) NOT NULL,
|
||||
"firstOccurredAt" TIMESTAMP(3) NOT NULL, "lastOccurredAt" TIMESTAMP(3) NOT NULL,
|
||||
"acknowledgedAt" TIMESTAMP(3), "acknowledgedById" TEXT, "ignoredAt" TIMESTAMP(3),
|
||||
"ignoredById" TEXT, "ignoreReason" TEXT, "blockId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "SecurityAlert_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE TABLE "SecurityBlock" (
|
||||
"id" TEXT NOT NULL, "operationKey" TEXT NOT NULL, "alertId" TEXT, "sourceIp" TEXT NOT NULL,
|
||||
"executor" TEXT NOT NULL, "status" TEXT NOT NULL DEFAULT 'requested', "durationSeconds" INTEGER NOT NULL,
|
||||
"reason" TEXT NOT NULL, "requestedById" TEXT NOT NULL, "requestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"appliedAt" TIMESTAMP(3), "expiresAt" TIMESTAMP(3), "releasedAt" TIMESTAMP(3), "releasedById" TEXT,
|
||||
"executorReference" TEXT, "lastError" TEXT, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "SecurityBlock_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE TABLE "SecurityProtectedNetwork" (
|
||||
"id" TEXT NOT NULL, "network" TEXT NOT NULL, "name" TEXT NOT NULL, "reason" TEXT NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true, "createdById" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "SecurityProtectedNetwork_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE UNIQUE INDEX "SecurityDetectionRule_code_key" ON "SecurityDetectionRule"("code");
|
||||
CREATE INDEX "SecurityDetectionRule_enabled_sourceType_idx" ON "SecurityDetectionRule"("enabled", "sourceType");
|
||||
CREATE UNIQUE INDEX "SecurityDetectionEvent_eventKey_key" ON "SecurityDetectionEvent"("eventKey");
|
||||
CREATE INDEX "SecurityDetectionEvent_ruleId_occurredAt_idx" ON "SecurityDetectionEvent"("ruleId", "occurredAt");
|
||||
CREATE INDEX "SecurityDetectionEvent_sourceIp_occurredAt_idx" ON "SecurityDetectionEvent"("sourceIp", "occurredAt");
|
||||
CREATE UNIQUE INDEX "SecurityAlert_fingerprint_key" ON "SecurityAlert"("fingerprint");
|
||||
CREATE INDEX "SecurityAlert_status_severity_lastOccurredAt_idx" ON "SecurityAlert"("status", "severity", "lastOccurredAt");
|
||||
CREATE INDEX "SecurityAlert_sourceIp_status_lastOccurredAt_idx" ON "SecurityAlert"("sourceIp", "status", "lastOccurredAt");
|
||||
CREATE INDEX "SecurityAlert_ruleId_status_lastOccurredAt_idx" ON "SecurityAlert"("ruleId", "status", "lastOccurredAt");
|
||||
CREATE UNIQUE INDEX "SecurityBlock_operationKey_key" ON "SecurityBlock"("operationKey");
|
||||
CREATE INDEX "SecurityBlock_status_expiresAt_idx" ON "SecurityBlock"("status", "expiresAt");
|
||||
CREATE INDEX "SecurityBlock_sourceIp_status_requestedAt_idx" ON "SecurityBlock"("sourceIp", "status", "requestedAt");
|
||||
CREATE INDEX "SecurityBlock_alertId_idx" ON "SecurityBlock"("alertId");
|
||||
CREATE UNIQUE INDEX "SecurityProtectedNetwork_network_key" ON "SecurityProtectedNetwork"("network");
|
||||
CREATE INDEX "SecurityProtectedNetwork_enabled_createdAt_idx" ON "SecurityProtectedNetwork"("enabled", "createdAt");
|
||||
ALTER TABLE "SecurityDetectionEvent" ADD CONSTRAINT "SecurityDetectionEvent_ruleId_fkey" FOREIGN KEY ("ruleId") REFERENCES "SecurityDetectionRule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "SecurityAlert" ADD CONSTRAINT "SecurityAlert_ruleId_fkey" FOREIGN KEY ("ruleId") REFERENCES "SecurityDetectionRule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
INSERT INTO "SecurityDetectionRule" ("id", "code", "name", "sourceType", "threshold", "windowSeconds", "cooldownSeconds", "severity", "defaultBlockSeconds", "maximumBlockSeconds", "configVersion", "effectiveVersion", "applyStatus", "updatedAt") VALUES
|
||||
('sec_admin_login', 'admin_login_failure', '运营端登录失败', 'application', 8, 600, 900, 'medium', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_client_login', 'client_login_failure', '客户端登录失败', 'application', 8, 600, 900, 'medium', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_ssh_auth', 'ssh_auth_failure', 'SSH认证失败', 'fail2ban', 6, 600, 1800, 'high', 86400, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_cmpp_auth', 'cmpp_auth_failure', 'CMPP认证失败', 'gateway', 5, 300, 900, 'high', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_cmpp_abuse', 'cmpp_protocol_abuse', 'CMPP协议滥用', 'gateway', 20, 60, 900, 'critical', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_http_key', 'http_invalid_api_key', 'HTTP错误密钥', 'application', 10, 300, 900, 'high', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_http_sign', 'http_signature_failure', 'HTTP签名错误', 'application', 10, 300, 900, 'high', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_http_replay', 'http_replay_attempt', 'HTTP重放尝试', 'application', 3, 600, 1800, 'critical', 86400, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP),
|
||||
('sec_http_scan', 'http_malicious_scan', 'HTTP恶意扫描', 'fail2ban', 20, 60, 900, 'high', 3600, 604800, 1, 1, 'effective', CURRENT_TIMESTAMP);
|
||||
@@ -2321,3 +2321,114 @@ model GatewayDownstreamRecoveryStatus {
|
||||
@@index([state, updatedAt])
|
||||
@@index([nextRetryAt])
|
||||
}
|
||||
|
||||
model SecurityDetectionRule {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
sourceType String
|
||||
enabled Boolean @default(true)
|
||||
threshold Int
|
||||
windowSeconds Int
|
||||
cooldownSeconds Int
|
||||
severity String
|
||||
defaultBlockSeconds Int
|
||||
maximumBlockSeconds Int
|
||||
configVersion Int @default(1)
|
||||
effectiveVersion Int @default(0)
|
||||
applyStatus String @default("pending")
|
||||
lastApplyError String?
|
||||
pendingConfig Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
events SecurityDetectionEvent[]
|
||||
alerts SecurityAlert[]
|
||||
|
||||
@@index([enabled, sourceType])
|
||||
}
|
||||
|
||||
model SecurityDetectionEvent {
|
||||
id String @id @default(cuid())
|
||||
eventKey String @unique
|
||||
ruleId String
|
||||
sourceIp String
|
||||
sourcePort Int?
|
||||
accountHash String?
|
||||
path String?
|
||||
protocol String?
|
||||
resultCode String?
|
||||
evidence Json?
|
||||
occurredAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
rule SecurityDetectionRule @relation(fields: [ruleId], references: [id], onDelete: Restrict)
|
||||
|
||||
@@index([ruleId, occurredAt])
|
||||
@@index([sourceIp, occurredAt])
|
||||
}
|
||||
|
||||
model SecurityAlert {
|
||||
id String @id @default(cuid())
|
||||
fingerprint String @unique
|
||||
ruleId String
|
||||
sourceIp String
|
||||
severity String
|
||||
status String @default("open")
|
||||
eventCount Int @default(0)
|
||||
windowStartedAt DateTime
|
||||
firstOccurredAt DateTime
|
||||
lastOccurredAt DateTime
|
||||
acknowledgedAt DateTime?
|
||||
acknowledgedById String?
|
||||
ignoredAt DateTime?
|
||||
ignoredById String?
|
||||
ignoreReason String?
|
||||
blockId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
rule SecurityDetectionRule @relation(fields: [ruleId], references: [id], onDelete: Restrict)
|
||||
|
||||
@@index([status, severity, lastOccurredAt])
|
||||
@@index([sourceIp, status, lastOccurredAt])
|
||||
@@index([ruleId, status, lastOccurredAt])
|
||||
}
|
||||
|
||||
model SecurityBlock {
|
||||
id String @id @default(cuid())
|
||||
operationKey String @unique
|
||||
alertId String?
|
||||
sourceIp String
|
||||
executor String
|
||||
status String @default("requested")
|
||||
durationSeconds Int
|
||||
reason String
|
||||
requestedById String
|
||||
requestedAt DateTime @default(now())
|
||||
appliedAt DateTime?
|
||||
expiresAt DateTime?
|
||||
releasedAt DateTime?
|
||||
releasedById String?
|
||||
executorReference String?
|
||||
lastError String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([status, expiresAt])
|
||||
@@index([sourceIp, status, requestedAt])
|
||||
@@index([alertId])
|
||||
}
|
||||
|
||||
model SecurityProtectedNetwork {
|
||||
id String @id @default(cuid())
|
||||
network String @unique
|
||||
name String
|
||||
reason String
|
||||
enabled Boolean @default(true)
|
||||
createdById String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([enabled, createdAt])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user