mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 08:24:25 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea36949d8a | ||
|
|
0564d0a2cf | ||
|
|
b22ba6eb49 | ||
|
|
3a221812f6 | ||
|
|
927ff4cc03 | ||
|
|
e5945a60aa | ||
|
|
072edd56b3 | ||
|
|
beb5f6bddc | ||
|
|
8be9792059 | ||
|
|
af2fc48378 |
2
.github/workflows/gofmt.yml
vendored
2
.github/workflows/gofmt.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|||||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|||||||
2
.github/workflows/smoke.yml
vendored
2
.github/workflows/smoke.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|||||||
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
@@ -37,6 +37,9 @@ jobs:
|
|||||||
- name: End 2 end
|
- name: End 2 end
|
||||||
run: make e2evv
|
run: make e2evv
|
||||||
|
|
||||||
|
- name: Build test mobile
|
||||||
|
run: make build-test-mobile
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: e2e packet flow
|
name: e2e packet flow
|
||||||
@@ -50,7 +53,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
@@ -74,7 +77,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
check-latest: true
|
check-latest: true
|
||||||
|
|||||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.8.2] - 2024-01-08
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix multiple routines when listen.port is zero. This was a regression
|
||||||
|
introduced in v1.6.0. (#1057)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Small dependency update for Noise. (#1038)
|
||||||
|
|
||||||
|
## [1.8.1] - 2023-12-19
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Update `golang.org/x/crypto`, which includes a fix for CVE-2023-48795. (#1048)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix a deadlock introduced in v1.8.0 that could occur during handshakes. (#1044)
|
||||||
|
|
||||||
|
- Fix mobile builds. (#1035)
|
||||||
|
|
||||||
## [1.8.0] - 2023-12-06
|
## [1.8.0] - 2023-12-06
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
@@ -535,7 +558,9 @@ created.)
|
|||||||
|
|
||||||
- Initial public release.
|
- Initial public release.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.8.0...HEAD
|
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.8.2...HEAD
|
||||||
|
[1.8.2]: https://github.com/slackhq/nebula/releases/tag/v1.8.2
|
||||||
|
[1.8.1]: https://github.com/slackhq/nebula/releases/tag/v1.8.1
|
||||||
[1.8.0]: https://github.com/slackhq/nebula/releases/tag/v1.8.0
|
[1.8.0]: https://github.com/slackhq/nebula/releases/tag/v1.8.0
|
||||||
[1.7.2]: https://github.com/slackhq/nebula/releases/tag/v1.7.2
|
[1.7.2]: https://github.com/slackhq/nebula/releases/tag/v1.7.2
|
||||||
[1.7.1]: https://github.com/slackhq/nebula/releases/tag/v1.7.1
|
[1.7.1]: https://github.com/slackhq/nebula/releases/tag/v1.7.1
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -169,6 +169,12 @@ test-cov-html:
|
|||||||
go test -coverprofile=coverage.out
|
go test -coverprofile=coverage.out
|
||||||
go tool cover -html=coverage.out
|
go tool cover -html=coverage.out
|
||||||
|
|
||||||
|
build-test-mobile:
|
||||||
|
GOARCH=amd64 GOOS=ios go build $(shell go list ./... | grep -v '/cmd/\|/examples/')
|
||||||
|
GOARCH=arm64 GOOS=ios go build $(shell go list ./... | grep -v '/cmd/\|/examples/')
|
||||||
|
GOARCH=amd64 GOOS=android go build $(shell go list ./... | grep -v '/cmd/\|/examples/')
|
||||||
|
GOARCH=arm64 GOOS=android go build $(shell go list ./... | grep -v '/cmd/\|/examples/')
|
||||||
|
|
||||||
bench:
|
bench:
|
||||||
go test -bench=.
|
go test -bench=.
|
||||||
|
|
||||||
@@ -214,5 +220,5 @@ smoke-docker-race: CGO_ENABLED = 1
|
|||||||
smoke-docker-race: smoke-docker
|
smoke-docker-race: smoke-docker
|
||||||
|
|
||||||
.FORCE:
|
.FORCE:
|
||||||
.PHONY: e2e e2ev e2evv e2evvv e2evvvv test test-cov-html bench bench-cpu bench-cpu-long bin proto release service smoke-docker smoke-docker-race
|
.PHONY: bench bench-cpu bench-cpu-long bin build-test-mobile e2e e2ev e2evv e2evvv e2evvvv proto release service smoke-docker smoke-docker-race test test-cov-html
|
||||||
.DEFAULT_GOAL := bin
|
.DEFAULT_GOAL := bin
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -27,15 +27,26 @@ Check the [releases](https://github.com/slackhq/nebula/releases/latest) page for
|
|||||||
|
|
||||||
#### Distribution Packages
|
#### Distribution Packages
|
||||||
|
|
||||||
- [Arch Linux](https://archlinux.org/packages/community/x86_64/nebula/)
|
- [Arch Linux](https://archlinux.org/packages/extra/x86_64/nebula/)
|
||||||
```
|
```
|
||||||
$ sudo pacman -S nebula
|
$ sudo pacman -S nebula
|
||||||
```
|
```
|
||||||
|
|
||||||
- [Fedora Linux](https://src.fedoraproject.org/rpms/nebula)
|
- [Fedora Linux](https://src.fedoraproject.org/rpms/nebula)
|
||||||
```
|
```
|
||||||
$ sudo dnf install nebula
|
$ sudo dnf install nebula
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- [Debian Linux](https://packages.debian.org/source/stable/nebula)
|
||||||
|
```
|
||||||
|
$ sudo apt install nebula
|
||||||
|
```
|
||||||
|
|
||||||
|
- [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=nebula)
|
||||||
|
```
|
||||||
|
$ sudo apk add nebula
|
||||||
|
```
|
||||||
|
|
||||||
- [macOS Homebrew](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/nebula.rb)
|
- [macOS Homebrew](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/nebula.rb)
|
||||||
```
|
```
|
||||||
$ brew install nebula
|
$ brew install nebula
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const (
|
|||||||
swapPrimary trafficDecision = 3
|
swapPrimary trafficDecision = 3
|
||||||
migrateRelays trafficDecision = 4
|
migrateRelays trafficDecision = 4
|
||||||
tryRehandshake trafficDecision = 5
|
tryRehandshake trafficDecision = 5
|
||||||
|
sendTestPacket trafficDecision = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
type connectionManager struct {
|
type connectionManager struct {
|
||||||
@@ -176,7 +177,7 @@ func (n *connectionManager) Run(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *connectionManager) doTrafficCheck(localIndex uint32, p, nb, out []byte, now time.Time) {
|
func (n *connectionManager) doTrafficCheck(localIndex uint32, p, nb, out []byte, now time.Time) {
|
||||||
decision, hostinfo, primary := n.makeTrafficDecision(localIndex, p, nb, out, now)
|
decision, hostinfo, primary := n.makeTrafficDecision(localIndex, now)
|
||||||
|
|
||||||
switch decision {
|
switch decision {
|
||||||
case deleteTunnel:
|
case deleteTunnel:
|
||||||
@@ -197,6 +198,9 @@ func (n *connectionManager) doTrafficCheck(localIndex uint32, p, nb, out []byte,
|
|||||||
|
|
||||||
case tryRehandshake:
|
case tryRehandshake:
|
||||||
n.tryRehandshake(hostinfo)
|
n.tryRehandshake(hostinfo)
|
||||||
|
|
||||||
|
case sendTestPacket:
|
||||||
|
n.intf.SendMessageToHostInfo(header.Test, header.TestRequest, hostinfo, p, nb, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.resetRelayTrafficCheck(hostinfo)
|
n.resetRelayTrafficCheck(hostinfo)
|
||||||
@@ -289,7 +293,7 @@ func (n *connectionManager) migrateRelayUsed(oldhostinfo, newhostinfo *HostInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *connectionManager) makeTrafficDecision(localIndex uint32, p, nb, out []byte, now time.Time) (trafficDecision, *HostInfo, *HostInfo) {
|
func (n *connectionManager) makeTrafficDecision(localIndex uint32, now time.Time) (trafficDecision, *HostInfo, *HostInfo) {
|
||||||
n.hostMap.RLock()
|
n.hostMap.RLock()
|
||||||
defer n.hostMap.RUnlock()
|
defer n.hostMap.RUnlock()
|
||||||
|
|
||||||
@@ -356,6 +360,7 @@ func (n *connectionManager) makeTrafficDecision(localIndex uint32, p, nb, out []
|
|||||||
return deleteTunnel, hostinfo, nil
|
return deleteTunnel, hostinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decision := doNothing
|
||||||
if hostinfo != nil && hostinfo.ConnectionState != nil && mainHostInfo {
|
if hostinfo != nil && hostinfo.ConnectionState != nil && mainHostInfo {
|
||||||
if !outTraffic {
|
if !outTraffic {
|
||||||
// If we aren't sending or receiving traffic then its an unused tunnel and we don't to test the tunnel.
|
// If we aren't sending or receiving traffic then its an unused tunnel and we don't to test the tunnel.
|
||||||
@@ -380,7 +385,7 @@ func (n *connectionManager) makeTrafficDecision(localIndex uint32, p, nb, out []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
|
// Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
|
||||||
n.intf.SendMessageToHostInfo(header.Test, header.TestRequest, hostinfo, p, nb, out)
|
decision = sendTestPacket
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if n.l.Level >= logrus.DebugLevel {
|
if n.l.Level >= logrus.DebugLevel {
|
||||||
@@ -390,7 +395,7 @@ func (n *connectionManager) makeTrafficDecision(localIndex uint32, p, nb, out []
|
|||||||
|
|
||||||
n.pendingDeletion[hostinfo.localIndexId] = struct{}{}
|
n.pendingDeletion[hostinfo.localIndexId] = struct{}{}
|
||||||
n.trafficTimer.Add(hostinfo.localIndexId, n.pendingDeletionInterval)
|
n.trafficTimer.Add(hostinfo.localIndexId, n.pendingDeletionInterval)
|
||||||
return doNothing, nil, nil
|
return decision, hostinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *connectionManager) shouldSwapPrimary(current, primary *HostInfo) bool {
|
func (n *connectionManager) shouldSwapPrimary(current, primary *HostInfo) bool {
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ var vpnIp iputil.VpnIp
|
|||||||
|
|
||||||
func newTestLighthouse() *LightHouse {
|
func newTestLighthouse() *LightHouse {
|
||||||
lh := &LightHouse{
|
lh := &LightHouse{
|
||||||
l: test.NewLogger(),
|
l: test.NewLogger(),
|
||||||
addrMap: map[iputil.VpnIp]*RemoteList{},
|
addrMap: map[iputil.VpnIp]*RemoteList{},
|
||||||
|
queryChan: make(chan iputil.VpnIp, 10),
|
||||||
}
|
}
|
||||||
lighthouses := map[iputil.VpnIp]struct{}{}
|
lighthouses := map[iputil.VpnIp]struct{}{}
|
||||||
staticList := map[iputil.VpnIp]struct{}{}
|
staticList := map[iputil.VpnIp]struct{}{}
|
||||||
|
|||||||
@@ -289,6 +289,10 @@ logging:
|
|||||||
# A 100ms interval with the default 10 retries will give a handshake 5.5 seconds to resolve before timing out
|
# A 100ms interval with the default 10 retries will give a handshake 5.5 seconds to resolve before timing out
|
||||||
#try_interval: 100ms
|
#try_interval: 100ms
|
||||||
#retries: 20
|
#retries: 20
|
||||||
|
|
||||||
|
# query_buffer is the size of the buffer channel for querying lighthouses
|
||||||
|
#query_buffer: 64
|
||||||
|
|
||||||
# trigger_buffer is the size of the buffer channel for quickly sending handshakes
|
# trigger_buffer is the size of the buffer channel for quickly sending handshakes
|
||||||
# after receiving the response for lighthouse queries
|
# after receiving the response for lighthouse queries
|
||||||
#trigger_buffer: 64
|
#trigger_buffer: 64
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -7,7 +7,7 @@ require (
|
|||||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||||
github.com/armon/go-radix v1.0.0
|
github.com/armon/go-radix v1.0.0
|
||||||
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432
|
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432
|
||||||
github.com/flynn/noise v1.0.0
|
github.com/flynn/noise v1.0.1
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
github.com/google/gopacket v1.1.19
|
github.com/google/gopacket v1.1.19
|
||||||
github.com/kardianos/service v1.2.2
|
github.com/kardianos/service v1.2.2
|
||||||
@@ -20,7 +20,7 @@ require (
|
|||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54
|
github.com/vishvananda/netlink v1.1.1-0.20211118161826-650dca95af54
|
||||||
golang.org/x/crypto v0.16.0
|
golang.org/x/crypto v0.17.0
|
||||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
|
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
|
||||||
golang.org/x/net v0.19.0
|
golang.org/x/net v0.19.0
|
||||||
golang.org/x/sync v0.5.0
|
golang.org/x/sync v0.5.0
|
||||||
|
|||||||
8
go.sum
8
go.sum
@@ -22,8 +22,8 @@ github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432/go.
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
|
github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y=
|
||||||
github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
github.com/flynn/noise v1.0.1/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||||
@@ -149,8 +149,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
|
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
|
||||||
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ func (hm *HandshakeManager) handleOutbound(vpnIp iputil.VpnIp, lighthouseTrigger
|
|||||||
// If we only have 1 remote it is highly likely our query raced with the other host registered within the lighthouse
|
// If we only have 1 remote it is highly likely our query raced with the other host registered within the lighthouse
|
||||||
// Our vpnIp here has a tunnel with a lighthouse but has yet to send a host update packet there so we only know about
|
// Our vpnIp here has a tunnel with a lighthouse but has yet to send a host update packet there so we only know about
|
||||||
// the learned public ip for them. Query again to short circuit the promotion counter
|
// the learned public ip for them. Query again to short circuit the promotion counter
|
||||||
hm.lightHouse.QueryServer(vpnIp, hm.f)
|
hm.lightHouse.QueryServer(vpnIp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the handshake to all known ips, stage 2 takes care of assigning the hostinfo.remote based on the first to reply
|
// Send the handshake to all known ips, stage 2 takes care of assigning the hostinfo.remote based on the first to reply
|
||||||
@@ -374,13 +374,13 @@ func (hm *HandshakeManager) GetOrHandshake(vpnIp iputil.VpnIp, cacheCb func(*Han
|
|||||||
// StartHandshake will ensure a handshake is currently being attempted for the provided vpn ip
|
// StartHandshake will ensure a handshake is currently being attempted for the provided vpn ip
|
||||||
func (hm *HandshakeManager) StartHandshake(vpnIp iputil.VpnIp, cacheCb func(*HandshakeHostInfo)) *HostInfo {
|
func (hm *HandshakeManager) StartHandshake(vpnIp iputil.VpnIp, cacheCb func(*HandshakeHostInfo)) *HostInfo {
|
||||||
hm.Lock()
|
hm.Lock()
|
||||||
|
defer hm.Unlock()
|
||||||
|
|
||||||
if hh, ok := hm.vpnIps[vpnIp]; ok {
|
if hh, ok := hm.vpnIps[vpnIp]; ok {
|
||||||
// We are already trying to handshake with this vpn ip
|
// We are already trying to handshake with this vpn ip
|
||||||
if cacheCb != nil {
|
if cacheCb != nil {
|
||||||
cacheCb(hh)
|
cacheCb(hh)
|
||||||
}
|
}
|
||||||
hm.Unlock()
|
|
||||||
return hh.hostinfo
|
return hh.hostinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,8 +421,7 @@ func (hm *HandshakeManager) StartHandshake(vpnIp iputil.VpnIp, cacheCb func(*Han
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hm.Unlock()
|
hm.lightHouse.QueryServer(vpnIp)
|
||||||
hm.lightHouse.QueryServer(vpnIp, hm.f)
|
|
||||||
return hostinfo
|
return hostinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ func (i *HostInfo) TryPromoteBest(preferredRanges []*net.IPNet, ifce *Interface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
i.nextLHQuery.Store(now + ifce.reQueryWait.Load())
|
i.nextLHQuery.Store(now + ifce.reQueryWait.Load())
|
||||||
ifce.lightHouse.QueryServer(i.vpnIp, ifce)
|
ifce.lightHouse.QueryServer(i.vpnIp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ func (f *Interface) sendNoMetrics(t header.MessageType, st header.MessageSubType
|
|||||||
if t != header.CloseTunnel && hostinfo.lastRebindCount != f.rebindCount {
|
if t != header.CloseTunnel && hostinfo.lastRebindCount != f.rebindCount {
|
||||||
//NOTE: there is an update hole if a tunnel isn't used and exactly 256 rebinds occur before the tunnel is
|
//NOTE: there is an update hole if a tunnel isn't used and exactly 256 rebinds occur before the tunnel is
|
||||||
// finally used again. This tunnel would eventually be torn down and recreated if this action didn't help.
|
// finally used again. This tunnel would eventually be torn down and recreated if this action didn't help.
|
||||||
f.lightHouse.QueryServer(hostinfo.vpnIp, f)
|
f.lightHouse.QueryServer(hostinfo.vpnIp)
|
||||||
hostinfo.lastRebindCount = f.rebindCount
|
hostinfo.lastRebindCount = f.rebindCount
|
||||||
if f.l.Level >= logrus.DebugLevel {
|
if f.l.Level >= logrus.DebugLevel {
|
||||||
f.l.WithField("vpnIp", hostinfo.vpnIp).Debug("Lighthouse update triggered for punch due to rebind counter")
|
f.l.WithField("vpnIp", hostinfo.vpnIp).Debug("Lighthouse update triggered for punch due to rebind counter")
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ type LightHouse struct {
|
|||||||
// IP's of relays that can be used by peers to access me
|
// IP's of relays that can be used by peers to access me
|
||||||
relaysForMe atomic.Pointer[[]iputil.VpnIp]
|
relaysForMe atomic.Pointer[[]iputil.VpnIp]
|
||||||
|
|
||||||
|
queryChan chan iputil.VpnIp
|
||||||
|
|
||||||
calculatedRemotes atomic.Pointer[cidr.Tree4[[]*calculatedRemote]] // Maps VpnIp to []*calculatedRemote
|
calculatedRemotes atomic.Pointer[cidr.Tree4[[]*calculatedRemote]] // Maps VpnIp to []*calculatedRemote
|
||||||
|
|
||||||
metrics *MessageMetrics
|
metrics *MessageMetrics
|
||||||
@@ -110,6 +112,7 @@ func NewLightHouseFromConfig(ctx context.Context, l *logrus.Logger, c *config.C,
|
|||||||
nebulaPort: nebulaPort,
|
nebulaPort: nebulaPort,
|
||||||
punchConn: pc,
|
punchConn: pc,
|
||||||
punchy: p,
|
punchy: p,
|
||||||
|
queryChan: make(chan iputil.VpnIp, c.GetUint32("handshakes.query_buffer", 64)),
|
||||||
l: l,
|
l: l,
|
||||||
}
|
}
|
||||||
lighthouses := make(map[iputil.VpnIp]struct{})
|
lighthouses := make(map[iputil.VpnIp]struct{})
|
||||||
@@ -139,6 +142,8 @@ func NewLightHouseFromConfig(ctx context.Context, l *logrus.Logger, c *config.C,
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
h.startQueryWorker()
|
||||||
|
|
||||||
return &h, nil
|
return &h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,9 +448,9 @@ func (lh *LightHouse) loadStaticMap(c *config.C, tunCidr *net.IPNet, staticList
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lh *LightHouse) Query(ip iputil.VpnIp, f EncWriter) *RemoteList {
|
func (lh *LightHouse) Query(ip iputil.VpnIp) *RemoteList {
|
||||||
if !lh.IsLighthouseIP(ip) {
|
if !lh.IsLighthouseIP(ip) {
|
||||||
lh.QueryServer(ip, f)
|
lh.QueryServer(ip)
|
||||||
}
|
}
|
||||||
lh.RLock()
|
lh.RLock()
|
||||||
if v, ok := lh.addrMap[ip]; ok {
|
if v, ok := lh.addrMap[ip]; ok {
|
||||||
@@ -456,30 +461,14 @@ func (lh *LightHouse) Query(ip iputil.VpnIp, f EncWriter) *RemoteList {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is asynchronous so no reply should be expected
|
// QueryServer is asynchronous so no reply should be expected
|
||||||
func (lh *LightHouse) QueryServer(ip iputil.VpnIp, f EncWriter) {
|
func (lh *LightHouse) QueryServer(ip iputil.VpnIp) {
|
||||||
if lh.amLighthouse {
|
// Don't put lighthouse ips in the query channel because we can't query lighthouses about lighthouses
|
||||||
|
if lh.amLighthouse || lh.IsLighthouseIP(ip) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if lh.IsLighthouseIP(ip) {
|
lh.queryChan <- ip
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a query to the lighthouses and hope for the best next time
|
|
||||||
query, err := NewLhQueryByInt(ip).Marshal()
|
|
||||||
if err != nil {
|
|
||||||
lh.l.WithError(err).WithField("vpnIp", ip).Error("Failed to marshal lighthouse query payload")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lighthouses := lh.GetLighthouses()
|
|
||||||
lh.metricTx(NebulaMeta_HostQuery, int64(len(lighthouses)))
|
|
||||||
nb := make([]byte, 12, 12)
|
|
||||||
out := make([]byte, mtu)
|
|
||||||
for n := range lighthouses {
|
|
||||||
f.SendMessageToVpnIp(header.LightHouse, 0, n, query, nb, out)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lh *LightHouse) QueryCache(ip iputil.VpnIp) *RemoteList {
|
func (lh *LightHouse) QueryCache(ip iputil.VpnIp) *RemoteList {
|
||||||
@@ -752,6 +741,46 @@ func NewUDPAddrFromLH6(ipp *Ip6AndPort) *udp.Addr {
|
|||||||
return udp.NewAddr(lhIp6ToIp(ipp), uint16(ipp.Port))
|
return udp.NewAddr(lhIp6ToIp(ipp), uint16(ipp.Port))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lh *LightHouse) startQueryWorker() {
|
||||||
|
if lh.amLighthouse {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
nb := make([]byte, 12, 12)
|
||||||
|
out := make([]byte, mtu)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-lh.ctx.Done():
|
||||||
|
return
|
||||||
|
case ip := <-lh.queryChan:
|
||||||
|
lh.innerQueryServer(ip, nb, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lh *LightHouse) innerQueryServer(ip iputil.VpnIp, nb, out []byte) {
|
||||||
|
if lh.IsLighthouseIP(ip) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a query to the lighthouses and hope for the best next time
|
||||||
|
query, err := NewLhQueryByInt(ip).Marshal()
|
||||||
|
if err != nil {
|
||||||
|
lh.l.WithError(err).WithField("vpnIp", ip).Error("Failed to marshal lighthouse query payload")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lighthouses := lh.GetLighthouses()
|
||||||
|
lh.metricTx(NebulaMeta_HostQuery, int64(len(lighthouses)))
|
||||||
|
|
||||||
|
for n := range lighthouses {
|
||||||
|
lh.ifce.SendMessageToVpnIp(header.LightHouse, 0, n, query, nb, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (lh *LightHouse) StartUpdateWorker() {
|
func (lh *LightHouse) StartUpdateWorker() {
|
||||||
interval := lh.GetUpdateInterval()
|
interval := lh.GetUpdateInterval()
|
||||||
if lh.amLighthouse || interval == 0 {
|
if lh.amLighthouse || interval == 0 {
|
||||||
|
|||||||
10
main.go
10
main.go
@@ -170,6 +170,16 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
|||||||
}
|
}
|
||||||
udpServer.ReloadConfig(c)
|
udpServer.ReloadConfig(c)
|
||||||
udpConns[i] = udpServer
|
udpConns[i] = udpServer
|
||||||
|
|
||||||
|
// If port is dynamic, discover it before the next pass through the for loop
|
||||||
|
// This way all routines will use the same port correctly
|
||||||
|
if port == 0 {
|
||||||
|
uPort, err := udpServer.LocalAddr()
|
||||||
|
if err != nil {
|
||||||
|
return nil, util.NewContextualError("Failed to get listening port", nil, err)
|
||||||
|
}
|
||||||
|
port = int(uPort.Port)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type tun struct {
|
|||||||
io.ReadWriteCloser
|
io.ReadWriteCloser
|
||||||
fd int
|
fd int
|
||||||
cidr *net.IPNet
|
cidr *net.IPNet
|
||||||
routeTree *cidr.Tree4
|
routeTree *cidr.Tree4[iputil.VpnIp]
|
||||||
l *logrus.Logger
|
l *logrus.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +46,8 @@ func newTun(_ *logrus.Logger, _ string, _ *net.IPNet, _ int, _ []Route, _ int, _
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *tun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
|
func (t *tun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
|
||||||
r := t.routeTree.MostSpecificContains(ip)
|
_, r := t.routeTree.MostSpecificContains(ip)
|
||||||
if r != nil {
|
return r
|
||||||
return r.(iputil.VpnIp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t tun) Activate() error {
|
func (t tun) Activate() error {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
type tun struct {
|
type tun struct {
|
||||||
io.ReadWriteCloser
|
io.ReadWriteCloser
|
||||||
cidr *net.IPNet
|
cidr *net.IPNet
|
||||||
routeTree *cidr.Tree4
|
routeTree *cidr.Tree4[iputil.VpnIp]
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTun(_ *logrus.Logger, _ string, _ *net.IPNet, _ int, _ []Route, _ int, _ bool, _ bool) (*tun, error) {
|
func newTun(_ *logrus.Logger, _ string, _ *net.IPNet, _ int, _ []Route, _ int, _ bool, _ bool) (*tun, error) {
|
||||||
@@ -46,12 +46,8 @@ func (t *tun) Activate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *tun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
|
func (t *tun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
|
||||||
r := t.routeTree.MostSpecificContains(ip)
|
_, r := t.routeTree.MostSpecificContains(ip)
|
||||||
if r != nil {
|
return r
|
||||||
return r.(iputil.VpnIp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following is hoisted up from water, we do this so we can inject our own fd on iOS
|
// The following is hoisted up from water, we do this so we can inject our own fd on iOS
|
||||||
|
|||||||
2
ssh.go
2
ssh.go
@@ -518,7 +518,7 @@ func sshQueryLighthouse(ifce *Interface, fs interface{}, a []string, w sshd.Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cm *CacheMap
|
var cm *CacheMap
|
||||||
rl := ifce.lightHouse.Query(vpnIp, ifce)
|
rl := ifce.lightHouse.Query(vpnIp)
|
||||||
if rl != nil {
|
if rl != nil {
|
||||||
cm = rl.CopyCache()
|
cm = rl.CopyCache()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user