dnsmock

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2022 License: MIT Imports: 7 Imported by: 0

README

DNSMOCK

Go Test

Go Report Card

codecov

DnsMock is a Go library that will return mocked DNS responses for any record type, in an easy to author YAML format.

It also can be run as a server that will record DNS results and return them as a YAML file, as well as replaying those results.

Let's look at a simple example:

# replay.yaml
rules:
 - name: google.com.
   records:
    A:
    - "google.com. 300 IN A 4.3.2.1"

Now run the server to return those results:

$./dnsmock -replay-file replay.yaml -port 9053 &
$ dig @localhost -p 9053 google.com

; <<>> DiG 9.16.1-Ubuntu <<>> @localhost -p 9053 google.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5540
;; flags: qr rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             300     IN      A       4.3.2.1

This can also be run as a Docker container for easy portability.

Server Usage Detail

To use as an executable simply run the cmd package, with the following params:

  • --port: Port to listen on, default is 53
  • --record: Record DNS queries and responses, output them to stdout at exit
  • --record-file: Record DNS queries and responses to specified file at exit.
  • --replay-file: Replay the responses in the file (see below for details)
  • --downstreams: Comma delimated list of downstreams or localhost (default) to load /etc/resolv.conf, or none to not have downstreams, e.g. anything not in replay file will fail to resolve.
go build -o dnsmock ./cmd
./dnsmock --port 53" --record --downstreams "8.8.8.8,8.4.4.4"

Now test with

dig @0.0.0.0 -p 50053 google.com

When you exit this will output the queries and responses to stdout. Capture those to a file like "replay.yaml".

Docker

Note this is also available as a Docker image:

docker build -t dnsmock:local .
docker run -p "50053:53/udp" -d dnsmock:local -record
dig @0.0.0.0 -p 50053 google.com

Test Library Usage

You can also use just the library for standing up mock servers.

There is a working example usage in TestMock in the incredibly well named e2e_example_mock_test.go file.

To do this in your project, you can do something like:

import (
    "github.com/shawnburke/dnsmock"
    "github.com/shawnburke/dnsmock/resolver"

    "go.uber.org/zap"
)

func runProxy() {
    logger := zap.NewNop()

    // create a resolver that looks up responses
    // from the replay file
    r := resolver.NewReplayFromFile("replay.yaml", logger)

    // Now create a new mocks server that serves those results
    p := dnsmock.New(":0", resolver, logger)
    err := p.Start()
    fmt.Println("Running at:", p.Addr())

    // Query it!
    client := &dns.Client{Network:"udp"}
    msg := &dns.Msg {
        Question: []dns.Question{
			{
				Name:   "google.com.",
				Qtype:  dns.TypeA,
				Qclass: dns.ClassINET,
			},
		},
    }
    response, err := client.Exchange(msg, p.Addr())
    fmt.Println(response)
    p.Stop()
}

Replay File Format

The replay file is simple, and allows wildcards. Entries are processed in order, first match wins.

Below, we set up rules for internet.com (exact match), *.awstest.com, and a fallthrough rule that returns 42 for all SRV requests.

  rules:
    - name: "internet.com."
      records:
        A:
            - "internet.com.\t197\tIN\tA\t172.64.155.149"
            - "internet.com.\t197\tIN\tA\t104.21.31.107"
    - name: "*.awstest.com."
      records:
        A:
          - "{{Name}}\t300\tIN\tA\t1.2.3.4"
    - name: "*" 
      records:
        SRV:
        - "{{Name}}\t60\tIN\tSRV\t0 100 42 {{Name}}"

To get these values either record or copy them from dig output.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Proxy

type Proxy interface {
	Start() error
	Stop() error
	Addr() string
}

func New

func New(
	addr string,
	resolver resolver.Resolver,
	logger *zap.Logger) Proxy

func NewFromConfig

func NewFromConfig(cfg config.Parameters, resolver resolver.Resolver, logger *zap.Logger) Proxy

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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