remove old hmac function. superceded by ix_psk0

This commit is contained in:
Ryan Huber 2019-11-23 16:50:36 +00:00
parent ef324bf7e3
commit 6a460ba38b
5 changed files with 65 additions and 183 deletions

View File

@ -61,16 +61,6 @@ punchy: true
# path to a network adjacent nebula node. # path to a network adjacent nebula node.
#local_range: "172.16.0.0/24" #local_range: "172.16.0.0/24"
# Handshake mac is an optional network-wide handshake authentication step that is used to prevent nebula from
# responding to handshakes from nodes not in possession of the shared secret. This is primarily used to prevent
# detection of nebula nodes when someone is scanning a network.
#handshake_mac:
#key: "DONOTUSETHISKEY"
# You can define multiple accepted keys
#accepted_keys:
#- "DONOTUSETHISKEY"
#- "dontusethiseither"
# sshd can expose informational and administrative functions via ssh this is a # sshd can expose informational and administrative functions via ssh this is a
#sshd: #sshd:
# Toggles the feature # Toggles the feature

View File

@ -1,12 +1,5 @@
package nebula package nebula
import (
"crypto/hmac"
"crypto/sha256"
"errors"
"github.com/golang/protobuf/proto"
)
const ( const (
handshakeIXPSK0 = 0 handshakeIXPSK0 = 0
handshakeXXPSK0 = 1 handshakeXXPSK0 = 1
@ -36,47 +29,3 @@ func HandleIncomingHandshake(f *Interface, addr *udpAddr, packet []byte, h *Head
f.handshakeManager.DeleteVpnIP(newHostinfo.hostId) f.handshakeManager.DeleteVpnIP(newHostinfo.hostId)
} }
} }
func HandshakeBytesWithMAC(details *NebulaHandshakeDetails, key []byte) ([]byte, error) {
mac := hmac.New(sha256.New, key)
b, err := proto.Marshal(details)
if err != nil {
return nil, errors.New("Unable to marshal nebula handshake")
}
mac.Write(b)
sum := mac.Sum(nil)
hs := &NebulaHandshake{
Details: details,
Hmac: sum,
}
hsBytes, err := proto.Marshal(hs)
if err != nil {
l.Debugln("failed to generate NebulaHandshake protobuf", err)
}
return hsBytes, nil
}
func (hs *NebulaHandshake) CheckHandshakeMAC(keys [][]byte) bool {
b, err := proto.Marshal(hs.Details)
if err != nil {
return false
}
for _, k := range keys {
mac := hmac.New(sha256.New, k)
mac.Write(b)
expectedMAC := mac.Sum(nil)
if hmac.Equal(hs.Hmac, expectedMAC) {
return true
}
}
//l.Debugln(hs.Hmac, expectedMAC)
return false
}

View File

@ -41,13 +41,13 @@ func ixHandshakeStage0(f *Interface, vpnIp uint32, hostinfo *HostInfo) {
Cert: ci.certState.rawCertificateNoKey, Cert: ci.certState.rawCertificateNoKey,
} }
hsBytes := []byte{}
hs := &NebulaHandshake{ hs := &NebulaHandshake{
Details: hsProto, Details: hsProto,
Hmac: nil,
} }
hsBytes, err = proto.Marshal(hs)
hsBytes, err := proto.Marshal(hs)
//hsBytes, err := HandshakeBytesWithMAC(hsProto, f.handshakeMACKey)
if err != nil { if err != nil {
l.WithError(err).WithField("vpnIp", IntIp(vpnIp)). l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message") WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
@ -151,7 +151,6 @@ func ixHandshakeStage1(f *Interface, addr *udpAddr, hostinfo *HostInfo, packet [
hostinfo.remoteIndexId = hs.Details.InitiatorIndex hostinfo.remoteIndexId = hs.Details.InitiatorIndex
hs.Details.ResponderIndex = myIndex hs.Details.ResponderIndex = myIndex
hs.Details.Cert = ci.certState.rawCertificateNoKey hs.Details.Cert = ci.certState.rawCertificateNoKey
hs.Hmac = nil
hsBytes, err := proto.Marshal(hs) hsBytes, err := proto.Marshal(hs)
if err != nil { if err != nil {

View File

@ -1,57 +1,49 @@
package nebula package nebula
import ( import (
"crypto/sha256"
"errors" "errors"
"fmt"
"io"
"os" "os"
"time" "time"
"github.com/rcrowley/go-metrics" "github.com/rcrowley/go-metrics"
"golang.org/x/crypto/hkdf"
) )
const mtu = 9001 const mtu = 9001
type InterfaceConfig struct { type InterfaceConfig struct {
HostMap *HostMap HostMap *HostMap
Outside *udpConn Outside *udpConn
Inside *Tun Inside *Tun
certState *CertState certState *CertState
Cipher string Cipher string
Firewall *Firewall Firewall *Firewall
ServeDns bool ServeDns bool
HandshakeManager *HandshakeManager HandshakeManager *HandshakeManager
lightHouse *LightHouse lightHouse *LightHouse
checkInterval int checkInterval int
pendingDeletionInterval int pendingDeletionInterval int
handshakeMACKey string DropLocalBroadcast bool
handshakeAcceptedMACKeys []string DropMulticast bool
DropLocalBroadcast bool UDPBatchSize int
DropMulticast bool
UDPBatchSize int
} }
type Interface struct { type Interface struct {
hostMap *HostMap hostMap *HostMap
outside *udpConn outside *udpConn
inside *Tun inside *Tun
certState *CertState certState *CertState
cipher string cipher string
firewall *Firewall firewall *Firewall
connectionManager *connectionManager connectionManager *connectionManager
handshakeManager *HandshakeManager handshakeManager *HandshakeManager
serveDns bool serveDns bool
createTime time.Time createTime time.Time
lightHouse *LightHouse lightHouse *LightHouse
handshakeMACKey []byte localBroadcast uint32
handshakeAcceptedMACKeys [][]byte dropLocalBroadcast bool
localBroadcast uint32 dropMulticast bool
dropLocalBroadcast bool udpBatchSize int
dropMulticast bool version string
udpBatchSize int
version string
metricRxRecvError metrics.Counter metricRxRecvError metrics.Counter
metricTxRecvError metrics.Counter metricTxRecvError metrics.Counter
@ -72,54 +64,21 @@ func NewInterface(c *InterfaceConfig) (*Interface, error) {
return nil, errors.New("no firewall rules") return nil, errors.New("no firewall rules")
} }
// Use KDF to make this useful
hmacKey, err := sha256KdfFromString(c.handshakeMACKey)
if err != nil {
l.Debugln(err)
}
allowedMacs := make([][]byte, 0)
//allowedMacs = append(allowedMacs, mac)
if len(c.handshakeAcceptedMACKeys) > 0 {
for _, k := range c.handshakeAcceptedMACKeys {
// Use KDF to make these useful too
hmacKey, err := sha256KdfFromString(k)
if err != nil {
l.Debugln(err)
}
allowedMacs = append(allowedMacs, hmacKey)
}
} else {
if len(c.handshakeMACKey) > 0 {
l.Warnln("You have set an outgoing MAC but do not accept any incoming. This is probably not what you want.")
} else {
// This else is a fallback if we have not set any mac keys at all
hmacKey, err := sha256KdfFromString("")
if err != nil {
l.Debugln(err)
}
allowedMacs = append(allowedMacs, hmacKey)
}
}
ifce := &Interface{ ifce := &Interface{
hostMap: c.HostMap, hostMap: c.HostMap,
outside: c.Outside, outside: c.Outside,
inside: c.Inside, inside: c.Inside,
certState: c.certState, certState: c.certState,
cipher: c.Cipher, cipher: c.Cipher,
firewall: c.Firewall, firewall: c.Firewall,
serveDns: c.ServeDns, serveDns: c.ServeDns,
handshakeManager: c.HandshakeManager, handshakeManager: c.HandshakeManager,
createTime: time.Now(), createTime: time.Now(),
lightHouse: c.lightHouse, lightHouse: c.lightHouse,
handshakeMACKey: hmacKey, localBroadcast: ip2int(c.certState.certificate.Details.Ips[0].IP) | ^ip2int(c.certState.certificate.Details.Ips[0].Mask),
handshakeAcceptedMACKeys: allowedMacs, dropLocalBroadcast: c.DropLocalBroadcast,
localBroadcast: ip2int(c.certState.certificate.Details.Ips[0].IP) | ^ip2int(c.certState.certificate.Details.Ips[0].Mask), dropMulticast: c.DropMulticast,
dropLocalBroadcast: c.DropLocalBroadcast, udpBatchSize: c.UDPBatchSize,
dropMulticast: c.DropMulticast,
udpBatchSize: c.UDPBatchSize,
metricRxRecvError: metrics.GetOrRegisterCounter("messages.rx.recv_error", nil), metricRxRecvError: metrics.GetOrRegisterCounter("messages.rx.recv_error", nil),
metricTxRecvError: metrics.GetOrRegisterCounter("messages.tx.recv_error", nil), metricTxRecvError: metrics.GetOrRegisterCounter("messages.tx.recv_error", nil),
@ -261,17 +220,3 @@ func (f *Interface) emitStats(i time.Duration) {
f.handshakeManager.EmitStats() f.handshakeManager.EmitStats()
} }
} }
func sha256KdfFromString(secret string) ([]byte, error) {
// Use KDF to make this useful
mac := []byte(secret)
hmacKey := make([]byte, sha256.BlockSize)
hash := sha256.New
hkdfer := hkdf.New(hash, []byte(mac), nil, nil)
n, err := io.ReadFull(hkdfer, hmacKey)
if n != len(hmacKey) || err != nil {
l.Errorln("KDF Failed!")
return nil, fmt.Errorf("%s", err)
}
return hmacKey, nil
}

37
main.go
View File

@ -12,8 +12,8 @@ import (
"time" "time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/slackhq/nebula/sshd" "github.com/slackhq/nebula/sshd"
"gopkg.in/yaml.v2"
) )
var l = logrus.New() var l = logrus.New()
@ -238,28 +238,27 @@ func Main(configPath string, configTest bool, buildVersion string) {
handshakeManager := NewHandshakeManager(tunCidr, preferredRanges, hostMap, lightHouse, udpServer) handshakeManager := NewHandshakeManager(tunCidr, preferredRanges, hostMap, lightHouse, udpServer)
handshakeMACKey := config.GetString("handshake_mac.key", "") //TODO: These will be reused for psk
handshakeAcceptedMACKeys := config.GetStringSlice("handshake_mac.accepted_keys", []string{}) //handshakeMACKey := config.GetString("handshake_mac.key", "")
//handshakeAcceptedMACKeys := config.GetStringSlice("handshake_mac.accepted_keys", []string{})
checkInterval := config.GetInt("timers.connection_alive_interval", 5) checkInterval := config.GetInt("timers.connection_alive_interval", 5)
pendingDeletionInterval := config.GetInt("timers.pending_deletion_interval", 10) pendingDeletionInterval := config.GetInt("timers.pending_deletion_interval", 10)
ifConfig := &InterfaceConfig{ ifConfig := &InterfaceConfig{
HostMap: hostMap, HostMap: hostMap,
Inside: tun, Inside: tun,
Outside: udpServer, Outside: udpServer,
certState: cs, certState: cs,
Cipher: config.GetString("cipher", "aes"), Cipher: config.GetString("cipher", "aes"),
Firewall: fw, Firewall: fw,
ServeDns: serveDns, ServeDns: serveDns,
HandshakeManager: handshakeManager, HandshakeManager: handshakeManager,
lightHouse: lightHouse, lightHouse: lightHouse,
checkInterval: checkInterval, checkInterval: checkInterval,
pendingDeletionInterval: pendingDeletionInterval, pendingDeletionInterval: pendingDeletionInterval,
handshakeMACKey: handshakeMACKey, DropLocalBroadcast: config.GetBool("tun.drop_local_broadcast", false),
handshakeAcceptedMACKeys: handshakeAcceptedMACKeys, DropMulticast: config.GetBool("tun.drop_multicast", false),
DropLocalBroadcast: config.GetBool("tun.drop_local_broadcast", false), UDPBatchSize: config.GetInt("listen.batch", 64),
DropMulticast: config.GetBool("tun.drop_multicast", false),
UDPBatchSize: config.GetInt("listen.batch", 64),
} }
switch ifConfig.Cipher { switch ifConfig.Cipher {