Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions go-waf/PROJECT_STRUCTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Go project structure (generated from TS interfaces and architecture)

```text
go-waf/
├── cmd/
│ └── waf/
│ └── main.go
├── internal/
│ ├── app/
│ │ ├── bootstrap.go
│ │ └── lifecycle.go
│ ├── config/
│ │ ├── loader.go
│ │ ├── defaults.go
│ │ ├── model_app_config.go
│ │ ├── model_waf_config.go
│ │ ├── model_api_metrics_sentry.go
│ │ ├── model_static_filters.go
│ │ ├── model_jail_config.go
│ │ └── model_under_attack_config.go
│ ├── api/
│ │ └── http/
│ │ ├── handlers/
│ │ │ ├── health_handler.go
│ │ │ ├── jail_handler.go
│ │ │ └── metrics_handler.go
│ │ ├── middleware/
│ │ │ └── basic_auth.go
│ │ └── routes/
│ │ └── routes.go
│ ├── waf/
│ │ ├── middleware.go
│ │ ├── client_detection.go
│ │ └── reject_response.go
│ ├── jail/
│ │ ├── manager.go
│ │ ├── types.go
│ │ ├── rules/
│ │ │ ├── abstract.go
│ │ │ ├── conditions.go
│ │ │ ├── composite.go
│ │ │ ├── flexible.go
│ │ │ └── static.go
│ │ └── storage/
│ │ ├── interface.go
│ │ ├── file_storage.go
│ │ ├── operator_storage.go
│ │ └── memory_storage.go
│ ├── underattack/
│ │ ├── middleware.go
│ │ ├── types.go
│ │ ├── challenge/
│ │ │ ├── manager.go
│ │ │ └── types.go
│ │ ├── fingerprint/
│ │ │ ├── validator.go
│ │ │ └── types.go
│ │ ├── proofs/
│ │ │ ├── validator.go
│ │ │ └── types.go
│ │ └── botdetector/
│ │ ├── detector.go
│ │ └── types.go
│ ├── metrics/
│ │ ├── service.go
│ │ └── registry.go
│ ├── observability/
│ │ ├── logging/
│ │ │ └── logger.go
│ │ └── sentry/
│ │ └── client.go
│ ├── geoip/
│ │ └── service.go
│ ├── proxy/
│ │ └── reverse_proxy.go
│ └── shared/
│ └── types/
│ ├── nullable.go
│ └── enums.go
├── pkg/
│ ├── httpx/
│ │ ├── response.go
│ │ └── request_id.go
│ ├── authx/
│ │ └── basic.go
│ └── envx/
│ └── env.go
├── configs/
│ ├── config.example.yaml
│ ├── basic.yaml
│ ├── production.yaml
│ └── under_attack.yaml
├── deployments/
│ ├── docker/
│ │ ├── Dockerfile
│ │ └── docker-compose.yml
│ └── k8s/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── configmap.yaml
├── scripts/
│ ├── run.sh
│ ├── lint.sh
│ └── test.sh
└── tests/
├── unit/
├── integration/
└── e2e/
```
9 changes: 9 additions & 0 deletions go-waf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# WAF (Go) — project scaffold

This scaffold mirrors the TypeScript architecture:
- API, Metrics, WAF middleware pipeline
- Jail subsystem (rules + storage adapters)
- UnderAttack subsystem (challenge, fingerprint, proofs)
- GeoIP, proxy, logging, sentry

See `PROJECT_STRUCTURE.md` for the detailed map of folders/files.
21 changes: 21 additions & 0 deletions go-waf/configs/basic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
proxy:
host: "http://localhost:8080"

api:
auth:
enabled: false

metrics:
enabled: true
auth:
enabled: false

wafMiddleware:
mode: audit

jailManager:
enabled: true
filterRules: []

sentry:
enabled: false
21 changes: 21 additions & 0 deletions go-waf/configs/config.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
proxy:
host: "http://localhost:8080"

api:
auth:
enabled: false

metrics:
enabled: true
auth:
enabled: false

wafMiddleware:
mode: audit

jailManager:
enabled: true
filterRules: []

sentry:
enabled: false
21 changes: 21 additions & 0 deletions go-waf/configs/production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
proxy:
host: "http://localhost:8080"

api:
auth:
enabled: false

metrics:
enabled: true
auth:
enabled: false

wafMiddleware:
mode: audit

jailManager:
enabled: true
filterRules: []

sentry:
enabled: false
21 changes: 21 additions & 0 deletions go-waf/configs/under_attack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
proxy:
host: "http://localhost:8080"

api:
auth:
enabled: false

metrics:
enabled: true
auth:
enabled: false

wafMiddleware:
mode: audit

jailManager:
enabled: true
filterRules: []

sentry:
enabled: false
8 changes: 8 additions & 0 deletions go-waf/deployments/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM golang:1.22-alpine AS build
WORKDIR /src
COPY . .
RUN go build -o /out/waf ./cmd/waf

FROM alpine:3.20
COPY --from=build /out/waf /usr/local/bin/waf
ENTRYPOINT ["/usr/local/bin/waf"]
8 changes: 8 additions & 0 deletions go-waf/deployments/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: '3.9'
services:
waf:
build:
context: ../../
dockerfile: deployments/docker/Dockerfile
ports:
- "3000:3000"
4 changes: 4 additions & 0 deletions go-waf/deployments/k8s/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: waf-go-config
19 changes: 19 additions & 0 deletions go-waf/deployments/k8s/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: waf-go
spec:
replicas: 1
selector:
matchLabels:
app: waf-go
template:
metadata:
labels:
app: waf-go
spec:
containers:
- name: waf-go
image: waf-go:latest
ports:
- containerPort: 3000
10 changes: 10 additions & 0 deletions go-waf/deployments/k8s/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: waf-go
spec:
selector:
app: waf-go
ports:
- port: 3000
targetPort: 3000
3 changes: 3 additions & 0 deletions go-waf/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/someblackmagic/web-application-firewall-go

go 1.22
3 changes: 3 additions & 0 deletions go-waf/internal/api/http/handlers/health_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package handlers

// TODO: implement.
3 changes: 3 additions & 0 deletions go-waf/internal/api/http/handlers/jail_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package handlers

// TODO: implement.
3 changes: 3 additions & 0 deletions go-waf/internal/api/http/handlers/metrics_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package handlers

// TODO: implement.
3 changes: 3 additions & 0 deletions go-waf/internal/api/http/middleware/basic_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package middleware

// TODO: implement.
3 changes: 3 additions & 0 deletions go-waf/internal/api/http/routes/routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package routes

// TODO: implement.
5 changes: 5 additions & 0 deletions go-waf/internal/app/bootstrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package app

func Run() {
// TODO: wire config, logger, sentry, geoip, metrics, jail, under-attack, waf middleware and reverse proxy.
}
3 changes: 3 additions & 0 deletions go-waf/internal/app/lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package app

// TODO: graceful shutdown, signal handling, panic/recovery integration.
3 changes: 3 additions & 0 deletions go-waf/internal/config/defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package config

// TODO: default values equivalent to TS merge/defaults behavior.
3 changes: 3 additions & 0 deletions go-waf/internal/config/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package config

// TODO: implement YAML/file/url config loader with env overrides.
23 changes: 23 additions & 0 deletions go-waf/internal/config/model_api_metrics_sentry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package config

type HttpBasicAuthConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
Username *string `yaml:"username,omitempty" json:"username,omitempty"`
Password *string `yaml:"password,omitempty" json:"password,omitempty"`
}

type APIConfig struct {
Auth HttpBasicAuthConfig `yaml:"auth" json:"auth"`
}

type MetricsConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
Auth HttpBasicAuthConfig `yaml:"auth" json:"auth"`
}

type SentryConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
DSN *string `yaml:"dsn,omitempty" json:"dsn,omitempty"`
Release *string `yaml:"release,omitempty" json:"release,omitempty"`
Debug *bool `yaml:"debug,omitempty" json:"debug,omitempty"`
}
13 changes: 13 additions & 0 deletions go-waf/internal/config/model_app_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config

type AppConfig struct {
Proxy struct {
Host string `yaml:"host" json:"host"`
} `yaml:"proxy" json:"proxy"`

WAFMiddleware WAFMiddlewareConfig `yaml:"wafMiddleware" json:"wafMiddleware"`
JailManager JailManagerConfig `yaml:"jailManager" json:"jailManager"`
API APIConfig `yaml:"api" json:"api"`
Metrics MetricsConfig `yaml:"metrics" json:"metrics"`
Sentry SentryConfig `yaml:"sentry" json:"sentry"`
}
17 changes: 17 additions & 0 deletions go-waf/internal/config/model_jail_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package config

type JailManagerConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
Storage *JailStorageConfig `yaml:"storage,omitempty" json:"storage,omitempty"`
LoadInterval *int `yaml:"loadInterval,omitempty" json:"loadInterval,omitempty"`
FlushInterval *int `yaml:"flushInterval,omitempty" json:"flushInterval,omitempty"`
FlushAlways *bool `yaml:"flushAlways,omitempty" json:"flushAlways,omitempty"`
FilterRules []AbstractRuleConfig `yaml:"filterRules" json:"filterRules"`
}

type JailStorageConfig struct {
Driver *string `yaml:"driver,omitempty" json:"driver,omitempty"`
DriverConfig any `yaml:"driverConfig,omitempty" json:"driverConfig,omitempty"`
}

type AbstractRuleConfig struct { Name string `yaml:"name" json:"name"`; Type string `yaml:"type" json:"type"` }
11 changes: 11 additions & 0 deletions go-waf/internal/config/model_static_filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package config

type StaticFilterConfig struct {
IPs []string `yaml:"ips,omitempty" json:"ips,omitempty"`
IPSubnet []string `yaml:"ipSubnet,omitempty" json:"ipSubnet,omitempty"`
GeoCountry []string `yaml:"geoCountry,omitempty" json:"geoCountry,omitempty"`
GeoCity []string `yaml:"geoCity,omitempty" json:"geoCity,omitempty"`
}

type WhitelistConfig struct{ StaticFilterConfig }
type BlacklistConfig struct{ StaticFilterConfig }
23 changes: 23 additions & 0 deletions go-waf/internal/config/model_under_attack_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package config

type UnderAttackConfig struct {
Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
Mode *string `yaml:"mode,omitempty" json:"mode,omitempty"`
ChallengeDurationMs *int64 `yaml:"challengeDurationMs,omitempty" json:"challengeDurationMs,omitempty"`
Conditions []map[string]any `yaml:"conditions,omitempty" json:"conditions,omitempty"`
FingerprintChecks *FingerprintValidatorConfig `yaml:"fingerprintChecks,omitempty" json:"fingerprintChecks,omitempty"`
ChallengeManager *ChallengeManagerConfig `yaml:"challengeManager,omitempty" json:"challengeManager,omitempty"`
ChallengePage *ChallengePageConfig `yaml:"challengePage,omitempty" json:"challengePage,omitempty"`
SkipURLs []string `yaml:"skipUrls,omitempty" json:"skipUrls,omitempty"`
CookieName *string `yaml:"cookieName,omitempty" json:"cookieName,omitempty"`
BypassHeaders []BypassHeader `yaml:"bypassHeaders,omitempty" json:"bypassHeaders,omitempty"`
}

type FingerprintValidatorConfig struct {
Enabled bool `yaml:"enabled" json:"enabled"`
MinScore float64 `yaml:"minScore" json:"minScore"`
}

type ChallengeManagerConfig struct { AutoCleanup bool `yaml:"autoCleanup" json:"autoCleanup"`; AutoCleanupInterval int `yaml:"autoCleanupInterval" json:"autoCleanupInterval"` }
type ChallengePageConfig struct { Title string `yaml:"title" json:"title"`; Path string `yaml:"path" json:"path"` }
type BypassHeader struct { Name string `yaml:"name" json:"name"`; Value string `yaml:"value" json:"value"` }
Loading