1
0
mirror of https://github.com/vbrandl/bind9-api.git synced 2024-11-24 03:42:59 +01:00
bind9-api/README.md

146 lines
4.0 KiB
Markdown
Raw Permalink Normal View History

2018-07-08 01:08:56 +02:00
# BIND9 API
[![Travis Build Status](https://travis-ci.org/vbrandl/bind9-api.svg?branch=master)](https://travis-ci.org/vbrandl/bind9-api)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/vbrandl/bind9-api/blob/master/LICENSE-MIT)
[![License](https://img.shields.io/badge/license-Apache-green.svg)](https://github.com/vbrandl/bind9-api/blob/master/LICENSE-APACHE)
2018-07-08 01:08:56 +02:00
This is an attempt to implement an API to create, update or delete DNS records
on a BIND9 DNS server.
2020-11-30 16:40:07 +01:00
## Building
To compile the code, you first need to [install Rust](https://rustup.rs/). Then
you can run
```
cargo build --release
```
in the project root. The server and client binary will be located in
`./target/release/bind9-api` and `./target/release/bind9-api-client`
respectively.
2018-07-08 01:08:56 +02:00
## Server
The server will wait for incoming requests and uses the `nsupdate` command to
perform operations on the BIND9 nameserver. For the server to work, a DNS key is
needed to perform the updates.
```
$ dnssec-keygen -r /dev/urandom -a HMAC-SHA256 -b 256 -n HOST dnskey
```
Copy the `Key` section of the resulting `Kdnskey*.private` file into a file that
looks like this:
```
key "dns-key" {
algorithm hmac-sha256;
secret "<your secret>";
}
```
And extend the zone section of the zones you'd like to modify in your
`named.conf.local`
```
zone "example.com" {
type master;
file "/var/lib/bind/db.example.com";
...
allow-update { key "dns-key"; };
...
}
```
Now you can start the server:
```
$ ./bind9-api -k <path to dnskey> -t <your api token>
```
By default, the server will bind to `0.0.0.0:8000`. The host and port to bind
to, can be changed using the `-h` and `-p` flags respectively. For production
use, you should bind to a private IP address (LAN or VLAN) or to `127.0.0.1` and
put the server behind a reverse proxy that offers TLS.
## Client
The client is used to perform changes to the DNS zone from any server. My use
case is to perform LetsEncrypt DNS challenges. The client will look for a
configuration file in `/etc/bind9apiclient.toml` which looks like this:
```
# API server host
host = "http://127.0.0.1:8080"
# API secret
secret = "topsecret"
```
The client can perform two operations: Creating/updating and deleting DNS
records. The client is invoked like this
```
$ ./bind9-api-client -d foo.example.com -r TXT update -v foobar
$ ./bind9-api-client -d foo.example.com -r TXT delete
```
## API Description
```
POST /record
X-Api-Token: <api-token>
{
"name": "foo.example.com",
"value": "127.0.0.1",
"record": "A",
"ttl": 1337
}
```
```
DELETE /record
X-Api-Token: <api-token>
{
"name": "foo.example.com",
"record": "A"
}
```
The API token is a SHA256 HMAC over the request body using a pre-shared secret.
### Security Considerations
The current API design does not migrate replay attacks. An attacker that is able
to intercept a request to the API can resend the same request again to execute
the same operation. To prevent these kinds of attacks, you should use a reverse
proxy and encrypt the connections using TLS. Future versions of the server might
provide TLS functionality by itself.
## Usage with LetsEncrypt
In `letsencrypt/`, two example scripts can be found to use the client as a
certbot hook for DNS challenges. It assumes that the client is located somewhere
in `$PATH` and that the configurations file exists.
2018-07-08 01:17:39 +02:00
2018-07-15 20:17:02 +02:00
To obtain a new certificate, certbot can be invoked as followed:
```
certbot certonly -n --agree-tos --server https://acme-v02.api.letsencrypt.org/directory --preferred-challenges=dns-01
--manual --manual-auth-hook /usr/lib/letsencrypt-bind9/certbot-bind9-auth --manual-cleanup-hook
/usr/lib/letsencrypt-bind9/certbot-bind9-cleanup --manual-public-ip-logging-ok -d example.com -d '*.example.com'
```
2018-07-08 01:17:39 +02:00
## License
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
http://opensource.org/licenses/MIT)
at your option.