Crate bindcar

Crate bindcar 

Source
Expand description

bindcar - HTTP REST API for managing BIND9 zones via RNDC

A lightweight library that provides programmatic control over BIND9 DNS zones using the RNDC (Remote Name Daemon Control) protocol.

§Features

  • Create, delete, and manage BIND9 zones dynamically
  • Execute RNDC commands asynchronously
  • Zone file generation and management
  • Shared request/response types for API operations
  • Authentication support (Bearer tokens and Kubernetes ServiceAccounts)
  • Prometheus metrics integration

§Usage

This crate can be used as both a library and a standalone binary:

§As a Library

§Using RNDC Executor

use bindcar::RndcExecutor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let executor = RndcExecutor::new(
        "127.0.0.1:953".to_string(),
        "sha256".to_string(),
        "dGVzdC1zZWNyZXQtaGVyZQ==".to_string(), // base64 encoded secret
    )?;

    // Execute RNDC commands
    let status = executor.status().await?;
    println!("BIND9 Status: {}", status);

    Ok(())
}

§Using Shared Types (for API clients)

use bindcar::{CreateZoneRequest, ZoneConfig, SoaRecord, DnsRecord};
use std::collections::HashMap;

// Create nameserver glue records
let mut ns_ips = HashMap::new();
ns_ips.insert("ns1.example.com.".to_string(), "192.0.2.10".to_string());

// Create a zone creation request
let request = CreateZoneRequest {
    zone_name: "example.com".to_string(),
    zone_type: "primary".to_string(),
    zone_config: ZoneConfig {
        ttl: 3600,
        soa: SoaRecord {
            primary_ns: "ns1.example.com.".to_string(),
            admin_email: "admin.example.com.".to_string(),
            serial: 2025010101,
            refresh: 3600,
            retry: 600,
            expire: 604800,
            negative_ttl: 86400,
        },
        name_servers: vec!["ns1.example.com.".to_string()],
        name_server_ips: ns_ips,
        records: vec![
            DnsRecord {
                name: "@".to_string(),
                record_type: "A".to_string(),
                value: "192.0.2.1".to_string(),
                ttl: None,
                priority: None,
            },
        ],
        also_notify: None,
        allow_transfer: None,
        primaries: None,
        dnssec_policy: None,
        inline_signing: None,
    },
    update_key_name: None,
};

// Serialize to JSON for API requests
let json = serde_json::to_string(&request).unwrap();

§As a Binary

cargo install bindcar
bindcar

§Zone File Generation

The serial field in SoaRecord will auto-generate in YYYYMMDD01 format if omitted from JSON.

use bindcar::{ZoneConfig, SoaRecord, DnsRecord};
use std::collections::HashMap;

// Example JSON can omit serial for auto-generation:
let json = r#"{
  "ttl": 3600,
  "soa": {
    "primaryNs": "ns1.example.com.",
    "adminEmail": "admin.example.com."
  },
  "nameServers": ["ns1.example.com."],
  "nameServerIps": {
    "ns1.example.com.": "192.0.2.10"
  },
  "records": []
}"#;

let zone_config: ZoneConfig = serde_json::from_str(json).unwrap();
let zone_file_content = zone_config.to_zone_file();
println!("{}", zone_file_content);

§Integration with Other Projects

This library is designed to be used by other projects (like bindy) that need to interact with the bindcar API. By importing this crate, you get:

  • Type-safe request/response structures
  • Automatic JSON serialization/deserialization
  • OpenAPI schema compatibility
  • No need to maintain duplicate type definitions

Re-exports§

pub use rndc::RndcExecutor;
pub use nsupdate::NsupdateExecutor;
pub use types::ApiError;
pub use types::AppState;
pub use types::ErrorResponse;
pub use zones::DnsRecord;
pub use zones::SoaRecord;
pub use zones::ZoneConfig;
pub use zones::CreateZoneRequest;
pub use zones::ServerStatusResponse;
pub use zones::ZoneInfo;
pub use zones::ZoneListResponse;
pub use zones::ZoneResponse;
pub use zones::ZONE_TYPE_PRIMARY;
pub use zones::ZONE_TYPE_SECONDARY;
pub use records::AddRecordRequest;
pub use records::RecordResponse;
pub use records::RemoveRecordRequest;
pub use records::UpdateRecordRequest;
pub use rndc::parse_rndc_conf;
pub use rndc::RndcConfig;
pub use rndc_conf_parser::parse_rndc_conf_file;
pub use rndc_conf_parser::parse_rndc_conf_str;
pub use rndc_conf_types::KeyBlock;
pub use rndc_conf_types::OptionsBlock;
pub use rndc_conf_types::RndcConfFile;
pub use rndc_conf_types::ServerAddress;
pub use rndc_conf_types::ServerBlock;

Modules§

auth
Authentication middleware for Kubernetes ServiceAccount tokens
cli
CLI argument parsing for the bindcar binary.
metrics
Prometheus metrics for bindcar
middleware
Middleware for metrics collection
nsupdate
nsupdate command executor for dynamic DNS updates
rate_limit
Rate limiting middleware for HTTP requests
records
DNS record management API handlers
rndc
RNDC command execution using native RNDC protocol
rndc_conf_parser
RNDC configuration file parser
rndc_conf_types
RNDC configuration data types
rndc_parser
RNDC output parser
rndc_types
RNDC data types for parsing BIND9 output
types
Common types and errors used throughout the bindcar library
zones
Zone management API handlers