Skip to content

Commit

Permalink
CoreDNS plugin connects to controller server
Browse files Browse the repository at this point in the history
* Fix firewall-controller nix run target
* Add helper targets to makefile
* Add test Corefile
  • Loading branch information
nikitawootten committed Dec 27, 2023
1 parent c2c0917 commit b26c28b
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 9 deletions.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,17 @@ test-unit:
.PHONY: codegen
codegen:
go generate ./...

COREDNS_PORT := 5300

.PHONY: run-coredns
run-coredns:
nix run .#coredns -- -conf support/TestCorefile -p $(COREDNS_PORT)

.PHONY: run-firewall-controller
run-firewall-controller:
nix run .#firewall-controller -- server --address :8080

.PHONY: send-dns-request
send-dns-request:
dig @127.0.0.1 -p $(COREDNS_PORT) lvh.me
38 changes: 32 additions & 6 deletions src/coredns_plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,51 @@ import (
"context"
"net"

"time"

"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/pkg/dnstest"
clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
"github.com/nikitawootten/dns-firewall-controller/src/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

var PLUGIN_NAME = "squawker"

var log = clog.NewWithPlugin(PLUGIN_NAME)

type Squawker struct {
Next plugin.Handler
client proto.FirewallControllerClient
Next plugin.Handler
}

type SquawkerConfig struct {
address string
}

func NewSquawker(next plugin.Handler) plugin.Handler {
return &Squawker{Next: next}
func NewSquawker(next plugin.Handler, config SquawkerConfig) plugin.Handler {
var opts []grpc.DialOption
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))

conn, err := grpc.Dial(config.address, opts...)
if err != nil {
plugin.Error(PLUGIN_NAME, err)
}

return &Squawker{
Next: next,
client: proto.NewFirewallControllerClient(conn),
}
}

func (s *Squawker) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
log.Info("Squawk!")

state := request.Request{W: w, Req: r}
client := state.IP()
client := net.ParseIP(state.IP())

rrw := dnstest.NewRecorder(w)
rc, err := plugin.NextOrFailure(s.Name(), s.Next, ctx, rrw, r)
Expand Down Expand Up @@ -59,9 +80,14 @@ func (s *Squawker) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Ms
}
}

log.Infof("Squawker writing policy for %v: %v for %v seconds", client, allowed_ips, max_ttl)
for_duration := time.Duration(max_ttl) * time.Second

// TODO: Write policy to server
log.Infof("Squawker writing policy for %v: %v for %v seconds", client, allowed_ips, max_ttl)
policy, err := proto.NewClientPolicy(client, allowed_ips, time.Now().Add(for_duration))
_, err = s.client.WriteClientPolicy(ctx, policy)
if err != nil {
return rc, plugin.Error(PLUGIN_NAME, err)
}

return rc, err
}
Expand Down
23 changes: 21 additions & 2 deletions src/coredns_plugin/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,30 @@ import (
func init() { plugin.Register(PLUGIN_NAME, setup) }

func setup(c *caddy.Controller) error {
c.Next() // Ignore "squawker" and give us the next token.
config, err := parseArgs(c)
if err != nil {
return err
}

dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
return NewSquawker(next)
return NewSquawker(next, *config)
})

return nil
}

func parseArgs(c *caddy.Controller) (*SquawkerConfig, error) {
config := SquawkerConfig{}

c.Next() // Ignore "squawker" and give us the next token.

args := c.RemainingArgs()

if len(args) != 1 {
return nil, plugin.Error(PLUGIN_NAME, c.ArgErr())
}

config.address = args[0]

return &config, nil
}
19 changes: 19 additions & 0 deletions src/coredns_plugin/setup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package squawker

import (
"testing"

"github.com/coredns/caddy"
"github.com/stretchr/testify/assert"
)

func TestSetupPlugin(t *testing.T) {
config, err := parseArgs(caddy.NewTestController("dns", "squawker"))
assert.Nil(t, config, "config not returned on error")
assert.Error(t, err, "error on no args")

config, err = parseArgs(caddy.NewTestController("dns", "squawker 192.168.1.1:8080"))
assert.NotNil(t, config, "config returned on provided address")
assert.Equal(t, "192.168.1.1:8080", config.address, "match provided address")
assert.NoError(t, err, "no error on provided address")
}
8 changes: 8 additions & 0 deletions support/TestCorefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
. {
reload
errors
debug
log
squawker 127.0.0.1:8080
forward . 8.8.8.8
}
2 changes: 1 addition & 1 deletion support/buildCoreDnsWithPlugin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pkgs.buildGoModule {

nativeBuildInputs = [ pkgs.installShellFiles ];

vendorHash = "sha256-Dfp1LTLtP0i3nbeWeEV2MFSbwc584ASBj+enFWmVCEk=";
vendorHash = "sha256-qs3Sb4MnosNIv5p9QWIJEcdJMF5bXQAwUY547ru3HYY=";
# vendorHash = pkgs.lib.fakeHash;

# VERY hacky way to add a plugin to the coredns build
Expand Down
4 changes: 4 additions & 0 deletions support/buildFirewallController.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ pkgs.buildGoModule {
src = common.src;
vendorHash = "sha256-sF8RFUEIy3mip/EyJDn0+mRfFbeBbn18rqsWtfsAOqo=";
# vendorHash = pkgs.lib.fakeHash;

postInstall = ''
mv $out/bin/firewall_controller $out/bin/firewall-controller
'';
}

0 comments on commit b26c28b

Please sign in to comment.