Always disconnect block listed hosts (#858)

This commit is contained in:
Nate Brown 2023-05-04 16:09:42 -05:00 committed by GitHub
parent 5fe8f45d05
commit 702e1c59bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 14 deletions

View file

@ -393,7 +393,7 @@ 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) { if ncp.IsBlocklisted(nc) {
return false, fmt.Errorf("certificate has been blocked") return false, ErrBlockListed
} }
signer, err := ncp.GetCAForCert(nc) signer, err := ncp.GetCAForCert(nc)
@ -402,15 +402,15 @@ func (nc *NebulaCertificate) Verify(t time.Time, ncp *NebulaCAPool) (bool, error
} }
if signer.Expired(t) { if signer.Expired(t) {
return false, fmt.Errorf("root certificate is expired") return false, ErrRootExpired
} }
if nc.Expired(t) { if nc.Expired(t) {
return false, fmt.Errorf("certificate is expired") return false, ErrExpired
} }
if !nc.CheckSignature(signer.Details.PublicKey) { if !nc.CheckSignature(signer.Details.PublicKey) {
return false, fmt.Errorf("certificate signature did not match") return false, ErrSignatureMismatch
} }
if err := nc.CheckRootConstrains(signer); err != nil { if err := nc.CheckRootConstrains(signer); err != nil {

View file

@ -177,7 +177,7 @@ func TestNebulaCertificate_Verify(t *testing.T) {
v, err := c.Verify(time.Now(), caPool) v, err := c.Verify(time.Now(), caPool)
assert.False(t, v) assert.False(t, v)
assert.EqualError(t, err, "certificate has been blocked") assert.EqualError(t, err, "certificate is in the block list")
caPool.ResetCertBlocklist() caPool.ResetCertBlocklist()
v, err = c.Verify(time.Now(), caPool) v, err = c.Verify(time.Now(), caPool)

View file

@ -1,9 +1,14 @@
package cert package cert
import "errors" import (
"errors"
)
var ( var (
ErrExpired = errors.New("certificate is expired") ErrRootExpired = errors.New("root certificate is expired")
ErrNotCA = errors.New("certificate is not a CA") ErrExpired = errors.New("certificate is expired")
ErrNotSelfSigned = errors.New("certificate is not self-signed") ErrNotCA = errors.New("certificate is not a CA")
ErrNotSelfSigned = errors.New("certificate is not self-signed")
ErrBlockListed = errors.New("certificate is in the block list")
ErrSignatureMismatch = errors.New("certificate signature did not match")
) )

View file

@ -8,6 +8,7 @@ import (
"github.com/rcrowley/go-metrics" "github.com/rcrowley/go-metrics"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/slackhq/nebula/cert"
"github.com/slackhq/nebula/header" "github.com/slackhq/nebula/header"
"github.com/slackhq/nebula/iputil" "github.com/slackhq/nebula/iputil"
"github.com/slackhq/nebula/udp" "github.com/slackhq/nebula/udp"
@ -419,12 +420,9 @@ func (n *connectionManager) swapPrimary(current, primary *HostInfo) {
} }
// isInvalidCertificate will check if we should destroy a tunnel if pki.disconnect_invalid is true and // isInvalidCertificate will check if we should destroy a tunnel if pki.disconnect_invalid is true and
// the certificate is no longer valid // the certificate is no longer valid. Block listed certificates will skip the pki.disconnect_invalid
// check and return true.
func (n *connectionManager) isInvalidCertificate(now time.Time, hostinfo *HostInfo) bool { func (n *connectionManager) isInvalidCertificate(now time.Time, hostinfo *HostInfo) bool {
if !n.intf.disconnectInvalid {
return false
}
remoteCert := hostinfo.GetCert() remoteCert := hostinfo.GetCert()
if remoteCert == nil { if remoteCert == nil {
return false return false
@ -435,6 +433,11 @@ func (n *connectionManager) isInvalidCertificate(now time.Time, hostinfo *HostIn
return false return false
} }
if !n.intf.disconnectInvalid && err != cert.ErrBlockListed {
// Block listed certificates should always be disconnected
return false
}
fingerprint, _ := remoteCert.Sha256Sum() fingerprint, _ := remoteCert.Sha256Sum()
hostinfo.logger(n.l).WithError(err). hostinfo.logger(n.l).WithError(err).
WithField("fingerprint", fingerprint). WithField("fingerprint", fingerprint).