Skip to content

Commit

Permalink
Merge tag 'v1.9.4' into multiport
Browse files Browse the repository at this point in the history
1.9.4 Release
  • Loading branch information
wadey committed Sep 13, 2024
2 parents 6b78e9c + ab81b62 commit dabce8a
Show file tree
Hide file tree
Showing 83 changed files with 2,051 additions and 2,750 deletions.
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.9.4] - 2024-09-09

### Added

- Support UDP dialing with gVisor. (#1181)

### Changed

- Make some Nebula state programmatically available via control object. (#1188)
- Switch internal representation of IPs to netip, to prepare for IPv6 support
in the overlay. (#1173)
- Minor build and cleanup changes. (#1171, #1164, #1162)
- Various dependency updates. (#1195, #1190, #1174, #1168, #1167, #1161, #1147, #1146)

### Fixed

- Fix a bug on big endian hosts, like mips. (#1194)
- Fix a rare panic if a local index collision happens. (#1191)
- Fix integer wraparound in the calculation of handshake timeouts on 32-bit targets. (#1185)

## [1.9.3] - 2024-06-06

### Fixed
Expand Down Expand Up @@ -644,7 +664,8 @@ created.)

- Initial public release.

[Unreleased]: https://github.com/slackhq/nebula/compare/v1.9.3...HEAD
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.9.4...HEAD
[1.9.4]: https://github.com/slackhq/nebula/releases/tag/v1.9.4
[1.9.3]: https://github.com/slackhq/nebula/releases/tag/v1.9.3
[1.9.2]: https://github.com/slackhq/nebula/releases/tag/v1.9.2
[1.9.1]: https://github.com/slackhq/nebula/releases/tag/v1.9.1
Expand Down
91 changes: 26 additions & 65 deletions allow_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@ package nebula

import (
"fmt"
"net"
"net/netip"
"regexp"

"github.com/slackhq/nebula/cidr"
"github.com/gaissmai/bart"
"github.com/slackhq/nebula/config"
"github.com/slackhq/nebula/iputil"
)

type AllowList struct {
// The values of this cidrTree are `bool`, signifying allow/deny
cidrTree *cidr.Tree6[bool]
cidrTree *bart.Table[bool]
}

type RemoteAllowList struct {
AllowList *AllowList

// Inside Range Specific, keys of this tree are inside CIDRs and values
// are *AllowList
insideAllowLists *cidr.Tree6[*AllowList]
insideAllowLists *bart.Table[*AllowList]
}

type LocalAllowList struct {
Expand Down Expand Up @@ -88,7 +87,7 @@ func newAllowList(k string, raw interface{}, handleKey func(key string, value in
return nil, fmt.Errorf("config `%s` has invalid type: %T", k, raw)
}

tree := cidr.NewTree6[bool]()
tree := new(bart.Table[bool])

// Keep track of the rules we have added for both ipv4 and ipv6
type allowListRules struct {
Expand Down Expand Up @@ -122,18 +121,20 @@ func newAllowList(k string, raw interface{}, handleKey func(key string, value in
return nil, fmt.Errorf("config `%s` has invalid value (type %T): %v", k, rawValue, rawValue)
}

_, ipNet, err := net.ParseCIDR(rawCIDR)
ipNet, err := netip.ParsePrefix(rawCIDR)
if err != nil {
return nil, fmt.Errorf("config `%s` has invalid CIDR: %s", k, rawCIDR)
return nil, fmt.Errorf("config `%s` has invalid CIDR: %s. %w", k, rawCIDR, err)
}

ipNet = netip.PrefixFrom(ipNet.Addr().Unmap(), ipNet.Bits())

// TODO: should we error on duplicate CIDRs in the config?
tree.AddCIDR(ipNet, value)
tree.Insert(ipNet, value)

maskBits, maskSize := ipNet.Mask.Size()
maskBits := ipNet.Bits()

var rules *allowListRules
if maskSize == 32 {
if ipNet.Addr().Is4() {
rules = &rules4
} else {
rules = &rules6
Expand All @@ -156,17 +157,15 @@ func newAllowList(k string, raw interface{}, handleKey func(key string, value in

if !rules4.defaultSet {
if rules4.allValuesMatch {
_, zeroCIDR, _ := net.ParseCIDR("0.0.0.0/0")
tree.AddCIDR(zeroCIDR, !rules4.allValues)
tree.Insert(netip.PrefixFrom(netip.IPv4Unspecified(), 0), !rules4.allValues)
} else {
return nil, fmt.Errorf("config `%s` contains both true and false rules, but no default set for 0.0.0.0/0", k)
}
}

if !rules6.defaultSet {
if rules6.allValuesMatch {
_, zeroCIDR, _ := net.ParseCIDR("::/0")
tree.AddCIDR(zeroCIDR, !rules6.allValues)
tree.Insert(netip.PrefixFrom(netip.IPv6Unspecified(), 0), !rules6.allValues)
} else {
return nil, fmt.Errorf("config `%s` contains both true and false rules, but no default set for ::/0", k)
}
Expand Down Expand Up @@ -218,13 +217,13 @@ func getAllowListInterfaces(k string, v interface{}) ([]AllowListNameRule, error
return nameRules, nil
}

func getRemoteAllowRanges(c *config.C, k string) (*cidr.Tree6[*AllowList], error) {
func getRemoteAllowRanges(c *config.C, k string) (*bart.Table[*AllowList], error) {
value := c.Get(k)
if value == nil {
return nil, nil
}

remoteAllowRanges := cidr.NewTree6[*AllowList]()
remoteAllowRanges := new(bart.Table[*AllowList])

rawMap, ok := value.(map[interface{}]interface{})
if !ok {
Expand All @@ -241,45 +240,27 @@ func getRemoteAllowRanges(c *config.C, k string) (*cidr.Tree6[*AllowList], error
return nil, err
}

_, ipNet, err := net.ParseCIDR(rawCIDR)
ipNet, err := netip.ParsePrefix(rawCIDR)
if err != nil {
return nil, fmt.Errorf("config `%s` has invalid CIDR: %s", k, rawCIDR)
return nil, fmt.Errorf("config `%s` has invalid CIDR: %s. %w", k, rawCIDR, err)
}

remoteAllowRanges.AddCIDR(ipNet, allowList)
remoteAllowRanges.Insert(netip.PrefixFrom(ipNet.Addr().Unmap(), ipNet.Bits()), allowList)
}

return remoteAllowRanges, nil
}

func (al *AllowList) Allow(ip net.IP) bool {
if al == nil {
return true
}

_, result := al.cidrTree.MostSpecificContains(ip)
return result
}

func (al *AllowList) AllowIpV4(ip iputil.VpnIp) bool {
if al == nil {
return true
}

_, result := al.cidrTree.MostSpecificContainsIpV4(ip)
return result
}

func (al *AllowList) AllowIpV6(hi, lo uint64) bool {
func (al *AllowList) Allow(ip netip.Addr) bool {
if al == nil {
return true
}

_, result := al.cidrTree.MostSpecificContainsIpV6(hi, lo)
result, _ := al.cidrTree.Lookup(ip)
return result
}

func (al *LocalAllowList) Allow(ip net.IP) bool {
func (al *LocalAllowList) Allow(ip netip.Addr) bool {
if al == nil {
return true
}
Expand All @@ -301,43 +282,23 @@ func (al *LocalAllowList) AllowName(name string) bool {
return !al.nameRules[0].Allow
}

func (al *RemoteAllowList) AllowUnknownVpnIp(ip net.IP) bool {
func (al *RemoteAllowList) AllowUnknownVpnIp(ip netip.Addr) bool {
if al == nil {
return true
}
return al.AllowList.Allow(ip)
}

func (al *RemoteAllowList) Allow(vpnIp iputil.VpnIp, ip net.IP) bool {
func (al *RemoteAllowList) Allow(vpnIp netip.Addr, ip netip.Addr) bool {
if !al.getInsideAllowList(vpnIp).Allow(ip) {
return false
}
return al.AllowList.Allow(ip)
}

func (al *RemoteAllowList) AllowIpV4(vpnIp iputil.VpnIp, ip iputil.VpnIp) bool {
if al == nil {
return true
}
if !al.getInsideAllowList(vpnIp).AllowIpV4(ip) {
return false
}
return al.AllowList.AllowIpV4(ip)
}

func (al *RemoteAllowList) AllowIpV6(vpnIp iputil.VpnIp, hi, lo uint64) bool {
if al == nil {
return true
}
if !al.getInsideAllowList(vpnIp).AllowIpV6(hi, lo) {
return false
}
return al.AllowList.AllowIpV6(hi, lo)
}

func (al *RemoteAllowList) getInsideAllowList(vpnIp iputil.VpnIp) *AllowList {
func (al *RemoteAllowList) getInsideAllowList(vpnIp netip.Addr) *AllowList {
if al.insideAllowLists != nil {
ok, inside := al.insideAllowLists.MostSpecificContainsIpV4(vpnIp)
inside, ok := al.insideAllowLists.Lookup(vpnIp)
if ok {
return inside
}
Expand Down
42 changes: 21 additions & 21 deletions allow_list_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package nebula

import (
"net"
"net/netip"
"regexp"
"testing"

"github.com/slackhq/nebula/cidr"
"github.com/gaissmai/bart"
"github.com/slackhq/nebula/config"
"github.com/slackhq/nebula/test"
"github.com/stretchr/testify/assert"
Expand All @@ -18,7 +18,7 @@ func TestNewAllowListFromConfig(t *testing.T) {
"192.168.0.0": true,
}
r, err := newAllowListFromConfig(c, "allowlist", nil)
assert.EqualError(t, err, "config `allowlist` has invalid CIDR: 192.168.0.0")
assert.EqualError(t, err, "config `allowlist` has invalid CIDR: 192.168.0.0. netip.ParsePrefix(\"192.168.0.0\"): no '/'")
assert.Nil(t, r)

c.Settings["allowlist"] = map[interface{}]interface{}{
Expand Down Expand Up @@ -98,26 +98,26 @@ func TestNewAllowListFromConfig(t *testing.T) {
}

func TestAllowList_Allow(t *testing.T) {
assert.Equal(t, true, ((*AllowList)(nil)).Allow(net.ParseIP("1.1.1.1")))

tree := cidr.NewTree6[bool]()
tree.AddCIDR(cidr.Parse("0.0.0.0/0"), true)
tree.AddCIDR(cidr.Parse("10.0.0.0/8"), false)
tree.AddCIDR(cidr.Parse("10.42.42.42/32"), true)
tree.AddCIDR(cidr.Parse("10.42.0.0/16"), true)
tree.AddCIDR(cidr.Parse("10.42.42.0/24"), true)
tree.AddCIDR(cidr.Parse("10.42.42.0/24"), false)
tree.AddCIDR(cidr.Parse("::1/128"), true)
tree.AddCIDR(cidr.Parse("::2/128"), false)
assert.Equal(t, true, ((*AllowList)(nil)).Allow(netip.MustParseAddr("1.1.1.1")))

tree := new(bart.Table[bool])
tree.Insert(netip.MustParsePrefix("0.0.0.0/0"), true)
tree.Insert(netip.MustParsePrefix("10.0.0.0/8"), false)
tree.Insert(netip.MustParsePrefix("10.42.42.42/32"), true)
tree.Insert(netip.MustParsePrefix("10.42.0.0/16"), true)
tree.Insert(netip.MustParsePrefix("10.42.42.0/24"), true)
tree.Insert(netip.MustParsePrefix("10.42.42.0/24"), false)
tree.Insert(netip.MustParsePrefix("::1/128"), true)
tree.Insert(netip.MustParsePrefix("::2/128"), false)
al := &AllowList{cidrTree: tree}

assert.Equal(t, true, al.Allow(net.ParseIP("1.1.1.1")))
assert.Equal(t, false, al.Allow(net.ParseIP("10.0.0.4")))
assert.Equal(t, true, al.Allow(net.ParseIP("10.42.42.42")))
assert.Equal(t, false, al.Allow(net.ParseIP("10.42.42.41")))
assert.Equal(t, true, al.Allow(net.ParseIP("10.42.0.1")))
assert.Equal(t, true, al.Allow(net.ParseIP("::1")))
assert.Equal(t, false, al.Allow(net.ParseIP("::2")))
assert.Equal(t, true, al.Allow(netip.MustParseAddr("1.1.1.1")))
assert.Equal(t, false, al.Allow(netip.MustParseAddr("10.0.0.4")))
assert.Equal(t, true, al.Allow(netip.MustParseAddr("10.42.42.42")))
assert.Equal(t, false, al.Allow(netip.MustParseAddr("10.42.42.41")))
assert.Equal(t, true, al.Allow(netip.MustParseAddr("10.42.0.1")))
assert.Equal(t, true, al.Allow(netip.MustParseAddr("::1")))
assert.Equal(t, false, al.Allow(netip.MustParseAddr("::2")))
}

func TestLocalAllowList_AllowName(t *testing.T) {
Expand Down
Loading

0 comments on commit dabce8a

Please sign in to comment.