About IPTeller
Server-side visitor and IP analytics.
IPTeller is a Django/PostgreSQL visitor analytics platform that uses Celery and Redis for asynchronous processing and GeoIP services to enrich public IP addresses with geographic and network intelligence.
How it works
Django middleware captures incoming requests and records visitor identity, IP address, request path, HTTP method, response status, referrer, user-agent, and response time. Visitors use persistent UUID cookies, while IP addresses are stored as unique records associated with individual visits.
Lightweight request recording stays in the HTTP lifecycle. Expensive work, including GeoIP enrichment, runs asynchronously through Celery so the monitored application does not wait for external services.
Asynchronous IP enrichment
When IPTeller sees an unprocessed public IP address, it sends an enrichment
job to the dedicated ipteller Celery queue. The worker queries
ipwho.is and stores country, city, latitude, longitude, ISP, and ASN data.
A processing flag prevents duplicate enrichment. Private, loopback, reserved, and non-public addresses are excluded from external lookups.
Internal architecture
Django application
│
▼
VisitorMiddleware
│
├── Identify visitor
├── Identify IP address
└── Record visit
│
▼
PostgreSQL
│
│ Unprocessed public IP
▼
Celery: ipteller queue
│
▼
Redis
│
▼
Celery worker
│
▼
GeoIP provider
│
▼
PostgreSQL
│
▼
Analytics UI / API
Core technologies
| Component | Technology | Purpose |
|---|---|---|
| Web framework | Django | Application, middleware, models, HTTP processing |
| Database | PostgreSQL | Persistent visitor, IP, and visit data |
| Task processing | Celery | Asynchronous and background processing |
| Message broker | Redis DB 0 | Celery task queue transport |
| Task results | Redis DB 2 | Ipteller Celery results |
| Scheduling | Celery Beat | Periodic retention and maintenance tasks |
| GeoIP | ipwho.is | Geographic and network enrichment |
| Web server | Gunicorn | Django application serving |
| Reverse proxy | Nginx | HTTPS termination and proxying |
| Runtime | Python 3.12 | Application runtime |
Designed as a reusable Django application
IPTeller can run as a standalone analytics service or as a reusable
analytics application inside an existing Django project.
Install the app, add its middleware, configure PostgreSQL, Redis, and
Celery, and the host project begins collecting and enriching visitor data.
The UI or a future REST API can expose traffic history, IP intelligence, geographic distributions, referrers, response-time statistics, bot detection, anomaly detection, and threat-intelligence signals.
Security and operations
- Manual enforcement: a Blocked status in Suspics is a review status and does not automatically block requests.
- Review actions: staff can review, allowlist, or temporarily block suspicious IP addresses.
- Threshold tuning: detection rules are reviewed over time to reduce false positives.
- Testing: middleware collection and risk-scoring rules should be tested before changes are deployed.
- Service monitoring: Celery Beat and workers run scheduled cleanup and risk analysis.
- Retention and access: analytics data is retained according to the configured policy and restricted to authorized staff.
Operational notes
- Public signup: new accounts are not staff and cannot access dashboards. Internal deployments may remove public signup entirely.
- IP privacy: IP addresses, user agents, and referrers can be personal data. Restrict access and document retention.
- Blocked is not enforcement: Suspics status records a decision only until explicit Nginx or Django enforcement is added.
- Trust boundary: Gunicorn uses a Unix socket and trusts Nginx forwarding headers. Keep the socket inaccessible to untrusted local users.
- Backups: back up PostgreSQL and test restoration before relying on long-term retention.
- Monitoring: monitor Celery Beat, workers, task retries, database growth, and unexpected 4xx or 5xx increases.
- Tests: test visit capture, GeoIP exclusions, retention cleanup, and Suspics scoring before tuning or enforcing scores.
Protection measures
For real protection, consider adding:
- Nginx rate limits and request-size limits.
- Fail2ban or firewall rules for confirmed abusive IP addresses.
- Django login throttling and strong admin access controls.
- A WAF or CDN for public-facing attacks.
- Manual review before blocking, using Suspics as evidence.
Scanner and reconnaissance detection
IPTeller can identify common automated reconnaissance requests by matching request paths against signatures associated with exposed secrets, configuration files, databases, frameworks, CMS platforms, API systems, webmail, and mail infrastructure.
A matching path is not automatically considered malicious. Detection is combined with other signals such as request frequency, response status, missing or unusual user-agent strings, repeated probing, and the number of different technologies targeted by the same IP address.
Secrets and configuration
/.env /.env.local /.env.production /.git/config /.git/HEAD /.svn/entries /.DS_Store /settings.py /local_settings.py /config/settings.py /project/settings.py /app/settings.py /config.php /configuration.php /config.yml /config.yaml /config.json /.forward /.procmailrc /.fetchmailrc /.msmtprc /.netrc /mail.conf /mail.ini /mail.yml /mail.json
Django
/admin/ /admin/login/ /admin/jsi18n/ /admin/autocomplete/ /__debug__/ /__debug__/render_panel /__debug__/history_sidebar /static/admin/ /static/admin/css/base.css /media/ /uploads/ /manage.py /requirements.txt /requirements-dev.txt /pyproject.toml /Pipfile /Pipfile.lock /poetry.lock /__pycache__/ /db.sqlite3 /db.sqlite /database.sqlite3
WordPress
/wp-admin/ /wp-login.php /xmlrpc.php /wp-config.php /wp-config.php.bak /wp-content/
Directus
/directus/ /directus/admin /directus/admin/ /server/health /server/info /server/ping /items/ /items/users /items/directus_users /items/directus_files /items/directus_settings /users /users/me /auth/login /auth/refresh /auth/logout /auth/password/request /auth/password/reset /graphql /graphql/system /schema /schema/snapshot /schema/diff /permissions /roles /policies /files /files/import /files/export /settings /settings/project /settings/data-model
PHP, database and server administration
/phpmyadmin/ /phpMyAdmin/ /pma/ /server-status /server-info
API and framework discovery
/actuator/env /actuator/health /swagger/ /swagger-ui/ /api-docs/ /openapi.json
Mail and webmail
/webmail/ /webmail/login /webmail/index.php /roundcube/ /roundcube/index.php /roundcube/?_task=login /rcmail/ /horde/ /squirrelmail/ /rainloop/ /afterlogic/ /snappymail/ /mail/ /mailadmin/ /mail-admin/ /mailserver/ /postfix/ /dovecot/ /admin/mail/ /admin/email/ /admin/mailserver/
Mail autodiscovery
/autodiscover/ /autodiscover/autodiscover.xml /Autodiscover/Autodiscover.xml /.well-known/autoconfig/mail/config-v1.1.xml /.well-known/autodiscover/autodiscover.xml
Microsoft Exchange and OWA
/owa/ /owa/auth.owa /EWS/ /EWS/Exchange.asmx /Microsoft-Server-ActiveSync/ /ecp/ /autodiscover/autodiscover.json
Backups and source files
/backup.zip /backup.tar.gz /site-backup.zip /wp-config.php.bak /.svn/entries /.DS_Store
Mail protocol reconnaissance
For mail infrastructure, reconnaissance can also occur outside HTTP. IPTeller can correlate suspicious activity with connections to common mail services such as SMTP, submission, IMAP, POP3, and ManageSieve.
SMTP 25 SMTPS 465 Submission 587 POP3 110 POP3S 995 IMAP 143 IMAPS 993 ManageSieve 4190
SMTP commands such as EHLO, HELO, and
AUTH are normal. Repeated VRFY,
EXPN, or rapid recipient enumeration can provide stronger
evidence of reconnaissance.
Important exceptions
Common paths such as /robots.txt, /admin/,
/static/admin/, and health-check endpoints are not inherently
malicious. IPTeller should treat them as contextual signals rather than
automatic evidence of abuse.
Scanner detection is therefore evidence-based: a single request to an administrative or discovery endpoint may be legitimate, while a rapid sequence targeting secrets, source files, multiple frameworks, databases, and mail systems is substantially more suspicious.
UFW firewall operations
Review and remove a blocked IP:
sudo ufw status numbered
sudo ufw delete 5
UFW will ask for confirmation.
Then verify the rules and reload UFW:
sudo ufw status numbered
sudo ufw reload