Revert "HBASE-25665 Option to use hostname instead of canonical hostname for secure HBase cluster connection (#3051)"
This reverts commit 90c147f97c
.
Reverting because new feature and only want bug fixes on branches.
This commit is contained in:
parent
90c147f97c
commit
7de67b30fc
|
@ -26,7 +26,6 @@ import javax.security.sasl.SaslClient;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hbase.security.SaslUtil;
|
import org.apache.hadoop.hbase.security.SaslUtil;
|
||||||
import org.apache.hadoop.hbase.security.SecurityConstants;
|
|
||||||
import org.apache.hadoop.hbase.security.SecurityInfo;
|
import org.apache.hadoop.hbase.security.SecurityInfo;
|
||||||
import org.apache.hadoop.hbase.security.User;
|
import org.apache.hadoop.hbase.security.User;
|
||||||
import org.apache.hadoop.security.SecurityUtil;
|
import org.apache.hadoop.security.SecurityUtil;
|
||||||
|
@ -45,40 +44,15 @@ public class GssSaslClientAuthenticationProvider extends GssSaslAuthenticationPr
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(
|
private static final Logger LOG = LoggerFactory.getLogger(
|
||||||
GssSaslClientAuthenticationProvider.class);
|
GssSaslClientAuthenticationProvider.class);
|
||||||
|
|
||||||
private static boolean useCanonicalHostname(Configuration conf) {
|
|
||||||
return !conf.getBoolean(
|
|
||||||
SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS,
|
|
||||||
SecurityConstants.DEFAULT_UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getHostnameForServerPrincipal(Configuration conf, InetAddress addr) {
|
|
||||||
final String hostname;
|
|
||||||
|
|
||||||
if (useCanonicalHostname(conf)) {
|
|
||||||
hostname = addr.getCanonicalHostName();
|
|
||||||
if (hostname.equals(addr.getHostAddress())) {
|
|
||||||
LOG.warn("Canonical hostname for SASL principal is the same with IP address: "
|
|
||||||
+ hostname + ", " + addr.getHostName() + ". Check DNS configuration or consider "
|
|
||||||
+ SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS
|
|
||||||
+ "=true");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hostname = addr.getHostName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return hostname.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
String getServerPrincipal(Configuration conf, SecurityInfo securityInfo, InetAddress server)
|
String getServerPrincipal(Configuration conf, SecurityInfo securityInfo, InetAddress server)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
String hostname = getHostnameForServerPrincipal(conf, server);
|
|
||||||
|
|
||||||
String serverKey = securityInfo.getServerPrincipal();
|
String serverKey = securityInfo.getServerPrincipal();
|
||||||
if (serverKey == null) {
|
if (serverKey == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't obtain server Kerberos config key from SecurityInfo");
|
"Can't obtain server Kerberos config key from SecurityInfo");
|
||||||
}
|
}
|
||||||
return SecurityUtil.getServerPrincipal(conf.get(serverKey), hostname);
|
return SecurityUtil.getServerPrincipal(conf.get(serverKey),
|
||||||
|
server.getCanonicalHostName().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hbase.security;
|
package org.apache.hadoop.hbase.security;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
|
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,18 +34,7 @@ public final class SecurityConstants {
|
||||||
public static final String REGIONSERVER_KRB_PRINCIPAL = "hbase.regionserver.kerberos.principal";
|
public static final String REGIONSERVER_KRB_PRINCIPAL = "hbase.regionserver.kerberos.principal";
|
||||||
public static final String REGIONSERVER_KRB_KEYTAB_FILE = "hbase.regionserver.keytab.file";
|
public static final String REGIONSERVER_KRB_KEYTAB_FILE = "hbase.regionserver.keytab.file";
|
||||||
|
|
||||||
/**
|
|
||||||
* This config is for experts: don't set its value unless you really know what you are doing.
|
|
||||||
* When set to true, HBase client using SASL Kerberos will skip reverse DNS lookup and use provided
|
|
||||||
* hostname of the destination for the principal instead. See https://issues.apache.org/jira/browse/HBASE-25665
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
|
|
||||||
public static final String UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS =
|
|
||||||
"hbase.unsafe.client.kerberos.hostname.disable.reversedns";
|
|
||||||
public static final boolean DEFAULT_UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS = false;
|
|
||||||
|
|
||||||
private SecurityConstants() {
|
private SecurityConstants() {
|
||||||
// Can't be instantiated with this ctor.
|
// Can't be instantiated with this ctor.
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1196,14 +1196,6 @@ possible configurations would overwhelm and obscure the important.
|
||||||
be used as a temporary measure while converting clients over to secure authentication. It
|
be used as a temporary measure while converting clients over to secure authentication. It
|
||||||
MUST BE DISABLED for secure operation.</description>
|
MUST BE DISABLED for secure operation.</description>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
|
||||||
<name>hbase.unsafe.client.kerberos.hostname.disable.reversedns</name>
|
|
||||||
<value>false</value>
|
|
||||||
<description>This config is for experts: don't set its value unless you really know what you are doing.
|
|
||||||
When set to true, HBase client using SASL Kerberos will skip reverse DNS lookup and use provided
|
|
||||||
hostname of the destination for the principal instead. See https://issues.apache.org/jira/browse/HBASE-25665
|
|
||||||
for more details.</description>
|
|
||||||
</property>
|
|
||||||
<property>
|
<property>
|
||||||
<name>hbase.display.keys</name>
|
<name>hbase.display.keys</name>
|
||||||
<value>true</value>
|
<value>true</value>
|
||||||
|
|
|
@ -22,7 +22,6 @@ import static org.apache.hadoop.hbase.ipc.TestProtobufRpcServiceImpl.newBlocking
|
||||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
|
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getKeytabFileForTesting;
|
||||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
|
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getPrincipalForTesting;
|
||||||
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getSecuredConfiguration;
|
import static org.apache.hadoop.hbase.security.HBaseKerberosUtils.getSecuredConfiguration;
|
||||||
import static org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProviders.SELECTOR_KEY;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotSame;
|
import static org.junit.Assert.assertNotSame;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
|
@ -30,16 +29,12 @@ import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import javax.security.sasl.SaslClient;
|
|
||||||
import javax.security.sasl.SaslException;
|
import javax.security.sasl.SaslException;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
@ -57,18 +52,11 @@ import org.apache.hadoop.hbase.ipc.RpcServer;
|
||||||
import org.apache.hadoop.hbase.ipc.RpcServerFactory;
|
import org.apache.hadoop.hbase.ipc.RpcServerFactory;
|
||||||
import org.apache.hadoop.hbase.ipc.RpcServerInterface;
|
import org.apache.hadoop.hbase.ipc.RpcServerInterface;
|
||||||
import org.apache.hadoop.hbase.ipc.SimpleRpcServer;
|
import org.apache.hadoop.hbase.ipc.SimpleRpcServer;
|
||||||
import org.apache.hadoop.hbase.security.provider.AuthenticationProviderSelector;
|
|
||||||
import org.apache.hadoop.hbase.security.provider.BuiltInProviderSelector;
|
|
||||||
import org.apache.hadoop.hbase.security.provider.SaslAuthMethod;
|
|
||||||
import org.apache.hadoop.hbase.security.provider.SaslClientAuthenticationProvider;
|
|
||||||
import org.apache.hadoop.hbase.testclassification.LargeTests;
|
import org.apache.hadoop.hbase.testclassification.LargeTests;
|
||||||
import org.apache.hadoop.hbase.testclassification.SecurityTests;
|
import org.apache.hadoop.hbase.testclassification.SecurityTests;
|
||||||
import org.apache.hadoop.hbase.util.Pair;
|
|
||||||
import org.apache.hadoop.minikdc.MiniKdc;
|
import org.apache.hadoop.minikdc.MiniKdc;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
|
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
|
||||||
import org.apache.hadoop.security.token.Token;
|
|
||||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -88,7 +76,6 @@ import org.apache.hbase.thirdparty.com.google.protobuf.BlockingService;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos;
|
import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestProtos;
|
||||||
import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
|
import org.apache.hadoop.hbase.shaded.ipc.protobuf.generated.TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface;
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.UserInformation;
|
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
@Category({ SecurityTests.class, LargeTests.class })
|
@Category({ SecurityTests.class, LargeTests.class })
|
||||||
|
@ -177,117 +164,6 @@ public class TestSecureIPC {
|
||||||
callRpcService(User.create(ugi2));
|
callRpcService(User.create(ugi2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRpcCallWithEnabledKerberosSaslAuth_CanonicalHostname() throws Exception {
|
|
||||||
UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
|
|
||||||
|
|
||||||
// check that the login user is okay:
|
|
||||||
assertSame(ugi2, ugi);
|
|
||||||
assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
|
|
||||||
assertEquals(krbPrincipal, ugi.getUserName());
|
|
||||||
|
|
||||||
enableCanonicalHostnameTesting(clientConf, "localhost");
|
|
||||||
clientConf.setBoolean(
|
|
||||||
SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS, false);
|
|
||||||
clientConf.set(HBaseKerberosUtils.KRB_PRINCIPAL, "hbase/_HOST@" + KDC.getRealm());
|
|
||||||
|
|
||||||
callRpcService(User.create(ugi2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRpcCallWithEnabledKerberosSaslAuth_NoCanonicalHostname() throws Exception {
|
|
||||||
UserGroupInformation ugi2 = UserGroupInformation.getCurrentUser();
|
|
||||||
|
|
||||||
// check that the login user is okay:
|
|
||||||
assertSame(ugi2, ugi);
|
|
||||||
assertEquals(AuthenticationMethod.KERBEROS, ugi.getAuthenticationMethod());
|
|
||||||
assertEquals(krbPrincipal, ugi.getUserName());
|
|
||||||
|
|
||||||
enableCanonicalHostnameTesting(clientConf, "127.0.0.1");
|
|
||||||
clientConf.setBoolean(
|
|
||||||
SecurityConstants.UNSAFE_HBASE_CLIENT_KERBEROS_HOSTNAME_DISABLE_REVERSEDNS, true);
|
|
||||||
clientConf.set(HBaseKerberosUtils.KRB_PRINCIPAL, "hbase/_HOST@" + KDC.getRealm());
|
|
||||||
|
|
||||||
callRpcService(User.create(ugi2));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void enableCanonicalHostnameTesting(Configuration conf, String canonicalHostname) {
|
|
||||||
conf.setClass(SELECTOR_KEY,
|
|
||||||
CanonicalHostnameTestingAuthenticationProviderSelector.class,
|
|
||||||
AuthenticationProviderSelector.class);
|
|
||||||
conf.set(CanonicalHostnameTestingAuthenticationProviderSelector.CANONICAL_HOST_NAME_KEY,
|
|
||||||
canonicalHostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CanonicalHostnameTestingAuthenticationProviderSelector extends
|
|
||||||
BuiltInProviderSelector {
|
|
||||||
private static final String CANONICAL_HOST_NAME_KEY =
|
|
||||||
"CanonicalHostnameTestingAuthenticationProviderSelector.canonicalHostName";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pair<SaslClientAuthenticationProvider, Token<? extends TokenIdentifier>> selectProvider(
|
|
||||||
String clusterId, User user) {
|
|
||||||
final Pair<SaslClientAuthenticationProvider, Token<? extends TokenIdentifier>> pair =
|
|
||||||
super.selectProvider(clusterId, user);
|
|
||||||
pair.setFirst(createCanonicalHostNameTestingProvider(pair.getFirst()));
|
|
||||||
return pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaslClientAuthenticationProvider createCanonicalHostNameTestingProvider(
|
|
||||||
SaslClientAuthenticationProvider delegate) {
|
|
||||||
return new SaslClientAuthenticationProvider() {
|
|
||||||
@Override
|
|
||||||
public SaslClient createClient(Configuration conf, InetAddress serverAddr,
|
|
||||||
SecurityInfo securityInfo, Token<? extends TokenIdentifier> token,
|
|
||||||
boolean fallbackAllowed, Map<String, String> saslProps) throws IOException {
|
|
||||||
final String s =
|
|
||||||
conf.get(CANONICAL_HOST_NAME_KEY);
|
|
||||||
if (s != null) {
|
|
||||||
try {
|
|
||||||
final Field canonicalHostName = InetAddress.class.getDeclaredField("canonicalHostName");
|
|
||||||
canonicalHostName.setAccessible(true);
|
|
||||||
canonicalHostName.set(serverAddr, s);
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return delegate.createClient(conf, serverAddr, securityInfo, token, fallbackAllowed, saslProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserInformation getUserInfo(User user) {
|
|
||||||
return delegate.getUserInfo(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserGroupInformation getRealUser(User ugi) {
|
|
||||||
return delegate.getRealUser(ugi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canRetry() {
|
|
||||||
return delegate.canRetry();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void relogin() throws IOException {
|
|
||||||
delegate.relogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SaslAuthMethod getSaslAuthMethod() {
|
|
||||||
return delegate.getSaslAuthMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTokenKind() {
|
|
||||||
return delegate.getTokenKind();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRpcFallbackToSimpleAuth() throws Exception {
|
public void testRpcFallbackToSimpleAuth() throws Exception {
|
||||||
String clientUsername = "testuser";
|
String clientUsername = "testuser";
|
||||||
|
|
Loading…
Reference in New Issue