Support Kerberos authentication between nodes#9683
Support Kerberos authentication between nodes#9683arhimondr merged 4 commits intoprestodb:masterfrom
Conversation
There was a problem hiding this comment.
it is not invalid method argument but invalid configuration. Should you throw configuration related exception here?
There was a problem hiding this comment.
hmm..looks like we valid configs in other places the same way.
There was a problem hiding this comment.
Another way to do this is to put the Kerberos configs in a separate class. This allows the properties to be @NotNull and thus they will be validated by the config system (which has good error messages). The class is only bound/requested if the isKerberosEnabled flag is set.
This is similar to how it works in the Hive connector where HdfsKerberosConfig has required properties but the config class is only bound when Kerberos is enabled.
There was a problem hiding this comment.
is this needed? I see that here com/facebook/presto/server/security/KerberosAuthenticator.java:68 it is dynamically evaluated from serviceName
There was a problem hiding this comment.
ya, but this is for setting io.airlift.http.client.HttpClientConfig which is by the http client between nodes. See https://github.com/airlift/airlift/blob/master/http-client/src/main/java/io/airlift/http/client/spnego/SpnegoAuthentication.java#L84
There was a problem hiding this comment.
Wouldn't this need to match http.server.authentication.krb5.service-name from KerberosConfig? Or will this be different after the next commit because it contains a _HOST placeholder?
There was a problem hiding this comment.
In com.facebook.presto.server.security.KerberosConfig#getKeytab it is nullable, does it have to be non null here?
There was a problem hiding this comment.
right. that assumption is good here as well. removed
There was a problem hiding this comment.
how does it relate to KerberosConfig configured in com/facebook/presto/server/security/ServerSecurityModule.java:50
What will happen if internal kerberos communication does not match server kerboros communication? WIll one overwrite the other?
There was a problem hiding this comment.
This one is different and is setting io.airlift.http.client.spnego.KerberosConfig which is used by the http client between nodes. Also see io.airlift.http.client.spnego.SpnegoAuthentication similar to KerberosAuthenticator.
There was a problem hiding this comment.
They are setting different things, but they have to match, right?
There was a problem hiding this comment.
Maybe you could have internal static class Parser and store parsing related code there. What do you think? Having this class defined at the bottom would not polute this file and would make the most important things to be at the top of the class.
There was a problem hiding this comment.
ya looks cleaner. done.
There was a problem hiding this comment.
I dont think there is any specific reason. just chose one of the simple kerberos configs.
.travis.yml
Outdated
There was a problem hiding this comment.
add description of this environment to README file
There was a problem hiding this comment.
This is using the HttpQueryStatsClient and hence fail with encrypted connection. Previously we never ran smoke group with multinode-tls tests, but with this profile we do.
There was a problem hiding this comment.
do you need to define new tempto configuration file, I thought you reuse file which is used other kerberized environment
There was a problem hiding this comment.
The only difference from the other kerberos config is that, this one defines http_port (line 22) which is needed by TLS test group (there is an assertion to test the http port is actually closed). I added this property to the other file and deleted this one.
7b5538d to
45fe2bd
Compare
anusudarsan
left a comment
There was a problem hiding this comment.
@kokosing addressed comments
There was a problem hiding this comment.
The only difference from the other kerberos config is that, this one defines http_port (line 22) which is needed by TLS test group (there is an assertion to test the http port is actually closed). I added this property to the other file and deleted this one.
There was a problem hiding this comment.
This is using the HttpQueryStatsClient and hence fail with encrypted connection. Previously we never ran smoke group with multinode-tls tests, but with this profile we do.
There was a problem hiding this comment.
I dont think there is any specific reason. just chose one of the simple kerberos configs.
There was a problem hiding this comment.
its already tested below at line 101?
There was a problem hiding this comment.
right. that assumption is good here as well. removed
There was a problem hiding this comment.
This one is different and is setting io.airlift.http.client.spnego.KerberosConfig which is used by the http client between nodes. Also see io.airlift.http.client.spnego.SpnegoAuthentication similar to KerberosAuthenticator.
There was a problem hiding this comment.
ya, but this is for setting io.airlift.http.client.HttpClientConfig which is by the http client between nodes. See https://github.com/airlift/airlift/blob/master/http-client/src/main/java/io/airlift/http/client/spnego/SpnegoAuthentication.java#L84
There was a problem hiding this comment.
probably. but that is not part of this PR.
There was a problem hiding this comment.
ya looks cleaner. done.
There was a problem hiding this comment.
this will just be appending the SEPARATORs to the username/hostname/realm, right? the actual escaping happens in parse and the escape characters will be retained in the variables here.
|
@electrum I have also addressed your comments from here- |
electrum
left a comment
There was a problem hiding this comment.
Overall this looks good. I have some concerns about the duplicated config parameters that must be the same value (as far as I can tell).
There was a problem hiding this comment.
Wouldn't this need to match http.server.authentication.krb5.service-name from KerberosConfig? Or will this be different after the next commit because it contains a _HOST placeholder?
There was a problem hiding this comment.
Same with these, shouldn't it be the same as KerberosConfig?
There was a problem hiding this comment.
Added a check to verify both matches.
There was a problem hiding this comment.
Another way to do this is to put the Kerberos configs in a separate class. This allows the properties to be @NotNull and thus they will be validated by the config system (which has good error messages). The class is only bound/requested if the isKerberosEnabled flag is set.
This is similar to how it works in the Hive connector where HdfsKerberosConfig has required properties but the config class is only bound when Kerberos is enabled.
There was a problem hiding this comment.
They are setting different things, but they have to match, right?
There was a problem hiding this comment.
This module is already quite long. How about we move the internal communication stuff into a separate InternalCommunicationModule?
There was a problem hiding this comment.
done. created a new module
There was a problem hiding this comment.
Make this public since it's part of the API
There was a problem hiding this comment.
Make public and move to the top
There was a problem hiding this comment.
Should this document _HOST?
a13745e to
9c9f1e1
Compare
anusudarsan
left a comment
There was a problem hiding this comment.
@electrum addressed your comments. please take another look.
There was a problem hiding this comment.
Added a check to verify both matches.
There was a problem hiding this comment.
done. created a new module
|
related - #10317 |
f2a6a3a to
2801eb0
Compare
271a310 to
d8ebc56
Compare
|
We are awaiting this change. Is it going to be merged soon? What's the ETA? |
|
@anusudarsan Could you please rebase? |
arhimondr
left a comment
There was a problem hiding this comment.
Please let me have an another look before you merge. Also please fix the commit history (git rebase "$(git merge-base HEAD master)" --ignore-date -x 'git commit --amend -C HEAD --date="$(date -R)" && sleep 1.05') (Thanks @findepi , sorry, didn't find the original paste)
| KerberosInternalCommunicationConfig internalKerberosConfig = buildConfigObject(KerberosInternalCommunicationConfig.class); | ||
| com.facebook.presto.server.security.KerberosConfig serverKerberosConfig = buildConfigObject(com.facebook.presto.server.security.KerberosConfig.class); | ||
|
|
||
| checkState(serverKerberosConfig.getKeytab() != null && serverKerberosConfig.getKeytab().getAbsolutePath().equals(internalKerberosConfig.getKerberosKeytab().getAbsolutePath()), "kerberos keytab values must match"); |
There was a problem hiding this comment.
Since we are doing these checks, do we actually need 2 type of properties (for the client and for the server). Can we just use these properties from the server config?
|
|
||
| public class KerberosInternalCommunicationConfig | ||
| { | ||
| private String kerberosPrincipal; |
There was a problem hiding this comment.
You can build it based on the service name. kerberosPrincipal=<kerberosServiceName>/_HOST, and it should get the realm from the config. See https://github.com/prestodb/presto/blob/master/presto-main/src/main/java/com/facebook/presto/server/security/KerberosAuthenticator.java#L68
We are using this convention to build the service principal for the server. I thing we can safely follow the approach to build a client principal as well.
| public class KerberosInternalCommunicationConfig | ||
| { | ||
| private String kerberosPrincipal; | ||
| private String kerberosServiceName; |
There was a problem hiding this comment.
Use the one from the server config, remove this property
| { | ||
| private String kerberosPrincipal; | ||
| private String kerberosServiceName; | ||
| private File kerberosKeytab; |
There was a problem hiding this comment.
Use the one from the server config, remove this property
| private String kerberosPrincipal; | ||
| private String kerberosServiceName; | ||
| private File kerberosKeytab; | ||
| private File kerberosConfig; |
There was a problem hiding this comment.
Use the one from the server config, remove this property. (this one is a static one property, JVM wide)
| return kerberosEnabled; | ||
| } | ||
|
|
||
| @Config("internal-communication.authentication.kerberos.enabled") |
There was a problem hiding this comment.
internal-communication.kerberos.enabled
| return kerberosUseCanonicalHostname; | ||
| } | ||
|
|
||
| @Config("internal-communication.authentication.krb5.use-canonical-hostname") |
There was a problem hiding this comment.
internal-communication.kerberos.use-canonical-hostname
| */ | ||
| package com.facebook.presto.server; | ||
|
|
||
| import com.facebook.presto.util.KerberosPrincipal; |
There was a problem hiding this comment.
If you build the principal name based on the service name you will no longer need this commit. Feel free to drop it.
.travis.yml
Outdated
| fi | ||
| if [[ -v PRODUCT_TESTS_SPECIFIC_ENVIRONMENT ]]; then | ||
| presto-product-tests/bin/run_on_docker.sh \ | ||
| multinode-tls-kerberos -g smoke,cli,group-by,join,tls -x stats_client |
There was a problem hiding this comment.
Personally i would just drop the smoke group here, so you don't have do exclude the stats_client group.
There was a problem hiding this comment.
The idea with group-by and join here is to make the Presto do the exchanges.
| presto: | ||
| host: presto-master.docker.cluster | ||
| port: 7778 | ||
| http_port: 8080 |
There was a problem hiding this comment.
Why is it needed? http is disabled
There was a problem hiding this comment.
ya. but we run TLS test group (TlsTests) now in this profile. This property is used there to test if http_port is not actually being used.
d8ebc56 to
e2dbb6e
Compare
anusudarsan
left a comment
There was a problem hiding this comment.
@arhimondr addressed all comments
| presto: | ||
| host: presto-master.docker.cluster | ||
| port: 7778 | ||
| http_port: 8080 |
There was a problem hiding this comment.
ya. but we run TLS test group (TlsTests) now in this profile. This property is used there to test if http_port is not actually being used.
There was a problem hiding this comment.
getServiceName and getKerberosConfig are marked as @NotNull, and being validated during the KerberosConfig configuration creation
There was a problem hiding this comment.
I wonder if there is better exception than NullPointerException. NPE for the end user looks like a bug in the code. How about io.airlift.configuration.InvalidConfigurationException?
e2dbb6e to
723d5c2
Compare
|
@arhimondr addressed comments |
723d5c2 to
dda62ca
Compare
|
@arhimondr ping :) |
|
@arhimondr i think i will just merge this |
There was a problem hiding this comment.
Let's just add a message here
There was a problem hiding this comment.
@findepi I can add the message and merge. Lets just figure out the message. How about
"http.server.authentication.krb5.keytab must be set when kerberos authentication for internal communication is enabled"
We can extract http.server.authentication.krb5.keytab into a constant ofcourse.
There was a problem hiding this comment.
sure. that sounds good to me
There was a problem hiding this comment.
maybe also point to internal-communication.kerberos.enabled in the message?
927c755 to
28ed737
Compare
28ed737 to
f08e10b
Compare
f08e10b to
3b50e03
Compare
Supersedes #8859.