Skip to content

Support Kerberos authentication between nodes#9683

Merged
arhimondr merged 4 commits intoprestodb:masterfrom
starburstdata:anu/kerberos_auth_between_nodes
Jul 20, 2018
Merged

Support Kerberos authentication between nodes#9683
arhimondr merged 4 commits intoprestodb:masterfrom
starburstdata:anu/kerberos_auth_between_nodes

Conversation

@anusudarsan
Copy link
Contributor

Supersedes #8859.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not invalid method argument but invalid configuration. Should you throw configuration related exception here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm..looks like we valid configs in other places the same way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed? I see that here com/facebook/presto/server/security/KerberosAuthenticator.java:68 it is dynamically evaluated from serviceName

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In com.facebook.presto.server.security.KerberosConfig#getKeytab it is nullable, does it have to be non null here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. that assumption is good here as well. removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are setting different things, but they have to match, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya looks cleaner. done.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no impersonation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think there is any specific reason. just chose one of the simple kerberos configs.

.travis.yml Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add description of this environment to README file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double licence

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why it fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need to define new tempto configuration file, I thought you reuse file which is used other kerberized environment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch from 7b5538d to 45fe2bd Compare January 9, 2018 21:20
Copy link
Contributor Author

@anusudarsan anusudarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kokosing addressed comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think there is any specific reason. just chose one of the simple kerberos configs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its already tested below at line 101?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. that assumption is good here as well. removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably. but that is not part of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya looks cleaner. done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@anusudarsan
Copy link
Contributor Author

@electrum I have also addressed your comments from here-
#8859 (review) . Please take a look.

Copy link
Contributor

@electrum electrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with these, shouldn't it be the same as KerberosConfig?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check to verify both matches.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are setting different things, but they have to match, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module is already quite long. How about we move the internal communication stuff into a separate InternalCommunicationModule?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. created a new module

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the class be private?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this public since it's part of the API

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make public and move to the top

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for break here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this document _HOST?

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch 2 times, most recently from a13745e to 9c9f1e1 Compare March 29, 2018 21:09
Copy link
Contributor Author

@anusudarsan anusudarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@electrum addressed your comments. please take another look.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check to verify both matches.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done. created a new module

@anusudarsan
Copy link
Contributor Author

related - #10317

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch 2 times, most recently from f2a6a3a to 2801eb0 Compare April 3, 2018 15:19
@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch 2 times, most recently from 271a310 to d8ebc56 Compare June 15, 2018 15:49
@panditsurabhi
Copy link

We are awaiting this change. Is it going to be merged soon? What's the ETA?

@kokosing
Copy link
Contributor

@anusudarsan Could you please rebase?
@arhimondr Could you please review?

Copy link
Member

@arhimondr arhimondr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the one from the server config, remove this property

{
private String kerberosPrincipal;
private String kerberosServiceName;
private File kerberosKeytab;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the one from the server config, remove this property

private String kerberosPrincipal;
private String kerberosServiceName;
private File kerberosKeytab;
private File kerberosConfig;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal-communication.kerberos.enabled

return kerberosUseCanonicalHostname;
}

@Config("internal-communication.authentication.krb5.use-canonical-hostname")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal-communication.kerberos.use-canonical-hostname

*/
package com.facebook.presto.server;

import com.facebook.presto.util.KerberosPrincipal;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally i would just drop the smoke group here, so you don't have do exclude the stats_client group.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it needed? http is disabled

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch from d8ebc56 to e2dbb6e Compare July 16, 2018 20:11
Copy link
Contributor Author

@anusudarsan anusudarsan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arhimondr addressed all comments

presto:
host: presto-master.docker.cluster
port: 7778
http_port: 8080
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Coordinator/server

Copy link
Member

@arhimondr arhimondr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM % few comments

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clientKerberosConfig?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UncheckedIOException

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getServiceName and getKerberosConfig are marked as @NotNull, and being validated during the KerberosConfig configuration creation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch from e2dbb6e to 723d5c2 Compare July 17, 2018 22:49
@anusudarsan
Copy link
Contributor Author

@arhimondr addressed comments

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch from 723d5c2 to dda62ca Compare July 17, 2018 22:59
@anusudarsan
Copy link
Contributor Author

@arhimondr ping :)

@findepi
Copy link
Contributor

findepi commented Jul 20, 2018

@arhimondr i think i will just merge this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just add a message here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Contributor Author

@anusudarsan anusudarsan Jul 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure. that sounds good to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also point to internal-communication.kerberos.enabled in the message?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that would work

@anusudarsan anusudarsan force-pushed the anu/kerberos_auth_between_nodes branch 2 times, most recently from 927c755 to 28ed737 Compare July 20, 2018 21:14
@arhimondr arhimondr force-pushed the anu/kerberos_auth_between_nodes branch from 28ed737 to f08e10b Compare July 20, 2018 21:22
@arhimondr arhimondr force-pushed the anu/kerberos_auth_between_nodes branch from f08e10b to 3b50e03 Compare July 20, 2018 21:27
@arhimondr arhimondr merged commit 3b50e03 into prestodb:master Jul 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants