001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.hadoop.security;
019
020 import java.net.InetAddress;
021 import java.net.UnknownHostException;
022 import java.util.Map;
023 import java.util.TreeMap;
024
025 import javax.security.sasl.Sasl;
026
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.apache.hadoop.conf.Configuration;
030 import org.apache.hadoop.security.SaslPropertiesResolver;
031 import org.apache.hadoop.security.SaslRpcServer.QualityOfProtection;
032 import org.apache.hadoop.util.CombinedIPWhiteList;
033 import org.apache.hadoop.util.StringUtils;
034
035
036 /**
037 * An implementation of the SaslPropertiesResolver.
038 * Uses a white list of IPs.
039 * If the connection's IP address is in the list of IP addresses, the salProperties
040 * will be unchanged.
041 * If the connection's IP is not in the list of IP addresses, then QOP for the
042 * connection will be restricted to "hadoop.rpc.protection.non-whitelist"
043 *
044 * Uses 3 IPList implementations together to form an aggregate whitelist.
045 * 1. ConstantIPList - to check against a set of hardcoded IPs
046 * 2. Fixed IP List - to check against a list of IP addresses which are specified externally, but
047 * will not change over runtime.
048 * 3. Variable IP List - to check against a list of IP addresses which are specified externally and
049 * could change during runtime.
050 * A connection IP address will checked against these 3 IP Lists in the order specified above.
051 * Once a match is found , the IP address is determined to be in whitelist.
052 *
053 * The behavior can be configured using a bunch of configuration parameters.
054 *
055 */
056 public class WhitelistBasedResolver extends SaslPropertiesResolver {
057 public static final Log LOG = LogFactory.getLog(WhitelistBasedResolver.class);
058
059 private static final String FIXEDWHITELIST_DEFAULT_LOCATION = "/etc/hadoop/fixedwhitelist";
060
061 private static final String VARIABLEWHITELIST_DEFAULT_LOCATION = "/etc/hadoop/whitelist";
062
063 /**
064 * Path to the file to containing subnets and ip addresses to form fixed whitelist.
065 */
066 public static final String HADOOP_SECURITY_SASL_FIXEDWHITELIST_FILE =
067 "hadoop.security.sasl.fixedwhitelist.file";
068 /**
069 * Enables/Disables variable whitelist
070 */
071 public static final String HADOOP_SECURITY_SASL_VARIABLEWHITELIST_ENABLE =
072 "hadoop.security.sasl.variablewhitelist.enable";
073 /**
074 * Path to the file to containing subnets and ip addresses to form variable whitelist.
075 */
076 public static final String HADOOP_SECURITY_SASL_VARIABLEWHITELIST_FILE =
077 "hadoop.security.sasl.variablewhitelist.file";
078 /**
079 * time in seconds by which the variable whitelist file is checked for updates
080 */
081 public static final String HADOOP_SECURITY_SASL_VARIABLEWHITELIST_CACHE_SECS =
082 "hadoop.security.sasl.variablewhitelist.cache.secs";
083
084 /**
085 * comma separated list containing alternate hadoop.rpc.protection values for
086 * clients which are not in whitelist
087 */
088 public static final String HADOOP_RPC_PROTECTION_NON_WHITELIST =
089 "hadoop.rpc.protection.non-whitelist";
090
091 private CombinedIPWhiteList whiteList;
092
093 private Map<String, String> saslProps;
094
095 @Override
096 public void setConf(Configuration conf) {
097 super.setConf(conf);
098 String fixedFile = conf.get(HADOOP_SECURITY_SASL_FIXEDWHITELIST_FILE,
099 FIXEDWHITELIST_DEFAULT_LOCATION);
100 String variableFile = null;
101 long expiryTime = 0;
102
103 if (conf.getBoolean(HADOOP_SECURITY_SASL_VARIABLEWHITELIST_ENABLE, false)) {
104 variableFile = conf.get(HADOOP_SECURITY_SASL_VARIABLEWHITELIST_FILE,
105 VARIABLEWHITELIST_DEFAULT_LOCATION);
106 expiryTime =
107 conf.getLong(HADOOP_SECURITY_SASL_VARIABLEWHITELIST_CACHE_SECS,3600) * 1000;
108 }
109
110 whiteList = new CombinedIPWhiteList(fixedFile,variableFile,expiryTime);
111
112 this.saslProps = getSaslProperties(conf);
113 }
114
115 /**
116 * Identify the Sasl Properties to be used for a connection with a client.
117 * @param clientAddress client's address
118 * @return the sasl properties to be used for the connection.
119 */
120 @Override
121 public Map<String, String> getServerProperties(InetAddress clientAddress) {
122 if (clientAddress == null) {
123 return saslProps;
124 }
125 return whiteList.isIn(clientAddress.getHostAddress())?getDefaultProperties():saslProps;
126 }
127
128 public Map<String, String> getServerProperties(String clientAddress) throws UnknownHostException {
129 if (clientAddress == null) {
130 return saslProps;
131 }
132 return getServerProperties(InetAddress.getByName(clientAddress));
133 }
134
135 static Map<String, String> getSaslProperties(Configuration conf) {
136 Map<String, String> saslProps =new TreeMap<String, String>();
137 String[] qop = conf.getStrings(HADOOP_RPC_PROTECTION_NON_WHITELIST,
138 QualityOfProtection.PRIVACY.toString());
139
140 for (int i=0; i < qop.length; i++) {
141 qop[i] = QualityOfProtection.valueOf(qop[i].toUpperCase()).getSaslQop();
142 }
143
144 saslProps.put(Sasl.QOP, StringUtils.join(",", qop));
145 saslProps.put(Sasl.SERVER_AUTH, "true");
146
147 return saslProps;
148 }
149 }