cancel
Showing results for 
Search instead for 
Did you mean: 
Login & Join the DevCentral Connects Group to watch the Recorded LiveStream (May 12) on Basic iControl Security - show notes included.
Satoshi_Toyosa1
F5 Employee
F5 Employee

Introduction

F5's role based access control (RBAC) mechanism allows a BIG-IP administrator to assign appropriate access privileges to the users (see Manual Chapter: User Roles). For example, with the operator role, the user is specifically allowed to enable or disable nodes and pool members. The mechanism is generally the best way to manage users easily and consistently, however, finer access management may be required from time to time: e.g., allow only to view the stats of a predefined set of virtuals. Restricting access is especially important in iControl REST because users can remotely and directly access the system.

The existing roles and their access permissions are defined in /mgmt/shared/authz/roles and /mgmt/shared/authz/resource-groups. You can add custom roles with custom permissions for particular users to these resources (iControl REST endpoints). The resources are described in BIG-IQ Systems REST API References, however, they are not exactly easy to follow. To fill the gap, this article describes a method to configure users and roles in a much finer manner.

Note

This method is only applicable to iControl REST: It does not apply to Configuration Utility or ssh.

The method relies on the resources for local users (i.e., /mgmt/tm/auth/user and /mgmt/shared/authz/users). It does not work for remote authentication mechanisms such as RADIUS or Active Directory.

Setup

In this example, a local user "foo" and a custom role "testRole" are created. The role allows users to GET (list) only the virtual server "vs". The access method and resource are defined in "testResourceGroup", that is referenced from the "testRole". No other operation such as PATCH (modify) or DELETE is permitted. Also, no other resource such as another virtual is allowed. All the REST calls are done using curl: You may want to consider using other methods such as F5 Python SDK .

1. Create a new user

The following curl command creates the user "foo". The password is "foo", the description is "Foo Bar", and the role is "operator" for all the partitions.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/tm/auth/user -X POST -H "Content-Type: application/json" \
  -d '{"name":"foo", "password":"foo", "description":"Foo Bar", "partitionAccess":[ { "name":"all-partitions", "role":"operator"} ] }'

You get the following JSON object:

{
    "description": "Foo Bar",
    "encryptedPassword": "$6$jwL4UUxv$IUrzWGEUsyJaXlOB2oyyTPflHFdvDBXb6f3f/No4KNfQb.V6bpQZBgvxl3KkBDXGtpttej79DDphEGRh8d4iA/",
    "fullPath": "foo",
    "generation": 1023,
    "kind": "tm:auth:user:userstate",
    "name": "foo",
    "partitionAccess": [
        {
            "name": "all-partitions",
            "nameReference": {
                "link": "https://localhost/mgmt/tm/auth/partition/all-partitions?ver=13.1.1.2"
            },
            "role": "operator"
        }
    ],
    "selfLink": "https://localhost/mgmt/tm/auth/user/satoshi?ver=13.1.1.2"
}

The role is important. When the access privileges conflict between the role and the fine grained RBAC, the stricter authorization is chosen. For example, if the RBAC is configured to allow PATCH or POST but the user's role is guest (no alteration allowed), the user won't be able to perform these methods.

You can create a user from tmsh or Configuration Utility if that's your preferred method.

2. (13.1.0 and later) Remove the user from /mgmt/shared/authz/roles/iControl_REST_API_User

From v13.1.0, a newly created local user is automatically added to iControl_REST_API_User, which grants access to iControl REST without any setup. To avoid assigning multiple permissions, you need to remove the user reference from /mgmt/shared/authz/roles/iControl_REST_API_User.

First, get the data from /mgmt/shared/authz/roles/iControl_REST_API_User and redirect it to a file.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/roles/iControl_REST_API_User \
  | python -m json.tool > file

Edit the file. The file contains a line for the user "foo" like this.

 "name": "iControl_REST_API_User",
 "userReferences": [
  {
    "link": "https://localhost/mgmt/shared/authz/users/foo"
  },
  ....

Remove the line including the opening and ending curly brackets plus the comma. Save the file.

Overwrite the current data by putting the file to the endpoint.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/roles/iControl_REST_API_User -X PUT -d@file

3. Create a custom resource-group

A resource-group consists of a set of resources and methods. In this example, the resource-group is named "testResourceGroup", which allows a role to perform GET request to the resource /mgmt/tm/ltm/virtual/vs. "testResourceGroup" is later used in the custom role.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/resource-groups -X POST -H "Content-Type: application/json" \
  -d '{"name":"testResourceGroup", "resources":[ {"restMethod":"GET", "resourceMask":"/mgmt/tm/ltm/virtual/vs" } ]}'

You get the following JSON object. 

{
 "id": "fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2",
 "name": "testResourceGroup",
 "resources": [
  {
   "resourceMask": "/mgmt/tm/ltm/virtual/vs",
   "restMethod": "GET"
  }
 ],
 "generation": 1,
 "lastUpdateMicros": 1521682571723849,
 "kind": "shared:authz:resource-groups:roleresourcegroupstate",
 "selfLink": "https://localhost/mgmt/shared/authz/resource-groups/fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2"
}

Note that a resource-group entry is keyed by "id", not "name". The id is automatically generated.

As you can see, the resources field is a list of multiple objects, each containing the endpoint and the method. To add more permissions to the resource-group, add objects to the list.

4. Create a custom role

Create a role "testRole" with the user "foo" and the resource-groups "testResourceGroup". This makes the user to become a member of the role "testRole", hence allows the users to perform GET only to the /mgmt/tm/ltm/virtual/vs.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/roles -X POST -H "Content-Type: application/json" \
  -d '{"name":"testRole", "userReferences":[ {"link":"https://localhost/mgmt/shared/authz/users/foo"} ], "resourceGroupReferences":[{"link":"https://localhost/mgmt/shared/authz/resource-groups/fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2"}]}'

Please note that the reference to the user foo in the userReferences field is different from Step #1: The user created was /mgmt/tm/auth/user/foo while the reference is /mgmt/shared/authz/users/foo. The /mgmt/shared/authz/users/foo is automatically created. Just use /mgmt/shared/authz/users/ + user name.

Again, please observe that the resource-groups reference is not by name but by ID. See the selfLink in the step #3.

You get the following JSON object.

{
 "name": "testRole",
 "userReferences": [
  {
   "link": "https://localhost/mgmt/shared/authz/users/foo"
  }
 ],
 "resourceGroupReferences": [
  {
   "link": "https://localhost/mgmt/shared/authz/resource-groups/fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2"
  }
 ],
 "generation": 1,
 "lastUpdateMicros": 1521682931708662,
 "kind": "shared:authz:roles:rolesworkerstate",
 "selfLink": "https://localhost/mgmt/shared/authz/roles/testRole"
}

Test

The following REST calls demonstrate that the user "foo" can GET the virtual "vs" but nothing else.

curl -D - -sku foo:foo https://192.168.226.155/mgmt/tm/ltm/virtual/vs | grep HTTP
HTTP/1.1 200 OK
curl -D - -sku foo:foo https://192.168.226.155/mgmt/tm/ltm/virtual | grep HTTP
HTTP/1.1 401 F5 Authorization Required
curl -D - -sku foo:foo https://192.168.226.155/mgmt/tm/ltm/virtual -X PATCH -d '{"test":"test"}' | grep HTTP
HTTP/1.1 401 F5 Authorization Required
curl -D - -sku foo:foo https://192.168.226.155/mgmt/tm/sys/version | grep HTTP
HTTP/1.1 401 F5 Authorization Required

Cleanup

Removing users that are no longer used is a good admin practice. The cleanup procedure is described below (response JSON blobs are not shown):

1. Delete the resource-group. Use ID.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/resource-groups/fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2 -X DELETE

2. Delete the custom role.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/shared/authz/roles/testRole -X DELETE

3. Delete the user.

You can perform this step from tmsh or Configuration Utility.

curl -sku admin:<pass> https://<mgmtIP>/mgmt/tm/auth/user/foo -X DELETE
Comments
235
Nimbostratus
Nimbostratus

@Satoshi Toyosawa

 

Very cool article.

 

I don't understand and How user-foo is associated with the testRole?

 

Part 4,Below output have not the user foo.

 

"name": "testRole", "userReferences": [ { "link": "; } ], "resourceGroupReferences": [ { "link": "; } ], "generation": 1, "lastUpdateMicros": 1521682931708662, "kind": "shared:authz:roles:rolesworkerstate", "selfLink": "; }

 

Thanks

 

Satoshi_Toyosa1
F5 Employee
F5 Employee

Good spotting. Typo fixed. Thanks.

 

JWhitesPro_1928
Cirrostratus
Cirrostratus

What does the format look like if you have multiple resources in the resource mask or multiple methods?

 

To specify multiple resourses you will simply add them to the collection in the context of "resources" by using a PATCH method (a POST would overwrite the collection).

 

Below you will find some examples.

 

virtuals GET ./mgmt/tm/ltm/virtual List all virtual servers (cannot list a specific one) GET ./mgmt/tm/ltm/virtual/* List specified virtual server (cannot list all) GET ./mgmt/tm/ltm/virtual/~~ List properties of specified virtual servers GET ./mgmt/tm/ltm/virtual/~~/* List properties (profiles, policies, ?) of specified virtual servers GET ./mgmt/tm/ltm/virtual/~~/profiles List profiles of specified virtual servers GET ./mgmt/tm/ltm/virtual/~~/policies List policies of specified virtual servers POST ./mgmt/tm/ltm/virtual/*/* Add properties (profiles, policies, ?) all virtual servers POST ./mgmt/tm/ltm/virtual/~~/* Add properties (profiles, policies, ?) of specified virtual servers POST ./mgmt/tm/ltm/virtual/~~/profiles Add profiles of specified virtual servers POST ./mgmt/tm/ltm/virtual/~~/policies Add policies of specified virtual servers PATCH ./mgmt/tm/ltm/virtual/* Modify properties all virtual servers PATCH ./mgmt/tm/ltm/virtual/~~ Modify properties of specified virtual servers DELETE ./mgmt/tm/ltm/virtual/*/*/* Delete properties (profiles, policies, ?) all virtual servers DELETE ./mgmt/tm/ltm/virtual/~~/*/* Delete properties (profiles, policies, ?) of specified virtual servers DELETE ./mgmt/tm/ltm/virtual/~~/profiles/* Delete profiles of specified virtual servers DELETE ./mgmt/tm/ltm/virtual/~~/policies/* Delete policies of specified virtual servers pools GET ./mgmt/tm/ltm/pool List all pools (cannot list a specific one) GET ./mgmt/tm/ltm/pool/* List specified pools (cannot list all) GET ./mgmt/tm/ltm/pool/~~ List properties of specified pools GET ./mgmt/tm/ltm/pool/~~/* List properties (members, ?) of specified pools GET ./mgmt/tm/ltm/pool/~~/members List Members of specified pools POST ./mgmt/tm/ltm/pool/*/* Add properties (members, ?) all pools POST ./mgmt/tm/ltm/pool/~~/* Add properties in specified pool POST ./mgmt/tm/ltm/pool/~~/members Add Members of specified pools DELETE ./mgmt/tm/ltm/pool/*/*/* Delete properties (members, ?) all pools DELETE ./mgmt/tm/ltm/pool/~~/*/* Delete properties in specified pool DELETE ./mgmt/tm/ltm/pool/~~/members/* Delete Members of specified pools PATCH ./mgmt/tm/ltm/pool/* Modify properties all pools PATCH ./mgmt/tm/ltm/pool/~~ Modify properties in specified pool PATCH ./mgmt/tm/ltm/pool/*/*/* Modify properties (members) all pools (administrative state) PATCH ./mgmt/tm/ltm/pool/~~/*/* Modify properties (members, ?) in specified pool (administrative state) PATCH ./mgmt/tm/ltm/pool/~~/members/* Modify Members of specified pools (administrative state) PATCH ./mgmt/tm/ltm/pool/~~/members/~~ Modify specified members of specified pools (administrative state)
Peter_Baumann
Cirrostratus
Cirrostratus

Hello

 

Is this custom resource-group config also saved into a backup?

 

Thanks, Peter

 

Hi Peter, no, it´s not. It seems to be reboot-proof. But it had to be restored after a software update. No idea, where the information is stored. We kept it in a script (stored in /config/) directory and executed it conditionally via /config/startup. Thanks, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephen, We are using Big-IP 13.1.0.3 Build 0.0.5 Point Release 3.

 

It seems to work only when we leave the user "foo" in the iControl_REST_API_User reference group... When we delete its reference we get an 401 Authorization error... Do you know what might be the problem? Thank you, Steve

 

Hi Steve,

 

that´s correct in my opinion.

 

The role needs to contain both the user reference and the resources (as described in my incomplete list of examples above).

 

I would expect it to work the same way in TMOS v13 but have not tested it yet (as we are using this mechanism in v11 and v12 by now).

 

At least there was a significant change in the latest BIG-IQ release v5.4, which does not support the described RBAC-model anymore.

 

Cheers, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, Thank you very much for the quick response!

 

The problem is that if we don`t delete the user from the iControl_REST_API_User reference group, it gets administrative permissions so that the RBAC model becomes irrelevant.

 

So the Rest API RBAC model does not work on Big-IP v13...?

 

Thank you, Steve

 

Hi Steve, I will check it tonight while travelling and provide an update. Will also check it´s behaviour on reboot and config restore. Cheers, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Thank you very much Stephan! Steve

 

Hi Steve, as described by Satoshi San an additional step is required for TMOS v13.1+. Here is what I just verified vs. TMOS v13.1.0.7:

 

Add role for role-based-access [RBAC] (i.e. "iControl_customRole_remote") curl -sk -H "Content-Type: application/json" -u admin:admin -X POST -d '{"name":"iControl_customRole_remote","description":"Custom REST API Proxy role, added via iControl","resources": []}' "https://10.200.200.21/mgmt/shared/authz/roles/" | \ python -m json.tool Modify role (resources) curl -sk -H "Content-Type: application/json" -u admin:admin -X PATCH -d '{"resources":[{"resourceMask":"/mgmt/tm/ltm/virtual","restMethod":"GET"}]}' "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | \ python -m json.tool curl -sk -H "Content-Type: application/json" -u admin:admin -X PATCH -d '{"resources":[{"resourceMask":"/mgmt/tm/ltm/virtual/*","restMethod":"GET"}]}' "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | \ python -m json.tool Create user (i.e. "remoterestapi") curl -sk -H "Content-Type: application/json" -u admin:admin -X POST -d '{"name":"remoterestapi","password":"changeme","displayName":"My REST API User"}' "https://10.200.200.21/mgmt/shared/authz/users/" | python -m json.tool Assign users to role (i.e. "remoterestapi" mapped to "iControl_customRole_remote") curl -sk -H "Content-Type: application/json" -u admin:admin -X PATCH -d '{"userReferences":[{"link":"https://localhost/mgmt/shared/authz/users/remoterestapi"}]}' "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | python -m json.tool Apply step as described by Satoshi San for TMOS v13.1+ curl -sk -H "Content-Type: application/json" -u admin:admin -X GET "https://10.200.200.21/mgmt/shared/authz/roles/iControl_REST_API_User" | python -m json.tool (Modify output by removing the newly created user and save to file) curl -sk -H "Content-Type: application/json" -u admin:admin -X PUT -d@/var/tmp/mod.iControlREST_API_User "https://10.200.200.21/mgmt/shared/authz/roles/iControl_REST_API_User" | python -m json.tool Test A: (Virtual Server) [expected result: list of virtual servers] curl -sk -H "Content-Type: application/json" -u remoterestapi:changeme -X GET "https://10.200.200.21/mgmt/tm/ltm/virtual" | \ python -m json.tool Test B: (Pools) [expected result: authorization failure due to limited privileges] curl -sk -H "Content-Type: application/json" -u remoterestapi:changeme -X GET "https://10.200.200.21/mgmt/tm/ltm/pool" | \ python -m json.tool Optional tasks: not required for repro Optional: Read role curl -sk -u admin:admin "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | \ python -m json.tool Optional: Remove user (i.e. "remoterestapi") curl -sk -u admin:admin -X DELETE "https://10.200.200.21/mgmt/shared/authz/users/remoterestapi" | python -m json.tool Optional: Combined replacement of user and role resources curl -sk -H "Content-Type: application/json" -u admin:admin -X PUT -d '{"resources":[{"resourceMask":"/mgmt/tm/ltm/virtual","restMethod":"GET"}],"userReferences":[{"link":"https://localhost/mgmt/shared/authz/users/remoterestapi"}]}' "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | python -m json.tool Optional: Remove role (via REST API only; removal via BIG-IP WebUI failde) curl -sk -u admin:admin -X DELETE "https://10.200.200.21/mgmt/shared/authz/roles/iControl_customRole_remote" | python -m json.tool

Looks like it works as expected. Unfortunately I´m running out of time now to test the backup/restore now. More to follow. Cheers, Stephan

 

Hi Steve, tests above were actually made vs. TMOS v13.1.0.6. The open question was about the ability to restore the config or to roll forward. Results look promising. In TMOS v13.1.0.6 I saved a .ucs, performed a tmsh load sys config default and restored from the .ucs. User and role was available after the procedure. Same result after installing TMOS v13.1.0.7 to HD1.2 followed by cpcfg HD1.2; switchboot -b HD1.2; reboot. The new step for v13.1+ was indeed required because the new user got all privileges. There seemed to be no limitations ... After removing the user according to the procedure provided above it worked the same way as in previous versions. Cheers, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, For some reason it does not work for us on version 13.1.0.3 I will try to do that on 12.1.3 and I will update with the results.

 

Thank you so much for all of your help and hard work! Steve

 

Hi Steve, for testing under v12 it should not be necessary to remove the newly created user from the "iControl_REST_API_User" role. Please keep us posted on your results. Cheers, Stephan

 

Hi Steve, it worked as usual under v12.1.3.4. No need to touch the iControl_REST_API_User. It worked as well under v13.1.0.3 in my environment after modifying the iControl_REST_API_User role.

 

After creating the new user via REST initially it looked as follows:

 

{ "generation": 5, "kind": "shared:authz:roles:rolesworkerstate", "lastUpdateMicros": 1531251954487702, "name": "iControl_REST_API_User", "resourceGroupReferences": [ { "link": "https://localhost/mgmt/shared/authz/resource-groups/b7592f19-027c-3272-b83d-9178bb9d9f0e" } ], "selfLink": "https://localhost/mgmt/shared/authz/roles/iControl_REST_API_User", "userReferences": [ { "link": "https://localhost/mgmt/shared/authz/users/admin" }, { "link": "https://localhost/mgmt/shared/authz/users/f5hubblelcdadmin" }, { "link": "https://localhost/mgmt/shared/authz/users/remoterestapi" } ] }

It was changed into the following (no need to worry about "kind", "generation" and "lastUpdateMicros" as they will be restored; make sure to create a proper JSON body; no trailing comma ...):

 

{ "name": "iControl_REST_API_User", "resourceGroupReferences": [ { "link": "https://localhost/mgmt/shared/authz/resource-groups/b7592f19-027c-3272-b83d-9178bb9d9f0e" } ], "selfLink": "https://localhost/mgmt/shared/authz/roles/iControl_REST_API_User", "userReferences": [ { "link": "https://localhost/mgmt/shared/authz/users/admin" }, { "link": "https://localhost/mgmt/shared/authz/users/f5hubblelcdadmin" } ] }

It was imported in the way described above and the RBAC worked properly (limited priviledges).

 

One more thing to note (which I cannot explain). After modifying the role, a lot of new entries like the following showed up in the context of the "userReferences" collection:

 

{ "link": "https://localhost/mgmt/cm/system/authn/providers/tmos/1f44a60e-11a7-3c51-a49f-82983026b41b/user-groups/2ef6ed6f-136c-3a41-9167-76a0b68fb64d" },

Cheers, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, If it works for you I am obviously doing something wrong..

 

I will try some more tests and then I will post exactly what I am doing.. Thank you again so much! Steve

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, Ok,

 

  1. I create the user "foo" { "name": "foo", "displayName": "Foo Bar", "encryptedPassword": "$6$YYD71I0t$TOpQJsDlz7TCjqpKvcQgVFWUVXCOwIV4s3LMQLsVdtnR7eULnI9dfjZhHAyiDTqEoR93RW2C1OPNUx1imRSWs/", "shell": "/sbin/nologin", "generation": 0, "lastUpdateMicros": 0, "kind": "shared:authz:users:usersworkerstate", "selfLink": "; }

     

  2. I create a role "testRole" and attach a "userReferences" and "resources" to it { "name": "testRole", "userReferences": [ { "link": "; } ], "resources": [ { "resourceMask": "/mgmt/tm/ltm/virtual/DVWA-master-vip", "restMethod": "GET" } ], "generation": 23, "lastUpdateMicros": 1531298163050205, "kind": "shared:authz:roles:rolesworkerstate", "selfLink": "; }

     

I have followed your post when I did that, What am I doing wrong? Thank you, Steve

 

Hi Steve, what TMOS version are you testing on now? There are syntax errors in your user reference and in the resource section. The trailing semicolon after the link in "userReference" will probably result in a malformed JSON body error message. There is another trailing semicolon behind the selfLink in the resources of your role which should cause errors as well. When testing versus your defined role please make sure to use the exact same path syntax. Your role will allow to send a GET request for /mgmt/tm/ltm/virtual/DVWA-master-vip only. It´s confusing me, that your role contains both references for localhost and a specific IP host of 192.168.203.11. My list of steps as described above can be executed remotely (including the setup for the user) completely and so I did. You are using local authentication? Cheers, Stephan

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, The output is from my lab environment . 1. The TMOS version is : Main Package Product BIG-IP Version 13.1.0.3 Build 0.0.5 Edition Point Release 3 Date Mon Feb 12 19:22:50 PST 2018

 

  1. I think the semicolon was added by mistake in this post because on the Big-IP itself it ok. I will add the syntax again : { "name": "testRole", "userReferences": [ { "link": "; } ], "resources": [ { "resourceMask": "/mgmt/tm/ltm/virtual/DVWA-master-vip", "restMethod": "GET" } ], "generation": 23, "lastUpdateMicros": 1531298163050205, "kind": "shared:authz:roles:rolesworkerstate", "selfLink": "; }

     

  2. I tried various ways to make this work that is why you see an IP address once and a "localhost" in an another reference. I have tried to do everything with an IP address and it didn`t work... Myabe I should try configuring everything with "localhost"?

     

  3. Yes, I am using local authentication. I also use "Postman" for the API calls and not "curl"

     

I have opened a support case with F5, I will update with the results. If you have anymore ideas I would gladly listen and implement.

 

Thank you again so much! Steve

 

SteveGold
Nimbostratus
Nimbostratus

BTY, Yes, the semicolon is added by Devcentral automatically

 

SteveGold
Nimbostratus
Nimbostratus

Hi Stephan, Good news, It WORKS! When you wrote : "It´s confusing me, that your role contains both references for localhost and a specific IP host of 192.168.203.11." it got me thinking.. I changed everything to "localhost with no IP address and it worked!!!! Thank you so much again! Steve

 

Nice! Thanks for the update.

 

Olivier_Gleizes
Nimbostratus
Nimbostratus

Hi ! As I understand this article, I can't give to a api user the permissions to POST or PATCH without give him the admin permissions. I try to give the rights to a user with the operator rôle to modify with iControl the gtm configuration (and only this part).

 

Indeed, the api user can bypass the fine grained permission of icontrol with the Configuration Utility and perform the actions manualy.

 

Piotr_Bratkows3
Nimbostratus
Nimbostratus

Hello,

 

How is it that you are using HTTP auth for non admin users? From 12.1 all authentication is done via token. Am I missing something?

 

Regards, Piotr

 

Olivier_Gleizes
Nimbostratus
Nimbostratus

Hello !

 

Maybe it's me misunderstanding something. A token is given to an user(*) and if the user don't have the admin role, he can't do any POST or PATCH API request. How you can create a user with admin role without give it the access to the configuration utility with the same role ?

 

(*) As I can see here : https://clouddocs.f5.com/api/icontrol-soap/Authentication_with_the_F5_REST_API.html

 

BenJ
Nimbostratus
Nimbostratus

I am inclined to agree with Olivier here. Unfortunately I don't have a unit to run tests on, but if I have understood the above article correctly, the fine-grained security control put in place here only applies to API requests.

 

As an example, Satoshi mentions giving access to the stats for a particular virtual server - which happens to be the exact use-case I have. To view stats normally, a user needs a role with administrative level privileges (which I can't make sense of, but that's another story!). Based on the example in the article, I am therefore concluding the role assigned to my user in the first step would need to be an administrative role. I would then create a new custom role as described above, attach the user to the custom role and apply the required restrictions (ie. GET only) via the custom resource-group mapped to the custom role.

 

I understand this works for API requests. However, my confusion is over how (or if) this new role has any effect on the new users' ability to login to the Configuration Utility? If the custom role has no bearing on login to the config utility, then I've just given a user GUI admin privileges when all I wanted was to let them see stats.

 

Very happy to be corrected if I've misunderstood something here.

 

Cheers.

 

Piotr_Bratkows3
Nimbostratus
Nimbostratus

@BenJ and @Oliver

 

I managed to get this to work. As a non-admin user you need to have token and RBAC policy for example to modify pool member can be written in sucha a way:

 

{ "name":"poolModifyGroup", "resources":[ {"restMethod":"PATCH", "resourceMask":"/mgmt/tm/ltm/pool/*" }, {"restMethod":"PATCH", "resourceMask":"/mgmt/tm/ltm/pool/*/*" }, {"restMethod":"PATCH", "resourceMask":"/mgmt/tm/ltm/pool/*/*/*" }, {"restMethod":"GET", "resourceMask":"/mgmt/tm/ltm/pool/*" } ] }

If you only write {"restMethod":"PATCH", "resourceMask":"/mgmt/tm/ltm/pool/*" } then it's not enough.

 

Hope that helps.

 

Regards, Piotr

 

jonwest1_uk
Cirrus
Cirrus

Hi, thanks for the well written article. I've tested on versions 12.1.2 and 13.0.0 and I don't get any 401 responses. Foo is able to successfully make each call with a 200 response. I'm guessing this only works for 13.1.0 and above (like step 2), is that correct? If so is there any other way to restrict API calls in lower versions?

 

Satoshi_Toyosa1
F5 Employee
F5 Employee

Step 2 is a specific instruction for 13.1.0 and above. Skip it for older versions. iControl REST RBAC should work for 11.6 and above.

 

dsfraser
Nimbostratus
Nimbostratus

I know there is the statement "It does not work for remote authentication mechanisms such as RADIUS or Active Directory." But could this work if I added a local user with the same username and gave it a role? I have tried but if I get a token I can pretty much do anything on the API with my AD user.

aheilmaier
Nimbostratus
Nimbostratus

I also struggle with this sentence.

Will this work if I have in parallel remote authenticaton for i.e. ssh admins ?

Because I get authorization errors and can not find what the reason is.

But with a remote authenticated admin user I do get a response on my get request via curl.

 

Whre can I check for authentication/authorization ?

Are there any logs ?

 I came across the auth issue yesterday after a client called me when getting a 401 for RADIUS authenticated REST API users.

The problem was observed an reproducable in TMOS v12.1.4.1 and v12.1.5.2.

I followed the steps described in K01293626 and the disabling/enabling of remote auth after creating a local account seemed to fix the issue.

After reenabling the remote auth the user was added to the remote role user reference as described in the solution.

Both token based and basic auth based access worked from now.

 

The solution mentioned above has minor mistakes and little room for optimization as described below (left as comment as well in the solution; got no feedback):

# 6. # - does not require basic auth w/ "-u user:password", because credentials are posted with the payload) # - requires the -H parameter declaration for the content type # - use jq to pipe the output for human readable format   curl -sk -H "Content-Type: application/json" -X POST https://<BIGIP address>/mgmt/shared/authn/login -d '{"username": <user>,"password": <password>,"loginProviderName": "tmos"}' | jq   # 7. # - does not require the content type declaration, because no data is provided to the service   curl -sk -H "X-F5-Auth-Token: <TOKEN>" https://<BIGIP address>/mgmt/tm/ltm/virtual/ | jq

To check the user was assigned to the remote role you might want to use the following:

curl -svk -u 'admin:<admin password>' 'https://<>/mgmt/shared/authz/roles/iControl_REST_API_User/?$select=userReferences' | python -m json.tool

As shown above the python -m json.tool might be use as an alternative to piping via jq depending on availability.

 

 

 

aheilmaier
Nimbostratus
Nimbostratus

I am not sure, but it looks like this fine grained access controll does not work, when tacacs authentication is enabled.

The user I created will be authenticated agains my tacacs remote auth server, and this auth ist failing.

Just checked `/var/log/secure` to see it authc against tacacs.

 What TMOS version are you on? Is it TACACS based authentication only or are you using remote roles as well?

For some TMOS versions a TOKEN based REST API access was working only with TACACS (fixed in v15.1.1 according to the release notes).

aheilmaier
Nimbostratus
Nimbostratus

Thank's Stephan, this also clarifies the need for a central authenticated user.

So https://support.f5.com/csp/article/K01293626 also mentions that the user needs to authenticat against radius.

"4. You should be able to log in with the RADIUS credentials."

 

 have not mentinoed I use version 14.1.2.6 and also configured remote roles groups. Hope I do not need a remote-role group also for this user.

mgateau
Nimbostratus
Nimbostratus

Dear all,

Is there a way to automate step 2 : delete the user entry added in iControl_REST_API_User

role using a curl request ?

Addind a user in a role needs to send a PATCH request to /mgmt/shared/authz/roles/<ROLE_NAME>

with json payload '{ "userReferences":[{"link":"https://localhost/mgmt/shared/authz/users/<USER_NAME>"}] }'

But how to delete, with a curl request, an entry in the userReferences array/subcollection (not using your manual method even if the suppression can be done with sed or ...)?

I try to find infos in icontrol user guide pdf but no way (https://cdn.f5.com/websites/devcentral.f5.com/downloads/icontrol-rest-api-user-guide-14-1-0.pdf).

Thanks for help ...

 

Hi ,

according to an article written by Jason Rahm, you may add items to the list.

But items can be deleted only, if it´s kind of subcollection.

So you may want to replace the whole collection by a new one, as far as I can say.

Kind regards, Stephan

Nicotrel
Nimbostratus
Nimbostratus

Good day, Does this method still work in 15.1.2? I have been trying to get it and a similar method (https://support.f5.com/csp/article/K55510624) to work that last couple days. I cannot get either to restrict to only a single VIP or pool.

 

Thank you, Jason

nandakumar19
Nimbostratus
Nimbostratus

This is not working for me Version: 14.1.4 Build 0.0.11.

Version history
Last update:
‎07-Nov-2018 03:00
Updated by:
Contributors