@Bean public EmbeddedServletContainerFactory servletContainer() { final TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); if (casProperties.getServer().getAjp().isEnabled()) { final Connector ajpConnector = new Connector(casProperties.getServer().getAjp().getProtocol()); ajpConnector.setProtocol(casProperties.getServer().getAjp().getProtocol()); ajpConnector.setPort(casProperties.getServer().getAjp().getPort()); ajpConnector.setSecure(casProperties.getServer().getAjp().isSecure()); ajpConnector.setAllowTrace(casProperties.getServer().getAjp().isAllowTrace()); ajpConnector.setScheme(casProperties.getServer().getAjp().getScheme()); ajpConnector.setAsyncTimeout(casProperties.getServer().getAjp().getAsyncTimeout()); ajpConnector.setEnableLookups(casProperties.getServer().getAjp().isEnableLookups()); ajpConnector.setMaxPostSize(casProperties.getServer().getAjp().getMaxPostSize()); if (casProperties.getServer().getAjp().getProxyPort() > 0) { ajpConnector.setProxyPort(casProperties.getServer().getAjp().getProxyPort()); } if (casProperties.getServer().getAjp().getRedirectPort() > 0) { ajpConnector.setRedirectPort(casProperties.getServer().getAjp().getRedirectPort()); } tomcat.addAdditionalTomcatConnectors(ajpConnector); } if (casProperties.getServer().getHttp().isEnabled()) { final Connector connector = new Connector(casProperties.getServer().getHttp().getProtocol()); int port = casProperties.getServer().getHttp().getPort(); if (port <= 0) { port = SocketUtils.findAvailableTcpPort(); } connector.setPort(port); tomcat.addAdditionalTomcatConnectors(connector); } tomcat .getAdditionalTomcatConnectors() .stream() .filter(connector -> connector.getProtocolHandler() instanceof AbstractProtocol) .forEach( connector -> { final AbstractProtocol handler = (AbstractProtocol) connector.getProtocolHandler(); handler.setSoTimeout(casProperties.getServer().getConnectionTimeout()); handler.setConnectionTimeout(casProperties.getServer().getConnectionTimeout()); }); return tomcat; }
private void start(boolean await) { // try to shutdown a previous Tomcat sendShutdownCommand(); try { final ServerSocket srv = new ServerSocket(this.httpPort); srv.close(); } catch (IOException e) { log.error("PORT " + this.httpPort + " ALREADY IN USE"); return; } // Read a dummy value. This triggers loading of the catalina.properties // file CatalinaProperties.getProperty("dummy"); appendSkipJars("tomcat.util.scan.DefaultJarScanner.jarsToSkip", this.skipJarsDefaultJarScanner); appendSkipJars( "org.apache.catalina.startup.ContextConfig.jarsToSkip", this.skipJarsContextConfig); appendSkipJars("org.apache.catalina.startup.TldConfig.jarsToSkip", this.skipJarsTldConfig); this.tomcat = new Tomcat(); if (this.tempDirectory == null) { this.tempDirectory = new File(".", "/target/tomcat." + this.httpPort).getAbsolutePath(); } this.tomcat.setBaseDir(this.tempDirectory); if (this.silent) { this.tomcat.setSilent(true); } if (this.addDefaultListeners) { this.tomcat.getServer().addLifecycleListener(new AprLifecycleListener()); } if (this.useNio) { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setPort(this.httpPort); connector.setMaxPostSize(this.maxPostSize); connector.setURIEncoding("UTF-8"); this.tomcat.setConnector(connector); this.tomcat.getService().addConnector(connector); } else { this.tomcat.setPort(this.httpPort); this.tomcat.getConnector().setURIEncoding("UTF-8"); this.tomcat.getConnector().setMaxPostSize(this.maxPostSize); } if (this.compressionMinSize >= 0) { this.tomcat .getConnector() .setProperty("compression", String.valueOf(this.compressionMinSize)); this.tomcat.getConnector().setProperty("compressableMimeType", this.compressableMimeType); } if (this.httpsPort != 0) { final Connector httpsConnector; if (this.useNio) { httpsConnector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); } else { httpsConnector = new Connector("HTTP/1.1"); } httpsConnector.setSecure(true); httpsConnector.setPort(this.httpsPort); httpsConnector.setMaxPostSize(this.maxPostSize); httpsConnector.setScheme("https"); httpsConnector.setURIEncoding("UTF-8"); httpsConnector.setProperty("SSLEnabled", "true"); httpsConnector.setProperty("keyAlias", this.keyAlias); httpsConnector.setProperty("keystoreFile", this.keyStoreFile); httpsConnector.setProperty("keystorePass", this.keyStorePass); httpsConnector.setProperty("sslProtocol", this.sslProtocol); if (this.compressionMinSize >= 0) { httpsConnector.setProperty("compression", String.valueOf(this.compressionMinSize)); httpsConnector.setProperty("compressableMimeType", this.compressableMimeType); } this.tomcat.getEngine().setDefaultHost("localhost"); this.tomcat.getService().addConnector(httpsConnector); } if (this.shutdownPort != null) { this.tomcat.getServer().setPort(this.shutdownPort); } String contextDir = this.contextDirectory; if (contextDir == null) { contextDir = new File(".").getAbsolutePath() + "/src/main/webapp"; } final Context ctx; try { if (!this.contextPath.equals("")) { File rootCtxDir = new File("./target/tcroot"); if (!rootCtxDir.exists()) { rootCtxDir.mkdirs(); } Context rootCtx = this.tomcat.addWebapp("", rootCtxDir.getAbsolutePath()); rootCtx.setPrivileged(true); Tomcat.addServlet(rootCtx, "listContexts", new ListContextsServlet(rootCtx)) .addMapping("/"); } ctx = this.tomcat.addWebapp(this.contextPath, contextDir); ctx.setResources(new TargetClassesContext()); } catch (ServletException e) { throw new RuntimeException(e); } if (this.privileged) { ctx.setPrivileged(true); } if (this.enableNaming || !this.contextEnvironments.isEmpty() || !this.contextResources.isEmpty() || this.contextFileURL != null) { this.tomcat.enableNaming(); if (this.addDefaultListeners) { this.tomcat.getServer().addLifecycleListener(new GlobalResourcesLifecycleListener()); } } if (this.addDefaultListeners) { Server server = this.tomcat.getServer(); server.addLifecycleListener(new JasperListener()); server.addLifecycleListener(new JreMemoryLeakPreventionListener()); server.addLifecycleListener(new ThreadLocalLeakPreventionListener()); } for (ContextEnvironment env : this.contextEnvironments) { ctx.getNamingResources().addEnvironment(env); } for (ContextResource res : this.contextResources) { ctx.getNamingResources().addResource(res); } for (ApplicationParameter param : this.contextInitializationParameters) { ctx.addApplicationParameter(param); } if (this.contextFileURL != null) { ctx.setConfigFile(this.contextFileURL); } // Shutdown tomcat if a failure occurs during startup ctx.addLifecycleListener( new LifecycleListener() { @Override public void lifecycleEvent(LifecycleEvent event) { if (event.getLifecycle().getState() == LifecycleState.FAILED) { ((StandardServer) EmbeddedTomcat.this.tomcat.getServer()).stopAwait(); } } }); try { this.tomcat.start(); } catch (LifecycleException e) { throw new RuntimeException(e); } ((StandardManager) ctx.getManager()).setPathname(null); installSlf4jBridge(); if (await) { this.tomcat.getServer().await(); stop(); } }
@Override protected void doStart() throws ElasticsearchException { try { final String currentDir = new File(".").getCanonicalPath(); final String tomcatDir = currentDir + File.separatorChar + "tomcat"; logger.debug("cur dir " + currentDir); if (tomcat != null) { try { tomcat.stop(); tomcat.destroy(); } catch (final Exception e) { } } tomcat = new ExtendedTomcat(); tomcat.enableNaming(); tomcat.getServer().setPort(-1); // shutdown disabled tomcat.getServer().setAddress("localhost"); final String httpProtocolImpl = blockingServer ? "org.apache.coyote.http11.Http11Protocol" : "org.apache.coyote.http11.Http11NioProtocol"; final Connector httpConnector = new Connector(httpProtocolImpl); tomcat.setConnector(httpConnector); tomcat.getService().addConnector(httpConnector); // TODO report tomcat bug with setProtocol if (maxContentLength != null) { httpConnector.setMaxPostSize(maxContentLength.bytesAsInt()); } if (maxHeaderSize != null) { httpConnector.setAttribute("maxHttpHeaderSize", maxHeaderSize.bytesAsInt()); } if (tcpNoDelay != null) { httpConnector.setAttribute("tcpNoDelay", tcpNoDelay.booleanValue()); } if (reuseAddress != null) { httpConnector.setAttribute("socket.soReuseAddress", reuseAddress.booleanValue()); } if (tcpKeepAlive != null) { httpConnector.setAttribute("socket.soKeepAlive", tcpKeepAlive.booleanValue()); httpConnector.setAttribute( "maxKeepAliveRequests", tcpKeepAlive.booleanValue() ? "100" : "1"); } if (tcpReceiveBufferSize != null) { httpConnector.setAttribute("socket.rxBufSize", tcpReceiveBufferSize.bytesAsInt()); } if (tcpSendBufferSize != null) { httpConnector.setAttribute("socket.txBufSize", tcpSendBufferSize.bytesAsInt()); } httpConnector.setAttribute( "compression", compression ? String.valueOf(compressionLevel) : "off"); if (maxChunkSize != null) { httpConnector.setAttribute("maxExtensionSize", maxChunkSize.bytesAsInt()); } httpConnector.setPort(Integer.parseInt(port)); tomcat.setBaseDir(tomcatDir); final TomcatHttpTransportHandlerServlet servlet = new TomcatHttpTransportHandlerServlet(); servlet.setTransport(this); final Context ctx = tomcat.addContext("", currentDir); logger.debug("currentDir " + currentDir); Tomcat.addServlet(ctx, "ES Servlet", servlet); ctx.addServletMapping("/*", "ES Servlet"); if (useSSL) { logger.info("Using SSL"); // System.setProperty("javax.net.debug", "ssl"); httpConnector.setAttribute("SSLEnabled", "true"); httpConnector.setSecure(true); httpConnector.setScheme("https"); httpConnector.setAttribute("sslProtocol", "TLS"); httpConnector.setAttribute( "keystoreFile", settings.get("security.ssl.keystorefile", "keystore")); httpConnector.setAttribute( "keystorePass", settings.get("security.ssl.keystorepass", "changeit")); httpConnector.setAttribute( "keystoreType", settings.get("security.ssl.keystoretype", "JKS")); final String keyalias = settings.get("security.ssl.keyalias", null); if (keyalias != null) { httpConnector.setAttribute("keyAlias", keyalias); } if (useClientAuth) { logger.info( "Using SSL Client Auth (PKI), so user/roles will be retrieved from client certificate."); httpConnector.setAttribute("clientAuth", "true"); httpConnector.setAttribute( "truststoreFile", settings.get("security.ssl.clientauth.truststorefile", "truststore")); httpConnector.setAttribute( "truststorePass", settings.get("security.ssl.clientauth.truststorepass", "changeit")); httpConnector.setAttribute( "truststoreType", settings.get("security.ssl.clientauth.truststoretype", "JKS")); /*final String loginconf = this.settings .get("security.kerberos.login.conf.path"); final String krbconf = this.settings .get("security.kerberos.krb5.conf.path"); SecurityUtil.setSystemPropertyToAbsoluteFile( "java.security.auth.login.config", loginconf); SecurityUtil.setSystemPropertyToAbsoluteFile( "java.security.krb5.conf", krbconf);*/ // httpConnector.setAttribute("allowUnsafeLegacyRenegotiation", "true"); final SecurityConstraint constraint = new SecurityConstraint(); constraint.addAuthRole("*"); constraint.setAuthConstraint(true); constraint.setUserConstraint("CONFIDENTIAL"); final SecurityCollection col = new SecurityCollection(); col.addPattern("/*"); constraint.addCollection(col); ctx.addConstraint(constraint); final LoginConfig lc = new LoginConfig(); lc.setAuthMethod("CLIENT-CERT"); lc.setRealmName("clientcretificate"); ctx.setLoginConfig(lc); configureJndiRealm(ctx); ctx.getPipeline().addValve(new SSLAuthenticator()); logger.info("Auth Method is CLIENT-CERT"); // http://pki-tutorial.readthedocs.org/en/latest/simple/ } } else { if (useClientAuth) { logger.error("Client Auth only available with SSL"); throw new RuntimeException("Client Auth only available with SSL"); } // useClientAuth = false; } if (!useClientAuth) { if ("waffle".equalsIgnoreCase(kerberosMode)) { final Boolean testMode = settings.getAsBoolean("security.waffle.testmode", false); final FilterDef fd = new FilterDef(); fd.setFilterClass("waffle.servlet.NegotiateSecurityFilter"); fd.setFilterName("Waffle"); if (testMode != null && testMode.booleanValue()) { fd.addInitParameter("principalFormat", "fqn"); fd.addInitParameter("roleFormat", "both"); fd.addInitParameter("allowGuestLogin", "true"); fd.addInitParameter( "securityFilterProviders", "org.elasticsearch.plugins.security.waffle.TestProvider"); logger.info( "Kerberos implementaton is WAFFLE in testmode (only work on Windows Operations system)"); } else { final Map<String, String> waffleSettings = settings.getByPrefix("security.waffle").getAsMap(); for (final String waffleKey : waffleSettings.keySet()) { fd.addInitParameter(waffleKey.substring(1), waffleSettings.get(waffleKey)); logger.debug(waffleKey.substring(1) + "=" + waffleSettings.get(waffleKey)); } fd.addInitParameter("principalFormat", "fqn"); fd.addInitParameter("roleFormat", "both"); fd.addInitParameter("allowGuestLogin", "false"); logger.info( "Kerberos implementaton is WAFFLE (only work on Windows Operations system)"); } ctx.addFilterDef(fd); final FilterMap fm = new FilterMap(); fm.setFilterName("Waffle"); fm.addURLPattern("/*"); ctx.addFilterMap(fm); } else if ("spnegoad".equalsIgnoreCase(kerberosMode)) { // System.setProperty("sun.security.krb5.debug", "true"); // TODO // switch // off System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); final SecurityConstraint constraint = new SecurityConstraint(); constraint.addAuthRole("*"); constraint.setAuthConstraint(true); constraint.setDisplayName("spnego_sc_all"); final SecurityCollection col = new SecurityCollection(); col.addPattern("/*"); constraint.addCollection(col); ctx.addConstraint(constraint); final LoginConfig lc = new LoginConfig(); lc.setAuthMethod("SPNEGO"); lc.setRealmName("SPNEGO"); ctx.setLoginConfig(lc); logger.info("Kerberos implementaton is SPNEGOAD"); configureJndiRealm(ctx); final ExtendedSpnegoAuthenticator spnegoValve = new ExtendedSpnegoAuthenticator(); // spnegoValve.setLoginConfigName("es-login"); spnegoValve.setStoreDelegatedCredential(true); ctx.getPipeline().addValve(spnegoValve); // final SpnegoAuthenticator spnegoValve = new SpnegoAuthenticator(); // spnegoValve.setLoginEntryName("es-login"); // ctx.getPipeline().addValve(spnegoValve); } else if ("none".equalsIgnoreCase(kerberosMode)) { logger.warn( "Kerberos is not configured so user/roles are unavailable. Host based security, in contrast, is woking. "); } else { logger.error( "No Kerberos implementaion '" + kerberosMode + "' found. Kerberos is therefore not configured so user/roles are unavailable. Host based security, in contrast, is woking. "); } } tomcat.start(); logger.info("Tomcat started"); InetSocketAddress bindAddress; try { bindAddress = new InetSocketAddress( networkService.resolveBindHostAddress(bindHost), tomcat.getConnector().getLocalPort()); } catch (final Exception e) { throw new BindTransportException("Failed to resolve bind address", e); } InetSocketAddress publishAddress; try { publishAddress = new InetSocketAddress( networkService.resolvePublishHostAddress(publishHost), bindAddress.getPort()); } catch (final Exception e) { throw new BindTransportException("Failed to resolve publish address", e); } logger.debug("bindAddress " + bindAddress); logger.debug("publishAddress " + publishAddress); boundAddress = new BoundTransportAddress( new InetSocketTransportAddress(bindAddress), new InetSocketTransportAddress(publishAddress)); } catch (final Exception e) { throw new ElasticsearchException("Unable to start Tomcat", e); } }
/** * Start, register and bind the web connector. * * @param context the start context * @throws StartException if the connector cannot be started */ public synchronized void start(StartContext context) throws StartException { final SocketBinding binding = this.binding.getValue(); final InetSocketAddress address = binding.getSocketAddress(); final Executor executor = this.executor.getOptionalValue(); try { // Create connector final Connector connector = new Connector(protocol); connector.setPort(address.getPort()); connector.setScheme(scheme); if (enableLookups != null) connector.setEnableLookups(enableLookups); if (maxPostSize != null) connector.setMaxPostSize(maxPostSize); if (maxSavePostSize != null) connector.setMaxSavePostSize(maxSavePostSize); if (proxyName != null) connector.setProxyName(proxyName); if (proxyPort != null) connector.setProxyPort(proxyPort); if (redirectPort != null) connector.setRedirectPort(redirectPort); if (secure != null) connector.setSecure(secure); if (executor != null) { Method m = connector.getProtocolHandler().getClass().getMethod("setExecutor", Executor.class); m.invoke(connector.getProtocolHandler(), executor); } if (address != null && address.getAddress() != null) { Method m = connector.getProtocolHandler().getClass().getMethod("setAddress", InetAddress.class); m.invoke(connector.getProtocolHandler(), address.getAddress()); } if (maxConnections != null) { try { Method m = connector.getProtocolHandler().getClass().getMethod("setPollerSize", Integer.TYPE); m.invoke(connector.getProtocolHandler(), maxConnections); } catch (NoSuchMethodException e) { // Not all connectors will have this } try { Method m = connector.getProtocolHandler().getClass().getMethod("setSendfileSize", Integer.TYPE); m.invoke(connector.getProtocolHandler(), maxConnections); } catch (NoSuchMethodException e) { // Not all connectors will have this } } if (virtualServers != null) { HashSet<String> virtualServersList = new HashSet<String>(); for (final ModelNode virtualServer : virtualServers.asList()) { virtualServersList.add(virtualServer.asString()); } connector.setAllowedHosts(virtualServersList); } if (ssl != null) { boolean nativeSSL = false; if (connector.getProtocolHandler() instanceof Http11AprProtocol) { nativeSSL = true; } else if (!(connector.getProtocolHandler() instanceof Http11Protocol)) { throw new StartException("Non HTTP connectors dor not support SSL"); } // Enable SSL try { Method m = connector.getProtocolHandler().getClass().getMethod("setSSLEnabled", Boolean.TYPE); m.invoke(connector.getProtocolHandler(), true); } catch (NoSuchMethodException e) { // No SSL support throw new StartException(e); } if (nativeSSL) { // OpenSSL configuration try { if (ssl.hasDefined(Constants.PASSWORD)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLPassword", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PASSWORD).asString()); } if (ssl.hasDefined(Constants.CERTIFICATE_KEY_FILE)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLCertificateKeyFile", String.class); m.invoke( connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_KEY_FILE).asString()); } if (ssl.hasDefined(Constants.CIPHER_SUITE)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLCipherSuite", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CIPHER_SUITE).asString()); } if (ssl.hasDefined(Constants.PROTOCOL)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLProtocol", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PROTOCOL).asString()); } if (ssl.hasDefined(Constants.VERIFY_CLIENT)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLVerifyClient", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_CLIENT).asString()); } if (ssl.hasDefined(Constants.VERIFY_DEPTH)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLVerifyDepth", Integer.TYPE); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_DEPTH).asInt()); } if (ssl.hasDefined(Constants.CERTIFICATE_FILE)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLCertificateFile", String.class); m.invoke( connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_FILE).asString()); } if (ssl.hasDefined(Constants.CA_CERTIFICATE_FILE)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLCACertificateFile", String.class); m.invoke( connector.getProtocolHandler(), ssl.get(Constants.CA_CERTIFICATE_FILE).asString()); } if (ssl.hasDefined(Constants.CA_REVOCATION_URL)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setSSLCARevocationFile", String.class); m.invoke( connector.getProtocolHandler(), ssl.get(Constants.CA_REVOCATION_URL).asString()); } } catch (NoSuchMethodException e) { throw new StartException(e); } } else { // JSSE configuration try { if (ssl.hasDefined(Constants.KEY_ALIAS)) { Method m = connector.getProtocolHandler().getClass().getMethod("setKeyAlias", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.KEY_ALIAS).asString()); } if (ssl.hasDefined(Constants.PASSWORD)) { Method m = connector.getProtocolHandler().getClass().getMethod("setKeypass", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PASSWORD).asString()); } if (ssl.hasDefined(Constants.CERTIFICATE_KEY_FILE)) { Method m = connector.getProtocolHandler().getClass().getMethod("setKeystore", String.class); m.invoke( connector.getProtocolHandler(), ssl.get(Constants.CERTIFICATE_KEY_FILE).asString()); } if (ssl.hasDefined(Constants.CIPHER_SUITE)) { Method m = connector.getProtocolHandler().getClass().getMethod("setCiphers", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.CIPHER_SUITE).asString()); } if (ssl.hasDefined(Constants.PROTOCOL)) { Method m = connector.getProtocolHandler().getClass().getMethod("setProtocols", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.PROTOCOL).asString()); } if (ssl.hasDefined(Constants.VERIFY_CLIENT)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setClientauth", String.class); m.invoke(connector.getProtocolHandler(), ssl.get(Constants.VERIFY_CLIENT).asString()); } if (ssl.hasDefined(Constants.SESSION_CACHE_SIZE)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setAttribute", String.class, Object.class); m.invoke( connector.getProtocolHandler(), "sessionCacheSize", ssl.get(Constants.SESSION_CACHE_SIZE).asString()); } if (ssl.hasDefined(Constants.SESSION_TIMEOUT)) { Method m = connector .getProtocolHandler() .getClass() .getMethod("setAttribute", String.class, Object.class); m.invoke( connector.getProtocolHandler(), "sessionCacheTimeout", ssl.get(Constants.SESSION_TIMEOUT).asString()); } } catch (NoSuchMethodException e) { throw new StartException(e); } } } getWebServer().addConnector(connector); this.connector = connector; } catch (Exception e) { throw new StartException(e); } // Register the binding after the connector is started binding.getSocketBindings().getNamedRegistry().registerBinding(new ConnectorBinding(binding)); }