HDFS-6219. Proxy superuser configuration should use true client IP for address checks. Contributed by Daryn Sharp.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1587962 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5e47eeca9d
commit
ef68759382
|
@ -125,6 +125,9 @@ Trunk (Unreleased)
|
||||||
|
|
||||||
HDFS-6228. comments typo fix for FsDatasetImpl.java (zhaoyunjiong via umamahesh)
|
HDFS-6228. comments typo fix for FsDatasetImpl.java (zhaoyunjiong via umamahesh)
|
||||||
|
|
||||||
|
HDFS-6219. Proxy superuser configuration should use true client IP for
|
||||||
|
address checks. (daryn via kihwal)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -646,7 +647,7 @@ public class JspHelper {
|
||||||
if (doAsUserFromQuery != null) {
|
if (doAsUserFromQuery != null) {
|
||||||
// create and attempt to authorize a proxy user
|
// create and attempt to authorize a proxy user
|
||||||
ugi = UserGroupInformation.createProxyUser(doAsUserFromQuery, ugi);
|
ugi = UserGroupInformation.createProxyUser(doAsUserFromQuery, ugi);
|
||||||
ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf);
|
ProxyUsers.authorize(ugi, getRemoteAddr(request), conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,6 +687,22 @@ public class JspHelper {
|
||||||
return ugi;
|
return ugi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// honor the X-Forwarded-For header set by a configured set of trusted
|
||||||
|
// proxy servers. allows audit logging and proxy user checks to work
|
||||||
|
// via an http proxy
|
||||||
|
static String getRemoteAddr(HttpServletRequest request) {
|
||||||
|
String remoteAddr = request.getRemoteAddr();
|
||||||
|
String proxyHeader = request.getHeader("X-Forwarded-For");
|
||||||
|
if (proxyHeader != null && ProxyUsers.isProxyServer(remoteAddr)) {
|
||||||
|
final String clientAddr = proxyHeader.split(",")[0].trim();
|
||||||
|
if (!clientAddr.isEmpty()) {
|
||||||
|
remoteAddr = clientAddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remoteAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected user name should be a short name.
|
* Expected user name should be a short name.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,6 @@ import static org.mockito.Mockito.when;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -62,6 +61,7 @@ import org.apache.hadoop.security.token.Token;
|
||||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
import org.apache.hadoop.security.token.TokenIdentifier;
|
||||||
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
|
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
@ -78,6 +78,13 @@ public class TestJspHelper {
|
||||||
private final Configuration conf = new HdfsConfiguration();
|
private final Configuration conf = new HdfsConfiguration();
|
||||||
private String jspWriterOutput = "";
|
private String jspWriterOutput = "";
|
||||||
|
|
||||||
|
// allow user with TGT to run tests
|
||||||
|
@BeforeClass
|
||||||
|
public static void setupKerb() {
|
||||||
|
System.setProperty("java.security.krb5.kdc", "");
|
||||||
|
System.setProperty("java.security.krb5.realm", "NONE");
|
||||||
|
}
|
||||||
|
|
||||||
public static class DummySecretManager extends
|
public static class DummySecretManager extends
|
||||||
AbstractDelegationTokenSecretManager<DelegationTokenIdentifier> {
|
AbstractDelegationTokenSecretManager<DelegationTokenIdentifier> {
|
||||||
|
|
||||||
|
@ -630,5 +637,49 @@ public class TestJspHelper {
|
||||||
50020, 50075, 50076, 50010);
|
50020, 50075, 50076, 50010);
|
||||||
assertNotNull(JspHelper.Url.authority("http", dnWithEmptyIp));
|
assertNotNull(JspHelper.Url.authority("http", dnWithEmptyIp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String clientAddr = "1.1.1.1";
|
||||||
|
private static String chainedClientAddr = clientAddr+", 2.2.2.2";
|
||||||
|
private static String proxyAddr = "3.3.3.3";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoteAddr() {
|
||||||
|
assertEquals(clientAddr, getRemoteAddr(clientAddr, null, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoteAddrWithUntrustedProxy() {
|
||||||
|
assertEquals(proxyAddr, getRemoteAddr(clientAddr, proxyAddr, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoteAddrWithTrustedProxy() {
|
||||||
|
assertEquals(clientAddr, getRemoteAddr(clientAddr, proxyAddr, true));
|
||||||
|
assertEquals(clientAddr, getRemoteAddr(chainedClientAddr, proxyAddr, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoteAddrWithTrustedProxyAndEmptyClient() {
|
||||||
|
assertEquals(proxyAddr, getRemoteAddr(null, proxyAddr, true));
|
||||||
|
assertEquals(proxyAddr, getRemoteAddr("", proxyAddr, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRemoteAddr(String clientAddr, String proxyAddr, boolean trusted) {
|
||||||
|
HttpServletRequest req = mock(HttpServletRequest.class);
|
||||||
|
when(req.getRemoteAddr()).thenReturn("1.2.3.4");
|
||||||
|
|
||||||
|
Configuration conf = new Configuration();
|
||||||
|
if (proxyAddr == null) {
|
||||||
|
when(req.getRemoteAddr()).thenReturn(clientAddr);
|
||||||
|
} else {
|
||||||
|
when(req.getRemoteAddr()).thenReturn(proxyAddr);
|
||||||
|
when(req.getHeader("X-Forwarded-For")).thenReturn(clientAddr);
|
||||||
|
if (trusted) {
|
||||||
|
conf.set(ProxyUsers.CONF_HADOOP_PROXYSERVERS, proxyAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProxyUsers.refreshSuperUserGroupsConfiguration(conf);
|
||||||
|
return JspHelper.getRemoteAddr(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue