commit 0a3ca79c8e36dc108fecf910524518063dadd56c
parent 8286582481dcaeaca322a57edebda5a492cf9b98
Author: Oliver Lowe <o@olowe.co>
Date: Sat, 13 Nov 2021 14:03:31 +1100
Make git.sr.ht/~otl/dns a Go package
And rename dohtest to dohproxy. This thing is going live soon baby
Diffstat:
8 files changed, 96 insertions(+), 84 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+cmd/dohproxy/dohproxy
diff --git a/README b/README
@@ -1,7 +1,11 @@
Please don't use this yet
+ $ cd cmd/dohproxy
$ go build
- $ ./dohtest
$ curl -v --doh-insecure --doh-url https://127.0.0.1:8080/dns-query http://www.olowe.co
Adjust upstream resolver by changing `quad9` to some other address.
+
+https://blog.nlnetlabs.nl/dns-over-https-in-unbound/
+
+https://datatracker.ietf.org/doc/html/rfc8484
diff --git a/cmd/dohproxy/dohproxy.go b/cmd/dohproxy/dohproxy.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+ "net"
+ "io"
+ "fmt"
+ "net/http"
+ "log"
+ "git.sr.ht/~otl/dns"
+// "golang.org/x/net/dns/dnsmessage"
+)
+
+// https://quad9.net
+const quad9 string = "9.9.9.9:domain"
+const cloudflare string = "1.1.1.1:domain"
+
+func forward(msg []byte) ([]byte, error) {
+ fmt.Println("starting to resolve")
+ conn, err := net.Dial("udp", quad9)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+ fmt.Println("dialled upstream ok")
+ if _, err := conn.Write(msg); err != nil {
+ return nil, err
+ }
+ fmt.Println("wrote request to upstream ok")
+ buf := make([]byte, 1024)
+ n, err := conn.Read(buf)
+ if err != nil {
+ return nil, err
+ }
+ return buf[:n], nil
+}
+
+func dnsHandler(w http.ResponseWriter, req *http.Request) {
+ if v, ok := req.Header["Content-Type"]; ok {
+ for _, s := range v {
+ if s != dns.MediaType {
+ http.Error(w, "unsupported media type", http.StatusUnsupportedMediaType)
+ return
+ }
+ }
+ }
+
+ if req.Method != http.MethodPost && req.Method != http.MethodGet {
+ http.Error(w, "method must be GET or POST", http.StatusNotImplemented)
+ return
+ }
+
+ buf := make([]byte, 512)
+ switch req.Method {
+ case http.MethodPost:
+ fmt.Println("got a POST request")
+ _, err := req.Body.Read(buf)
+ if err != nil && err != io.EOF {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ fmt.Println("read request body into buffer")
+ req.Body.Close()
+ case http.MethodGet:
+ log.Println("got a GET request but that's not implemented")
+ http.Error(w, "in progress!", http.StatusNotImplemented)
+ return
+ }
+
+ resolved, err := forward(buf)
+ if err != nil {
+ fmt.Println(err.Error())
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ w.Header().Add("Content-Type", dns.MediaType)
+ if _, err := w.Write(resolved); err != nil {
+ log.Fatalln(err)
+ }
+}
+
+func main() {
+ http.HandleFunc("/dns-query", dnsHandler)
+ log.Fatalln(http.ListenAndServeTLS("127.0.0.1:8080", "otl.crt", "otl.key", nil))
+}
diff --git a/otl.crt b/cmd/dohproxy/otl.crt
diff --git a/otl.key b/cmd/dohproxy/otl.key
diff --git a/dns.go b/dns.go
@@ -0,0 +1,5 @@
+package dns
+
+// https://datatracker.ietf.org/doc/html/rfc8484
+const MediaType string = "application/dns-message"
+const MaxMsgSize int = 65535 // max size of a message in bytes
diff --git a/dohtest.go b/dohtest.go
@@ -1,82 +0,0 @@
-package main
-
-import (
- "net"
- "io"
- "fmt"
- "net/http"
- "log"
-// "golang.org/x/net/dns/dnsmessage"
-)
-
-// https://quad9.net
-const quad9 string = "9.9.9.9:domain"
-const cloudflare string = "1.1.1.1:domain"
-const dnsMediaType string = "application/dns-message"
-
-func forward(msg []byte) ([]byte, error) {
- fmt.Println("starting to resolve")
- conn, err := net.Dial("udp", cloudflare)
- if err != nil {
- return nil, err
- }
- defer conn.Close()
- fmt.Println("dialled upstream ok")
- if _, err := conn.Write(msg); err != nil {
- return nil, err
- }
- fmt.Println("wrote request to upstream ok")
- buf := make([]byte, 1024)
- n, err := conn.Read(buf)
- if err != nil {
- return nil, err
- }
- return buf[:n], nil
-}
-
-func dnsHandler(w http.ResponseWriter, req *http.Request) {
- if v, ok := req.Header["Content-Type"]; ok {
- for _, s := range v {
- if s != dnsMediaType {
- http.Error(w, "unsupported media type", http.StatusUnsupportedMediaType)
- return
- }
- }
- }
-
- buf := make([]byte, 512)
- switch req.Method {
- case http.MethodPost:
- fmt.Println("got a POST request")
- _, err := req.Body.Read(buf)
- if err != nil && err != io.EOF {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- fmt.Println("read request body into buffer")
- req.Body.Close()
- case http.MethodGet:
- log.Println("got a GET request but that's not implemented")
- http.Error(w, "in progress!", http.StatusNotImplemented)
- return
- default:
- http.Error(w, "method must be GET or POST", http.StatusNotImplemented)
- return
- }
-
- resolved, err := forward(buf)
- if err != nil {
- fmt.Println(err.Error())
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- w.Header().Add("Content-type", dnsMediaType)
- if _, err := w.Write(resolved); err != nil {
- log.Fatalln(err)
- }
-}
-
-func main() {
- http.HandleFunc("/dns-query", dnsHandler)
- log.Fatalln(http.ListenAndServeTLS("127.0.0.1:8080", "otl.crt", "otl.key", nil))
-}
diff --git a/go.mod b/go.mod
@@ -1,3 +1,3 @@
-module dohtest
+module git.sr.ht/~otl/dns
go 1.17