RANGER-232 Knox plugin changed to use new service model
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/6edf6d86 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/6edf6d86 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/6edf6d86 Branch: refs/heads/stack Commit: 6edf6d8686c3e8078ca7b95f96affa6b25e8dc2c Parents: 4e121ea Author: Alok Lal <[email protected]> Authored: Sun Feb 8 15:24:02 2015 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Sun Feb 8 15:24:02 2015 -0800 ---------------------------------------------------------------------- agents-common/pom.xml | 4 + .../RangerConditionEvaluator.java | 9 + .../conditionevaluator/RangerIpMatcher.java | 117 ++++++++ .../ranger/plugin/model/RangerPolicy.java | 28 +- .../policyengine/RangerAccessRequest.java | 2 + .../policyengine/RangerAccessRequestImpl.java | 21 +- .../RangerDefaultPolicyEvaluator.java | 170 ++++++++++- .../service-defs/ranger-servicedef-knox.json | 2 +- .../conditionevaluator/RangerIpMatcherTest.java | 160 ++++++++++ .../RangerDefaultPolicyEvaluatorTest.java | 297 +++++++++++++++++++ .../ranger/pdp/knox/RangerAuthorizer.java | 64 ---- .../RangerPDPKnoxDeploymentContributor.java | 2 +- .../pdp/knox/filter/RangerPDPKnoxFilter.java | 214 ------------- knox-agent/conf/ranger-knox-audit-changes.cfg | 34 +++ knox-agent/conf/ranger-knox-audit.xml | 191 ++++++++++++ .../conf/ranger-knox-security-changes.cfg | 26 ++ knox-agent/conf/ranger-knox-security.xml | 68 +++++ .../conf/ranger-policymgr-ssl-changes.cfg | 23 ++ knox-agent/conf/ranger-policymgr-ssl.xml | 63 ++++ knox-agent/conf/xasecure-audit-changes.cfg | 33 --- knox-agent/conf/xasecure-audit.xml | 191 ------------ .../conf/xasecure-knox-security-changes.cfg | 24 -- knox-agent/conf/xasecure-knox-security.xml | 69 ----- .../conf/xasecure-policymgr-ssl-changes.cfg | 20 -- knox-agent/conf/xasecure-policymgr-ssl.xml | 35 --- .../authorization/knox/KnoxAccessVerifier.java | 30 -- .../knox/KnoxAccessVerifierFactory.java | 65 ---- .../authorization/knox/KnoxRangerPlugin.java | 129 ++++++++ .../authorization/knox/RangerPDPKnoxFilter.java | 160 ++++++++++ .../org/apache/ranger/common/ServiceUtil.java | 10 +- 30 files changed, 1490 insertions(+), 771 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/pom.xml ---------------------------------------------------------------------- diff --git a/agents-common/pom.xml b/agents-common/pom.xml index e2e904a..ede7b9d 100644 --- a/agents-common/pom.xml +++ b/agents-common/pom.xml @@ -56,6 +56,10 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> <dependency> <groupId>security_plugins.ranger-plugins-audit</groupId> <artifactId>ranger-plugins-audit</artifactId> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java new file mode 100644 index 0000000..9dc61a7 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java @@ -0,0 +1,9 @@ +package org.apache.ranger.plugin.conditionevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; + +public interface RangerConditionEvaluator { + + void init(RangerPolicyItemCondition condition); + boolean isMatched(String value); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java new file mode 100644 index 0000000..f21f7f4 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcher.java @@ -0,0 +1,117 @@ +/* + * 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.ranger.plugin.conditionevaluator; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; + +/** + * Credits: Large parts of this file have been lifted as is from org.apache.ranger.pdp.knox.URLBasedAuthDB. Credits for those are due to Dilli Arumugam. + * @author alal + * + */ +public class RangerIpMatcher implements RangerConditionEvaluator { + + private static final Log LOG = LogFactory.getLog(RangerIpMatcher.class); + private List<String> _ipAddresses = new ArrayList<String>(); + private boolean _allowAny = false; + + @Override + public void init(RangerPolicyItemCondition condition) { + if (condition != null) { + List<String> ipAddresses = condition.getValues(); + if (CollectionUtils.isNotEmpty(ipAddresses)) { + _ipAddresses.addAll(ipAddresses); + // do this once, contains on a list is O(n) operation! + if (_ipAddresses.contains("*")) { + _allowAny = true; + } + } + } + } + + @Override + public boolean isMatched(String requestIp) { + boolean ipMatched = false; + if (LOG.isDebugEnabled()) { + LOG.debug("Checking ipMatch for rolePermissionIpList: " + _ipAddresses + + ", requestIP: " + requestIp); + } + if (CollectionUtils.isEmpty(_ipAddresses)) { + LOG.debug("RolePermission does not require IP Matching"); + ipMatched = true; + } else if (_allowAny) { + LOG.debug("RolePermission allows any IP: *"); + ipMatched = true; + } else { + for (String ip : _ipAddresses) { + if (ipMatches(ip, requestIp)) { + LOG.debug("RolePermission IP matches request IP"); + ipMatched = true; + break;// break out of ipList + } + } + } + return ipMatched; + } + + private boolean ipMatches(String policyIp, String requestIp) { + if (policyIp == null) { + return false; + } + policyIp = policyIp.trim(); + if (policyIp.isEmpty()) { + return false; + } + boolean ipMatched = false; + boolean wildEnd = false; + if (policyIp.contains(".")) { + while (policyIp.endsWith(".*")) { + wildEnd = true; + policyIp = policyIp.substring(0, policyIp.lastIndexOf(".*")); + } + if (wildEnd) { + policyIp = policyIp + "."; + } + } else if (policyIp.contains(":")) { + while (policyIp.endsWith(":*")) { + wildEnd = true; + policyIp = policyIp.substring(0, policyIp.lastIndexOf(":*")); + } + if (wildEnd) { + policyIp = policyIp + ":"; + } + } + if (wildEnd && requestIp.toLowerCase().startsWith(policyIp.toLowerCase())) { + ipMatched = true; + } else if (policyIp.equalsIgnoreCase(requestIp)) { + ipMatched = true; + } + return ipMatched; + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java index d118f84..cdcda0e 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java @@ -28,6 +28,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import org.apache.commons.collections.CollectionUtils; import org.codehaus.jackson.annotate.JsonAutoDetect; import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; @@ -632,15 +633,15 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria private static final long serialVersionUID = 1L; private String type = null; - private String value = null; + private List<String> values = null; public RangerPolicyItemCondition() { this(null, null); } - public RangerPolicyItemCondition(String type, String value) { + public RangerPolicyItemCondition(String type, List<String> values) { setType(type); - setValue(value); + setValues(values); } /** @@ -660,15 +661,20 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria /** * @return the value */ - public String getValue() { - return value; + public List<String> getValues() { + return values; } /** * @param value the value to set */ - public void setValue(String value) { - this.value = value; + public void setValues(List<String> values) { + if (CollectionUtils.isEmpty(values)) { + this.values = new ArrayList<String>(); + } + else { + this.values = new ArrayList<String>(values); + } } @Override @@ -683,7 +689,13 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria public StringBuilder toString(StringBuilder sb) { sb.append("RangerPolicyItemCondition={"); sb.append("type={").append(type).append("} "); - sb.append("value={").append(value).append("} "); + sb.append("values={"); + if(values != null) { + for(String value : values) { + sb.append(value).append(" "); + } + } + sb.append("} "); sb.append("}"); return sb; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java index 56a55ae..3f4570d 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequest.java @@ -45,4 +45,6 @@ public interface RangerAccessRequest { String getSessionId(); Map<String, Object> getContext(); + + Map<String, String> getConditions(); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java index fff8d4c..1114804 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java @@ -25,8 +25,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.apache.commons.lang.StringUtils; - public class RangerAccessRequestImpl implements RangerAccessRequest { private RangerResource resource = null; @@ -40,6 +38,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { private String requestData = null; private String sessionId = null; private Map<String, Object> context = null; + private Map<String, String> conditions = null; public RangerAccessRequestImpl() { @@ -60,6 +59,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { setRequestData(null); setSessionId(null); setContext(null); + setConditions(null); } @Override @@ -117,6 +117,10 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { return context; } + @Override + public Map<String, String> getConditions() { + return conditions; + } public void setResource(RangerResource resource) { this.resource = resource; @@ -162,6 +166,10 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { this.context = (context == null) ? new HashMap<String, Object>() : context; } + public void setConditions(final Map<String, String> conditions) { + this.conditions = (conditions == null) ? new HashMap<String, String>() : conditions; + } + @Override public String toString( ) { StringBuilder sb = new StringBuilder(); @@ -184,6 +192,7 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { sb.append(userGroup).append(" "); } } + sb.append("} "); sb.append("accessTime={").append(accessTime).append("} "); sb.append("clientIPAddress={").append(clientIPAddress).append("} "); @@ -201,6 +210,14 @@ public class RangerAccessRequestImpl implements RangerAccessRequest { } sb.append("} "); + sb.append("conditions={"); + if(conditions != null) { + for(Map.Entry<String, String> e : conditions.entrySet()) { + sb.append(e.getKey()).append("={").append(e.getValue()).append("} "); + } + } + sb.append("} "); + sb.append("}"); return sb; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index f3322d2..7d05d30 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -23,18 +23,22 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator; import org.apache.ranger.plugin.model.RangerPolicy; -import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResult; @@ -43,11 +47,14 @@ import org.apache.ranger.plugin.policyengine.RangerResource; import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher; import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; +import com.google.common.base.Strings; + public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator { private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyEvaluator.class); private Map<String, RangerResourceMatcher> matchers = null; + private Map<String, RangerConditionEvaluator> conditionEvaluators = null; @Override public void init(RangerPolicy policy, RangerServiceDef serviceDef) { @@ -77,12 +84,128 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } } } + + conditionEvaluators = initializeConditionEvaluators(policy, serviceDef); if(LOG.isDebugEnabled()) { LOG.debug("<== RangerDefaultPolicyEvaluator.init()"); } } + /** + * Non-private only for testability. + * @param policy + * @param serviceDef + * @return a Map of condition name to a new evaluator object of the class configured in service definition for that condition name + */ + Map<String, RangerConditionEvaluator> initializeConditionEvaluators(RangerPolicy policy, RangerServiceDef serviceDef) { + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("==> RangerDefaultPolicyEvaluator.initializeConditionEvaluators(%s, %s)", policy, serviceDef)); + } + + Map<String, RangerConditionEvaluator> result = new HashMap<String, RangerConditionEvaluator>(); + if (policy == null) { + LOG.debug("initializeConditionEvaluators: Policy is null!"); + } else if (CollectionUtils.isEmpty(policy.getPolicyItems())) { + LOG.debug("initializeConditionEvaluators: Policyitems collection null or empty!"); + } else { + for (RangerPolicyItem item : policy.getPolicyItems()) { + if (CollectionUtils.isEmpty(item.getConditions())) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("initializeConditionEvaluators: null or empty condition collection on policy item[%s]. Ok, skipping", item)); + } + } else { + for (RangerPolicyItemCondition condition : item.getConditions()) { + String conditionName = condition.getType(); + // skip it if we have already processed this condition earlier + if (result.containsKey(conditionName)) { + continue; + } + String evaluatorClassName = getEvaluatorName(serviceDef, conditionName); + if (Strings.isNullOrEmpty(evaluatorClassName)) { + LOG.error("initializeConditionEvaluators: Serious Configuration error: Couldn't get condition evaluator class name for condition[" + conditionName + "]! Disabling all checks for this condition."); + } else { + RangerConditionEvaluator anEvaluator = newConditionEvauator(evaluatorClassName); + if (anEvaluator == null) { + LOG.error("initializeConditionEvaluators: Serious Configuration error: Couldn't instantiate condition evaluator for class[" + evaluatorClassName + "]. All checks for condition[" + conditionName + "] disabled."); + } else { + anEvaluator.init(condition); + result.put(conditionName, anEvaluator); + } + } + } + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("<== RangerDefaultPolicyEvaluator.initializeConditionEvaluators(%s)", result.toString())); + } + return result; + } + + // TODO this should be cached in the policyengine to avoid repeated processing for every policy + String getEvaluatorName(RangerServiceDef serviceDef, String conditionName) { + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("==> RangerDefaultPolicyEvaluator.initializeConditionEvaluators(%s, %s)", serviceDef, conditionName)); + } + + String evaluatorName = null; + if (Strings.isNullOrEmpty(conditionName)) { + LOG.debug("initializeConditionEvaluators: Condition name was null or empty!"); + } + else if (serviceDef == null) { + LOG.debug("initializeConditionEvaluators: Servicedef was null!"); + } else if (CollectionUtils.isEmpty(serviceDef.getPolicyConditions())) { + LOG.debug("initializeConditionEvaluators: Policy conditions collection of the service def is empty! Ok, skipping."); + } else { + Iterator<RangerPolicyConditionDef> iterator = serviceDef.getPolicyConditions().iterator(); + while (iterator.hasNext() && evaluatorName == null) { + RangerPolicyConditionDef conditionDef = iterator.next(); + String name = conditionDef.getName(); + if (conditionName.equals(name)) { + evaluatorName = conditionDef.getEvaluator(); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("<== RangerDefaultPolicyEvaluator.initializeConditionEvaluators(%s -> %s)", conditionName, evaluatorName)); + } + return evaluatorName; + } + + RangerConditionEvaluator newConditionEvauator(String className) { + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("==> RangerDefaultPolicyEvaluator.newConditionEvauator(%s)", className)); + } + + RangerConditionEvaluator evaluator = null; + try { + @SuppressWarnings("unchecked") + Class<RangerConditionEvaluator> matcherClass = (Class<RangerConditionEvaluator>)Class.forName(className); + + evaluator = matcherClass.newInstance(); + } catch(ClassNotFoundException excp) { + LOG.error("Caught ClassNotFoundException: error instantiating object of class[" + className + "]. Returning null!"); + excp.printStackTrace(); + } catch (InstantiationException excp) { + LOG.error("Caught InstantiationException: error instantiating object of class[" + className + "]. Returning null!"); + excp.printStackTrace(); + } catch (IllegalAccessException excp) { + LOG.error("Caught IllegalAccessException: error instantiating object of class[" + className + "]. Returning null!"); + excp.printStackTrace(); + } catch (Throwable t) { + LOG.error("Caught Throwable: unexpected error instantiating object of class[" + className + "]. Returning null!"); + t.printStackTrace(); + } + + if(LOG.isDebugEnabled()) { + LOG.debug(String.format("<== RangerDefaultPolicyEvaluator.newConditionEvauator(%s)", evaluator == null ? null : evaluator.toString())); + } + return evaluator; + } + @Override public void evaluate(RangerAccessRequest request, RangerAccessResult result) { if(LOG.isDebugEnabled()) { @@ -129,7 +252,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator continue; } - boolean isCustomConditionsMatch = matchCustomConditions(policyItem, request); + boolean isCustomConditionsMatch = matchCustomConditions(request, conditionEvaluators); if(! isCustomConditionsMatch) { continue; @@ -334,21 +457,44 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } - protected boolean matchCustomConditions(RangerPolicyItem policyItem, RangerAccessRequest request) { + // takes map in as argument for testability + protected boolean matchCustomConditions(RangerAccessRequest request, Map<String, RangerConditionEvaluator> evaluatorMap) { if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.matchCustomConditions(" + policyItem + ", " + request + ")"); + LOG.debug("==> RangerDefaultPolicyEvaluator.matchCustomConditions(" + request + ")"); + } + + boolean matched = true; + + Map<String, String> input = request.getConditions(); + if (input == null || input.size() == 0) { + // if input didn't even have certain inputs then it could never fail the check. + matched = true; // assignment only to document in code the result + } else { + // we want to abort the minute we find a mismatch + Iterator<Map.Entry<String, String>> iterator = input.entrySet().iterator(); + while (iterator.hasNext() && matched) { + Map.Entry<String, String> anEntry = iterator.next(); + String conditionName = anEntry.getKey(); + String value = anEntry.getValue(); + RangerConditionEvaluator evaluator = evaluatorMap.get(conditionName); + if (evaluator == null) { + // it is possible that due to mis-configuration no evaluator was found. + LOG.warn("No evaluator found for condition[" + conditionName + "]! Check implicitly passed. Context: value[" + value + "]"); + } else { + matched = evaluator.isMatched(value); + if (LOG.isDebugEnabled()) { + String format = "Condition evaluation verdict for condition[%s] with value[%s]: %s"; + LOG.debug(String.format(format, conditionName, value, matched)); + } + } + } } - - boolean ret = false; - - // TODO: - ret = true; - + if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.matchCustomConditions(" + policyItem + ", " + request + "): " + ret); + LOG.debug("<== RangerDefaultPolicyEvaluator.matchCustomConditions(" + request + "): " + matched); } - return ret; + return matched; } protected RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json ---------------------------------------------------------------------- diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json index f6a7157..5857285 100644 --- a/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json +++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-knox.json @@ -29,6 +29,6 @@ ], "policyConditions": [ - {"name":"ip-range","evaluator":"org.apache.ranger.knox.IpRangeCondition","evaluatorOptions":"","label":"IP Address Range","description":"IP Address Range"} + {"name":"ip-range","evaluator":"org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher","evaluatorOptions":"","label":"IP Address Range","description":"IP Address Range"} ] } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java new file mode 100644 index 0000000..10c8697 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/conditionevaluator/RangerIpMatcherTest.java @@ -0,0 +1,160 @@ +/* + * 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.ranger.plugin.conditionevaluator; + + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.mockito.Mockito.*; + +public class RangerIpMatcherTest { + + @Before + public void setUp() throws Exception { + + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void test() { + + RangerIpMatcher ipMatcher = new RangerIpMatcher(); + // uninitialized matcher shoudl behave sensibly! empty matcher matches everything! + assertTrue(ipMatcher.isMatched("1.2.3.4")); + + // empty ip-address list is same as null, i.e. matchs anything! + ipMatcher = createMatcher(new String[]{}); + assertTrue(ipMatcher.isMatched("1.2.3.4")); + + // wildcard address will match anything -- ipv4 and ipv6 addresses + ipMatcher = createMatcher(new String[]{"*"}); + assertTrue(ipMatcher.isMatched("1.2.3.4")); + assertTrue(ipMatcher.isMatched("1:2:3:4:5:6")); + + // partial wildcard matches work as expected. + ipMatcher = createMatcher(new String[]{"1.2.3.*"} ); + assertTrue(ipMatcher.isMatched("1.2.3.4")); + assertTrue(ipMatcher.isMatched("1.2.3.123")); + // NOTE: absurd ipv4 address but it should match too! + assertTrue(ipMatcher.isMatched("1.2.3.123567")); + assertTrue(ipMatcher.isMatched("1.2.3..123567")); + assertTrue(ipMatcher.isMatched("1.2.3.boo")); + // mismatches caught correctly + assertFalse(ipMatcher.isMatched("1.2.31.123567")); + assertFalse(ipMatcher.isMatched("1.2.33.123567")); + // no address has special meaning + assertFalse(ipMatcher.isMatched("1.2.0.0")); + assertFalse(ipMatcher.isMatched("1.2.255.255")); + assertFalse(ipMatcher.isMatched("1.2.254.254")); + assertFalse(ipMatcher.isMatched("0.0.0.0")); + assertFalse(ipMatcher.isMatched("255.255.255.255")); + + // wild card can be more than one octets + ipMatcher = createMatcher(new String[]{"11.22.*.*"} ); + assertTrue(ipMatcher.isMatched("11.22.33.4")); + assertTrue(ipMatcher.isMatched("11.22.33.44")); + assertTrue(ipMatcher.isMatched("11.22.253.190")); + assertTrue(ipMatcher.isMatched("11.22.253.190")); + // mismatches + assertFalse(ipMatcher.isMatched("11.222.253.190")); + assertFalse(ipMatcher.isMatched("11.21.253.190")); + + // one need't provide all the octets; missing ones are treaetd as wild cards + ipMatcher = createMatcher(new String[]{"193.214.*"} ); // note just 3 octets in pattern + assertTrue(ipMatcher.isMatched("193.214.3.4")); + assertFalse(ipMatcher.isMatched("193.21.253.190")); + // can't match ipv6 address using a ipv4 policy + assertFalse(ipMatcher.isMatched("193:214:3:4")); + + // same holds for ipv6 addresses + ipMatcher = createMatcher(new String[]{"193:214:*"} ); + assertTrue(ipMatcher.isMatched("193:214:3:4:5:6")); + assertTrue(ipMatcher.isMatched("193:214:13:94:a90:b4f")); + // mismatches work as expected + assertFalse(ipMatcher.isMatched("193:215:13:94:a90:b4f")); + // can't match ipv4 address against ipv6 policy + assertFalse(ipMatcher.isMatched("193.214.3.4")); + + // direct match works as expected + ipMatcher = createMatcher(new String[]{"99:a9:b9:c9:d9:e9"} ); + assertTrue(ipMatcher.isMatched("99:a9:b9:c9:d9:e9")); + assertFalse(ipMatcher.isMatched("99:a9:b9:c9:d0:e9")); + + // Matcher can support multiple patterns of different domains - a mix of ipv4 and ipv6 addresses + ipMatcher = createMatcher(new String[]{"10.20.30.*", "99:a9:b9:c9:d9:*"} ); + assertTrue(ipMatcher.isMatched("99:a9:b9:c9:d9:e9")); + assertTrue(ipMatcher.isMatched("99:a9:b9:c9:d9:e9")); + assertFalse(ipMatcher.isMatched("99:a9:b9:c9:dd:e9")); + assertFalse(ipMatcher.isMatched("89:a9:b9:c9:d9:e9")); + assertTrue(ipMatcher.isMatched("10.20.30.10")); + assertTrue(ipMatcher.isMatched("10.20.30.20")); + assertFalse(ipMatcher.isMatched("10.20.3.10")); + assertFalse(ipMatcher.isMatched("10.20.33.10")); + } + + @Test + public void testUnexpected() { + // this documents some unexpected behavior of the ip matcher + RangerIpMatcher ipMatcher = createMatcher(new String[]{"1.2.3.*"} ); + // NOTE: absurd and downright illegal ipv4 address would match too! + assertTrue(ipMatcher.isMatched("1.2.3.123567")); + assertTrue(ipMatcher.isMatched("1.2.3..123567")); + assertTrue(ipMatcher.isMatched("1.2.3.boo")); + assertTrue(ipMatcher.isMatched("1.2.3.")); + + // wildcard match happens only at the end + ipMatcher = createMatcher(new String[]{"1.*.3.4"} ); + assertFalse(ipMatcher.isMatched("1.3.3.4")); + assertFalse(ipMatcher.isMatched("1.1.3.4")); + // it becomes a literal match! + assertTrue(ipMatcher.isMatched("1.*.3.4")); + + // same is true of ipv6 + ipMatcher = createMatcher(new String[]{"99:a9:b9:c9:*"} ); + // NOTE: absurd and downright illegal ipv4 address would match too! + assertTrue(ipMatcher.isMatched("99:a9:b9:c9:*")); + assertTrue(ipMatcher.isMatched("99:a9:b9:c9:1.3.4")); + assertTrue(ipMatcher.isMatched("99:a9:b9:c9: <:-) ")); + } + + RangerIpMatcher createMatcher(String[] ipArray) { + List<String> addresses = Arrays.asList(ipArray); + + RangerPolicyItemCondition condition = mock(RangerPolicyItemCondition.class); + + when(condition.getValues()).thenReturn(addresses); + RangerIpMatcher matcher = new RangerIpMatcher(); + matcher.init(condition); + + return matcher; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluatorTest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluatorTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluatorTest.java new file mode 100644 index 0000000..a42ad5b --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluatorTest.java @@ -0,0 +1,297 @@ +/* + * 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.ranger.plugin.policyevaluator; + + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator; +import org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class RangerDefaultPolicyEvaluatorTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void test_newConditionEvauator() { + RangerDefaultPolicyEvaluator evaluator = new RangerDefaultPolicyEvaluator(); + RangerConditionEvaluator ipMatcher = evaluator.newConditionEvauator("org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher"); + assertTrue(ipMatcher.getClass().equals(RangerIpMatcher.class)); + + // bogus value will lead to null object from coming back + ipMatcher = evaluator.newConditionEvauator("org.apache.ranger.plugin.conditionevaluator.RangerIpMatcha"); + assertNull(ipMatcher); + ipMatcher = evaluator.newConditionEvauator("RangerIpMatcher"); + assertNull(ipMatcher); + } + + @Test + public void test_getEvaluatorName() { + + // null policy passing has reasonable response + RangerDefaultPolicyEvaluator evaluator = new RangerDefaultPolicyEvaluator(); + String className = evaluator.getEvaluatorName(null, "aCondition"); + assertNull(className); + // null policy condition def collection should behave sensibly + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + when(serviceDef.getPolicyConditions()).thenReturn(null); + className = evaluator.getEvaluatorName(serviceDef, "aCondition"); + assertNull(className); + + // so should an service def with empty list of policy conditions. + when(serviceDef.getPolicyConditions()).thenReturn(new ArrayList<RangerServiceDef.RangerPolicyConditionDef>()); + className = evaluator.getEvaluatorName(serviceDef, "aCondition"); + assertNull(className); + + // if service has a condition then sensible answer should come back + Map<String, String> pairs = new HashMap<String, String>(); + pairs.put("type1", "com.company.SomeEvaluator"); + pairs.put("type2", "com.company.AnotherEvaluator"); + serviceDef = getMockServiceDef(pairs); + className = evaluator.getEvaluatorName(serviceDef, "type1"); + assertEquals("com.company.SomeEvaluator", className); + className = evaluator.getEvaluatorName(serviceDef, "type2"); + assertEquals("com.company.AnotherEvaluator", className); + className = evaluator.getEvaluatorName(serviceDef, "type3"); + assertNull(className); + } + + @Test + public void test_initializeConditionEvaluators_firewalling() { + RangerServiceDef serviceDef = null; + RangerPolicy policy = null; + // passing null values should yield sensible response + RangerDefaultPolicyEvaluator policyEvaluator = new RangerDefaultPolicyEvaluator(); + Map<String, RangerConditionEvaluator> result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // or if is the policy item collection in the policy is null + policy = mock(RangerPolicy.class); + when(policy.getPolicyItems()).thenReturn(null); + result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // or if the policy item collection is empty + List<RangerPolicyItem> policyItems = new ArrayList<RangerPolicy.RangerPolicyItem>(); + when(policy.getPolicyItems()).thenReturn(policyItems); + result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // or when the policy conditions collection is null + RangerPolicyItem aPolicyItem = mock(RangerPolicyItem.class); + when(aPolicyItem.getConditions()).thenReturn(null); + policyItems.add(aPolicyItem); + when(policy.getPolicyItems()).thenReturn(policyItems); + result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // or when the policy conditions collection is not null but empty + List<RangerPolicyItemCondition> itemConditions = new ArrayList<RangerPolicy.RangerPolicyItemCondition>(); + when(aPolicyItem.getConditions()).thenReturn(itemConditions); + // remove left over from prior test + policyItems.clear(); policyItems.add(aPolicyItem); + when(policy.getPolicyItems()).thenReturn(policyItems); + result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // or when any combination of fields of item conditions are null + RangerPolicyItemCondition anItemCondition = mock(RangerPolicyItemCondition.class); + when(anItemCondition.getType()).thenReturn(null); + when(anItemCondition.getValues()).thenReturn(null); + itemConditions.add(anItemCondition); + when(aPolicyItem.getConditions()).thenReturn(itemConditions); + policyItems.clear(); policyItems.add(aPolicyItem); + when(policy.getPolicyItems()).thenReturn(policyItems); + result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + public void test_initializeConditionEvaluators_happyPath() { + /* + * A policy could contain several policy items and each policy item could contain non-overlapping sets of conditions in them. + * Resulting map should contain a union of conditions in it and each pointing to correct evaluator object. + */ + // first create a service with right condition-name and evaluator names + Map<String, String> conditionEvaluatorMap = new HashMap<String, String>(); + conditionEvaluatorMap.put("c1", "org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluatorTest$Evaluator1"); + conditionEvaluatorMap.put("c2", "org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluatorTest$Evaluator2"); + conditionEvaluatorMap.put("c3", "org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluatorTest$Evaluator3"); + conditionEvaluatorMap.put("c4", "org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluatorTest$Evaluator4"); + RangerServiceDef serviceDef = getMockServiceDef(conditionEvaluatorMap); + // create policy items each with overlapping but dissimilar sets of conditions in them. + RangerPolicyItem anItem = getMockPolicyItem(new String[] {"c1", "c2"}); + RangerPolicyItem anotherItem = getMockPolicyItem(new String[] {"c2", "c3"}); + RangerPolicy policy = mock(RangerPolicy.class); + when(policy.getPolicyItems()).thenReturn(Arrays.asList(anItem, anotherItem)); + RangerDefaultPolicyEvaluator policyEvaluator = new RangerDefaultPolicyEvaluator(); + Map<String, RangerConditionEvaluator> result = policyEvaluator.initializeConditionEvaluators(policy, serviceDef); + + assertNotNull(result); + assertEquals(3, result.size()); + assertTrue(result.containsKey("c1")); + assertTrue(result.containsKey("c2")); + assertTrue(result.containsKey("c3")); + + RangerConditionEvaluator anEvaluator = result.get("c1"); + assertTrue(anEvaluator.getClass().equals(Evaluator1.class)); + anEvaluator = result.get("c2"); + assertTrue(anEvaluator.getClass().equals(Evaluator2.class)); + anEvaluator = result.get("c3"); + assertTrue(anEvaluator.getClass().equals(Evaluator3.class)); + } + + /** + * Test classs: that exists only for testing purposes + * @author alal + * + */ + static class AlwaysPass implements RangerConditionEvaluator { + + @Override + public void init(RangerPolicyItemCondition condition) { + // empty body! + } + @Override + public boolean isMatched(String value) { + return true; + } + + } + + static class AlwaysFail implements RangerConditionEvaluator { + + @Override + public void init(RangerPolicyItemCondition condition) { + // empty body + } + + @Override + public boolean isMatched(String value) { + return false; + } + + } + + static class Evaluator1 extends AlwaysPass {} + static class Evaluator2 extends AlwaysPass {} + static class Evaluator3 extends AlwaysFail {} + static class Evaluator4 extends AlwaysFail {} + + /** + * A request may contain a value for several conditions. A policy could contain evaluators for more conditions than that are in the request. + * check should fail if any condition check fails for the conditions that are contained in the request + */ + @Test + public void test_matchCustomConditions_happyPath() { + + // let's first create a request with 3 different conditons + Map<String, String> requestValues = new HashMap<String, String>(); + requestValues.put("c1", "value1"); + requestValues.put("c2", "value2"); + // let's create the condition evaluator map for each of these conditions and some more. + RangerAccessRequest request = mock(RangerAccessRequest.class); + when(request.getConditions()).thenReturn(requestValues); + Map<String, RangerConditionEvaluator> evaluators = new HashMap<String, RangerConditionEvaluator>(); + evaluators.put("c1", new Evaluator1()); + evaluators.put("c2", new Evaluator2()); + evaluators.put("c3", new Evaluator3()); // conditions 3 and 4 would always fail! + evaluators.put("c4", new Evaluator4()); + // stuff the evaluator with this map + RangerDefaultPolicyEvaluator policyEvaluator = new RangerDefaultPolicyEvaluator(); + boolean result = policyEvaluator.matchCustomConditions(request, evaluators); + assertTrue(result); + + // now check for failure + requestValues.clear(); + requestValues.put("c1", "value1"); + requestValues.put("c3", "value3"); + when(request.getConditions()).thenReturn(requestValues); + result = policyEvaluator.matchCustomConditions(request, evaluators); + assertFalse(result); + } + + RangerPolicyItem getMockPolicyItem(String[] strings) { + RangerPolicyItem policyItem = mock(RangerPolicyItem.class); + if (strings == null) { + when(policyItem.getConditions()).thenReturn(null); + } else if (strings.length == 0) { + when(policyItem.getConditions()).thenReturn(new ArrayList<RangerPolicy.RangerPolicyItemCondition>()); + } else { + List<RangerPolicyItemCondition> conditions = new ArrayList<RangerPolicy.RangerPolicyItemCondition>(strings.length); + for (String name : strings) { + RangerPolicyItemCondition aCondition = mock(RangerPolicyItemCondition.class); + when(aCondition.getType()).thenReturn(name); + when(aCondition.getValues()).thenReturn(null); // values aren't used/needed so set it to a predictable value + conditions.add(aCondition); + } + when(policyItem.getConditions()).thenReturn(conditions); + } + return policyItem; + } + + RangerServiceDef getMockServiceDef(Map<String, String> pairs) { + // create a service def + RangerServiceDef serviceDef = mock(RangerServiceDef.class); + if (pairs == null) { + return serviceDef; + } + List<RangerPolicyConditionDef> conditions = new ArrayList<RangerServiceDef.RangerPolicyConditionDef>(); + // null policy condition def collection should behave sensibly + for (Map.Entry<String, String> anEntry : pairs.entrySet()) { + RangerPolicyConditionDef aCondition = mock(RangerPolicyConditionDef.class); + when(aCondition.getName()).thenReturn(anEntry.getKey()); + when(aCondition.getEvaluator()).thenReturn(anEntry.getValue()); + conditions.add(aCondition); + } + when(serviceDef.getPolicyConditions()).thenReturn(conditions); + return serviceDef; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-impl/src/main/java/org/apache/ranger/pdp/knox/RangerAuthorizer.java ---------------------------------------------------------------------- diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/RangerAuthorizer.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/RangerAuthorizer.java deleted file mode 100644 index 4d14ce0..0000000 --- a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/RangerAuthorizer.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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.ranger.pdp.knox; - -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.ranger.authorization.knox.KnoxAccessVerifier; - -public class RangerAuthorizer implements KnoxAccessVerifier { - - private static final Log LOG = LogFactory.getLog(RangerAuthorizer.class) ; - - private static URLBasedAuthDB authDB = URLBasedAuthDB.getInstance() ; - - public RangerAuthorizer() { - } - - @Override - public boolean isAccessAllowed(String topologyName, String serviceName, String accessType, - String userName, Set<String> groups, String requestIp) { - boolean accessAllowed = authDB.isAccessGranted(topologyName, serviceName, accessType, userName, groups, - requestIp); - if (LOG.isDebugEnabled()) { - LOG.debug("Computed access permission for topology: " + topologyName + - ", service: " + serviceName + - ", access: " + accessType + - ", requestingIp: " +requestIp + - ", requestingUser: " + userName + - ", requestingUserGroups: " + groups + - ", permitted: " + accessAllowed); - } - return accessAllowed; - } - - @Override - public boolean isAuditEnabled(String topologyName, String serviceName) { - boolean auditEnabled = authDB.isAuditEnabled(topologyName, serviceName); - if (LOG.isDebugEnabled()) { - LOG.debug("Computed audit enabled for topology: " + topologyName + - ", service: " + serviceName + - ", auditLogEnabled: " + auditEnabled); - } - return auditEnabled; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java ---------------------------------------------------------------------- diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java index a70224f..a5286f1 100644 --- a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java +++ b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/deploy/RangerPDPKnoxDeploymentContributor.java @@ -31,7 +31,7 @@ import org.apache.hadoop.gateway.topology.Service; public class RangerPDPKnoxDeploymentContributor extends ProviderDeploymentContributorBase { - private static final String FILTER_CLASSNAME = "org.apache.ranger.pdp.knox.filter.RangerPDPKnoxFilter"; + private static final String FILTER_CLASSNAME = "org.apache.ranger.authorization.knox.RangerPDPKnoxFilter"; @Override public String getRole() { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java ---------------------------------------------------------------------- diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java b/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java deleted file mode 100644 index f5608a1..0000000 --- a/agents-impl/src/main/java/org/apache/ranger/pdp/knox/filter/RangerPDPKnoxFilter.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * 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.ranger.pdp.knox.filter; - -import java.io.IOException; -import java.security.AccessController; -import java.security.Principal; -import java.util.HashSet; -import java.util.Set; - -import javax.security.auth.Subject; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.gateway.filter.AbstractGatewayFilter; -import org.apache.hadoop.gateway.security.GroupPrincipal; -import org.apache.hadoop.gateway.security.ImpersonatedPrincipal; -import org.apache.hadoop.gateway.security.PrimaryPrincipal; -import org.apache.ranger.audit.model.EnumRepositoryType; -import org.apache.ranger.audit.model.AuthzAuditEvent; -import org.apache.ranger.audit.provider.AuditProvider; -import org.apache.ranger.audit.provider.AuditProviderFactory; -import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; -import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants; -import org.apache.ranger.authorization.knox.KnoxAccessVerifier; -import org.apache.ranger.authorization.knox.KnoxAccessVerifierFactory; -import org.apache.ranger.authorization.utils.StringUtil; - -public class RangerPDPKnoxFilter implements Filter { - - private static final Log LOG = LogFactory.getLog(RangerPDPKnoxFilter.class); - private static final String ACL_ENFORCER = "xasecure-acl"; - private static final String PERM_ALLOW = "allow"; - private String resourceRole = null; - private KnoxAccessVerifier knoxAccessVerifier; - - - AuditProvider auditProvider = AuditProviderFactory.getAuditProvider(); - private final String REPOSITORY_NAME = RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_REPOSITORY_NAME_PROP); - - static { - RangerConfiguration.getInstance().initAudit("knox"); - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - resourceRole = getInitParameter(filterConfig, "resource.role"); - knoxAccessVerifier = KnoxAccessVerifierFactory.getInstance(); - } - - private String getInitParameter(FilterConfig filterConfig, String paramName) { - return filterConfig.getInitParameter(paramName.toLowerCase()); - } - - public void destroy() { - } - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - - String sourceUrl = (String) request - .getAttribute(AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME); - String topologyName = getTopologyName(sourceUrl); - String serviceName = getServiceName(); - - Subject subject = Subject.getSubject(AccessController.getContext()); - - Principal primaryPrincipal = (Principal) subject.getPrincipals( - PrimaryPrincipal.class).toArray()[0]; - String primaryUser = primaryPrincipal.getName(); - - String impersonatedUser = null; - Object[] impersonations = subject.getPrincipals( - ImpersonatedPrincipal.class).toArray(); - if (impersonations != null && impersonations.length > 0) { - impersonatedUser = ((Principal) impersonations[0]).getName(); - } - - String user = (impersonatedUser != null) ? impersonatedUser - : primaryUser; - if (LOG.isDebugEnabled()) { - LOG.debug("Checking access primaryUser: " + primaryUser + ", impersonatedUser: " - + impersonatedUser + ", effectiveUser: " + user); - } - - Object[] groupObjects = subject.getPrincipals(GroupPrincipal.class) - .toArray(); - Set<String> groups = new HashSet<String>(); - for (Object obj : groupObjects) { - groups.add(((Principal) obj).getName()); - } - - String clientIp = request.getRemoteAddr(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Checking access primaryUser: " + primaryUser + ", impersonatedUser: " - + impersonatedUser + ", effectiveUser: " + user + - ", groups: " + groups + ", clientIp: " + clientIp); - } - boolean accessAllowed = knoxAccessVerifier.isAccessAllowed( - topologyName, serviceName, PERM_ALLOW, user, groups, clientIp); - - if (LOG.isDebugEnabled()) { - LOG.debug("Access allowed: " + accessAllowed); - } - if (accessAllowed) { - chain.doFilter(request, response); - if (knoxAccessVerifier.isAuditEnabled(topologyName, serviceName)) { - LOG.debug("Audit is enabled"); - logAuditEvent(user, clientIp, topologyName, serviceName, - "allow", true); - } else { - LOG.debug("Audit is not enabled"); - } - } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Access is denied"); - } - if (knoxAccessVerifier.isAuditEnabled(topologyName, serviceName)) { - LOG.debug("Audit is enabled"); - logAuditEvent(user, clientIp, topologyName, serviceName, - "allow", false); - } else { - LOG.debug("Audit is not enabled"); - } - sendForbidden((HttpServletResponse) response); - } - } - - private void sendForbidden(HttpServletResponse res) { - sendErrorCode(res, 403); - } - - private void sendErrorCode(HttpServletResponse res, int code) { - try { - res.sendError(code); - } catch (IOException e) { - LOG.error("Error while redireting:", e); - } - } - - private String getTopologyName(String requestUrl) { - if (requestUrl == null) { - return null; - } - String url = requestUrl.trim(); - String[] tokens = url.split("/"); - if (tokens.length > 2) { - return tokens[2]; - } else { - return null; - } - } - - private String getServiceName() { - return resourceRole; - } - - private void logAuditEvent(String userName, String clientIp, - String topology, String service, - String accessType, boolean accessGranted) { - - AuthzAuditEvent auditEvent = new AuthzAuditEvent(); - - auditEvent.setUser(userName == null ? - RangerHadoopConstants.AUDITLOG_EMPTY_STRING : userName); - auditEvent.setResourcePath("/" + topology + "/" + service); - auditEvent.setResourceType("service"); - auditEvent.setAccessType(accessType); - auditEvent.setClientIP(clientIp); - auditEvent.setEventTime(StringUtil.getUTCDate()); - auditEvent.setAccessResult((short) (accessGranted ? 1 : 0)); - auditEvent.setResultReason(null); - auditEvent.setRepositoryType(EnumRepositoryType.KNOX); - auditEvent.setRepositoryName(REPOSITORY_NAME); - auditEvent.setAclEnforcer(ACL_ENFORCER); - - try { - LOG.debug("logEvent [" + auditEvent + "] - START"); - - AuditProvider ap = AuditProviderFactory.getAuditProvider(); - ap.log(auditEvent); - - LOG.debug("logEvent [" + auditEvent + "] - END"); - } catch (Throwable t) { - LOG.error("ERROR logEvent [" + auditEvent + "]", t); - } - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-knox-audit-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-audit-changes.cfg b/knox-agent/conf/ranger-knox-audit-changes.cfg new file mode 100644 index 0000000..f8226ce --- /dev/null +++ b/knox-agent/conf/ranger-knox-audit-changes.cfg @@ -0,0 +1,34 @@ +# 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. +xasecure.audit.db.is.enabled %XAAUDIT.DB.IS_ENABLED% mod create-if-not-exists +xasecure.audit.jpa.javax.persistence.jdbc.url %XAAUDIT_DB_JDBC_URL% mod create-if-not-exists +xasecure.audit.jpa.javax.persistence.jdbc.user %XAAUDIT.DB.USER_NAME% mod create-if-not-exists +xasecure.audit.jpa.javax.persistence.jdbc.password crypted mod create-if-not-exists +xasecure.audit.repository.name %REPOSITORY_NAME% mod create-if-not-exists +xasecure.audit.credential.provider.file jceks://file%CREDENTIAL_PROVIDER_FILE% mod create-if-not-exists +xasecure.audit.jpa.javax.persistence.jdbc.driver %XAAUDIT_DB_JDBC_DRIVER% mod create-if-not-exists + +xasecure.audit.hdfs.is.enabled %XAAUDIT.HDFS.IS_ENABLED% mod create-if-not-exists +xasecure.audit.hdfs.config.destination.directory %XAAUDIT.HDFS.DESTINATION_DIRECTORY% mod create-if-not-exists +xasecure.audit.hdfs.config.destination.file %XAAUDIT.HDFS.DESTINTATION_FILE% mod create-if-not-exists +xasecure.audit.hdfs.config.destination.flush.interval.seconds %XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS% mod create-if-not-exists +xasecure.audit.hdfs.config.destination.rollover.interval.seconds %XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS% mod create-if-not-exists +xasecure.audit.hdfs.config.destination.open.retry.interval.seconds %XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS% mod create-if-not-exists +xasecure.audit.hdfs.config.local.buffer.directory %XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY% mod create-if-not-exists +xasecure.audit.hdfs.config.local.buffer.file %XAAUDIT.HDFS.LOCAL_BUFFER_FILE% mod create-if-not-exists +xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds %XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS% mod create-if-not-exists +xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds %XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS% mod create-if-not-exists +xasecure.audit.hdfs.config.local.archive.directory %XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY% mod create-if-not-exists +xasecure.audit.hdfs.config.local.archive.max.file.count %XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT% mod create-if-not-exists http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-knox-audit.xml ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-audit.xml b/knox-agent/conf/ranger-knox-audit.xml new file mode 100644 index 0000000..d16899f --- /dev/null +++ b/knox-agent/conf/ranger-knox-audit.xml @@ -0,0 +1,191 @@ +<?xml version="1.0"?> +<!-- + 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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + <property> + <name>xasecure.audit.is.enabled</name> + <value>true</value> + </property> + + <property> + <name>xasecure.audit.repository.name</name> + <value>knoxdev</value> + </property> + + + <!-- DB audit provider configuration --> + <property> + <name>xasecure.audit.db.is.enabled</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.db.is.async</name> + <value>true</value> + </property> + + <property> + <name>xasecure.audit.db.async.max.queue.size</name> + <value>10240</value> + </property> + + <property> + <name>xasecure.audit.db.async.max.flush.interval.ms</name> + <value>30000</value> + </property> + + <property> + <name>xasecure.audit.db.batch.size</name> + <value>100</value> + </property> + + <!-- Properties whose name begin with "xasecure.audit.jpa." are used to configure JPA --> + <property> + <name>xasecure.audit.jpa.javax.persistence.jdbc.url</name> + <value>jdbc:mysql://localhost:3306/ranger_audit</value> + </property> + + <property> + <name>xasecure.audit.jpa.javax.persistence.jdbc.user</name> + <value>rangerlogger</value> + </property> + + <property> + <name>xasecure.audit.jpa.javax.persistence.jdbc.password</name> + <value>none</value> + </property> + + <property> + <name>xasecure.audit.jpa.javax.persistence.jdbc.driver</name> + <value>com.mysql.jdbc.Driver</value> + </property> + + <property> + <name>xasecure.audit.credential.provider.file</name> + <value>jceks://file/etc/ranger/knoxdev/auditcred.jceks</value> + </property> + + + <!-- HDFS audit provider configuration --> + <property> + <name>xasecure.audit.hdfs.is.enabled</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.hdfs.is.async</name> + <value>true</value> + </property> + + <property> + <name>xasecure.audit.hdfs.async.max.queue.size</name> + <value>1048576</value> + </property> + + <property> + <name>xasecure.audit.hdfs.async.max.flush.interval.ms</name> + <value>30000</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.encoding</name> + <value></value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.destination.directory</name> + <value>hdfs://NAMENODE_HOST:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.destination.file</name> + <value>%hostname%-audit.log</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.destination.flush.interval.seconds</name> + <value>900</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.destination.rollover.interval.seconds</name> + <value>86400</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.destination.open.retry.interval.seconds</name> + <value>60</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.buffer.directory</name> + <value>/var/log/knox/audit</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.buffer.file</name> + <value>%time:yyyyMMdd-HHmm.ss%.log</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.buffer.file.buffer.size.bytes</name> + <value>8192</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds</name> + <value>60</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds</name> + <value>600</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.archive.directory</name> + <value>/var/log/knox/audit/archive</value> + </property> + + <property> + <name>xasecure.audit.hdfs.config.local.archive.max.file.count</name> + <value>10</value> + </property> + + + <!-- Log4j audit provider configuration --> + <property> + <name>xasecure.audit.log4j.is.enabled</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.log4j.is.async</name> + <value>false</value> + </property> + + <property> + <name>xasecure.audit.log4j.async.max.queue.size</name> + <value>10240</value> + </property> + + <property> + <name>xasecure.audit.log4j.async.max.flush.interval.ms</name> + <value>30000</value> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-knox-security-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-security-changes.cfg b/knox-agent/conf/ranger-knox-security-changes.cfg new file mode 100644 index 0000000..7a2b597 --- /dev/null +++ b/knox-agent/conf/ranger-knox-security-changes.cfg @@ -0,0 +1,26 @@ +# 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. +# +# Change the original policy parameter to work with policy manager based. +# +# +ranger.plugin.knox.service.name %REPOSITORY_NAME% mod create-if-not-exists + +ranger.plugin.knox.service.store.class org.apache.ranger.plugin.store.rest.ServiceRESTStore mod create-if-not-exists +ranger.plugin.knox.service.store.cache.dir %POLICY_CACHE_FILE_PATH% mod create-if-not-exists +ranger.plugin.knox.service.store.pollIntervalMs 30000 mod create-if-not-exists + +ranger.service.store.rest.url %POLICY_MGR_URL% mod create-if-not-exists +ranger.service.store.rest.ssl.config.file /etc/knox/conf/ranger-policymgr-ssl.xml mod create-if-not-exists http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-knox-security.xml ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-knox-security.xml b/knox-agent/conf/ranger-knox-security.xml new file mode 100644 index 0000000..0b03a35 --- /dev/null +++ b/knox-agent/conf/ranger-knox-security.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- + 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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + + <property> + <name>ranger.plugin.knox.service.name</name> + <value>knoxdev</value> + <description> + Name of the Ranger service containing policies for this Knox instance + </description> + </property> + + <property> + <name>ranger.plugin.knox.service.store.class</name> + <value>org.apache.ranger.plugin.store.rest.ServiceRESTStore</value> + <description> + Service storage implementation class to use to retrieve policies + </description> + </property> + + <property> + <name>ranger.plugin.knox.service.store.pollIntervalMs</name> + <value>30000</value> + <description> + How often to poll for changes in policies? + </description> + </property> + + <property> + <name>ranger.plugin.knox.service.store.cache.dir</name> + <value>/etc/ranger/knoxdev/policycache</value> + <description> + Directory where Ranger policies are cached after successful retrieval from the store + </description> + </property> + + <!-- The following properties are used only when Ranger Admin REST interface is used to retrieve the policies --> + <property> + <name>ranger.service.store.rest.url</name> + <value>http://policymanagerhost:port</value> + <description> + URL to Ranger Admin + </description> + </property> + + <property> + <name>ranger.service.store.rest.ssl.config.file</name> + <value>/etc/knox/conf/ranger-policymgr-ssl.xml</value> + <description>Path to the file containing SSL details to contact Ranger Admin</description> + </property> + +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-policymgr-ssl-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-policymgr-ssl-changes.cfg b/knox-agent/conf/ranger-policymgr-ssl-changes.cfg new file mode 100644 index 0000000..50915b2 --- /dev/null +++ b/knox-agent/conf/ranger-policymgr-ssl-changes.cfg @@ -0,0 +1,23 @@ +# 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. +# +# SSL Params +# +xasecure.policymgr.clientssl.keystore %SSL_KEYSTORE_FILE_PATH% mod create-if-not-exists +xasecure.policymgr.clientssl.keystore.password %SSL_KEYSTORE_PASSWORD% mod create-if-not-exists +xasecure.policymgr.clientssl.keystore.credential.file jceks://file%CREDENTIAL_PROVIDER_FILE% mod create-if-not-exists +xasecure.policymgr.clientssl.truststore %SSL_TRUSTSTORE_FILE_PATH% mod create-if-not-exists +xasecure.policymgr.clientssl.truststore.password %SSL_TRUSTSTORE_PASSWORD% mod create-if-not-exists +xasecure.policymgr.clientssl.truststore.credential.file jceks://file%CREDENTIAL_PROVIDER_FILE% mod create-if-not-exists http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/ranger-policymgr-ssl.xml ---------------------------------------------------------------------- diff --git a/knox-agent/conf/ranger-policymgr-ssl.xml b/knox-agent/conf/ranger-policymgr-ssl.xml new file mode 100644 index 0000000..1020ec4 --- /dev/null +++ b/knox-agent/conf/ranger-policymgr-ssl.xml @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<!-- + 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. +--> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> + <!-- The following properties are used for 2-way SSL client server validation --> + <property> + <name>xasecure.policymgr.clientssl.keystore</name> + <value>knoxdev-clientcert.jks</value> + <description> + Java Keystore files + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.keystore.password</name> + <value>none</value> + <description> + password for keystore + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore</name> + <value>cacerts-xasecure.jks</value> + <description> + java truststore file + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore.password</name> + <value>none</value> + <description> + java truststore password + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.keystore.credential.file</name> + <value>jceks://file/tmp/keystore-knoxdev-ssl.jceks</value> + <description> + java keystore credential file + </description> + </property> + <property> + <name>xasecure.policymgr.clientssl.truststore.credential.file</name> + <value>jceks://file/tmp/truststore-knoxdev-ssl.jceks</value> + <description> + java truststore credential file + </description> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/xasecure-audit-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/xasecure-audit-changes.cfg b/knox-agent/conf/xasecure-audit-changes.cfg deleted file mode 100644 index bec9ab5..0000000 --- a/knox-agent/conf/xasecure-audit-changes.cfg +++ /dev/null @@ -1,33 +0,0 @@ -# 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. -xasecure.audit.db.is.enabled %XAAUDIT.DB.IS_ENABLED% mod create-if-not-exists -xasecure.audit.jpa.javax.persistence.jdbc.url %XAAUDIT_DB_JDBC_URL% mod create-if-not-exists -xasecure.audit.jpa.javax.persistence.jdbc.user %XAAUDIT.DB.USER_NAME% mod create-if-not-exists -xasecure.audit.credential.provider.file jceks://file%CREDENTIAL_PROVIDER_FILE% mod create-if-not-exists -xasecure.audit.repository.name %REPOSITORY_NAME% mod create-if-not-exists -xasecure.audit.jpa.javax.persistence.jdbc.driver %XAAUDIT_DB_JDBC_DRIVER% mod create-if-not-exists - -xasecure.audit.hdfs.is.enabled %XAAUDIT.HDFS.IS_ENABLED% mod create-if-not-exists -xasecure.audit.hdfs.config.destination.directory %XAAUDIT.HDFS.DESTINATION_DIRECTORY% mod create-if-not-exists -xasecure.audit.hdfs.config.destination.file %XAAUDIT.HDFS.DESTINTATION_FILE% mod create-if-not-exists -xasecure.audit.hdfs.config.destination.flush.interval.seconds %XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS% mod create-if-not-exists -xasecure.audit.hdfs.config.destination.rollover.interval.seconds %XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS% mod create-if-not-exists -xasecure.audit.hdfs.config.destination.open.retry.interval.seconds %XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS% mod create-if-not-exists -xasecure.audit.hdfs.config.local.buffer.directory %XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY% mod create-if-not-exists -xasecure.audit.hdfs.config.local.buffer.file %XAAUDIT.HDFS.LOCAL_BUFFER_FILE% mod create-if-not-exists -xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds %XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS% mod create-if-not-exists -xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds %XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS% mod create-if-not-exists -xasecure.audit.hdfs.config.local.archive.directory %XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY% mod create-if-not-exists -xasecure.audit.hdfs.config.local.archive.max.file.count %XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT% mod create-if-not-exists http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/xasecure-audit.xml ---------------------------------------------------------------------- diff --git a/knox-agent/conf/xasecure-audit.xml b/knox-agent/conf/xasecure-audit.xml deleted file mode 100644 index d16899f..0000000 --- a/knox-agent/conf/xasecure-audit.xml +++ /dev/null @@ -1,191 +0,0 @@ -<?xml version="1.0"?> -<!-- - 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. ---> -<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> -<configuration xmlns:xi="http://www.w3.org/2001/XInclude"> - <property> - <name>xasecure.audit.is.enabled</name> - <value>true</value> - </property> - - <property> - <name>xasecure.audit.repository.name</name> - <value>knoxdev</value> - </property> - - - <!-- DB audit provider configuration --> - <property> - <name>xasecure.audit.db.is.enabled</name> - <value>false</value> - </property> - - <property> - <name>xasecure.audit.db.is.async</name> - <value>true</value> - </property> - - <property> - <name>xasecure.audit.db.async.max.queue.size</name> - <value>10240</value> - </property> - - <property> - <name>xasecure.audit.db.async.max.flush.interval.ms</name> - <value>30000</value> - </property> - - <property> - <name>xasecure.audit.db.batch.size</name> - <value>100</value> - </property> - - <!-- Properties whose name begin with "xasecure.audit.jpa." are used to configure JPA --> - <property> - <name>xasecure.audit.jpa.javax.persistence.jdbc.url</name> - <value>jdbc:mysql://localhost:3306/ranger_audit</value> - </property> - - <property> - <name>xasecure.audit.jpa.javax.persistence.jdbc.user</name> - <value>rangerlogger</value> - </property> - - <property> - <name>xasecure.audit.jpa.javax.persistence.jdbc.password</name> - <value>none</value> - </property> - - <property> - <name>xasecure.audit.jpa.javax.persistence.jdbc.driver</name> - <value>com.mysql.jdbc.Driver</value> - </property> - - <property> - <name>xasecure.audit.credential.provider.file</name> - <value>jceks://file/etc/ranger/knoxdev/auditcred.jceks</value> - </property> - - - <!-- HDFS audit provider configuration --> - <property> - <name>xasecure.audit.hdfs.is.enabled</name> - <value>false</value> - </property> - - <property> - <name>xasecure.audit.hdfs.is.async</name> - <value>true</value> - </property> - - <property> - <name>xasecure.audit.hdfs.async.max.queue.size</name> - <value>1048576</value> - </property> - - <property> - <name>xasecure.audit.hdfs.async.max.flush.interval.ms</name> - <value>30000</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.encoding</name> - <value></value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.destination.directory</name> - <value>hdfs://NAMENODE_HOST:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.destination.file</name> - <value>%hostname%-audit.log</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.destination.flush.interval.seconds</name> - <value>900</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.destination.rollover.interval.seconds</name> - <value>86400</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.destination.open.retry.interval.seconds</name> - <value>60</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.buffer.directory</name> - <value>/var/log/knox/audit</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.buffer.file</name> - <value>%time:yyyyMMdd-HHmm.ss%.log</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.buffer.file.buffer.size.bytes</name> - <value>8192</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds</name> - <value>60</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds</name> - <value>600</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.archive.directory</name> - <value>/var/log/knox/audit/archive</value> - </property> - - <property> - <name>xasecure.audit.hdfs.config.local.archive.max.file.count</name> - <value>10</value> - </property> - - - <!-- Log4j audit provider configuration --> - <property> - <name>xasecure.audit.log4j.is.enabled</name> - <value>false</value> - </property> - - <property> - <name>xasecure.audit.log4j.is.async</name> - <value>false</value> - </property> - - <property> - <name>xasecure.audit.log4j.async.max.queue.size</name> - <value>10240</value> - </property> - - <property> - <name>xasecure.audit.log4j.async.max.flush.interval.ms</name> - <value>30000</value> - </property> -</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/6edf6d86/knox-agent/conf/xasecure-knox-security-changes.cfg ---------------------------------------------------------------------- diff --git a/knox-agent/conf/xasecure-knox-security-changes.cfg b/knox-agent/conf/xasecure-knox-security-changes.cfg deleted file mode 100644 index 8431962..0000000 --- a/knox-agent/conf/xasecure-knox-security-changes.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# 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. -# -# Change the original policy parameter to work with policy manager based. -# -# -knox.authorization.verifier.classname org.apache.ranger.pdp.knox.RangerAuthorizer mod create-if-not-exists -xasecure.knox.policymgr.url %POLICY_MGR_URL%/service/assets/policyList/%REPOSITORY_NAME% mod create-if-not-exists -xasecure.knox.policymgr.url.saveAsFile /tmp/knox%REPOSITORY_NAME%_json mod create-if-not-exists -xasecure.knox.policymgr.url.reloadIntervalInMillis 30000 mod create-if-not-exists -hadoop.security.credential.provider.path %CREDENTIAL_PROVIDER_FILE% mod create-if-not-exists -xasecure.knox.policymgr.ssl.config /etc/knox/conf/xasecure-policymgr-ssl.xml mod create-if-not-exists
