Skip to content

A Bash script to manage Pi-hole local DNS entries using a Git repository as the source of truth.

Notifications You must be signed in to change notification settings

Cave-Johnson/DNS-Sync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

dns-sync

A tool to synchronize local DNS entries from a Git repository to a Pi-hole instance. It uses a dedicated Git repository as a source of truth for DNS mappings, allowing you to manage Pi-hole's local DNS records via git.

The tool supports both Pi-hole v5 (modifying custom.list) and Pi-hole v6+ (using the HTTP API) and is designed to be run as a cron job.

Project Structure

This project uses a two-repository system:

  1. The dns-sync Tool (This Repo): The Bash script that performs the synchronization, handles authentication, and updates Pi-hole.
  2. Your DNS Mappings Repo: A separate Git repository (public or private, Github or Gitlab) that you create and maintain. This repository contains your actual DNS lists.

How It Works

The tool is designed to support multiple "locations" or Pi-hole instances from a single DNS mappings repository.

  1. Your DNS Mappings Repo contains your lists (e.g., core.conf, servers.conf).
  2. A servers/ directory in that repo defines which lists apply to which location using a YAML file.
  3. For example, a file named servers/london_server.yml might specify that the "london" location should load core.conf and printers.conf.
  4. An optional exceptions/ directory can be used to block specific domains for a given location.
  5. When dns-sync runs, it:
    • Pulls the latest changes from your DNS Mappings Repo.
    • Reads its LOCATION_CONFIG variable (e.g., london).
    • Parses servers/london_server.yml to find which lists to load.
    • Builds the final list of DNS entries.
    • Applies any exceptions from exceptions/london_exceptions.conf.
    • Pushes the final, correct list of entries to Pi-hole.

The project was written in bash so that it can run on a wide variery of systems e.g DietPi

Mappings Repository Layout

Your DNS mappings repository should follow this structure:

.
├── lists/
│   ├── core.conf
│   ├── printers.conf
│   └── servers.conf
│
├── servers/
│   ├── london_server.yml
│   └── home_server.yml
│
└── exceptions/
    ├── london_exceptions.conf
    └── home_exceptions.conf

servers/london_server.yml:

dns_lists:
  - core
  - servers
  - printers

lists/core.conf:

# Comments are allowed
192.168.1.1   router.local
10.0.0.1      nas.local

exceptions/london_exceptions.conf:

# This domain will be skipped, even if it's in a list
nas.local

Features

  • Git-based Source of Truth: Manage your DNS records using version control.
  • Location-Aware: Use one mappings repo to manage multiple, distinct Pi-hole instances.
  • Pi-hole v5 and v6 Support: Works with legacy custom.list (v5) and the modern HTTP API (v6).
  • Safe and Idempotent: Only applies changes when detected. Uses a lockfile to prevent concurrent runs.
  • Resilient: Caches the DNS list repository locally, so a temporary Git outage does not prevent the tool from running.
  • Automated: Designed to be run from cron for both list syncing and self-updating.

Requirements

  • A Linux host (tested on Debian-based systems).
  • root privileges (for installation, cron setup, and writing to Pi-hole's config).
  • git, curl, jq, cron, logrotate.
  • yq (v4+) - The installer will attempt to download this binary to /opt/dns-sync/yq if it is not found.

Installation

  1. Clone the Tool Clone this dns-sync repository to your Pi-hole machine.

    git clone https://github.com/your-user/dns-sync.git
    cd dns-sync
  2. Create and Edit Configuration Copy the example config and edit it with your specific values.

    cp dns-sync.conf.example dns-sync.conf
    chmod 600 dns-sync.conf
    nano dns-sync.conf

    You must update DNS_REPO_URL and all placeholder authentication and Pi-hole variables.

  3. Run the Installer Run the installer from within the cloned directory:

    sudo ./dns-sync.sh --install

    This script will:

    • Install dependencies (on Debian-based systems).
    • Copy the dns-sync script to /usr/local/bin/.
    • Copy dns-sync.conf to /etc/dns-sync/.
    • Create the local repo cache at /opt/dns-sync/lists.
    • Install yq to /opt/dns-sync/yq if needed.
    • Set up the cron jobs for syncing and self-updating.

Configuration

All configuration is handled in /etc/dns-sync/dns-sync.conf (after installation).

Variable Description
Core
LOCATION_CONFIG The location profile to apply. ldn expects servers/ldn_server.yml in the DNS repo.
LOG_FILE Path to the log file (e.g., /var/log/dns-sync.log).
BIN_PATH Path to install the tool (e.g., /usr/local/bin).
Repositories
TOOL_REPO_URL URL to this tool's repo, used for self-updating.
TOOL_TOKEN_NAME (Optional) Access token name for a private tool repo.
TOOL_ACCESS_TOKEN (Optional) Access token secret for a private tool repo.
DNS_REPO_URL Required. URL to your separate DNS mappings repo.
DNS_TOKEN_NAME (Optional) Access token name for a private DNS repo.
DNS_ACCESS_TOKEN (Optional) Access token secret for a private DNS repo.
Pi-hole
PIHOLE_VERSION Set to "5" or "6".
PIHOLE_CUSTOM_LIST (v5 only) Path to Pi-hole's list (e.g., /etc/pihole/custom.list).
PIHOLE_API_URL (v6 only) Base URL for the API (e.g., http://127.0.0.1/api).
PIHOLE_API_TOKEN (v6 only) The password for your Pi-hole admin interface.
PIHOLE_INSECURE (v6 only) Set to true to allow curl -k for self-signed certificates.
Automation
CUSTOM_CRON The cron schedule for running the DNS sync (e.g., */2 * * * *).
CUSTOM_UPDATE_CRON The cron schedule for self-updating the tool (e.g., 0 0 * * *).

Authentication

The tool supports three methods for accessing your Git repositories:

  • Public HTTPS: Use an https:// URL and leave the _TOKEN_ variables blank.
  • Private HTTPS: Use an https:// URL and provide both _TOKEN_NAME and _ACCESS_TOKEN.
  • SSH: Use an git@... URL and leave the _TOKEN_ variables blank. Ensure the root user on the host has a valid SSH key with access to the repo.

Usage

Once installed, the tool is run by cron. You can also run it manually at any time.

Run a standard sync:

sudo dns-sync

Check for tool updates:

sudo dns-sync --update-tool

Validate your configuration:

sudo dns-sync --validate

Command Line Options

  • -h, --help: Display the help message.
  • -i, --install: Run the installation or re-installation.
  • -up, --update-tool: Check for and apply updates to the tool itself.
  • -ul, --update-lists: Force an update of the local DNS lists repo cache.
  • --validate: Check config, repo, and API access without making changes.
  • --dry-run: Run the full sync process but do not apply changes to Pi-hole.
  • -c, --config-file <path>: Use a specific config file for this run.
  • -l, --location <name>: Override the LOCATION_CONFIG for this run.
  • -ls, --list: List all DNS entries for all locations.
  • --debug-level=<n>: Set verbosity (1=debug, 2=full curl/git trace).
  • -v, --version: Display the tool's version.

Notes

  • Conflict Resolution: If multiple DNS lists for a single location contain the same hostname, the last one processed (which is determined by the order in the YAML file) will be used.
  • Cron Schedule: Be mindful of Git provider rate limits. Syncing more than once a minute is not recommended.
  • Pi-hole v6 Token: The PIHOLE_API_TOKEN is your Pi-hole web interface password.

Uninstall

To remove the tool from your system:

  1. Remove Cron Jobs:

    sudo crontab -l | grep -v '/usr/local/bin/dns-sync' | sudo crontab -
  2. Remove Files:

    sudo rm -f /usr/local/bin/dns-sync
    sudo rm -rf /etc/dns-sync
    sudo rm -rf /opt/dns-sync
    sudo rm -f /var/log/dns-sync.log
    sudo rm -f /var/lock/dns-sync.lock
    sudo rm -f /etc/logrotate.d/dns-sync

About

A Bash script to manage Pi-hole local DNS entries using a Git repository as the source of truth.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages