Repository: hive Updated Branches: refs/heads/master 230ed7876 -> b569b49e0
HIVE-15661 : Add security error logging to LLAP (Sergey Shelukhin, reviewed by Jason Dere) Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/b569b49e Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/b569b49e Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/b569b49e Branch: refs/heads/master Commit: b569b49e0596c52234fadc620c014844d0539f0e Parents: 230ed78 Author: Sergey Shelukhin <ser...@apache.org> Authored: Thu Jan 19 15:10:21 2017 -0800 Committer: Sergey Shelukhin <ser...@apache.org> Committed: Thu Jan 19 15:14:20 2017 -0800 ---------------------------------------------------------------------- .../hive/llap/security/LlapTokenIdentifier.java | 3 +- .../llap/daemon/impl/ContainerRunnerImpl.java | 45 ++++++++++++++++++-- .../hive/llap/daemon/impl/LlapTokenChecker.java | 4 +- 3 files changed, 45 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java ---------------------------------------------------------------------- diff --git a/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java b/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java index 08c141f..0786b7a 100644 --- a/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java +++ b/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java @@ -105,7 +105,8 @@ public class LlapTokenIdentifier extends AbstractDelegationTokenIdentifier { @Override public String toString() { - return KIND + "; " + super.toString() + ", cluster " + clusterId + ", app ID " + appId; + return KIND + "; " + super.toString() + ", cluster " + clusterId + + ", app ID " + appId + ", signing " + isSigningRequired; } @InterfaceAudience.Private http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java ---------------------------------------------------------------------- diff --git a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java index 1346050..6d7d4de 100644 --- a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java +++ b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import org.apache.hadoop.conf.Configuration; @@ -54,6 +55,7 @@ import org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.Terminate import org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.VertexOrBinary; import org.apache.hadoop.hive.llap.metrics.LlapDaemonExecutorMetrics; import org.apache.hadoop.hive.llap.security.LlapSignerImpl; +import org.apache.hadoop.hive.llap.security.LlapTokenIdentifier; import org.apache.hadoop.hive.llap.tez.Converters; import org.apache.hadoop.hive.llap.tezplugins.LlapTezUtils; import org.apache.hadoop.io.DataInputBuffer; @@ -171,7 +173,13 @@ public class ContainerRunnerImpl extends CompositeService implements ContainerRu @Override public SubmitWorkResponseProto submitWork(SubmitWorkRequestProto request) throws IOException { - LlapTokenInfo tokenInfo = LlapTokenChecker.getTokenInfo(clusterId); + LlapTokenInfo tokenInfo = null; + try { + tokenInfo = LlapTokenChecker.getTokenInfo(clusterId); + } catch (SecurityException ex) { + logSecurityErrorRarely(null); + throw ex; + } SignableVertexSpec vertex = extractVertexSpec(request, tokenInfo); TezEvent initialEvent = extractInitialEvent(request, tokenInfo); @@ -296,10 +304,16 @@ public class ContainerRunnerImpl extends CompositeService implements ContainerRu NotTezEvent initialEvent = NotTezEvent.parseFrom(initialEventBytes); if (tokenInfo.isSigningRequired) { if (!request.hasInitialEventSignature()) { + logSecurityErrorRarely(tokenInfo.userName); throw new SecurityException("Unsigned initial event is not allowed"); } byte[] signatureBytes = request.getInitialEventSignature().toByteArray(); - signer.checkSignature(initialEventBytes, signatureBytes, initialEvent.getKeyId()); + try { + signer.checkSignature(initialEventBytes, signatureBytes, initialEvent.getKeyId()); + } catch (SecurityException ex) { + logSecurityErrorRarely(tokenInfo.userName); + throw ex; + } } return NotTezEventHelper.toTezEvent(initialEvent); } @@ -307,6 +321,7 @@ public class ContainerRunnerImpl extends CompositeService implements ContainerRu private void checkSignature(SignableVertexSpec vertex, ByteString vertexBinary, SubmitWorkRequestProto request, String tokenUserName) throws SecurityException, IOException { if (!request.hasWorkSpecSignature()) { + logSecurityErrorRarely(tokenUserName); throw new SecurityException("Unsigned fragment not allowed"); } if (vertexBinary == null) { @@ -314,14 +329,36 @@ public class ContainerRunnerImpl extends CompositeService implements ContainerRu vertex.writeTo(os); vertexBinary = os.toByteString(); } - signer.checkSignature(vertexBinary.toByteArray(), - request.getWorkSpecSignature().toByteArray(), (int)vertex.getSignatureKeyId()); + try { + signer.checkSignature(vertexBinary.toByteArray(), + request.getWorkSpecSignature().toByteArray(), (int)vertex.getSignatureKeyId()); + } catch (SecurityException ex) { + logSecurityErrorRarely(tokenUserName); + throw ex; + } if (!vertex.hasUser() || !vertex.getUser().equals(tokenUserName)) { + logSecurityErrorRarely(tokenUserName); throw new SecurityException("LLAP token is for " + tokenUserName + " but the fragment is for " + (vertex.hasUser() ? vertex.getUser() : null)); } } + private final AtomicLong lastLoggedError = new AtomicLong(0); + private void logSecurityErrorRarely(String userName) { + if (!LOG.isWarnEnabled()) return; + long time = System.nanoTime(); + long oldTime = lastLoggedError.get(); + if (oldTime != 0 && (time - oldTime) < 1000000000L) return; // 1 second + if (!lastLoggedError.compareAndSet(oldTime, time)) return; + String tokens = null; + try { + tokens = "" + LlapTokenChecker.getLlapTokens(UserGroupInformation.getCurrentUser(), null); + } catch (Exception e) { + tokens = "error: " + e.getMessage(); + } + LOG.warn("Security error from " + userName + "; cluster " + clusterId + "; tokens " + tokens); + } + @Override public SourceStateUpdatedResponseProto sourceStateUpdated( SourceStateUpdatedRequestProto request) throws IOException { http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java ---------------------------------------------------------------------- diff --git a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java index c606c9b..170ba33 100644 --- a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java +++ b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java @@ -72,7 +72,7 @@ public final class LlapTokenChecker { } } - private static List<LlapTokenIdentifier> getLlapTokens( + static List<LlapTokenIdentifier> getLlapTokens( UserGroupInformation ugi, String clusterId) { List<LlapTokenIdentifier> tokens = null; for (TokenIdentifier id : ugi.getTokenIdentifiers()) { @@ -81,7 +81,7 @@ public final class LlapTokenChecker { LOG.debug("Token {}", id); } LlapTokenIdentifier llapId = (LlapTokenIdentifier)id; - if (!clusterId.equals(llapId.getClusterId())) continue; + if (clusterId != null && !clusterId.equals(llapId.getClusterId())) continue; if (tokens == null) { tokens = new ArrayList<>(); }