mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 08:24:25 +01:00
Compare commits
6 Commits
vhost
...
changelog-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee8e4d2017 | ||
|
|
8d656fb890 | ||
|
|
27ea667aee | ||
|
|
4df8bcb1f5 | ||
|
|
36c890eaad | ||
|
|
44001244f2 |
60
CHANGELOG.md
60
CHANGELOG.md
@@ -7,12 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.10.0] - ????
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- PKCS11 support for P256 keys when built with `pkcs11` tag (#1153)
|
||||||
|
- ASN.1 based v2 nebula certificates with support for ipv6 and multiple ip addresses.
|
||||||
|
Certificates now have a unified interface for external implementations. (#1212, #1216, #1345)
|
||||||
|
**TODO: External documentation link!**
|
||||||
|
- Add the ability to mark packets on linux to better target nebula packets in iptables/nftables. (#1331)
|
||||||
|
- Add ECMP support for `unsafe_routes`. (#1332)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `default_local_cidr_any` now defaults to false, meaning that any firewall rule
|
- `default_local_cidr_any` now defaults to false, meaning that any firewall rule
|
||||||
intended to target an `unsafe_routes` entry must explicitly declare it via the
|
intended to target an `unsafe_routes` entry must explicitly declare it via the
|
||||||
`local_cidr` field. This is almost always the intended behavior. This flag is
|
`local_cidr` field. This is almost always the intended behavior. This flag is
|
||||||
deprecated and will be removed in a future release.
|
deprecated and will be removed in a future release. (#1373)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix moving a udp address from one vpn address to another in the `static_host_map`
|
||||||
|
which could cause rapid re-handshaking with an incorrect remote. (#1259)
|
||||||
|
- Improve smoke tests in environments where the docker network is not the default. (#1347)
|
||||||
|
|
||||||
|
## [1.9.7] - 2025-10-10
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- Fix an issue where Nebula could incorrectly accept and process a packet from an erroneous source IP when the sender's
|
||||||
|
certificate is configured with unsafe_routes (cert v1/v2) or multiple IPs (cert v2). (#1494)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Disable sending `recv_error` messages when a packet is received outside the allowable counter window. (#1459)
|
||||||
|
- Improve error messages and remove some unnecessary fatal conditions in the Windows and generic udp listener. (#1543)
|
||||||
|
|
||||||
|
## [1.9.6] - 2025-7-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support dropping inactive tunnels. This is disabled by default in this release but can be enabled with `tunnels.drop_inactive`. See example config for more details. (#1413)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix Darwin freeze due to presence of some Network Extensions (#1426)
|
||||||
|
- Ensure the same relay tunnel is always used when multiple relay tunnels are present (#1422)
|
||||||
|
- Fix Windows freeze due to ICMP error handling (#1412)
|
||||||
|
- Fix relay migration panic (#1403)
|
||||||
|
|
||||||
|
## [1.9.5] - 2024-12-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Gracefully ignore v2 certificates. (#1282)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix relays that refuse to re-establish after one of the remote tunnel pairs breaks. (#1277)
|
||||||
|
|
||||||
## [1.9.4] - 2024-09-09
|
## [1.9.4] - 2024-09-09
|
||||||
|
|
||||||
@@ -671,7 +723,11 @@ created.)
|
|||||||
|
|
||||||
- Initial public release.
|
- Initial public release.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.9.4...HEAD
|
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.10.0...HEAD
|
||||||
|
[1.10.0]: https://github.com/slackhq/nebula/releases/tag/v1.10.0
|
||||||
|
[1.9.7]: https://github.com/slackhq/nebula/releases/tag/v1.9.7
|
||||||
|
[1.9.6]: https://github.com/slackhq/nebula/releases/tag/v1.9.6
|
||||||
|
[1.9.5]: https://github.com/slackhq/nebula/releases/tag/v1.9.5
|
||||||
[1.9.4]: https://github.com/slackhq/nebula/releases/tag/v1.9.4
|
[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.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.2]: https://github.com/slackhq/nebula/releases/tag/v1.9.2
|
||||||
|
|||||||
109
bits.go
109
bits.go
@@ -9,14 +9,13 @@ type Bits struct {
|
|||||||
length uint64
|
length uint64
|
||||||
current uint64
|
current uint64
|
||||||
bits []bool
|
bits []bool
|
||||||
firstSeen bool
|
|
||||||
lostCounter metrics.Counter
|
lostCounter metrics.Counter
|
||||||
dupeCounter metrics.Counter
|
dupeCounter metrics.Counter
|
||||||
outOfWindowCounter metrics.Counter
|
outOfWindowCounter metrics.Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBits(bits uint64) *Bits {
|
func NewBits(bits uint64) *Bits {
|
||||||
return &Bits{
|
b := &Bits{
|
||||||
length: bits,
|
length: bits,
|
||||||
bits: make([]bool, bits, bits),
|
bits: make([]bool, bits, bits),
|
||||||
current: 0,
|
current: 0,
|
||||||
@@ -24,34 +23,37 @@ func NewBits(bits uint64) *Bits {
|
|||||||
dupeCounter: metrics.GetOrRegisterCounter("network.packets.duplicate", nil),
|
dupeCounter: metrics.GetOrRegisterCounter("network.packets.duplicate", nil),
|
||||||
outOfWindowCounter: metrics.GetOrRegisterCounter("network.packets.out_of_window", nil),
|
outOfWindowCounter: metrics.GetOrRegisterCounter("network.packets.out_of_window", nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There is no counter value 0, mark it to avoid counting a lost packet later.
|
||||||
|
b.bits[0] = true
|
||||||
|
b.current = 0
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bits) Check(l logrus.FieldLogger, i uint64) bool {
|
func (b *Bits) Check(l *logrus.Logger, i uint64) bool {
|
||||||
// If i is the next number, return true.
|
// If i is the next number, return true.
|
||||||
if i > b.current || (i == 0 && b.firstSeen == false && b.current < b.length) {
|
if i > b.current {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// If i is within the window, check if it's been set already. The first window will fail this check
|
// If i is within the window, check if it's been set already.
|
||||||
if i > b.current-b.length {
|
if i > b.current-b.length || i < b.length && b.current < b.length {
|
||||||
return !b.bits[i%b.length]
|
|
||||||
}
|
|
||||||
|
|
||||||
// If i is within the first window
|
|
||||||
if i < b.length {
|
|
||||||
return !b.bits[i%b.length]
|
return !b.bits[i%b.length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not within the window
|
// Not within the window
|
||||||
l.Debugf("rejected a packet (top) %d %d\n", b.current, i)
|
if l.Level >= logrus.DebugLevel {
|
||||||
|
l.Debugf("rejected a packet (top) %d %d\n", b.current, i)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bits) Update(l *logrus.Logger, i uint64) bool {
|
func (b *Bits) Update(l *logrus.Logger, i uint64) bool {
|
||||||
// If i is the next number, return true and update current.
|
// If i is the next number, return true and update current.
|
||||||
if i == b.current+1 {
|
if i == b.current+1 {
|
||||||
// Report missed packets, we can only understand what was missed after the first window has been gone through
|
// Check if the oldest bit was lost since we are shifting the window by 1 and occupying it with this counter
|
||||||
if i > b.length && b.bits[i%b.length] == false {
|
// The very first window can only be tracked as lost once we are on the 2nd window or greater
|
||||||
|
if b.bits[i%b.length] == false && i > b.length {
|
||||||
b.lostCounter.Inc(1)
|
b.lostCounter.Inc(1)
|
||||||
}
|
}
|
||||||
b.bits[i%b.length] = true
|
b.bits[i%b.length] = true
|
||||||
@@ -59,61 +61,32 @@ func (b *Bits) Update(l *logrus.Logger, i uint64) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// If i packet is greater than current but less than the maximum length of our bitmap,
|
// If i is a jump, adjust the window, record lost, update current, and return true
|
||||||
// flip everything in between to false and move ahead.
|
if i > b.current {
|
||||||
if i > b.current && i < b.current+b.length {
|
lost := int64(0)
|
||||||
// In between current and i need to be zero'd to allow those packets to come in later
|
// Zero out the bits between the current and the new counter value, limited by the window size,
|
||||||
for n := b.current + 1; n < i; n++ {
|
// since the window is shifting
|
||||||
|
for n := b.current + 1; n <= min(i, b.current+b.length); n++ {
|
||||||
|
if b.bits[n%b.length] == false && n > b.length {
|
||||||
|
lost++
|
||||||
|
}
|
||||||
b.bits[n%b.length] = false
|
b.bits[n%b.length] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
b.bits[i%b.length] = true
|
// Only record any skipped packets as a result of the window moving further than the window length
|
||||||
b.current = i
|
// Any loss within the new window will be accounted for in future calls
|
||||||
//l.Debugf("missed %d packets between %d and %d\n", i-b.current, i, b.current)
|
lost += max(0, int64(i-b.current-b.length))
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If i is greater than the delta between current and the total length of our bitmap,
|
|
||||||
// just flip everything in the map and move ahead.
|
|
||||||
if i >= b.current+b.length {
|
|
||||||
// The current window loss will be accounted for later, only record the jump as loss up until then
|
|
||||||
lost := maxInt64(0, int64(i-b.current-b.length))
|
|
||||||
//TODO: explain this
|
|
||||||
if b.current == 0 {
|
|
||||||
lost++
|
|
||||||
}
|
|
||||||
|
|
||||||
for n := range b.bits {
|
|
||||||
// Don't want to count the first window as a loss
|
|
||||||
//TODO: this is likely wrong, we are wanting to track only the bit slots that we aren't going to track anymore and this is marking everything as missed
|
|
||||||
//if b.bits[n] == false {
|
|
||||||
// lost++
|
|
||||||
//}
|
|
||||||
b.bits[n] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lostCounter.Inc(lost)
|
b.lostCounter.Inc(lost)
|
||||||
|
|
||||||
if l.Level >= logrus.DebugLevel {
|
|
||||||
l.WithField("receiveWindow", m{"accepted": true, "currentCounter": b.current, "incomingCounter": i, "reason": "window shifting"}).
|
|
||||||
Debug("Receive window")
|
|
||||||
}
|
|
||||||
b.bits[i%b.length] = true
|
b.bits[i%b.length] = true
|
||||||
b.current = i
|
b.current = i
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow for the 0 packet to come in within the first window
|
// If i is within the current window but below the current counter,
|
||||||
if i == 0 && b.firstSeen == false && b.current < b.length {
|
// Check to see if it's a duplicate
|
||||||
b.firstSeen = true
|
if i > b.current-b.length || i < b.length && b.current < b.length {
|
||||||
b.bits[i%b.length] = true
|
if b.current == i || b.bits[i%b.length] == true {
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If i is within the window of current minus length (the total pat window size),
|
|
||||||
// allow it and flip to true but to NOT change current. We also have to account for the first window
|
|
||||||
if ((b.current >= b.length && i > b.current-b.length) || (b.current < b.length && i < b.length)) && i <= b.current {
|
|
||||||
if b.current == i {
|
|
||||||
if l.Level >= logrus.DebugLevel {
|
if l.Level >= logrus.DebugLevel {
|
||||||
l.WithField("receiveWindow", m{"accepted": false, "currentCounter": b.current, "incomingCounter": i, "reason": "duplicate"}).
|
l.WithField("receiveWindow", m{"accepted": false, "currentCounter": b.current, "incomingCounter": i, "reason": "duplicate"}).
|
||||||
Debug("Receive window")
|
Debug("Receive window")
|
||||||
@@ -122,18 +95,8 @@ func (b *Bits) Update(l *logrus.Logger, i uint64) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.bits[i%b.length] == true {
|
|
||||||
if l.Level >= logrus.DebugLevel {
|
|
||||||
l.WithField("receiveWindow", m{"accepted": false, "currentCounter": b.current, "incomingCounter": i, "reason": "old duplicate"}).
|
|
||||||
Debug("Receive window")
|
|
||||||
}
|
|
||||||
b.dupeCounter.Inc(1)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
b.bits[i%b.length] = true
|
b.bits[i%b.length] = true
|
||||||
return true
|
return true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In all other cases, fail and don't change current.
|
// In all other cases, fail and don't change current.
|
||||||
@@ -147,11 +110,3 @@ func (b *Bits) Update(l *logrus.Logger, i uint64) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func maxInt64(a, b int64) int64 {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|||||||
109
bits_test.go
109
bits_test.go
@@ -15,48 +15,41 @@ func TestBits(t *testing.T) {
|
|||||||
assert.Len(t, b.bits, 10)
|
assert.Len(t, b.bits, 10)
|
||||||
|
|
||||||
// This is initialized to zero - receive one. This should work.
|
// This is initialized to zero - receive one. This should work.
|
||||||
|
|
||||||
assert.True(t, b.Check(l, 1))
|
assert.True(t, b.Check(l, 1))
|
||||||
u := b.Update(l, 1)
|
assert.True(t, b.Update(l, 1))
|
||||||
assert.True(t, u)
|
|
||||||
assert.EqualValues(t, 1, b.current)
|
assert.EqualValues(t, 1, b.current)
|
||||||
g := []bool{false, true, false, false, false, false, false, false, false, false}
|
g := []bool{true, true, false, false, false, false, false, false, false, false}
|
||||||
assert.Equal(t, g, b.bits)
|
assert.Equal(t, g, b.bits)
|
||||||
|
|
||||||
// Receive two
|
// Receive two
|
||||||
assert.True(t, b.Check(l, 2))
|
assert.True(t, b.Check(l, 2))
|
||||||
u = b.Update(l, 2)
|
assert.True(t, b.Update(l, 2))
|
||||||
assert.True(t, u)
|
|
||||||
assert.EqualValues(t, 2, b.current)
|
assert.EqualValues(t, 2, b.current)
|
||||||
g = []bool{false, true, true, false, false, false, false, false, false, false}
|
g = []bool{true, true, true, false, false, false, false, false, false, false}
|
||||||
assert.Equal(t, g, b.bits)
|
assert.Equal(t, g, b.bits)
|
||||||
|
|
||||||
// Receive two again - it will fail
|
// Receive two again - it will fail
|
||||||
assert.False(t, b.Check(l, 2))
|
assert.False(t, b.Check(l, 2))
|
||||||
u = b.Update(l, 2)
|
assert.False(t, b.Update(l, 2))
|
||||||
assert.False(t, u)
|
|
||||||
assert.EqualValues(t, 2, b.current)
|
assert.EqualValues(t, 2, b.current)
|
||||||
|
|
||||||
// Jump ahead to 15, which should clear everything and set the 6th element
|
// Jump ahead to 15, which should clear everything and set the 6th element
|
||||||
assert.True(t, b.Check(l, 15))
|
assert.True(t, b.Check(l, 15))
|
||||||
u = b.Update(l, 15)
|
assert.True(t, b.Update(l, 15))
|
||||||
assert.True(t, u)
|
|
||||||
assert.EqualValues(t, 15, b.current)
|
assert.EqualValues(t, 15, b.current)
|
||||||
g = []bool{false, false, false, false, false, true, false, false, false, false}
|
g = []bool{false, false, false, false, false, true, false, false, false, false}
|
||||||
assert.Equal(t, g, b.bits)
|
assert.Equal(t, g, b.bits)
|
||||||
|
|
||||||
// Mark 14, which is allowed because it is in the window
|
// Mark 14, which is allowed because it is in the window
|
||||||
assert.True(t, b.Check(l, 14))
|
assert.True(t, b.Check(l, 14))
|
||||||
u = b.Update(l, 14)
|
assert.True(t, b.Update(l, 14))
|
||||||
assert.True(t, u)
|
|
||||||
assert.EqualValues(t, 15, b.current)
|
assert.EqualValues(t, 15, b.current)
|
||||||
g = []bool{false, false, false, false, true, true, false, false, false, false}
|
g = []bool{false, false, false, false, true, true, false, false, false, false}
|
||||||
assert.Equal(t, g, b.bits)
|
assert.Equal(t, g, b.bits)
|
||||||
|
|
||||||
// Mark 5, which is not allowed because it is not in the window
|
// Mark 5, which is not allowed because it is not in the window
|
||||||
assert.False(t, b.Check(l, 5))
|
assert.False(t, b.Check(l, 5))
|
||||||
u = b.Update(l, 5)
|
assert.False(t, b.Update(l, 5))
|
||||||
assert.False(t, u)
|
|
||||||
assert.EqualValues(t, 15, b.current)
|
assert.EqualValues(t, 15, b.current)
|
||||||
g = []bool{false, false, false, false, true, true, false, false, false, false}
|
g = []bool{false, false, false, false, true, true, false, false, false, false}
|
||||||
assert.Equal(t, g, b.bits)
|
assert.Equal(t, g, b.bits)
|
||||||
@@ -69,10 +62,29 @@ func TestBits(t *testing.T) {
|
|||||||
|
|
||||||
// Walk through a few windows in order
|
// Walk through a few windows in order
|
||||||
b = NewBits(10)
|
b = NewBits(10)
|
||||||
for i := uint64(0); i <= 100; i++ {
|
for i := uint64(1); i <= 100; i++ {
|
||||||
assert.True(t, b.Check(l, i), "Error while checking %v", i)
|
assert.True(t, b.Check(l, i), "Error while checking %v", i)
|
||||||
assert.True(t, b.Update(l, i), "Error while updating %v", i)
|
assert.True(t, b.Update(l, i), "Error while updating %v", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert.False(t, b.Check(l, 1), "Out of window check")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBitsLargeJumps(t *testing.T) {
|
||||||
|
l := test.NewLogger()
|
||||||
|
b := NewBits(10)
|
||||||
|
b.lostCounter.Clear()
|
||||||
|
|
||||||
|
b = NewBits(10)
|
||||||
|
b.lostCounter.Clear()
|
||||||
|
assert.True(t, b.Update(l, 55)) // We saw packet 55 and can still track 45,46,47,48,49,50,51,52,53,54
|
||||||
|
assert.Equal(t, int64(45), b.lostCounter.Count())
|
||||||
|
|
||||||
|
assert.True(t, b.Update(l, 100)) // We saw packet 55 and 100 and can still track 90,91,92,93,94,95,96,97,98,99
|
||||||
|
assert.Equal(t, int64(89), b.lostCounter.Count())
|
||||||
|
|
||||||
|
assert.True(t, b.Update(l, 200)) // We saw packet 55, 100, and 200 and can still track 190,191,192,193,194,195,196,197,198,199
|
||||||
|
assert.Equal(t, int64(188), b.lostCounter.Count())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBitsDupeCounter(t *testing.T) {
|
func TestBitsDupeCounter(t *testing.T) {
|
||||||
@@ -124,8 +136,7 @@ func TestBitsOutOfWindowCounter(t *testing.T) {
|
|||||||
assert.False(t, b.Update(l, 0))
|
assert.False(t, b.Update(l, 0))
|
||||||
assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
|
assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
|
||||||
|
|
||||||
//tODO: make sure lostcounter doesn't increase in orderly increment
|
assert.Equal(t, int64(19), b.lostCounter.Count()) // packet 0 wasn't lost
|
||||||
assert.Equal(t, int64(20), b.lostCounter.Count())
|
|
||||||
assert.Equal(t, int64(0), b.dupeCounter.Count())
|
assert.Equal(t, int64(0), b.dupeCounter.Count())
|
||||||
assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
|
assert.Equal(t, int64(1), b.outOfWindowCounter.Count())
|
||||||
}
|
}
|
||||||
@@ -137,8 +148,6 @@ func TestBitsLostCounter(t *testing.T) {
|
|||||||
b.dupeCounter.Clear()
|
b.dupeCounter.Clear()
|
||||||
b.outOfWindowCounter.Clear()
|
b.outOfWindowCounter.Clear()
|
||||||
|
|
||||||
//assert.True(t, b.Update(0))
|
|
||||||
assert.True(t, b.Update(l, 0))
|
|
||||||
assert.True(t, b.Update(l, 20))
|
assert.True(t, b.Update(l, 20))
|
||||||
assert.True(t, b.Update(l, 21))
|
assert.True(t, b.Update(l, 21))
|
||||||
assert.True(t, b.Update(l, 22))
|
assert.True(t, b.Update(l, 22))
|
||||||
@@ -149,7 +158,7 @@ func TestBitsLostCounter(t *testing.T) {
|
|||||||
assert.True(t, b.Update(l, 27))
|
assert.True(t, b.Update(l, 27))
|
||||||
assert.True(t, b.Update(l, 28))
|
assert.True(t, b.Update(l, 28))
|
||||||
assert.True(t, b.Update(l, 29))
|
assert.True(t, b.Update(l, 29))
|
||||||
assert.Equal(t, int64(20), b.lostCounter.Count())
|
assert.Equal(t, int64(19), b.lostCounter.Count()) // packet 0 wasn't lost
|
||||||
assert.Equal(t, int64(0), b.dupeCounter.Count())
|
assert.Equal(t, int64(0), b.dupeCounter.Count())
|
||||||
assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
|
assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
|
||||||
|
|
||||||
@@ -158,8 +167,6 @@ func TestBitsLostCounter(t *testing.T) {
|
|||||||
b.dupeCounter.Clear()
|
b.dupeCounter.Clear()
|
||||||
b.outOfWindowCounter.Clear()
|
b.outOfWindowCounter.Clear()
|
||||||
|
|
||||||
assert.True(t, b.Update(l, 0))
|
|
||||||
assert.Equal(t, int64(0), b.lostCounter.Count())
|
|
||||||
assert.True(t, b.Update(l, 9))
|
assert.True(t, b.Update(l, 9))
|
||||||
assert.Equal(t, int64(0), b.lostCounter.Count())
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
// 10 will set 0 index, 0 was already set, no lost packets
|
// 10 will set 0 index, 0 was already set, no lost packets
|
||||||
@@ -214,6 +221,62 @@ func TestBitsLostCounter(t *testing.T) {
|
|||||||
assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
|
assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBitsLostCounterIssue1(t *testing.T) {
|
||||||
|
l := test.NewLogger()
|
||||||
|
b := NewBits(10)
|
||||||
|
b.lostCounter.Clear()
|
||||||
|
b.dupeCounter.Clear()
|
||||||
|
b.outOfWindowCounter.Clear()
|
||||||
|
|
||||||
|
assert.True(t, b.Update(l, 4))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 1))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 9))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 2))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 3))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 5))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 6))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 7))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
// assert.True(t, b.Update(l, 8))
|
||||||
|
assert.True(t, b.Update(l, 10))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 11))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
|
||||||
|
assert.True(t, b.Update(l, 14))
|
||||||
|
assert.Equal(t, int64(0), b.lostCounter.Count())
|
||||||
|
// Issue seems to be here, we reset missing packet 8 to false here and don't increment the lost counter
|
||||||
|
assert.True(t, b.Update(l, 19))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 12))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 13))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 15))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 16))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 17))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 18))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 20))
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.True(t, b.Update(l, 21))
|
||||||
|
|
||||||
|
// We missed packet 8 above
|
||||||
|
assert.Equal(t, int64(1), b.lostCounter.Count())
|
||||||
|
assert.Equal(t, int64(0), b.dupeCounter.Count())
|
||||||
|
assert.Equal(t, int64(0), b.outOfWindowCounter.Count())
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkBits(b *testing.B) {
|
func BenchmarkBits(b *testing.B) {
|
||||||
z := NewBits(10)
|
z := NewBits(10)
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
|
|||||||
@@ -173,23 +173,26 @@ func ca(args []string, out io.Writer, errOut io.Writer, pr PasswordReader) error
|
|||||||
|
|
||||||
var passphrase []byte
|
var passphrase []byte
|
||||||
if !isP11 && *cf.encryption {
|
if !isP11 && *cf.encryption {
|
||||||
for i := 0; i < 5; i++ {
|
passphrase = []byte(os.Getenv("NEBULA_CA_PASSPHRASE"))
|
||||||
out.Write([]byte("Enter passphrase: "))
|
|
||||||
passphrase, err = pr.ReadPassword()
|
|
||||||
|
|
||||||
if err == ErrNoTerminal {
|
|
||||||
return fmt.Errorf("out-key must be encrypted interactively")
|
|
||||||
} else if err != nil {
|
|
||||||
return fmt.Errorf("error reading passphrase: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(passphrase) > 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(passphrase) == 0 {
|
if len(passphrase) == 0 {
|
||||||
return fmt.Errorf("no passphrase specified, remove -encrypt flag to write out-key in plaintext")
|
for i := 0; i < 5; i++ {
|
||||||
|
out.Write([]byte("Enter passphrase: "))
|
||||||
|
passphrase, err = pr.ReadPassword()
|
||||||
|
|
||||||
|
if err == ErrNoTerminal {
|
||||||
|
return fmt.Errorf("out-key must be encrypted interactively")
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("error reading passphrase: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(passphrase) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(passphrase) == 0 {
|
||||||
|
return fmt.Errorf("no passphrase specified, remove -encrypt flag to write out-key in plaintext")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,17 @@ func Test_ca(t *testing.T) {
|
|||||||
assert.Equal(t, pwPromptOb, ob.String())
|
assert.Equal(t, pwPromptOb, ob.String())
|
||||||
assert.Empty(t, eb.String())
|
assert.Empty(t, eb.String())
|
||||||
|
|
||||||
|
// test encrypted key with passphrase environment variable
|
||||||
|
os.Remove(keyF.Name())
|
||||||
|
os.Remove(crtF.Name())
|
||||||
|
ob.Reset()
|
||||||
|
eb.Reset()
|
||||||
|
args = []string{"-version", "1", "-encrypt", "-name", "test", "-duration", "100m", "-groups", "1,2,3,4,5", "-out-crt", crtF.Name(), "-out-key", keyF.Name()}
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", string(passphrase))
|
||||||
|
require.NoError(t, ca(args, ob, eb, testpw))
|
||||||
|
assert.Empty(t, eb.String())
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", "")
|
||||||
|
|
||||||
// read encrypted key file and verify default params
|
// read encrypted key file and verify default params
|
||||||
rb, _ = os.ReadFile(keyF.Name())
|
rb, _ = os.ReadFile(keyF.Name())
|
||||||
k, _ := pem.Decode(rb)
|
k, _ := pem.Decode(rb)
|
||||||
|
|||||||
@@ -5,10 +5,28 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A version string that can be set with
|
||||||
|
//
|
||||||
|
// -ldflags "-X main.Build=SOMEVERSION"
|
||||||
|
//
|
||||||
|
// at compile-time.
|
||||||
var Build string
|
var Build string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Build == "" {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Build = strings.TrimPrefix(info.Main.Version, "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type helpError struct {
|
type helpError struct {
|
||||||
s string
|
s string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,26 +116,28 @@ func signCert(args []string, out io.Writer, errOut io.Writer, pr PasswordReader)
|
|||||||
// naively attempt to decode the private key as though it is not encrypted
|
// naively attempt to decode the private key as though it is not encrypted
|
||||||
caKey, _, curve, err = cert.UnmarshalSigningPrivateKeyFromPEM(rawCAKey)
|
caKey, _, curve, err = cert.UnmarshalSigningPrivateKeyFromPEM(rawCAKey)
|
||||||
if errors.Is(err, cert.ErrPrivateKeyEncrypted) {
|
if errors.Is(err, cert.ErrPrivateKeyEncrypted) {
|
||||||
// ask for a passphrase until we get one
|
|
||||||
var passphrase []byte
|
var passphrase []byte
|
||||||
for i := 0; i < 5; i++ {
|
passphrase = []byte(os.Getenv("NEBULA_CA_PASSPHRASE"))
|
||||||
out.Write([]byte("Enter passphrase: "))
|
|
||||||
passphrase, err = pr.ReadPassword()
|
|
||||||
|
|
||||||
if errors.Is(err, ErrNoTerminal) {
|
|
||||||
return fmt.Errorf("ca-key is encrypted and must be decrypted interactively")
|
|
||||||
} else if err != nil {
|
|
||||||
return fmt.Errorf("error reading password: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(passphrase) > 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(passphrase) == 0 {
|
if len(passphrase) == 0 {
|
||||||
return fmt.Errorf("cannot open encrypted ca-key without passphrase")
|
// ask for a passphrase until we get one
|
||||||
}
|
for i := 0; i < 5; i++ {
|
||||||
|
out.Write([]byte("Enter passphrase: "))
|
||||||
|
passphrase, err = pr.ReadPassword()
|
||||||
|
|
||||||
|
if errors.Is(err, ErrNoTerminal) {
|
||||||
|
return fmt.Errorf("ca-key is encrypted and must be decrypted interactively")
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("error reading password: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(passphrase) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(passphrase) == 0 {
|
||||||
|
return fmt.Errorf("cannot open encrypted ca-key without passphrase")
|
||||||
|
}
|
||||||
|
}
|
||||||
curve, caKey, _, err = cert.DecryptAndUnmarshalSigningPrivateKey(passphrase, rawCAKey)
|
curve, caKey, _, err = cert.DecryptAndUnmarshalSigningPrivateKey(passphrase, rawCAKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error while parsing encrypted ca-key: %s", err)
|
return fmt.Errorf("error while parsing encrypted ca-key: %s", err)
|
||||||
|
|||||||
@@ -379,6 +379,15 @@ func Test_signCert(t *testing.T) {
|
|||||||
assert.Equal(t, "Enter passphrase: ", ob.String())
|
assert.Equal(t, "Enter passphrase: ", ob.String())
|
||||||
assert.Empty(t, eb.String())
|
assert.Empty(t, eb.String())
|
||||||
|
|
||||||
|
// test with the proper password in the environment
|
||||||
|
os.Remove(crtF.Name())
|
||||||
|
os.Remove(keyF.Name())
|
||||||
|
args = []string{"-version", "1", "-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, , 10.2.2.2/32 , , ,, 10.5.5.5/32", "-groups", "1,, 2 , ,,,3,4,5"}
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", string(passphrase))
|
||||||
|
require.NoError(t, signCert(args, ob, eb, testpw))
|
||||||
|
assert.Empty(t, eb.String())
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", "")
|
||||||
|
|
||||||
// test with the wrong password
|
// test with the wrong password
|
||||||
ob.Reset()
|
ob.Reset()
|
||||||
eb.Reset()
|
eb.Reset()
|
||||||
@@ -389,6 +398,17 @@ func Test_signCert(t *testing.T) {
|
|||||||
assert.Equal(t, "Enter passphrase: ", ob.String())
|
assert.Equal(t, "Enter passphrase: ", ob.String())
|
||||||
assert.Empty(t, eb.String())
|
assert.Empty(t, eb.String())
|
||||||
|
|
||||||
|
// test with the wrong password in environment
|
||||||
|
ob.Reset()
|
||||||
|
eb.Reset()
|
||||||
|
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", "invalid password")
|
||||||
|
args = []string{"-version", "1", "-ca-crt", caCrtF.Name(), "-ca-key", caKeyF.Name(), "-name", "test", "-ip", "1.1.1.1/24", "-out-crt", crtF.Name(), "-out-key", keyF.Name(), "-duration", "100m", "-subnets", "10.1.1.1/32, , 10.2.2.2/32 , , ,, 10.5.5.5/32", "-groups", "1,, 2 , ,,,3,4,5"}
|
||||||
|
require.EqualError(t, signCert(args, ob, eb, nopw), "error while parsing encrypted ca-key: invalid passphrase or corrupt private key")
|
||||||
|
assert.Empty(t, ob.String())
|
||||||
|
assert.Empty(t, eb.String())
|
||||||
|
os.Setenv("NEBULA_CA_PASSPHRASE", "")
|
||||||
|
|
||||||
// test with the user not entering a password
|
// test with the user not entering a password
|
||||||
ob.Reset()
|
ob.Reset()
|
||||||
eb.Reset()
|
eb.Reset()
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/slackhq/nebula"
|
"github.com/slackhq/nebula"
|
||||||
@@ -18,6 +20,17 @@ import (
|
|||||||
// at compile-time.
|
// at compile-time.
|
||||||
var Build string
|
var Build string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Build == "" {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Build = strings.TrimPrefix(info.Main.Version, "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
serviceFlag := flag.String("service", "", "Control the system service.")
|
serviceFlag := flag.String("service", "", "Control the system service.")
|
||||||
configPath := flag.String("config", "", "Path to either a file or directory to load configuration from")
|
configPath := flag.String("config", "", "Path to either a file or directory to load configuration from")
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/slackhq/nebula"
|
"github.com/slackhq/nebula"
|
||||||
@@ -18,6 +20,17 @@ import (
|
|||||||
// at compile-time.
|
// at compile-time.
|
||||||
var Build string
|
var Build string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Build == "" {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Build = strings.TrimPrefix(info.Main.Version, "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
configPath := flag.String("config", "", "Path to either a file or directory to load configuration from")
|
configPath := flag.String("config", "", "Path to either a file or directory to load configuration from")
|
||||||
configTest := flag.Bool("test", false, "Test the config and print the end result. Non zero exit indicates a faulty config")
|
configTest := flag.Bool("test", false, "Test the config and print the end result. Non zero exit indicates a faulty config")
|
||||||
|
|||||||
@@ -106,13 +106,13 @@ func TestFirewall_AddRule(t *testing.T) {
|
|||||||
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
||||||
require.NoError(t, fw.AddRule(false, firewall.ProtoAny, 1, 1, []string{}, "", netip.Prefix{}, ti, "", ""))
|
require.NoError(t, fw.AddRule(false, firewall.ProtoAny, 1, 1, []string{}, "", netip.Prefix{}, ti, "", ""))
|
||||||
assert.NotNil(t, fw.OutRules.AnyProto[1].Any.Any)
|
assert.NotNil(t, fw.OutRules.AnyProto[1].Any.Any)
|
||||||
_, ok = fw.OutRules.AnyProto[1].Any.Any.LocalCIDR.Get(ti)
|
ok = fw.OutRules.AnyProto[1].Any.Any.LocalCIDR.Get(ti)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
||||||
require.NoError(t, fw.AddRule(false, firewall.ProtoAny, 1, 1, []string{}, "", netip.Prefix{}, ti6, "", ""))
|
require.NoError(t, fw.AddRule(false, firewall.ProtoAny, 1, 1, []string{}, "", netip.Prefix{}, ti6, "", ""))
|
||||||
assert.NotNil(t, fw.OutRules.AnyProto[1].Any.Any)
|
assert.NotNil(t, fw.OutRules.AnyProto[1].Any.Any)
|
||||||
_, ok = fw.OutRules.AnyProto[1].Any.Any.LocalCIDR.Get(ti6)
|
ok = fw.OutRules.AnyProto[1].Any.Any.LocalCIDR.Get(ti6)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
fw = NewFirewall(l, time.Second, time.Minute, time.Hour, c)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
|||||||
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.1.0
|
github.com/flynn/noise v1.1.0
|
||||||
github.com/gaissmai/bart v0.25.0
|
github.com/gaissmai/bart v0.26.0
|
||||||
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.4
|
github.com/kardianos/service v1.2.4
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -24,8 +24,8 @@ 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.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
|
||||||
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
|
||||||
github.com/gaissmai/bart v0.25.0 h1:eqiokVPqM3F94vJ0bTHXHtH91S8zkKL+bKh+BsGOsJM=
|
github.com/gaissmai/bart v0.26.0 h1:xOZ57E9hJLBiQaSyeZa9wgWhGuzfGACgqp4BE77OkO0=
|
||||||
github.com/gaissmai/bart v0.25.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c=
|
github.com/gaissmai/bart v0.26.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c=
|
||||||
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=
|
||||||
|
|||||||
21
main.go
21
main.go
@@ -5,6 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@@ -27,6 +29,10 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if buildVersion == "" {
|
||||||
|
buildVersion = moduleVersion()
|
||||||
|
}
|
||||||
|
|
||||||
l := logger
|
l := logger
|
||||||
l.Formatter = &logrus.TextFormatter{
|
l.Formatter = &logrus.TextFormatter{
|
||||||
FullTimestamp: true,
|
FullTimestamp: true,
|
||||||
@@ -296,3 +302,18 @@ func Main(c *config.C, configTest bool, buildVersion string, logger *logrus.Logg
|
|||||||
connManager.Start,
|
connManager.Start,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func moduleVersion() string {
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dep := range info.Deps {
|
||||||
|
if dep.Path == "github.com/slackhq/nebula" {
|
||||||
|
return strings.TrimPrefix(dep.Version, "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user