1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hdfs.server.namenode; 19 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertThat; 22 import static org.hamcrest.core.Is.is; 23 import static org.hamcrest.core.IsNot.not; 24 import org.junit.Test; 25 26 import org.apache.hadoop.fs.FileUtil; 27 import org.apache.hadoop.hdfs.DFSConfigKeys; 28 import org.apache.hadoop.http.HttpConfig; 29 import org.apache.hadoop.security.ssl.KeyStoreTestUtil; 30 31 import java.io.File; 32 import java.io.IOException; 33 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.apache.hadoop.conf.Configuration; 37 import static org.apache.hadoop.hdfs.DFSConfigKeys.*; 38 import static org.junit.Assert.assertTrue; 39 40 import org.apache.hadoop.hdfs.HdfsConfiguration; 41 import org.apache.hadoop.hdfs.MiniDFSCluster; 42 43 /** 44 * This test checks that the NameNode respects the following keys: 45 * 46 * - DFS_NAMENODE_RPC_BIND_HOST_KEY 47 * - DFS_NAMENODE_SERVICE_RPC_BIND_HOST_KEY 48 * - DFS_NAMENODE_HTTP_BIND_HOST_KEY 49 * - DFS_NAMENODE_HTTPS_BIND_HOST_KEY 50 51 */ 52 public class TestNameNodeRespectsBindHostKeys { 53 public static final Log LOG = LogFactory.getLog(TestNameNodeRespectsBindHostKeys.class); 54 private static final String WILDCARD_ADDRESS = "0.0.0.0"; 55 private static final String LOCALHOST_SERVER_ADDRESS = "127.0.0.1:0"; 56 getRpcServerAddress(MiniDFSCluster cluster)57 private static String getRpcServerAddress(MiniDFSCluster cluster) { 58 NameNodeRpcServer rpcServer = (NameNodeRpcServer) cluster.getNameNodeRpc(); 59 return rpcServer.getClientRpcServer().getListenerAddress().getAddress().toString(); 60 } 61 getServiceRpcServerAddress(MiniDFSCluster cluster)62 private static String getServiceRpcServerAddress(MiniDFSCluster cluster) { 63 NameNodeRpcServer rpcServer = (NameNodeRpcServer) cluster.getNameNodeRpc(); 64 return rpcServer.getServiceRpcServer().getListenerAddress().getAddress().toString(); 65 } 66 67 @Test (timeout=300000) testRpcBindHostKey()68 public void testRpcBindHostKey() throws IOException { 69 Configuration conf = new HdfsConfiguration(); 70 MiniDFSCluster cluster = null; 71 72 LOG.info("Testing without " + DFS_NAMENODE_RPC_BIND_HOST_KEY); 73 74 // NN should not bind the wildcard address by default. 75 try { 76 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 77 cluster.waitActive(); 78 String address = getRpcServerAddress(cluster); 79 assertThat("Bind address not expected to be wildcard by default.", 80 address, not("/" + WILDCARD_ADDRESS)); 81 } finally { 82 if (cluster != null) { 83 cluster.shutdown(); 84 cluster = null; 85 } 86 } 87 88 LOG.info("Testing with " + DFS_NAMENODE_RPC_BIND_HOST_KEY); 89 90 // Tell NN to bind the wildcard address. 91 conf.set(DFS_NAMENODE_RPC_BIND_HOST_KEY, WILDCARD_ADDRESS); 92 93 // Verify that NN binds wildcard address now. 94 try { 95 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 96 cluster.waitActive(); 97 String address = getRpcServerAddress(cluster); 98 assertThat("Bind address " + address + " is not wildcard.", 99 address, is("/" + WILDCARD_ADDRESS)); 100 } finally { 101 if (cluster != null) { 102 cluster.shutdown(); 103 } 104 } 105 } 106 107 @Test (timeout=300000) testServiceRpcBindHostKey()108 public void testServiceRpcBindHostKey() throws IOException { 109 Configuration conf = new HdfsConfiguration(); 110 MiniDFSCluster cluster = null; 111 112 LOG.info("Testing without " + DFS_NAMENODE_SERVICE_RPC_BIND_HOST_KEY); 113 114 conf.set(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, LOCALHOST_SERVER_ADDRESS); 115 116 // NN should not bind the wildcard address by default. 117 try { 118 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 119 cluster.waitActive(); 120 String address = getServiceRpcServerAddress(cluster); 121 assertThat("Bind address not expected to be wildcard by default.", 122 address, not("/" + WILDCARD_ADDRESS)); 123 } finally { 124 if (cluster != null) { 125 cluster.shutdown(); 126 cluster = null; 127 } 128 } 129 130 LOG.info("Testing with " + DFS_NAMENODE_SERVICE_RPC_BIND_HOST_KEY); 131 132 // Tell NN to bind the wildcard address. 133 conf.set(DFS_NAMENODE_SERVICE_RPC_BIND_HOST_KEY, WILDCARD_ADDRESS); 134 135 // Verify that NN binds wildcard address now. 136 try { 137 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 138 cluster.waitActive(); 139 String address = getServiceRpcServerAddress(cluster); 140 assertThat("Bind address " + address + " is not wildcard.", 141 address, is("/" + WILDCARD_ADDRESS)); 142 } finally { 143 if (cluster != null) { 144 cluster.shutdown(); 145 } 146 } 147 } 148 149 @Test(timeout=300000) testHttpBindHostKey()150 public void testHttpBindHostKey() throws IOException { 151 Configuration conf = new HdfsConfiguration(); 152 MiniDFSCluster cluster = null; 153 154 LOG.info("Testing without " + DFS_NAMENODE_HTTP_BIND_HOST_KEY); 155 156 // NN should not bind the wildcard address by default. 157 try { 158 conf.set(DFS_NAMENODE_HTTP_ADDRESS_KEY, LOCALHOST_SERVER_ADDRESS); 159 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 160 cluster.waitActive(); 161 String address = cluster.getNameNode().getHttpAddress().toString(); 162 assertFalse("HTTP Bind address not expected to be wildcard by default.", 163 address.startsWith(WILDCARD_ADDRESS)); 164 } finally { 165 if (cluster != null) { 166 cluster.shutdown(); 167 cluster = null; 168 } 169 } 170 171 LOG.info("Testing with " + DFS_NAMENODE_HTTP_BIND_HOST_KEY); 172 173 // Tell NN to bind the wildcard address. 174 conf.set(DFS_NAMENODE_HTTP_BIND_HOST_KEY, WILDCARD_ADDRESS); 175 176 // Verify that NN binds wildcard address now. 177 try { 178 conf.set(DFS_NAMENODE_HTTP_ADDRESS_KEY, LOCALHOST_SERVER_ADDRESS); 179 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 180 cluster.waitActive(); 181 String address = cluster.getNameNode().getHttpAddress().toString(); 182 assertTrue("HTTP Bind address " + address + " is not wildcard.", 183 address.startsWith(WILDCARD_ADDRESS)); 184 } finally { 185 if (cluster != null) { 186 cluster.shutdown(); 187 } 188 } 189 } 190 191 private static final String BASEDIR = System.getProperty("test.build.dir", 192 "target/test-dir") + "/" + TestNameNodeRespectsBindHostKeys.class.getSimpleName(); 193 setupSsl()194 private static void setupSsl() throws Exception { 195 Configuration conf = new Configuration(); 196 conf.setBoolean(DFSConfigKeys.DFS_WEBHDFS_ENABLED_KEY, true); 197 conf.set(DFSConfigKeys.DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name()); 198 conf.set(DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY, "localhost:0"); 199 conf.set(DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KEY, "localhost:0"); 200 201 File base = new File(BASEDIR); 202 FileUtil.fullyDelete(base); 203 assertTrue(base.mkdirs()); 204 final String keystoresDir = new File(BASEDIR).getAbsolutePath(); 205 final String sslConfDir = KeyStoreTestUtil.getClasspathDir(TestNameNodeRespectsBindHostKeys.class); 206 207 KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, conf, false); 208 } 209 210 /** 211 * HTTPS test is different since we need to setup SSL configuration. 212 * NN also binds the wildcard address for HTTPS port by default so we must 213 * pick a different host/port combination. 214 * @throws Exception 215 */ 216 @Test (timeout=300000) testHttpsBindHostKey()217 public void testHttpsBindHostKey() throws Exception { 218 Configuration conf = new HdfsConfiguration(); 219 MiniDFSCluster cluster = null; 220 221 LOG.info("Testing behavior without " + DFS_NAMENODE_HTTPS_BIND_HOST_KEY); 222 223 setupSsl(); 224 225 conf.set(DFS_HTTP_POLICY_KEY, HttpConfig.Policy.HTTPS_ONLY.name()); 226 227 // NN should not bind the wildcard address by default. 228 try { 229 conf.set(DFS_NAMENODE_HTTPS_ADDRESS_KEY, LOCALHOST_SERVER_ADDRESS); 230 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 231 cluster.waitActive(); 232 String address = cluster.getNameNode().getHttpsAddress().toString(); 233 assertFalse("HTTP Bind address not expected to be wildcard by default.", 234 address.startsWith(WILDCARD_ADDRESS)); 235 } finally { 236 if (cluster != null) { 237 cluster.shutdown(); 238 cluster = null; 239 } 240 } 241 242 LOG.info("Testing behavior with " + DFS_NAMENODE_HTTPS_BIND_HOST_KEY); 243 244 // Tell NN to bind the wildcard address. 245 conf.set(DFS_NAMENODE_HTTPS_BIND_HOST_KEY, WILDCARD_ADDRESS); 246 247 // Verify that NN binds wildcard address now. 248 try { 249 conf.set(DFS_NAMENODE_HTTPS_ADDRESS_KEY, LOCALHOST_SERVER_ADDRESS); 250 cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).build(); 251 cluster.waitActive(); 252 String address = cluster.getNameNode().getHttpsAddress().toString(); 253 assertTrue("HTTP Bind address " + address + " is not wildcard.", 254 address.startsWith(WILDCARD_ADDRESS)); 255 } finally { 256 if (cluster != null) { 257 cluster.shutdown(); 258 } 259 } 260 } 261 } 262