-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
TLS support #4270
TLS support #4270
Conversation
@pjain1 very cool! Will fit in well with work we've been doing to add basic authentication, which requires https to be effective… How would a transition from http to https look for a cluster? For outwards-facing APIs, could they be served on both http and https for some transition period, before the user decides to cut over to https completely? I think something like that is necessary to avoid disrupting clients. (i.e. a three part migration: first enable both http/https on Druid, then switch clients to https, then turn off http on Druid) For inwards-facing APIs, like historical, middleManager, task announcement, etc, what's the idea there? The fact that "scheme" is added but there's still only one "port" makes me think that they won't support both http and https at the same time. How would we do a rolling update in that case? |
We did not wanted to support two ports simultaneously on nodes to avoid complexity and code which will not be useful in future. This is what we thought about how rolling upgrade will work -
We thought of the three phase approach but thought it might a lot of unnecessary complexity to code which is not so nice. What do you think ? |
For the 4. point about external clients, actually they should also the external discovery to figure out the scheme and use that and then there won't be any disruptions. |
For the internally-facing APIs I think it's workable to only listen/announce one scheme at a time. But for the externally-facing APIs I think users will really appreciate it if we listen on two ports for a while. That's because a lot of peoples' clients don't use Curator service discovery to find Druid -- they use some other mechanism, like load balancers, VIPs, or even hard-coded URLs.
Some clients don't have the ability to use such custom logic, such as if your client is actually a load balancer or VIP where you can't configure a fallback like that. And even for clients that do have the ability to use custom logic, we'd be asking users to write code to implement that, which is a burden on them. |
Sounds like a valid concern. @himanshug @cheddar Do you have any opinions on Gian's comment. |
@gianm it was discussed internally whether to enable same process to run both http and https simultaneously , but with scheme discovery via zookeeper it was possible to support druid's rolling upgrade and become https. so we decided not to go that route. |
Sorry but it still sounds too user-unfriendly to me. Redirects aren't always easy or even possible for clients to follow. Consider the case where the brokers are fronted by a load balancer, which is super common (amazon ELB in particular is quite common, as are other kinds of load balancers). In many cases the user doesn't have access to the brokers directly and has to go through the balancer. If the load balancer doesn't follow redirects -- and many don't -- the client will get redirected to a url it can't access. Also, many http libraries don't follow redirects by default, if they support it at all (our own http-client doesn't, and I've worked with others that also don't). And some libraries will follow for GET, but not for POST. I think asking users to get all their clients to be able to deal with this kind of stuff before they can switch to https is going to be a pain for them, if it is even possible at all. |
hmmm, in the case when brokers are behind a load balancer and all external clients talk to that ... then rolling upgrade is pretty simple ... remove that said, in the most general case only option would be to have broker accept both http and https. @cheddar any additional thoughts? |
That wouldn't work for Amazon ELBs, at least, which don't let you specify different schemes or ports for different instances behind a load balancer. Those have to match across all of them. I think in this case it's best for us to take the complexity hit in order to make life simpler for users. |
yeah, may be, so user would probably configure additional |
Yeah, that makes sense to me. |
We might want additional configs too to determine what ports to listen on. Something to make it possible to disable http when we don't want it anymore. Would we also add 'standard' SSL ports for Druid services, meant to replace the 808x and 81xx ports we currently use? |
@gianm Ignoring the current configs in this PR, moving forward something like this can be done-
Another design would be to have a config like
There can be multiple combinations with these 3 configs. What do you think is better ? |
One more option is to have a config like |
Both of those seem a bit magical to me. If I'm a user I don't want to have to worry about whether Instead how about the following?
|
oops, should have said |
Interesting, my last comment looks similar to what you are proposing. |
Yes it does look similar :) I like |
OK lets go with the properties name you suggested. I'll make the changes soon. Thanks for the comments. |
If port is deprecated and if user was setting port using config then do we expect user to change it to plaintextPort or should the code internally map port to plaintextPort. |
Having two types of ports and a separate configuration to enable each type sounds good to me. I think we could keep If both plaintext/TLS ports are enabled, I think having |
@pjain1 This patch mostly LGTM now, I'm okay with merging this once the discussions around the PasswordProvider are resolved. I agree with @gianm and @drcrallen on keeping the existing password handling for the metadata store unchanged in this PR, and left my thoughts on @drcrallen's comment regarding the PasswordProvider(or SecretProvider) interface. |
@@ -14,7 +14,8 @@ The indexing service uses several of the global configs in [Configuration](../co | |||
|Property|Description|Default| | |||
|--------|-----------|-------| | |||
|`druid.host`|The host for the current node. This is used to advertise the current processes location as reachable from another node and should generally be specified such that `http://${druid.host}/` could actually talk to this process|InetAddress.getLocalHost().getCanonicalHostName()| | |||
|`druid.port`|This is the port to actually listen on; unless port mapping is used, this will be the same port as is on `druid.host`|8090| | |||
|`druid.plaintextPort`|This is the port to actually listen on; unless port mapping is used, this will be the same port as is on `druid.host`|8090| |
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.
This should note that the MiddleManager defaults to ports 8091/8291
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.
added new section for MiddleManager configs
@gianm @jon-wei @drcrallen to keep things simple I have kept Added separate documentation pages for how to use and implement |
@pjain1 Reviewed the patch again, didn't have any more comments, looks good to me. The new password provider design looks good. I'll approve after resolving conflicts. |
I am going to do some basic testing again tomorrow after which I think the PR will be mergeable. |
The PR is mergeable now (if there are no more comments), note that I have added |
@drcrallen @nishantmonu51 Did you have any more comments on this patch? |
@nishantmonu51 @drcrallen @jihoonson @gianm Does anyone else want to take a look at this patch again? If not, I'm planning on merging this tomorrow. |
Open for discussion.
Configurations -
druid.server.http.plainText
- enable/disable http connectordruid.server.http.tls
- enable/disable https connectordruid.plainTextPort
- port for http connectordruid.tlsPort
- port for https connectordruid.server.https.*
- Jetty server TLS configsBehavior of configuring http connector using
druid.host
anddruid.port
is kept backwards compatible. However, ifdruid.server.http.tls
is set thendruid.tlsPort
config will be used for TLS port and ifdruid.host
contains port then that port will be ignored, this also means thatdruid.tlsPort
should be a non-negative Integer . Please seeDruidNodeTest
unit tests for all the different configurations that will work and ones that will not.High Level Implementation details -
DruidServerMetadata
) to includehostAndTlsPort
in addition tohost
which is combination of host and plain text port. Ifdruid.server.http.plainText
is not set then announcedhost
will be null, similarly ifdruid.server.http.tls
is not set then announcedhostAndTlsPort
will be null.sslPort
in addition toport
.sslPort
will be -1 if tls is disabled, similarlyport
will be -1 if plainText is disabled.TaskLocation
to includetlsPort
.Worker
to includescheme
which will behttps
iftlsPort
is greater than or equal to 0 otherwisehttp
.ListenerResourceAnnouncer
to announceHostAndPortWithScheme
instead ofHostAndPort
. IftlsPort
is valid then host and tls port withhttps
scheme will be used otherwise plainText port andhttp
will be used.PasswordProvider
to includegetPassword(key)
to support getting other passwords than just Metadata Storage Connector password. More details in comment inPasswordProvider
class.SSLContext
is bound then that would be used with the client. Therefore, keeping it the same way but providing a sample implementation module (in extensions-core) that creates an example context, good enough for most simple cases.TODO -
3. DocumentationI have tested the changes locally.