Skip to content

Commit

Permalink
Add notprox (#29)
Browse files Browse the repository at this point in the history
* Add notprox

Also move to github action and drop travis.

Signed-off-by: Miek Gieben <miek@miek.nl>

* go mod wrong?

Signed-off-by: Miek Gieben <miek@miek.nl>

---------

Signed-off-by: Miek Gieben <miek@miek.nl>
  • Loading branch information
miekg authored Jan 13, 2024
1 parent 5f23f82 commit b1c92bc
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 13 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "monthly"
32 changes: 32 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: "Code scanning - action"

on:
push:
branches: [master, ]
pull_request:
branches: [master]
schedule:
- cron: '0 23 * * 5'

jobs:
CodeQL-Build:

runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 2

- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}

- name: Initialize CodeQL
uses: github/codeql-action/init@v2

- name: Autobuild
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
25 changes: 25 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Go
on: [push, pull_request]
jobs:

build:
name: Build and Test
runs-on: ubuntu-latest
strategy:
matrix:
go: [ 1.20.x, 1.21.x ]
steps:

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}

- name: Check out code
uses: actions/checkout@v3

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[![Build Status](https://travis-ci.org/miekg/exdns.svg?branch=master)](https://travis-ci.org/miekg/exdns)
[![BSD 2-clause license](https://img.shields.io/github/license/miekg/exdns.svg?maxAge=2592000)](https://opensource.org/licenses/BSD-2-Clause)

# Examples made with Go DNS
Expand All @@ -13,3 +12,4 @@ Currently they include:
* `check-soa`: check the SOA record of zones for all nameservers
* `q`: dig-like query tool
* `reflect`: reflection nameserver
* `notprox`: a notify proxy server
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/miekg/exdns

go 1.21.1
go 1.21

require github.com/miekg/dns v1.1.56

Expand Down
13 changes: 13 additions & 0 deletions notproxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# notprox

A DNS notify proxy server. See route.go for the routing of the notifies.
It purely proxies, meaning the server itself doesn't send replies, it requires
that the server the notify is sent too, will send a notify response.

See RFC 1996 for DNS notifies.

Not done and problems one can forsee:

* TSIG key configuration

Tested with `dig @localhost -p 8053 SOA +aa +norec +opcode=notify miek.nl`
59 changes: 59 additions & 0 deletions notproxy/notprox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2024 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// A notify proxy server.

package main

import (
"flag"
"log"
"net"
"os"
"os/signal"
"strconv"
"syscall"

"github.com/miekg/dns"
)

// route holds all the routing information
var routes = []Route{
{"miek.nl.", net.ParseIP("127.0.0.1"), net.ParseIP("10.10.0.1")},
}

func main() {
port := flag.Int("port", 8053, "port to run on")
flag.Parse()

for i := range routes {
err := Register(routes[i])
if err != nil {
log.Fatalf("Failed to register route for: %q: %s", routes[i].Zone, err)
}
log.Printf("Registered route for zone: %q", routes[i].Zone)
}

go func() {
srv := &dns.Server{Addr: ":" + strconv.Itoa(*port), Net: "udp"}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("Failed to set udp listener: %s", err.Error())
}
}()

// technically we don't need to listen on TCP
go func() {
srv := &dns.Server{Addr: ":" + strconv.Itoa(*port), Net: "tcp"}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("Failed to set tcp listener: %s", err.Error())
}
}()

log.Printf("Ready for foward notifies on port %d", *port)

sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
s := <-sig
log.Fatalf("Signal (%v) received, stopping", s)
}
61 changes: 61 additions & 0 deletions notproxy/routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"log"
"net"

"github.com/miekg/dns"
)

// Route holds the routing configuration. Per zone there is one "from" and one "to" address.
// TODO: extend to multiple addresses.
type Route struct {
Zone string
From net.IP
To net.IP
}

// Register registers a dns.Handler for each zone that routes DNS notifies.
func Register(rt Route) error {
// Setup a conn for the lifetime of the server. Notifies are always UDP.
connTo, err := dns.Dial("udp", rt.To.String()+":53")
if err != nil {
return err
}
connFrom, err := dns.Dial("udp", rt.From.String()+":53")
if err != nil {
return err
}

dns.HandleFunc(rt.Zone, func(w dns.ResponseWriter, r *dns.Msg) {
if r.Opcode != dns.OpcodeNotify {
log.Printf("Non notify seen for zone: %q", r.Question[0].Name)
return
}

from, ok := w.RemoteAddr().(*net.UDPAddr)
if !ok {
log.Printf("Notify came in over TCP: dropping for zone: %q", r.Question[0].Name)
return
}
// if from 'from' then forward to 'to'
if rt.From.Equal(from.IP) {
if err := connTo.WriteMsg(r); err != nil {
log.Printf("Error while forwarding notify to %s for zone: %q: %s", rt.To, r.Question[0].Name, err)
}
return
}

// if from 'to' then forward to 'from'
if rt.To.Equal(from.IP) {
if err := connFrom.WriteMsg(r); err != nil {
log.Printf("Error while forwarding notify to %s for zone: %q: %s", rt.From, r.Question[0].Name, err)
}
return
}

log.Printf("No routing found for %q for zone: %q", from.IP, r.Question[0].Name)
// dropping request
})
return nil
}

0 comments on commit b1c92bc

Please sign in to comment.