Skip to content

Latest commit

 

History

135 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DNSTrailer - DNS Monitoring & Change Alerting System

A comprehensive DNS monitoring system built with Django that replicates the functionality of zonewatcher.com. Monitor DNS records across multiple providers, track changes, and receive real-time alerts via email, webhooks, Slack, Teams, and Discord.

Features

Core Features

  • DNS Record Monitoring: Monitor all major DNS record types (A, AAAA, MX, TXT, CNAME, NS, SOA, SRV, CAA, PTR)
  • Real-Time Change Detection: Instantly detect and log DNS record changes with full audit history
  • Multi-Provider Support: Direct API integration with major DNS providers:
    • Cloudflare
    • AWS Route53
    • Google Cloud DNS
    • Azure DNS
    • DigitalOcean DNS
    • DNS Made Easy
    • Public DNS (any domain)

Public DNS Scanner

  • Automatically scan domains for common DNS records
  • Pre-configured with 5000+ most common subdomain names
  • Discover records without DNS provider API access

Notification System

  • Multiple Channels:
    • Email
    • Webhooks (custom HTTP endpoints)
    • Slack
    • Microsoft Teams
    • Discord
  • Flexible Filtering: Configure which change types trigger notifications
  • Maintenance Windows: Suppress alerts during planned maintenance

Additional Features

  • Domain expiration monitoring via WHOIS
  • Complete change history with unlimited retention
  • RESTful API for programmatic access
  • Modern web interface with Tailwind CSS
  • Django admin panel for easy management

Quick Start

Prerequisites

  • Python 3.11+
  • pip
  • SQLite (default) or PostgreSQL (recommended for production)

Installation

Quick Setup (Recommended)

Use the provided setup script for automated installation:

Linux/macOS:

git clone <repository-url>
cd zonewatcher-poc
chmod +x setup.sh
./setup.sh

Windows:

git clone <repository-url>
cd zonewatcher-poc
setup.bat

The setup script will automatically:

  • Create and activate a virtual environment (.venv)
  • Install all dependencies
  • Run database migrations
  • Create necessary directories
  • Prompt to create a superuser

Manual Setup

If you prefer manual installation:

  1. Clone the repository
git clone <repository-url>
cd zonewatcher-poc
  1. Create necessary directories
mkdir -p logs static staticfiles
  1. Create and activate virtual environment
# Create virtual environment
python3 -m venv .venv

# Activate virtual environment
# On Linux/macOS:
source .venv/bin/activate

# On Windows:
# .venv\Scripts\activate
  1. Install dependencies
pip install -r requirements.txt
  1. Run migrations
python manage.py migrate
  1. Create a superuser
python manage.py createsuperuser
  1. Run the development server
# For local access only
python manage.py runserver

# For access from other machines (specify IP and port)
python manage.py runserver 0.0.0.0:8000

Accessing the Application

Once the server is running:

Note: The application is configured with ALLOWED_HOSTS = ['*'] for development, allowing access from any IP. For production, restrict this to specific domains.

Note: Always ensure your virtual environment is activated before running any Python/Django commands:

# Linux/macOS
source .venv/bin/activate

# Windows
.venv\Scripts\activate

For more details on virtual environment usage, see VIRTUAL_ENV_GUIDE.md

Configuration

Dependencies

The project uses a minimal set of required dependencies with optional packages you can enable as needed.

Required dependencies (automatically installed):

  • Django 5.0.1
  • Django REST Framework
  • dnspython
  • requests
  • python-dateutil
  • pytz

Optional dependencies (commented out in requirements.txt):

  • PostgreSQL: psycopg2-binary - For production database (recommended)
  • DNS Providers: Individual provider SDKs (Cloudflare, AWS Route53, Google Cloud, Azure, DigitalOcean)
  • Email: sendgrid - For advanced email features
  • Additional Django packages: CORS headers, filtering, static file serving

To enable optional dependencies, edit requirements.txt and uncomment the packages you need, then run:

pip install -r requirements.txt

Database Configuration

By default, the application uses SQLite. For production, configure PostgreSQL in zonewatcher/settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'zonewatcher',
        'USER': 'your_user',
        'PASSWORD': 'your_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Email Configuration

Configure email settings in zonewatcher/settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'
EMAIL_HOST_PASSWORD = 'your-app-password'
DEFAULT_FROM_EMAIL = 'noreply@yourdomain.com'

Usage Guide

1. Adding DNS Providers

Navigate to Admin Panel → DNS Providers → Add DNS Provider

Cloudflare Example:

  • Name: My Cloudflare Account
  • Provider Type: Cloudflare
  • API Key: Your Cloudflare API token
  • Is Active: Yes

Public DNS Example:

  • Name: Public DNS
  • Provider Type: Public DNS
  • (No API key needed)

2. Adding Domains

Admin Panel → Domains → Add Domain

  • Name: example.com
  • Provider: Select your DNS provider
  • Check Interval: 300 (seconds)
  • Status: Active

3. Configuring Notifications

Email Notification

Admin Panel → Notification Channels → Add

  • Name: Email Alerts
  • Channel Type: Email
  • Email Address: alerts@yourdomain.com
  • Notify on Create/Modify/Delete: Yes

Webhook Notification

Slack Notification

4. Linking Notifications to Domains

Admin Panel → Domain Notification Channels → Add

  • Domain: example.com
  • Channel: Select notification channel

5. Manual DNS Check

Via API:

curl -X POST http://localhost:8000/api/domains/{id}/check_now/ \
  -H "Authorization: Bearer YOUR_TOKEN"

6. Scanning a Domain

Use the public DNS scanner to discover records:

curl -X POST http://localhost:8000/api/domains/scan/ \
  -H "Content-Type: application/json" \
  -d '{
    "domain_name": "example.com",
    "limit": 5000
  }'

API Documentation

Authentication

The API uses session authentication. To access protected endpoints:

  1. Login via the web interface at /api-auth/login/
  2. Use session cookies for subsequent requests

API Endpoints

Domains

GET    /api/domains/              List all domains
POST   /api/domains/              Create domain
GET    /api/domains/{id}/         Get domain details
PUT    /api/domains/{id}/         Update domain
DELETE /api/domains/{id}/         Delete domain
POST   /api/domains/{id}/check_now/  Trigger immediate check
GET    /api/domains/{id}/records/    Get domain records
GET    /api/domains/{id}/history/    Get change history
POST   /api/domains/scan/            Scan domain

DNS Providers

GET    /api/providers/                    List providers
POST   /api/providers/                    Create provider
GET    /api/providers/{id}/               Get provider
PUT    /api/providers/{id}/               Update provider
DELETE /api/providers/{id}/               Delete provider
POST   /api/providers/{id}/test_connection/  Test connection

DNS Records

GET    /api/dns-records/          List all records
GET    /api/dns-records/{id}/     Get record details

Change History

GET    /api/history/              List all changes
GET    /api/history/{id}/         Get change details

Notification Channels

GET    /api/notification-channels/        List channels
POST   /api/notification-channels/        Create channel
GET    /api/notification-channels/{id}/   Get channel
PUT    /api/notification-channels/{id}/   Update channel
DELETE /api/notification-channels/{id}/   Delete channel
POST   /api/notification-channels/{id}/test/  Send test notification

Notification Logs

GET    /api/notification-logs/    List notification logs
GET    /api/notification-logs/{id}/  Get log details

Maintenance Windows

GET    /api/maintenance-windows/         List windows
POST   /api/maintenance-windows/         Create window
GET    /api/maintenance-windows/{id}/    Get window
PUT    /api/maintenance-windows/{id}/    Update window
DELETE /api/maintenance-windows/{id}/    Delete window

API Examples

Get All Domains

curl -X GET http://localhost:8000/api/domains/ \
  -H "Content-Type: application/json"

Create Domain

curl -X POST http://localhost:8000/api/domains/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "example.com",
    "provider": 1,
    "status": "active",
    "check_interval": 300
  }'

Trigger DNS Check

curl -X POST http://localhost:8000/api/domains/1/check_now/

View Change History

curl -X GET http://localhost:8000/api/domains/1/history/

Create Webhook Notification

curl -X POST http://localhost:8000/api/notification-channels/ \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Webhook",
    "channel_type": "webhook",
    "webhook_url": "https://example.com/webhook",
    "webhook_method": "POST",
    "is_active": true,
    "notify_on_create": true,
    "notify_on_modify": true,
    "notify_on_delete": true
  }'

Webhook Payload Format

When DNS changes are detected, webhooks receive the following JSON payload:

{
  "event": "dns_record_change",
  "domain": "example.com",
  "change_type": "modified",
  "record": {
    "type": "A",
    "name": "www",
    "old_value": "1.2.3.4",
    "new_value": "5.6.7.8",
    "old_ttl": 300,
    "new_ttl": 600,
    "old_priority": null,
    "new_priority": null
  },
  "detected_at": "2024-01-15T10:30:00Z",
  "summary": "Modified A record www: Value: 1.2.3.4 → 5.6.7.8, TTL: 300 → 600"
}

Architecture

Project Structure

zonewatcher-poc/
├── core/                    # Core DNS monitoring functionality
│   ├── models.py           # Domain, DNSRecord, DNSRecordHistory models
│   ├── dns_monitor.py      # DNS monitoring service
│   └── admin.py            # Admin configuration
├── providers/              # DNS provider integrations
│   ├── dns_providers.py    # Provider implementations
│   └── common_subdomains.py # 5000+ common subdomain list
├── notifications/          # Notification system
│   ├── models.py           # NotificationChannel, NotificationLog
│   ├── notification_service.py  # Notification handlers
│   └── admin.py            # Admin configuration
├── api/                    # REST API
│   ├── serializers.py      # API serializers
│   ├── views.py            # API viewsets
│   └── urls.py             # API URL configuration
├── templates/              # HTML templates
│   └── index.html          # Landing page
├── static/                 # Static files
├── zonewatcher/           # Django project settings
│   ├── settings.py
│   └── urls.py
└── manage.py

Models Overview

  • DNSProvider: DNS provider configurations (API credentials)
  • Domain: Domains to monitor
  • DNSRecord: Current DNS records
  • DNSRecordHistory: Change history log
  • NotificationChannel: Notification configurations
  • NotificationLog: Notification delivery log
  • MaintenanceWindow: Scheduled maintenance periods
  • DomainExpirationAlert: Domain expiration tracking

Supported DNS Providers

The system includes integration code for multiple DNS providers. To use a specific provider, uncomment the corresponding package in requirements.txt and install it.

Public DNS (No Installation Required)

  • Installation: None required (works out of the box)
  • Use case: Monitor any publicly accessible domain
  • Queries public DNS servers (Google DNS, Cloudflare DNS)
  • Scans 5000+ common subdomains
  • Perfect for getting started or monitoring external domains

Cloudflare

  • Installation: Uncomment cloudflare==2.19.2 in requirements.txt
  • Requirements: API token with DNS read permissions
  • Automatic zone discovery
  • Full record type support

AWS Route53

  • Installation: Uncomment boto3==1.34.34 in requirements.txt
  • Requirements: AWS access key and secret key
  • Automatic hosted zone discovery
  • Supports all Route53 record types

Google Cloud DNS

  • Installation: Uncomment google-cloud-dns==0.35.0 in requirements.txt
  • Requirements: Service account JSON credentials and Project ID
  • Supports all Google Cloud DNS record types

Azure DNS

  • Installation: Uncomment azure-mgmt-dns==8.1.0 in requirements.txt
  • Requirements: Azure credentials

DigitalOcean DNS

  • Installation: Uncomment python-digitalocean==1.17.0 in requirements.txt
  • Requirements: DigitalOcean API token

Scheduled Monitoring

To enable automatic DNS monitoring, set up a scheduled task (cron or similar):

# Example management command (create in core/management/commands/)
from django.core.management.base import BaseCommand
from core.models import Domain
from core.dns_monitor import DNSMonitor
from django.utils import timezone

class Command(BaseCommand):
    help = 'Check all active domains'

    def handle(self, *args, **options):
        domains = Domain.objects.filter(
            status='active',
            next_check__lte=timezone.now()
        )

        for domain in domains:
            monitor = DNSMonitor(domain)
            result = monitor.check_domain()
            self.stdout.write(f"Checked {domain.name}: {result}")

Run via cron:

*/5 * * * * cd /path/to/zonewatcher-poc && python manage.py check_domains

Security Considerations

  1. API Keys: Store sensitive credentials securely, use environment variables
  2. HTTPS: Always use HTTPS in production
  3. Authentication: Enable authentication for API endpoints
  4. Rate Limiting: Implement rate limiting for public-facing APIs
  5. Input Validation: All user inputs are validated via Django forms/serializers
  6. SQL Injection: Protected by Django ORM
  7. XSS: Protected by Django template escaping

Production Deployment

This guide provides step-by-step instructions for deploying DNSTrailer in production using uWSGI, nginx, and systemd.

Prerequisites

  • Ubuntu/Debian Linux server
  • Python 3.11+
  • nginx web server
  • sudo access

Important Security Settings

⚠️ CRITICAL: The default settings allow all hosts (ALLOWED_HOSTS = ['*']) for development convenience. This MUST be changed for production!

  1. Set DEBUG = False in settings.py

    DEBUG = False
  2. Configure ALLOWED_HOSTS with your specific domains

    ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com', 'your-ip-address']
  3. Use PostgreSQL instead of SQLite for better performance and reliability

  4. Set up proper SMTP for email notifications via the web interface at /portal/settings/

Step 1: Install System Dependencies

sudo apt update
sudo apt install -y python3.11 python3.11-venv python3-pip nginx

Step 2: Clone and Setup Application

# Clone the repository
cd /home/yourusername
git clone <repository-url> zonewatcher-poc
cd zonewatcher-poc

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Install uWSGI
pip install uwsgi

# Create necessary directories
mkdir -p logs staticfiles media

# Run migrations
python manage.py migrate

# Collect static files
python manage.py collectstatic --noinput

# Create superuser
python manage.py createsuperuser

Step 3: Configure uWSGI

The repository includes a production-ready uWSGI configuration at uwsgi-production.ini. Verify the paths match your installation:

[uwsgi]
# Django-related settings
chdir           = /home/yourusername/zonewatcher-poc
module          = zonewatcher.wsgi:application
home            = /home/yourusername/zonewatcher-poc/.venv

# Process-related settings
master          = true
processes       = 4
threads         = 2
enable-threads  = true

# Socket (for nginx)
socket          = /home/yourusername/zonewatcher-poc/uwsgi.sock
chmod-socket    = 666
vacuum          = true

# Logging
logto           = /home/yourusername/zonewatcher-poc/logs/uwsgi.log
disable-logging = false

# Performance
buffer-size     = 65535
harakiri        = 300
socket-timeout  = 60

# Environment
env             = DJANGO_SETTINGS_MODULE=zonewatcher.settings
pythonpath      = /home/yourusername/zonewatcher-poc

# Reload
touch-reload    = /home/yourusername/zonewatcher-poc/reload.txt
die-on-term     = true

Step 4: Configure Systemd Service

Copy the service file to systemd:

sudo cp dnstrailer.service /etc/systemd/system/dns-trailer.service

Edit the service file if needed to match your username:

sudo nano /etc/systemd/system/dns-trailer.service

The service file should look like this:

[Unit]
Description=DNSTrailer uWSGI Service
After=network.target

[Service]
Type=simple
User=yourusername
Group=www-data
WorkingDirectory=/home/yourusername/zonewatcher-poc
Environment="PATH=/home/yourusername/zonewatcher-poc/.venv/bin:/usr/bin"
ExecStart=/home/yourusername/zonewatcher-poc/.venv/bin/uwsgi --ini /home/yourusername/zonewatcher-poc/uwsgi-production.ini
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Step 5: Configure Nginx

Copy and configure the nginx configuration:

sudo cp nginx-dnstrailer.conf /etc/nginx/sites-available/nginx-dnstrailer.conf

Edit the file to match your setup:

sudo nano /etc/nginx/sites-available/nginx-dnstrailer.conf

The configuration should look like this:

upstream dnstrailer {
    server unix:///home/yourusername/zonewatcher-poc/uwsgi.sock;
}

server {
    listen 8002;
    server_name your-server-ip dnstrailer.local;
    charset utf-8;

    # Max upload size
    client_max_body_size 10M;

    # Logs
    access_log /var/log/nginx/dnstrailer_access.log;
    error_log /var/log/nginx/dnstrailer_error.log;

    # Django static files
    location /static {
        alias /home/yourusername/zonewatcher-poc/staticfiles;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Django media files
    location /media {
        alias /home/yourusername/zonewatcher-poc/media;
        expires 7d;
    }

    # Send all other requests to Django
    location / {
        uwsgi_pass dnstrailer;
        include uwsgi_params;
        uwsgi_read_timeout 300;

        # Security headers
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "OK\n";
        add_header Content-Type text/plain;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/nginx-dnstrailer.conf /etc/nginx/sites-enabled/

Step 6: Set Required Permissions

Critical for nginx to access the uWSGI socket:

# Directory permissions (nginx must be able to traverse to the socket)
chmod 755 /home/yourusername
chmod 755 /home/yourusername/zonewatcher-poc

# Project ownership
sudo chown -R yourusername:www-data /home/yourusername/zonewatcher-poc

# Add user to www-data group
sudo usermod -a -G www-data yourusername

# Ensure logs directory exists
mkdir -p /home/yourusername/zonewatcher-poc/logs

Step 7: Enable and Start Services

# Reload systemd daemon
sudo systemctl daemon-reload

# Enable service to start on boot
sudo systemctl enable dns-trailer.service

# Start the service
sudo systemctl start dns-trailer.service

# Check service status
sudo systemctl status dns-trailer.service

# Test nginx configuration
sudo nginx -t

# Reload nginx
sudo systemctl reload nginx

Step 8: Verify Deployment

# Check service is running
sudo systemctl status dns-trailer.service

# Verify socket exists and has correct permissions
ls -la /home/yourusername/zonewatcher-poc/uwsgi.sock

# Test nginx can access socket
sudo -u www-data test -r /home/yourusername/zonewatcher-poc/uwsgi.sock && echo "OK" || echo "FAIL"

# Test application
curl http://your-server-ip:8002

# Or access via browser
# http://your-server-ip:8002

Useful Management Commands

# Restart the service
sudo systemctl restart dns-trailer.service

# Stop the service
sudo systemctl stop dns-trailer.service

# View service logs
sudo journalctl -u dns-trailer.service -f

# View uWSGI logs
tail -f ~/zonewatcher-poc/logs/uwsgi.log

# View nginx logs
sudo tail -f /var/log/nginx/dnstrailer_error.log
sudo tail -f /var/log/nginx/dnstrailer_access.log

# Hot reload Django (without restarting service)
touch ~/zonewatcher-poc/reload.txt

Troubleshooting

502 Bad Gateway Error

  1. Check uWSGI service is running:

    sudo systemctl status dns-trailer.service
  2. Verify socket exists and permissions are correct:

    ls -la /home/yourusername/zonewatcher-poc/uwsgi.sock
    # Should show: srw-rw-rw-
  3. Check directory permissions:

    namei -l /home/yourusername/zonewatcher-poc/uwsgi.sock
    # All directories should have at least 755 (drwxr-xr-x)
  4. Test nginx can access socket:

    sudo -u www-data test -r /home/yourusername/zonewatcher-poc/uwsgi.sock && echo "OK" || echo "FAIL"
  5. Check logs for errors:

    tail -50 ~/zonewatcher-poc/logs/uwsgi.log
    sudo tail -50 /var/log/nginx/dnstrailer_error.log

Service Won't Start

  1. Check for syntax errors in uwsgi-production.ini
  2. Verify virtual environment exists and has correct packages
  3. Check service logs: sudo journalctl -u dns-trailer.service -n 50

Static Files Not Loading

  1. Collect static files: python manage.py collectstatic --noinput
  2. Verify nginx has permission to read staticfiles directory
  3. Check nginx configuration paths match actual directories

SSL/TLS Setup (Optional but Recommended)

For production, set up SSL/TLS certificates using Let's Encrypt:

# Install certbot
sudo apt install certbot python3-certbot-nginx

# Obtain certificate (replace with your domain)
sudo certbot --nginx -d yourdomain.com

# Certificates auto-renew via cron

Database Backup Strategy

For production, set up automated PostgreSQL backups:

# Create backup script
cat > ~/backup-db.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/home/yourusername/backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
pg_dump dnstrailer > $BACKUP_DIR/dnstrailer_$DATE.sql
# Keep only last 7 days
find $BACKUP_DIR -name "dnstrailer_*.sql" -mtime +7 -delete
EOF

chmod +x ~/backup-db.sh

# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /home/yourusername/backup-db.sh") | crontab -

Troubleshooting

DNS Queries Failing

  • Check network connectivity
  • Verify DNS provider API credentials
  • Ensure firewall allows DNS queries (port 53)

Notifications Not Sending

  • Check notification channel configuration
  • Verify webhook URLs are accessible
  • Check email SMTP settings
  • Review notification logs in admin panel

Performance Issues

  • Increase check interval for domains
  • Optimize database with indexes
  • Use PostgreSQL for better performance
  • Implement caching for frequently accessed data

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues.

License

This project is provided as-is for educational and testing purposes.

Support

For issues and questions, please use the GitHub issue tracker.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages