ipn/ipnlocal: restrict exit node DoH server based on ACL'ed packet filter

Don't be a DoH DNS server to peers unless the Tailnet admin has permitted
that peer autogroup:internet access.

Updates #1713

Change-Id: Iec69360d8e4d24d5187c26904b6a75c1dabc8979
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2021-11-25 09:43:39 -08:00
committed by Brad Fitzpatrick
parent ff9727c9ff
commit c2efe46f72
3 changed files with 110 additions and 13 deletions

View File

@ -19,8 +19,13 @@ import (
"strings"
"testing"
"inet.af/netaddr"
"tailscale.com/ipn"
"tailscale.com/tailcfg"
"tailscale.com/tstest"
"tailscale.com/types/logger"
"tailscale.com/wgengine"
"tailscale.com/wgengine/filter"
)
type peerAPITestEnv struct {
@ -568,3 +573,55 @@ func TestDeletedMarkers(t *testing.T) {
}
}
func TestPeerAPIReplyToDNSQueries(t *testing.T) {
var h peerAPIHandler
h.isSelf = true
if !h.replyToDNSQueries() {
t.Errorf("for isSelf = false; want true")
}
h.isSelf = false
h.remoteAddr = netaddr.MustParseIPPort("100.150.151.152:12345")
eng, _ := wgengine.NewFakeUserspaceEngine(logger.Discard, 0)
h.ps = &peerAPIServer{
b: &LocalBackend{
e: eng,
},
}
if h.ps.b.OfferingExitNode() {
t.Fatal("unexpectedly offering exit node")
}
h.ps.b.prefs = &ipn.Prefs{
AdvertiseRoutes: []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("0.0.0.0/0"),
netaddr.MustParseIPPrefix("::/0"),
},
}
if !h.ps.b.OfferingExitNode() {
t.Fatal("unexpectedly not offering exit node")
}
if h.replyToDNSQueries() {
t.Errorf("unexpectedly doing DNS without filter")
}
h.ps.b.setFilter(filter.NewAllowNone(logger.Discard, new(netaddr.IPSet)))
if h.replyToDNSQueries() {
t.Errorf("unexpectedly doing DNS without filter")
}
f := filter.NewAllowAllForTest(logger.Discard)
h.ps.b.setFilter(f)
if !h.replyToDNSQueries() {
t.Errorf("unexpectedly deny; wanted to be a DNS server")
}
// Also test IPv6.
h.remoteAddr = netaddr.MustParseIPPort("[fe70::1]:12345")
if !h.replyToDNSQueries() {
t.Errorf("unexpectedly IPv6 deny; wanted to be a DNS server")
}
}