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-6219. Proxy superuser configuration should use true client IP for
|
||||
address checks. (daryn via kihwal)
|
||||
|
||||
OPTIMIZATIONS
|
||||
|
||||
BUG FIXES
|
||||
|
@ -25,6 +25,7 @@
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
@ -646,7 +647,7 @@ public static UserGroupInformation getUGI(ServletContext context,
|
||||
if (doAsUserFromQuery != null) {
|
||||
// create and attempt to authorize a proxy user
|
||||
ugi = UserGroupInformation.createProxyUser(doAsUserFromQuery, ugi);
|
||||
ProxyUsers.authorize(ugi, request.getRemoteAddr(), conf);
|
||||
ProxyUsers.authorize(ugi, getRemoteAddr(request), conf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -686,6 +687,22 @@ private static UserGroupInformation getTokenUGI(ServletContext context,
|
||||
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.
|
||||
*/
|
||||
|
@ -29,7 +29,6 @@
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
@ -62,6 +61,7 @@
|
||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
||||
import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
@ -78,6 +78,13 @@ public class TestJspHelper {
|
||||
private final Configuration conf = new HdfsConfiguration();
|
||||
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
|
||||
AbstractDelegationTokenSecretManager<DelegationTokenIdentifier> {
|
||||
|
||||
@ -630,5 +637,49 @@ public void testAuthority(){
|
||||
50020, 50075, 50076, 50010);
|
||||
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
Block a user