You've already forked caddy-opnsense-blocker
Build initial caddy-opnsense-blocker daemon
This commit is contained in:
97
README.md
Normal file
97
README.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# caddy-opnsense-blocker
|
||||
|
||||
`caddy-opnsense-blocker` is a local-first daemon that ingests Caddy access logs in their default JSON format, evaluates suspicious requests, keeps persistent local state in SQLite, provides a lightweight web UI for review, and blocks or unblocks IP addresses through an OPNsense alias.
|
||||
|
||||
## Features
|
||||
|
||||
- Real-time ingestion of multiple Caddy JSON log files.
|
||||
- One heuristic profile per log source.
|
||||
- Persistent local state in SQLite.
|
||||
- Local-only web UI for reviewing events and IPs.
|
||||
- Manual block, unblock, and override reset actions.
|
||||
- OPNsense alias backend with automatic alias creation.
|
||||
- Concurrent polling across multiple log files.
|
||||
|
||||
## Current scope
|
||||
|
||||
This first version is intentionally strong on ingestion, persistence, UI, and OPNsense integration.
|
||||
The decision engine is deliberately simple and deterministic for now:
|
||||
|
||||
- suspicious path prefixes
|
||||
- unexpected `POST` requests
|
||||
- `.php` path detection
|
||||
- explicit known-agent allow/deny rules
|
||||
- excluded CIDR ranges
|
||||
- manual overrides
|
||||
|
||||
This keeps the application usable immediately while leaving room for a more advanced network-intelligence engine later.
|
||||
|
||||
## Architecture
|
||||
|
||||
- `internal/caddylog`: parses default Caddy JSON access logs
|
||||
- `internal/engine`: evaluates requests against a profile
|
||||
- `internal/store`: persists events, IP state, manual decisions, backend actions, and source offsets
|
||||
- `internal/opnsense`: manages the target OPNsense alias through its API
|
||||
- `internal/service`: runs concurrent log followers and applies automatic decisions
|
||||
- `internal/web`: serves the local review UI and JSON API
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Generate or provision OPNsense API credentials.
|
||||
2. Copy `config.example.yaml` to `config.yaml` and adapt it.
|
||||
3. Start the daemon:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 go run ./cmd/caddy-opnsense-blocker -config ./config.yaml
|
||||
```
|
||||
|
||||
4. Open the local UI on the configured address, for example `http://127.0.0.1:9080`.
|
||||
|
||||
## Example configuration
|
||||
|
||||
See `config.example.yaml`.
|
||||
|
||||
Important points:
|
||||
|
||||
- Each source points to one Caddy log file.
|
||||
- Each source references exactly one profile.
|
||||
- `initial_position: end` means “start following new lines only” on first boot.
|
||||
- The web UI should stay bound to a local address such as `127.0.0.1:9080`.
|
||||
|
||||
## Web UI and API
|
||||
|
||||
The web UI is intentionally small and server-rendered.
|
||||
It refreshes through lightweight JSON polling and exposes these endpoints:
|
||||
|
||||
- `GET /healthz`
|
||||
- `GET /api/overview`
|
||||
- `GET /api/events`
|
||||
- `GET /api/ips`
|
||||
- `GET /api/ips/{ip}`
|
||||
- `POST /api/ips/{ip}/block`
|
||||
- `POST /api/ips/{ip}/unblock`
|
||||
- `POST /api/ips/{ip}/reset`
|
||||
|
||||
## Development
|
||||
|
||||
Run the test suite:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 go test ./...
|
||||
```
|
||||
|
||||
Build the daemon:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 go build ./cmd/caddy-opnsense-blocker
|
||||
```
|
||||
|
||||
`CGO_ENABLED=0` is useful on systems without a C toolchain. The application itself only relies on pure-Go dependencies.
|
||||
|
||||
## Roadmap
|
||||
|
||||
- richer decision engine
|
||||
- asynchronous DNS / RDAP / ASN enrichment
|
||||
- richer review filters in the UI
|
||||
- alternative blocking backends besides OPNsense
|
||||
- direct streaming ingestion targets in addition to file polling
|
||||
Reference in New Issue
Block a user