-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Closed
Description
I was looking at an odd bug report and it looks like the PacketConn server always rebinds to any address after first query. Here's a simple program:
package main
import (
"net"
"github.com/miekg/dns"
)
func main() {
pc, err := net.ListenPacket("udp", "127.0.0.1:1053")
if err != nil {
panic(err)
}
server := &dns.Server{PacketConn: pc}
server.ActivateAndServe()
}
When I run it it binds to 127.0.0.1:1053 correctly:
$ go run bug.go &
$ lsof -p 10509 -n | grep UDP
bug 10509 vavrusa 3u IPv4 0x52525d6e93c51cd9 0t0 UDP 127.0.0.1:remote-as
Cool. When I query it it answers, but the binding changes to *:1053:
$ kdig @127.0.0.1 -p 1053 +short
$ lsof -p 10509 -n | grep UDP
bug 10509 vavrusa 3u IPv4 0x52525d6e93c51cd9 0t0 UDP *:remote-as
It also answers on any interface now:
$ kdig @192.168.86.110 -p 1053
;; ->>HEADER<<- opcode: QUERY; status: SERVFAIL; id: 16510
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 0
;; QUESTION SECTION:
;; . IN NS
;; Received 17 B
;; Time 2019-03-17 20:03:06 PDT
;; From 192.168.86.110@1053(UDP) in 2.8 ms
I traced the problem to https://github.com/miekg/dns/blob/master/server.go#L326 which seems to have been added in #594. The problematic part is https://github.com/miekg/dns/blob/master/udp.go#L60:
// Try setting the flags for both families and ignore the errors unless they
// both error.
err6 := ipv6.NewPacketConn(conn).SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true)
err4 := ipv4.NewPacketConn(conn).SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
It does what it says (converts it into a raw socket). I'm not sure why was it added in the first place, but it is probably not what you want, as it opens up a DNS server using this library to any interface without user's control. Like CoreDNS:
$ cat Corefile
.:1053 {
bind 127.0.0.1
forward . 8.8.8.8:53
log
}
$ coredns &
$ lsof -p $(ps ax | grep coredns | grep -v grep | awk '{print $1}') | grep UDP
coredns 16303 vavrusa 6u IPv4 0x52525d6e9d492501 0t0 UDP localhost:remote-as
$ kdig @127.0.0.1 -p 1053 google.com +short
216.58.194.206
$ lsof -p $(ps ax | grep coredns | grep -v grep | awk '{print $1}') | grep UDP
coredns 16303 vavrusa 6u IPv4 0x52525d6e9d492501 0t0 UDP *:remote-as