File size: 3,471 Bytes
de83fbe bf3ef55 de83fbe | 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 | # deploy/Caddyfile.example — reference Caddy config for this box.
#
# The deployment runs TWO bots behind one Caddy:
#
# arb.elghaly.dev -> 127.0.0.1:8080 the Rust bot (basicauth, private)
# bot.elghaly.dev -> 127.0.0.1:8081 this Python bot (public, read-only)
#
# Copy to /etc/caddy/Caddyfile, adjust, then:
#
# sudo caddy validate --config /etc/caddy/Caddyfile
# sudo systemctl reload caddy
#
# ─────────────────────────────────────────────────────────────────────────
# THE PATH ALLOWLIST IS THE POINT OF THIS FILE
# ─────────────────────────────────────────────────────────────────────────
# A bare `reverse_proxy 127.0.0.1:8081` publishes EVERY route the Python
# bot serves, and two of them are not public routes:
#
# POST /command fund-moving. Runs /hunt, toggles ghost and mint mode.
# GET /logs operational detail — wallet addresses, tx signatures,
# route sizes, internal errors.
#
# Both are Bearer-token gated in the application (modules/bot_api_server.py)
# and both are rate-limited and lockout-protected (modules/http_guard.py),
# so a bare proxy is not an immediate compromise. It is still the wrong
# shape. Anything that can move funds should be unreachable for two
# independent reasons, so that no single mistake — a token in a shell
# history, a bad `git add`, a regression in the auth check — is sufficient
# on its own.
#
# So this config lists what MAY be reached and 404s everything else. Note
# the direction: an allowlist fails closed, so a new endpoint added to the
# Python server tomorrow is private until someone deliberately publishes
# it. A blocklist would fail open and publish it by default.
arb.elghaly.dev {
basicauth {
# Generate with: caddy hash-password
# The hash is not a password, but it is still an offline-crackable
# artifact — keep it out of screenshots and out of git.
admin REPLACE_WITH_BCRYPT_HASH
}
reverse_proxy 127.0.0.1:8080
}
bot.elghaly.dev {
encode gzip
# The public read-only surface. Nothing here can act, and nothing here
# returns a secret — see modules/bot_api_server.py's own audit note for
# the field-by-field reasoning.
@public {
path /
path /status
path /api/pnl
path /api/receipts
path /api/routes
path /api/nearmiss
path /api/engine
path /receipts.csv
}
handle @public {
reverse_proxy 127.0.0.1:8081
}
# Everything else, including /command and /logs, does not exist as far
# as the internet is concerned. 404 rather than 403: a 403 confirms the
# path is real and worth attacking, which is free reconnaissance.
handle {
respond "not found" 404
}
header {
# This page loads no external anything — no CDN, no fonts, no
# analytics — so the policy can be this tight honestly. 'unsafe-inline'
# covers the one inline <style> and <script> the page is built from.
Content-Security-Policy "default-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'"
X-Content-Type-Options "nosniff"
Referrer-Policy "no-referrer"
X-Frame-Options "DENY"
-Server
}
}
|