Add proof of concept
This commit is contained in:
commit
7dd6650fd0
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.env
|
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
FROM golang:1.10
|
||||||
|
WORKDIR $GOPATH/src/git.k-space.ee/pinecrypt/goredns
|
||||||
|
COPY main.go .
|
||||||
|
RUN go get -d -v ./...
|
||||||
|
RUN go install -v ./...
|
||||||
|
CMD ["goredns"]
|
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
goredns:
|
||||||
|
network_mode: host
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
env_file: .env
|
||||||
|
|
86
main.go
Normal file
86
main.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryItem struct {
|
||||||
|
Ip []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapper(coll *mongo.Collection) func(dns.ResponseWriter, *dns.Msg) {
|
||||||
|
return func(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
|
m := new(dns.Msg)
|
||||||
|
m.SetReply(r)
|
||||||
|
m.Compress = false
|
||||||
|
switch r.Opcode {
|
||||||
|
case dns.OpcodeQuery:
|
||||||
|
for _, q := range m.Question {
|
||||||
|
switch q.Qtype {
|
||||||
|
case dns.TypeA:
|
||||||
|
log.Printf("Query for %s\n", q.Name[:len(q.Name)-1])
|
||||||
|
cur, err := coll.Find(context.TODO(), bson.M{"hostname":q.Name[:len(q.Name)-1]})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for cur.Next(context.TODO()) {
|
||||||
|
var elem InventoryItem
|
||||||
|
err := cur.Decode(&elem)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ip := range elem.Ip {
|
||||||
|
tp := "A"
|
||||||
|
if (strings.Contains(ip, ":")) {
|
||||||
|
tp = "AAAA"
|
||||||
|
}
|
||||||
|
rr, err := dns.NewRR(fmt.Sprintf("%s %s %s",
|
||||||
|
q.Name, tp, ip))
|
||||||
|
if err == nil {
|
||||||
|
m.Answer = append(m.Answer, rr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.WriteMsg(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client, err := mongo.NewClient(options.Client().ApplyURI(os.Getenv("MONGO_URI")))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
err = client.Connect(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
coll := client.Database("kspace_accounting").Collection("inventory")
|
||||||
|
defer client.Disconnect(ctx)
|
||||||
|
dns.HandleFunc(".", wrapper(coll))
|
||||||
|
port := 5354
|
||||||
|
server := &dns.Server{Addr: ":" + strconv.Itoa(port), Net: "udp"}
|
||||||
|
log.Printf("Starting at %d\n", port)
|
||||||
|
err2 := server.ListenAndServe()
|
||||||
|
defer server.Shutdown()
|
||||||
|
if err2 != nil {
|
||||||
|
log.Fatalf("Failed to start server: %s\n ", err2.Error())
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user