예제 #1
0
        /// <summary>This tests whether a containerId is serialized/deserialized with epoch.</summary>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="System.Exception"/>
        /// <exception cref="Org.Apache.Hadoop.Yarn.Exceptions.YarnException"/>
        private void TestContainerTokenWithEpoch(Configuration conf)
        {
            Log.Info("Running test for serializing/deserializing containerIds");
            NMTokenSecretManagerInRM nmTokenSecretManagerInRM = yarnCluster.GetResourceManager
                                                                    ().GetRMContext().GetNMTokenSecretManager();
            ApplicationId            appId                    = ApplicationId.NewInstance(1, 1);
            ApplicationAttemptId     appAttemptId             = ApplicationAttemptId.NewInstance(appId, 0);
            ContainerId              cId                      = ContainerId.NewContainerId(appAttemptId, (5L << 40) | 3L);
            NodeManager              nm                       = yarnCluster.GetNodeManager(0);
            NMTokenSecretManagerInNM nmTokenSecretManagerInNM = nm.GetNMContext().GetNMTokenSecretManager
                                                                    ();
            string user = "******";

            WaitForNMToReceiveNMTokenKey(nmTokenSecretManagerInNM, nm);
            NodeId nodeId = nm.GetNMContext().GetNodeId();

            // Both id should be equal.
            NUnit.Framework.Assert.AreEqual(nmTokenSecretManagerInNM.GetCurrentKey().GetKeyId
                                                (), nmTokenSecretManagerInRM.GetCurrentKey().GetKeyId());
            // Creating a normal Container Token
            RMContainerTokenSecretManager containerTokenSecretManager = yarnCluster.GetResourceManager
                                                                            ().GetRMContext().GetContainerTokenSecretManager();
            Resource r = Resource.NewInstance(1230, 2);

            Org.Apache.Hadoop.Yarn.Api.Records.Token containerToken = containerTokenSecretManager
                                                                      .CreateContainerToken(cId, nodeId, user, r, Priority.NewInstance(0), 0);
            ContainerTokenIdentifier containerTokenIdentifier = new ContainerTokenIdentifier(
                );

            byte[]          tokenIdentifierContent = ((byte[])containerToken.GetIdentifier().Array());
            DataInputBuffer dib = new DataInputBuffer();

            dib.Reset(tokenIdentifierContent, tokenIdentifierContent.Length);
            containerTokenIdentifier.ReadFields(dib);
            NUnit.Framework.Assert.AreEqual(cId, containerTokenIdentifier.GetContainerID());
            NUnit.Framework.Assert.AreEqual(cId.ToString(), containerTokenIdentifier.GetContainerID
                                                ().ToString());
            Org.Apache.Hadoop.Yarn.Api.Records.Token nmToken = nmTokenSecretManagerInRM.CreateNMToken
                                                                   (appAttemptId, nodeId, user);
            YarnRPC rpc = YarnRPC.Create(conf);

            TestStartContainer(rpc, appAttemptId, nodeId, containerToken, nmToken, false);
            IList <ContainerId> containerIds = new List <ContainerId>();

            containerIds.AddItem(cId);
            ContainerManagementProtocol proxy = GetContainerManagementProtocolProxy(rpc, nmToken
                                                                                    , nodeId, user);
            GetContainerStatusesResponse res = proxy.GetContainerStatuses(GetContainerStatusesRequest
                                                                          .NewInstance(containerIds));

            NUnit.Framework.Assert.IsNotNull(res.GetContainerStatuses()[0]);
            NUnit.Framework.Assert.AreEqual(cId, res.GetContainerStatuses()[0].GetContainerId
                                                ());
            NUnit.Framework.Assert.AreEqual(cId.ToString(), res.GetContainerStatuses()[0].GetContainerId
                                                ().ToString());
        }
예제 #2
0
        /// <summary>
        /// This tests a malice user getting a proper token but then messing with it by
        /// tampering with containerID/Resource etc..
        /// </summary>
        /// <remarks>
        /// This tests a malice user getting a proper token but then messing with it by
        /// tampering with containerID/Resource etc.. His/her containers should be
        /// rejected.
        /// </remarks>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="System.Exception"/>
        /// <exception cref="Org.Apache.Hadoop.Yarn.Exceptions.YarnException"/>
        private void TestContainerToken(Configuration conf)
        {
            Log.Info("Running test for malice user");

            /*
             * We need to check for containerToken (authorization).
             * Here we will be assuming that we have valid NMToken
             * 1) ContainerToken used is expired.
             * 2) ContainerToken is tampered (resource is modified).
             */
            NMTokenSecretManagerInRM nmTokenSecretManagerInRM = yarnCluster.GetResourceManager
                                                                    ().GetRMContext().GetNMTokenSecretManager();
            ApplicationId            appId                    = ApplicationId.NewInstance(1, 1);
            ApplicationAttemptId     appAttemptId             = ApplicationAttemptId.NewInstance(appId, 0);
            ContainerId              cId                      = ContainerId.NewContainerId(appAttemptId, 0);
            NodeManager              nm                       = yarnCluster.GetNodeManager(0);
            NMTokenSecretManagerInNM nmTokenSecretManagerInNM = nm.GetNMContext().GetNMTokenSecretManager
                                                                    ();
            string user = "******";

            WaitForNMToReceiveNMTokenKey(nmTokenSecretManagerInNM, nm);
            NodeId nodeId = nm.GetNMContext().GetNodeId();

            // Both id should be equal.
            NUnit.Framework.Assert.AreEqual(nmTokenSecretManagerInNM.GetCurrentKey().GetKeyId
                                                (), nmTokenSecretManagerInRM.GetCurrentKey().GetKeyId());
            RMContainerTokenSecretManager containerTokenSecretManager = yarnCluster.GetResourceManager
                                                                            ().GetRMContext().GetContainerTokenSecretManager();
            Resource r = Resource.NewInstance(1230, 2);

            Org.Apache.Hadoop.Yarn.Api.Records.Token containerToken = containerTokenSecretManager
                                                                      .CreateContainerToken(cId, nodeId, user, r, Priority.NewInstance(0), 0);
            ContainerTokenIdentifier containerTokenIdentifier = GetContainerTokenIdentifierFromToken
                                                                    (containerToken);
            // Verify new compatible version ContainerTokenIdentifier can work successfully.
            ContainerTokenIdentifierForTest newVersionTokenIdentifier = new ContainerTokenIdentifierForTest
                                                                            (containerTokenIdentifier, "message");

            byte[] password = containerTokenSecretManager.CreatePassword(newVersionTokenIdentifier
                                                                         );
            Org.Apache.Hadoop.Yarn.Api.Records.Token newContainerToken = BuilderUtils.NewContainerToken
                                                                             (nodeId, password, newVersionTokenIdentifier);
            Org.Apache.Hadoop.Yarn.Api.Records.Token nmToken = nmTokenSecretManagerInRM.CreateNMToken
                                                                   (appAttemptId, nodeId, user);
            YarnRPC rpc = YarnRPC.Create(conf);

            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, appAttemptId, nodeId, newContainerToken
                                                             , nmToken, false).IsEmpty());
            // Creating a tampered Container Token
            RMContainerTokenSecretManager tamperedContainerTokenSecretManager = new RMContainerTokenSecretManager
                                                                                    (conf);

            tamperedContainerTokenSecretManager.RollMasterKey();
            do
            {
                tamperedContainerTokenSecretManager.RollMasterKey();
                tamperedContainerTokenSecretManager.ActivateNextMasterKey();
            }while (containerTokenSecretManager.GetCurrentKey().GetKeyId() == tamperedContainerTokenSecretManager
                    .GetCurrentKey().GetKeyId());
            ContainerId cId2 = ContainerId.NewContainerId(appAttemptId, 1);

            // Creating modified containerToken
            Org.Apache.Hadoop.Yarn.Api.Records.Token containerToken2 = tamperedContainerTokenSecretManager
                                                                       .CreateContainerToken(cId2, nodeId, user, r, Priority.NewInstance(0), 0);
            StringBuilder sb = new StringBuilder("Given Container ");

            sb.Append(cId2);
            sb.Append(" seems to have an illegally generated token.");
            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, appAttemptId, nodeId, containerToken2
                                                             , nmToken, true).Contains(sb.ToString()));
        }
예제 #3
0
        /// <exception cref="System.Exception"/>
        private void TestNMTokens(Configuration conf)
        {
            NMTokenSecretManagerInRM nmTokenSecretManagerRM = yarnCluster.GetResourceManager(
                ).GetRMContext().GetNMTokenSecretManager();
            NMTokenSecretManagerInNM nmTokenSecretManagerNM = yarnCluster.GetNodeManager(0).GetNMContext
                                                                  ().GetNMTokenSecretManager();
            RMContainerTokenSecretManager containerTokenSecretManager = yarnCluster.GetResourceManager
                                                                            ().GetRMContext().GetContainerTokenSecretManager();
            NodeManager nm = yarnCluster.GetNodeManager(0);

            WaitForNMToReceiveNMTokenKey(nmTokenSecretManagerNM, nm);
            // Both id should be equal.
            NUnit.Framework.Assert.AreEqual(nmTokenSecretManagerNM.GetCurrentKey().GetKeyId()
                                            , nmTokenSecretManagerRM.GetCurrentKey().GetKeyId());

            /*
             * Below cases should be tested.
             * 1) If Invalid NMToken is used then it should be rejected.
             * 2) If valid NMToken but belonging to another Node is used then that
             * too should be rejected.
             * 3) NMToken for say appAttempt-1 is used for starting/stopping/retrieving
             * status for container with containerId for say appAttempt-2 should
             * be rejected.
             * 4) After start container call is successful nmtoken should have been
             * saved in NMTokenSecretManagerInNM.
             * 5) If start container call was successful (no matter if container is
             * still running or not), appAttempt->NMToken should be present in
             * NMTokenSecretManagerInNM's cache. Any future getContainerStatus call
             * for containerId belonging to that application attempt using
             * applicationAttempt's older nmToken should not get any invalid
             * nmToken error. (This can be best tested if we roll over NMToken
             * master key twice).
             */
            YarnRPC              rpc               = YarnRPC.Create(conf);
            string               user              = "******";
            Resource             r                 = Resource.NewInstance(1024, 1);
            ApplicationId        appId             = ApplicationId.NewInstance(1, 1);
            ApplicationAttemptId validAppAttemptId = ApplicationAttemptId.NewInstance(appId,
                                                                                      1);
            ContainerId validContainerId = ContainerId.NewContainerId(validAppAttemptId, 0);
            NodeId      validNode        = yarnCluster.GetNodeManager(0).GetNMContext().GetNodeId();
            NodeId      invalidNode      = NodeId.NewInstance("InvalidHost", 1234);
            Token       validNMToken     = nmTokenSecretManagerRM.CreateNMToken(validAppAttemptId, validNode
                                                                                , user);
            Token validContainerToken = containerTokenSecretManager.CreateContainerToken(validContainerId
                                                                                         , validNode, user, r, Priority.NewInstance(10), 1234);
            ContainerTokenIdentifier identifier = BuilderUtils.NewContainerTokenIdentifier(validContainerToken
                                                                                           );

            NUnit.Framework.Assert.AreEqual(Priority.NewInstance(10), identifier.GetPriority(
                                                ));
            NUnit.Framework.Assert.AreEqual(1234, identifier.GetCreationTime());
            StringBuilder sb;
            // testInvalidNMToken ... creating NMToken using different secret manager.
            NMTokenSecretManagerInRM tempManager = new NMTokenSecretManagerInRM(conf);

            tempManager.RollMasterKey();
            do
            {
                tempManager.RollMasterKey();
                tempManager.ActivateNextMasterKey();
            }while (tempManager.GetCurrentKey().GetKeyId() == nmTokenSecretManagerRM.GetCurrentKey
                        ().GetKeyId());
            // Making sure key id is different.
            // Testing that NM rejects the requests when we don't send any token.
            if (UserGroupInformation.IsSecurityEnabled())
            {
                sb = new StringBuilder("Client cannot authenticate via:[TOKEN]");
            }
            else
            {
                sb = new StringBuilder("SIMPLE authentication is not enabled.  Available:[TOKEN]"
                                       );
            }
            string errorMsg = TestStartContainer(rpc, validAppAttemptId, validNode, validContainerToken
                                                 , null, true);

            NUnit.Framework.Assert.IsTrue(errorMsg.Contains(sb.ToString()));
            Token invalidNMToken = tempManager.CreateNMToken(validAppAttemptId, validNode, user
                                                             );

            sb = new StringBuilder("Given NMToken for application : ");
            sb.Append(validAppAttemptId.ToString()).Append(" seems to have been generated illegally."
                                                           );
            NUnit.Framework.Assert.IsTrue(sb.ToString().Contains(TestStartContainer(rpc, validAppAttemptId
                                                                                    , validNode, validContainerToken, invalidNMToken, true)));
            // valid NMToken but belonging to other node
            invalidNMToken = nmTokenSecretManagerRM.CreateNMToken(validAppAttemptId, invalidNode
                                                                  , user);
            sb = new StringBuilder("Given NMToken for application : ");
            sb.Append(validAppAttemptId).Append(" is not valid for current node manager.expected : "
                                                ).Append(validNode.ToString()).Append(" found : ").Append(invalidNode.ToString()
                                                                                                          );
            NUnit.Framework.Assert.IsTrue(sb.ToString().Contains(TestStartContainer(rpc, validAppAttemptId
                                                                                    , validNode, validContainerToken, invalidNMToken, true)));
            // using correct tokens. nmtoken for app attempt should get saved.
            conf.SetInt(YarnConfiguration.RmContainerAllocExpiryIntervalMs, 4 * 60 * 1000);
            validContainerToken = containerTokenSecretManager.CreateContainerToken(validContainerId
                                                                                   , validNode, user, r, Priority.NewInstance(0), 0);
            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, validAppAttemptId, validNode
                                                             , validContainerToken, validNMToken, false).IsEmpty());
            NUnit.Framework.Assert.IsTrue(nmTokenSecretManagerNM.IsAppAttemptNMTokenKeyPresent
                                              (validAppAttemptId));
            // using a new compatible version nmtoken, expect container can be started
            // successfully.
            ApplicationAttemptId validAppAttemptId2 = ApplicationAttemptId.NewInstance(appId,
                                                                                       2);
            ContainerId validContainerId2    = ContainerId.NewContainerId(validAppAttemptId2, 0);
            Token       validContainerToken2 = containerTokenSecretManager.CreateContainerToken(validContainerId2
                                                                                                , validNode, user, r, Priority.NewInstance(0), 0);
            Token validNMToken2 = nmTokenSecretManagerRM.CreateNMToken(validAppAttemptId2, validNode
                                                                       , user);
            // First, get a new NMTokenIdentifier.
            NMTokenIdentifier newIdentifier = new NMTokenIdentifier();

            byte[]          tokenIdentifierContent = ((byte[])validNMToken2.GetIdentifier().Array());
            DataInputBuffer dib = new DataInputBuffer();

            dib.Reset(tokenIdentifierContent, tokenIdentifierContent.Length);
            newIdentifier.ReadFields(dib);
            // Then, generate a new version NMTokenIdentifier (NMTokenIdentifierNewForTest)
            // with additional field of message.
            NMTokenIdentifierNewForTest newVersionIdentifier = new NMTokenIdentifierNewForTest
                                                                   (newIdentifier, "message");

            // check new version NMTokenIdentifier has correct info.
            NUnit.Framework.Assert.AreEqual("The ApplicationAttemptId is changed after set to "
                                            + "newVersionIdentifier", validAppAttemptId2.GetAttemptId(), newVersionIdentifier
                                            .GetApplicationAttemptId().GetAttemptId());
            NUnit.Framework.Assert.AreEqual("The message is changed after set to newVersionIdentifier"
                                            , "message", newVersionIdentifier.GetMessage());
            NUnit.Framework.Assert.AreEqual("The NodeId is changed after set to newVersionIdentifier"
                                            , validNode, newVersionIdentifier.GetNodeId());
            // create new Token based on new version NMTokenIdentifier.
            Token newVersionedNMToken = BaseNMTokenSecretManager.NewInstance(nmTokenSecretManagerRM
                                                                             .RetrievePassword(newVersionIdentifier), newVersionIdentifier);

            // Verify startContainer is successful and no exception is thrown.
            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, validAppAttemptId2, validNode
                                                             , validContainerToken2, newVersionedNMToken, false).IsEmpty());
            NUnit.Framework.Assert.IsTrue(nmTokenSecretManagerNM.IsAppAttemptNMTokenKeyPresent
                                              (validAppAttemptId2));
            //Now lets wait till container finishes and is removed from node manager.
            WaitForContainerToFinishOnNM(validContainerId);
            sb = new StringBuilder("Attempt to relaunch the same container with id ");
            sb.Append(validContainerId);
            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, validAppAttemptId, validNode
                                                             , validContainerToken, validNMToken, true).Contains(sb.ToString()));
            // Container is removed from node manager's memory by this time.
            // trying to stop the container. It should not throw any exception.
            TestStopContainer(rpc, validAppAttemptId, validNode, validContainerId, validNMToken
                              , false);
            // Rolling over master key twice so that we can check whether older keys
            // are used for authentication.
            RollNMTokenMasterKey(nmTokenSecretManagerRM, nmTokenSecretManagerNM);
            // Key rolled over once.. rolling over again
            RollNMTokenMasterKey(nmTokenSecretManagerRM, nmTokenSecretManagerNM);
            // trying get container status. Now saved nmToken should be used for
            // authentication... It should complain saying container was recently
            // stopped.
            sb = new StringBuilder("Container ");
            sb.Append(validContainerId);
            sb.Append(" was recently stopped on node manager");
            NUnit.Framework.Assert.IsTrue(TestGetContainer(rpc, validAppAttemptId, validNode,
                                                           validContainerId, validNMToken, true).Contains(sb.ToString()));
            // Now lets remove the container from nm-memory
            nm.GetNodeStatusUpdater().ClearFinishedContainersFromCache();
            // This should fail as container is removed from recently tracked finished
            // containers.
            sb = new StringBuilder("Container ");
            sb.Append(validContainerId.ToString());
            sb.Append(" is not handled by this NodeManager");
            NUnit.Framework.Assert.IsTrue(TestGetContainer(rpc, validAppAttemptId, validNode,
                                                           validContainerId, validNMToken, false).Contains(sb.ToString()));
            // using appAttempt-1 NMtoken for launching container for appAttempt-2 should
            // succeed.
            ApplicationAttemptId attempt2 = ApplicationAttemptId.NewInstance(appId, 2);
            Token attempt1NMToken         = nmTokenSecretManagerRM.CreateNMToken(validAppAttemptId, validNode
                                                                                 , user);
            Token newContainerToken = containerTokenSecretManager.CreateContainerToken(ContainerId
                                                                                       .NewContainerId(attempt2, 1), validNode, user, r, Priority.NewInstance(0), 0);

            NUnit.Framework.Assert.IsTrue(TestStartContainer(rpc, attempt2, validNode, newContainerToken
                                                             , attempt1NMToken, false).IsEmpty());
        }