add support for cloudflare https dns

main
fangdingjun 7 years ago
parent b202c341f7
commit a19ee5a6dc

1
.gitignore vendored

@ -1,2 +1,3 @@
*~ *~
dns* dns*
gdns*

@ -0,0 +1,19 @@
package main
import (
"fmt"
"testing"
"github.com/miekg/dns"
)
func TestCFDns(t *testing.T) {
cf := &CloudflareHTTPDns{}
m := new(dns.Msg)
m.SetQuestion("www.google.com.", dns.TypeA)
m1, _, err := cf.Exchange(m, "1.1.1.1")
if err != nil {
t.Fatal(err)
}
fmt.Println(m1.String())
}

@ -0,0 +1,59 @@
package main
import (
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/miekg/dns"
)
var httpclientCF = &http.Client{
Timeout: 8 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{ServerName: "cloudflare-dns.com"},
TLSHandshakeTimeout: 5 * time.Second,
},
}
// CloudflareHTTPDns cloudflare http dns
type CloudflareHTTPDns struct {
}
// Exchange send request to server and get result
func (cf *CloudflareHTTPDns) Exchange(m *dns.Msg, addr string) (m1 *dns.Msg, d time.Duration, err error) {
u := fmt.Sprintf("https://%s/dns-query", addr)
data, err := m.Pack()
if err != nil {
return
}
body := bytes.NewBuffer(data)
req, err := http.NewRequest("POST", u, body)
if err != nil {
return
}
req.Header.Set("Content-Type", "application/dns-udpwireformat")
resp, err := httpclientCF.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
data, err = ioutil.ReadAll(resp.Body)
if err != nil {
return
}
m1 = new(dns.Msg)
if err = m1.Unpack(data); err != nil {
return
}
return
}

@ -2,10 +2,11 @@ package main
import ( import (
"bufio" "bufio"
"github.com/go-yaml/yaml"
"io/ioutil" "io/ioutil"
"os" "os"
"strings" "strings"
"github.com/go-yaml/yaml"
) )
type conf struct { type conf struct {

@ -1,10 +1,12 @@
listen: listen:
- network: tcp -
network: tcp
host: 0.0.0.0 host: 0.0.0.0
port: 1053 port: 1053
- network: udp -
network: udp
host: 0.0.0.0 host: 0.0.0.0
port: 1053 port: 1053
@ -24,18 +26,28 @@ defaultupstream:
port: 53 port: 53
forwardrules: forwardrules:
- domainfile: ./testdata/cn.dat -
domainfile: ./testdata/cn.dat
server: server:
- network: tcp -
network: tcp
host: 114.114.114.114 host: 114.114.114.114
port: 53 port: 53
- domainfile: testdata/us.dat -
domainfile: testdata/us.dat
server: server:
- network: tcp -
network: tcp
host: 8.8.8.8 host: 8.8.8.8
port: 53 port: 53
- network: https -
host: 74.175.200.100 network: https_google
host: 172.217.161.174
port: 443
-
network: https_cloudflare
host: 1.1.1.1
port: 443 port: 443

@ -4,13 +4,14 @@ import (
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/miekg/dns"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"sync" "sync"
"time" "time"
"github.com/miekg/dns"
) )
// ServerAddr is Google dns server ip // ServerAddr is Google dns server ip

@ -3,9 +3,10 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/miekg/dns"
"strings" "strings"
"time" "time"
"github.com/miekg/dns"
) )
type dnsClient interface { type dnsClient interface {
@ -16,7 +17,8 @@ type dnsHandler struct {
cfg *conf cfg *conf
tcpclient dnsClient tcpclient dnsClient
udpclient dnsClient udpclient dnsClient
httpsclient dnsClient httpsgoogle dnsClient
httpscf dnsClient
} }
func newDNSHandler(cfg *conf) *dnsHandler { func newDNSHandler(cfg *conf) *dnsHandler {
@ -24,7 +26,8 @@ func newDNSHandler(cfg *conf) *dnsHandler {
cfg: cfg, cfg: cfg,
tcpclient: &dns.Client{Net: "tcp", Timeout: 8 * time.Second, UDPSize: 4096}, tcpclient: &dns.Client{Net: "tcp", Timeout: 8 * time.Second, UDPSize: 4096},
udpclient: &dns.Client{Net: "udp", Timeout: 5 * time.Second, UDPSize: 4096}, udpclient: &dns.Client{Net: "udp", Timeout: 5 * time.Second, UDPSize: 4096},
httpsclient: &GoogleHTTPDns{}, httpsgoogle: &GoogleHTTPDns{},
httpscf: &CloudflareHTTPDns{},
} }
} }
@ -79,13 +82,20 @@ func (h *dnsHandler) queryUpstream(r *dns.Msg, srv addr, ch chan *dns.Msg) {
srv.Host, srv.Host,
srv.Port) srv.Port)
m, _, err = h.udpclient.Exchange(r, fmt.Sprintf("%s:%d", srv.Host, srv.Port)) m, _, err = h.udpclient.Exchange(r, fmt.Sprintf("%s:%d", srv.Host, srv.Port))
case "https": case "https_google":
info("query %s IN %s, forward to %s:%d through https", info("query %s IN %s, forward to %s:%d through google https",
r.Question[0].Name,
dns.TypeToString[r.Question[0].Qtype],
srv.Host,
srv.Port)
m, _, err = h.httpsgoogle.Exchange(r, fmt.Sprintf("%s:%d", srv.Host, srv.Port))
case "https_cloudflare":
info("query %s IN %s, forward to %s:%d through cloudflare https",
r.Question[0].Name, r.Question[0].Name,
dns.TypeToString[r.Question[0].Qtype], dns.TypeToString[r.Question[0].Qtype],
srv.Host, srv.Host,
srv.Port) srv.Port)
m, _, err = h.httpsclient.Exchange(r, fmt.Sprintf("%s:%d", srv.Host, srv.Port)) m, _, err = h.httpscf.Exchange(r, srv.Host)
default: default:
// ignore // ignore
} }

@ -3,8 +3,9 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/miekg/dns"
"log" "log"
"github.com/miekg/dns"
) )
func main() { func main() {

Loading…
Cancel
Save