Documentation
¶
Overview ¶
Package dnscrypt includes client-side and server-side implementations of the DNSCrypt v2. See https://dnscrypt.info/protocol for a detailed description of the protocol.
Index ¶
- Constants
- func HexDecodeKey(str string) (decoded []byte, err error)
- func HexEncodeKey(b []byte) (encoded string)
- type Certificate
- func (c *Certificate) MarshalBinary() (serialized []byte, err error)
- func (c *Certificate) Sign(privateKey ed25519.PrivateKey)
- func (c *Certificate) String() (s string)
- func (c *Certificate) UnmarshalBinary(b []byte) (err error)
- func (c *Certificate) Validate() (err error)
- func (c *Certificate) VerifyDate() (ok bool)
- func (c *Certificate) VerifySignature(publicKey ed25519.PublicKey) (ok bool)
- type Client
- func (c *Client) DialContext(ctx context.Context, stampStr string) (info *ResolverInfo, err error)
- func (c *Client) DialStampContext(ctx context.Context, stamp dnsstamps.ServerStamp) (info *ResolverInfo, err error)
- func (c *Client) ExchangeConnContext(ctx context.Context, conn net.Conn, m *dns.Msg, info *ResolverInfo) (resp *dns.Msg, err error)
- func (c *Client) ExchangeContext(ctx context.Context, m *dns.Msg, info *ResolverInfo) (resp *dns.Msg, err error)
- type ClientConfig
- type CryptoConstruction
- type Handler
- type Proto
- type ResolverConfig
- type ResolverInfo
- type ResponseWriter
- type Server
- type ServerConfig
Constants ¶
const ( // KeySize is the size of public and secret keys in bytes. See // https://dnscrypt.info/protocol for more information. KeySize = 32 // messages. SharedKeySize = 32 )
const ( // ErrTooShort is returned when the DNS query is shorter than possible. ErrTooShort errors.Error = "message is too short" // ErrQueryTooLarge is returned when the DNS query is larger than max // allowed size. ErrQueryTooLarge errors.Error = "dnscrypt query is too large" // ErrESVersion is returned when the cert contains unsupported es-version. ErrESVersion errors.Error = "unsupported es-version" // ErrInvalidDate is returned when the cert is not valid for the current // time. ErrInvalidDate errors.Error = "cert has invalid ts-start or ts-end" // ErrInvalidCertSignature is returned when the cert has invalid signature. ErrInvalidCertSignature errors.Error = "cert has invalid signature" // ErrInvalidQuery is returned when it failed to decrypt a DNSCrypt query. ErrInvalidQuery errors.Error = "dnscrypt query is invalid and cannot be decrypted" // ErrInvalidClientMagic is returned when client-magic does not match. ErrInvalidClientMagic errors.Error = "dnscrypt query contains invalid client magic" // ErrInvalidResolverMagic is returned when server-magic does not match. ErrInvalidResolverMagic errors.Error = "dnscrypt response contains invalid resolver magic" // ErrInvalidResponse is returned when it failed to decrypt a DNSCrypt // response. ErrInvalidResponse errors.Error = "dnscrypt response is invalid and cannot be decrypted" // ErrInvalidPadding is returned when it failed to unpad a query. ErrInvalidPadding errors.Error = "invalid padding" // ErrInvalidDNSStamp is returned when an invalid DNS stamp is provided. ErrInvalidDNSStamp errors.Error = "invalid stamp" // ErrFailedToFetchCert is returned when it failed to fetch DNSCrypt // certificate. ErrFailedToFetchCert errors.Error = "failed to fetch dnscrypt certificate" // ErrCertTooShort is returned when it failed to deserialize cert, too // short. ErrCertTooShort errors.Error = "cert is too short" // ErrCertMagic is returned when an invalid cert magic is encountered. ErrCertMagic errors.Error = "invalid cert magic" // ErrServerConfig is returned when it failed to start the DNSCrypt server // due to invalid configuration. ErrServerConfig errors.Error = "invalid server configuration" // ErrServerNotStarted is returned if there's nothing to shutdown. ErrServerNotStarted errors.Error = "server is not started" // ErrServerAlreadyStarted is returned if [Server.Start] is being called on // a server that is already started. ErrServerAlreadyStarted errors.Error = "server is already started" )
const (
// DNSCryptV2Prefix is the prefix for DNSCrypt v2 provider names.
DNSCryptV2Prefix = "2.dnscrypt-cert."
)
Variables ¶
This section is empty.
Functions ¶
func HexDecodeKey ¶
HexDecodeKey decodes a hex-encoded string with (optional) colons to a byte array.
func HexEncodeKey ¶
HexEncodeKey encodes a byte slice to a hex-encoded string.
Types ¶
type Certificate ¶
type Certificate struct {
// Serial is a 4 byte serial number in big-endian format. If more than
// one certificates are valid, the client must prefer the certificate with
// a higher serial number.
Serial uint32
// ESVersion is the cryptographic construction to use with this
// certificate.
ESVersion CryptoConstruction
// Signature is a 64-byte signature of (<resolver-pk> <client-magic>
// <serial> <ts-start> <ts-end> <extensions>) using the Ed25519 algorithm
// and the provider secret key. Ed25519 must be used in this version of
// the protocol.
Signature [ed25519.SignatureSize]byte
// ResolverPk is the resolver's short-term public key, which is 32 bytes
// when using X25519. This key is used to encrypt/decrypt DNS queries.
ResolverPk [KeySize]byte
// ResolverSk is the resolver's short-term private key, which is 32 bytes
// when using X25519. Note that it's only used in the server implementation
// and never serialized/deserialized. This key is used to encrypt/decrypt
// DNS queries.
ResolverSk [KeySize]byte
// ClientMagic is the first 8 bytes of a client query that is to be built
// using the information from this certificate. It may be a truncated
// public key. Two valid certificates cannot share the same <client-magic>.
ClientMagic [clientMagicSize]byte
// NotBefore is the date the certificate is valid from, as a big-endian
// 4-byte unsigned Unix timestamp.
NotBefore uint32
// NotAfter is the date the certificate is valid until (inclusive), as a
// big-endian 4-byte unsigned Unix timestamp.
NotAfter uint32
}
Certificate is a DNSCrypt server certificate. See ResolverConfig for more info on how to create one.
func (*Certificate) MarshalBinary ¶
func (c *Certificate) MarshalBinary() (serialized []byte, err error)
MarshalBinary implements the encoding.BinaryMarshaler interface for *Certificate. The certificate is serialised into a byte slice using the following schema: <cert> ::= <cert-magic> <es-version> <protocol-minor-version> <signature> <resolver-pk> <client-magic> <serial> <ts-start> <ts-end>
Certificates made of these information, without extensions, are 116 bytes long. With the addition of the cert-magic, es-version and protocol-minor-version, the record is [certByteLength] bytes long. err is always nil.
func (*Certificate) Sign ¶
func (c *Certificate) Sign(privateKey ed25519.PrivateKey)
Sign creates cert signature. privateKey must not be nil.
func (*Certificate) String ¶
func (c *Certificate) String() (s string)
String implements the fmt.Stringer interface for *Certificate.
func (*Certificate) UnmarshalBinary ¶
func (c *Certificate) UnmarshalBinary(b []byte) (err error)
UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for *Certificate. Certificate is being deserialized using the following schema: <cert> ::= <cert-magic> <es-version> <protocol-minor-version> <signature> <resolver-pk> <client-magic> <serial> <ts-start> <ts-end>
func (*Certificate) Validate ¶
func (c *Certificate) Validate() (err error)
Validate implements the validate.Interface for *Certificate.
func (*Certificate) VerifyDate ¶
func (c *Certificate) VerifyDate() (ok bool)
VerifyDate checks that the cert is valid at this moment.
func (*Certificate) VerifySignature ¶
func (c *Certificate) VerifySignature(publicKey ed25519.PublicKey) (ok bool)
VerifySignature checks if the cert is properly signed with the specified signature. publicKey must not be nil.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a DNSCrypt resolver client.
func NewClient ¶
func NewClient(conf *ClientConfig) (c *Client)
NewClient returns properly initialized *Client. c must be non-nil and valid.
func (*Client) DialContext ¶
DialContext 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) DialStampContext ¶
func (c *Client) DialStampContext( ctx context.Context, stamp dnsstamps.ServerStamp, ) (info *ResolverInfo, err error)
DialStampContext fetches and validates DNSCrypt certificate from the given server. Data received during this call is then used for DNS requests encryption/decryption.
func (*Client) ExchangeConnContext ¶
func (c *Client) ExchangeConnContext( ctx context.Context, conn net.Conn, m *dns.Msg, info *ResolverInfo, ) (resp *dns.Msg, err error)
ExchangeConnContext 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 Client.DialStampContext method. conn, m, and info must not be nil.
func (*Client) ExchangeContext ¶
func (c *Client) ExchangeContext( ctx context.Context, m *dns.Msg, info *ResolverInfo, ) (resp *dns.Msg, err error)
ExchangeContext 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 cert needs to be fetched and validated prior to this call using the Client.DialStampContext method. m and info must not be nil.
type ClientConfig ¶
type ClientConfig struct {
// Logger is a logger instance for Client. If not set, slog.Default()
// will be used.
Logger *slog.Logger
// Proto is the base network protocol.
Proto Proto
// UDPSize is the maximum size of a DNS response (or query) this client
// can send or receive. If not set, we use [dns.MinMsgSize] by default.
UDPSize int
}
ClientConfig is the configuration structure for Client.
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 represents XSalsa20Poly1305 encryption. XSalsa20Poly1305 CryptoConstruction = 0x0001 // XChacha20Poly1305 represents XChacha20Poly1305 encryption. XChacha20Poly1305 CryptoConstruction = 0x0002 )
func (CryptoConstruction) String ¶
func (c CryptoConstruction) String() (construction string)
String implements the fmt.Stringer interface for CryptoConstruction.
type Handler ¶
type Handler interface {
// ServeDNS handles DNS requests. rw and r must not be nil.
ServeDNS(ctx context.Context, rw ResponseWriter, r *dns.Msg) (err error)
}
Handler describes DNS handlers.
type Proto ¶
type Proto string
Proto represents the base network protocol.
func ProtoFromString ¶
ProtoFromString converts s into a Proto and makes sure it is valid. This should be preferred to a simple type conversion.
func (Proto) Validate ¶
Validate implements the validate.Interface for Proto.
type ResolverConfig ¶
type ResolverConfig struct {
// ProviderName is the DNSCrypt provider name.
ProviderName string `yaml:"provider_name"`
// PublicKey is the DNSCrypt resolver public key.
PublicKey string `yaml:"public_key"`
// PrivateKey is the DNSCrypt resolver private key. The main and only
// purpose of this key is to sign the certificate.
PrivateKey string `yaml:"private_key"`
// ResolverSk is a hex-encoded short-term private key. This key is used to
// encrypt/decrypt DNS queries. If not set, we'll generate a new random
// ResolverSk and ResolverPk.
ResolverSk string `yaml:"resolver_secret"`
// ResolverPk is a hex-encoded short-term public key corresponding to
// ResolverSk. This key is used to encrypt/decrypt DNS queries.
ResolverPk string `yaml:"resolver_public"`
// ESVersion is the crypto to use in this resolver.
ESVersion CryptoConstruction `yaml:"es_version"`
// CertificateTTL is the time-to-live value for the certificate that is
// generated using this ResolverConfig. If not set, we'll use 1 year by
// default.
CertificateTTL time.Duration `yaml:"certificate_ttl"`
}
ResolverConfig is the DNSCrypt resolver configuration.
func GenerateResolverConfig ¶
func GenerateResolverConfig( providerName string, privateKey ed25519.PrivateKey, ttl time.Duration, ) (rc ResolverConfig, err error)
GenerateResolverConfig generates resolver configuration for a given provider name. providerName is mandatory. If needed, DNSCryptV2Prefix prefix is added to it. privateKey is optional. If not set, it will be generated automatically.
func (*ResolverConfig) CreateStamp ¶
func (rc *ResolverConfig) CreateStamp(addr string) (stamp dnsstamps.ServerStamp, err error)
CreateStamp generates a DNS stamp for this resolver.
func (*ResolverConfig) NewCert ¶
func (rc *ResolverConfig) NewCert() (cert *Certificate, err error)
NewCert generates a signed Certificate to be used by Server.
func (*ResolverConfig) Validate ¶
func (rc *ResolverConfig) Validate() (err error)
Validate implements the validate.Interface for *ResolverConfig.
type ResolverInfo ¶
type ResolverInfo struct {
// ResolverCert contains certificate info (obtained with the first
// unencrypted DNS request).
ResolverCert *Certificate
// ServerAddress is the server IP address.
ServerAddress string
// ProviderName is the provider name.
ProviderName string
// ServerPublicKey is the resolver public key (this key is used to
// validate cert signature).
ServerPublicKey ed25519.PublicKey
// messages.
SharedKey [KeySize]byte
// SecretKey is the client short-term secret key.
SecretKey [KeySize]byte
// PublicKey is the client short-term public key.
PublicKey [KeySize]byte
}
ResolverInfo contains DNSCrypt resolver information necessary for decryption/encryption.
type ResponseWriter ¶
type ResponseWriter interface {
// LocalAddr returns local socket address.
LocalAddr() (addr net.Addr)
// RemoteAddr returns remote client socket address.
RemoteAddr() (addr net.Addr)
// WriteMsg writes response message to the client. m must not be nil.
WriteMsg(ctx context.Context, m *dns.Msg) (err error)
}
ResponseWriter describes response writer for various protocols.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a DNSCrypt server implementation.
func NewServer ¶
func NewServer(conf *ServerConfig) (s *Server, err error)
NewServer returns properly initialized *Server. conf must be non-nil and valid.
func (*Server) LocalAddr ¶
LocalAddr returns the local network address for the given protocol, if known.
func (*Server) Shutdown ¶
Shutdown implements the service.Interface for *Server. It waits until all connections are processed and only after that it leaves the method. If context deadline is specified, it will exit earlier.
type ServerConfig ¶
type ServerConfig struct {
// Handler to invoke. If nil, the [DefaultHandler] is used.
Handler Handler
// ResolverCert contains resolver certificate. It must not be nil.
ResolverCert *Certificate
// Logger is a logger instance for Server. If not set, slog.Default() will
// be used.
Logger *slog.Logger
// ProviderName is a DNSCrypt provider name.
ProviderName string
// Addr is the address for server to listen. It must not be empty.
Addr netip.AddrPort
// Proto defines protocol for serving. It must be one of the following:
//
// - [ProtoTCP]
// - [ProtoUDP]
Proto Proto
// UDPSize is the default buffer size to use to read incoming UDP messages.
// If not set it defaults to [defaultUDPSize].
UDPSize uint
}
ServerConfig is the configuration structure for Server.
func (*ServerConfig) Validate ¶
func (c *ServerConfig) Validate() (err error)
Validate implements the validate.Interface for *ServerConfig.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
dnscrypt
command
|
|
|
internal
|
|
|
cmd
Package cmd is the DNSCrypt entry point.
|
Package cmd is the DNSCrypt entry point. |
|
forward
Package forward contains all the necessary utilities for DNS request forwarding.
|
Package forward contains all the necessary utilities for DNS request forwarding. |
|
version
Package version contains the version information.
|
Package version contains the version information. |
|
xsecretbox
Package xsecretbox implements encryption/decryption of a message using specified keys.
|
Package xsecretbox implements encryption/decryption of a message using specified keys. |