-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
164 lines (151 loc) · 6.24 KB
/
Copy pathdocker-compose.yml
File metadata and controls
164 lines (151 loc) · 6.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# docker-compose — run the live spine: detector + transparent edge proxy.
# `docker compose up` starts blue; `docker compose --profile evaders run vanilla` fires the control.
services:
detector:
build:
context: .
dockerfile: detector/Dockerfile
# No host port publish by default (services talk over the compose network); add
# `ports: ["8080:8080"]` to reach the detector from the host.
# KITSUNE_ARENA_URL points at the owned arena challenge-gate; the detector relays /arena/* to it so a
# visitor reaches the gate on one origin (through the edge). Absent -> the /arena routes return 503.
environment:
KITSUNE_ARENA_URL: "http://arena:8095"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/healthz')"]
interval: 5s
timeout: 3s
retries: 5
# `uv run` re-syncs the env on first start (~25-30s); give it room before counting failures so the
# edge's depends_on:healthy gate doesn't trip on a cold start.
start_period: 45s
edge:
build:
context: ./edge
environment:
KITSUNE_EDGE_ADDR: "0.0.0.0:8443"
KITSUNE_BACKEND: "http://detector:8080"
KITSUNE_DETECTOR: "http://detector:8080"
# NET_RAW lets the edge raw-capture client SYNs for TCP/IP-stack fingerprinting (p0f-style OS
# kernel). The image is non-root by default (secure); the lab runs it as root so CAP_NET_RAW is in
# the effective set for the AF_PACKET sniffer. Without this the edge still runs — no tcp_kernel signal.
user: root
cap_add:
- NET_RAW
# Add `ports: ["8443:8443"]` to drive the edge from the host.
depends_on:
detector:
condition: service_healthy
# The public arena challenge-gate (owned infra) — a long-running service in the live spine. Reproduces
# documented OPEN PoW mechanisms (anubis/friendlycaptcha/altcha) for visitors to challenge; the detector
# relays /arena/* here. It only ever talks to itself — never a third-party endpoint.
arena:
build:
context: .
dockerfile: arena/Dockerfile
environment:
ARENA_ADDR: "0.0.0.0:8095"
restart: unless-stopped
# Red side vs the arena — a browserless solver that beats every arena CAPTCHA gate (owned gates only),
# while the detector convicts the no-JS client. `--profile arena-solver run --rm arena-solver`.
arena-solver:
build:
context: .
dockerfile: evaders/arena-solver/Dockerfile
environment:
KITSUNE_DETECTOR: "http://detector:8080"
depends_on: [detector, arena]
profiles: ["arena-solver"]
# OCR evader vs the arena's distorted-text gate — a HF TrOCR captcha model reads it (owned gate only),
# while the detector convicts the no-JS client. Heavy (downloads the model). `--profile arena-solver`.
arena-solver-ocr:
build:
context: .
dockerfile: evaders/arena-solver-ocr/Dockerfile
environment:
KITSUNE_DETECTOR: "http://detector:8080"
depends_on: [detector, arena]
profiles: ["arena-solver"]
# Red side — one-shot, only with `--profile evaders`.
vanilla:
build:
context: .
dockerfile: evaders/vanilla/Dockerfile
environment:
KITSUNE_EDGE: "https://edge:8443/healthz"
KITSUNE_DETECTOR: "http://detector:8080"
depends_on: [edge]
profiles: ["evaders"]
# HTTP/1.1 slow-header (slowloris) hold — a fleet of ALPN-http/1.1 connections dribbling an incomplete
# request header, so the edge's SlowLorisScanner emits net.slow_http_attack (and the fleet aggregates as an
# L7 flood). A slow-header hold, not a volumetric flood. `--profile evaders run --rm slow-http`.
slow-http:
build:
context: ./evaders/slow-http
environment:
KITSUNE_EDGE: "https://edge:8443/"
depends_on: [edge]
profiles: ["evaders"]
# uTLS MITM front for the chained-tool experiment: forges a browser TLS+H2 handshake to the edge while a
# real browser proxies through it (point a browser evader at KITSUNE_EDGE=https://chain-front:8444/). Tests
# whether chaining a network-forging tool behind a real runtime moves the single-session frontier — it does
# not (see evaders/chain-mitm/README.md). `--profile evaders up -d chain-front`, then run any browser evader.
chain-front:
build:
context: ./evaders/chain-mitm
environment:
KITSUNE_EDGE: "https://edge:8443"
KS_HELLO: "chrome" # chrome | firefox | safari — the forged network engine
depends_on: [edge]
profiles: ["evaders"]
# Kernel OS spoof: a userspace TCP stack (AF_PACKET) forges a chosen kernel's SYN option order + a matching
# uTLS hello + UA, beating net.tcp_os_vs_ua. KS_PROFILE=<name>|random|list; a fleet of random nodes morphs
# into any mix of OSes. Needs NET_RAW + NET_ADMIN. `--profile evaders run --rm os-spoof`.
os-spoof:
build:
context: ./evaders/os-spoof
environment:
KS_EDGE_HOST: "edge"
KS_PROFILE: "random" # windows-chrome | macos-safari | linux-firefox | ios-safari | … | random | list
cap_add: [NET_RAW, NET_ADMIN]
depends_on: [edge]
profiles: ["evaders"]
# High-fidelity network impersonator (Chrome TLS+H2 via primp/BoringSSL, no JS).
primp:
build:
context: .
dockerfile: evaders/primp/Dockerfile
environment:
KITSUNE_EDGE: "https://edge:8443/healthz"
KITSUNE_DETECTOR: "http://detector:8080"
depends_on: [edge]
profiles: ["evaders"]
# Go/uTLS forged-ClientHello impersonator over HTTP/2 (Chrome JA3/JA4, no JS).
go-tls:
build:
context: .
dockerfile: evaders/go-tls/Dockerfile
environment:
KITSUNE_EDGE: "https://edge:8443/healthz"
depends_on: [edge]
profiles: ["evaders"]
# PoW arms-race testbed — the BLUE gate (long-running target). `--profile pow up pow-gate`.
pow-gate:
build:
context: .
dockerfile: evaders/pow/Dockerfile
environment:
POW_ADDR: "0.0.0.0:8090"
POW_DIFFICULTY: "20"
profiles: ["pow"]
# PoW native (no-browser) solver — the RED evader; beats the gate and redeems the token.
pow-solver:
build:
context: .
dockerfile: evaders/pow/Dockerfile
entrypoint: ["/pow-solver"]
environment:
POW_GATE: "http://pow-gate:8090"
POW_CLASS: "hashcash"
depends_on: [pow-gate]
profiles: ["pow"]