commit b1bd5dc331f07d95b1cfcb9b3671fa1162fdd3c0
parent 0a3ca79c8e36dc108fecf910524518063dadd56c
Author: Oliver Lowe <o@olowe.co>
Date: Sun, 14 Nov 2021 11:31:20 +1100
Only forward DNS queries upstream
If someone made a POST request with any old bytes in the body we'd forward that upstream regardless.
Validate stuff sent to us by parsing the DNS queries and packing, unpacking each, then forward
Diffstat:
3 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/cmd/dohproxy/dohproxy.go b/cmd/dohproxy/dohproxy.go
@@ -3,35 +3,42 @@ package main
import (
"net"
"io"
- "fmt"
"net/http"
"log"
"git.sr.ht/~otl/dns"
-// "golang.org/x/net/dns/dnsmessage"
+ "golang.org/x/crypto/acme/autocert"
+ "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")
+func forward(msg dnsmessage.Message) (dnsmessage.Message, error) {
+ packed, err := msg.Pack()
+ if err != nil {
+ return dnsmessage.Message{}, err
+ }
+
conn, err := net.Dial("udp", quad9)
if err != nil {
- return nil, err
+ return dnsmessage.Message{}, err
}
defer conn.Close()
- fmt.Println("dialled upstream ok")
- if _, err := conn.Write(msg); err != nil {
- return nil, err
+ if _, err := conn.Write(packed); err != nil {
+ return dnsmessage.Message{}, err
}
- fmt.Println("wrote request to upstream ok")
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
- return nil, err
+ return dnsmessage.Message{}, err
+ }
+
+ var rmsg dnsmessage.Message
+ if err := rmsg.Unpack(buf[:n]); err != nil {
+ return dnsmessage.Message{}, err
}
- return buf[:n], nil
+ return rmsg, nil
}
func dnsHandler(w http.ResponseWriter, req *http.Request) {
@@ -52,13 +59,11 @@ func dnsHandler(w http.ResponseWriter, req *http.Request) {
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")
@@ -66,19 +71,30 @@ func dnsHandler(w http.ResponseWriter, req *http.Request) {
return
}
- resolved, err := forward(buf)
+ var msg dnsmessage.Message
+ if err := msg.Unpack(buf); err != nil {
+ log.Println("unpack query:", err)
+ http.Error(w, "unpack query: "+err.Error(), http.StatusInternalServerError)
+ }
+
+ resolved, err := forward(msg)
if err != nil {
- fmt.Println(err.Error())
+ log.Println(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
+ packed, err := resolved.Pack()
+ if err != nil {
+ log.Println("pack resolved query:", err.Error)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
w.Header().Add("Content-Type", dns.MediaType)
- if _, err := w.Write(resolved); err != nil {
+ if _, err := w.Write(packed); 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))
+ log.Fatalln(http.Serve(autocert.NewListener("syd.olowe.co"), nil))
}
diff --git a/go.mod b/go.mod
@@ -1,3 +1,9 @@
module git.sr.ht/~otl/dns
go 1.17
+
+require (
+ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
+ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
+ golang.org/x/text v0.3.3 // indirect
+)
diff --git a/go.sum b/go.sum
@@ -0,0 +1,9 @@
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=