Committed by
Gerrit Code Review
securing the openflow channel
Change-Id: Ifae379e7e372baeb14a4ad919f014c64752c3a7f
Showing
2 changed files
with
95 additions
and
2 deletions
... | @@ -39,9 +39,15 @@ import org.projectfloodlight.openflow.protocol.OFVersion; | ... | @@ -39,9 +39,15 @@ import org.projectfloodlight.openflow.protocol.OFVersion; |
39 | import org.slf4j.Logger; | 39 | import org.slf4j.Logger; |
40 | import org.slf4j.LoggerFactory; | 40 | import org.slf4j.LoggerFactory; |
41 | 41 | ||
42 | +import javax.net.ssl.KeyManagerFactory; | ||
43 | +import javax.net.ssl.SSLContext; | ||
44 | +import javax.net.ssl.SSLEngine; | ||
45 | +import javax.net.ssl.TrustManagerFactory; | ||
46 | +import java.io.FileInputStream; | ||
42 | import java.lang.management.ManagementFactory; | 47 | import java.lang.management.ManagementFactory; |
43 | import java.lang.management.RuntimeMXBean; | 48 | import java.lang.management.RuntimeMXBean; |
44 | import java.net.InetSocketAddress; | 49 | import java.net.InetSocketAddress; |
50 | +import java.security.KeyStore; | ||
45 | import java.util.Dictionary; | 51 | import java.util.Dictionary; |
46 | import java.util.HashMap; | 52 | import java.util.HashMap; |
47 | import java.util.List; | 53 | import java.util.List; |
... | @@ -66,6 +72,8 @@ public class Controller { | ... | @@ -66,6 +72,8 @@ public class Controller { |
66 | 72 | ||
67 | protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13); | 73 | protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13); |
68 | protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10); | 74 | protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10); |
75 | + private static final boolean TLS_DISABLED = false; | ||
76 | + private static final short MIN_KS_LENGTH = 6; | ||
69 | 77 | ||
70 | protected HashMap<String, String> controllerNodeIPsCache; | 78 | protected HashMap<String, String> controllerNodeIPsCache; |
71 | 79 | ||
... | @@ -82,9 +90,16 @@ public class Controller { | ... | @@ -82,9 +90,16 @@ public class Controller { |
82 | 90 | ||
83 | private NioServerSocketChannelFactory execFactory; | 91 | private NioServerSocketChannelFactory execFactory; |
84 | 92 | ||
93 | + protected String ksLocation; | ||
94 | + protected String tsLocation; | ||
95 | + protected char[] ksPwd; | ||
96 | + protected char[] tsPwd; | ||
97 | + private SSLEngine serverSSLEngine; | ||
98 | + | ||
85 | // Perf. related configuration | 99 | // Perf. related configuration |
86 | protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; | 100 | protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024; |
87 | private DriverService driverService; | 101 | private DriverService driverService; |
102 | + private boolean enableOFTLS = TLS_DISABLED; | ||
88 | 103 | ||
89 | // *************** | 104 | // *************** |
90 | // Getters/Setters | 105 | // Getters/Setters |
... | @@ -134,7 +149,7 @@ public class Controller { | ... | @@ -134,7 +149,7 @@ public class Controller { |
134 | bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); | 149 | bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE); |
135 | 150 | ||
136 | ChannelPipelineFactory pfact = | 151 | ChannelPipelineFactory pfact = |
137 | - new OpenflowPipelineFactory(this, null); | 152 | + new OpenflowPipelineFactory(this, null, serverSSLEngine); |
138 | bootstrap.setPipelineFactory(pfact); | 153 | bootstrap.setPipelineFactory(pfact); |
139 | cg = new DefaultChannelGroup(); | 154 | cg = new DefaultChannelGroup(); |
140 | openFlowPorts.forEach(port -> { | 155 | openFlowPorts.forEach(port -> { |
... | @@ -189,6 +204,68 @@ public class Controller { | ... | @@ -189,6 +204,68 @@ public class Controller { |
189 | this.controllerNodeIPsCache = new HashMap<>(); | 204 | this.controllerNodeIPsCache = new HashMap<>(); |
190 | 205 | ||
191 | this.systemStartTime = System.currentTimeMillis(); | 206 | this.systemStartTime = System.currentTimeMillis(); |
207 | + | ||
208 | + try { | ||
209 | + getTLSParameters(); | ||
210 | + if (enableOFTLS) { | ||
211 | + initSSL(); | ||
212 | + } | ||
213 | + } catch (Exception ex) { | ||
214 | + log.error("SSL init failed: {}", ex.getMessage()); | ||
215 | + } | ||
216 | + | ||
217 | + } | ||
218 | + | ||
219 | + private void getTLSParameters() { | ||
220 | + String tempString = System.getProperty("enableOFTLS"); | ||
221 | + enableOFTLS = Strings.isNullOrEmpty(tempString) ? TLS_DISABLED : Boolean.parseBoolean(tempString); | ||
222 | + log.info("OpenFlow Security is {}", enableOFTLS ? "enabled" : "disabled"); | ||
223 | + if (enableOFTLS) { | ||
224 | + ksLocation = System.getProperty("javax.net.ssl.keyStore"); | ||
225 | + if (Strings.isNullOrEmpty(ksLocation)) { | ||
226 | + enableOFTLS = TLS_DISABLED; | ||
227 | + return; | ||
228 | + } | ||
229 | + tsLocation = System.getProperty("javax.net.ssl.trustStore"); | ||
230 | + if (Strings.isNullOrEmpty(tsLocation)) { | ||
231 | + enableOFTLS = TLS_DISABLED; | ||
232 | + return; | ||
233 | + } | ||
234 | + ksPwd = System.getProperty("javax.net.ssl.keyStorePassword").toCharArray(); | ||
235 | + if (MIN_KS_LENGTH > ksPwd.length) { | ||
236 | + enableOFTLS = TLS_DISABLED; | ||
237 | + return; | ||
238 | + } | ||
239 | + tsPwd = System.getProperty("javax.net.ssl.trustStorePassword").toCharArray(); | ||
240 | + if (MIN_KS_LENGTH > tsPwd.length) { | ||
241 | + enableOFTLS = TLS_DISABLED; | ||
242 | + return; | ||
243 | + } | ||
244 | + } | ||
245 | + } | ||
246 | + | ||
247 | + private void initSSL() throws Exception { | ||
248 | + | ||
249 | + TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||
250 | + KeyStore ts = KeyStore.getInstance("JKS"); | ||
251 | + ts.load(new FileInputStream(tsLocation), tsPwd); | ||
252 | + tmFactory.init(ts); | ||
253 | + | ||
254 | + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); | ||
255 | + KeyStore ks = KeyStore.getInstance("JKS"); | ||
256 | + ks.load(new FileInputStream(ksLocation), ksPwd); | ||
257 | + kmf.init(ks, ksPwd); | ||
258 | + | ||
259 | + SSLContext serverContext = SSLContext.getInstance("TLS"); | ||
260 | + serverContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null); | ||
261 | + | ||
262 | + serverSSLEngine = serverContext.createSSLEngine(); | ||
263 | + | ||
264 | + serverSSLEngine.setNeedClientAuth(true); | ||
265 | + serverSSLEngine.setUseClientMode(false); | ||
266 | + serverSSLEngine.setEnabledProtocols(serverSSLEngine.getSupportedProtocols()); | ||
267 | + serverSSLEngine.setEnabledCipherSuites(serverSSLEngine.getSupportedCipherSuites()); | ||
268 | + serverSSLEngine.setEnableSessionCreation(true); | ||
192 | } | 269 | } |
193 | 270 | ||
194 | // ************** | 271 | // ************** | ... | ... |
... | @@ -27,6 +27,10 @@ import org.jboss.netty.handler.timeout.ReadTimeoutHandler; | ... | @@ -27,6 +27,10 @@ import org.jboss.netty.handler.timeout.ReadTimeoutHandler; |
27 | import org.jboss.netty.util.ExternalResourceReleasable; | 27 | import org.jboss.netty.util.ExternalResourceReleasable; |
28 | import org.jboss.netty.util.HashedWheelTimer; | 28 | import org.jboss.netty.util.HashedWheelTimer; |
29 | import org.jboss.netty.util.Timer; | 29 | import org.jboss.netty.util.Timer; |
30 | +import org.slf4j.Logger; | ||
31 | +import org.slf4j.LoggerFactory; | ||
32 | + | ||
33 | +import javax.net.ssl.SSLEngine; | ||
30 | 34 | ||
31 | /** | 35 | /** |
32 | * Creates a ChannelPipeline for a server-side openflow channel. | 36 | * Creates a ChannelPipeline for a server-side openflow channel. |
... | @@ -34,6 +38,9 @@ import org.jboss.netty.util.Timer; | ... | @@ -34,6 +38,9 @@ import org.jboss.netty.util.Timer; |
34 | public class OpenflowPipelineFactory | 38 | public class OpenflowPipelineFactory |
35 | implements ChannelPipelineFactory, ExternalResourceReleasable { | 39 | implements ChannelPipelineFactory, ExternalResourceReleasable { |
36 | 40 | ||
41 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
42 | + | ||
43 | + private final SSLEngine sslEngine; | ||
37 | protected Controller controller; | 44 | protected Controller controller; |
38 | protected ThreadPoolExecutor pipelineExecutor; | 45 | protected ThreadPoolExecutor pipelineExecutor; |
39 | protected Timer timer; | 46 | protected Timer timer; |
... | @@ -41,13 +48,15 @@ public class OpenflowPipelineFactory | ... | @@ -41,13 +48,15 @@ public class OpenflowPipelineFactory |
41 | protected ReadTimeoutHandler readTimeoutHandler; | 48 | protected ReadTimeoutHandler readTimeoutHandler; |
42 | 49 | ||
43 | public OpenflowPipelineFactory(Controller controller, | 50 | public OpenflowPipelineFactory(Controller controller, |
44 | - ThreadPoolExecutor pipelineExecutor) { | 51 | + ThreadPoolExecutor pipelineExecutor, |
52 | + SSLEngine sslEngine) { | ||
45 | super(); | 53 | super(); |
46 | this.controller = controller; | 54 | this.controller = controller; |
47 | this.pipelineExecutor = pipelineExecutor; | 55 | this.pipelineExecutor = pipelineExecutor; |
48 | this.timer = new HashedWheelTimer(); | 56 | this.timer = new HashedWheelTimer(); |
49 | this.idleHandler = new IdleStateHandler(timer, 20, 25, 0); | 57 | this.idleHandler = new IdleStateHandler(timer, 20, 25, 0); |
50 | this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30); | 58 | this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30); |
59 | + this.sslEngine = sslEngine; | ||
51 | } | 60 | } |
52 | 61 | ||
53 | @Override | 62 | @Override |
... | @@ -55,6 +64,13 @@ public class OpenflowPipelineFactory | ... | @@ -55,6 +64,13 @@ public class OpenflowPipelineFactory |
55 | OFChannelHandler handler = new OFChannelHandler(controller); | 64 | OFChannelHandler handler = new OFChannelHandler(controller); |
56 | 65 | ||
57 | ChannelPipeline pipeline = Channels.pipeline(); | 66 | ChannelPipeline pipeline = Channels.pipeline(); |
67 | + if (sslEngine != null) { | ||
68 | + log.info("OpenFlow SSL enabled."); | ||
69 | + pipeline.addLast("ssl", | ||
70 | + new org.jboss.netty.handler.ssl.SslHandler(sslEngine)); | ||
71 | + } else { | ||
72 | + log.info("OpenFlow SSL disabled"); | ||
73 | + } | ||
58 | pipeline.addLast("ofmessagedecoder", new OFMessageDecoder()); | 74 | pipeline.addLast("ofmessagedecoder", new OFMessageDecoder()); |
59 | pipeline.addLast("ofmessageencoder", new OFMessageEncoder()); | 75 | pipeline.addLast("ofmessageencoder", new OFMessageEncoder()); |
60 | pipeline.addLast("idle", idleHandler); | 76 | pipeline.addLast("idle", idleHandler); | ... | ... |
-
Please register or login to post a comment