diff --git a/examples/config.yaml b/examples/config.yaml index d339fa4..995971f 100644 --- a/examples/config.yaml +++ b/examples/config.yaml @@ -61,16 +61,6 @@ punchy: true # path to a network adjacent nebula node. #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: # Toggles the feature diff --git a/handshake.go b/handshake.go index 9836f83..c9cf6e2 100644 --- a/handshake.go +++ b/handshake.go @@ -1,12 +1,5 @@ package nebula -import ( - "crypto/hmac" - "crypto/sha256" - "errors" - "github.com/golang/protobuf/proto" -) - const ( handshakeIXPSK0 = 0 handshakeXXPSK0 = 1 @@ -36,47 +29,3 @@ func HandleIncomingHandshake(f *Interface, addr *udpAddr, packet []byte, h *Head 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 -} diff --git a/handshake_ix.go b/handshake_ix.go index 2eaabc3..19cbdb6 100644 --- a/handshake_ix.go +++ b/handshake_ix.go @@ -41,13 +41,13 @@ func ixHandshakeStage0(f *Interface, vpnIp uint32, hostinfo *HostInfo) { Cert: ci.certState.rawCertificateNoKey, } + hsBytes := []byte{} + hs := &NebulaHandshake{ Details: hsProto, - Hmac: nil, } + hsBytes, err = proto.Marshal(hs) - hsBytes, err := proto.Marshal(hs) - //hsBytes, err := HandshakeBytesWithMAC(hsProto, f.handshakeMACKey) if err != nil { l.WithError(err).WithField("vpnIp", IntIp(vpnIp)). 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 hs.Details.ResponderIndex = myIndex hs.Details.Cert = ci.certState.rawCertificateNoKey - hs.Hmac = nil hsBytes, err := proto.Marshal(hs) if err != nil { diff --git a/interface.go b/interface.go index 2cbb776..9324e2c 100644 --- a/interface.go +++ b/interface.go @@ -1,57 +1,49 @@ package nebula import ( - "crypto/sha256" "errors" - "fmt" - "io" "os" "time" "github.com/rcrowley/go-metrics" - "golang.org/x/crypto/hkdf" ) const mtu = 9001 type InterfaceConfig struct { - HostMap *HostMap - Outside *udpConn - Inside *Tun - certState *CertState - Cipher string - Firewall *Firewall - ServeDns bool - HandshakeManager *HandshakeManager - lightHouse *LightHouse - checkInterval int - pendingDeletionInterval int - handshakeMACKey string - handshakeAcceptedMACKeys []string - DropLocalBroadcast bool - DropMulticast bool - UDPBatchSize int + HostMap *HostMap + Outside *udpConn + Inside *Tun + certState *CertState + Cipher string + Firewall *Firewall + ServeDns bool + HandshakeManager *HandshakeManager + lightHouse *LightHouse + checkInterval int + pendingDeletionInterval int + DropLocalBroadcast bool + DropMulticast bool + UDPBatchSize int } type Interface struct { - hostMap *HostMap - outside *udpConn - inside *Tun - certState *CertState - cipher string - firewall *Firewall - connectionManager *connectionManager - handshakeManager *HandshakeManager - serveDns bool - createTime time.Time - lightHouse *LightHouse - handshakeMACKey []byte - handshakeAcceptedMACKeys [][]byte - localBroadcast uint32 - dropLocalBroadcast bool - dropMulticast bool - udpBatchSize int - version string + hostMap *HostMap + outside *udpConn + inside *Tun + certState *CertState + cipher string + firewall *Firewall + connectionManager *connectionManager + handshakeManager *HandshakeManager + serveDns bool + createTime time.Time + lightHouse *LightHouse + localBroadcast uint32 + dropLocalBroadcast bool + dropMulticast bool + udpBatchSize int + version string metricRxRecvError metrics.Counter metricTxRecvError metrics.Counter @@ -72,54 +64,21 @@ func NewInterface(c *InterfaceConfig) (*Interface, error) { 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{ - hostMap: c.HostMap, - outside: c.Outside, - inside: c.Inside, - certState: c.certState, - cipher: c.Cipher, - firewall: c.Firewall, - serveDns: c.ServeDns, - handshakeManager: c.HandshakeManager, - createTime: time.Now(), - lightHouse: c.lightHouse, - handshakeMACKey: hmacKey, - handshakeAcceptedMACKeys: allowedMacs, - localBroadcast: ip2int(c.certState.certificate.Details.Ips[0].IP) | ^ip2int(c.certState.certificate.Details.Ips[0].Mask), - dropLocalBroadcast: c.DropLocalBroadcast, - dropMulticast: c.DropMulticast, - udpBatchSize: c.UDPBatchSize, + hostMap: c.HostMap, + outside: c.Outside, + inside: c.Inside, + certState: c.certState, + cipher: c.Cipher, + firewall: c.Firewall, + serveDns: c.ServeDns, + handshakeManager: c.HandshakeManager, + createTime: time.Now(), + lightHouse: c.lightHouse, + localBroadcast: ip2int(c.certState.certificate.Details.Ips[0].IP) | ^ip2int(c.certState.certificate.Details.Ips[0].Mask), + dropLocalBroadcast: c.DropLocalBroadcast, + dropMulticast: c.DropMulticast, + udpBatchSize: c.UDPBatchSize, metricRxRecvError: metrics.GetOrRegisterCounter("messages.rx.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() } } - -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 -} diff --git a/main.go b/main.go index 1e9dc59..ab23331 100644 --- a/main.go +++ b/main.go @@ -12,8 +12,8 @@ import ( "time" "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" "github.com/slackhq/nebula/sshd" + "gopkg.in/yaml.v2" ) var l = logrus.New() @@ -238,28 +238,27 @@ func Main(configPath string, configTest bool, buildVersion string) { handshakeManager := NewHandshakeManager(tunCidr, preferredRanges, hostMap, lightHouse, udpServer) - handshakeMACKey := config.GetString("handshake_mac.key", "") - handshakeAcceptedMACKeys := config.GetStringSlice("handshake_mac.accepted_keys", []string{}) + //TODO: These will be reused for psk + //handshakeMACKey := config.GetString("handshake_mac.key", "") + //handshakeAcceptedMACKeys := config.GetStringSlice("handshake_mac.accepted_keys", []string{}) checkInterval := config.GetInt("timers.connection_alive_interval", 5) pendingDeletionInterval := config.GetInt("timers.pending_deletion_interval", 10) ifConfig := &InterfaceConfig{ - HostMap: hostMap, - Inside: tun, - Outside: udpServer, - certState: cs, - Cipher: config.GetString("cipher", "aes"), - Firewall: fw, - ServeDns: serveDns, - HandshakeManager: handshakeManager, - lightHouse: lightHouse, - checkInterval: checkInterval, - pendingDeletionInterval: pendingDeletionInterval, - handshakeMACKey: handshakeMACKey, - handshakeAcceptedMACKeys: handshakeAcceptedMACKeys, - DropLocalBroadcast: config.GetBool("tun.drop_local_broadcast", false), - DropMulticast: config.GetBool("tun.drop_multicast", false), - UDPBatchSize: config.GetInt("listen.batch", 64), + HostMap: hostMap, + Inside: tun, + Outside: udpServer, + certState: cs, + Cipher: config.GetString("cipher", "aes"), + Firewall: fw, + ServeDns: serveDns, + HandshakeManager: handshakeManager, + lightHouse: lightHouse, + checkInterval: checkInterval, + pendingDeletionInterval: pendingDeletionInterval, + DropLocalBroadcast: config.GetBool("tun.drop_local_broadcast", false), + DropMulticast: config.GetBool("tun.drop_multicast", false), + UDPBatchSize: config.GetInt("listen.batch", 64), } switch ifConfig.Cipher {