-
Notifications
You must be signed in to change notification settings - Fork 7.3k
ZOOKEEPER-5029: Port unification for PrometheusMetricsProvider #2362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,11 @@ | |
| import org.apache.zookeeper.metrics.MetricsProviderLifeCycleException; | ||
| import org.apache.zookeeper.metrics.Summary; | ||
| import org.apache.zookeeper.metrics.SummarySet; | ||
| import org.apache.zookeeper.server.admin.UnifiedConnectionFactory; | ||
| import org.eclipse.jetty.http.HttpVersion; | ||
| import org.eclipse.jetty.server.HttpConfiguration; | ||
| import org.eclipse.jetty.server.HttpConnectionFactory; | ||
| import org.eclipse.jetty.server.SecureRequestCustomizer; | ||
| import org.eclipse.jetty.server.Server; | ||
| import org.eclipse.jetty.server.ServerConnector; | ||
| import org.eclipse.jetty.servlet.ServletContextHandler; | ||
|
|
@@ -84,6 +89,7 @@ public class PrometheusMetricsProvider implements MetricsProvider { | |
| private boolean wantClientAuth = true; // Secure default | ||
| private String enabledProtocols; | ||
| private String cipherSuites; | ||
| private int httpVersion; | ||
|
|
||
| // Constants for configuration | ||
| public static final String HTTP_HOST = "httpHost"; | ||
|
|
@@ -101,7 +107,10 @@ public class PrometheusMetricsProvider implements MetricsProvider { | |
| public static final String SSL_WANT_CLIENT_AUTH = "ssl.want.client.auth"; | ||
| public static final String SSL_ENABLED_PROTOCOLS = "ssl.enabledProtocols"; | ||
| public static final String SSL_ENABLED_CIPHERS = "ssl.ciphersuites"; | ||
| public static final String HTTP_VERSION = "httpVersion"; | ||
| public static final int SCAN_INTERVAL = 60 * 10; // 10 minutes | ||
| public static final int DEFAULT_HTTP_VERSION = 11; // based on HttpVersion.java in jetty | ||
| public static final int DEFAULT_STS_MAX_AGE = 1 * 24 * 60 * 60; // seconds in a day | ||
|
|
||
| /** | ||
| * Custom servlet to disable the TRACE method for security reasons. | ||
|
|
@@ -139,6 +148,7 @@ public void configure(Properties configuration) throws MetricsProviderLifeCycleE | |
| this.wantClientAuth = Boolean.parseBoolean(configuration.getProperty(SSL_WANT_CLIENT_AUTH, "true")); | ||
| this.enabledProtocols = configuration.getProperty(SSL_ENABLED_PROTOCOLS); | ||
| this.cipherSuites = configuration.getProperty(SSL_ENABLED_CIPHERS); | ||
| this.httpVersion = Integer.getInteger(HTTP_VERSION, DEFAULT_HTTP_VERSION); | ||
| } | ||
|
|
||
| // Validate that at least one port is configured. | ||
|
|
@@ -171,23 +181,47 @@ public void start() throws MetricsProviderLifeCycleException { | |
| int acceptors = 1; | ||
| int selectors = 1; | ||
|
|
||
| // Configure HTTP connector if enabled | ||
| if (this.httpPort != -1) { | ||
| ServerConnector httpConnector = new ServerConnector(server, acceptors, selectors); | ||
| httpConnector.setPort(this.httpPort); | ||
| httpConnector.setHost(this.host); | ||
| server.addConnector(httpConnector); | ||
| } | ||
| ServerConnector connector = null; | ||
|
|
||
| if (this.httpPort != -1 && this.httpsPort != -1 && this.httpPort == this.httpsPort) { | ||
| SecureRequestCustomizer customizer = new SecureRequestCustomizer(); | ||
| customizer.setStsMaxAge(DEFAULT_STS_MAX_AGE); | ||
| customizer.setStsIncludeSubDomains(true); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might need to add some comments to briefly explain what is this about.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sets a directive of the Strict-Transport-Security HTTP response header.
Same as we have in JettyAdminServer here:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the explanation. I think it'd be beneficial to briefly mention these in a Javadoc. |
||
|
|
||
| HttpConfiguration config = new HttpConfiguration(); | ||
| config.setSecureScheme("https"); | ||
| config.addCustomizer(customizer); | ||
|
|
||
| // Configure HTTPS connector if enabled | ||
| if (this.httpsPort != -1) { | ||
| SslContextFactory.Server sslContextFactory = createSslContextFactory(); | ||
| KeyStoreScanner keystoreScanner = new KeyStoreScanner(sslContextFactory); | ||
| keystoreScanner.setScanInterval(SCAN_INTERVAL); | ||
| server.addBean(keystoreScanner); | ||
| server.addConnector(createSslConnector(server, acceptors, selectors, sslContextFactory)); | ||
| setKeyStoreScanner(sslContextFactory); | ||
|
|
||
| String nextProtocol = HttpVersion.fromVersion(httpVersion).asString(); | ||
| connector = new ServerConnector(server, | ||
| new UnifiedConnectionFactory(sslContextFactory, nextProtocol), | ||
| new HttpConnectionFactory(config)); | ||
| connector.setPort(this.httpPort); | ||
| connector.setHost(this.host); | ||
| LOG.debug("Created unified ServerConnector for host: {}, httpPort: {}", host, httpPort); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can move these messages to INFO level. We should see clearly which type of server has been initialized. |
||
| } else { | ||
| // Configure HTTP connector if enabled | ||
| if (this.httpPort != -1) { | ||
| connector = new ServerConnector(server, acceptors, selectors); | ||
| connector.setPort(this.httpPort); | ||
| connector.setHost(this.host); | ||
| LOG.debug("Created ServerConnector for host: {}, httpPort: {}", host, httpPort); | ||
| } | ||
|
|
||
| // Configure HTTPS connector if enabled | ||
| if (this.httpsPort != -1) { | ||
| SslContextFactory.Server sslContextFactory = createSslContextFactory(); | ||
| setKeyStoreScanner(sslContextFactory); | ||
| connector = createSslConnector(server, acceptors, selectors, sslContextFactory); | ||
| LOG.debug("Created HTTPS ServerConnector for host: {}, httpsPort: {}", host, httpsPort); | ||
| } | ||
| } | ||
|
|
||
| server.addConnector(connector); | ||
|
|
||
| // Set up the servlet context handler | ||
| ServletContextHandler context = new ServletContextHandler(); | ||
| context.setContextPath("/"); | ||
|
|
@@ -207,6 +241,12 @@ public void start() throws MetricsProviderLifeCycleException { | |
| } | ||
| } | ||
|
|
||
| private void setKeyStoreScanner(SslContextFactory.Server sslContextFactory) { | ||
| KeyStoreScanner keystoreScanner = new KeyStoreScanner(sslContextFactory); | ||
| keystoreScanner.setScanInterval(SCAN_INTERVAL); | ||
| server.addBean(keystoreScanner); | ||
| } | ||
|
|
||
| /** | ||
| * Creates and configures the SslContextFactory for the server. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is STS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
STS means the Strict-Transport-Security HTTP response header.
...
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security
This is implemented here the same way as we have it in JettyAdminServer:
https://github.com/apache/zookeeper/blob/master/zookeeper-server/src/main/java/org/apache/zookeeper/server/admin/JettyAdminServer.java#L119