Skip to content

Commit

Permalink
Custom DNS Server returns only TXT records
Browse files Browse the repository at this point in the history
This small DNS server only returns one type of record, a TXT record,
meant to be a token assigned by a certificate authority (e.g. Let's
Encrypt) to verify domain ownership.

The TXT record will be updateable by an API endpoint on the webserver
(same executable as the DNS server), but I haven't yet written that
portion.

Drive-by: in our _other_ (main) sslip.io DNS server, I changed `break` →
`continue` in the main loop. Had we gotten a malformed UDP packet, we
would have exited, but now we continue to the next packet. Exiting is
not that big a deal—`monit` would have restarted the server—but moving
on to the next packet is a more robust approach.

[#6]
  • Loading branch information
cunnie committed Jan 9, 2021
1 parent 631ae31 commit 838911f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 4 deletions.
2 changes: 1 addition & 1 deletion bosh-release/src/sslip.io-dns-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func main() {
_, addr, err := conn.ReadFromUDP(query)
if err != nil {
log.Println(err.Error())
break
continue
}

go func() {
Expand Down
5 changes: 5 additions & 0 deletions bosh-release/src/wildcard-dns-http-server/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/cunnie/sslip.io/bosh-release/src/wildcard-dns-http-server

go 1.15

require golang.org/x/net v0.0.0-20201224014010-6772e930b67b
6 changes: 6 additions & 0 deletions bosh-release/src/wildcard-dns-http-server/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
90 changes: 90 additions & 0 deletions bosh-release/src/wildcard-dns-http-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"log"
"net"
"sync"

"golang.org/x/net/dns/dnsmessage"
)

var txt = `Set this TXT record: curl -X POST http://localhost/update -d '{"txt":"Certificate Authority's validation token"}'`

func main() {
conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: 53})
if err != nil {
log.Fatal(err.Error())
}

var group sync.WaitGroup
group.Add(1)
go dnsServer(conn, &group)
group.Add(1)
go httpServer(&group)
group.Wait()
}

func dnsServer(conn *net.UDPConn, group *sync.WaitGroup) {
var query dnsmessage.Message

defer group.Done()
log.Println("I'm firing up the DNS server.")
queryRaw := make([]byte, 512)
for {
_, addr, err := conn.ReadFromUDP(queryRaw)
if err != nil {
log.Println(err.Error())
continue
}
err = query.Unpack(queryRaw)
if err != nil {
log.Println(err.Error())
continue
}
// Technically, there can be multiple questions in a DNS message; practically, there's only one
if len(query.Questions) != 1 {
log.Printf("I expected one question but got %d.\n", len(query.Questions))
continue
}
// We only return answers to TXT records, nothing else
if query.Questions[0].Type != dnsmessage.TypeTXT {
log.Println("I expected a question for a TypeTXT record but got a question for a " + query.Questions[0].Type.String() + " record.")
continue
}
reply := dnsmessage.Message{
Header: dnsmessage.Header{
ID: query.ID,
Response: true,
Authoritative: true,
RecursionDesired: query.RecursionDesired,
},
Questions: query.Questions,
Answers: []dnsmessage.Resource{
{
Header: dnsmessage.ResourceHeader{
Name: query.Questions[0].Name,
Type: dnsmessage.TypeTXT,
Class: dnsmessage.ClassINET,
},
Body: &dnsmessage.TXTResource{TXT: []string{txt}},
},
},
}
replyRaw, err := reply.Pack()
if err != nil {
log.Println(err.Error())
continue
}
_, err = conn.WriteToUDP(replyRaw, addr)
if err != nil {
log.Println(err.Error())
continue
}
log.Printf("%v.%d %s → \"%s\"\n", addr.IP, addr.Port, query.Questions[0].Type.String(), txt)
}
}

func httpServer(group *sync.WaitGroup) {
defer group.Done()
log.Println("I'm firing up the HTTP server.")
}
4 changes: 1 addition & 3 deletions docs/wildcard.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ docker run --rm -it \

Clean-up:
```
gcloud compute firewall-rules delete sslip-io-allow-dns-http-ssh
gcloud compute firewall-rules delete sslip-io-allow-dns-http
gcloud compute firewall-rules delete sslip-io-allow-dns
gcloud compute instances delete
gcloud compute instances delete sslip
```

0 comments on commit 838911f

Please sign in to comment.