mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 22:47:30 +00:00
wgengine/filter: use IPSet for localNets instead of prefixes.
Part of #1177, preparing for doing fancier set operations on the allowed local nets. Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:

committed by
Dave Anderson

parent
2c500cee23
commit
b83c273737
@@ -20,13 +20,11 @@ import (
|
||||
// Filter is a stateful packet filter.
|
||||
type Filter struct {
|
||||
logf logger.Logf
|
||||
// local4 and local6 are the lists of IP prefixes that we know
|
||||
// to be "local" to this node. All packets coming in over
|
||||
// tailscale must have a destination within local4 or local6,
|
||||
// regardless of the policy filter below. Zero values reject
|
||||
// all incoming traffic.
|
||||
local4 []netaddr.IPPrefix
|
||||
local6 []netaddr.IPPrefix
|
||||
// local is the set of IPs prefixes that we know to be "local" to
|
||||
// this node. All packets coming in over tailscale must have a
|
||||
// destination within local, regardless of the policy filter
|
||||
// below.
|
||||
local *netaddr.IPSet
|
||||
// matches4 and matches6 are lists of match->action rules
|
||||
// applied to all packets arriving over tailscale
|
||||
// tunnels. Matches are checked in order, and processing stops
|
||||
@@ -124,19 +122,22 @@ func NewAllowAllForTest(logf logger.Logf) *Filter {
|
||||
},
|
||||
}
|
||||
|
||||
return New(ms, []netaddr.IPPrefix{any4, any6}, nil, logf)
|
||||
var sb netaddr.IPSetBuilder
|
||||
sb.AddPrefix(any4)
|
||||
sb.AddPrefix(any6)
|
||||
return New(ms, sb.IPSet(), nil, logf)
|
||||
}
|
||||
|
||||
// NewAllowNone returns a packet filter that rejects everything.
|
||||
func NewAllowNone(logf logger.Logf) *Filter {
|
||||
return New(nil, nil, nil, logf)
|
||||
return New(nil, &netaddr.IPSet{}, nil, logf)
|
||||
}
|
||||
|
||||
// NewShieldsUpFilter returns a packet filter that rejects incoming connections.
|
||||
//
|
||||
// If shareStateWith is non-nil, the returned filter shares state with the previous one,
|
||||
// as long as the previous one was also a shields up filter.
|
||||
func NewShieldsUpFilter(localNets []netaddr.IPPrefix, shareStateWith *Filter, logf logger.Logf) *Filter {
|
||||
func NewShieldsUpFilter(localNets *netaddr.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
|
||||
// Don't permit sharing state with a prior filter that wasn't a shields-up filter.
|
||||
if shareStateWith != nil && !shareStateWith.shieldsUp {
|
||||
shareStateWith = nil
|
||||
@@ -151,7 +152,7 @@ func NewShieldsUpFilter(localNets []netaddr.IPPrefix, shareStateWith *Filter, lo
|
||||
// by matches. If shareStateWith is non-nil, the returned filter
|
||||
// shares state with the previous one, to enable changing rules at
|
||||
// runtime without breaking existing stateful flows.
|
||||
func New(matches []Match, localNets []netaddr.IPPrefix, shareStateWith *Filter, logf logger.Logf) *Filter {
|
||||
func New(matches []Match, localNets *netaddr.IPSet, shareStateWith *Filter, logf logger.Logf) *Filter {
|
||||
var state *filterState
|
||||
if shareStateWith != nil {
|
||||
state = shareStateWith.state
|
||||
@@ -164,23 +165,12 @@ func New(matches []Match, localNets []netaddr.IPPrefix, shareStateWith *Filter,
|
||||
logf: logf,
|
||||
matches4: matchesFamily(matches, netaddr.IP.Is4),
|
||||
matches6: matchesFamily(matches, netaddr.IP.Is6),
|
||||
local4: netsFamily(localNets, netaddr.IP.Is4),
|
||||
local6: netsFamily(localNets, netaddr.IP.Is6),
|
||||
local: localNets,
|
||||
state: state,
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func netsFamily(nets []netaddr.IPPrefix, keep func(netaddr.IP) bool) []netaddr.IPPrefix {
|
||||
var ret []netaddr.IPPrefix
|
||||
for _, net := range nets {
|
||||
if keep(net.IP) {
|
||||
ret = append(ret, net)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// matchesFamily returns the subset of ms for which keep(srcNet.IP)
|
||||
// and keep(dstNet.IP) are both true.
|
||||
func matchesFamily(ms matches, keep func(netaddr.IP) bool) matches {
|
||||
@@ -321,7 +311,7 @@ func (f *Filter) runIn4(q *packet.Parsed) (r Response, why string) {
|
||||
// A compromised peer could try to send us packets for
|
||||
// destinations we didn't explicitly advertise. This check is to
|
||||
// prevent that.
|
||||
if !ipInList(q.Dst.IP, f.local4) {
|
||||
if !f.local.Contains(q.Dst.IP) {
|
||||
return Drop, "destination not allowed"
|
||||
}
|
||||
|
||||
@@ -378,7 +368,7 @@ func (f *Filter) runIn6(q *packet.Parsed) (r Response, why string) {
|
||||
// A compromised peer could try to send us packets for
|
||||
// destinations we didn't explicitly advertise. This check is to
|
||||
// prevent that.
|
||||
if !ipInList(q.Dst.IP, f.local6) {
|
||||
if !f.local.Contains(q.Dst.IP) {
|
||||
return Drop, "destination not allowed"
|
||||
}
|
||||
|
||||
|
@@ -31,9 +31,12 @@ func newFilter(logf logger.Logf) *Filter {
|
||||
|
||||
// Expects traffic to 100.122.98.50, 1.2.3.4, 5.6.7.8,
|
||||
// 102.102.102.102, 119.119.119.119, 8.1.0.0/16
|
||||
localNets := nets("100.122.98.50", "1.2.3.4", "5.6.7.8", "102.102.102.102", "119.119.119.119", "8.1.0.0/16", "2001::/16")
|
||||
var localNets netaddr.IPSetBuilder
|
||||
for _, n := range nets("100.122.98.50", "1.2.3.4", "5.6.7.8", "102.102.102.102", "119.119.119.119", "8.1.0.0/16", "2001::/16") {
|
||||
localNets.AddPrefix(n)
|
||||
}
|
||||
|
||||
return New(matches, localNets, nil, logf)
|
||||
return New(matches, localNets.IPSet(), nil, logf)
|
||||
}
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
|
@@ -110,8 +110,9 @@ func setfilter(logf logger.Logf, tun *TUN) {
|
||||
{Srcs: nets("5.6.7.8"), Dsts: netports("1.2.3.4:89-90")},
|
||||
{Srcs: nets("1.2.3.4"), Dsts: netports("5.6.7.8:98")},
|
||||
}
|
||||
localNets := nets("1.2.0.0/16")
|
||||
tun.SetFilter(filter.New(matches, localNets, nil, logf))
|
||||
var sb netaddr.IPSetBuilder
|
||||
sb.AddPrefix(netaddr.MustParseIPPrefix("1.2.0.0/16"))
|
||||
tun.SetFilter(filter.New(matches, sb.IPSet(), nil, logf))
|
||||
}
|
||||
|
||||
func newChannelTUN(logf logger.Logf, secure bool) (*tuntest.ChannelTUN, *TUN) {
|
||||
|
Reference in New Issue
Block a user