summaryrefslogtreecommitdiffstats
path: root/infra/minimal-distribution/src/main
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-08-17 11:47:46 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-08-19 12:49:56 +0200
commit672f0c90fdbf4b5dc60cbfaaaf262e16561fdb7a (patch)
treee6787fafc90f4b19ee387b1a16f1eaf8adfbe715 /infra/minimal-distribution/src/main
parent77fa76b4b15ec6d74920349f9a066ec4597b2585 (diff)
HONEYCOMB-21 Add HTTPS for Restconf
Change-Id: If8bae91ce30592971584645b8dcecdbbeb4a0ddb Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'infra/minimal-distribution/src/main')
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy10
-rw-r--r--infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy92
-rw-r--r--infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystorebin0 -> 2296 bytes
-rw-r--r--infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb.pkcs12bin0 -> 2549 bytes
-rw-r--r--infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml21
-rw-r--r--infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json3
-rw-r--r--infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/logback.xml5
7 files changed, 97 insertions, 34 deletions
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
index 78a1a04fd..422c84435 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.groovy
@@ -41,10 +41,16 @@ class HoneycombConfiguration {
int notificationServiceQueueDepth
// RESTCONF
- @InjectConfig("restconf-websocket-port")
- int restconfWebsocketPort
+ @InjectConfig("restconf-binding-address")
+ String restconfBindingAddress
@InjectConfig("restconf-port")
int restconfPort
+ @InjectConfig("restconf-https-binding-address")
+ String restconfHttpsBindingAddress
+ @InjectConfig("restconf-https-port")
+ int restconfHttpsPort
+ @InjectConfig("restconf-websocket-port")
+ int restconfWebsocketPort
@InjectConfig("restconf-root-path")
String restconfRootPath
diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
index ff96f4e86..bffe1da1a 100644
--- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
+++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/restconf/RestconfProvider.groovy
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2016 Cisco and/or its affiliates.
*
- * Licensed under the Apache License, Version 2.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
@@ -21,7 +21,18 @@ import groovy.transform.ToString
import groovy.util.logging.Slf4j
import io.fd.honeycomb.infra.distro.ProviderTrait
import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration
+import org.eclipse.jetty.http.HttpVersion
+import org.eclipse.jetty.security.ConstraintMapping
+import org.eclipse.jetty.security.ConstraintSecurityHandler
+import org.eclipse.jetty.security.HashLoginService
+import org.eclipse.jetty.security.authentication.BasicAuthenticator
+import org.eclipse.jetty.server.HttpConnectionFactory
import org.eclipse.jetty.server.Server
+import org.eclipse.jetty.server.ServerConnector
+import org.eclipse.jetty.server.SslConnectionFactory
+import org.eclipse.jetty.util.security.Constraint
+import org.eclipse.jetty.util.security.Password
+import org.eclipse.jetty.util.ssl.SslContextFactory
import org.eclipse.jetty.webapp.WebAppContext
import org.opendaylight.controller.sal.core.api.Broker
import org.opendaylight.netconf.sal.rest.api.RestConnector
@@ -32,6 +43,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
@ToString
class RestconfProvider extends ProviderTrait<RestConnector> {
+ public static final String KEYSTORE_PASSWORD = "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u"
+ public static final String KEYSTORE_NAME = "/honeycomb-keystore"
+ public static final String REALM = "HCRealm"
+
@Inject
HoneycombConfiguration cfg
@@ -39,17 +54,60 @@ class RestconfProvider extends ProviderTrait<RestConnector> {
Broker domBroker
def create() {
- RestconfProviderImpl instance = new RestconfProviderImpl()
+ def instance = new RestconfProviderImpl()
instance.setWebsocketPort(new PortNumber(cfg.restconfWebsocketPort))
domBroker.registerProvider(instance)
- Server server = new Server(cfg.restconfPort);
- final URL resource = getClass().getResource("/");
- WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath);
- server.setHandler(webapp);
+ def server = new Server(InetSocketAddress.createUnresolved(cfg.restconfBindingAddress, cfg.restconfPort))
+
+ // Load Realm for basic auth
+ def service = new HashLoginService(REALM)
+ // Reusing the name as role
+ // TODO make this more configurable
+ service.putUser(cfg.username, new Password(cfg.password), cfg.username)
+ server.addBean(service)
+
+ final URL resource = getClass().getResource("/")
+ WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath)
+
+ ConstraintSecurityHandler security = getBaseAuth(service, webapp)
+ server.setHandler(security)
+
+ // SSL Context Factory
+ // Based on:
+ // https://github.com/eclipse/jetty.project/blob/jetty-9.3.x/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+ // https://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Loading_Keys_and_Certificates_via_PKCS12
+ // Keystore created with:
+ // openssl genrsa -des3 -out honeycomb.key
+ // openssl req -new -x509 -key honeycomb.key -out honeycomb.crt
+ // openssl pkcs12 -inkey honeycomb.key -in honeycomb.crt -export -out honeycomb.pkcs12
+ // keytool -importkeystore -srckeystore honeycomb.pkcs12 -srcstoretype PKCS12 -destkeystore honeycomb-keystore
+ def sslContextFactory = new SslContextFactory()
+ def keystoreURL = getClass().getResource(KEYSTORE_NAME)
+ sslContextFactory.setKeyStorePath(keystoreURL.path)
+ sslContextFactory.setKeyStorePassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setKeyManagerPassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setTrustStorePath(keystoreURL.path)
+ sslContextFactory.setTrustStorePassword(KEYSTORE_PASSWORD)
+ sslContextFactory.setExcludeCipherSuites(
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA")
+
+ // SSL Connector
+ def sslConnector = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+ new HttpConnectionFactory())
+ sslConnector.setHost(cfg.restconfHttpsBindingAddress)
+ sslConnector.setPort(cfg.restconfHttpsPort)
+ server.addConnector(sslConnector)
try {
- server.start();
+ server.start()
} catch (Exception e) {
log.error "Unable to start Restconf", e
throw new RuntimeException("Unable to start Restconf", e)
@@ -57,4 +115,24 @@ class RestconfProvider extends ProviderTrait<RestConnector> {
return instance
}
+
+ private ConstraintSecurityHandler getBaseAuth(HashLoginService service, WebAppContext webapp) {
+ ConstraintSecurityHandler security = new ConstraintSecurityHandler()
+
+ Constraint constraint = new Constraint()
+ constraint.setName("auth")
+ constraint.setAuthenticate(true)
+ constraint.setRoles(cfg.username)
+
+ ConstraintMapping mapping = new ConstraintMapping()
+ mapping.setPathSpec("/*")
+ mapping.setConstraint(constraint)
+
+ security.setConstraintMappings(Collections.singletonList(mapping))
+ security.setAuthenticator(new BasicAuthenticator())
+ security.setLoginService(service)
+
+ security.setHandler(webapp)
+ security
+ }
}
diff --git a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore
new file mode 100644
index 000000000..27a263308
--- /dev/null
+++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore
Binary files differ
diff --git a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb.pkcs12 b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb.pkcs12
new file mode 100644
index 000000000..e2f4fdd82
--- /dev/null
+++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb.pkcs12
Binary files differ
diff --git a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml
index 4a4adfbd8..7e59a1a7d 100644
--- a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml
+++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml
@@ -29,27 +29,6 @@
<load-on-startup>1</load-on-startup>
</servlet>
- <!-- FIXME-minimal configure SHIRO -->
- <!-- FIXME-minimal configure https -->
- <!--<context-param>-->
- <!--<param-name>shiroEnvironmentClass</param-name>-->
- <!--<param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>-->
- <!--</context-param>-->
-
- <!--<listener>-->
- <!--<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>-->
- <!--</listener>-->
-
- <!--<filter>-->
- <!--<filter-name>ShiroFilter</filter-name>-->
- <!--<filter-class>org.opendaylight.aaa.shiro.filters.AAAFilter</filter-class>-->
- <!--</filter>-->
-
- <!--<filter-mapping>-->
- <!--<filter-name>ShiroFilter</filter-name>-->
- <!--<url-pattern>/*</url-pattern>-->
- <!--</filter-mapping>-->
-
<servlet-mapping>
<servlet-name>JAXRSRestconf</servlet-name>
<url-pattern>/*</url-pattern>
diff --git a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json
index 606f44d8a..fdfb57f9a 100644
--- a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json
+++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json
@@ -7,7 +7,10 @@
"notification-service-queue-depth": 1,
"restconf-root-path": "/restconf",
+ "restconf-binding-address": "127.0.0.1",
"restconf-port": 8181,
+ "restconf-https-binding-address": "0.0.0.0",
+ "restconf-https-port": 8443,
"restconf-websocket-port": 7779,
"netconf-netty-threads": 2,
diff --git a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/logback.xml b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/logback.xml
index d3cdd6f1e..6dd4d4fc0 100644
--- a/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/logback.xml
+++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/logback.xml
@@ -22,14 +22,11 @@
</encoder>
</appender>
- <root level="error">
+ <root level="warn">
<appender-ref ref="STDOUT" />
<appender-ref ref="honeycomb.log" />
</root>
<logger name="org.opendaylight" level="INFO"/>
<logger name="io.fd" level="INFO"/>
-
- <!-- Netty -->
- <logger name="io.netty" level="WARN"/>
</configuration>