Skip to content

Environment Variables

Complete reference of all environment variables used by bindcar.

Core Variables

BIND_ZONE_DIR

  • Type: String (path)
  • Default: /var/cache/bind
  • Required: No
  • Description: Directory where BIND9 zone files are stored
BIND_ZONE_DIR=/var/cache/bind

Must be: - Readable and writable by the bindcar user (UID 101) - Shared between bindcar and BIND9 containers - An existing directory

API_PORT

  • Type: Integer
  • Default: 8080
  • Required: No
  • Description: Port for the HTTP API server
API_PORT=8080

Valid range: 1-65535

RNDC_SERVER

  • Type: String (address:port)
  • Default: 127.0.0.1:953 (or from /etc/bind/rndc.conf)
  • Required: No
  • Description: RNDC server address and port
RNDC_SERVER=127.0.0.1:953

RNDC_ALGORITHM

  • Type: String
  • Default: sha256 (or from /etc/bind/rndc.conf)
  • Required: No
  • Description: HMAC algorithm for RNDC authentication
RNDC_ALGORITHM=sha256

Valid values: - md5 (or hmac-md5) - sha1 (or hmac-sha1) - sha224 (or hmac-sha224) - sha256 (or hmac-sha256) - sha384 (or hmac-sha384) - sha512 (or hmac-sha512)

Both formats (with or without hmac- prefix) are accepted.

RNDC_SECRET

  • Type: String (base64-encoded)
  • Default: None (read from /etc/bind/rndc.conf or /etc/rndc.conf)
  • Required: Only if not using rndc.conf
  • Description: Base64-encoded RNDC secret key
RNDC_SECRET=dGVzdC1zZWNyZXQtaGVyZQ==

Note: If RNDC_SECRET is not set, bindcar will automatically parse the RNDC configuration from /etc/bind/rndc.conf or /etc/rndc.conf, including any include directives for separate key files.

The secret must be: - Base64-encoded - Match the key configured in BIND9's rndc.conf

nsupdate Variables

These variables configure the nsupdate executor for dynamic DNS record updates. If not set, bindcar automatically falls back to using RNDC credentials.

NSUPDATE_KEY_NAME

  • Type: String
  • Default: Falls back to RNDC key name
  • Required: No
  • Description: TSIG key name for nsupdate authentication
NSUPDATE_KEY_NAME=update-key

This should match the key name in your zone's allow-update directive.

NSUPDATE_ALGORITHM

  • Type: String
  • Default: Falls back to RNDC_ALGORITHM
  • Required: No
  • Description: HMAC algorithm for TSIG authentication
NSUPDATE_ALGORITHM=HMAC-SHA256

Valid values (same as RNDC): - md5 (or hmac-md5 or HMAC-MD5) - sha1 (or hmac-sha1 or HMAC-SHA1) - sha224 (or hmac-sha224 or HMAC-SHA224) - sha256 (or hmac-sha256 or HMAC-SHA256) - sha384 (or hmac-sha384 or HMAC-SHA384) - sha512 (or hmac-sha512 or HMAC-SHA512)

NSUPDATE_SECRET

  • Type: String (base64-encoded)
  • Default: Falls back to RNDC_SECRET
  • Required: No
  • Description: Base64-encoded TSIG secret for nsupdate
NSUPDATE_SECRET=dGVzdC1zZWNyZXQtaGVyZQ==

Must be: - Base64-encoded - Match the key configured in BIND9's zone allow-update directive

NSUPDATE_SERVER

  • Type: String (IP address)
  • Default: 127.0.0.1
  • Required: No
  • Description: DNS server address for nsupdate commands
NSUPDATE_SERVER=127.0.0.1

Typically localhost when running as a sidecar.

NSUPDATE_PORT

  • Type: Integer
  • Default: 53
  • Required: No
  • Description: DNS server port for nsupdate commands
NSUPDATE_PORT=53

Example Configurations

Using separate keys (recommended for security):

# RNDC for zone management
RNDC_SECRET=rndc-key-secret-here
RNDC_ALGORITHM=sha256

# nsupdate for record updates (different key)
NSUPDATE_KEY_NAME=update-key
NSUPDATE_SECRET=update-key-secret-here
NSUPDATE_ALGORITHM=HMAC-SHA256

Using same key (simpler setup):

# Set RNDC vars only - nsupdate automatically uses them
RNDC_SECRET=shared-key-secret-here
RNDC_ALGORITHM=sha256
# nsupdate will use RNDC credentials automatically

Logging Variables

RUST_LOG

  • Type: String (log level)
  • Default: info
  • Required: No
  • Description: Log level for the application
RUST_LOG=info

Valid values: - error - Only error messages - warn - Warnings and errors - info - Informational messages, warnings, and errors - debug - Debug information - trace - Very detailed trace information

Can also be module-specific:

RUST_LOG=bindcar=debug,tower_http=info

Security Variables

DISABLE_AUTH

  • Type: Boolean
  • Default: false
  • Required: No
  • Description: Disable Bearer token authentication
DISABLE_AUTH=false

Valid values: - true - Disable authentication (USE ONLY IN TRUSTED ENVIRONMENTS) - false - Enable authentication (recommended)

WARNING: Setting this to true disables all authentication. Only use in environments where authentication is handled by infrastructure (Linkerd service mesh, API gateway, etc.).

BIND_TOKEN_AUDIENCES

  • Type: String (comma-separated)
  • Default: bindcar
  • Required: No (only when k8s-token-review feature enabled)
  • Description: Expected token audiences for TokenReview validation
BIND_TOKEN_AUDIENCES=bindcar,https://bindcar.dns-system.svc.cluster.local

Prevents token reuse across different services. Tokens must be created with matching audience:

kubectl create token my-app --audience=bindcar

BIND_ALLOWED_NAMESPACES

  • Type: String (comma-separated)
  • Default: None (allow all)
  • Required: No (only when k8s-token-review feature enabled)
  • Description: Allowed Kubernetes namespaces for token authentication
BIND_ALLOWED_NAMESPACES=dns-system,kube-system

Empty value allows all namespaces (default). When set, only tokens from specified namespaces are accepted.

BIND_ALLOWED_SERVICE_ACCOUNTS

  • Type: String (comma-separated)
  • Default: None (allow all)
  • Required: No (only when k8s-token-review feature enabled)
  • Description: Allowed ServiceAccounts for token authentication
BIND_ALLOWED_SERVICE_ACCOUNTS=system:serviceaccount:dns-system:external-dns,system:serviceaccount:dns-system:cert-manager

Format: system:serviceaccount:<namespace>:<name>

Empty value allows all ServiceAccounts (default). When set, only specified ServiceAccounts are accepted.

Rate Limiting Variables

RATE_LIMIT_ENABLED

  • Type: Boolean
  • Default: true
  • Required: No
  • Description: Enable or disable rate limiting
RATE_LIMIT_ENABLED=true

Valid values: - true - Enable rate limiting (recommended) - false - Disable rate limiting (USE ONLY IN TRUSTED ENVIRONMENTS)

Rate limiting helps protect the API from abuse and ensures fair resource allocation across clients.

RATE_LIMIT_REQUESTS

  • Type: Integer
  • Default: 100
  • Required: No
  • Description: Maximum number of requests allowed per time period
RATE_LIMIT_REQUESTS=100

This value represents the total number of requests a client can make within the time period defined by RATE_LIMIT_PERIOD_SECS.

Valid range: 1-4,294,967,295 (must be greater than 0)

RATE_LIMIT_PERIOD_SECS

  • Type: Integer
  • Default: 60
  • Required: No
  • Description: Time period in seconds for rate limit calculation
RATE_LIMIT_PERIOD_SECS=60

Combined with RATE_LIMIT_REQUESTS, this defines the rate limit. For example: - RATE_LIMIT_REQUESTS=100 + RATE_LIMIT_PERIOD_SECS=60 = 100 requests per minute - RATE_LIMIT_REQUESTS=1000 + RATE_LIMIT_PERIOD_SECS=3600 = 1000 requests per hour

Valid range: 1-4,294,967,295 (must be greater than 0)

RATE_LIMIT_BURST

  • Type: Integer
  • Default: 10
  • Required: No
  • Description: Maximum burst size for rate limiting
RATE_LIMIT_BURST=10

The burst size allows clients to temporarily exceed the steady-state rate limit. This accommodates legitimate traffic spikes without penalizing normal usage patterns.

For example, with a burst of 10, a client can make 10 requests immediately, then must wait according to the rate limit before making more requests.

Valid range: 1-4,294,967,295 (must be greater than 0)

How Rate Limiting Works:

bindcar uses the Generic Cell Rate Algorithm (GCRA) via the tower-governor crate, which provides sophisticated rate limiting based on client IP addresses.

Client IP Detection (in order of precedence): 1. X-Forwarded-For header (first IP) 2. X-Real-IP header 3. Peer socket address

This ensures proper rate limiting when bindcar is deployed behind reverse proxies like Linkerd.

Rate Limit Responses:

When a client exceeds the rate limit: - HTTP Status: 429 Too Many Requests - Response Body: Rate limit exceeded. Please try again later. - Metrics: Tracked via bindcar_rate_limit_requests_total{result="rejected"}

Example Configurations:

Permissive (development):

RATE_LIMIT_REQUESTS=1000
RATE_LIMIT_PERIOD_SECS=60
RATE_LIMIT_BURST=50

Standard (production):

RATE_LIMIT_REQUESTS=100
RATE_LIMIT_PERIOD_SECS=60
RATE_LIMIT_BURST=10

Strict (high-security):

RATE_LIMIT_REQUESTS=30
RATE_LIMIT_PERIOD_SECS=60
RATE_LIMIT_BURST=5

Disabled (trusted environment only):

RATE_LIMIT_ENABLED=false

Environment Variable Precedence

  1. Explicit environment variables (highest priority)
  2. Default values (lowest priority)

Validation

bindcar validates all environment variables on startup:

  • Path variables must point to existing, accessible locations
  • Port numbers must be valid (1-65535)
  • Log levels must be recognized values

Invalid configuration will cause bindcar to exit with an error message.

Examples

Development

export RUST_LOG=debug
export BIND_ZONE_DIR=./zones
export API_PORT=3000
export DISABLE_AUTH=true

Production (Docker)

docker run -d \
  -e BIND_ZONE_DIR=/var/cache/bind \
  -e API_PORT=8080 \
  -e RUST_LOG=info \
  -e RNDC_SERVER=127.0.0.1:953 \
  -e RNDC_ALGORITHM=sha256 \
  -e RNDC_SECRET=dGVzdC1zZWNyZXQtaGVyZQ== \
  -e DISABLE_AUTH=false \
  ghcr.io/firestoned/bindcar:latest

Kubernetes (Basic Auth)

env:
- name: BIND_ZONE_DIR
  value: "/var/cache/bind"
- name: API_PORT
  value: "8080"
- name: RUST_LOG
  value: "info"
- name: RNDC_SERVER
  value: "127.0.0.1:953"
- name: RNDC_ALGORITHM
  value: "sha256"
- name: RNDC_SECRET
  valueFrom:
    secretKeyRef:
      name: rndc-secret
      key: secret
- name: DISABLE_AUTH
  value: "false"

Kubernetes (TokenReview Mode - Production)

env:
- name: BIND_ZONE_DIR
  value: "/var/cache/bind"
- name: API_PORT
  value: "8080"
- name: RUST_LOG
  value: "info"
- name: RNDC_SERVER
  value: "127.0.0.1:953"
- name: RNDC_ALGORITHM
  value: "sha256"
- name: RNDC_SECRET
  valueFrom:
    secretKeyRef:
      name: rndc-secret
      key: secret
- name: DISABLE_AUTH
  value: "false"
# TokenReview security configuration
- name: BIND_TOKEN_AUDIENCES
  value: "bindcar,https://bindcar.dns-system.svc.cluster.local"
- name: BIND_ALLOWED_NAMESPACES
  value: "dns-system"
- name: BIND_ALLOWED_SERVICE_ACCOUNTS
  value: "system:serviceaccount:dns-system:external-dns"

Best Practices

  1. Use defaults where possible - Only override when necessary
  2. Store secrets securely - Use Kubernetes Secrets or similar for sensitive values
  3. Use appropriate log levels - info for production, debug for troubleshooting
  4. Don't disable authentication - Unless absolutely necessary and in trusted environments
  5. Validate paths exist - Ensure directories and binaries exist before starting

Next Steps