dbsqlite

package
v0.5.26 Latest Latest
Warning

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

Go to latest
Published: Nov 17, 2025 License: BSD-3-Clause Imports: 16 Imported by: 0

README

Name

dbsqilte - serve zone data from a SQLite database

Description

The dbsqlite handler reads zone data from a data and serves that to clients. If the database contains signatures (i.e. is signed using DNSSEC), correct DNSSEC answers are returned. Only NSEC is supported. You can create the database completely off-line, if it holds the correct data, dbsqlite will happily serve from it.

The sign handler does not support databases, so you need something like ldns-signzone to sign and resign your zones and put the generated records in the database.

When started the database file will be created and the schema will be written to it (if it does not already exist). After this step, the handler will never write to the database, for the purpose of generating answers the database is completely read-only. The database can be prepared beforehand.

An RR that fails to be converted into a proper dns.RR is silently discarded, unless debug is active, see atomdns-global(7) for details. The class is IN and can't be overridden.

When atomdns startup the dbsqlite handler will log how many zones it found in the database, this is a live query and may differ with the zones specified in the configuration.

The server will reply with minimal responses by default.

Database

The schema used for the database is:

CREATE TABLE rrs (
name VARCHAR(255),
type VARCHAR(10),
data VARCHAR(65535),
ttl INTEGER,
UNIQUE (name, type, data)
);

You can just add RRs to this table for any zone and dbsqlite will happily use them. Relative names will be made not be made into fully qualified ones, and for some queries that will not be matched and silently not included.

sqlite> insert into rrs values ( '_ssh._tcp.host1.example.', 'srv', '10 5 43 example', 3600);
sqlite> insert into rrs values ( 'subdel.example', 'ns', 'ns.example.com', 3600);

This one database can be safely used for all zones you have. Note that you still have to make sure the handler gets queries for new zones.

Importing zone files

If you have a zone file you can use the .import feature of SQLite to import the file in one go using the excellent "ldns" utils from NLnet Labs (https://www.nlnetlabs.nl/projects/ldns/about/).

ldns-read-zone db.example.org  | sed 's/;.*$//' | sed 's/ $//'  | \
awk '{print $1 "," $4 "," substr($0, index($0, $5)) "," $2}' > csv.example.org

And then:

sqlite3 /tmp/db <<EOF
heredoc> .mode csv
heredoc> BEGIN;
heredoc> .import csv.example.org rrs
heredoc> COMMIT;
heredoc> EOF

Where the ldns-read-zone pipeline removes trailing white space, and the helpful comments after DNSKEY records, then awk re-arranges it into the proper format.

Syntax

In it simplest form dbsqlite you can use:

dbsqlite DATABASE
  • DATABASE the file the sqlite database to query. If the path is relative, the path from the global root config will be prepended to it.

If DATABASE does not exists the file is created and the rrs table is initialized.

For extra control you can open the block and define multiple extra properties that deal with zone transfers. Only outgoing zone transfers are supported. It is similar to dbfile, and we refer to that documentation then to repeat it here.

dbsqlite DATABASE {
    transfer {
        to [IP[:PORT]]... {
            notify IP[:PORT] [IP[:PORT]]...
            source IP [IP]...
            key NAME ALGORITHM SECRET
        }
    }
}

Examples

Have both example.org and example.net read from the same database.

example.org example.net {
    dbsqlite example.db
}

If you want everything to end up in dbsqlite, you might be tempted to:

. {
    dbsqlite root.db
}

But this fails, unless you are actually authoritative for . (the root zone), this because the zones are used to find those in the database.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Err added in v0.5.2

func Err(err error) slog.Attr

Types

type Dbsqlite

type Dbsqlite struct {
	Path string

	Zones map[string]*Zone // read-only after startup

	To *dbfile.Transfer
	// contains filtered or unexported fields
}

func (*Dbsqlite) Count

func (d *Dbsqlite) Count() int

func (*Dbsqlite) Err

func (h *Dbsqlite) Err(err error) error

func (*Dbsqlite) HandlerFunc

func (d *Dbsqlite) HandlerFunc(next dns.HandlerFunc) dns.HandlerFunc

func (*Dbsqlite) HandlerFuncTransfer added in v0.5.2

func (d *Dbsqlite) HandlerFuncTransfer(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)

func (*Dbsqlite) Key

func (h *Dbsqlite) Key() string

func (*Dbsqlite) Origins

func (d *Dbsqlite) Origins() []string

func (*Dbsqlite) Setup

func (d *Dbsqlite) Setup(co *dnsserver.Controller) error

func (*Dbsqlite) SetupTransfer

func (d *Dbsqlite) SetupTransfer(co *dnsserver.Controller) (err error)

Setup transfer handles the transfer options.

type RR

type RR struct {
	Name string
	Type string
	Data string
	TTL  int
}

RR is the data we stored in the rrs table.

type Zone

type Zone struct {
	// contains filtered or unexported fields
}

func (*Zone) Apex

func (z *Zone) Apex() *dnszone.Node

func (*Zone) AuthoritativeWalk

func (z *Zone) AuthoritativeWalk(fn func(*dnszone.Node, bool) bool)

func (*Zone) Get

func (z *Zone) Get(name string) (*dnszone.Node, bool)

func (*Zone) Labels

func (z *Zone) Labels() int

func (*Zone) Load

func (z *Zone) Load() error

func (*Zone) Origin

func (z *Zone) Origin() string

func (*Zone) Previous

func (z *Zone) Previous(name string) *dnszone.Node

func (*Zone) Select

func (z *Zone) Select(rrs *[]RR, query string, args ...any) error

func (*Zone) Set

func (z *Zone) Set(*dnszone.Node) string

func (*Zone) Walk

func (z *Zone) Walk(fn func(*dnszone.Node) bool)

Jump to

Keyboard shortcuts

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