Skip to content

Commit

Permalink
Add new --ednsopt argument to add arbitrary EDNS option
Browse files Browse the repository at this point in the history
To add a new edns option with code 4242:

$ echo -n "This is a binary string" | base64
VGhpcyBpcyBhIGJpbmFyeSBzdHJpbmc=

./dnsproxy -u 1.1.1.1 --ednsopt "4242:VGhpcyBpcyBhIGJpbmFyeSBzdHJpbmc="
  • Loading branch information
jubarbot-cisco committed Jul 20, 2020
1 parent 7b79d1c commit 61a8a31
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
27 changes: 27 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package main

import (
"crypto/tls"
"encoding/base64"
"fmt"
"io/ioutil"
"net"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"

Expand Down Expand Up @@ -100,6 +103,9 @@ type Options struct {
// Use Custom EDNS Client Address
EDNSAddr string `long:"edns-addr" description:"Send EDNS Client Address"`

// Add user-specific EDNS exstension
EDNSOpt []string `long:"ednsopt" description:"List of EDNS extensions to send along with the DNS query (ex: 8:deadbeaf)"`

// Other settings and options
// --

Expand Down Expand Up @@ -218,6 +224,27 @@ func createProxyConfig(options Options) proxy.Config {
}
}

if len(options.EDNSOpt) > 0 {
config.EDNSOpts = make(map[uint16][]byte)
for _, s := range options.EDNSOpt {
kv := strings.Split(s, ":")
if len(kv) != 2 {
log.Fatalf("parse error for '%s', --ednsopt must be of the form: option-code:base64encodeddata (ex: --ednsopt 8:SGVsbG8gd29ybGQK)", s)
} else {
r, err := strconv.ParseUint(kv[0], 10, 16)
if err != nil {
log.Fatalf("parse error for '%s', --ednsopt option-code must be a valid 16 bits numbers (between 0 and 65535)", kv[0])
}
optionCode := uint16(r)
data, err := base64.StdEncoding.DecodeString(kv[1])
if err != nil {
log.Fatalf("parse error for '%s', --ednsopt data must be a valid base64 encoded string: (%s)", kv[1], err)
}
config.EDNSOpts[optionCode] = data
}
}
}

if options.Fallbacks != nil {
fallbacks := []upstream.Upstream{}
for i, f := range options.Fallbacks {
Expand Down
3 changes: 3 additions & 0 deletions proxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ type Config struct {
EnableEDNSClientSubnet bool
EDNSAddr net.IP // ECS IP used in request

// List of raw EDNS options
EDNSOpts map[uint16][]byte

// Cache settings
// --

Expand Down
31 changes: 31 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ func (p *Proxy) Resolve(d *DNSContext) error {
p.processECS(d)
}

if p.Config.EDNSOpts != nil {
p.processEDNSOpts(d)
}

if p.replyFromCache(d) {
return nil
}
Expand Down Expand Up @@ -349,3 +353,30 @@ func (p *Proxy) processECS(d *DNSContext) {
d.ecsReqIP = ip
d.ecsReqMask = mask
}

// Set EDNSOpts
func (p *Proxy) processEDNSOpts(d *DNSContext) {
var o (*dns.OPT) = nil
for _, ex := range d.Req.Extra {
if ex.Header().Rrtype == dns.TypeOPT {
o = ex.(*dns.OPT)
break
}
}

if o == nil { // OPT Record does not already exist, create it
o = new(dns.OPT)
o.SetUDPSize(4096)
o.Hdr.Name = "."
o.Hdr.Rrtype = dns.TypeOPT
}

for k, v := range p.Config.EDNSOpts {
e := new(dns.EDNS0_LOCAL)
e.Code = k
e.Data = v
o.Option = append(o.Option, e)
}

d.Req.Extra = append(d.Req.Extra, o)
}

0 comments on commit 61a8a31

Please sign in to comment.