Configuration package (#369)
This commit is contained in:
154
internal/configuration/dns.go
Normal file
154
internal/configuration/dns.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
unboundmodels "github.com/qdm12/dns/pkg/models"
|
||||
unbound "github.com/qdm12/dns/pkg/unbound"
|
||||
"github.com/qdm12/golibs/params"
|
||||
)
|
||||
|
||||
// DNS contains settings to configure Unbound for DNS over TLS operation.
|
||||
type DNS struct { //nolint:maligned
|
||||
Enabled bool
|
||||
PlaintextAddress net.IP
|
||||
KeepNameserver bool
|
||||
BlockMalicious bool
|
||||
BlockAds bool
|
||||
BlockSurveillance bool
|
||||
UpdatePeriod time.Duration
|
||||
Unbound unboundmodels.Settings
|
||||
}
|
||||
|
||||
func (settings *DNS) String() string {
|
||||
return strings.Join(settings.lines(), "\n")
|
||||
}
|
||||
|
||||
func (settings *DNS) lines() (lines []string) {
|
||||
lines = append(lines, lastIndent+"DNS:")
|
||||
|
||||
if settings.PlaintextAddress != nil {
|
||||
lines = append(lines, indent+lastIndent+"Plaintext address: "+settings.PlaintextAddress.String())
|
||||
}
|
||||
|
||||
if settings.KeepNameserver {
|
||||
lines = append(lines, indent+lastIndent+"Keep nameserver (disabled blocking): yes")
|
||||
}
|
||||
|
||||
if !settings.Enabled {
|
||||
return lines
|
||||
}
|
||||
|
||||
lines = append(lines, indent+lastIndent+"DNS over TLS:")
|
||||
|
||||
lines = append(lines, indent+indent+lastIndent+"Unbound:")
|
||||
for _, line := range settings.Unbound.Lines() {
|
||||
lines = append(lines, indent+indent+indent+line)
|
||||
}
|
||||
|
||||
if settings.BlockMalicious {
|
||||
lines = append(lines, indent+indent+lastIndent+"Block malicious: enabled")
|
||||
}
|
||||
|
||||
if settings.BlockAds {
|
||||
lines = append(lines, indent+indent+lastIndent+"Block ads: enabled")
|
||||
}
|
||||
|
||||
if settings.BlockSurveillance {
|
||||
lines = append(lines, indent+indent+lastIndent+"Block surveillance: enabled")
|
||||
}
|
||||
|
||||
if settings.UpdatePeriod > 0 {
|
||||
lines = append(lines, indent+indent+lastIndent+"Update: every "+settings.UpdatePeriod.String())
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
var (
|
||||
ErrUnboundSettings = errors.New("failed getting Unbound settings")
|
||||
ErrDNSProviderNoData = errors.New("DNS provider has no associated data")
|
||||
ErrDNSProviderNoTLS = errors.New("DNS provider does not support DNS over TLS")
|
||||
ErrDNSNoIPv6Support = errors.New("no DNS provider supports IPv6")
|
||||
)
|
||||
|
||||
func (settings *DNS) read(r reader) (err error) {
|
||||
settings.Enabled, err = r.env.OnOff("DOT", params.Default("on"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Plain DNS settings
|
||||
if err := settings.readDNSPlaintext(r.env); err != nil {
|
||||
return err
|
||||
}
|
||||
settings.KeepNameserver, err = r.env.OnOff("DNS_KEEP_NAMESERVER", params.Default("off"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// DNS over TLS external settings
|
||||
settings.BlockMalicious, err = r.env.OnOff("BLOCK_MALICIOUS", params.Default("on"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.BlockSurveillance, err = r.env.OnOff("BLOCK_SURVEILLANCE", params.Default("on"),
|
||||
params.RetroKeys([]string{"BLOCK_NSA"}, r.onRetroActive))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.BlockAds, err = r.env.OnOff("BLOCK_ADS", params.Default("off"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.UpdatePeriod, err = r.env.Duration("DNS_UPDATE_PERIOD", params.Default("24h"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := settings.readUnbound(r); err != nil {
|
||||
return fmt.Errorf("%w: %s", ErrUnboundSettings, err)
|
||||
}
|
||||
|
||||
// Consistency check
|
||||
IPv6Support := false
|
||||
for _, provider := range settings.Unbound.Providers {
|
||||
providerData, ok := unbound.GetProviderData(provider)
|
||||
switch {
|
||||
case !ok:
|
||||
return fmt.Errorf("%w: %s", ErrDNSProviderNoData, provider)
|
||||
case !providerData.SupportsTLS:
|
||||
return fmt.Errorf("%w: %s", ErrDNSProviderNoTLS, provider)
|
||||
case providerData.SupportsIPv6:
|
||||
IPv6Support = true
|
||||
}
|
||||
}
|
||||
|
||||
if settings.Unbound.IPv6 && !IPv6Support {
|
||||
return ErrDNSNoIPv6Support
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
ErrDNSAddressNotAnIP = errors.New("DNS plaintext address is not an IP address")
|
||||
)
|
||||
|
||||
func (settings *DNS) readDNSPlaintext(env params.Env) error {
|
||||
s, err := env.Get("DNS_PLAINTEXT_ADDRESS", params.Default("1.1.1.1"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.PlaintextAddress = net.ParseIP(s)
|
||||
if settings.PlaintextAddress == nil {
|
||||
return fmt.Errorf("%w: %s", ErrDNSAddressNotAnIP, s)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user