fix(handler/socks5): resolve UDP domains via configured resolver to stop DNS leak
SOCKS5 UDP datagrams carrying ATYP=DOMAINNAME were force-resolved via net.ResolveUDPAddr in udpConn.ReadFrom, which always used the system resolver and ignored any configured handler resolver (resolver=1.1.1.1), leaking the query locally. The premature domain→IP conversion also stripped the hostname before it reached the relay chain, so the exit node could not resolve DNS itself. udpConn.ReadFrom now returns a domainAddr for domain targets, letting the name flow untouched through udp.Relay into the upstream WriteTo. Chain-backed PacketConns (udpTunConn, udpRelayConn) encode it as ATYP=Domain and forward to the exit. Direct (no-chain) associations yield a raw *net.UDPConn that cannot consume a domainAddr, so they are wrapped with resolvePacketConn, which resolves via hostMapper → configured resolver → system DNS.
This commit is contained in:
@@ -3,6 +3,7 @@ package socks
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-gost/core/common/bufpool"
|
||||
"github.com/go-gost/gosocks5"
|
||||
@@ -106,6 +107,20 @@ func UDPConn(c net.PacketConn, bufferSize int) net.PacketConn {
|
||||
}
|
||||
}
|
||||
|
||||
// domainAddr is a net.Addr that preserves a domain name without resolving it.
|
||||
// Returned by udpConn.ReadFrom when a SOCKS5 UDP datagram carries
|
||||
// ATYP=DOMAINNAME, so that downstream consumers (e.g. relay-chain WriteTo) can
|
||||
// forward the domain verbatim instead of forcing a local DNS lookup that would
|
||||
// leak the query through the system resolver and bypass any configured resolver.
|
||||
type domainAddr struct {
|
||||
network string
|
||||
host string
|
||||
port int
|
||||
}
|
||||
|
||||
func (a *domainAddr) Network() string { return a.network }
|
||||
func (a *domainAddr) String() string { return net.JoinHostPort(a.host, strconv.Itoa(a.port)) }
|
||||
|
||||
// ReadFrom reads an UDP datagram.
|
||||
// NOTE: for server side,
|
||||
// the returned addr is the target address the client want to relay to.
|
||||
@@ -128,7 +143,11 @@ func (c *udpConn) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
||||
}
|
||||
n = copy(b, buf[hlen:n])
|
||||
|
||||
addr, err = net.ResolveUDPAddr("udp", socksAddr.String())
|
||||
if net.ParseIP(socksAddr.Host) != nil {
|
||||
addr, err = net.ResolveUDPAddr("udp", socksAddr.String())
|
||||
} else {
|
||||
addr = &domainAddr{network: "udp", host: socksAddr.Host, port: int(socksAddr.Port)}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user