djlactose/dnsscaner

By djlactose

Updated 3 months ago

Monitors DNS records across multiple domains and be notified when problems are detected.

Image
Networking
Security
Monitoring & observability
0

10K+

djlactose/dnsscaner repository overview

DNS Scanner

A containerized Progressive Web App (PWA) that monitors DNS records across multiple domains, detects dead endpoints, identifies subdomain takeover risks, and sends notifications when issues are found.

Features

  • Full DNS Enumeration - AXFR zone transfer + per-type queries (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, SOA)
  • Health Checking - HTTPS, HTTP, TCP ports (443, 80, 22, 8443, 8080, 3389, 21), ICMP ping
  • Dead Record Detection - Records marked dead after 3 consecutive failed checks across scans
  • Subdomain Takeover Detection - Dangling CNAME detection for AWS S3, GitHub Pages, Heroku, Azure, Netlify, and 20+ cloud services
  • DNS Propagation Monitoring - Compare results across Google, Cloudflare, Quad9, and OpenDNS resolvers
  • Domain Expiry Monitoring - Whois-based expiry tracking with 90/30/14/7 day warnings
  • DNS Change Detection - Track when record values change between scans
  • SSL Certificate Tracking - Monitor validity, expiration, and errors
  • Push Notifications - Browser push via Web Push API (VAPID)
  • Email Notifications - Configurable SMTP with encrypted credentials
  • Webhooks - HMAC-signed webhooks with retry logic (Slack, Discord, Teams, Generic)
  • Multi-User Auth - Admin/viewer roles, bcrypt password hashing, session management, account lockout
  • Tagging & Grouping - Tag domains for filtering and targeted notifications
  • Bulk Import - CSV import up to 100 domains at once
  • Export & Reporting - CSV export and HTML print-ready reports
  • Trend Charts - Canvas-based health trend visualization
  • Real-time Updates - Server-Sent Events for live scan progress
  • PWA - Installable, offline-capable, responsive design with auto light/dark theme
  • Background Scanning - Configurable intervals per domain (15 min to 7 days)

Architecture

ServiceTechnologyPurpose
appNode.js 22 + ExpressAPI server, web UI, background worker
dbPostgreSQL 16Primary data store

Quick Start

1. Start the application
./start.sh

This generates a .env file with random secrets and starts the containers. If you prefer to manage secrets manually, copy .env.example to .env, fill in your own values, and run docker compose up -d.

2. Access the app

Open http://localhost:8080 in your browser.

The first user to register automatically becomes an admin.

Configuration

All configuration is via environment variables (see .env.example):

VariableRequiredDefaultDescription
DB_PASSWORDNoauto-generatedPostgreSQL password
SESSION_SECRETNoauto-generatedSession encryption key (min 32 chars)
ENCRYPTION_KEYNoauto-generatedSMTP credential encryption key (min 32 chars)
REGISTRATION_ENABLEDNotrueAllow new user registration
ALLOW_PRIVATE_RANGESNofalseAllow scanning private IP ranges
MAX_DOMAINSNo50Maximum domains per instance
APP_PORTNo8080Host port for web UI

Security

  • All database queries use parameterized queries (no SQL injection)
  • Frontend uses textContent only (no XSS via innerHTML)
  • Content Security Policy enforced
  • SSRF protection blocks private IP ranges by default
  • Passwords hashed with bcrypt (cost factor 12)
  • Account lockout after 5 failed attempts (15 min)
  • SMTP credentials encrypted with AES-256-GCM at rest
  • Webhooks signed with HMAC-SHA256
  • All containers run as non-root with minimal capabilities
  • Internal services not exposed to host network
  • Rate limiting on login, registration, scan triggers, and general API
  • Gzip compression enabled

Ports

ServiceContainer PortHost PortDescription
app8080${APP_PORT:-8080}Web UI and API
db5432not exposedPostgreSQL (internal only)

Only the app is exposed to the host network. The database communicates over an internal Docker bridge network.

Volumes

VolumeContainerMount PathPurpose
pgdatadb (PostgreSQL)/var/lib/postgresql/dataDatabase storage — all domains, records, scan history, and user accounts

This volume persists across container restarts and rebuilds. To manage it:

# Back up the database
docker compose exec db pg_dump -U dnsscanner dnsscanner > backup.sql

# Restore from backup
docker compose exec -T db psql -U dnsscanner dnsscanner < backup.sql

# Reset all data (destructive — removes everything)
docker compose down -v

How "Dead" Is Determined

A record is dead only when nothing responds at all — no HTTP, no TCP port, no ICMP ping. A server returning HTTP 500 or having an expired SSL certificate is still considered alive (the server is responding, just unhealthy).

Records are marked dead after 3 consecutive failed health checks across scans to avoid false positives from transient issues.

Check Cascade by Record Type
TypeChecks (stops at first success)
A/AAAAHTTPS -> HTTP -> TCP ports (443,80,22,8443,8080,3389,21) -> ICMP
CNAMEResolve target, then same as A/AAAA
MXTCP 25 -> TCP 587 -> TCP 465 -> ICMP
NSDNS query -> ICMP
SRVTCP host:port -> ICMP
TXT/CAA/SOASkipped (informational)

API

All endpoints require authentication unless noted. Admin-only endpoints require role: admin.

Auth
  • POST /api/auth/register - Create account
  • POST /api/auth/login - Login
  • POST /api/auth/logout - Logout
  • GET /api/auth/me - Current user
Domains (admin: create/update/delete)
  • GET /api/domains - List domains
  • POST /api/domains - Add domain
  • PUT /api/domains/:id - Update domain
  • DELETE /api/domains/:id - Delete domain
  • POST /api/domains/import - Bulk CSV import
Scanning
  • POST /api/domains/:id/scan - Manual scan
  • POST /api/scan-all - Scan all domains
  • GET /api/domains/:id/scans - Scan history
Records
  • GET /api/domains/:id/records - DNS records with health status
  • GET /api/records/:id/history - Health check history
  • GET /api/records/:id/changes - DNS change history
Dashboard
  • GET /api/dashboard - Summary stats, dead records, recent changes
Export
  • GET /api/domains/:id/export/csv - CSV download
  • GET /api/domains/:id/export/report - HTML report
Notifications & Webhooks
  • GET/PUT /api/notifications/settings - User notification preferences
  • POST /api/push/subscribe - Register push subscription
  • GET/POST/PUT/DELETE /api/webhooks - Webhook management
Real-time
  • GET /api/events - Server-Sent Events stream

Development

# Run without Docker (requires PostgreSQL)
npm install
DB_PASSWORD=dev SESSION_SECRET=$(openssl rand -hex 32) ENCRYPTION_KEY=$(openssl rand -hex 32) node server.js

License

MIT

Tag summary

Content type

Image

Digest

sha256:aa92ec862

Size

60.8 MB

Last updated

3 months ago

docker pull djlactose/dnsscaner:sha-17e7280b03c73ddd071e89b5d60a87114aa36a68