Skip to content

Commit

Permalink
Configurable access control
Browse files Browse the repository at this point in the history
- Add all IPv6 addresses to whitelist
  • Loading branch information
qdm12 committed Jan 3, 2021
1 parent 1323cba commit 2b70eec
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 4 deletions.
2 changes: 1 addition & 1 deletion internal/models/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type ProviderData struct {
SupportsDNSSEC bool
}

type Settings struct { //nolint:maligned
type Settings struct {
Unbound models.Settings
Username string
Puid, Pgid int
Expand Down
13 changes: 13 additions & 0 deletions internal/settings/unbound.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package settings

import (
"net"

"github.com/qdm12/dns/internal/params"
"github.com/qdm12/dns/pkg/models"
)
Expand Down Expand Up @@ -55,5 +57,16 @@ func getUnboundSettings(reader params.Reader) (settings models.Settings, err err
return settings, err
}
settings.BlockedIPs = append(settings.BlockedIPs, privateAddresses...)

settings.AccessControl.Allowed = []net.IPNet{
{
IP: net.IPv4zero,
Mask: net.IPv4Mask(0, 0, 0, 0),
},
{
IP: net.IPv6zero,
Mask: net.IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
}
return settings, nil
}
24 changes: 22 additions & 2 deletions pkg/models/settings.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package models

import (
"net"
"strconv"
"strings"
)

const prefix = " |--"

// Settings represents all the user settings for Unbound.
type Settings struct { //nolint:maligned
type Settings struct {
Providers []string
ListeningPort uint16
Caching bool
Expand All @@ -17,6 +21,7 @@ type Settings struct { //nolint:maligned
BlockedHostnames []string
BlockedIPs []string
AllowedHostnames []string
AccessControl AccessControlSettings
}

func (s *Settings) String() string {
Expand All @@ -28,7 +33,6 @@ func (s *Settings) Lines() (lines []string) {
disabled = "disabled"
enabled = "enabled"
)
const prefix = " |--"

lines = append(lines, "DNS over TLS provider:")
for _, provider := range s.Providers {
Expand All @@ -38,6 +42,8 @@ func (s *Settings) Lines() (lines []string) {
lines = append(lines,
"Listening port: "+strconv.Itoa(int(s.ListeningPort)))

lines = append(lines, s.AccessControl.Lines()...)

caching := disabled
if s.Caching {
caching = enabled
Expand Down Expand Up @@ -85,3 +91,17 @@ func (s *Settings) Lines() (lines []string) {

return lines
}

type AccessControlSettings struct {
Allowed []net.IPNet
}

func (s *AccessControlSettings) Lines() (lines []string) {
lines = append(lines, "Access control:")
lines = append(lines, prefix+"Allowed:")
for _, subnet := range s.Allowed {
lines = append(lines,
" "+prefix+subnet.String())
}
return lines
}
12 changes: 12 additions & 0 deletions pkg/models/settings_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package models

import (
"net"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -16,6 +17,8 @@ func Test_Settings_Lines(t *testing.T) {
lines: []string{
"DNS over TLS provider:",
"Listening port: 0",
"Access control:",
" |--Allowed:",
"Caching: disabled",
"IPv4 resolution: disabled",
"IPv6 resolution: disabled",
Expand All @@ -40,12 +43,21 @@ func Test_Settings_Lines(t *testing.T) {
BlockedHostnames: []string{"hostname 1", "hostname 2"},
BlockedIPs: []string{"1.1.1.2", "2.2.2.2"},
AllowedHostnames: []string{"hostname 3", "hostname 4"},
AccessControl: AccessControlSettings{
Allowed: []net.IPNet{{
IP: net.IPv4zero,
Mask: net.IPv4Mask(0, 0, 0, 0),
}},
},
},
lines: []string{
"DNS over TLS provider:",
" |--quad9",
" |--cloudflare",
"Listening port: 53",
"Access control:",
" |--Allowed:",
" |--0.0.0.0/0",
"Caching: enabled",
"IPv4 resolution: enabled",
"IPv6 resolution: enabled",
Expand Down
7 changes: 6 additions & 1 deletion pkg/unbound/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,18 @@ func generateUnboundConf(settings models.Settings,
"do-ip4: " + ipv4,
"do-ip6: " + ipv6,
"interface: 0.0.0.0",
"access-control: 0.0.0.0/0 allow",
"port: " + strconv.Itoa(int(settings.ListeningPort)),
// Other
`username: "` + username + `"`,
`include: "` + filepath.Join(unboundDir, includeConfFilename) + `"`,
}

// Access control
for _, subnet := range settings.AccessControl.Allowed {
line := "access-control: " + subnet.String() + " allow"
serverLines = append(serverLines, line)
}

// DNSSEC trust anchor file
dnsSec := true
for _, provider := range settings.Providers {
Expand Down
7 changes: 7 additions & 0 deletions pkg/unbound/conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"sync"
Expand All @@ -27,6 +28,12 @@ func Test_generateUnboundConf(t *testing.T) {
ListeningPort: 53,
IPv4: true,
IPv6: true,
AccessControl: dnsmodels.AccessControlSettings{
Allowed: []net.IPNet{{
IP: net.IPv4zero,
Mask: net.IPv4Mask(0, 0, 0, 0),
}},
},
}
lines := generateUnboundConf(settings,
[]string{
Expand Down

0 comments on commit 2b70eec

Please sign in to comment.