Metadata-Version: 2.4
Name: honeydj
Version: 0.1.0
Summary: Self-hosted Django honeypot and attacker intelligence platform
Project-URL: Homepage, https://github.com/bistasulove/honeydj
Project-URL: Repository, https://github.com/bistasulove/honeydj
Project-URL: Documentation, https://github.com/bistasulove/honeydj#readme
Project-URL: Bug Tracker, https://github.com/bistasulove/honeydj/issues
Author: Sulav Raj Bista
License: MIT
License-File: LICENSE
Keywords: django,honeypot,intrusion-detection,security
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Requires-Python: >=3.11
Requires-Dist: celery<6.0,>=5.4
Requires-Dist: channels-redis<5.0,>=4.2
Requires-Dist: channels<5.0,>=4.2
Requires-Dist: django-unfold<1.0,>=0.43
Requires-Dist: django<6.0,>=5.2
Requires-Dist: maxminddb<3.0,>=2.6
Requires-Dist: requests<3.0,>=2.31
Requires-Dist: stix2<4.0,>=3.0
Provides-Extra: dev
Requires-Dist: factory-boy>=3.3; extra == 'dev'
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
Requires-Dist: pytest-django>=4.9; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: responses>=0.25; extra == 'dev'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]<4.0,>=3.2; extra == 'postgres'
Description-Content-Type: text/markdown

# HoneyDjango

Self-hosted Django honeypot and attacker intelligence platform. Serves decoy
endpoints (`/.env`, `/wp-admin/`, canary tokens, …), captures and enriches
every hit via Celery (GeoIP, JA3/User-Agent fingerprinting, threat feeds),
builds attacker profiles, and shows it all live in the Django admin — real-time
map, alert rules with Slack/email/webhook notifiers, and CSV/JSON/STIX export.

## Requirements

- Python 3.11+
- PostgreSQL (models use `ArrayField`; JSONB for payloads)
- Redis (Channels layer + Celery broker)

## Install

```bash
pip install honeydj            # host project already has a Postgres driver
pip install "honeydj[postgres]"  # or bring psycopg 3 along
```

## Quickstart (~5 minutes)

**1. Settings** — at the end of your `settings.py`:

```python
from honeydj.contrib.quickstart import apply_honeydj_settings

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "honeydj.honeypot.middleware.HoneyMiddleware",  # right after SecurityMiddleware
    # ... the rest of your middleware ...
]

REDIS_URL = "redis://localhost:6379/0"  # optional; defaults derive from this
apply_honeydj_settings(globals())
```

The helper appends the honeydj apps (plus `unfold` and `channels`) to
`INSTALLED_APPS` and fills in Channels/Celery/honeydj defaults without
overwriting anything you already set. Your `DATABASES` must point at
PostgreSQL.

**2. URLs** — decoys go at the site root, **last**, so they never shadow real
routes and their attack paths look authentic:

```python
urlpatterns = [
    # ... your real routes ...
    path("intel/dashboard/", include("honeydj.dashboard.urls", namespace="dashboard")),
    path("api/events/", include("honeydj.events.urls", namespace="events")),
    path("api/feeds/", include("honeydj.feeds.urls", namespace="feeds")),
    path("", include("honeydj.honeypot.urls", namespace="honeypot")),  # keep last
]
```

Mount the dashboard behind a non-obvious prefix — it shares the admin's auth.

**3. Migrate and run:**

```bash
python manage.py migrate
python manage.py seed_decoy_routes        # optional starter decoys
celery -A yourproject worker -Q default,enrichment,alerts -l info
celery -A yourproject beat -l info        # hourly threat-feed purge
```

The live map needs an ASGI server (Daphne/Uvicorn) with a
`ProtocolTypeRouter` routing `honeydj.events.routing.websocket_urlpatterns`
— see [`config/asgi.py`](config/asgi.py) for a working example. Everything
else works under plain WSGI.

## GeoIP (optional)

The GeoLite2 database is not distributable on PyPI. Download
`GeoLite2-City.mmdb` from [MaxMind](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data)
(free account) and set `GEOIP_PATH` to its directory. Without it, events are
simply captured without geo data.

## Configuration

`apply_honeydj_settings` documents every setting it touches. The ones you'll
most likely override: `GEOIP_PATH`, `ABUSEIPDB_API_KEY`, `VIRUSTOTAL_API_KEY`
(feed adapters self-disable while empty), `ALERT_REFIRE_WINDOW_SECONDS`, and
`ADMIN_BASE_URL` (absolute base URL used to build clickable links in alerts).

## Development

This repo doubles as the dev/demo project (`config/` holds the harness — it is
not part of the PyPI package):

```bash
cp .env.example .env
docker compose up
docker compose run --rm web pytest
```

Lint and types: `ruff check . && mypy .` (config lives in `pyproject.toml`).

## Releasing

CI (`.github/workflows/ci.yml`) runs ruff, mypy, and pytest with a coverage
gate on every push and PR. Publishing (`.github/workflows/publish.yml`)
triggers **only** on tags matching `v*.*.*`:

```bash
# bump __version__ in honeydj/__init__.py (single source of truth), then:
git tag v0.1.0 && git push origin v0.1.0
```

Requires a `PYPI_API_TOKEN` repository secret (PyPI → Account settings → API
tokens; use `__token__` scoped to this project after the first upload).

## License

MIT — see [LICENSE](LICENSE).
