02-Dec-2022 01:31
Hi All,
I am trying to access the icontrol API and collect the BIG IP logs.
curl -sku admin:admin -H "Content-Type: application/json" -X GET https://x.x.x.x/mgmt/tm/sys/log/ltm/stats
I am able to get the logs using the admin:admin user credentials.
But I wanted to know if there is any other way to access the api without admin user credentials. something like an API key which can be used only for API access as I cannot share the admin credentials with external users.
Please help me with the API authentication options.
Thanks!
Solved! Go to Solution.
05-Dec-2022 04:25 - edited 06-Dec-2022 01:23
Hi srinidhi,
the links I've provided you are outlining the details to configure iControl REST. There is unfortunately no GUI for it.
I somehow share your doubts. Personally I wont give lets say "untrusted people" a network access to my iControl REST and grant them "minimalistic" access permissions (e.g. Operator Role + API permissions). Its already to much for my taste...
You may check the iRule coding below to use a Virtual Server to provide an alternative and very restricted access method to your iControl REST. The iRule checks for a PERM-API-KEY header value and applies simple access rules. When an request is allowed to pass, F5 administrative credentials are getting insert in the forwarded request. On this way you dont need to forward any credentials to a "untrusted people" and the dont need a direct access to your Management IP at all.
when HTTP_REQUEST {
# Check if a given "PERM-API-KEY" HTTP header value is allowed to access a specific API endpoint
switch -glob -- "[HTTP::header value "PERM-API-KEY"]|[HTTP::method]|[HTTP::uri]" {
"InsertYourKeyValueToAllow|GET|/mgmt/tm/sys/log/ltm/stats?options=lines,10" {
# Allow the request
}
"InsertYourKeyValueToAllow|GET|/mgmt/tm/sys/log/ltm/stats?options=lines,20" {
# Allow the request
}
default {
# Deny all remaining requests
HTTP::respond 403 content "Access Denied" "Content-Type" "text/html"
return
}
}
# Sanitize inbound HTTP request headers and inject F5 Admin Credentials
HTTP::header sanitize
HTTP::header insert "Authorization" "Basic [b64encode "admin:admin"]"
# Forward the request to REST API (using Route-Domains other than 0 is required)
node 10.0.17.200%1 443
}
when HTTP_RESPONSE {
# Sanitize outbound HTTP request headers
HTTP::header sanitize
HTTP::header remove "Set-Cookie"
}
ltm virtual VS_for_restricted_API_access {
destination 10.0.18.23%1:https
ip-protocol tcp
mask 255.255.255.255
profiles {
clientssl {
context clientside
}
http { }
serverssl {
context serverside
}
tcp { }
}
rules {
iRule_for_restricted_API_access
}
serverssl-use-sni disabled
source 0.0.0.0%1/0
source-address-translation {
type automap
}
translate-address enabled
translate-port enabled
}
Note: The only requirement for the Virtual Server alternative access method is, that the Virtual Server must be operated in a Route-Domain other than 0 (default). The traffic has to leave your LTM-SelfIP and then find its way to the management IP via your network infrastructure.
Cheers, Kai
06-Dec-2022 06:49
Its a free-text value. Simply replace the value in the iRule i send your with a long password string like "hsU8iHU28HU283HU283d8ad8a3d8ash247da334lkxm".
Then send the string to the guy who needs to access to your API. Tell the guy to use this string as the value in a custom HTTP Header called "PERM_API_KEY" when accessing your API. Its basically a shared-key authentication used between the API caller and your F5.
curl -H "PERM_API_KEY: hsU8iHU28HU283HU283d8ad8a3d8ash247da334lkxm" https://10.0.17.200/mgmt/tm/sys/log/audit/stats
The F5 injects Basic credentials to the HTTP request before forwarding to REST API. You may create a new user account with at least Admin or Auditor permissions to read the logs. Then replace "admin:admin" with "Username:Password" of the just created user account.
You may also base64 encode the "Username:Password" string offline an replace the line with:
HTTP::header insert "Authorization" "Basic YOURBASE64CODE=="
It will basically masks the contained password value a bit...
Cheers, Kai
02-Dec-2022 01:55 - edited 02-Dec-2022 02:10
Hi srinidhi,
iControl REST has its own RBAC, which can be used to grant access to specific API endpoints to non-admin users. You may read the following article to see how it should be configured...
iControl REST Fine-Grained Role Based Access Contr... - DevCentral (f5.com)
iControl REST Role Based Access Control (RBAC) for remotely authenticated users (f5.com)
Alternatively may also use a Virtual Server front-ending your REST-API as alternative access method. By doing so you could Pre-Auth users (e.g. Certifictate, BASIC, HTTP header providing permanent API-Key) via exteral Repositories (e.g. User Names / Credentials / Keys / Settings stored in a Data-Group), apply restrictions by filtering HTTP requests (e.g. user ABC is only allowed to GET /mgmt/tm/sys/log/ltm/stats) and finally forward the request to your REST-API by replacing the client-side credentials with F5-Admin BASIC credentials on the server side.
Cheers, Kai
04-Dec-2022 20:44
Hey Kai, thanks for the info,
As you mentioned, can you please let me know how to grant user access to specific API endpoint.
That would be a great help.
05-Dec-2022 00:04
I have few doubts on giving access only to API:
Please let me know if I am missing on any detail
05-Dec-2022 04:25 - edited 06-Dec-2022 01:23
Hi srinidhi,
the links I've provided you are outlining the details to configure iControl REST. There is unfortunately no GUI for it.
I somehow share your doubts. Personally I wont give lets say "untrusted people" a network access to my iControl REST and grant them "minimalistic" access permissions (e.g. Operator Role + API permissions). Its already to much for my taste...
You may check the iRule coding below to use a Virtual Server to provide an alternative and very restricted access method to your iControl REST. The iRule checks for a PERM-API-KEY header value and applies simple access rules. When an request is allowed to pass, F5 administrative credentials are getting insert in the forwarded request. On this way you dont need to forward any credentials to a "untrusted people" and the dont need a direct access to your Management IP at all.
when HTTP_REQUEST {
# Check if a given "PERM-API-KEY" HTTP header value is allowed to access a specific API endpoint
switch -glob -- "[HTTP::header value "PERM-API-KEY"]|[HTTP::method]|[HTTP::uri]" {
"InsertYourKeyValueToAllow|GET|/mgmt/tm/sys/log/ltm/stats?options=lines,10" {
# Allow the request
}
"InsertYourKeyValueToAllow|GET|/mgmt/tm/sys/log/ltm/stats?options=lines,20" {
# Allow the request
}
default {
# Deny all remaining requests
HTTP::respond 403 content "Access Denied" "Content-Type" "text/html"
return
}
}
# Sanitize inbound HTTP request headers and inject F5 Admin Credentials
HTTP::header sanitize
HTTP::header insert "Authorization" "Basic [b64encode "admin:admin"]"
# Forward the request to REST API (using Route-Domains other than 0 is required)
node 10.0.17.200%1 443
}
when HTTP_RESPONSE {
# Sanitize outbound HTTP request headers
HTTP::header sanitize
HTTP::header remove "Set-Cookie"
}
ltm virtual VS_for_restricted_API_access {
destination 10.0.18.23%1:https
ip-protocol tcp
mask 255.255.255.255
profiles {
clientssl {
context clientside
}
http { }
serverssl {
context serverside
}
tcp { }
}
rules {
iRule_for_restricted_API_access
}
serverssl-use-sni disabled
source 0.0.0.0%1/0
source-address-translation {
type automap
}
translate-address enabled
translate-port enabled
}
Note: The only requirement for the Virtual Server alternative access method is, that the Virtual Server must be operated in a Route-Domain other than 0 (default). The traffic has to leave your LTM-SelfIP and then find its way to the management IP via your network infrastructure.
Cheers, Kai
05-Dec-2022 04:52
Thank you Kai for the iRule coding below to use a Virtual Server to provide an alternative.
I will try this method in my BIG-IP. I am checking the irule code, so is this code needs to be run in the BIG-IP tmsh cli?
Meanwhile I justed wanted to know if it is possible to create a user with access only to specific iControl REST API endpoint. I hhave tried to create user with guest role from the UI, but I am unable to provide a custom role via curl command as mentioned in this link: linkhttps://community.f5.com/t5/technical-articles/icontrol-rest-fine-grained-role-based-access-control/...
Can you please help me with the commands to create a user and give access to read all log related endpoint, also I doubt there are multiple logs API endpoint so I should be created resource group that includes all these endpoints?
05-Dec-2022 05:13
Hi
> ... so is this code needs to be run in the BIG-IP tmsh cli?
The 1st snippet is an iRule and 2nd is an VS configuration export. You would need to build such alike VS in your environment and then attach the iRule to it to filter and forward incomming traffic.
> Can you please help me with the commands to create a user and give access to read all log related endpoint, also I doubt there are multiple logs API endpoint so I should be created resource group that includes all these endpoints?
Depends on what you want to make accessible. Valid endpoints are shown below...
GET /mgmt/tm/sys/log/daemon/stats : Unix Daemon Logs
GET /mgmt/tm/sys/log/gtm/stats : Global Traffic Manager Logs
GET /mgmt/tm/sys/log/kernel/stats : Linux Kernel Messages
GET /mgmt/tm/sys/log/ltm/stats : Local Traffic Manager Logs
GET /mgmt/tm/sys/log/mail/stats : Mail Daemon Logs
GET /mgmt/tm/sys/log/messages/stats : Application Messages
GET /mgmt/tm/sys/log/security/stats : Security Related Messages
GET /mgmt/tm/sys/log/tmm/stats : Traffic Manager Microkernel Logs
GET /mgmt/tm/sys/log/user/stats : Various user process logs
GET /mgmt/tm/sys/log/webui/stats : Logs for the Web User Interface
GET /mgmt/tm/sys/log/audit/stats : Audits of configuration changes
Cheers, Kai
05-Dec-2022 07:27 - edited 05-Dec-2022 07:30
Thanks for the details I will try the code that you shared!
on the logs endpoint you have shared,
step 1:
so I have tried to create a custom resource group using this command:
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/sys/log/audit/stats" } ]}'
with resource mask as "/mgmt/tm/sys/log/audit/stats"
step 2: created a custom role with
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/test"} ], "resourceGroupReferences":[{"link":"https://localhost/mgmt/shared/authz/resource-groups/fe7a1ebc-3e61-30aa-8a5d-c7721f7c6ce2"}]}'
by updating the resourceGroupReferences with my reference got from the selfLink.
testing:
so till here everything is done and when I tried to test the user by accessing /mgmt/tm/sys/log/audit/stats I get 401 unauthorized error.
curl -D - -sku test:password https://192.168.0.102/mgmt/tm/sys/log/audit/stats | grep HTTP
HTTP/1.1 401 F5 Authorization Required
Is there any other step that I am missing. Please help me with this process.
Thanks for you support!
05-Dec-2022 07:31
You granted user "foo" the permissions but using user "test" for curl access. That could be the problem...
Cheers, Kai
05-Dec-2022 07:33
Sorry that was my mistake in the reply,
But I did the same process with the user "test" and getting the error 401
05-Dec-2022 07:40
Give me a second to repro the setup steps in my dev environment..
Cheers, Kai
05-Dec-2022 08:24 - edited 05-Dec-2022 08:25
I followed the guide below step-by-step...
iControl REST Fine-Grained Role Based Access Contr... - DevCentral (f5.com)
... outcome was...
{"code":401,"message":"user foo with role operator doesn't have access to show sys log audit","errorStack":[],"apiError":1}
... i needed to switch the role of user "foo" to "Auditor". Right after is was able to get access...
{"kind":"tm:sys:log:logstats","generation":0,"selfLink":"https://localhost/mgmt/tm/sys/log/audit/stats?ver=15.1.6","apiRawValues":{"apiAnonymous":"\nSys::Log\n--------------------------------------------\nMaximum line count (10000) exceeded\nSpecify a narrower range or increase maximum\n--------------------------------------------\n"}}
Side effect of using this RBAC-Config is that the user "foo" is now "Auditor" and can read LTMs configuration. Not via REST (its protected, thanks to RBAC!) but by logging into LTMs GUI (same IP/Port). And thats obviously not good...
I recommend you to implement the Virtual Server with iRule filtering approach. Much cleaner and does not require giving external people access to your Management IP and providing them with a real user account.
Cheers, Kai
06-Dec-2022 01:19
Thanks for the details, I will try executing the irule!
06-Dec-2022 01:22
You're welcome. Let me know if you need further assistance with the iRule and the VS setup..
Cheers, Kai
06-Dec-2022 05:43
Hi kai,
So I have created a VS and added the iRule in my F5, now I have a couple of doubts:
HTTP::header insert "Authorization" "Basic [b64encode "admin:admin"]"
06-Dec-2022 06:49
Its a free-text value. Simply replace the value in the iRule i send your with a long password string like "hsU8iHU28HU283HU283d8ad8a3d8ash247da334lkxm".
Then send the string to the guy who needs to access to your API. Tell the guy to use this string as the value in a custom HTTP Header called "PERM_API_KEY" when accessing your API. Its basically a shared-key authentication used between the API caller and your F5.
curl -H "PERM_API_KEY: hsU8iHU28HU283HU283d8ad8a3d8ash247da334lkxm" https://10.0.17.200/mgmt/tm/sys/log/audit/stats
The F5 injects Basic credentials to the HTTP request before forwarding to REST API. You may create a new user account with at least Admin or Auditor permissions to read the logs. Then replace "admin:admin" with "Username:Password" of the just created user account.
You may also base64 encode the "Username:Password" string offline an replace the line with:
HTTP::header insert "Authorization" "Basic YOURBASE64CODE=="
It will basically masks the contained password value a bit...
Cheers, Kai
07-Dec-2022 22:33
Hi Thanks for the detailed explanation!!!
07-Dec-2022 22:43
You're welcome. Could you please change your "Accepted Answer" to display the iRule itself or maybe both - the iRule itself and the last post containing the curl -H "PERM_API_KEY." command?
This would help other members which are looking for the same solution.
Thanks!
Cheers, Kai
12-Dec-2022 04:04
Hi Kai,
Apologize for multiple questions.
I am trying the iRule and wanted to know where I need to replace my key.
switch -glob -- "[HTTP::header value "PERM-API-KEY"]|[HTTP::method]|[HTTP::uri]" {
Do I need to replace the "PERM-API-KEY" which my key here.
And is this node the virtual server IP?
# Forward the request to REST API (using Route-Domains other than 0 is required) node 10.0.17.200%1 443
Also, does the end user will make API request to the virtual server?
13-Dec-2022 02:35 - edited 13-Dec-2022 02:39
Hi srinidhi12,
you would need to insert your generated keys into those rule strings...
"InsertYourKeyValueToAllow|GET|/mgmt/tm/sys/log/ltm/stats?options=lines,10"
The rule basically says, whenever someone with provides a PERM-API-KEY HTTP header with the value of "InsertYourKeyValueToAllow" and tries request with method "GET" at the endpoint "GET|/mgmt/tm/sys/log/ltm/stats" with query param "?options=lines,10", then allow this request and forward the request to your Management IP...
The "node 10.0.17.200%1 443" should be updated with the Management IP of your F5. The IP of the Virtual Server will be defined in the VS configuration.
Info: Keep in mind, that the VS must be configured to use a Route-Domain other than ID=0 and the iRule must forward the Request to your Management IP via the very same Route-Domain. Otherwise you wont get access...
Cheers, Kai
14-Dec-2022 04:06
Hi Kai, got it, thanks for the details