mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 22:47:30 +00:00
tailcfg: add Node.UnsignedPeerAPIOnly to let server mark node as peerapi-only
capver 48 Change-Id: I20b2fa81d61ef8cc8a84e5f2afeefb68832bd904 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
3367136d9e
commit
e55ae53169
@@ -1303,6 +1303,14 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P
|
||||
localNetsB.AddPrefix(p)
|
||||
}
|
||||
packetFilter = netMap.PacketFilter
|
||||
|
||||
if packetFilterPermitsUnlockedNodes(netMap.Peers, packetFilter) {
|
||||
err := errors.New("server sent invalid packet filter permitting traffic to unlocked nodes; rejecting all packets for safety")
|
||||
health.SetValidUnsignedNodes(err)
|
||||
packetFilter = nil
|
||||
} else {
|
||||
health.SetValidUnsignedNodes(nil)
|
||||
}
|
||||
}
|
||||
if prefs.Valid() {
|
||||
ar := prefs.AdvertiseRoutes()
|
||||
@@ -1375,6 +1383,45 @@ func (b *LocalBackend) updateFilterLocked(netMap *netmap.NetworkMap, prefs ipn.P
|
||||
}
|
||||
}
|
||||
|
||||
// packetFilterPermitsUnlockedNodes reports any peer in peers with the
|
||||
// UnsignedPeerAPIOnly bool set true has any of its allowed IPs in the packet
|
||||
// filter.
|
||||
//
|
||||
// If this reports true, the packet filter is invalid (the server is either broken
|
||||
// or malicious) and should be ignored for safety.
|
||||
func packetFilterPermitsUnlockedNodes(peers []*tailcfg.Node, packetFilter []filter.Match) bool {
|
||||
var b netipx.IPSetBuilder
|
||||
var numUnlocked int
|
||||
for _, p := range peers {
|
||||
if !p.UnsignedPeerAPIOnly {
|
||||
continue
|
||||
}
|
||||
numUnlocked++
|
||||
for _, a := range p.AllowedIPs { // not only addresses!
|
||||
b.AddPrefix(a)
|
||||
}
|
||||
}
|
||||
if numUnlocked == 0 {
|
||||
return false
|
||||
}
|
||||
s, err := b.IPSet()
|
||||
if err != nil {
|
||||
// Shouldn't happen, but if it does, fail closed.
|
||||
return true
|
||||
}
|
||||
for _, m := range packetFilter {
|
||||
for _, r := range m.Srcs {
|
||||
if !s.OverlapsPrefix(r) {
|
||||
continue
|
||||
}
|
||||
if len(m.Dsts) != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *LocalBackend) setFilter(f *filter.Filter) {
|
||||
b.filterAtomic.Store(f)
|
||||
b.e.SetFilter(f)
|
||||
|
Reference in New Issue
Block a user