SONAR-6139 Upgrade Tomcat from 7.0.54 to 8.0.18

SONAR-6141 apply Mozilla recommandations for default ciphers (Intermediate Compatibility)
This commit is contained in:
Simon Brandhof 2015-02-01 20:03:19 +01:00
parent b50745d4f8
commit dc222394a1
8 changed files with 60 additions and 46 deletions

View File

@ -74,7 +74,7 @@
<jetty.version>8.1.12.v20130726</jetty.version>
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<tomcat.version>7.0.57</tomcat.version>
<tomcat.version>8.0.18</tomcat.version>
<elasticsearch.version>1.4.2</elasticsearch.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.min.version>3.0.5</maven.min.version>

View File

@ -37,15 +37,25 @@ import java.util.Set;
*/
class Connectors {
private static final int DISABLED_PORT = -1;
static final String HTTP_PROTOCOL = "HTTP/1.1";
static final String AJP_PROTOCOL = "AJP/1.3";
public static final String PROP_HTTPS_CIPHERS = "sonar.web.https.ciphers";
/**
* Removes the weak ciphers that are provided by default in JVM
* We follow the recommendations from Mozilla (Intermediate Compatibility)
* https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
*/
public static final String DEFVAL_HTTPS_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
public static final int DISABLED_PORT = -1;
public static final String HTTP_PROTOCOL = "HTTP/1.1";
public static final String AJP_PROTOCOL = "AJP/1.3";
private Connectors() {
// only static stuff
}
static void configure(Tomcat tomcat, Props props) {
List<Connector> connectors = new ArrayList<Connector>();
List<Connector> connectors = new ArrayList<>();
connectors.addAll(Arrays.asList(newHttpConnector(props), newAjpConnector(props), newHttpsConnector(props)));
connectors.removeAll(Collections.singleton(null));
@ -61,7 +71,7 @@ class Connectors {
if (connectors.isEmpty()) {
throw new IllegalStateException("HTTP connectors are disabled");
}
Set<Integer> ports = new HashSet<Integer>();
Set<Integer> ports = new HashSet<>();
for (Connector connector : connectors) {
int port = connector.getPort();
if (ports.contains(port)) {
@ -115,7 +125,7 @@ class Connectors {
setConnectorAttribute(connector, "truststoreType", props.value("sonar.web.https.truststoreType", "JKS"));
setConnectorAttribute(connector, "truststoreProvider", props.value("sonar.web.https.truststoreProvider"));
setConnectorAttribute(connector, "clientAuth", props.value("sonar.web.https.clientAuth", "false"));
setConnectorAttribute(connector, "ciphers", props.value("sonar.web.https.ciphers"));
setConnectorAttribute(connector, "ciphers", props.value(PROP_HTTPS_CIPHERS, DEFVAL_HTTPS_CIPHERS));
// SSLv3 must not be enable because of Poodle vulnerability
// See https://jira.codehaus.org/browse/SONAR-5860
setConnectorAttribute(connector, "sslEnabledProtocols", "TLSv1,TLSv1.1,TLSv1.2");

View File

@ -19,18 +19,31 @@
*/
package org.sonar.server.app;
import org.apache.tomcat.JarScanFilter;
import org.apache.tomcat.JarScanType;
import org.apache.tomcat.JarScanner;
import org.apache.tomcat.JarScannerCallback;
import javax.servlet.ServletContext;
import java.util.Set;
/**
* Disable taglib and web-fragment.xml scanning of Tomcat. Should speed up startup.
*/
class NullJarScanner implements JarScanner {
@Override
public void scan(ServletContext context, ClassLoader classloader, JarScannerCallback callback, Set<String> jarsToSkip) {
public void scan(JarScanType jarScanType, ServletContext servletContext, JarScannerCallback jarScannerCallback) {
// doing nothing is fast!
}
@Override
public JarScanFilter getJarScanFilter() {
return null;
}
@Override
public void setJarScanFilter(JarScanFilter jarScanFilter) {
}
}

View File

@ -58,17 +58,12 @@ class StartupLogs {
}
private void logHttps(Connector connector) {
StringBuilder additional = new StringBuilder();
StringBuilder sb = new StringBuilder();
sb.append("HTTPS connector enabled on port ").append(connector.getPort());
ProtocolHandler protocol = connector.getProtocolHandler();
if (protocol instanceof AbstractHttp11JsseProtocol) {
additional.append("| ciphers=");
String ciphers = ((AbstractHttp11JsseProtocol) protocol).getCiphers();
if (StringUtils.isBlank(ciphers)) {
additional.append("JVM defaults");
} else {
additional.append(ciphers);
}
}
log.info(String.format("HTTPS connector enabled on port %d %s", connector.getPort(), additional));
String[] ciphers = ((AbstractHttp11JsseProtocol) protocol).getCiphersUsed();
sb.append(" | ciphers=").append(StringUtils.join(ciphers, ","));
log.info(sb.toString());
}
}

View File

@ -51,12 +51,9 @@ class Webapp {
context.setClearReferencesStopTimerThreads(false);
context.setClearReferencesStopTimerThreads(false);
context.setAntiResourceLocking(false);
context.setAntiJARLocking(false);
context.setReloadable(false);
context.setUseHttpOnly(true);
context.setProcessTlds(false);
context.setTldValidation(false);
context.setTldNamespaceAware(false);
context.setXmlValidation(false);
context.setXmlNamespaceAware(false);
context.setUseNaming(false);

View File

@ -39,13 +39,14 @@
*/
package org.sonar.server.app;
import org.apache.tomcat.JarScanFilter;
import org.apache.tomcat.JarScanType;
import org.apache.tomcat.JarScannerCallback;
import org.junit.Test;
import javax.servlet.ServletContext;
import java.util.HashSet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;
@ -53,9 +54,13 @@ public class NullJarScannerTest {
@Test
public void does_nothing() {
ServletContext context = mock(ServletContext.class);
ClassLoader classloader = mock(ClassLoader.class);
JarScannerCallback callback = mock(JarScannerCallback.class);
new NullJarScanner().scan(context, classloader, callback, new HashSet<String>());
verifyZeroInteractions(context, classloader, callback);
NullJarScanner scanner = new NullJarScanner();
scanner.scan(JarScanType.PLUGGABILITY, context, callback);
verifyZeroInteractions(context, callback);
scanner.setJarScanFilter(mock(JarScanFilter.class));
assertThat(scanner.getJarScanFilter()).isNull();
}
}

View File

@ -21,7 +21,7 @@ package org.sonar.server.app;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.http11.Http11Protocol;
import org.apache.coyote.http11.AbstractHttp11JsseProtocol;
import org.junit.Test;
import org.mockito.Mockito;
import org.slf4j.Logger;
@ -58,22 +58,15 @@ public class StartupLogsTest {
}
@Test
public void logHttps_default_ciphers() throws Exception {
Connector connector = newConnector("HTTP/1.1", "https");
when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
sut.log(tomcat);
verify(logger).info("HTTPS connector enabled on port 1234 | ciphers=JVM defaults");
verifyNoMoreInteractions(logger);
}
@Test
public void logHttps_overridden_ciphers() throws Exception {
Connector connector = newConnector("HTTP/1.1", "https");
connector.setProtocolHandlerClassName("org.apache.coyote.http11.Http11Protocol");
((Http11Protocol) connector.getProtocolHandler()).setCiphers("SSL_RSA,TLS_RSA_WITH_RC4");
public void logHttps() throws Exception {
Connector connector = mock(Connector.class, Mockito.RETURNS_DEEP_STUBS);
when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector});
when(connector.getScheme()).thenReturn("https");
when(connector.getProtocol()).thenReturn("HTTP/1.1");
when(connector.getPort()).thenReturn(1234);
AbstractHttp11JsseProtocol protocol = mock(AbstractHttp11JsseProtocol.class);
when(connector.getProtocolHandler()).thenReturn(protocol);
when(protocol.getCiphersUsed()).thenReturn(new String[] {"SSL_RSA", "TLS_RSA_WITH_RC4"});
sut.log(tomcat);

View File

@ -156,10 +156,11 @@
# HTTPS - comma separated list of encryption ciphers to support for HTTPS connections.
# If specified, only the ciphers that are listed and supported by the SSL implementation will be used.
# By default, the default ciphers for the JVM will be used. Note that this usually means that the weak
# export grade ciphers will be included in the list of available ciphers.
# The ciphers are specified using the JSSE cipher naming convention (see
# https://www.openssl.org/docs/apps/ciphers.html)
# By default, the Mozilla recommendations are followed (Intermediate Compatibility). See
# https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
#
# Example: sonar.web.https.ciphers=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
#sonar.web.https.ciphers=