HADOOP-10982
This commit is contained in:
parent
0a495bef5c
commit
d9a86031a0
@ -45,6 +45,7 @@
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -400,6 +401,8 @@ public HttpURLConnection run() throws Exception {
|
|||||||
});
|
});
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
|
} catch (UndeclaredThrowableException ex) {
|
||||||
|
throw new IOException(ex.getUndeclaredThrowable());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IOException(ex);
|
throw new IOException(ex);
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,31 @@ $ keytool -genkey -alias tomcat -keyalg RSA
|
|||||||
|
|
||||||
*** HTTP Kerberos Principals Configuration
|
*** HTTP Kerberos Principals Configuration
|
||||||
|
|
||||||
TBD
|
When KMS instances are behind a load-balancer or VIP, clients will use the
|
||||||
|
hostname of the VIP. For Kerberos SPNEGO authentication, the hostname of the
|
||||||
|
URL is used to construct the Kerberos service name of the server,
|
||||||
|
<<<HTTP/#HOSTNAME#>>>. This means that all KMS instances must have have a
|
||||||
|
Kerberos service name with the load-balancer or VIP hostname.
|
||||||
|
|
||||||
|
In order to be able to access directly a specific KMS instance, the KMS
|
||||||
|
instance must also have Kebero service name with its own hostname. This is
|
||||||
|
require for monitoring and admin purposes.
|
||||||
|
|
||||||
|
Both Kerberos service principal credentials (for the load-balancer/VIP
|
||||||
|
hostname and for the actual KMS instance hostname) must be in the keytab file
|
||||||
|
configured for authentication. And the principal name specified in the
|
||||||
|
configuration must be '*'. For example:
|
||||||
|
|
||||||
|
+---+
|
||||||
|
<property>
|
||||||
|
<name>hadoop.kms.authentication.kerberos.principal</name>
|
||||||
|
<value>*</value>
|
||||||
|
</property>
|
||||||
|
+---+
|
||||||
|
|
||||||
|
<<NOTE:>> If using HTTPS, the SSL certificate used by the KMS instance must
|
||||||
|
be configured to support multiple hostnames (see Java 7
|
||||||
|
<<<keytool>> SAN extension support for details on how to do this).
|
||||||
|
|
||||||
*** HTTP Authentication Signature
|
*** HTTP Authentication Signature
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
import org.apache.hadoop.security.Credentials;
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.SecurityUtil;
|
import org.apache.hadoop.security.SecurityUtil;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
|
import org.apache.hadoop.security.authentication.client.AuthenticationException;
|
||||||
import org.apache.hadoop.security.authorize.AuthorizationException;
|
import org.apache.hadoop.security.authorize.AuthorizationException;
|
||||||
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
|
import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
@ -209,6 +210,7 @@ public static void setUpMiniKdc() throws Exception {
|
|||||||
keytab = new File(kdcDir, "keytab");
|
keytab = new File(kdcDir, "keytab");
|
||||||
List<String> principals = new ArrayList<String>();
|
List<String> principals = new ArrayList<String>();
|
||||||
principals.add("HTTP/localhost");
|
principals.add("HTTP/localhost");
|
||||||
|
principals.add("HTTP/127.0.0.1");
|
||||||
principals.add("client");
|
principals.add("client");
|
||||||
principals.add("hdfs");
|
principals.add("hdfs");
|
||||||
principals.add("otheradmin");
|
principals.add("otheradmin");
|
||||||
@ -251,8 +253,8 @@ private <T> T doAs(String user, final PrivilegedExceptionAction<T> action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartStop(final boolean ssl, final boolean kerberos)
|
public void testStartStop(final boolean ssl, final boolean kerberos,
|
||||||
throws Exception {
|
final boolean multipleServerPrincipals) throws Exception {
|
||||||
Configuration conf = new Configuration();
|
Configuration conf = new Configuration();
|
||||||
if (kerberos) {
|
if (kerberos) {
|
||||||
conf.set("hadoop.security.authentication", "kerberos");
|
conf.set("hadoop.security.authentication", "kerberos");
|
||||||
@ -278,7 +280,12 @@ public void testStartStop(final boolean ssl, final boolean kerberos)
|
|||||||
conf.set("hadoop.kms.authentication.type", "kerberos");
|
conf.set("hadoop.kms.authentication.type", "kerberos");
|
||||||
conf.set("hadoop.kms.authentication.kerberos.keytab",
|
conf.set("hadoop.kms.authentication.kerberos.keytab",
|
||||||
keytab.getAbsolutePath());
|
keytab.getAbsolutePath());
|
||||||
conf.set("hadoop.kms.authentication.kerberos.principal", "HTTP/localhost");
|
if (multipleServerPrincipals) {
|
||||||
|
conf.set("hadoop.kms.authentication.kerberos.principal", "*");
|
||||||
|
} else {
|
||||||
|
conf.set("hadoop.kms.authentication.kerberos.principal",
|
||||||
|
"HTTP/localhost");
|
||||||
|
}
|
||||||
conf.set("hadoop.kms.authentication.kerberos.name.rules", "DEFAULT");
|
conf.set("hadoop.kms.authentication.kerberos.name.rules", "DEFAULT");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,21 +298,42 @@ public Void call() throws Exception {
|
|||||||
URL url = getKMSUrl();
|
URL url = getKMSUrl();
|
||||||
Assert.assertEquals(keystore != null,
|
Assert.assertEquals(keystore != null,
|
||||||
url.getProtocol().equals("https"));
|
url.getProtocol().equals("https"));
|
||||||
final URI uri = createKMSUri(getKMSUrl());
|
|
||||||
|
|
||||||
if (kerberos) {
|
if (kerberos) {
|
||||||
for (String user : new String[]{"client", "client/host"}) {
|
for (String user : new String[]{"client", "client/host"}) {
|
||||||
doAs(user, new PrivilegedExceptionAction<Void>() {
|
doAs(user, new PrivilegedExceptionAction<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void run() throws Exception {
|
public Void run() throws Exception {
|
||||||
final KeyProvider kp = new KMSClientProvider(uri, conf);
|
URI uri = createKMSUri(getKMSUrl());
|
||||||
|
KeyProvider kp = new KMSClientProvider(uri, conf);
|
||||||
// getKeys() empty
|
// getKeys() empty
|
||||||
Assert.assertTrue(kp.getKeys().isEmpty());
|
Assert.assertTrue(kp.getKeys().isEmpty());
|
||||||
|
|
||||||
|
if (!ssl) {
|
||||||
|
String url = getKMSUrl().toString();
|
||||||
|
url = url.replace("localhost", "127.0.0.1");
|
||||||
|
uri = createKMSUri(new URL(url));
|
||||||
|
if (multipleServerPrincipals) {
|
||||||
|
kp = new KMSClientProvider(uri, conf);
|
||||||
|
// getKeys() empty
|
||||||
|
Assert.assertTrue(kp.getKeys().isEmpty());
|
||||||
|
} else {
|
||||||
|
kp = new KMSClientProvider(uri, conf);
|
||||||
|
try {
|
||||||
|
kp.getKeys().isEmpty();
|
||||||
|
Assert.fail();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Assert.assertEquals(AuthenticationException.class,
|
||||||
|
ex.getCause().getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
URI uri = createKMSUri(getKMSUrl());
|
||||||
KeyProvider kp = new KMSClientProvider(uri, conf);
|
KeyProvider kp = new KMSClientProvider(uri, conf);
|
||||||
// getKeys() empty
|
// getKeys() empty
|
||||||
Assert.assertTrue(kp.getKeys().isEmpty());
|
Assert.assertTrue(kp.getKeys().isEmpty());
|
||||||
@ -317,22 +345,27 @@ public Void run() throws Exception {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartStopHttpPseudo() throws Exception {
|
public void testStartStopHttpPseudo() throws Exception {
|
||||||
testStartStop(false, false);
|
testStartStop(false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartStopHttpsPseudo() throws Exception {
|
public void testStartStopHttpsPseudo() throws Exception {
|
||||||
testStartStop(true, false);
|
testStartStop(true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartStopHttpKerberos() throws Exception {
|
public void testStartStopHttpKerberos() throws Exception {
|
||||||
testStartStop(false, true);
|
testStartStop(false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartStopHttpsKerberos() throws Exception {
|
public void testStartStopHttpsKerberos() throws Exception {
|
||||||
testStartStop(true, true);
|
testStartStop(true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStartStopHttpsKerberosMultiplePrincipals() throws Exception {
|
||||||
|
testStartStop(false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1340,7 +1373,8 @@ public Void call() throws Exception {
|
|||||||
KeyProvider kp = new KMSClientProvider(uri, conf);
|
KeyProvider kp = new KMSClientProvider(uri, conf);
|
||||||
kp.createKey("kA", new KeyProvider.Options(conf));
|
kp.createKey("kA", new KeyProvider.Options(conf));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.out.println(ex.getMessage());
|
Assert.assertEquals(AuthenticationException.class,
|
||||||
|
ex.getCause().getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
doAs("client", new PrivilegedExceptionAction<Void>() {
|
doAs("client", new PrivilegedExceptionAction<Void>() {
|
||||||
|
Loading…
Reference in New Issue
Block a user