Handle upstream dns ipv6 properly

This commit is contained in:
Owen
2026-09-30 09:05:57 -04:00
parent b119feaf7f
commit 815f3e506c
3 changed files with 26 additions and 2 deletions
+9 -1
View File
@@ -713,6 +713,14 @@ func (p *DNSProxy) dialTunnel(network, addr string) (net.Conn, uint16, error) {
return nil, 0, err
}
// The tunnel netstack only has an IPv4 address and route (the WireGuard
// interface IP), so an IPv6 upstream server can't be reached through it.
// To4() is nil for those, and converting that to a [4]byte below would panic.
raddrIP := raddr.IP.To4()
if raddrIP == nil {
return nil, 0, fmt.Errorf("upstream DNS server %s is not an IPv4 address, only IPv4 is supported over the tunnel", addr)
}
// Use tunnel IP as source
ipBytes := p.tunnelIP.As4()
@@ -725,7 +733,7 @@ func (p *DNSProxy) dialTunnel(network, addr string) (net.Conn, uint16, error) {
raddrTcpip := &tcpip.FullAddress{
NIC: 1,
Addr: tcpip.AddrFrom4([4]byte(raddr.IP.To4())),
Addr: tcpip.AddrFrom4([4]byte(raddrIP)),
Port: uint16(raddr.Port),
}
+16
View File
@@ -2,9 +2,11 @@ package dns
import (
"net"
"net/netip"
"testing"
"github.com/miekg/dns"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
func TestCheckLocalRecordsNODATAForAAAA(t *testing.T) {
@@ -176,3 +178,17 @@ func TestCheckLocalRecordsNODATAWildcard(t *testing.T) {
t.Fatalf("Expected 1 answer, got %d", len(response.Answer))
}
}
func TestDialTunnelRejectsIPv6Upstream(t *testing.T) {
proxy := &DNSProxy{
tunnelStack: stack.New(stack.Options{}),
tunnelIP: netip.MustParseAddr("100.90.128.1"),
tunnelActivePorts: make(map[uint16]bool),
}
defer proxy.tunnelStack.Close()
// Must return an error rather than panic: the tunnel netstack is IPv4-only
if _, _, err := proxy.dialTunnel("udp", "[2606:4700:4700::1111]:53"); err == nil {
t.Fatal("Expected error dialing an IPv6 upstream through the tunnel, got nil")
}
}
+1 -1
View File
@@ -554,7 +554,7 @@ func (o *Olm) StartTunnel(config TunnelConfig) {
// Fall back to hardcoded DNS if the system monitor could not detect any.
if len(o.tunnelConfig.PublicDNS) == 0 {
if o.tunnelConfig.DNS != "" {
o.tunnelConfig.PublicDNS = []string{o.tunnelConfig.DNS + ":53"}
o.tunnelConfig.PublicDNS = []string{net.JoinHostPort(o.tunnelConfig.DNS, "53")}
} else {
o.tunnelConfig.PublicDNS = []string{"8.8.8.8:53"}
}