You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-commits@hadoop.apache.org by jg...@apache.org on 2010/07/10 21:36:10 UTC
svn commit: r962907 - in /hadoop/hdfs/trunk: ./
src/java/org/apache/hadoop/hdfs/server/namenode/
src/test/unit/org/apache/hadoop/hdfs/server/namenode/
Author: jghoman
Date: Sat Jul 10 19:36:10 2010
New Revision: 962907
URL: http://svn.apache.org/viewvc?rev=962907&view=rev
Log:
HDFS-1033. In secure clusters, NN and SNN should verify that the remote principal during image and edits transfer.
Added:
hadoop/hdfs/trunk/src/test/unit/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
Modified:
hadoop/hdfs/trunk/CHANGES.txt
hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java
Modified: hadoop/hdfs/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hdfs/trunk/CHANGES.txt?rev=962907&r1=962906&r2=962907&view=diff
==============================================================================
--- hadoop/hdfs/trunk/CHANGES.txt (original)
+++ hadoop/hdfs/trunk/CHANGES.txt Sat Jul 10 19:36:10 2010
@@ -18,6 +18,9 @@ Trunk (unreleased changes)
HDFS-1006. getImage/putImage http requests should be https for the case
of security enabled. (borya and jghoman via jghoman)
+ HDFS-1033. In secure clusters, NN and SNN should verify that the remote
+ principal during image and edits transfer. (jghoman)
+
IMPROVEMENTS
HDFS-1096. fix for prev. commit. (boryas)
Modified: hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java
URL: http://svn.apache.org/viewvc/hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java?rev=962907&r1=962906&r2=962907&view=diff
==============================================================================
--- hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java (original)
+++ hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/GetImageServlet.java Sat Jul 10 19:36:10 2010
@@ -17,6 +17,11 @@
*/
package org.apache.hadoop.hdfs.server.namenode;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_USER_NAME_KEY;
+
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.io.*;
@@ -26,6 +31,9 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys;
@@ -41,6 +49,8 @@ import org.apache.hadoop.util.StringUtil
public class GetImageServlet extends HttpServlet {
private static final long serialVersionUID = -7669068179452648952L;
+ private static final Log LOG = LogFactory.getLog(GetImageServlet.class);
+
@SuppressWarnings("unchecked")
public void doGet(final HttpServletRequest request,
final HttpServletResponse response
@@ -51,9 +61,17 @@ public class GetImageServlet extends Htt
final FSImage nnImage = (FSImage)context.getAttribute("name.system.image");
final TransferFsImage ff = new TransferFsImage(pmap, request, response);
final Configuration conf = (Configuration)getServletContext().getAttribute("name.conf");
+
+ if(UserGroupInformation.isSecurityEnabled() &&
+ !isValidRequestor(request.getRemoteUser(), conf)) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN,
+ "Only Namenode and Secondary Namenode may access this servlet");
+ LOG.warn("Received non-NN/SNN request for image or edits from "
+ + request.getRemoteHost());
+ return;
+ }
- UserGroupInformation.getCurrentUser().doAs(new PrivilegedExceptionAction<Void>() {
-
+ UserGroupInformation.getCurrentUser().doAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
if (ff.getImage()) {
@@ -103,4 +121,25 @@ public class GetImageServlet extends Htt
response.getOutputStream().close();
}
}
+
+ protected boolean isValidRequestor(String remoteUser, Configuration conf) {
+ if(remoteUser == null) { // This really shouldn't happen...
+ LOG.warn("Received null remoteUser while authorizing access to getImage servlet");
+ return false;
+ }
+
+ String [] validRequestors = {conf.get(DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY),
+ conf.get(DFS_NAMENODE_USER_NAME_KEY),
+ conf.get(DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY),
+ conf.get(DFS_SECONDARY_NAMENODE_USER_NAME_KEY) };
+
+ for(String v : validRequestors) {
+ if(v != null && v.equals(remoteUser)) {
+ if(LOG.isDebugEnabled()) LOG.debug("isValidRequestor is allowing: " + remoteUser);
+ return true;
+ }
+ }
+ if(LOG.isDebugEnabled()) LOG.debug("isValidRequestor is rejecting: " + remoteUser);
+ return false;
+ }
}
Modified: hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java
URL: http://svn.apache.org/viewvc/hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java?rev=962907&r1=962906&r2=962907&view=diff
==============================================================================
--- hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java (original)
+++ hadoop/hdfs/trunk/src/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java Sat Jul 10 19:36:10 2010
@@ -115,8 +115,8 @@ public class SecondaryNameNode implement
public SecondaryNameNode(Configuration conf) throws IOException {
UserGroupInformation.setConfiguration(conf);
DFSUtil.login(conf,
- DFSConfigKeys.DFS_NAMENODE_KEYTAB_FILE_KEY,
- DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY);
+ DFSConfigKeys.DFS_SECONDARY_NAMENODE_KEYTAB_FILE_KEY,
+ DFSConfigKeys.DFS_SECONDARY_NAMENODE_USER_NAME_KEY);
try {
initialize(conf);
Added: hadoop/hdfs/trunk/src/test/unit/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java
URL: http://svn.apache.org/viewvc/hadoop/hdfs/trunk/src/test/unit/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java?rev=962907&view=auto
==============================================================================
--- hadoop/hdfs/trunk/src/test/unit/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java (added)
+++ hadoop/hdfs/trunk/src/test/unit/org/apache/hadoop/hdfs/server/namenode/TestGetImageServlet.java Sat Jul 10 19:36:10 2010
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdfs.server.namenode;
+
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY;
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_SECONDARY_NAMENODE_USER_NAME_KEY;
+import static org.junit.Assert.*;
+
+import org.apache.hadoop.conf.Configuration;
+import org.junit.Test;
+
+public class TestGetImageServlet {
+
+ // Worker class to poke the isValidRequestor method with verifying it accepts
+ // or rejects with these standard allowed principals
+ private void verifyIsValidReqBehavior(GetImageServlet gim,
+ boolean shouldSucceed, String msg) {
+ final String [] validRequestors = {DFS_NAMENODE_KRB_HTTPS_USER_NAME_KEY,
+ DFS_NAMENODE_USER_NAME_KEY,
+ DFS_SECONDARY_NAMENODE_KRB_HTTPS_USER_NAME_KEY,
+ DFS_SECONDARY_NAMENODE_USER_NAME_KEY };
+
+ for(String v : validRequestors) {
+ Configuration conf = new Configuration();
+ conf.set(v, "a");
+ assertEquals(msg + v, gim.isValidRequestor(shouldSucceed ? "a" : "b", conf),
+ shouldSucceed);
+ }
+ }
+
+ @Test
+ public void IsValidRequestorAcceptsCorrectly() {
+ GetImageServlet gim = new GetImageServlet();
+
+ verifyIsValidReqBehavior(gim, true,
+ "isValidRequestor has rejected a valid requestor: ");
+ }
+
+ @Test
+ public void IsValidRequestorRejectsCorrectly() {
+ GetImageServlet gim = new GetImageServlet();
+
+ // Don't set any valid requestors
+ assertFalse("isValidRequestor allowed a requestor despite no values being set",
+ gim.isValidRequestor("not set", new Configuration()));
+
+ verifyIsValidReqBehavior(gim, false,
+ "isValidRequestor has allowed an invalid requestor: ");
+ }
+
+}