mirror of
https://github.com/qdm12/gluetun.git
synced 2026-06-14 23:43:56 +02:00
feat(dns): restrict plain DNS output traffic
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
Debug(s string)
|
||||
Info(s string)
|
||||
Warn(s string)
|
||||
Error(s string)
|
||||
}
|
||||
|
||||
type Firewall interface {
|
||||
RestrictOutputAddrPort(ctx context.Context, addrPort netip.AddrPort) (err error)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package dns
|
||||
|
||||
type Logger interface {
|
||||
Debug(s string)
|
||||
Info(s string)
|
||||
Warn(s string)
|
||||
Error(s string)
|
||||
}
|
||||
@@ -24,6 +24,7 @@ type Loop struct {
|
||||
localResolvers []netip.Addr
|
||||
resolvConf string
|
||||
client *http.Client
|
||||
firewall Firewall
|
||||
logger Logger
|
||||
userTrigger bool
|
||||
start <-chan struct{}
|
||||
@@ -39,7 +40,7 @@ type Loop struct {
|
||||
const defaultBackoffTime = 10 * time.Second
|
||||
|
||||
func NewLoop(settings settings.DNS,
|
||||
client *http.Client, logger Logger,
|
||||
client *http.Client, firewall Firewall, logger Logger,
|
||||
) (loop *Loop, err error) {
|
||||
start := make(chan struct{})
|
||||
running := make(chan models.LoopStatus)
|
||||
@@ -64,6 +65,7 @@ func NewLoop(settings settings.DNS,
|
||||
filter: filter,
|
||||
resolvConf: "/etc/resolv.conf",
|
||||
client: client,
|
||||
firewall: firewall,
|
||||
logger: logger,
|
||||
userTrigger: true,
|
||||
start: start,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/dns/v2/pkg/nameserver"
|
||||
)
|
||||
|
||||
func (l *Loop) useUnencryptedDNS(fallback bool) {
|
||||
func (l *Loop) useUnencryptedDNS(ctx context.Context, fallback bool) {
|
||||
settings := l.GetSettings()
|
||||
|
||||
targetIP := settings.GetFirstPlaintextIPv4()
|
||||
@@ -20,8 +21,9 @@ func (l *Loop) useUnencryptedDNS(fallback bool) {
|
||||
|
||||
const dialTimeout = 3 * time.Second
|
||||
const defaultDNSPort = 53
|
||||
addrPort := netip.AddrPortFrom(targetIP, defaultDNSPort)
|
||||
settingsInternalDNS := nameserver.SettingsInternalDNS{
|
||||
AddrPort: netip.AddrPortFrom(targetIP, defaultDNSPort),
|
||||
AddrPort: addrPort,
|
||||
Timeout: dialTimeout,
|
||||
}
|
||||
nameserver.UseDNSInternally(settingsInternalDNS)
|
||||
@@ -34,4 +36,9 @@ func (l *Loop) useUnencryptedDNS(fallback bool) {
|
||||
if err != nil {
|
||||
l.logger.Error(err.Error())
|
||||
}
|
||||
|
||||
err = l.firewall.RestrictOutputAddrPort(ctx, addrPort)
|
||||
if err != nil {
|
||||
l.logger.Error("restricting plain DNS traffic to " + targetIP.String() + ": " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -24,7 +24,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
"and go through your container network DNS outside the VPN tunnel!")
|
||||
} else {
|
||||
const fallback = false
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.useUnencryptedDNS(ctx, fallback)
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -56,7 +56,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
|
||||
if !errors.Is(err, errUpdateBlockLists) {
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.useUnencryptedDNS(ctx, fallback)
|
||||
}
|
||||
l.logAndWait(ctx, err)
|
||||
settings = l.GetSettings()
|
||||
@@ -66,7 +66,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
settings = l.GetSettings()
|
||||
if !*settings.KeepNameserver && !*settings.ServerEnabled {
|
||||
const fallback = false
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.useUnencryptedDNS(ctx, fallback)
|
||||
}
|
||||
|
||||
l.userTrigger = false
|
||||
@@ -94,7 +94,7 @@ func (l *Loop) runWait(ctx context.Context, runError <-chan error) (exitLoop boo
|
||||
settings := l.GetSettings()
|
||||
if !*settings.KeepNameserver && *settings.ServerEnabled {
|
||||
const fallback = false
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.useUnencryptedDNS(ctx, fallback)
|
||||
l.stopServer()
|
||||
}
|
||||
l.stopped <- struct{}{}
|
||||
@@ -105,7 +105,7 @@ func (l *Loop) runWait(ctx context.Context, runError <-chan error) (exitLoop boo
|
||||
case err := <-runError: // unexpected error
|
||||
l.statusManager.SetStatus(constants.Crashed)
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.useUnencryptedDNS(ctx, fallback)
|
||||
l.logAndWait(ctx, err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -39,8 +39,9 @@ func (l *Loop) setupServer(ctx context.Context) (runError <-chan error, err erro
|
||||
|
||||
// use internal DNS server
|
||||
const defaultDNSPort = 53
|
||||
addrPort := netip.AddrPortFrom(settings.ServerAddress, defaultDNSPort)
|
||||
nameserver.UseDNSInternally(nameserver.SettingsInternalDNS{
|
||||
AddrPort: netip.AddrPortFrom(settings.ServerAddress, defaultDNSPort),
|
||||
AddrPort: addrPort,
|
||||
})
|
||||
err = nameserver.UseDNSSystemWide(nameserver.SettingsSystemDNS{
|
||||
IPs: []netip.Addr{settings.ServerAddress},
|
||||
@@ -50,6 +51,11 @@ func (l *Loop) setupServer(ctx context.Context) (runError <-chan error, err erro
|
||||
l.logger.Error(err.Error())
|
||||
}
|
||||
|
||||
err = l.firewall.RestrictOutputAddrPort(ctx, addrPort)
|
||||
if err != nil {
|
||||
l.logger.Error("restricting plain DNS traffic to " + addrPort.Addr().String() + ": " + err.Error())
|
||||
}
|
||||
|
||||
err = check.WaitForDNS(ctx, check.Settings{})
|
||||
if err != nil {
|
||||
l.stopServer()
|
||||
|
||||
Reference in New Issue
Block a user