You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by ad...@apache.org on 2021/10/11 07:00:03 UTC
[ozone] branch HDDS-4440-s3-performance updated: HDDS-5780. Support
s3 authentication on a per request basis (#2721)
This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch HDDS-4440-s3-performance
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-4440-s3-performance by this push:
new b0f41d6 HDDS-5780. Support s3 authentication on a per request basis (#2721)
b0f41d6 is described below
commit b0f41d67da7cdec7aabdb71de8b005cc879280bc
Author: Neil Joshi <ne...@gmail.com>
AuthorDate: Mon Oct 11 00:59:50 2021 -0600
HDDS-5780. Support s3 authentication on a per request basis (#2721)
---
.../ozone/om/protocolPB/GrpcOmTransport.java | 39 +++++++++
.../hadoop/ozone/om/GrpcOzoneManagerServer.java | 24 ++++--
.../org/apache/hadoop/ozone/om/OzoneManager.java | 7 +-
.../hadoop/ozone/om/OzoneManagerServiceGrpc.java | 95 ++++++++++++++++++----
.../ozone/om/TestGrpcOzoneManagerServer.java | 6 +-
5 files changed, 142 insertions(+), 29 deletions(-)
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/GrpcOmTransport.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/GrpcOmTransport.java
index 752f29e..22d49a9 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/GrpcOmTransport.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/GrpcOmTransport.java
@@ -17,7 +17,11 @@
*/
package org.apache.hadoop.ozone.om.protocolPB;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -27,8 +31,14 @@ import org.apache.hadoop.hdds.conf.ConfigGroup;
import org.apache.hadoop.hdds.conf.ConfigTag;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.io.Text;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerServiceGrpc;
@@ -45,6 +55,8 @@ import static org.apache.hadoop.ozone.om.OMConfigKeys
import static org.apache.hadoop.ozone.om.OMConfigKeys
.OZONE_OM_GRPC_MAXIMUM_RESPONSE_LENGTH_DEFAULT;
import static org.apache.hadoop.hdds.HddsUtils.getHostNameFromConfigKeys;
+import static org.apache.hadoop.ozone.protocol.proto
+ .OzoneManagerProtocolProtos.OMTokenProto.Type.S3AUTHINFO;
/**
* Grpc transport for grpc between s3g and om.
@@ -98,6 +110,33 @@ public class GrpcOmTransport implements OmTransport {
@Override
public OMResponse submitRequest(OMRequest payload) throws IOException {
+ UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+
+ final Collection<Token<? extends TokenIdentifier>> tokenS3Requests =
+ ugi.getTokens();
+ if (tokenS3Requests.size() > 1) {
+ throw new OMException(ResultCodes.INVALID_TOKEN);
+ }
+ Iterator<Token<? extends TokenIdentifier>> tokenit =
+ tokenS3Requests.iterator();
+ if (tokenit.hasNext()) {
+ OzoneTokenIdentifier oti = OzoneTokenIdentifier.newInstance();
+ oti.readFields(new DataInputStream(
+ new ByteArrayInputStream(tokenit.next().getIdentifier())));
+ if (oti.getTokenType().equals(S3AUTHINFO)) {
+ payload = OMRequest.newBuilder(payload)
+ .setS3Authentication(
+ OzoneManagerProtocolProtos
+ .S3Authentication.newBuilder()
+ .setSignature(oti.getSignature())
+ .setStringToSign(oti.getStrToSign())
+ .setAccessId(oti.getAwsAccessId()))
+ .setUserInfo(OzoneManagerProtocolProtos
+ .UserInfo.newBuilder()
+ .setUserName(ugi.getUserName()).build())
+ .build();
+ }
+ }
return client.submitRequest(payload);
}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/GrpcOzoneManagerServer.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/GrpcOzoneManagerServer.java
index d82024a..60942f9 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/GrpcOzoneManagerServer.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/GrpcOzoneManagerServer.java
@@ -23,8 +23,10 @@ import java.util.concurrent.TimeUnit;
import org.apache.hadoop.hdds.conf.Config;
import org.apache.hadoop.hdds.conf.ConfigGroup;
import org.apache.hadoop.hdds.conf.ConfigTag;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.protocolPB.OzoneManagerProtocolServerSideTranslatorPB;
+import org.apache.hadoop.ozone.security.OzoneDelegationTokenSecretManager;
import io.grpc.Server;
import io.grpc.netty.NettyServerBuilder;
import org.slf4j.Logger;
@@ -40,17 +42,27 @@ public class GrpcOzoneManagerServer {
private Server server;
private int port = 8981;
- public GrpcOzoneManagerServer(GrpcOzoneManagerServerConfig omServerConfig,
+ public GrpcOzoneManagerServer(OzoneConfiguration config,
OzoneManagerProtocolServerSideTranslatorPB
- omTranslator) {
- this.port = omServerConfig.getPort();
- init(omTranslator);
+ omTranslator,
+ OzoneDelegationTokenSecretManager
+ delegationTokenMgr) {
+ this.port = config.getObject(
+ GrpcOzoneManagerServerConfig.class).
+ getPort();
+ init(omTranslator,
+ delegationTokenMgr,
+ config);
}
- public void init(OzoneManagerProtocolServerSideTranslatorPB omTranslator) {
+ public void init(OzoneManagerProtocolServerSideTranslatorPB omTranslator,
+ OzoneDelegationTokenSecretManager delegationTokenMgr,
+ OzoneConfiguration omServerConfig) {
NettyServerBuilder nettyServerBuilder = NettyServerBuilder.forPort(port)
.maxInboundMessageSize(OzoneConsts.OZONE_SCM_CHUNK_MAX_SIZE)
- .addService(new OzoneManagerServiceGrpc(omTranslator));
+ .addService(new OzoneManagerServiceGrpc(omTranslator,
+ delegationTokenMgr,
+ omServerConfig));
server = nettyServerBuilder.build();
}
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 1dd402d..29688ba 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -111,7 +111,6 @@ import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
import org.apache.hadoop.ozone.om.exceptions.OMLeaderNotReadyException;
import org.apache.hadoop.ozone.om.exceptions.OMNotLeaderException;
-import org.apache.hadoop.ozone.om.GrpcOzoneManagerServer.GrpcOzoneManagerServerConfig;
import org.apache.hadoop.ozone.om.ha.OMHANodeDetails;
import org.apache.hadoop.ozone.om.helpers.OMNodeDetails;
import org.apache.hadoop.ozone.om.helpers.DBUpdates;
@@ -1023,9 +1022,9 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
*/
private GrpcOzoneManagerServer startGrpcServer(OzoneConfiguration conf)
throws IOException {
- return new GrpcOzoneManagerServer(conf.getObject(
- GrpcOzoneManagerServerConfig.class),
- this.omServerProtocol);
+ return new GrpcOzoneManagerServer(conf,
+ this.omServerProtocol,
+ this.delegationTokenMgr);
}
private static boolean isOzoneSecurityEnabled() {
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerServiceGrpc.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerServiceGrpc.java
index 95b9285..a23f7ef 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerServiceGrpc.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerServiceGrpc.java
@@ -18,22 +18,35 @@
package org.apache.hadoop.ozone.om;
import com.google.protobuf.RpcController;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.security.x509.SecurityConfig;
+import org.apache.hadoop.io.Text;
import org.apache.hadoop.ipc.ClientId;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.Server;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerServiceGrpc.OzoneManagerServiceImplBase;
import org.apache.hadoop.ozone.protocolPB.OzoneManagerProtocolServerSideTranslatorPB;
import org.apache.hadoop.ozone.protocol.proto
+ .OzoneManagerProtocolProtos.S3Authentication;
+import org.apache.hadoop.ozone.protocol.proto
.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.protocol.proto
.OzoneManagerProtocolProtos.OMResponse;
+import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
+import org.apache.hadoop.ozone.security.OzoneDelegationTokenSecretManager;
+import org.apache.hadoop.security.UserGroupInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
import java.util.concurrent.atomic.AtomicInteger;
+import static org.apache.hadoop.ozone.protocol.proto
+ .OzoneManagerProtocolProtos.OMTokenProto.Type.S3AUTHINFO;
+
/**
* Grpc Service for handling S3 gateway OzoneManagerProtocol client requests.
*/
@@ -45,10 +58,16 @@ public class OzoneManagerServiceGrpc extends OzoneManagerServiceImplBase {
*/
private static final RpcController NULL_RPC_CONTROLLER = null;
private OzoneManagerProtocolServerSideTranslatorPB omTranslator;
+ private OzoneDelegationTokenSecretManager delegationTokenMgr;
+ private final SecurityConfig secConfig;
OzoneManagerServiceGrpc(
- OzoneManagerProtocolServerSideTranslatorPB omTranslator) {
+ OzoneManagerProtocolServerSideTranslatorPB omTranslator,
+ OzoneDelegationTokenSecretManager delegationTokenMgr,
+ OzoneConfiguration configuration) {
this.omTranslator = omTranslator;
+ this.delegationTokenMgr = delegationTokenMgr;
+ this.secConfig = new SecurityConfig(configuration);
}
@Override
@@ -60,22 +79,66 @@ public class OzoneManagerServiceGrpc extends OzoneManagerServiceImplBase {
request.getCmdType().name());
AtomicInteger callCount = new AtomicInteger(0);
OMResponse omResponse;
+
+ if (secConfig.isSecurityEnabled()) {
+ if (request.hasS3Authentication()) {
+ S3Authentication auth = request.getS3Authentication();
+ OzoneTokenIdentifier identifier = new OzoneTokenIdentifier();
+ identifier.setTokenType(S3AUTHINFO);
+ identifier.setStrToSign(auth.getStringToSign());
+ identifier.setSignature(auth.getSignature());
+ identifier.setAwsAccessId(auth.getAccessId());
+ identifier.setOwner(new Text(auth.getAccessId()));
+ try {
+ // authenticate user with signature verification through
+ // delegationTokenMgr validateToken via retrievePassword
+ delegationTokenMgr.retrievePassword(identifier);
+ } catch (Throwable e) {
+ LOG.error("signatures do NOT match for S3 identifier:{}",
+ identifier, e);
+ responseObserver.onNext(
+ createErrorResponse(request,
+ new OMException("User " + request.getUserInfo()
+ .getUserName() +
+ " request authorization failure: " +
+ "signatures do NOT match",
+ OMException.ResultCodes.S3_SECRET_NOT_FOUND)));
+ responseObserver.onCompleted();
+ return;
+ }
+ }
+ }
+
+ org.apache.hadoop.ipc.Server.getCurCall().set(new Server.Call(1,
+ callCount.incrementAndGet(),
+ null,
+ null,
+ RPC.RpcKind.RPC_PROTOCOL_BUFFER,
+ ClientId.getClientId()));
+ // TODO: currently require setting the Server class for each request
+ // with thread context (Server.Call()) that includes retries
+ // and importantly random ClientId. This is currently necessary for
+ // Om Ratis Server to create createWriteRaftClientRequest.
+ // Look to remove Server class requirement for issuing ratis transactions
+ // for OMRequests. Test through successful ratis-enabled OMRequest
+ // handling without dependency on hadoop IPC based Server.
try {
- org.apache.hadoop.ipc.Server.getCurCall().set(new Server.Call(1,
- callCount.incrementAndGet(),
- null,
- null,
- RPC.RpcKind.RPC_PROTOCOL_BUFFER,
- ClientId.getClientId()));
- // TODO: currently require setting the Server class for each request
- // with thread context (Server.Call()) that includes retries
- // and importantly random ClientId. This is currently necessary for
- // Om Ratis Server to create createWriteRaftClientRequest.
- // Look to remove Server class requirement for issuing ratis transactions
- // for OMRequests. Test through successful ratis-enabled OMRequest
- // handling without dependency on hadoop IPC based Server.
- omResponse = this.omTranslator.
- submitRequest(NULL_RPC_CONTROLLER, request);
+ omResponse =
+ UserGroupInformation.getCurrentUser().doAs(
+ (PrivilegedExceptionAction<OMResponse>) () -> {
+ try {
+ return this.omTranslator.
+ submitRequest(NULL_RPC_CONTROLLER, request);
+ } catch (Throwable se) {
+ Throwable e = se.getCause();
+ if (e == null) {
+ throw new IOException(se);
+ } else {
+ throw e instanceof IOException ?
+ (IOException) e : new IOException(se);
+ }
+ }
+ });
} catch (Throwable e) {
omResponse = createErrorResponse(
request,
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestGrpcOzoneManagerServer.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestGrpcOzoneManagerServer.java
index 46155ae..b75a651 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestGrpcOzoneManagerServer.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestGrpcOzoneManagerServer.java
@@ -47,9 +47,9 @@ public class TestGrpcOzoneManagerServer {
ozoneManager = Mockito.mock(OzoneManager.class);
omServerProtocol = ozoneManager.getOmServerProtocol();
- server = new GrpcOzoneManagerServer(conf.getObject(
- GrpcOzoneManagerServer.GrpcOzoneManagerServerConfig.class),
- omServerProtocol);
+ server = new GrpcOzoneManagerServer(conf,
+ omServerProtocol,
+ ozoneManager.getDelegationTokenMgr());
try {
server.start();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org