UNPKG

pork2bind

Version:

Convert Porkbun DNS records to BIND zone files

472 lines (360 loc) 14.1 kB
# pork2bind Convert Porkbun DNS records to BIND zone files with a simple two-phase workflow. ## Features - **Two-phase operation**: Fetch DNS data from Porkbun API, then convert to BIND format - **Batch processing**: Handle multiple domains at once - **Domain discovery**: Automatically find all domains in your Porkbun account - **Pattern filtering**: Include/exclude domains using glob patterns (`*.com`, `test-*`) - **API access checking**: Detect which domains have API access enabled - **Smart filtering**: Automatically filters out external NS records (with override option) - **Flexible directories**: Control input/output locations - **Standard BIND format**: Generates properly formatted zone files with timestamp-based serials, priority-sorted MX records, and RFC-compliant quoted TXT values - **Clean output control**: Quiet mode and stdout output for scripting and automation - **Error resilience**: Continue processing even when some domains fail ## Installation 1. Clone this repository: ```bash git clone https://github.com/smurp/pork2bind.git cd pork2bind ``` 2. Install dependencies: ```bash npm install ``` 3. Make executable: ```bash chmod +x pork2bind ``` 4. Create your `.env` file: ```bash cp .env.example .env # Edit .env with your Porkbun API credentials ``` ## Configuration Create a `.env` file in the project directory: ```bash PORKBUN_API_KEY=pk1_your_api_key_here PORKBUN_SECRET_KEY=sk1_your_secret_key_here ``` ### Getting Porkbun API Keys 1. Log into your [Porkbun account](https://porkbun.com) 2. Go to Account Settings → API Access 3. Generate your API key and secret key 4. Enable API access for your domains ## Usage ### Domain Discovery First, discover what domains you own and which have API access: ```bash # List all domains in your Porkbun account pork2bind --list-domains # List only .com domains pork2bind --list-domains --all-domains --match "*.com" # Check which domains have API access enabled pork2bind --check-api-access --all-domains # Check API access for only production domains pork2bind --check-api-access --all-domains --match "prod-*" # Get only API-enabled domains for scripting pork2bind --check-api-access --all-domains --stdout > enabled-domains.txt ``` ### Phase 1: Fetch DNS Records Retrieve DNS records from Porkbun and save as JSON files: ```bash # Single domain pork2bind --json example.com # Multiple specific domains pork2bind --json example.com other.com # All domains in your account pork2bind --json --all-domains # Only domains with API access enabled (skip problematic ones) pork2bind --json --all-domains --api-enabled-only # Continue processing even if some domains fail pork2bind --json --all-domains --continue-on-error # Only process .com domains pork2bind --json --all-domains --match "*.com" # Process everything except test domains pork2bind --json --all-domains --exclude "test-*" # Save to specific directory pork2bind --json --all-domains --to ./dns-cache ``` This creates `example.com.json` with all DNS records from Porkbun. ### Phase 2: Generate BIND Zone Files Convert JSON files to BIND zone format: ```bash # Single domain (reads example.com.json, creates db.example.com) pork2bind --bind example.com # Multiple domains pork2bind --bind example.com other.com # Specify input/output directories pork2bind --bind example.com --from ./dns-cache --to /etc/bind/zones # Include NS records (normally filtered out) pork2bind --bind example.com --include-ns ``` ## Command Line Options ### Global Options - `--to <directory>` - Output directory (default: current directory) - `--quiet` - Minimal output, only errors and warnings - `--stdout` - Output data to stdout instead of files (for piping) - `--all-domains` - Process all domains in your Porkbun account - `--api-enabled-only` - Only process domains with API access enabled - `--continue-on-error` - Continue processing even if some domains fail - `--match <pattern>` - Only include domains matching glob pattern - `--exclude <pattern>` - Exclude domains matching glob pattern - `--help` - Show help message ### Discovery Commands - `--list-domains` - List all domains in your Porkbun account - `--check-api-access` - Check which domains have API access enabled ### JSON Mode (`--json`) - Fetches DNS records from Porkbun API - Saves records as `domain.json` files (or to stdout with `--stdout`) - Requires valid API credentials in `.env` - Can process individual domains or all domains in account ### BIND Mode (`--bind`) - `--from <directory>` - Input directory for JSON files (default: current directory) - `--include-ns` - Include NS records in output (default: filtered out) - Converts JSON to BIND zone files as `db.domain` (or to stdout with `--stdout`) ## Examples ### Simple Workflow ```bash # Fetch data pork2bind --json mysite.com # Generate zone file pork2bind --bind mysite.com ``` ### Domain Discovery and Management ```bash # See all your domains pork2bind --list-domains # See only .com domains pork2bind --list-domains --all-domains --match "*.com" # Check API access for production domains pork2bind --check-api-access --all-domains --match "prod-*" # Backup all API-enabled .org domains pork2bind --json --all-domains --match "*.org" --api-enabled-only --to ./org-backup # Process all domains except test ones pork2bind --json --all-domains --exclude "test-*" --exclude "dev-*" --quiet ``` ### Pattern Filtering Examples ```bash # Match patterns (--match) pork2bind --json --all-domains --match "*.com" # All .com domains pork2bind --json --all-domains --match "prod-*" # Domains starting with "prod-" pork2bind --json --all-domains --match "*-staging" # Domains ending with "-staging" # Exclude patterns (--exclude) pork2bind --json --all-domains --exclude "test-*" # Exclude test domains pork2bind --json --all-domains --exclude "temp-*" # Exclude temporary domains # Combine filters pork2bind --json --all-domains --match "*.com" --exclude "test-*" ``` ### Organized Workflow ```bash # Fetch multiple domains to cache directory pork2bind --json site1.com site2.com site3.com --to ./dns-cache # Or backup everything you own pork2bind --json --all-domains --api-enabled-only --to ./dns-cache # Convert to BIND zones in production directory pork2bind --bind site1.com site2.com site3.com \ --from ./dns-cache \ --to /etc/bind/zones ``` ### Including External Nameservers ```bash # Keep Porkbun NS records in zone file pork2bind --bind mysite.com --include-ns ``` ### Output Control and Scripting ```bash # Quiet operation (minimal output) pork2bind --json mysite.com --quiet # Output to stdout for piping/redirection pork2bind --json mysite.com --stdout > mysite.json pork2bind --bind mysite.com --stdout > db.mysite # Combine for silent piping pork2bind --bind mysite.com --stdout --quiet > /etc/bind/zones/db.mysite ``` ### Shell Pipeline Examples ```bash # Fetch and convert in one pipeline pork2bind --json mysite.com --stdout | \ jq '.[] | select(.type == "A")' | \ pork2bind --bind mysite.com --from /dev/stdin --stdout > only-a-records.zone # Backup all domains for domain in $(cat domains.txt); do pork2bind --json $domain --stdout --quiet > backup/${domain}.json done # Or use the built-in --all-domains feature with filtering pork2bind --json --all-domains --api-enabled-only --to ./backup --quiet # Backup only production domains pork2bind --json --all-domains --match "prod-*" --to ./prod-backup --quiet ``` ## Output Format ### JSON Files Raw DNS records from Porkbun API: ```json [ { "id": "123456789", "name": "www", "type": "A", "content": "192.0.2.1", "ttl": "600" } ] ``` ### BIND Zone Files Standard BIND format with SOA record and succinct formatting: ``` $TTL 3600 $ORIGIN example.com. @ IN SOA ns1.example.com. admin.example.com. ( 20250619143022 ; Serial 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 3600 ) ; Minimum TTL @ IN A 192.0.2.1 www IN A 192.0.2.1 mail IN A 192.0.2.2 @ IN MX 1 primary.mail.com @ IN MX 10 backup.mail.com @ IN TXT "v=spf1 include:_spf.google.com ~all" _dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:admin@example.com" ``` The zone files use: - `@` symbol for the apex domain (shortcut for `$ORIGIN`) - Relative names for subdomains (e.g., `www` instead of `www.example.com`) - Compact formatting without excessive padding - Timestamp-based serial numbers (YYYYMMDDHHMMSS format) - MX records sorted by priority (lowest number = highest priority) - Quoted TXT record values for RFC compliance ## Output Control ### Default Behavior - Progress messages go to `stderr` - Data files saved to disk - Full verbose output showing what's happening ### Quiet Mode (`--quiet`) - Suppresses progress messages - Only shows errors and warnings - Perfect for automated scripts ### Stdout Mode (`--stdout`) - Outputs data to `stdout` instead of files - Progress messages still go to `stderr` - Enables piping and shell redirection - Can be combined with `--quiet` for pure data output ### Unix-Style Output Following standard Unix conventions: - **Data**`stdout` (when using `--stdout`) - **Progress/Status**`stderr` - **Errors**`stderr` This allows clean piping without interference from status messages. ## Pattern Matching The `--match` and `--exclude` flags support glob patterns for flexible domain filtering: ### Supported Patterns - `*` - Matches any number of characters - `?` - Matches exactly one character - Patterns are case-insensitive ### Common Use Cases ```bash # TLD filtering --match "*.com" # All .com domains --match "*.org" # All .org domains # Prefix filtering --match "prod-*" # Production domains --match "staging-*" # Staging domains # Suffix filtering --match "*-api" # API domains --match "*-staging" # Staging environments # Exclusion filtering --exclude "test-*" # Skip test domains --exclude "temp-*" # Skip temporary domains --exclude "dev-*" # Skip development domains # Complex combinations --match "*.com" --exclude "test-*" # .com domains except tests --match "prod-*" --exclude "*-staging" # Prod domains except staging ``` ### Multiple Patterns You can use multiple `--exclude` patterns to filter out different types of domains: ```bash pork2bind --json --all-domains \ --exclude "test-*" \ --exclude "dev-*" \ --exclude "temp-*" \ --to ./production-backup ``` ## Error Handling The tool provides clear error messages for common issues: - Missing or invalid API credentials - Network connectivity problems - Missing JSON files - Permission errors - Malformed JSON data ## Default Filtering By default, `--bind` mode filters out NS records because: - External NS records (like Porkbun's) shouldn't be in local BIND zones - Prevents DNS configuration conflicts - Most users want local DNS serving without external dependencies Use `--include-ns` if you need the original NS records for secondary DNS setups. ## Error Handling The tool provides comprehensive error handling for real-world scenarios: ### API Access Issues Many domains in your Porkbun account may not have API access enabled. The tool handles this gracefully: ```bash # Check which domains work before processing pork2bind --check-api-access --all-domains # Only process domains that have API access pork2bind --json --all-domains --api-enabled-only # Try all domains but continue on errors pork2bind --json --all-domains --continue-on-error ``` ### Common Error Scenarios - **Missing API credentials**: Clear error messages guide you to fix `.env` file - **API access disabled**: Shows which domains need API access enabled in Porkbun - **Network issues**: Retry-friendly design for network connectivity problems - **Permission errors**: Clear messages about directory write permissions - **Malformed JSON**: Helpful error messages for corrupted data files ### Exit Codes - `0` - Success (all operations completed) - `1` - Partial failure (some domains failed, others succeeded) - `2` - Total failure (no operations succeeded) ## Use Cases - **Local DNS serving**: Run your own authoritative DNS server - **DNS backup**: Keep local copies of your DNS configuration - **Zone file management**: Convert API data to standard BIND format - **DNS migration**: Move from Porkbun to self-hosted DNS - **Development**: Test DNS changes locally before deploying - **Automation**: Script DNS updates and deployments - **Integration**: Pipe DNS data through shell tools for processing - **Portfolio management**: Bulk operations across many domains with pattern filtering - **Disaster recovery**: Maintain offline copies of all DNS configurations ## Requirements - Node.js 14.0.0 or higher - Valid Porkbun account with API access - Domains managed through Porkbun ## License GPL-3.0 License - see [LICENSE](LICENSE) file for details. ## Author Shawn Murphy <smurp@smurp.com> ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests if applicable 5. Submit a pull request ## Support - Report bugs: [GitHub Issues](https://github.com/smurp/pork2bind/issues) - Documentation: This README and `--help` output - API Documentation: [Porkbun API Docs](https://porkbun.com/api/json/v3/documentation) ## Changelog ### v1.0.0 - Initial release - JSON and BIND conversion modes - Automatic NS record filtering - Batch domain processing - Flexible directory management - Output control with `--quiet` and `--stdout` flags - Unix-style stdout/stderr separation for scripting - Succinct BIND zone formatting with `@` shortcuts - Priority-sorted MX records and quoted TXT values - Domain discovery with `--list-domains` and `--all-domains` - API access checking with `--check-api-access` - Error resilience with `--continue-on-error` and `--api-enabled-only` - Pattern filtering with `--match` and `--exclude` for domain selection