cmd/cli: strip EDNS0_SUBNET for RFC 1918 and loopback address

Since passing them to upstream is pointless, these cannot be used by
anything on the WAN.
This commit is contained in:
Cuong Manh Le
2023-11-08 18:15:48 +07:00
committed by Cuong Manh Le
parent efb5a92571
commit 990bc620f7
2 changed files with 60 additions and 0 deletions
+18
View File
@@ -71,6 +71,7 @@ func (p *prog) serveDNS(listenerNum string, reload bool, reloadCh chan struct{})
reqId := requestID()
remoteIP, _, _ := net.SplitHostPort(w.RemoteAddr().String())
ci := p.getClientInfo(remoteIP, m)
stripClientSubnet(m)
remoteAddr := spoofRemoteAddr(w.RemoteAddr(), ci)
fmtSrcToDest := fmtRemoteToLocal(listenerNum, remoteAddr.String(), w.LocalAddr().String())
t := time.Now()
@@ -498,6 +499,23 @@ func ipAndMacFromMsg(msg *dns.Msg) (string, string) {
return ip, mac
}
// stripClientSubnet removes EDNS0_SUBNET from DNS message if the IP is RFC1918 or loopback address,
// passing them to upstream is pointless, these cannot be used by anything on the WAN.
func stripClientSubnet(msg *dns.Msg) {
if opt := msg.IsEdns0(); opt != nil {
opts := make([]dns.EDNS0, 0, len(opt.Option))
for _, s := range opt.Option {
if e, ok := s.(*dns.EDNS0_SUBNET); ok && (e.Address.IsPrivate() || e.Address.IsLoopback()) {
continue
}
opts = append(opts, s)
}
if len(opts) != len(opt.Option) {
opt.Option = opts
}
}
}
func spoofRemoteAddr(addr net.Addr, ci *ctrld.ClientInfo) net.Addr {
if ci != nil && ci.IP != "" {
switch addr := addr.(type) {