-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
The Logstash HTTP API is currently unsecured. In order to prevent malicious actors on the network from abusing access to the API, we have historically taken two approaches:
- bind the HTTP API to the local loopback interface by default, AND
- avoid adding features to the API that could be abused.
Because it is not always practical for the Logstash API to be bound to the host's loopback interface, and because we would like to add a number of features that have the potential for abuse if left unguarded, we need to secure the HTTP API and ensure that only verifiably known, authorized users have access.
In doing so, we need to support a number of practical scenarios:
- Unsecured HTTP (status quo, bound to loopback interface by default);
- SSL-only Client Authentication; AND
- SLL + HTTP Authentication.
When configured in a way that allows us to establish trust of a client, we can safely bind to any interface and should do so by default.
Securing the connection (SSL/TLS)
Adding TLS/SSL allows Logstash to establish privacy with the client, which allows the client to safely send credentials if they are required. In some configurations, TLS allows Logstash to establish a baseline trust of the client. TLS is therefore either the means by which trust of the client is established, or a pre-requisite for doing so.
We will add a number of settings that mirror the intent behind similar Elasticsearch xpack.security.http.ssl.* settings, grouped under Logstash's api.ssl.*:
api.ssl.enabled: boolean, default tofalsefor now. Whenfalse, Logstash should warn about other SSL-related settings being provided.api.ssl.keystore.path: the path to a readable X509 Keystore, required whenapi.ssl.enabled: true.api.ssl.keystore.password: optional password to be used to access the provided keystore.api.ssl.client_authentication: one ofnone,optional, orrequired, mirroringxpack.security.http.ssl.client_authenticationand mapping to Puma'snone,peer, andforce_peerrespectively.api.ssl.supported_protocols: accepts an unordered list of supported TLS protocols (implementation tricky: underlying PUMA only allows us to explicitly disableTLSv1andTLSv1.1, so we may need to require that the provided list includeTLSv1.2etc until such opt-out support is added to Puma; if we can't implement in this way, we should add one or more distinctapi.ssl.*settings that do not overlapapi.ssl.supported_protocols)
Establishing trust of client using SSL + HTTP Authentication
When configured with SSL enabled in any client_authentication mode, we have mutual proof-of-privacy with the client, and can use HTTP Authentication to establish authorization.
We will add a new option api.auth.type, whose valid values are either none or basic, so that we can add additional HTTP Authorization schemes or backends in the future.
To configure basic auth on the API, a user will add api.auth.basic.username and api.auth.basic.password directly in their logstash.yml configuration. Users who wish to store their credentials in the Logstash keystore will need to reference a value stored there using variable expansion.
- Failure to specify both values when
api.auth.type: basicis considered a configuration error. - Setting either value when
api.auth.typeis notbasicis considered a configuration error. - Setting
api.auth.type: basicwithoutauth.ssl.enabledwill produce a warning and will not qualify the configuration to default to any-interface binding. - Setting
api.ssl.enabled: trueandapi.auth.type: basicqualifies the API for defaulting to bind to any interface (0.0.0.0).
Establishing trust of client using SSL-only client authentication
In some organizations, SSL-only client authentication (api.ssl.enabled: true AND api.ssl.client_authentication: required) is sufficient to establish trust of the client.
- Setting
api.ssl.enabled: trueandapi.ssl.client_authentication: requiredqualifies the API for defaulting to bind to any interface (0.0.0.0).
API Settings Mapping Overhaul
Logstash currently has its API-related settings nested under http, even when some of those settings don't map to HTTP-related things. We are adding a number of API-related settings here that don't directly apply to http either, and adding them there or as top-level ssl is liable to add confusion as user-configured pipelines also have HTTP- and SSL-related settings that would be unaffected by these settings here.
As a part of securing the HTTP API, we therefore will be re-naming a number of settings to be consistently grouped under a consistent top-level api grouping.
api.enabled(previously:http.enabled)api.http.host(previously:http.host)api.http.port(previously:http.port)api.environment(previously:http.environment)
Notable behaviours:
- when both a canonical setting and its deprecated counterpart are used, it is a configuration error.
- when a deprecated-and-renamed setting is used, a deprecation warning is emitted to the deprecation logger and the canonical setting is set.
- we are too close to 8.0 to consider removing these newly-deprecated
http.*settings; they will be sticking with us for a while to allow users to make the switch in their own time.