diff options
8 files changed, 98 insertions, 35 deletions
diff --git a/common/minimal-distribution-parent/pom.xml b/common/minimal-distribution-parent/pom.xml index ac3931f4f..d1a62889c 100644 --- a/common/minimal-distribution-parent/pom.xml +++ b/common/minimal-distribution-parent/pom.xml @@ -87,7 +87,7 @@ <classpathMavenRepositoryLayout>true</classpathMavenRepositoryLayout> </manifest> <manifestEntries> - <Class-Path>config/</Class-Path> + <Class-Path>config/ cert/</Class-Path> </manifestEntries> </archive> </configuration> 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 Binary files differnew file mode 100644 index 000000000..27a263308 --- /dev/null +++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore 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 Binary files differnew file mode 100644 index 000000000..e2f4fdd82 --- /dev/null +++ b/infra/minimal-distribution/src/main/resources/honeycomb-minimal-resources/cert/honeycomb.pkcs12 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> |