dnscrypt

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2020 License: Unlicense Imports: 16 Imported by: 1

README

Build Status Code Coverage Go Report Card Go Doc

DNSCrypt Client

This is a very simple DNSCrypt client library written in Go.

The idea is to let others use DNSCrypt resolvers in the same manner as we can use regular and DoT resolvers with miekg's DNS library. Unfortunately, I have not found an easy way to use dnscrypt-proxy as a dependency so here's why this library was created.

Usage
    // AdGuard DNS stamp
    stampStr := "sdns://AQIAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20"
    
    // Initializing the DNSCrypt client
    c := dnscrypt.Client{Proto: "udp", Timeout: 10 * time.Second}
    
    // Fetching and validating the server certificate
    serverInfo, rtt, err := client.Dial(stampStr)
    
    // Create a DNS request
    req := dns.Msg{}
    req.Id = dns.Id()
    req.RecursionDesired = true
    req.Question = []dns.Question{
        {Name: "google-public-dns-a.google.com.", Qtype: dns.TypeA, Qclass: dns.ClassINET},
    }
    
    // Get the DNS response
    reply, rtt, err := c.Exchange(&req, serverInfo)

Documentation

Overview

Package dnscrypt implements a very simple DNSCrypt client library.

The idea is to let others use DNSCrypt resolvers in the same manner as we can use regular and DoT resolvers with miekg's DNS library.

Here is a simple usage example:

// AdGuard DNS stamp
stampStr := "sdns://AQIAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20"

// Initializing the DNSCrypt client
c := dnscrypt.Client{Proto: "udp", Timeout: 10 * time.Second}

// Fetching and validating the server certificate
serverInfo, rtt, err := client.Dial(stampStr)

// Create a DNS request
req := dns.Msg{}
req.Id = dns.Id()
req.RecursionDesired = true
req.Question = []dns.Question{
    {Name: "google-public-dns-a.google.com.", Qtype: dns.TypeA, Qclass: dns.ClassINET},
}

// Get the DNS response
reply, rtt, err := c.Exchange(&req, serverInfo)

Unfortunately, I have not found an easy way to use dnscrypt-proxy as a dependency so here's why this library was created.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CertInfo

type CertInfo struct {
	Serial             uint32   // Cert serial number (the cert can be superseded by another one with a higher serial number)
	ServerPk           [32]byte // Server public key
	SharedKey          [32]byte // Shared key
	MagicQuery         [clientMagicLen]byte
	CryptoConstruction CryptoConstruction // Encryption algorithm
	NotBefore          uint32             // Cert is valid starting from this date (epoch time)
	NotAfter           uint32             // Cert is valid until this date (epoch time)
}

CertInfo contains DnsCrypt server certificate data retrieved from the server

type Client

type Client struct {
	Proto             string        // Protocol ("udp" or "tcp"). Empty means "udp".
	Timeout           time.Duration // Timeout for read/write operations (0 means infinite timeout)
	AdjustPayloadSize bool          // If true, the client will automatically add a EDNS0 RR that will advertise a larger buffer
}

Client contains parameters for a DNSCrypt client

func (*Client) Dial

func (c *Client) Dial(stampStr string) (*ServerInfo, time.Duration, error)

Dial fetches and validates DNSCrypt certificate from the given server Data received during this call is then used for DNS requests encryption/decryption stampStr is an sdns:// address which is parsed using go-dnsstamps package

func (*Client) DialStamp

func (c *Client) DialStamp(stamp dnsstamps.ServerStamp) (*ServerInfo, time.Duration, error)

DialStamp fetches and validates DNSCrypt certificate from the given server Data received during this call is then used for DNS requests encryption/decryption

func (*Client) Exchange

func (c *Client) Exchange(m *dns.Msg, s *ServerInfo) (*dns.Msg, time.Duration, error)

Exchange performs a synchronous DNS query to the specified DNSCrypt server and returns a DNS response. This method creates a new network connection for every call so avoid using it for TCP. DNSCrypt server information needs to be fetched and validated prior to this call using the c.DialStamp method.

func (*Client) ExchangeConn

func (c *Client) ExchangeConn(m *dns.Msg, s *ServerInfo, conn net.Conn) (*dns.Msg, time.Duration, error)

ExchangeConn performs a synchronous DNS query to the specified DNSCrypt server and returns a DNS response. DNSCrypt server information needs to be fetched and validated prior to this call using the c.DialStamp method

type CryptoConstruction

type CryptoConstruction uint16

CryptoConstruction represents the encryption algorithm (either XSalsa20Poly1305 or XChacha20Poly1305)

const (
	// UndefinedConstruction is the default value for empty CertInfo only
	UndefinedConstruction CryptoConstruction = iota
	// XSalsa20Poly1305 encryption
	XSalsa20Poly1305
	// XChacha20Poly1305 encryption
	XChacha20Poly1305
)

type ServerInfo

type ServerInfo struct {
	SecretKey       [32]byte          // Client secret key
	PublicKey       [32]byte          // Client public key
	ServerPublicKey ed25519.PublicKey // Server public key
	ServerAddress   string            // Server IP address
	ProviderName    string            // Provider name

	ServerCert *CertInfo // Certificate info (obtained with the first unencrypted DNS request)
}

ServerInfo contains DNSCrypt server information necessary for decryption/encryption

Directories

Path Synopsis
Package xsecretbox implements encryption/decryption of a message using specified keys
Package xsecretbox implements encryption/decryption of a message using specified keys

Jump to

Keyboard shortcuts

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