home-ddns

command module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2024 License: CC0-1.0 Imports: 9 Imported by: 0

README

Home-ddns

Simple Golang tool to update DNS records (extensible to multiple providers) for home public IP. Emulate Dynamic DNS for free.

Installation

The tool can be easily compiled locally:

git clone https://github.com/Sudneo/Home-ddns.git
cd Home-ddns
make build
./home-ddns -h

Alternatively, a prebuild release can be downloaded from Github.

Docker

A Dockerfile is provided to build the tool using Docker:

cd Home-ddns
docker build -t home-ddns .
docker run -v ${PWD}/config.yaml:/home-ddns/config.yaml -it home-ddns [-v -j -cron -interval 1]

Alternative it's possible to use the Makefile:

make docker-build
make docker-run

The image is built using a scratch container, so it's very minimal and does not even have a shell (hence, you won't be able to exec inside it).

home-ddns      latest          2a04c146665c   About a minute ago   5.48MB

Usage

All the configuration is in a YAML file, this allows to manage multiple providers/domains/records at once, with full flexibility in each domain type, TTL, etc.

An example configuration is as follows:

providers:
  - name: "Godaddy" # The only implemented at the moment
    client_id: "MYID" 
    client_key: "MYKEY"
    domains:
      - domain: "mydomain.com"
        records:
          - name:  "home"
            type:  "A"
          - name:  "test"
            type:  "CNAME"
          - name:  "anotherCNAME"
            type:  "CNAME"
            ttl:   "1200"
          - name:  "proxy"
            type:  "A"
            value: "260.1.1.1"

The usage therefore now is simple:

Usage of ./home-ddns:
  -config string
        Configuration file to use (default "config.yaml")
  -cron
        Enable cron mode (execute every interval)
  -interval int
        Interval in minutes between each execution (requires cron mode) (default 60)
  -j    Enable logging in JSON
  -v    Enable debug logs

The cron mode simply will have the execution run in an infinite loop. At every loop the configuration is re-read, so it can be modified dynamically (for example as a ConfigMap in Kubernetes).

Use Case

The main use case is to update a given DNS record (or a set of record) for a domain in a DNS provider with the public IP address of the machine where this script is run from. This is the case for example for non-static domestic IPs, where we want to achieve Dynamic-DNS to have our home IPs publicly reachable with a DNS name. However, the tool supports specifying a value for a domain record, if this is different from the public IP, and can be used to set whetever record type the provider supports.

Note: The script uses http://ifconfig.io to query the public IP. This means that the folks running that site will be able to see your IP address (as you are making a request to them). If this is not fine for you, consider selfhosting a similar service.

Features

  • The record to be set is first queried, if it exists and matches the specified value (or alternatively the public IP), nothing is done.
  • If the record exists but doesn't match the current public IP/the specified value, that record is updated.
  • If the record does not exist, it is created.
  • Cron mode, Docker friendly way to run the tool periodically without having to install cron inside the image.

Development

The most common use case for development is adding a new provider to support. To do this, it's enough to implement the models.Provider interface and then register the new provider in the global map in main.go to map a string of choice to the corresponding type.

Currently, the only implemented provider is Godaddy:

const (
	godaddyProvider = "Godaddy"
	// New provider here
	myProvider = "MyProvider"
)

var providersMap = map[string]models.Provider{
	godaddyProvider: &api.GodaddyHandler{},
	myProvider: &api.MyProviderHandler{},
}

and

package api

[...]

type MyProviderHandler struct {
	ClientID  string
	ClientKey string
	MyKey string
}
func (h *MyProviderHandler) SetAPIKey(key string) error {}
func (h *MyProviderHandler) SetAPIID(key string) error {}
func (h *MyProviderHandler) GetRecord(domain string, record models.DNSRecord) (dnsRecord models.DNSRecord, err error) {}
func (h *MyProviderHandler) SetRecord(domain string, record models.DNSRecord) (err error) {}
func (h *MyProviderHandler) UpdateRecord(domain string, record models.DNSRecord) (err error) {}

Finally, the new provider can be used directly in the configuration:

[...]
  - name: "MyProvider"
    client_id: "MYID" 
    client_key: "MYKEY"
    domains:
    [...]

It's important to consider a few things:

  • For CNAME records, the value expected is the A record pointer, such as @, rather than the IP, this is used for drift detection. At worst, the tool will set the value everytime, even if it's already correct, if this is not implemented correctly.
  • When a DNS record does NOT exist, GetRecord should return "" as the record value.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL