134 lines
3.2 KiB
Go
134 lines
3.2 KiB
Go
package configuration
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
|
|
unbound "github.com/qdm12/dns/pkg/unbound"
|
|
"github.com/qdm12/golibs/params"
|
|
)
|
|
|
|
func (settings *DNS) readUnbound(r reader) (err error) {
|
|
if err := settings.readUnboundProviders(r.env); err != nil {
|
|
return err
|
|
}
|
|
|
|
settings.Unbound.ListeningPort = 53
|
|
|
|
settings.Unbound.Caching, err = r.env.OnOff("DOT_CACHING", params.Default("on"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
settings.Unbound.IPv4 = true
|
|
|
|
settings.Unbound.IPv6, err = r.env.OnOff("DOT_IPV6", params.Default("off"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
verbosityLevel, err := r.env.IntRange("DOT_VERBOSITY", 0, 5, params.Default("1"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
settings.Unbound.VerbosityLevel = uint8(verbosityLevel)
|
|
|
|
verbosityDetailsLevel, err := r.env.IntRange("DOT_VERBOSITY_DETAILS", 0, 4, params.Default("0"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
settings.Unbound.VerbosityDetailsLevel = uint8(verbosityDetailsLevel)
|
|
|
|
validationLogLevel, err := r.env.IntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, params.Default("0"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
settings.Unbound.ValidationLogLevel = uint8(validationLogLevel)
|
|
|
|
if err := settings.readUnboundPrivateAddresses(r.env); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := settings.readUnboundUnblockedHostnames(r); err != nil {
|
|
return err
|
|
}
|
|
|
|
settings.Unbound.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 nil
|
|
}
|
|
|
|
var (
|
|
ErrInvalidDNSOverTLSProvider = errors.New("invalid DNS over TLS provider")
|
|
)
|
|
|
|
func (settings *DNS) readUnboundProviders(env params.Env) (err error) {
|
|
s, err := env.Get("DOT_PROVIDERS", params.Default("cloudflare"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, provider := range strings.Split(s, ",") {
|
|
_, ok := unbound.GetProviderData(provider)
|
|
if !ok {
|
|
return fmt.Errorf("%w: %s", ErrInvalidDNSOverTLSProvider, provider)
|
|
}
|
|
settings.Unbound.Providers = append(settings.Unbound.Providers, provider)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
ErrInvalidPrivateAddress = errors.New("private address is not a valid IP or CIDR range")
|
|
)
|
|
|
|
func (settings *DNS) readUnboundPrivateAddresses(env params.Env) (err error) {
|
|
privateAddresses, err := env.CSV("DOT_PRIVATE_ADDRESS")
|
|
if err != nil {
|
|
return err
|
|
} else if len(privateAddresses) == 0 {
|
|
return nil
|
|
}
|
|
for _, address := range privateAddresses {
|
|
ip := net.ParseIP(address)
|
|
_, _, err := net.ParseCIDR(address)
|
|
if ip == nil && err != nil {
|
|
return fmt.Errorf("%w: %s", ErrInvalidPrivateAddress, address)
|
|
}
|
|
}
|
|
settings.Unbound.BlockedIPs = append(
|
|
settings.Unbound.BlockedIPs, privateAddresses...)
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
ErrInvalidHostname = errors.New("invalid hostname")
|
|
)
|
|
|
|
func (settings *DNS) readUnboundUnblockedHostnames(r reader) (err error) {
|
|
hostnames, err := r.env.CSV("UNBLOCK")
|
|
if err != nil {
|
|
return err
|
|
} else if len(hostnames) == 0 {
|
|
return nil
|
|
}
|
|
for _, hostname := range hostnames {
|
|
if !r.regex.MatchHostname(hostname) {
|
|
return fmt.Errorf("%w: %s", ErrInvalidHostname, hostname)
|
|
}
|
|
}
|
|
settings.Unbound.AllowedHostnames = append(
|
|
settings.Unbound.AllowedHostnames, hostnames...)
|
|
return nil
|
|
}
|