mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-10 14:33:59 +01:00
Merge remote-tracking branch 'origin/master' into multiport
This commit is contained in:
commit
a2b9747b0f
75
CHANGELOG.md
75
CHANGELOG.md
@ -7,12 +7,82 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.7.0] - 2023-05-17
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `nebula-cert ca` now supports encrypting the CA's private key with a
|
- `nebula-cert ca` now supports encrypting the CA's private key with a
|
||||||
passphrase. Pass `-encrypt` in order to be prompted for a passphrase.
|
passphrase. Pass `-encrypt` in order to be prompted for a passphrase.
|
||||||
Encryption is performed using AES-256-GCM and Argon2id for KDF. KDF
|
Encryption is performed using AES-256-GCM and Argon2id for KDF. KDF
|
||||||
parameters default to RFC recommendations, but can be overridden via CLI
|
parameters default to RFC recommendations, but can be overridden via CLI
|
||||||
flags `-argon-memory`, `-argon-parallelism`, and `-argon-iterations`.
|
flags `-argon-memory`, `-argon-parallelism`, and `-argon-iterations`. (#386)
|
||||||
|
|
||||||
|
- Support for curve P256 and BoringCrypto has been added. See README section
|
||||||
|
"Curve P256 and BoringCrypto" for more details. (#865, #861, #769, #856, #803)
|
||||||
|
|
||||||
|
- New firewall rule `local_cidr`. This could be used to filter destinations
|
||||||
|
when using `unsafe_routes`. (#507)
|
||||||
|
|
||||||
|
- Add `unsafe_route` option `install`. This controls whether the route is
|
||||||
|
installed in the systems routing table. (#831)
|
||||||
|
|
||||||
|
- Add `tun.use_system_route_table` option. Set to true to manage unsafe routes
|
||||||
|
directly on the system route table with gateway routes instead of in Nebula
|
||||||
|
configuration files. This is only supported on Linux. (#839)
|
||||||
|
|
||||||
|
- The metric `certificate.ttl_seconds` is now exposed via stats. (#782)
|
||||||
|
|
||||||
|
- Add `punchy.respond_delay` option. This allows you to change the delay
|
||||||
|
before attempting punchy.respond. Default is 5 seconds. (#721)
|
||||||
|
|
||||||
|
- Added SSH commands to allow the capture of a mutex profile. (#737)
|
||||||
|
|
||||||
|
- You can now set `lighthouse.calculated_remotes` to make it possible to do
|
||||||
|
handshakes without a lighthouse in certain configurations. (#759)
|
||||||
|
|
||||||
|
- The firewall can be configured to send REJECT replies instead of the default
|
||||||
|
DROP behavior. (#738)
|
||||||
|
|
||||||
|
- For macOS, an example launchd configuration file is now provided. (#762)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Lighthouses and other `static_host_map` entries that use DNS names will now
|
||||||
|
be automatically refreshed to detect when the IP address changes. (#796)
|
||||||
|
|
||||||
|
- Lighthouses send ACK replies back to clients so that they do not fall into
|
||||||
|
connection testing as often by clients. (#851, #408)
|
||||||
|
|
||||||
|
- Allow the `listen.host` option to contain a hostname. (#825)
|
||||||
|
|
||||||
|
- When Nebula switches to a new certificate (such as via SIGHUP), we now
|
||||||
|
rehandshake with all existing tunnels. This allows firewall groups to be
|
||||||
|
updated and `pki.disconnect_invalid` to know about the new certificate
|
||||||
|
expiration time. (#838, #857, #842, #840, #835, #828, #820, #807)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Always disconnect blocklisted hosts, even if `pki.disconnect_invalid` is
|
||||||
|
not set. (#858)
|
||||||
|
|
||||||
|
- Dependencies updated and go1.20 required. (#780, #824, #855, #854)
|
||||||
|
|
||||||
|
- Fix possible race condition with relays. (#827)
|
||||||
|
|
||||||
|
- FreeBSD: Fix connection to the localhost's own Nebula IP. (#808)
|
||||||
|
|
||||||
|
- Normalize and document some common log field values. (#837, #811)
|
||||||
|
|
||||||
|
- Fix crash if you set unlucky values for the firewall timeout configuration
|
||||||
|
options. (#802)
|
||||||
|
|
||||||
|
- Make DNS queries case insensitive. (#793)
|
||||||
|
|
||||||
|
- Update example systemd configurations to want `nss-lookup`. (#791)
|
||||||
|
|
||||||
|
- Errors with SSH commands now go to the SSH tunnel instead of stderr. (#757)
|
||||||
|
|
||||||
|
- Fix a hang when shutting down Android. (#772)
|
||||||
|
|
||||||
## [1.6.1] - 2022-09-26
|
## [1.6.1] - 2022-09-26
|
||||||
|
|
||||||
@ -405,7 +475,8 @@ created.)
|
|||||||
|
|
||||||
- Initial public release.
|
- Initial public release.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.6.1...HEAD
|
[Unreleased]: https://github.com/slackhq/nebula/compare/v1.7.0...HEAD
|
||||||
|
[1.7.0]: https://github.com/slackhq/nebula/releases/tag/v1.7.0
|
||||||
[1.6.1]: https://github.com/slackhq/nebula/releases/tag/v1.6.1
|
[1.6.1]: https://github.com/slackhq/nebula/releases/tag/v1.6.1
|
||||||
[1.6.0]: https://github.com/slackhq/nebula/releases/tag/v1.6.0
|
[1.6.0]: https://github.com/slackhq/nebula/releases/tag/v1.6.0
|
||||||
[1.5.2]: https://github.com/slackhq/nebula/releases/tag/v1.5.2
|
[1.5.2]: https://github.com/slackhq/nebula/releases/tag/v1.5.2
|
||||||
|
|||||||
10
cert/ca.go
10
cert/ca.go
@ -91,9 +91,15 @@ func (ncp *NebulaCAPool) ResetCertBlocklist() {
|
|||||||
ncp.certBlocklist = make(map[string]struct{})
|
ncp.certBlocklist = make(map[string]struct{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBlocklisted returns true if the fingerprint fails to generate or has been explicitly blocklisted
|
// NOTE: This uses an internal cache for Sha256Sum() that will not be invalidated
|
||||||
|
// automatically if you manually change any fields in the NebulaCertificate.
|
||||||
func (ncp *NebulaCAPool) IsBlocklisted(c *NebulaCertificate) bool {
|
func (ncp *NebulaCAPool) IsBlocklisted(c *NebulaCertificate) bool {
|
||||||
h, err := c.Sha256Sum()
|
return ncp.isBlocklistedWithCache(c, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsBlocklisted returns true if the fingerprint fails to generate or has been explicitly blocklisted
|
||||||
|
func (ncp *NebulaCAPool) isBlocklistedWithCache(c *NebulaCertificate, useCache bool) bool {
|
||||||
|
h, err := c.sha256SumWithCache(useCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
72
cert/cert.go
72
cert/cert.go
@ -17,6 +17,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/curve25519"
|
"golang.org/x/crypto/curve25519"
|
||||||
@ -42,6 +43,14 @@ const (
|
|||||||
type NebulaCertificate struct {
|
type NebulaCertificate struct {
|
||||||
Details NebulaCertificateDetails
|
Details NebulaCertificateDetails
|
||||||
Signature []byte
|
Signature []byte
|
||||||
|
|
||||||
|
// the cached hex string of the calculated sha256sum
|
||||||
|
// for VerifyWithCache
|
||||||
|
sha256sum atomic.Pointer[string]
|
||||||
|
|
||||||
|
// the cached public key bytes if they were verified as the signer
|
||||||
|
// for VerifyWithCache
|
||||||
|
signatureVerified atomic.Pointer[[]byte]
|
||||||
}
|
}
|
||||||
|
|
||||||
type NebulaCertificateDetails struct {
|
type NebulaCertificateDetails struct {
|
||||||
@ -562,6 +571,27 @@ func (nc *NebulaCertificate) CheckSignature(key []byte) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This uses an internal cache that will not be invalidated automatically
|
||||||
|
// if you manually change any fields in the NebulaCertificate.
|
||||||
|
func (nc *NebulaCertificate) checkSignatureWithCache(key []byte, useCache bool) bool {
|
||||||
|
if !useCache {
|
||||||
|
return nc.CheckSignature(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v := nc.signatureVerified.Load(); v != nil {
|
||||||
|
return bytes.Equal(*v, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
verified := nc.CheckSignature(key)
|
||||||
|
if verified {
|
||||||
|
keyCopy := make([]byte, len(key))
|
||||||
|
copy(keyCopy, key)
|
||||||
|
nc.signatureVerified.Store(&keyCopy)
|
||||||
|
}
|
||||||
|
|
||||||
|
return verified
|
||||||
|
}
|
||||||
|
|
||||||
// Expired will return true if the nebula cert is too young or too old compared to the provided time, otherwise false
|
// Expired will return true if the nebula cert is too young or too old compared to the provided time, otherwise false
|
||||||
func (nc *NebulaCertificate) Expired(t time.Time) bool {
|
func (nc *NebulaCertificate) Expired(t time.Time) bool {
|
||||||
return nc.Details.NotBefore.After(t) || nc.Details.NotAfter.Before(t)
|
return nc.Details.NotBefore.After(t) || nc.Details.NotAfter.Before(t)
|
||||||
@ -569,7 +599,26 @@ func (nc *NebulaCertificate) Expired(t time.Time) bool {
|
|||||||
|
|
||||||
// Verify will ensure a certificate is good in all respects (expiry, group membership, signature, cert blocklist, etc)
|
// Verify will ensure a certificate is good in all respects (expiry, group membership, signature, cert blocklist, etc)
|
||||||
func (nc *NebulaCertificate) Verify(t time.Time, ncp *NebulaCAPool) (bool, error) {
|
func (nc *NebulaCertificate) Verify(t time.Time, ncp *NebulaCAPool) (bool, error) {
|
||||||
if ncp.IsBlocklisted(nc) {
|
return nc.verify(t, ncp, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyWithCache will ensure a certificate is good in all respects (expiry, group membership, signature, cert blocklist, etc)
|
||||||
|
//
|
||||||
|
// NOTE: This uses an internal cache that will not be invalidated automatically
|
||||||
|
// if you manually change any fields in the NebulaCertificate.
|
||||||
|
func (nc *NebulaCertificate) VerifyWithCache(t time.Time, ncp *NebulaCAPool) (bool, error) {
|
||||||
|
return nc.verify(t, ncp, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetCache resets the cache used by VerifyWithCache.
|
||||||
|
func (nc *NebulaCertificate) ResetCache() {
|
||||||
|
nc.sha256sum.Store(nil)
|
||||||
|
nc.signatureVerified.Store(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify will ensure a certificate is good in all respects (expiry, group membership, signature, cert blocklist, etc)
|
||||||
|
func (nc *NebulaCertificate) verify(t time.Time, ncp *NebulaCAPool, useCache bool) (bool, error) {
|
||||||
|
if ncp.isBlocklistedWithCache(nc, useCache) {
|
||||||
return false, ErrBlockListed
|
return false, ErrBlockListed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +635,7 @@ func (nc *NebulaCertificate) Verify(t time.Time, ncp *NebulaCAPool) (bool, error
|
|||||||
return false, ErrExpired
|
return false, ErrExpired
|
||||||
}
|
}
|
||||||
|
|
||||||
if !nc.CheckSignature(signer.Details.PublicKey) {
|
if !nc.checkSignatureWithCache(signer.Details.PublicKey, useCache) {
|
||||||
return false, ErrSignatureMismatch
|
return false, ErrSignatureMismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,6 +858,25 @@ func (nc *NebulaCertificate) Sha256Sum() (string, error) {
|
|||||||
return hex.EncodeToString(sum[:]), nil
|
return hex.EncodeToString(sum[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This uses an internal cache that will not be invalidated automatically
|
||||||
|
// if you manually change any fields in the NebulaCertificate.
|
||||||
|
func (nc *NebulaCertificate) sha256SumWithCache(useCache bool) (string, error) {
|
||||||
|
if !useCache {
|
||||||
|
return nc.Sha256Sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
if s := nc.sha256sum.Load(); s != nil {
|
||||||
|
return *s, nil
|
||||||
|
}
|
||||||
|
s, err := nc.Sha256Sum()
|
||||||
|
if err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nc.sha256sum.Store(&s)
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (nc *NebulaCertificate) MarshalJSON() ([]byte, error) {
|
func (nc *NebulaCertificate) MarshalJSON() ([]byte, error) {
|
||||||
toString := func(ips []*net.IPNet) []string {
|
toString := func(ips []*net.IPNet) []string {
|
||||||
s := []string{}
|
s := []string{}
|
||||||
|
|||||||
@ -427,7 +427,7 @@ func (n *connectionManager) isInvalidCertificate(now time.Time, hostinfo *HostIn
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
valid, err := remoteCert.Verify(now, n.intf.caPool)
|
valid, err := remoteCert.VerifyWithCache(now, n.intf.caPool)
|
||||||
if valid {
|
if valid {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user