A modern, lightweight DNS server designed to automatically generate IPv6 PTR (reverse DNS) records on-the-fly. Perfect for ISPs, hosting providers, and network administrators who need dynamic reverse DNS for IPv6 subnets.
- Automatic PTR Generation: Dynamically creates PTR records for any IPv6 address within configured subnets
- Custom PTR Records: Support for custom PTR mappings via configuration files
- Multi-Protocol: Supports both UDP and TCP DNS protocols
- High Performance: Multi-threaded architecture with configurable worker pools
- Enterprise Configuration: YAML configuration files with environment variable support
- Docker Ready: Production-ready containerization with security hardening
- IPv6 Native: Built specifically for IPv6 with full dual-stack support
- Zero Downtime Config: Hot-reload configuration without service restart
Note: This DNS server is specialized for IPv6 PTR records only. It cannot handle other DNS record types by design.
- Python: 3.13+ (tested and optimized)
- Dependencies:
dnslib,pyyaml(see requirements.txt) - Network: IPv6-enabled network interface
- Permissions: Ability to bind to DNS port (53) or configured port
# Clone the repository
git clone https://github.com/uppaljs/ipv6autoptr.git
cd ipv6autoptr
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Configure your subnets in config.yaml
# Edit config.yaml to set your IPv6 subnets and domain
# Run the server
python ipv6autoptr.py --udp --port 5353 --verbose# Quick start with Docker
docker run -d \
--name ipv6autoptr \
-p 53:53/udp \
-e IPV6AUTOPTR_DOMAIN_SUFFIX="ip6.yourdomain.com." \
-e IPV6AUTOPTR_SUBNETS="2001:db8:1000::/48,2001:db8:2000::/64" \
uppal/ipv6autoptr:latest
# Or use docker-compose for full setup
docker-compose up -dThe server supports multiple configuration methods with the following priority order:
- Command Line Arguments (highest priority)
- Environment Variables (
IPV6AUTOPTR_*prefix) - Configuration File (
config.yaml) - Built-in Defaults (lowest priority)
# Server Configuration
server:
port: 53
bind_address: "::"
enable_udp: true
enable_tcp: false
verbose: 1
# DNS Configuration
dns:
ttl: 86400
domain_suffix: "ip6.yourdomain.com."
max_workers: 32
# IPv6 Subnets
ipv6:
subnets:
- "2001:db8:1000::/48"
- "2001:db8:2000::/64"
# Custom PTR Records
ptr_records:
config_file: "ipv6autoptr.conf"
use_custom: true
# Logging
logging:
level: "INFO"
format: "%(asctime)s - %(levelname)s - %(message)s"
file: nullPerfect for Docker and Kubernetes deployments:
IPV6AUTOPTR_PORT=53
IPV6AUTOPTR_BIND_ADDRESS="::"
IPV6AUTOPTR_DOMAIN_SUFFIX="ip6.yourdomain.com."
IPV6AUTOPTR_SUBNETS="2001:db8:1000::/48,2001:db8:2000::/64"
IPV6AUTOPTR_TTL=86400
IPV6AUTOPTR_VERBOSE=1
IPV6AUTOPTR_MAX_WORKERS=32See CONFIGURATION.md for complete configuration reference.
docker run -d \
--name ipv6autoptr \
--restart unless-stopped \
-p 53:53/udp \
-p 53:53/tcp \
-e IPV6AUTOPTR_DOMAIN_SUFFIX="ip6.example.com." \
-e IPV6AUTOPTR_SUBNETS="2001:db8:1000::/48" \
-e IPV6AUTOPTR_VERBOSE=1 \
uppal/ipv6autoptr:latestversion: '3.8'
services:
ipv6autoptr:
image: ghcr.io/uppaljs/ipv6autoptr:latest
container_name: ipv6autoptr
restart: unless-stopped
ports:
- "53:53/udp"
- "53:53/tcp"
environment:
- IPV6AUTOPTR_PORT=53
- IPV6AUTOPTR_DOMAIN_SUFFIX=ip6.yourdomain.com.
- IPV6AUTOPTR_SUBNETS=2001:db8:1000::/32
- IPV6AUTOPTR_VERBOSE=1
- IPV6AUTOPTR_TTL=3600
volumes:
- ./custom-ptr-records.conf:/app/ipv6autoptr.conf:ro
networks:
- dns_network
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
read_only: true
tmpfs:
- /tmpapiVersion: apps/v1
kind: Deployment
metadata:
name: ipv6autoptr
spec:
replicas: 2
selector:
matchLabels:
app: ipv6autoptr
template:
metadata:
labels:
app: ipv6autoptr
spec:
containers:
- name: ipv6autoptr
image: ghcr.io/uppaljs/ipv6autoptr:latest
ports:
- containerPort: 53
protocol: UDP
env:
- name: IPV6AUTOPTR_DOMAIN_SUFFIX
value: "ip6.yourdomain.com."
- name: IPV6AUTOPTR_SUBNETS
value: "2001:db8:1000::/32"When a PTR query is received for an IPv6 address:
- Parse: Extract IPv6 address from
ip6.arpaquery - Validate: Check if address is within configured subnets
- Lookup: Check for custom PTR record in config file
- Generate: Create automatic PTR record if no custom mapping exists
- Respond: Return PTR response with configured TTL
# Query for 2001:db8:1000::251
$ dig @your-server -x 2001:db8:1000::251
# Automatic Response:
1.5.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
β 20010db8100000000000000000000251.ip6.yourdomain.com.
# Query for custom record
$ dig @your-server -x 2001:db8:1000::1
# Custom Response (if configured):
β server.yourdomain.com.Create custom mappings in ipv6autoptr.conf:
# Format: <ipv6-address-in-arpa-format> = <custom-domain-name>
# Custom PTR for 2001:db8:1000::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. = server.yourdomain.com.
# Custom PTR for 2001:db8:1000::5
5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. = mail.yourdomain.com.# Download and install
wget https://github.com/uppaljs/ipv6autoptr/releases/latest/download/ipv6autoptr.py -O /usr/local/bin/ipv6autoptr.py
chmod 755 /usr/local/bin/ipv6autoptr.py
# Create service file
cat > /etc/systemd/system/ipv6autoptr.service << EOF
[Unit]
Description=IPv6 Auto PTR DNS Server
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=dns
Group=dns
WorkingDirectory=/etc/ipv6autoptr
ExecStart=/usr/bin/python3 /usr/local/bin/ipv6autoptr.py --config /etc/ipv6autoptr/config.yaml
ExecReload=/bin/kill -s HUP \$MAINPID
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/etc/ipv6autoptr
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
systemctl daemon-reload
systemctl enable ipv6autoptr.service
systemctl start ipv6autoptr.serviceFor high-traffic environments:
dns:
max_workers: 64 # Increase worker threads
ttl: 3600 # Lower TTL for faster updates
server:
enable_tcp: true # Enable TCP for large responses
enable_udp: true # Keep UDP for standard queries
logging:
level: "WARNING" # Reduce log verbosity# Test automatic PTR generation
dig @localhost -p 5353 -x 2001:db8:1000::10
# Test custom PTR record
dig @localhost -p 5353 -x 2001:db8:1000::1
# Test NXDOMAIN response (out of subnet)
dig @localhost -p 5353 -x 2001:db8:9000::1
# Performance test
dig @localhost -p 5353 -x 2001:db8:1000::$(shuf -i 1-1000 -n 1)# Install dnsperf for load testing
sudo apt-get install dnsperf
# Create test file
echo "2001:db8:1000::10 PTR" > test-queries.txt
# Run performance test
dnsperf -s localhost -p 5353 -d test-queries.txt -c 10 -T 10# Docker health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD dig @localhost -p $IPV6AUTOPTR_PORT -x 2001:db8:1::1 || exit 1
# Kubernetes readiness probe
readinessProbe:
exec:
command:
- dig
- "@localhost"
- "-x"
- "2001:db8:1::1"
initialDelaySeconds: 5
periodSeconds: 10# Example metrics endpoint (planned feature)
curl http://localhost:9090/metrics
# Sample metrics:
# ipv6autoptr_queries_total{type="automatic"} 1234
# ipv6autoptr_queries_total{type="custom"} 567
# ipv6autoptr_query_duration_seconds{quantile="0.95"} 0.001# Clone and setup
git clone https://github.com/uppaljs/ipv6autoptr.git
cd ipv6autoptr
# Setup development environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run with development config
cp config.yaml config-dev.yaml
# Edit config-dev.yaml with development settings
python ipv6autoptr.py --config config-dev.yaml --port 5353 --verbose# Build image
docker build -t ipv6autoptr:dev .
# Test image
docker run --rm -p 5353:53/udp ipv6autoptr:dev# Install test dependencies
pip install pytest pytest-cov
# Run tests
pytest tests/ -v --cov=ipv6autoptr
# Test specific functionality
python -m pytest tests/test_config.py -vIf you're upgrading from the original hardcoded version:
- Create Configuration File: Use your existing hardcoded values
- Update Systemd Service: Use new configuration-based startup
- Test Configuration: Verify all settings work correctly
- Deploy Gradually: Test in development first
# Extract current configuration
python3 -c "
from ipv6autoptr import Config
config = Config('config.yaml')
print('Current configuration loaded successfully')
print(f'Subnets: {config.subnets}')
print(f'Domain: {config.domain_suffix}')
"We welcome contributions! Please see our Contributing Guidelines for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Dmitriy Terehin - Original implementation and concept - @meatlayer
- Junaid Saeed Uppal - Modernization, Docker support, configuration system - @uppaljs
- β Python 3.13 Support - Latest Python compatibility
- β YAML Configuration - Professional configuration management
- β Environment Variables - Docker and Kubernetes ready
- β Docker Support - Production-ready containerization
- β Security Hardening - Non-root user, minimal privileges
- β Comprehensive Documentation - Usage guides and examples
- β Performance Improvements - Configurable threading and optimization
- β Modern Development - Virtual environments, pinned dependencies
- β Production Ready - Health checks, monitoring, logging
- β CI/CD Pipeline - Automated testing, building, and releases
This project features a complete automated CI/CD pipeline with GitHub Actions:
- β Multi-Python Testing - Tests across Python 3.11, 3.12, and 3.13
- β Code Quality Checks - Automated linting, formatting, and security scans
- β Docker Build Validation - Ensures containers build correctly
- β Configuration Validation - YAML syntax and configuration testing
- π·οΈ Semantic Versioning - Create releases with
git tag v1.0.0 - π³ Multi-Platform Docker Images - Automatic builds for AMD64 and ARM64
- π Generated Changelogs - Automatic release notes from commit history
- π Security Scanning - Container vulnerability analysis with Trivy
Official Images: uppal/ipv6autoptr
# Latest stable release
docker pull uppal/ipv6autoptr:latest
# Specific version
docker pull uppal/ipv6autoptr:v1.0.0
# Development builds
docker pull uppal/ipv6autoptr:mainSupported Platforms:
linux/amd64(Intel/AMD 64-bit)linux/arm64(ARM64/Apple Silicon)
See .github/ACTIONS.md for detailed CI/CD documentation, including:
- Setting up Docker Hub credentials
- Creating releases
- Workflow customization
- Troubleshooting guide
- Bug Reports: GitHub Issues
- Feature Requests: GitHub Discussions
- Security Issues: GitHub Issues
- Prometheus Metrics - Built-in monitoring support
- DNS-over-HTTPS - Modern DNS protocol support
- Rate Limiting - Built-in DDoS protection
- Geographic PTR - Location-based PTR generation
- API Interface - REST API for management
- High Availability - Clustering and failover support
Tested on modern hardware with Python 3.13:
| Metric | Value |
|---|---|
| Queries/second | 10,000+ (single instance) |
| Memory usage | < 50MB (base) |
| CPU usage | < 5% (normal load) |
| Response time | < 1ms (average) |
| Concurrent connections | 1000+ |
Made with β€οΈ for the IPv6 community