ECS AD integration and user self-service

AD integration and user self-servicesIn that post I discuss how to configure and use domain users allowing them to generate object storage access credentials by themselves.

Local and domain users

Just a little bit of ECS theory.

ECS provides support for local and domain users. We discuss these types of users in details below.

Local users are user accounts whose credentials are stored by ECS. Both management users and object users can be defined locally to ECS.

Domain users are set out in an AD database. ECS talks to the AD to authenticate domain user login request. Domain users are defined in the form username@domain. Management user with names without @ are authenticated against an ECS local user database.

Only management users can be authenticated as domain users. Object users are always local. So their credentials can not be taken from AD. Object users names can be either defined as simple local-style names or domain-style names with the @ symbol. However, domain-style object users names are still local. They are just used for a convenience only to enable keeping names unique and consistent with AD usernames.

Create ECS Auth Provider

ECS uses an Authentication Provider to supply the credentials it needs to talk to the AD server and authenticate domain users.

Note: To add an Authentication Provider you must have the System Admin role.
  • Specify the AD domain vipr.local
  • AD URL in ldap:// format
  • Manager DN as CN=Administrator,CN=Users,DC=vipr,DC=local

 

Add authentication provider

Note: AD manager DN can be checked using dsquery command
C:\Users\Administrator>dsquery user -name Administrator 
"CN=Administrator,CN=Users,DC=vipr,DC=local"
  • Specify a Search Base

Search Base indicates the Base Distinguished Name that ECS uses to search for users at login time. The search base needs to be high enough in the directory structure to correctly find all the users in the targeted domains.
The structure of the search base value begins with the “leaf” level and goes up to the domain controller level.

Note: Search Base structure is a reverse of the structure presented in AD GUI.
  • Specify a Search Scope

One Level Search Scope will allow searching for users one level under the search base. The subtree is searching the entire subtree under the search base.

  • Specify Search filter as userPrincipalName=%u

Search Filter indicates the string used to select subsets of users. userPrincipalName=%u or sAMAccountName=%U are usually used.

 

AD parameters

Note: Capital %U stands for a username which doesn’t contain a domain name

Create Namespace admin user in AD

Namespace Admin is a management user who can access the ECS Portal to configure namespace settings, such as quotas and retention periods, and can map domain users into the namespace and assign local users as object users for the namespace.

  • Create the new AD user in the vipr.local domain – ecsadmin@vipr.local

Create the new AD user

  • Specify a password

AD parameters

  • Create the new ECS Management user ecsadmin@vipr.local
  • The user doesn’t have System Admin and Monitoring roles

Create the new ECS Management user

  • Assign the user as the ns2 Namespace administrator

Assign the user as Namespace administrator

  • Login as ecsadmin@vipr.local user

Login as ecsadmin@vipr.local user

  • The user is the Namespace admin

The user is the Namespace admin

  • Because the user is not System Admin, it doesn’t have permissions to manage VDC and corresponding configuration

User does not have permissions

 

Create an ordinary user in AD

  • Create the new AD user in the vipr.local domain – ecsuser@vipr.local

Create the new AD user

  • Specify a password

Specify a password

  • Create a new AD Group ecsadmingroup

Assign a group

  • Place the user into the AD group

Place the user into the AD group

Domain user self-service

To save the administrative overhead of manually creating many of object users, a self-service ECS REST APIs allows authenticating domain users, automatically adding them as object users and assigning a secret key to them.

Note: Object users secret keys must be locally created in ECS. AD passwords can not be used by object users.

To be able using self-service APIs, domain user should be mapped into a Namespace-based on a domain name, group membership and attributes associated with AD user account.

Note: ECS REST API must be used to obtain a corresponding object user secret key. Object users do not have access to an ECS portal (ECS 3.0).
  • Log in as a domain user and obtain an authentication token that can be used to authenticate subsequent requests.
host$ curl -ik -u ecsuser@vipr.local:P@ssw0rd https://10.76.246.143:4443/login?using-cookies=true -c cookiefile
 HTTP/1.1 200 OK
 Date: Thu, 03 Nov 2016 20:46:41 GMT
 Content-Type: application/xml
 Content-Length: 107
 Connection: keep-alive
 X-SDS-AUTH-TOKEN: BAAcdCttQXFJYloyWG9RcEVkbUFDTUl0U1k3VE1RPQMAjAQASHVybjpzdG9yYWdlb3M6VmlydHVhbERhdGFDZW50ZXJEYXRhOjBhODNiMjI2LTQwMDQtNGYwMC05OWIzLWEyNmVmNGMxNWZkYQIADTE0NzgwOTg3Mzg0OTADAC51cm46VG9rZW46M2RmMjg3YTctMGY3Mi00YmQ1LWEzYjYtYmEzNzZmN2M5NWZlAgAC0A8=
 Set-Cookie: X-SDS-AUTH-TOKEN=BAAcdCttQXFJYloyWG9RcEVkbUFDTUl0U1k3VE1RPQMAjAQASHVybjpzdG9yYWdlb3M6VmlydHVhbERhdGFDZW50ZXJEYXRhOjBhODNiMjI2LTQwMDQtNGYwMC05OWIzLWEyNmVmNGMxNWZkYQIADTE0NzgwOTg3Mzg0OTADAC51cm46VG9rZW46M2RmMjg3YTctMGY3Mi00YmQ1LWEzYjYtYmEzNzZmN2M5NWZlAgAC0A8=;Version=1;Max-Age=28800;Secure

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><loggedIn><user>ecsuser@vipr.local</user></loggedIn>

 

  • Generate a secret key
host$ curl -ks -b cookiefile -H "Content-Type: application/json" -X POST -d "{}" https://10.76.246.143:4443/object/secret-keys | xmllint --format -
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <user_secret_key>
 <link rel="self" href="/object/user-secret-keys/ecsuser@vipr.local"/>
 <secret_key>E0VL18aDehVxfW4GuwpOQluMe6qBMNpNh/5aVwO8</secret_key>
 <key_expiry_timestamp/>
 <key_timestamp>2016-11-03 20:52:32.394</key_timestamp>
 </user_secret_key>
  • Generate a second secret key and set the expiration for the first key.
host$ curl -ks -b cookiefile -H "Content-Type: application/json" -X POST -d "{}" https://10.76.246.143:4443/object/secret-keys | xmllint --format -
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <user_secret_key>
 <link rel="self" href="/object/user-secret-keys/ecsuser@vipr.local"/>
 <secret_key>laCoJq2CNTrlFqH1Uvva5efCNCK6M65sdc3/NuFV</secret_key>
 <key_expiry_timestamp/>
 <key_timestamp>2016-11-03 20:54:05.448</key_timestamp>
 </user_secret_key>
  • One more time
host$ curl -ks -b cookiefile -H "Content-Type: application/json" -X POST -d "{}" https://10.76.246.143:4443/object/secret-keys | xmllint --format -
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <error>
 <code>1013</code>
 <description>Bad request body</description>
 <details>User ecsuser@vipr.local already has 2 valid keys.</details>
 <retryable>false</retryable>
 </error>
  • Check the keys that you have been assigned.
host$ curl -ks -b cookiefile https://10.76.246.143:4443/object/secret-keys | xmllint --format -
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <user_secret_keys>
 <secret_key_1>E0VL18aDehVxfW4GuwpOQluMe6qBMNpNh/5aVwO8</secret_key_1>
 <secret_key_2>laCoJq2CNTrlFqH1Uvva5efCNCK6M65sdc3/NuFV</secret_key_2>
 <key_expiry_timestamp_1/>
 <key_expiry_timestamp_2/>
 <key_timestamp_1>2016-11-03 20:52:32.394</key_timestamp_1>
 <key_timestamp_2>2016-11-03 20:54:05.448</key_timestamp_2>
 <link rel="self" href="/object/secret-keys"/>
 </user_secret_keys>
Note: key expiration date/time can be assigned if needed.
  • Delete secret keys before regenerating them.
host$ curl -ks -b cookiefile -H "Content-Type: application/json" -X POST -d "{}" https://10.76.246.143:4443/object/secret-keys/

host$ curl -ks -b cookiefile https://10.76.246.143:4443/object/secret-keys | xmllint --format -
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <user_secret_keys>
 <secret_key_1/>
 <secret_key_2/>
 <key_timestamp_1/>
 <key_timestamp_2/>
 </user_secret_keys>

 

Check object access

  • Modify .s3curl hidden config file in the home directory.
  • 600 permissions should be assigned to .s3curl file.
  • Several profiles can be used. Here “ecsid” profile is configured.
host$ /usr/share/s3curl # touch ~/.s3curl

host$ :/usr/share/s3curl # chmod 600 ~/.s3curl

host$ /usr/share/s3curl # vi ~/.s3curl
%awsSecretAccessKeys = (
   # ECS account
   ecsid => {
       id => ecsuser@vipr.local',
       key => ‘E0VL18aDehVxfW4GuwpOQluMe6qBMNpNh/5aVwO8',
   },
   @endpoints = ('10.76.246.146','10.76.246.144','10.76.246.145','10.76.246.143')
);
  • Check authentication using ECS account nickname you specified by ecsid profile in .s3curl file.
host$ ./s3curl.pl --id=ecsid -- -v -s http://10.76.246.143:9020/ |xmllint --format -
 * Trying 10.76.246.143...
 * Connected to 10.76.246.143 (10.76.246.143) port 9020 (#0)
 > GET / HTTP/1.1
 > Host: 10.76.246.143:9020
 > User-Agent: curl/7.49.1
 > Accept: */*
 > Date: Fri, 04 Nov 2016 16:04:56 +0000
 > Authorization: AWS ecsuser@vipr.local:amWVaaJDr1kpV7WI+wahSdq6pqg=
 >
 < HTTP/1.1 200 OK
 < Date: Fri, 04 Nov 2016 16:04:04 GMT
 < Server: ViPR/1.0
 < x-amz-request-id: 0a4cf68f:157f7328cf8:2226:1
 < x-amz-id-2:
 < Content-Type: application/xml
 < Content-Length: 281
 <
 { [281 bytes data]
 * Connection #0 to host 10.76.246.143 left intact
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
 <Owner>
 <ID>ecsuser@vipr.local</ID>
 <DisplayName>ecsuser@vipr.local</DisplayName>
 </Owner>
 <Buckets/>
 <IsTruncated>false</IsTruncated>
 </ListAllMyBucketsResult>
  • Create a bucket
host$ ./s3curl.pl --id=ecsid --createBucket -- -v -s http://10.76.246.143:9020/ecsbucket1
 * Trying 10.76.246.143...
 * Connected to 10.76.246.143 (10.76.246.143) port 9020 (#0)
 > PUT /ecsbucket1 HTTP/1.1
 > Host: 10.76.246.143:9020
 > User-Agent: curl/7.49.1
 > Accept: */*
 > Date: Fri, 04 Nov 2016 16:13:33 +0000
 > Authorization: AWS ecsuser@vipr.local:G9BYwg6qMZqstAnMJ42J9bYoAmQ=
 > Content-Length: 0
 >
 < HTTP/1.1 200 OK
 < Date: Fri, 04 Nov 2016 16:12:45 GMT
 < Server: ViPR/1.0
 < x-amz-request-id: 0a4cf68f:157f7328cf8:222e:1
 < x-amz-id-2: 3edc5666e73ab1593af862dea0c639ebf174c513397745192b1bedf56c910998
 < Location: /ecsbucket1
 < Content-Length: 0
 <
 * Connection #0 to host 10.76.246.143 left intact
  • Create and upload a file
host$ cat <<EOF> myfile
 > Hello World !
 >^d

host$ ./s3curl.pl --id=ecsid --put=myfile -- -v -s http://10.76.246.143:9020/ecsbucket1/myfile
 * Trying 10.76.246.143...
 * Connected to 10.76.246.143 (10.76.246.143) port 9020 (#0)
 > PUT /ecsbucket1/myfile HTTP/1.1
 > Host: 10.76.246.143:9020
 > User-Agent: curl/7.49.1
 > Accept: */*
 > Date: Fri, 04 Nov 2016 21:02:33 +0000
 > Authorization: AWS ecsuser@vipr.local:pP5qmPGJUnwW9Zs1raiVe8EIYg0=
 > Content-Length: 177
 > Expect: 100-continue
 >
 < HTTP/1.1 100 Continue
 * We are completely uploaded and fine
 < HTTP/1.1 200 OK
 < Date: Fri, 04 Nov 2016 21:01:40 GMT
 < Server: ViPR/1.0
 < x-amz-request-id: 0a4cf68f:157f7328cf8:22b7:d
 < x-amz-id-2: 97b30c0b46e1207109d3841724c121feb5f528217df2d9968f1073b46a5e737b
 < ETag: "89e8742ee81990ce8e1597e13e4feee4"
 < Last-Modified: Fri, 04 Nov 2016 21:01:40 GMT
 < x-emc-mtime: 1478293300707
 < x-emc-previous-object-size: 0
 < x-amz-copy-source-version-id:
 < Content-Length: 0
 <
 * Connection #0 to host 10.76.246.143 left intact

host$ ./s3curl.pl --id=ecsid -- -v -s http://10.76.246.143:9020/ecsbucket1/ |xmllint --format -
 * Trying 10.76.246.143...
 * Connected to 10.76.246.143 (10.76.246.143) port 9020 (#0)
 > GET /ecsbucket1/ HTTP/1.1
 > Host: 10.76.246.143:9020
 > User-Agent: curl/7.49.1
 > Accept: */*
 > Date: Fri, 04 Nov 2016 21:03:02 +0000
 > Authorization: AWS ecsuser@vipr.local:k8bJwoJ9BFCt5ZVRodXkRUyAp10=
 >
 < HTTP/1.1 200 OK
 < Date: Fri, 04 Nov 2016 21:02:10 GMT
 < Server: ViPR/1.0
 < x-amz-request-id: 0a4cf68f:157f7328cf8:22b9:5
 < x-amz-id-2: 3edc5666e73ab1593af862dea0c639ebf174c513397745192b1bedf56c910998
 < x-emc-retention-period: 0
 < Content-Type: application/xml
 < Content-Length: 590
 <
 { [590 bytes data]
 * Connection #0 to host 10.76.246.143 left intact
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
 <Name>ecsbucket1</Name>
 <Prefix/>
 <Marker/>
 <MaxKeys>1000</MaxKeys>
 <IsTruncated>false</IsTruncated>
 <ServerSideEncryptionEnabled>false</ServerSideEncryptionEnabled>
 <Contents>
 <Key> myfile </Key>
 <LastModified>2016-11-04T21:01:40Z</LastModified>
 <ETag>"89e8742ee81990ce8e1597e13e4feee4"</ETag>
 <Size>177</Size>
 <StorageClass>STANDARD</StorageClass>
 <Owner>
 <ID>ecsuser@vipr.local</ID>
 <DisplayName>ecsuser@vipr.local</DisplayName>
 </Owner>
 </Contents>
 </ListBucketResult>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: