1
0
Fork 0
mirror of https://github.com/SamTherapy/dnscrypt.git synced 2024-11-20 04:43:47 +00:00
Fork of a Golang DNSCrypt v2 protocol implementation + a command-line tool
Find a file
2021-03-19 16:13:44 +03:00
.github/workflows added github actions 2021-03-19 16:13:44 +03:00
cmd Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
testdata Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
xsecretbox refactor: 💡 upgrade to go v1.14 2020-04-03 18:29:07 +03:00
.codecov.yml Set target coverage to 60% 2020-10-19 17:31:54 +03:00
.gitignore cleanup repo 2020-10-19 17:45:36 +03:00
.golangci.yml Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
cert.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
cert_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
client.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
client_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
constants.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
doc.go Added DNSCrypt server implementation 2020-10-19 17:20:49 +03:00
encrypted_query.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
encrypted_query_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
encrypted_response.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
encrypted_response_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
generate.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
generate_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
go.mod Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
go.sum Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
handler.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
LICENSE Init 2018-12-17 01:55:58 +03:00
Makefile all: fix Makefile 2020-11-30 19:40:06 +03:00
README.md Add convert-dnscrypt-wrapper command 2021-02-02 13:54:52 +03:00
server.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
server_bench_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
server_tcp.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
server_test.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
server_udp.go Graceful shutdown of the DNSCrypt server (#6) 2021-03-19 15:42:48 +03:00
util.go Upgrade to v2 2020-10-19 18:36:54 +03:00

Build Status Code Coverage Go Report Card Go Doc

DNSCrypt Go

Golang-implementation of the DNSCrypt v2 protocol.

This repo includes everything you need to work with DNSCrypt. You can run your own resolver, make DNS lookups to other DNSCrypt resolvers, and you can use it as a library in your own projects.

Command-line tool

dnscrypt is a helper tool that can work as a DNSCrypt client or server.

Please note, that even though this tool can work as a server, it's purpose is merely testing. Use dnsproxy or AdGuard Home for real-life purposes.

How to install

Download and unpack an archive for your platform from the latest release.

How to configure

Generate a configuration file for running a DNSCrypt server:

./dnscrypt generate

[generate command options]
      -p, --provider-name= DNSCrypt provider name. Param is required.
      -o, --out=           Path to the resulting config file. Param is required.
      -k, --private-key=   Private key (hex-encoded)
      -t, --ttl=           Certificate time-to-live (seconds)

It will generate a configuration file that looks like this:

provider_name: 2.dnscrypt-cert.example.org
public_key: F11DDBCC4817E543845FDDD4CB881849B64226F3DE397625669D87B919BC4FB0
private_key: 5752095FFA56D963569951AFE70FE1690F378D13D8AD6F8054DFAA100907F8B6F11DDBCC4817E543845FDDD4CB881849B64226F3DE397625669D87B919BC4FB0
resolver_secret: 9E46E79FEB3AB3D45F4EB3EA957DEAF5D9639A0179F1850AFABA7E58F87C74C4
resolver_public: 9327C5E64783E19C339BD6B680A56DB85521CC6E4E0CA5DF5274E2D3CE026C6B
es_version: 1
certificate_ttl: 0s
  • provider_name - DNSCrypt resolver name.
  • public_key, private_key - keypair that is used by the DNSCrypt resolver to sign the certificate.
  • resolver_secret, resolver_public - keypair that is used by the DNSCrypt resolver to encrypt and decrypt messages.
  • es_version - crypto to use. Can be 1 (XSalsa20Poly1305) or 2 (XChacha20Poly1305).
  • certificate_ttl - certificate time-to-live. By default it's set to 0 and in this case 1-year cert is generated. The certificate is generated on dnscrypt start-up and it will only be valid for the specified amount of time. You should periodically restart dnscrypt to rotate the cert.

Converting dnscrypt-wrapper configuration

Also, to create a configuration, you can use the keys generated using dnscrypt-wrapper by running the command:

./dnscrypt convert-dnscrypt-wrapper

[convert-dnscrypt-wrapper command options]
      -p, --private-key=     Path to the DNSCrypt resolver private key file that is used for signing certificates. Param is required.
      -r, --resolver-secret= Path to the Short-term privacy key file for encrypting/decrypting DNS queries. If not specified, resolver_secret and resolver_public will be randomly generated.
      -n, --provider-name=   DNSCrypt provider name. Param is required.
      -o, --out=             Path to the resulting config file. Param is required.
      -t, --ttl=             Certificate time-to-live (seconds)

Running a server

This configuration file can be used to run a DNSCrypt forwarding server:

./dnscrypt server 

[server command options]
      -c, --config=  Path to the DNSCrypt configuration file. Param is required.
      -f, --forward= Forwards DNS queries to the specified address (default: 94.140.14.140:53)
      -l, --listen=  Listening addresses (default: 0.0.0.0)
      -p, --port=    Listening ports (default: 443)

Now you can go to https://dnscrypt.info/stamps and use provider_name and public_key from this configuration to generate a DNS stamp. Here's how it looks like for a server running on 127.0.0.1:443:

sdns://AQcAAAAAAAAADTEyNy4wLjAuMTo0NDMg8R3bzEgX5UOEX93Uy4gYSbZCJvPeOXYlZp2HuRm8T7AbMi5kbnNjcnlwdC1jZXJ0LmV4YW1wbGUub3Jn

Making lookups

You can use that stamp to send a DNSCrypt request to your server:

./dnscrypt lookup-stamp

[lookup-stamp command options]
      -n, --network= network type (tcp/udp) (default: udp)
      -s, --stamp=   DNSCrypt resolver stamp. Param is required.
      -d, --domain=  Domain to resolve. Param is required.
      -t, --type=    DNS query type (default: A)

You can also send a DNSCrypt request using a command that does not require stamps:

./dnscrypt lookup \

[lookup command options]
      -n, --network=       network type (tcp/udp) (default: udp)
      -p, --provider-name= DNSCrypt resolver provider name. Param is required.
      -k, --public-key=    DNSCrypt resolver public key. Param is required.
      -a, --addr=          Resolver address (IP[:port]). By default, the port is 443. Param is required.
      -d, --domain=        Domain to resolve. Param is required.
      -t, --type=          DNS query type (default: A)

Programming interface

Client

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

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

// Fetching and validating the server certificate
resolverInfo, err := client.Dial(stampStr)
if err != nil {
    return err
}

// 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, err := c.Exchange(&req, resolverInfo)

Server

// Prepare the test DNSCrypt server config
rc, err := dnscrypt.GenerateResolverConfig("example.org", nil)
if err != nil {
    return err
}

cert, err := rc.CreateCert()
if err != nil {
    return err
}

s := &dnscrypt.Server{
    ProviderName: rc.ProviderName,
    ResolverCert: cert,
    Handler:      dnscrypt.DefaultHandler,
}

// Prepare TCP listener
tcpConn, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4zero, Port: 443})
if err != nil {
    return err
}

// Prepare UDP listener
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 443})
if err != nil {
    return err
}

// Start the server
go s.ServeUDP(udpConn)
go s.ServeTCP(tcpConn)