Secure LLDP-based Topology Detection
Current LLDP/BDDP-based Topology Detection is vulnerable to the
creation of fake links via forged, modified, or replayed LLDP packets.
This patch fixes this vulnerability by authenticating LLDP/BDDP packets
using a Message Authentication Code and adding a timestamp to prevent
replay. We use HMAC with SHA-256 has our Messge Authentication Code and
derive the key from the config/cluster.json file via the
ClusterMetadata class.
Change-Id: I01dd6edc5cffd6dfe274bcdb97189f2661a6c4f1
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java b/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
index d5ef232..de7a3e1 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ConfigFileBasedClusterMetadataProvider.java
@@ -119,6 +119,7 @@
.stream()
.map(this::toPrototype)
.collect(Collectors.toSet()));
+ prototype.setClusterSecret(metadata.getClusterSecret());
return prototype;
}
@@ -274,7 +275,8 @@
metadata.getStorage()
.stream()
.map(node -> new DefaultControllerNode(getNodeId(node), getNodeHost(node), getNodePort(node)))
- .collect(Collectors.toSet())),
+ .collect(Collectors.toSet()),
+ metadata.getClusterSecret()),
version);
} catch (IOException e) {
throw new IllegalArgumentException(e);
@@ -307,6 +309,7 @@
private NodePrototype node;
private Set<NodePrototype> controller = Sets.newHashSet();
private Set<NodePrototype> storage = Sets.newHashSet();
+ private String clusterSecret;
public String getName() {
return name;
@@ -339,6 +342,14 @@
public void setStorage(Set<NodePrototype> storage) {
this.storage = storage;
}
+
+ public void setClusterSecret(String clusterSecret) {
+ this.clusterSecret = clusterSecret;
+ }
+
+ public String getClusterSecret() {
+ return clusterSecret;
+ }
}
private static class NodePrototype {
@@ -379,4 +390,4 @@
this.port = port;
}
}
-}
\ No newline at end of file
+}
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java b/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
index a6f24ae..35a56a8 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/DefaultClusterMetadataProvider.java
@@ -20,6 +20,7 @@
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.Set;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@@ -73,7 +74,8 @@
ControllerNode localNode =
new DefaultControllerNode(new NodeId(localIp), IpAddress.valueOf(localIp), DEFAULT_ONOS_PORT);
ClusterMetadata metadata = new ClusterMetadata(
- PROVIDER_ID, "default", localNode, ImmutableSet.of(), ImmutableSet.of());
+ PROVIDER_ID, "default", localNode, ImmutableSet.of(), ImmutableSet.of(),
+ UUID.randomUUID().toString());
long version = System.currentTimeMillis();
cachedMetadata.set(new Versioned<>(metadata, version));
providerRegistry.register(this);