Skip to content

Commit 6ec6280

Browse files
author
Jan Broer
committed
Merge branch 'master' into minimal
2 parents f1878f1 + ad37396 commit 6ec6280

File tree

5 files changed

+80
-130
lines changed

5 files changed

+80
-130
lines changed

README.md

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,71 @@
11
# go-dnsmasq
22
*Version 0.9.8*
33

4-
go-dnsmasq is a light weight (1.2 MB) DNS caching server/forwarder with minimal filesystem and runtime overhead. It is designed to serve global DNS records by forwarding queries to upstream nameservers as well as local hostname records from a hostsfile.
4+
go-dnsmasq is a light weight (1.2 MB) DNS caching server/forwarder with minimal filesystem and runtime overhead.
55

66
### Application examples:
77

8-
- as local DNS cache for Docker containers
9-
- as nameserver providing local and global DNS records to clients in a private networks
10-
- as DNS proxy providing `search` domain path capability to `musl-libc` based clients (e.g. Alpine Linux)
8+
- Caching DNS server/forwarder in a local network
9+
- Container/Host DNS cache
10+
- DNS proxy providing DNS `search` capabilities to `musl-libc` based clients, particularly Alpine Linux
1111

1212
### Features
1313

14-
* Parses upstream nameservers from resolv.conf
15-
* Configures itself as local DNS cache in resolv.conf
16-
* Serves static hostname records from a hostsfile
17-
* Caching of answers
18-
* Replicates the `search` domain suffixing not supported by `musl-libc` based Linux distributions.
19-
* Stubzones (use a different nameserver for specific domains)
20-
* Round-robin of address records
21-
* Sending stats to Graphite server
22-
* Configuration through CLI and environment variables
23-
24-
### Resolver logic
25-
26-
DNS queries are processed according to the logic used by the GNU C resolver library:
27-
* The first nameserver (as listed in resolv.conf or configured by `--nameservers`) is considered the primary server. Additional servers are queried only when the primary server times out or returns an error code.
28-
* Multiple `search` paths are tried in the order they are configured.
29-
* Single-label queries (e.g.: "redis-service") will always be qualified with `search` list elements
30-
* For multi-label queries (ndots >= 1) the name will be tried first as an absolute name before any `search` list elements are appended to it.
31-
32-
### Commandline options
33-
34-
```sh
35-
NAME:
36-
go-dnsmasq - Lightweight caching DNS proxy for Docker containers
37-
38-
USAGE:
39-
go-dnsmasq [global options] command [command options] [arguments...]
40-
41-
VERSION:
42-
0.9.8
43-
44-
COMMANDS:
45-
help, h Shows a list of commands or help for one command
46-
47-
GLOBAL OPTIONS:
48-
--listen, -l "127.0.0.1:53" listen address: ‘host[:port]‘ [$DNSMASQ_LISTEN]
49-
--default-resolver, -d make go-dnsmasq the local primary nameserver (updates /etc/resolv.conf) [$DNSMASQ_DEFAULT]
50-
--nameservers, -n comma-separated list of name servers: ‘host[:port]‘ [$DNSMASQ_SERVERS]
51-
--stubzones, -z domains to resolve using a specific nameserver: ‘fqdn[,fqdn]/host[:port]‘ [$DNSMASQ_STUB]
52-
--hostsfile, -f full path to hostsfile (e.g. ‘/etc/hosts‘) [$DNSMASQ_HOSTSFILE]
53-
--hostsfile-poll, -p "0" how frequently to poll hostsfile (in seconds, ‘0‘ to disable) [$DNSMASQ_POLL]
54-
--search-domains, -s specify SEARCH domains taking precedence over /etc/resolv.conf: ‘fqdn[,fqdn]‘ [$DNSMASQ_SEARCH]
55-
--append-search-domains, -a enable suffixing single-label queries with SEARCH domains [$DNSMASQ_APPEND]
56-
--rcache, -r "0" capacity of the response cache (‘0‘ to disable caching) [$DNSMASQ_RCACHE]
57-
--rcache-ttl "60" TTL of entries in the response cache [$DNSMASQ_RCACHE_TTL]
58-
--no-rec disable recursion [$DNSMASQ_NOREC]
59-
--round-robin enable round robin of A/AAAA replies [$DNSMASQ_RR]
60-
--systemd bind to socket(s) activated by systemd (ignores --listen) [$DNSMASQ_SYSTEMD]
61-
--verbose enable verbose logging [$DNSMASQ_VERBOSE]
62-
--syslog enable syslog logging [$DNSMASQ_SYSLOG]
63-
--multithreading enable multithreading (num physical CPU cores) [$DNSMASQ_MULTITHREADING]
64-
--help, -h show help
65-
--version, -v print the version
66-
```
67-
68-
### Environment Variables
69-
70-
See above (the names inside the brackets).
14+
* Automatically set upstream `nameservers` and `search` domains from resolv.conf
15+
* Insert itself into the host's /etc/resolv.conf on start
16+
* Serve static A/AAAA records from a hostsfile
17+
* Provide DNS response caching
18+
* Replicate the `search` domain treatment not supported by `musl-libc` based Linux distributions
19+
* Supports virtually unlimited number of `search` paths and `nameservers` ([related Kubernetes article](https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns#known-issues))
20+
* Configure stubzones (different nameserver for specific domains)
21+
* Round-robin of DNS records
22+
* Send server metrics to Graphite and StatHat
23+
* Configuration through both command line flags and environment variables
24+
25+
### Resolve logic
26+
27+
DNS queries are resolved in the style of the GNU libc resolver:
28+
* The first nameserver (as listed in resolv.conf or configured by `--nameservers`) is always queried first, additional servers are considered fallbacks
29+
* Multiple `search` domains are tried in the order they are configured.
30+
* Single-label queries (e.g.: "redis-service") are always qualified with the `search` domains
31+
* Multi-label queries (ndots >= 1) are first tried as absolute names before qualifying them with the `search` domains
32+
33+
### Command-line options / environment variables
34+
35+
| Flag | Description | Default | Environment vars |
36+
| ------------------------------ | ----------------------------------------------------------------------------- | ------------- | -------------------- |
37+
| --listen, -l | Address to listen on `host[:port]` | 127.0.0.1:53 | $DNSMASQ_LISTEN |
38+
| --default-resolver, -d | Update resolv.conf and make go-dnsmasq the host's primary nameserver | False | $DNSMASQ_DEFAULT |
39+
| --nameservers, -n | Comma-separated list of nameservers `host[:port]` | - | $DNSMASQ_SERVERS |
40+
| --stubzones, -z | Use different nameservers for specific domains `fqdn[,fqdn]/host[:port]` | - | $DNSMASQ_STUB |
41+
| --hostsfile, -f | Full path to a hostsfile | - | $DNSMASQ_HOSTSFILE |
42+
| --hostsfile-poll, -p | How frequently to check hostsfile for changes (seconds, ‘0‘ to disable) | 0 | $DNSMASQ_POLL |
43+
| --search-domains, -s | Specify SEARCH domains (takes precedence over /etc/resolv.conf) `fqdn[,fqdn]` | - | $DNSMASQ_SEARCH |
44+
| --append-search-domains, -a | Qualify queries with SEARCH domains | False | $DNSMASQ_APPEND |
45+
| --rcache, -r | Capacity of the response cache (‘0‘ to disable cache) | 0 | $DNSMASQ_RCACHE |
46+
| --rcache-ttl | TTL for entries in the response cache | 60 | $DNSMASQ_RCACHE_TTL |
47+
| --no-rec | Disable recursion | False | $DNSMASQ_NOREC |
48+
| --round-robin | enable round robin of A/AAAA records | False | $DNSMASQ_RR |
49+
| --systemd | Bind to socket(s) activated by Systemd (ignores --listen) | False | $DNSMASQ_SYSTEMD |
50+
| --verbose | Enable verbose logging | False | $DNSMASQ_VERBOSE |
51+
| --syslog | Log to syslog | False | $DNSMASQ_SYSLOG |
52+
| --multithreading | Enable multithreading | False | |
53+
| --help, -h | Show help | | |
54+
| --version, -v | Print the version | | |
55+
56+
#### Enable Graphite/StatHat metrics
57+
58+
EnvVar: **GRAPHITE_SERVER**
59+
Default: ` `
60+
Set to the `host:port` of the Graphite server
61+
62+
EnvVar: **GRAPHITE_PREFIX**
63+
Default: `go-dnsmasq`
64+
Set a custom prefix for Graphite metrics
65+
66+
EnvVar: **STATHAT_USER**
67+
Default: ` `
68+
Set to your StatHat account email address
7169

7270
### Usage
7371

main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
)
2727

2828
// var Version string
29-
const Version = "0.9.8"
29+
const Version = "0.9.9"
3030

3131
var (
3232
nameservers = []string{}
@@ -173,7 +173,7 @@ func main() {
173173
if sd := c.String("search-domains"); sd != "" {
174174
for _, domain := range strings.Split(sd, ",") {
175175

176-
if dns.CountLabel(domain) < 2 {
176+
if dns.CountLabel(domain) < 1 {
177177
log.Fatalf("This search domain is not a FQDN: %s", domain)
178178
}
179179
domain = dns.Fqdn(strings.ToLower(domain))
@@ -231,7 +231,7 @@ func main() {
231231
}
232232

233233
for _, sdomain := range strings.Split(segments[0], ",") {
234-
if dns.CountLabel(sdomain) < 2 {
234+
if dns.CountLabel(sdomain) < 1 {
235235
log.Fatalf("This stubzones domain is not a FQDN: %s", sdomain)
236236
}
237237
sdomain = dns.Fqdn(sdomain)

server/forwarding.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func (s *server) ServeDNSForward(w dns.ResponseWriter, req *dns.Msg) *dns.Msg {
5050
var (
5151
r *dns.Msg
5252
err error
53+
nsList []string
5354
nsIndex int // nameserver list index
5455
sdIndex int // search list index
5556
sdName string // QNAME with search path
@@ -80,11 +81,23 @@ Redo:
8081
req.Question[0] = dns.Question{sdName, req.Question[0].Qtype, req.Question[0].Qclass}
8182
}
8283

84+
nsList = s.config.Nameservers
85+
86+
// Check whether the name matches a stub zone
87+
for zone, nss := range *s.config.Stub {
88+
if strings.HasSuffix(req.Question[0].Name, zone) {
89+
nsList = nss
90+
break
91+
}
92+
}
93+
94+
log.Debugf("Querying nameserver %s question %s", nsList[nsIndex], req.Question[0].Name)
95+
8396
switch tcp {
8497
case false:
85-
r, _, err = s.dnsUDPclient.Exchange(req, s.config.Nameservers[nsIndex])
98+
r, _, err = s.dnsUDPclient.Exchange(req, nsList[nsIndex])
8699
case true:
87-
r, _, err = s.dnsTCPclient.Exchange(req, s.config.Nameservers[nsIndex])
100+
r, _, err = s.dnsTCPclient.Exchange(req, nsList[nsIndex])
88101
}
89102
if err == nil {
90103
if canSearch {
@@ -111,7 +124,7 @@ Redo:
111124

112125
if r.Rcode == dns.RcodeServerFailure || r.Rcode == dns.RcodeRefused {
113126
// continue with next available nameserver
114-
if (nsIndex + 1) < len(s.config.Nameservers) {
127+
if (nsIndex + 1) < len(nsList) {
115128
nsIndex++
116129
doingSearch = false
117130
goto Redo
@@ -138,10 +151,10 @@ Redo:
138151
w.WriteMsg(r)
139152
return r
140153
} else {
141-
log.Debugf("Error querying nameserver %s: %q", s.config.Nameservers[nsIndex], err)
154+
log.Debugf("Error querying nameserver %s: %q", nsList[nsIndex], err)
142155
// Got an error, this usually means the server did not respond
143156
// Continue with next available nameserver
144-
if (nsIndex + 1) < len(s.config.Nameservers) {
157+
if (nsIndex + 1) < len(nsList) {
145158
nsIndex++
146159
doingSearch = false
147160
goto Redo

server/server.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,6 @@ func (s *server) ServeDNS(w dns.ResponseWriter, req *dns.Msg) {
202202
return
203203
}
204204

205-
// Forward queries matching stub zones
206-
for zone, ns := range *s.config.Stub {
207-
if strings.HasSuffix(name, zone) {
208-
local = false
209-
s.ServeDNSStubForward(w, req, ns)
210-
return
211-
}
212-
}
213-
214205
// Forward all other queries
215206
local = false
216207
s.ServeDNSForward(w, req)

server/stub.go

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)